Block matrix, initial version

This commit is contained in:
Hrvoje Jasak 2010-09-29 19:57:03 +01:00
parent c698684d7f
commit c62d4896c0
171 changed files with 27901 additions and 0 deletions

View file

@ -0,0 +1,8 @@
tensor2Field.C
blockVector2Matrix.C
blockVector2Solvers.C
blockCoupledScalarTransportFoam.C
EXE = $(FOAM_APPBIN)/blockCoupledScalarTransportFoam

View file

@ -0,0 +1,8 @@
EXE_INC = \
-ftemplate-depth-100 \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/blockMatrix/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lblockMatrix

View file

@ -0,0 +1,154 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Application
blockCoupledScalarTransportFoam
Description
Solves two coupled transport equations in a block-coupled manner
1) transport equation for a passive scalar
2) diffusion only
This resembles heat exchanging flow through a porous medium
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "fieldTypes.H"
#include "blockLduMatrices.H"
#include "blockLduSolvers.H"
#include "Time.H"
#include "fvMesh.H"
#include "blockVector2Matrix.H"
#include "tensor2.H"
#include "vector2Field.H"
#include "tensor2Field.H"
#include "blockMatrixTools.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
# include "setRootCase.H"
# include "createTime.H"
# include "createMesh.H"
# include "createFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nCalculating scalar transport\n" << endl;
# include "CourantNo.H"
for (runTime++; !runTime.end(); runTime++)
{
Info<< "Time = " << runTime.timeName() << nl << endl;
# include "readSIMPLEControls.H"
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
{
fvScalarMatrix TEqn
(
fvm::div(phi, T)
- fvm::laplacian(DT, T)
==
alpha*Ts
- fvm::Sp(alpha, T)
);
TEqn.relax();
fvScalarMatrix TsEqn
(
- fvm::laplacian(DTs, Ts)
==
alpha*T
- fvm::Sp(alpha, Ts)
);
TsEqn.relax();
// Prepare block system
BlockLduMatrix<vector2> blockM(mesh);
// Grab block diagonal and set it to zero
Field<tensor2>& d = blockM.diag().asSquare();
d = tensor2::zero;
// Grab linear off-diagonal and set it to zero
Field<vector2>& u = blockM.upper().asLinear();
Field<vector2>& l = blockM.lower().asLinear();
u = vector2::zero;
l = vector2::zero;
vector2Field blockX(mesh.nCells(), vector2::zero);
vector2Field blockB(mesh.nCells(), vector2::zero);
//- Inset equations into block Matrix
blockMatrixTools::insertEquation(0, TEqn, blockM, blockX, blockB);
blockMatrixTools::insertEquation(1, TsEqn, blockM, blockX, blockB);
//- Add off-diagonal terms and remove from Block source
forAll(d, i)
{
d[i](0,1) = -alpha.value()*mesh.V()[i];
d[i](1,0) = -alpha.value()*mesh.V()[i];
blockB[i][0] -= alpha.value()*blockX[i][1]*mesh.V()[i];
blockB[i][1] -= alpha.value()*blockX[i][0]*mesh.V()[i];
}
BlockSolverPerformance<vector2> solverPerf =
BlockLduSolver<vector2>::New
(
word("blockVar"),
blockM,
mesh.solver("blockVar")
)->solve(blockX, blockB);
solverPerf.print();
// Retrieve solution
blockMatrixTools::blockRetrieve(0, T.internalField(), blockX);
blockMatrixTools::blockRetrieve(1, Ts.internalField(), blockX);
T.correctBoundaryConditions();
Ts.correctBoundaryConditions();
}
runTime.write();
}
Info<< "End\n" << endl;
return(0);
}
// ************************************************************************* //

View file

@ -0,0 +1,247 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace blockMatrixTools
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class BlockType>
void blockInsert
(
const direction dir,
const scalarField& x,
Field<BlockType>& blockX
)
{
forAll (x, i)
{
blockX[i](dir) = x[i];
}
}
template<class BlockType>
void blockRetrieve
(
const direction dir,
scalarField& x,
const Field<BlockType>& blockX
)
{
forAll (x, i)
{
x[i] = blockX[i](dir);
}
}
template<class BlockType>
void insertDiagSource
(
const direction dir,
const fvScalarMatrix& m,
BlockLduMatrix<BlockType>& blockM,
Field<BlockType>& blockB
)
{
// Prepare the diagonal and source
scalarField diag = m.diag();
scalarField source = m.source();
// Add boundary source contribution
m.addBoundaryDiag(diag, 0);
m.addBoundarySource(source);
if (blockM.diag().activeType() == blockCoeffBase::UNALLOCATED)
{
blockM.diag().asScalar() = diag;
}
else if
(
blockM.diag().activeType() == blockCoeffBase::SCALAR
|| blockM.diag().activeType() == blockCoeffBase::LINEAR
)
{
typename CoeffField<BlockType>::linearTypeField& blockDiag =
blockM.diag().asLinear();
forAll (diag, i)
{
blockDiag[i](dir) = diag[i];
}
}
else if (blockM.diag().activeType() == blockCoeffBase::SQUARE)
{
typename CoeffField<BlockType>::squareTypeField& blockDiag =
blockM.diag().asSquare();
forAll (diag, i)
{
blockDiag[i](dir, dir) = diag[i];
}
}
blockInsert(dir, source, blockB);
}
template<class BlockType>
void insertUpperLower
(
const direction dir,
const fvScalarMatrix& m,
BlockLduMatrix<BlockType>& blockM
)
{
if (m.diagonal())
{
// Matrix for insertion is diagonal-only: nothing to do
return;
}
if (m.hasUpper())
{
const scalarField& upper = m.upper();
if (blockM.upper().activeType() == blockCoeffBase::UNALLOCATED)
{
blockM.upper().asScalar() = upper;
}
else if
(
blockM.upper().activeType() == blockCoeffBase::SCALAR
|| blockM.upper().activeType() == blockCoeffBase::LINEAR
)
{
typename CoeffField<BlockType>::linearTypeField& blockUpper =
blockM.upper().asLinear();
forAll (upper, i)
{
blockUpper[i](dir) = upper[i];
}
}
else if (blockM.upper().activeType() == blockCoeffBase::SQUARE)
{
typename CoeffField<BlockType>::squareTypeField& blockUpper =
blockM.upper().asSquare();
forAll (upper, i)
{
blockUpper[i](dir, dir) = upper[i];
}
}
}
else
{
FatalErrorIn
(
"void insertUpperLower\n"
"(\n"
" const direction dir,\n"
" const fvScalarMatrix& m,\n"
" BlockLduMatrix<BlockType>& blockM\n"
")"
) << "Error in matrix insertion: problem with block structure"
<< abort(FatalError);
}
if (m.symmetric() && blockM.symmetric())
{
Info<< "Both m and blockM are symmetric: inserting only upper triangle"
<< endl;
}
else
{
// Either scalar or block matrix is asymmetric: insert lower triangle
const scalarField& lower = m.lower();
if (blockM.lower().activeType() == blockCoeffBase::UNALLOCATED)
{
blockM.lower().asScalar() = lower;
}
else if
(
blockM.lower().activeType() == blockCoeffBase::SCALAR
|| blockM.lower().activeType() == blockCoeffBase::LINEAR
)
{
typename CoeffField<BlockType>::linearTypeField& blockLower =
blockM.lower().asLinear();
forAll (lower, i)
{
blockLower[i](dir) = lower[i];
}
}
else if (blockM.lower().activeType() == blockCoeffBase::SQUARE)
{
typename CoeffField<BlockType>::squareTypeField& blockLower =
blockM.lower().asSquare();
forAll (lower, i)
{
blockLower[i](dir, dir) = lower[i];
}
}
}
}
template<class BlockType>
void insertEquation
(
const direction dir,
const fvScalarMatrix& m,
BlockLduMatrix<BlockType>& blockM,
Field<BlockType>& blockX,
Field<BlockType>& blockB
)
{
insertDiagSource(dir, m, blockM, blockB);
insertUpperLower(dir, m, blockM);
blockInsert(dir, m.psi(), blockX);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace blockMatrixTools
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,130 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
InNamespace
Foam::
Description
Block matrix insertion and retrieval tools
SourceFiles
blockMatrixTools.C
\*---------------------------------------------------------------------------*/
#ifndef blockMatrixTools_H
#define blockMatrixTools_H
#include "blockLduMatrices.H"
#include "fvMatrices.H"
#include "surfaceFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Namespace blockMatrixTools functions Declaration
\*---------------------------------------------------------------------------*/
namespace blockMatrixTools
{
//- Insert field into block field
template<class BlockType>
void blockInsert
(
const direction dir,
const scalarField& x,
Field<BlockType>& blockX
);
//- Retrieve field from block field
template<class BlockType>
void blockRetrieve
(
const direction dir,
scalarField& x,
const Field<BlockType>& blockX
);
//- Insert matrix diagonal and source into the block system
template<class BlockType>
void insertDiagSource
(
const direction dir,
const fvScalarMatrix& m,
BlockLduMatrix<BlockType>& blockM,
Field<BlockType>& blockB
);
// Insert matrix into the block system
template<class Type, class BlockType>
void insertUpperLower
(
const direction dir,
const fvScalarMatrix& m,
BlockLduMatrix<BlockType>& blockM
);
// Insert matrix into the block system
template<class BlockType>
void insertEquation
(
const direction dir,
const fvScalarMatrix& m,
BlockLduMatrix<BlockType>& blockM,
Field<BlockType>& blockX,
Field<BlockType>& blockB
);
// Update coupling of block system
// Subtracts the block-coefficient coupling as specified by the user
// from the source, leaving the implicit update given by linearisation
template<class BlockType>
void updateCoupling
(
BlockLduMatrix<BlockType>& blockM,
Field<BlockType>& x,
Field<BlockType>& b
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "blockMatrixTools.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,50 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
Block matrix member static data members
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
\*---------------------------------------------------------------------------*/
#include "blockVector2Matrix.H"
#include "vector2.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineNamedTemplateTypeNameAndDebug(blockVector2Matrix, 0);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockLduMatrix
Description
Typedefs for block matrices
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
\*---------------------------------------------------------------------------*/
#ifndef blockVector2Matrices_H
#define blockVector2Matrices_H
#include "blockLduMatrices.H"
#include "vector2.H"
#include "ExpandTensorNField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef BlockLduMatrix<vector2> blockVector2Matrix;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,128 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#include "vector2Field.H"
#include "tensor2Field.H"
#include "ExpandTensorN.H"
#include "ExpandTensorNField.H"
#include "blockLduMatrices.H"
#include "addToRunTimeSelectionTable.H"
#include "blockLduPrecons.H"
#include "BlockNoPrecon.H"
#include "blockDiagonalPrecons.H"
#include "blockGaussSeidelPrecons.H"
#include "BlockCholeskyPrecon.H"
#include "blockLduSmoothers.H"
#include "blockGaussSeidelSmoothers.H"
#include "BlockILUSmoother.H"
#include "blockLduSolvers.H"
#include "BlockDiagonalSolver.H"
#include "BlockBiCGStabSolver.H"
#include "BlockCGSolver.H"
#include "BlockGaussSeidelSolver.H"
#include "BlockGMRESSolver.H"
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// Preconditioners
typedef BlockLduPrecon<vector2> blockVector2Precon;
defineNamedTemplateTypeNameAndDebug(blockVector2Precon, 0);
defineTemplateRunTimeSelectionTable(blockVector2Precon, dictionary);
typedef BlockNoPrecon<vector2> blockNoPreconVector2;
makeBlockPrecon(blockVector2Precon, blockNoPreconVector2);
typedef BlockDiagonalPrecon<vector2> blockDiagonalPreconVector2;
makeBlockPrecon(blockVector2Precon, blockDiagonalPreconVector2);
typedef BlockGaussSeidelPrecon<vector2> blockGaussSeidelPreconVector2;
makeBlockPrecon(blockVector2Precon, blockGaussSeidelPreconVector2);
typedef BlockCholeskyPrecon<vector2> blockCholeskyPreconVector2;
makeBlockPrecon(blockVector2Precon, blockCholeskyPreconVector2);
// Smoothers
typedef BlockLduSmoother<vector2> blockVector2Smoother;
defineNamedTemplateTypeNameAndDebug(blockVector2Smoother, 0);
defineTemplateRunTimeSelectionTable(blockVector2Smoother, dictionary);
typedef BlockGaussSeidelSmoother<vector2> blockGaussSeidelSmootherVector2;
makeBlockSmoother(blockVector2Smoother, blockGaussSeidelSmootherVector2);
typedef BlockILUSmoother<vector2> blockILUSmootherVector2;
makeBlockSmoother(blockVector2Smoother, blockILUSmootherVector2);
// Solvers
typedef BlockLduSolver<vector2> blockVector2Solver;
defineNamedTemplateTypeNameAndDebug(blockVector2Solver, 0);
defineTemplateRunTimeSelectionTable
(
blockVector2Solver,
symMatrix
);
defineTemplateRunTimeSelectionTable
(
blockVector2Solver,
asymMatrix
);
typedef BlockDiagonalSolver<vector2> blockDiagonalSolverVector2;
defineNamedTemplateTypeNameAndDebug(blockDiagonalSolverVector2, 0);
typedef BlockBiCGStabSolver<vector2> blockBiCGStabSolverVector2;
makeBlockSolverTypeName(blockBiCGStabSolverVector2);
addSolverToBlockMatrix(Vector2, blockBiCGStabSolverVector2, symMatrix);
addSolverToBlockMatrix(Vector2, blockBiCGStabSolverVector2, asymMatrix);
typedef BlockCGSolver<vector2> blockCGSolverVector2;
makeBlockSolverTypeName(blockCGSolverVector2);
addSolverToBlockMatrix(Vector2, blockCGSolverVector2, symMatrix);
typedef BlockGaussSeidelSolver<vector2> blockGaussSeidelSolverVector2;
makeBlockSolverTypeName(blockGaussSeidelSolverVector2);
addSolverToBlockMatrix(Vector2, blockGaussSeidelSolverVector2, symMatrix);
typedef BlockGMRESSolver<vector2> blockGMRESSolverVector2;
makeBlockSolverTypeName(blockGMRESSolverVector2);
addSolverToBlockMatrix(Vector2, blockGMRESSolverVector2, symMatrix);
addSolverToBlockMatrix(Vector2, blockGMRESSolverVector2, asymMatrix);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,111 @@
Info<< "Reading field T\n" << endl;
volScalarField T
(
IOobject
(
"T",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading field Ts\n" << endl;
volScalarField Ts
(
IOobject
(
"Ts",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
// Removed comparison with the reference field. HJ, 17/Jun/2010
#if (0)
Info<< "Reading field Tref\n" << endl;
volScalarField Tref
(
IOobject
(
"Tref",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading field Tsref\n" << endl;
volScalarField Tsref
(
IOobject
(
"Tsref",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
#endif
Info<< "Reading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading transportProperties\n" << endl;
IOdictionary transportProperties
(
IOobject
(
"transportProperties",
runTime.constant(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
Info<< "Reading diffusivity D\n" << endl;
dimensionedScalar DT
(
transportProperties.lookup("DT")
);
dimensionedScalar DTs
(
transportProperties.lookup("DTs")
);
dimensionedScalar alpha
(
transportProperties.lookup("alpha")
);
# include "createPhi.H"

View file

@ -0,0 +1,64 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Type
tensor2
Description
TensorN of 2 scalars.
SourceFiles
tensor2.C
\*---------------------------------------------------------------------------*/
#ifndef tensor2_H
#define tensor2_H
#include "TensorN.H"
#include "contiguous.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef TensorN<scalar, 2> tensor2;
//- Specify data associated with tensor2 type is contiguous
template<>
inline bool contiguous<tensor2>() {return true;}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "tensor2Field.H"
#include "transformField.H"
#define TEMPLATE
#include "FieldFunctionsM.C"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * //
UNARY_FUNCTION(tensor2, tensor2, inv)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "undefFieldFunctionsM.H"
// ************************************************************************* //

View file

@ -0,0 +1,66 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
tensor2Field
Description
Specialisation of Field<T> for tensor2.
SourceFiles
tensor2Field.C
\*---------------------------------------------------------------------------*/
#ifndef tensor2Field_H
#define tensor2Field_H
#include "scalarField.H"
#include "tensor2.H"
#define TEMPLATE
#include "FieldFunctionsM.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef Field<tensor2> tensor2Field;
UNARY_FUNCTION(tensor2, tensor2, inv)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "undefFieldFunctionsM.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,128 @@
// The FOAM Project // File: testCoeffField.C
/*
-------------------------------------------------------------------------------
========= | Application
\\ / |
\\ / | Name: testCoeffField
\\ / | Family: Utility
\\/ |
F ield | FOAM version: 2.2
O peration |
A and | Copyright (C) 1991-2003 Nabla Ltd.
M anipulation | All Rights Reserved.
-------------------------------------------------------------------------------
DESCRIPTION
Test coeff field and block matrix
AUTHOR
Hrvoje Jasak
-------------------------------------------------------------------------------
*/
#include "argList.H"
#include "fieldTypes.H"
#include "blockLduMatrices.H"
#include "blockLduSolvers.H"
#include "Time.H"
#include "fvMesh.H"
#include "blockVector2Matrix.H"
#include "tensor2.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
# include "setRootCase.H"
# include "createTime.H"
# include "createMesh.H"
blockScalarMatrix scalarMatrix(mesh);
blockVectorMatrix blockMatrix(mesh);
const label diagSize = mesh.lduAddr().size();
const label ulSize = mesh.lduAddr().lowerAddr().size();
const scalar diagCoeff = -2.0;
// const scalar diagCoeff = -4.0;
// Info << "Doing diagonal matrix" << endl;
blockMatrix.upper() = scalarField(ulSize, 1.0);
scalarField dScalar(diagSize, diagCoeff);
dScalar[0] = -10000;
dScalar[diagSize - 1] = -10000;
blockMatrix.diag() = dScalar;
// tensorField dTensor
// (
// diagSize,
// tensor
// (
// diagCoeff, 0.0, 0.0,
// 0.0, diagCoeff, 0.0,
// 0.0, 0.0, -1.0
// )
// );
// dTensor[0] =
// tensor
// (
// -10000.0, 0.0, 0.0,
// 0.0, -10000.0, 0.0,
// 0.0, 0.0, -1.0
// );
// dTensor[diagSize - 1] =
// tensor
// (
// -1.0, 0.0, 0.0,
// 0.0, -1.0, 0.0,
// 0.0, 0.0, -1.0
// );
// blockMatrix.diag() = dTensor;
vectorField psi(diagSize, vector(0, 0, 0));
vectorField source(diagSize, vector(0, 0, 0));
source[0] = vector(0, 0, 0);
source[diagSize - 1] = vector(10000, 0, 0);
// psi[0] = vector(0, 0, 0);
// psi[diagSize - 1] = vector(-1, 0, 0);
BlockSolverPerformance<vector> solverPerf =
blockVectorSolver::New
(
"HrvsVar",
blockMatrix,
mesh.solver("HrvsVar")
)->solve(psi, source);
Info << "Psi: " << psi << endl;
// Info << "Psi: " << psi.component(vector::X) << endl;
// Large block matrix
BlockLduMatrix<vector2> vector2Matrix(mesh);
vector2Matrix.diag().asScalar() =
scalarField(vector2Matrix.diag().size(), 1);
vector2Matrix.diag() +=
Field<vector2>(vector2Matrix.diag().size(), vector2::one);
vector2Matrix.upper() =
Field<tensor2>(vector2Matrix.upper().size(), tensor2::one);
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View file

@ -0,0 +1,66 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Type
vector2
Description
vector2 obtained from generic VectorN
SourceFiles
vector2.C
\*---------------------------------------------------------------------------*/
#ifndef vector2_H
#define vector2_H
#include "scalar.H"
#include "VectorN.H"
#include "contiguous.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef VectorN<scalar, 2> vector2;
//- Specify data associated with vector2 type is contiguous
template<>
inline bool contiguous<vector2>() {return true;}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,64 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
vector2Field
Description
Specialisation of Field<T> for vector2.
SourceFiles
vector2Field.C
\*---------------------------------------------------------------------------*/
#ifndef vector2Field_H
#define vector2Field_H
#include "scalarField.H"
#include "vector2.H"
#define TEMPLATE
#include "FieldFunctionsM.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef Field<vector2> vector2Field;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "undefFieldFunctionsM.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -36,6 +36,8 @@ wmake libso finiteVolume
wmake libso finiteArea wmake libso finiteArea
wmake libso lduSolvers wmake libso lduSolvers
wmake libso blockMatrix
wmake libso dynamicMesh wmake libso dynamicMesh
(cd tetDecompositionFiniteElement ; Allwmake) (cd tetDecompositionFiniteElement ; Allwmake)

View file

@ -0,0 +1,483 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
Generic block coefficient type. Used in BlockLduMatrix. HJ, 2/Jan/2006
\*---------------------------------------------------------------------------*/
#include "demandDrivenData.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
typename Foam::BlockCoeff<Type>::scalarType&
Foam::BlockCoeff<Type>::toScalar()
{
if (!scalarCoeffPtr_)
{
// Debug check: demotion
if (linearCoeffPtr_ || squareCoeffPtr_)
{
FatalErrorIn
(
"BlockCoeff<Type>::scalarType& "
"BlockCoeff<Type>::toScalar()"
) << "Detected demotion to scalar. Probably an error"
<< abort(FatalError);
}
scalarCoeffPtr_ = new scalarType(pTraits<scalarType>::zero);
}
return *scalarCoeffPtr_;
}
template<class Type>
typename Foam::BlockCoeff<Type>::linearType&
Foam::BlockCoeff<Type>::toLinear()
{
if (!linearCoeffPtr_)
{
// Debug check: demotion
if (squareCoeffPtr_)
{
FatalErrorIn
(
"BlockCoeff<Type>::linearType& "
"BlockCoeff<Type>::toLinear()"
) << "Detected demotion to linear. Probably an error"
<< abort(FatalError);
}
linearCoeffPtr_ = new linearType(pTraits<linearType>::zero);
// If scalar is active, promote to linear
if (scalarCoeffPtr_)
{
*linearCoeffPtr_ = (*scalarCoeffPtr_)*pTraits<linearType>::one;
deleteDemandDrivenData(scalarCoeffPtr_);
}
}
return *linearCoeffPtr_;
}
template<class Type>
typename Foam::BlockCoeff<Type>::squareType&
Foam::BlockCoeff<Type>::toSquare()
{
if (!squareCoeffPtr_)
{
squareCoeffPtr_ = new squareType(pTraits<squareType>::zero);
// If scalar is active, promote to square
if (scalarCoeffPtr_)
{
expandScalar(*squareCoeffPtr_, *scalarCoeffPtr_);
deleteDemandDrivenData(scalarCoeffPtr_);
}
// If linear is active, promote to square
if (linearCoeffPtr_)
{
expandLinear(*squareCoeffPtr_, *linearCoeffPtr_);
deleteDemandDrivenData(linearCoeffPtr_);
}
}
return *squareCoeffPtr_;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::BlockCoeff<Type>::BlockCoeff()
:
scalarCoeffPtr_(NULL),
linearCoeffPtr_(NULL),
squareCoeffPtr_(NULL)
{}
template<class Type>
Foam::BlockCoeff<Type>::BlockCoeff(const BlockCoeff<Type>& f)
:
scalarCoeffPtr_(NULL),
linearCoeffPtr_(NULL),
squareCoeffPtr_(NULL)
{
if (f.scalarCoeffPtr_)
{
scalarCoeffPtr_ = new scalarType(*(f.scalarCoeffPtr_));
}
else if (f.linearCoeffPtr_)
{
linearCoeffPtr_ = new linearType(*(f.linearCoeffPtr_));
}
else if (f.squareCoeffPtr_)
{
squareCoeffPtr_ = new squareType(*(f.squareCoeffPtr_));
}
}
template<class Type>
Foam::BlockCoeff<Type>::BlockCoeff(Istream& is)
:
scalarCoeffPtr_(NULL),
linearCoeffPtr_(NULL),
squareCoeffPtr_(NULL)
{
// Read keyword and pick up allocated field
word key(is);
if
(
key
== blockCoeffBase::activeLevelNames_[blockCoeffBase::UNALLOCATED]
)
{
}
else if
(
key
== blockCoeffBase::activeLevelNames_[blockCoeffBase::SCALAR]
)
{
scalarCoeffPtr_ = new scalarType(readScalar(is));
}
else if
(
key
== blockCoeffBase::activeLevelNames_[blockCoeffBase::LINEAR]
)
{
linearCoeffPtr_ = new linearType(is);
}
else if
(
key
== blockCoeffBase::activeLevelNames_[blockCoeffBase::SQUARE]
)
{
squareCoeffPtr_ = new squareType(is);
}
else
{
FatalIOErrorIn
(
"BlockCoeff<Type>::BlockCoeff(Istream& is)",
is
) << "invalid keyword while reading: " << key
<< exit(FatalIOError);
}
}
template<class Type>
Foam::BlockCoeff<Type> Foam::BlockCoeff<Type>::clone() const
{
return BlockCoeff<Type>(*this);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class Type>
Foam::BlockCoeff<Type>::~BlockCoeff()
{
this->clear();
}
template<class Type>
inline void Foam::BlockCoeff<Type>::clear()
{
deleteDemandDrivenData(scalarCoeffPtr_);
deleteDemandDrivenData(linearCoeffPtr_);
deleteDemandDrivenData(squareCoeffPtr_);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::blockCoeffBase::activeLevel
Foam::BlockCoeff<Type>::activeType() const
{
if (scalarCoeffPtr_)
{
return blockCoeffBase::SCALAR;
}
else if (linearCoeffPtr_)
{
return blockCoeffBase::LINEAR;
}
else if (squareCoeffPtr_)
{
return blockCoeffBase::SQUARE;
}
else
{
return blockCoeffBase::UNALLOCATED;
}
}
template<class Type>
void Foam::BlockCoeff<Type>::checkActive() const
{
label nActive = 0;
if (scalarCoeffPtr_) nActive++;
if (linearCoeffPtr_) nActive++;
if (squareCoeffPtr_) nActive++;
if (nActive > 1)
{
FatalErrorIn("void Foam::BlockCoeff<Type>::checkActive() const")
<< "Activation/deactivation error. nActive = " << nActive
<< abort(FatalError);
}
}
template<class Type>
const typename Foam::BlockCoeff<Type>::scalarType&
Foam::BlockCoeff<Type>::asScalar() const
{
if (!scalarCoeffPtr_)
{
FatalErrorIn
(
"BlockCoeff<Type>::scalarType& "
"BlockCoeff<Type>::asScalar()"
) << "Requested scalar but active type is: "
<< blockCoeffBase::activeLevelNames_[this->activeType()]
<< ". This is not allowed."
<< abort(FatalError);
}
return *scalarCoeffPtr_;
}
template<class Type>
const typename Foam::BlockCoeff<Type>::linearType&
Foam::BlockCoeff<Type>::asLinear() const
{
if (!linearCoeffPtr_)
{
FatalErrorIn
(
"BlockCoeff<Type>::linearType& "
"BlockCoeff<Type>::asLinear()"
) << "Requested linear but active type is: "
<< blockCoeffBase::activeLevelNames_[this->activeType()]
<< ". This is not allowed."
<< abort(FatalError);
}
return *linearCoeffPtr_;
}
template<class Type>
const typename Foam::BlockCoeff<Type>::squareType&
Foam::BlockCoeff<Type>::asSquare() const
{
if (!squareCoeffPtr_)
{
FatalErrorIn
(
"BlockCoeff<Type>::squareType& "
"BlockCoeff<Type>::asSquare()"
) << "Requested square but active type is: "
<< blockCoeffBase::activeLevelNames_[this->activeType()]
<< ". This is not allowed."
<< abort(FatalError);
}
return *squareCoeffPtr_;
}
template<class Type>
typename Foam::BlockCoeff<Type>::scalarType&
Foam::BlockCoeff<Type>::asScalar()
{
if (linearCoeffPtr_ || squareCoeffPtr_)
{
FatalErrorIn
(
"BlockCoeff<Type>::scalarType& "
"BlockCoeff<Type>::asScalar()"
) << "Requested scalar but active type is: "
<< blockCoeffBase::activeLevelNames_[this->activeType()]
<< ". This is not allowed."
<< abort(FatalError);
}
if (!scalarCoeffPtr_)
{
return this->toScalar();
}
return *scalarCoeffPtr_;
}
template<class Type>
typename Foam::BlockCoeff<Type>::linearType&
Foam::BlockCoeff<Type>::asLinear()
{
if (squareCoeffPtr_)
{
FatalErrorIn
(
"BlockCoeff<Type>::linearType& "
"BlockCoeff<Type>::asLinear()"
) << "Requested linear but active type is: "
<< blockCoeffBase::activeLevelNames_[this->activeType()]
<< ". This is not allowed."
<< abort(FatalError);
}
if (!linearCoeffPtr_)
{
return this->toLinear();
}
return *linearCoeffPtr_;
}
template<class Type>
typename Foam::BlockCoeff<Type>::squareType&
Foam::BlockCoeff<Type>::asSquare()
{
if (!squareCoeffPtr_)
{
return this->toSquare();
}
return *squareCoeffPtr_;
}
template<class Type>
typename Foam::BlockCoeff<Type>::scalarType
Foam::BlockCoeff<Type>::component(const direction dir) const
{
if (scalarCoeffPtr_)
{
return *scalarCoeffPtr_;
}
else if (linearCoeffPtr_)
{
return linearCoeffPtr_->component(dir);
}
else if (squareCoeffPtr_)
{
return contractLinear
(
*squareCoeffPtr_
)().component(dir);
}
else
{
FatalErrorIn
(
"tmp<BlockCoeff<Type>::scalarType>"
"BlockCoeff<Type>::component(const direction dir) const"
) << " not allocated."
<< abort(FatalError);
}
// Dummy return to keep compiler happy
return *scalarCoeffPtr_;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Type>
void Foam::BlockCoeff<Type>::operator=(const BlockCoeff<Type>& f)
{
if (this == &f)
{
FatalErrorIn("BlockCoeff<Type>::operator=(const BlockCoeff<Type>&)")
<< "attempted assignment to self"
<< abort(FatalError);
}
if (f.scalarCoeffPtr_)
{
this->toScalar() = *(f.scalarCoeffPtr_);
}
else if (f.linearCoeffPtr_)
{
this->toLinear() = *(f.linearCoeffPtr_);
}
else if (f.squareCoeffPtr_)
{
this->toSquare() = *(f.squareCoeffPtr_);
}
else
{
// Not allocated - do nothing
}
}
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
template<class Type>
Foam::Ostream& Foam::operator<<(Ostream& os, const BlockCoeff<Type>& f)
{
// Write active type
os << blockCoeffBase::activeLevelNames_[f.activeType()] << nl;
if (f.scalarCoeffPtr_)
{
os << *(f.scalarCoeffPtr_);
}
else if (f.linearCoeffPtr_)
{
os << *(f.linearCoeffPtr_);
}
else if (f.squareCoeffPtr_)
{
os << *(f.squareCoeffPtr_);
}
return os;
}
// ************************************************************************* //

View file

@ -0,0 +1,341 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
blockCoeff
Description
Block coefficient combines a scalar, linear and square coefficient
for different levels of coupling
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
\*---------------------------------------------------------------------------*/
#ifndef BlockCoeff_H
#define BlockCoeff_H
#include "blockCoeffBase.H"
#include "expandTensor.H"
#include "Field.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * Forward declaration of template friend fuctions * * * * * * * //
template<class Type>
class BlockCoeff;
template<class Type>
Ostream& operator<<(Ostream&, const BlockCoeff<Type>&);
/*---------------------------------------------------------------------------*\
Class BlockCoeff Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class BlockCoeff
:
public blockCoeffBase
{
public:
// Public data types
//- Component type
typedef Type xType;
typedef Field<xType> xTypeField;
//- Coefficient type
typedef typename pTraits<Type>::cmptType scalarType;
typedef Type linearType;
typedef typename outerProduct<Type, Type>::type squareType;
//- Field type
typedef Field<scalarType> scalarTypeField;
typedef Field<linearType> linearTypeField;
typedef Field<squareType> squareTypeField;
//- Multiplication trait
class multiply
{
public:
multiply() {}
// Coefficient times type multiplication
Type operator()(const scalarType& c, const Type& x) const
{
return c*x;
}
Type operator()(const linearType& c, const Type& x) const
{
return cmptMultiply(c, x);
}
Type operator()(const squareType& c, const Type& x) const
{
return (c & x);
}
Type operator()(const BlockCoeff<Type>& c, const Type& x) const
{
if (c.scalarCoeffPtr_)
{
return operator()(*c.scalarCoeffPtr_, x);
}
else if (c.linearCoeffPtr_)
{
return operator()(*c.linearCoeffPtr_, x);
}
else if (c.squareCoeffPtr_)
{
return operator()(*c.squareCoeffPtr_, x);
}
else
{
return pTraits<Type>::zero;
}
}
// Transpose functions
scalarType transpose(const scalarType& c) const
{
return c;
}
linearType transpose(const linearType& c) const
{
return c;
}
squareType transpose(const squareType& c) const
{
return c.T();
}
// Inverse functions
scalarType inverse(const scalarType& c) const
{
return 1.0/c;
}
linearType inverse(const linearType& c) const
{
return cmptDivide(pTraits<linearType>::one, c);
}
squareType inverse(const squareType& c) const
{
return inv(c);
}
// Triple product of coefficients
scalarType tripleProduct
(
const scalarType& a,
const scalarType& b,
const scalarType& c
) const
{
return a*c/b;
}
linearType tripleProduct
(
const scalarType& a,
const linearType& b,
const scalarType& c
) const
{
return a*c*inverse(b);
}
linearType tripleProduct
(
const linearType& a,
const linearType& b,
const linearType& c
) const
{
return cmptDivide(cmptMultiply(a, c), b);
}
squareType tripleProduct
(
const scalarType& a,
const squareType& b,
const scalarType& c
) const
{
return a*c*inv(b);
}
squareType tripleProduct
(
const linearType& a,
const squareType& b,
const linearType& c
) const
{
squareType result;
linearType sac = cmptMultiply(a, c);
expandLinear(result, sac);
return result & inv(b);
}
squareType tripleProduct
(
const squareType& a,
const squareType& b,
const squareType& c
) const
{
return (a & inv(b)) & c;
}
};
private:
// Private data
//- Scalar coefficient
mutable scalarType* scalarCoeffPtr_;
//- Linear coefficient
mutable linearType* linearCoeffPtr_;
//- Square coefficient
mutable squareType* squareCoeffPtr_;
// Private Member Functions
//- Promote to scalar
scalarType& toScalar();
//- Promote to linear
linearType& toLinear();
//- Promote to square
squareType& toSquare();
public:
// Constructors
//- Construct null
explicit BlockCoeff();
//- Construct as copy
BlockCoeff(const BlockCoeff<Type>&);
//- Construct from Istream
BlockCoeff(Istream&);
//- Clone
BlockCoeff<Type> clone() const;
// Destructor
~BlockCoeff();
//- Clear data
void clear();
// Member functions
//- Return active type
blockCoeffBase::activeLevel activeType() const;
//- Check pointers: only one type should be active (debug only)
void checkActive() const;
// Return as typed. Fails when asked for the incorrect type
//- Return as scalar
const scalarType& asScalar() const;
scalarType& asScalar();
//- Return as linear
const linearType& asLinear() const;
linearType& asLinear();
//- Return as square
const squareType& asSquare() const;
squareType& asSquare();
//- Return component
scalarType component(const direction) const;
// Member operators
void operator=(const BlockCoeff<Type>&);
// IOstream operators
friend Ostream& operator<< <Type>
(
Ostream&,
const BlockCoeff<Type>&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "BlockCoeff.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,372 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#include "demandDrivenData.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
typename Foam::DecoupledBlockCoeff<Type>::scalarType&
Foam::DecoupledBlockCoeff<Type>::toScalar()
{
if (!scalarCoeffPtr_)
{
// Debug check: demotion
if (linearCoeffPtr_)
{
FatalErrorIn
(
"DecoupledBlockCoeff<Type>::scalarType& "
"DecoupledBlockCoeff<Type>::toScalar()"
) << "Detected demotion to scalar. Probably an error"
<< abort(FatalError);
}
scalarCoeffPtr_ = new scalarType(pTraits<scalarType>::zero);
}
return *scalarCoeffPtr_;
}
template<class Type>
typename Foam::DecoupledBlockCoeff<Type>::linearType&
Foam::DecoupledBlockCoeff<Type>::toLinear()
{
if (!linearCoeffPtr_)
{
linearCoeffPtr_ = new linearType(pTraits<linearType>::zero);
// If scalar is active, promote to linear
if (scalarCoeffPtr_)
{
*linearCoeffPtr_ = (*scalarCoeffPtr_)*pTraits<linearType>::one;
deleteDemandDrivenData(scalarCoeffPtr_);
}
}
return *linearCoeffPtr_;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::DecoupledBlockCoeff<Type>::DecoupledBlockCoeff()
:
scalarCoeffPtr_(NULL),
linearCoeffPtr_(NULL)
{}
template<class Type>
Foam::DecoupledBlockCoeff<Type>::DecoupledBlockCoeff
(
const DecoupledBlockCoeff<Type>& f
)
:
scalarCoeffPtr_(NULL),
linearCoeffPtr_(NULL)
{
if (f.scalarCoeffPtr_)
{
scalarCoeffPtr_ = new scalarType(*(f.scalarCoeffPtr_));
}
else if (f.linearCoeffPtr_)
{
linearCoeffPtr_ = new linearType(*(f.linearCoeffPtr_));
}
}
template<class Type>
Foam::DecoupledBlockCoeff<Type>::DecoupledBlockCoeff(Istream& is)
:
scalarCoeffPtr_(NULL),
linearCoeffPtr_(NULL)
{
// Read keyword and pick up allocated field
word key(is);
if
(
key
== blockCoeffBase::activeLevelNames_[blockCoeffBase::UNALLOCATED]
)
{
}
else if
(
key
== blockCoeffBase::activeLevelNames_[blockCoeffBase::SCALAR]
)
{
scalarCoeffPtr_ = new scalarType(readScalar(is));
}
else if
(
key
== blockCoeffBase::activeLevelNames_[blockCoeffBase::LINEAR]
)
{
linearCoeffPtr_ = new linearType(is);
}
else
{
FatalIOErrorIn
(
"DecoupledBlockCoeff<Type>::DecoupledBlockCoeff(Istream& is)",
is
) << "invalid keyword while reading: " << key
<< exit(FatalIOError);
}
}
template<class Type>
Foam::DecoupledBlockCoeff<Type> Foam::DecoupledBlockCoeff<Type>::clone() const
{
return DecoupledBlockCoeff<Type>(*this);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class Type>
Foam::DecoupledBlockCoeff<Type>::~DecoupledBlockCoeff()
{
this->clear();
}
template<class Type>
void Foam::DecoupledBlockCoeff<Type>::clear()
{
deleteDemandDrivenData(scalarCoeffPtr_);
deleteDemandDrivenData(linearCoeffPtr_);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::blockCoeffBase::activeLevel
Foam::DecoupledBlockCoeff<Type>::activeType() const
{
if (scalarCoeffPtr_)
{
return blockCoeffBase::SCALAR;
}
else if (linearCoeffPtr_)
{
return blockCoeffBase::LINEAR;
}
else
{
return blockCoeffBase::UNALLOCATED;
}
}
template<class Type>
void Foam::DecoupledBlockCoeff<Type>::checkActive() const
{
label nActive = 0;
if (scalarCoeffPtr_) nActive++;
if (linearCoeffPtr_) nActive++;
if (nActive > 1)
{
FatalErrorIn
(
"void Foam::DecoupledBlockCoeff<Type>::checkActive() const"
) << "Activation/deactivation error. nActive = " << nActive
<< abort(FatalError);
}
}
template<class Type>
const typename Foam::DecoupledBlockCoeff<Type>::scalarType&
Foam::DecoupledBlockCoeff<Type>::asScalar() const
{
if (!scalarCoeffPtr_)
{
FatalErrorIn
(
"DecoupledBlockCoeff<Type>::scalarType& "
"DecoupledBlockCoeff<Type>::asScalar()"
) << "Requested scalar but active type is: "
<< blockCoeffBase::activeLevelNames_[this->activeType()]
<< ". This is not allowed."
<< abort(FatalError);
}
return *scalarCoeffPtr_;
}
template<class Type>
const typename Foam::DecoupledBlockCoeff<Type>::linearType&
Foam::DecoupledBlockCoeff<Type>::asLinear() const
{
if (!linearCoeffPtr_)
{
FatalErrorIn
(
"DecoupledBlockCoeff<Type>::linearType& "
"DecoupledBlockCoeff<Type>::asLinear()"
) << "Requested linear but active type is: "
<< blockCoeffBase::activeLevelNames_[this->activeType()]
<< ". This is not allowed."
<< abort(FatalError);
}
return *linearCoeffPtr_;
}
template<class Type>
typename Foam::DecoupledBlockCoeff<Type>::scalarType&
Foam::DecoupledBlockCoeff<Type>::asScalar()
{
if (linearCoeffPtr_)
{
FatalErrorIn
(
"DecoupledBlockCoeff<Type>::scalarType& "
"DecoupledBlockCoeff<Type>::asScalar()"
) << "Requested scalar but active type is: "
<< blockCoeffBase::activeLevelNames_[this->activeType()]
<< ". This is not allowed."
<< abort(FatalError);
}
if (!scalarCoeffPtr_)
{
return this->toScalar();
}
return *scalarCoeffPtr_;
}
template<class Type>
typename Foam::DecoupledBlockCoeff<Type>::linearType&
Foam::DecoupledBlockCoeff<Type>::asLinear()
{
if (!linearCoeffPtr_)
{
return this->toLinear();
}
return *linearCoeffPtr_;
}
template<class Type>
typename Foam::DecoupledBlockCoeff<Type>::scalarType
Foam::DecoupledBlockCoeff<Type>::component(const direction dir) const
{
if (scalarCoeffPtr_)
{
return *scalarCoeffPtr_;
}
else if (linearCoeffPtr_)
{
return linearCoeffPtr_->component(dir);
}
else
{
FatalErrorIn
(
"tmp<DecoupledBlockCoeff<Type>::scalarType>"
"DecoupledBlockCoeff<Type>::component(const direction dir) const"
) << " not allocated."
<< abort(FatalError);
}
// Dummy return to keep compiler happy
return *scalarCoeffPtr_;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Type>
void Foam::DecoupledBlockCoeff<Type>::operator=
(
const DecoupledBlockCoeff<Type>& f
)
{
if (this == &f)
{
FatalErrorIn
(
"DecoupledBlockCoeff<Type>::operator=("
"const DecoupledBlockCoeff<Type>&)"
) << "attempted assignment to self"
<< abort(FatalError);
}
if (f.scalarCoeffPtr_)
{
this->toScalar() = *(f.scalarCoeffPtr_);
}
else if (f.linearCoeffPtr_)
{
this->toLinear() = *(f.linearCoeffPtr_);
}
else
{
// Not allocated - do nothing
}
}
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
template<class Type>
Foam::Ostream& Foam::operator<<(Ostream& os, const DecoupledBlockCoeff<Type>& f)
{
// Write active type
os << blockCoeffBase::activeLevelNames_[f.activeType()] << nl;
if (f.scalarCoeffPtr_)
{
os << *(f.scalarCoeffPtr_);
}
else if (f.linearCoeffPtr_)
{
os << *(f.linearCoeffPtr_);
}
return os;
}
// ************************************************************************* //

View file

@ -0,0 +1,261 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockCoeff
Description
Template for the terminal decoupled class. It is designed to avoid
endless expansion of tensor order by excluding block coupling at the
terminal type level.
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
\*---------------------------------------------------------------------------*/
#ifndef DecoupledBlockCoeff_H
#define DecoupledBlockCoeff_H
#include "blockCoeffBase.H"
#include "Field.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * Forward declaration of template friend fuctions * * * * * * * //
template<class Type>
class DecoupledBlockCoeff;
template<class Type>
Ostream& operator<<(Ostream&, const DecoupledBlockCoeff<Type>&);
/*---------------------------------------------------------------------------*\
Class DecoupledBlockCoeff Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class DecoupledBlockCoeff
:
public blockCoeffBase
{
public:
// Public data types
//- Component type
typedef Type xType;
typedef Field<xType> xTypeField;
//- Coefficient type
typedef scalar scalarType;
typedef Type linearType;
//- Field type
typedef Field<scalarType> scalarTypeField;
typedef Field<linearType> linearTypeField;
//- Multiplication trait
class multiply
{
public:
multiply() {}
Type operator()(const scalarType& c, const Type& x) const
{
return c*x;
}
Type operator()(const linearType& c, const Type& x) const
{
return cmptMultiply(c, x);
}
Type operator()(const DecoupledBlockCoeff<Type>& c, const Type& x) const
{
if (c.scalarCoeffPtr_)
{
return operator()(*c.scalarCoeffPtr_, x);
}
else if (c.linearCoeffPtr_)
{
return operator()(*c.linearCoeffPtr_, x);
}
else
{
return pTraits<Type>::zero;
}
}
// Inverse functions
scalarType inverse(const scalarType& c) const
{
return 1.0/c;
}
linearType inverse(const linearType& c) const
{
return cmptDivide(pTraits<linearType>::one, c);
}
// Triple product of coefficients
scalarType tripleProduct
(
const scalarType& a,
const scalarType& b,
const scalarType& c
) const
{
return a*c/b;
}
linearType tripleProduct
(
const linearType& a,
const linearType& b,
const linearType& c
) const
{
return cmptDivide(cmptMultiply(a, c), b);
}
linearType tripleProduct
(
const scalarType& a,
const linearType& b,
const scalarType& c
) const
{
return a*c*inverse(b);
}
};
private:
// Private data
//- Scalar coefficient
mutable scalarType* scalarCoeffPtr_;
//- Linear coefficient
mutable linearType* linearCoeffPtr_;
// Private Member Functions
//- Promote to scalar
scalarType& toScalar();
//- Promote to linear
linearType& toLinear();
public:
// Constructors
//- Construct null
explicit DecoupledBlockCoeff();
//- Construct as copy
DecoupledBlockCoeff(const DecoupledBlockCoeff<Type>&);
//- Construct from Istream
DecoupledBlockCoeff(Istream&);
//- Clone
DecoupledBlockCoeff<Type> clone() const;
// Destructor
~DecoupledBlockCoeff();
//- Clear data
void clear();
// Member functions
//- Return active type
blockCoeffBase::activeLevel activeType() const;
//- Check pointers: only one type should be active (debug only)
void checkActive() const;
// Return as typed. Fails when asked for the incorrect type
//- Return as scalar
const scalarType& asScalar() const;
scalarType& asScalar();
//- Return as linear
const linearType& asLinear() const;
linearType& asLinear();
//- Return component
scalarType component(const direction) const;
// Member operators
void operator=(const DecoupledBlockCoeff<Type>&);
// IOstream operators
friend Ostream& operator<< <Type>
(
Ostream&,
const DecoupledBlockCoeff<Type>&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "DecoupledBlockCoeff.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,44 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#include "blockCoeffBase.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
template<>
const char* Foam::NamedEnum<Foam::blockCoeffBase::activeLevel, 4>::names[] =
{
"unallocated",
"scalar",
"linear",
"square"
};
const Foam::NamedEnum<Foam::blockCoeffBase::activeLevel, 4>
Foam::blockCoeffBase::activeLevelNames_;
// ************************************************************************* //

View file

@ -0,0 +1,81 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
blockCoeffBase
Description
Base block coefficient for templated block coefficient types.
Holds enumerations
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
\*---------------------------------------------------------------------------*/
#ifndef blockCoeffBase_H
#define blockCoeffBase_H
#include "NamedEnum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class blockCoeffBase Declaration
\*---------------------------------------------------------------------------*/
class blockCoeffBase
{
public:
// Public data types
//- Enumeration defining the active level
enum activeLevel
{
UNALLOCATED,
SCALAR,
LINEAR,
SQUARE
};
// Static member functions
//- Direction names
static const NamedEnum<activeLevel, 4> activeLevelNames_;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,106 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
blockCoeffs
Description
\*---------------------------------------------------------------------------*/
#ifndef blockCoeffs_H
#define blockCoeffs_H
#include "scalarBlockCoeff.H"
#include "sphericalTensorBlockCoeff.H"
#include "symmTensorBlockCoeff.H"
#include "tensorBlockCoeff.H"
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef BlockCoeff<scalar> scalarBlockCoeff;
typedef BlockCoeff<vector> vectorBlockCoeff;
typedef BlockCoeff<sphericalTensor> sphericalTensorBlockCoeff;
typedef BlockCoeff<symmTensor> symmTensorBlockCoeff;
typedef BlockCoeff<tensor> tensorBlockCoeff;
/* * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * */
template<class Type>
scalar sumMult
(
const Field<Type>& f1,
const Field<Type>& f2
)
{
Type result = pTraits<Type>::zero;
typename BlockCoeff<Type>::multiply mult;
for (register label i = 0; i < f1.size(); i++)
{
result += mult(f1[i], f2[i]);
}
return cmptSum(result);
}
template<class Type>
scalar gSumMult
(
const Field<Type>& f1,
const Field<Type>& f2
)
{
scalar SumProd = sumMult(f1, f2);
reduce(SumProd, sumOp<scalar>());
return SumProd;
}
template<>
inline scalar sumMult
(
const scalarField& f1,
const scalarField& f2
)
{
return sumProd(f1, f2);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,91 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#include "scalarBlockCoeff.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::BlockCoeff<Foam::scalar>::BlockCoeff()
:
scalarCoeff_(pTraits<scalar>::zero)
{}
Foam::BlockCoeff<Foam::scalar>::BlockCoeff(const BlockCoeff<scalar>& f)
:
scalarCoeff_(f.scalarCoeff_)
{}
Foam::BlockCoeff<Foam::scalar>::BlockCoeff(Istream& is)
:
scalarCoeff_(readScalar(is))
{}
Foam::BlockCoeff<Foam::scalar> Foam::BlockCoeff<Foam::scalar>::clone() const
{
return BlockCoeff<scalar>(*this);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::BlockCoeff<Foam::scalar>::~BlockCoeff()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::BlockCoeff<Foam::scalar>::operator=(const BlockCoeff<scalar>& f)
{
if (this == &f)
{
FatalErrorIn
(
"BlockCoeff<scalar>::operator=(const BlockCoeff<scalar>&)"
) << "attempted assignment to self"
<< abort(FatalError);
}
scalarCoeff_ = f.scalarCoeff_;
}
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const BlockCoeff<scalar>& f)
{
os << f.scalarCoeff_;
return os;
}
// ************************************************************************* //

View file

@ -0,0 +1,174 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockCoeff specialisation for terminal class.
Description
Specialisation of a block coefficient for a scalar: always a scalae.
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
\*---------------------------------------------------------------------------*/
#ifndef scalarBlockCoeff_H
#define scalarBlockCoeff_H
#include "BlockCoeff.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class BlockCoeff Declaration
\*---------------------------------------------------------------------------*/
template<>
class BlockCoeff<scalar>
:
public blockCoeffBase
{
public:
// Public data types
//- Component type
typedef scalar Type;
typedef Type xType;
//- Coefficient type
typedef scalar scalarType;
//- Multiplication trait
class multiply
{
public:
multiply() {}
Type operator()(const scalarType& c, const Type& x) const
{
return c*x;
}
Type operator()(const BlockCoeff<Type>& c, const Type& x) const
{
return c.asScalar()*x;
}
// Inverse functions
scalarType inverse(const scalarType& c) const
{
return 1.0/c;
}
// Triple product of coefficients
scalarType tripleProduct
(
const scalarType& a,
const scalarType& b,
const scalarType& c
) const
{
return a*c/b;
}
};
private:
// Private data
//- Scalar coefficient
scalar scalarCoeff_;
public:
// Constructors
//- Construct null
explicit BlockCoeff();
//- Construct as copy
BlockCoeff(const BlockCoeff<scalar>&);
//- Construct from Istream
BlockCoeff(Istream&);
//- Clone
BlockCoeff<scalar> clone() const;
// Destructor
~BlockCoeff();
// Member functions
//- Return as scalar
const scalar& asScalar() const
{
return scalarCoeff_;
}
scalar& asScalar()
{
return scalarCoeff_;
}
//- Return component
scalar component(const direction) const;
// Member operators
void operator=(const BlockCoeff<scalar>&);
// IOstream operators
friend Ostream& operator<<
(
Ostream&,
const BlockCoeff<scalar>&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,52 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#include "sphericalTensorBlockCoeff.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::BlockCoeff<Foam::sphericalTensor>::BlockCoeff()
:
DecoupledBlockCoeff<sphericalTensor>()
{}
Foam::BlockCoeff<Foam::sphericalTensor>::BlockCoeff
(
const BlockCoeff<sphericalTensor>& f
)
:
DecoupledBlockCoeff<sphericalTensor>(f)
{}
Foam::BlockCoeff<Foam::sphericalTensor>::BlockCoeff(Istream& is)
:
DecoupledBlockCoeff<sphericalTensor>(is)
{}
// ************************************************************************* //

View file

@ -0,0 +1,82 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockCoeff
Description
Template specialisation for the terminal class. It is designed to avoid
endless expansion of tensor order by excluding block coupling at the
terminal type level.
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
\*---------------------------------------------------------------------------*/
#ifndef sphericalTensorBlockCoeff_H
#define sphericalTensorBlockCoeff_H
#include "BlockCoeff.H"
#include "DecoupledBlockCoeff.H"
#include "sphericalTensor.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class BlockCoeff Declaration
\*---------------------------------------------------------------------------*/
template<>
class BlockCoeff<sphericalTensor>
:
public DecoupledBlockCoeff<sphericalTensor>
{
public:
// Constructors
//- Construct null
explicit BlockCoeff();
//- Construct as copy
BlockCoeff(const BlockCoeff<sphericalTensor>&);
//- Construct from Istream
BlockCoeff(Istream&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,52 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#include "symmTensorBlockCoeff.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::BlockCoeff<Foam::symmTensor>::BlockCoeff()
:
DecoupledBlockCoeff<symmTensor>()
{}
Foam::BlockCoeff<Foam::symmTensor>::BlockCoeff
(
const BlockCoeff<symmTensor>& f
)
:
DecoupledBlockCoeff<symmTensor>(f)
{}
Foam::BlockCoeff<Foam::symmTensor>::BlockCoeff(Istream& is)
:
DecoupledBlockCoeff<symmTensor>(is)
{}
// ************************************************************************* //

View file

@ -0,0 +1,82 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockCoeff
Description
Template specialisation for the terminal class. It is designed to avoid
endless expansion of tensor order by excluding block coupling at the
terminal type level.
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
\*---------------------------------------------------------------------------*/
#ifndef symmTensorBlockCoeff_H
#define symmTensorBlockCoeff_H
#include "BlockCoeff.H"
#include "DecoupledBlockCoeff.H"
#include "symmTensor.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class BlockCoeff Declaration
\*---------------------------------------------------------------------------*/
template<>
class BlockCoeff<symmTensor>
:
public DecoupledBlockCoeff<symmTensor>
{
public:
// Constructors
//- Construct null
explicit BlockCoeff();
//- Construct as copy
BlockCoeff(const BlockCoeff<symmTensor>&);
//- Construct from Istream
BlockCoeff(Istream&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#include "tensorBlockCoeff.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::BlockCoeff<Foam::tensor>::BlockCoeff()
:
DecoupledBlockCoeff<tensor>()
{}
Foam::BlockCoeff<Foam::tensor>::BlockCoeff(const BlockCoeff<tensor>& f)
:
DecoupledBlockCoeff<tensor>(f)
{}
Foam::BlockCoeff<Foam::tensor>::BlockCoeff(Istream& is)
:
DecoupledBlockCoeff<tensor>(is)
{}
// ************************************************************************* //

View file

@ -0,0 +1,82 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockCoeff
Description
Template specialisation for the terminal class. It is designed to avoid
endless expansion of tensor order by excluding block coupling at the
terminal type level.
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
\*---------------------------------------------------------------------------*/
#ifndef tensorBlockCoeff_H
#define tensorBlockCoeff_H
#include "BlockCoeff.H"
#include "DecoupledBlockCoeff.H"
#include "tensor.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class BlockCoeff Declaration
\*---------------------------------------------------------------------------*/
template<>
class BlockCoeff<tensor>
:
public DecoupledBlockCoeff<tensor>
{
public:
// Constructors
//- Construct null
explicit BlockCoeff();
//- Construct as copy
BlockCoeff(const BlockCoeff<tensor>&);
//- Construct from Istream
BlockCoeff(Istream&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,307 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
A storage mechanism which allows setting of the fixed value and
consequently recovering the equation for a single row of the matrix as
well as the source. The equation is taken out of the matrix using a
variant of compact matrix storage mechanism.
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "BlockConstraint.H"
#include "demandDrivenData.H"
#include "BlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
template<class Type>
BlockConstraint<Type>::BlockConstraint
(
const label row,
const Type value,
const Type& fixedCmpts
)
:
rowID_(row),
value_(value),
fixedComponents_(fixedCmpts),
matrixCoeffsSet_(false),
diagCoeff_(),
upperCoeffsOwnerPtr_(NULL),
upperCoeffsNeighbourPtr_(NULL),
lowerCoeffsOwnerPtr_(NULL),
lowerCoeffsNeighbourPtr_(NULL)
{}
// Construct as copy
template<class Type>
BlockConstraint<Type>::BlockConstraint(const BlockConstraint& e)
:
rowID_(e.rowID_),
value_(e.value_),
fixedComponents_(e.fixedComponents_),
matrixCoeffsSet_(false),
upperCoeffsOwnerPtr_(NULL),
upperCoeffsNeighbourPtr_(NULL),
lowerCoeffsOwnerPtr_(NULL),
lowerCoeffsNeighbourPtr_(NULL)
{}
// Construct from Istream
template<class Type>
BlockConstraint<Type>::BlockConstraint(Istream& is)
:
rowID_(is),
value_(is),
fixedComponents_(is),
matrixCoeffsSet_(false),
upperCoeffsOwnerPtr_(NULL),
upperCoeffsNeighbourPtr_(NULL),
lowerCoeffsOwnerPtr_(NULL),
lowerCoeffsNeighbourPtr_(NULL)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class Type>
BlockConstraint<Type>::~BlockConstraint()
{
deleteDemandDrivenData(upperCoeffsOwnerPtr_);
deleteDemandDrivenData(upperCoeffsNeighbourPtr_);
deleteDemandDrivenData(lowerCoeffsOwnerPtr_);
deleteDemandDrivenData(lowerCoeffsNeighbourPtr_);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
const BlockCoeff<Type>& BlockConstraint<Type>::diagCoeff() const
{
if (matrixCoeffsSet_)
{
FatalErrorIn
(
"const BlockCoeff<Type>& BlockConstraint<Type>::diagCoeff() const"
) << "matrix coefficients not set"
<< abort(FatalError);
}
return diagCoeff_;
}
template<class Type>
const Type& BlockConstraint<Type>::b() const
{
if (matrixCoeffsSet_)
{
FatalErrorIn
(
"Type BlockConstraint<Type>::b() const"
) << "matrix coefficients not set"
<< abort(FatalError);
}
return b_;
}
template<class Type>
const CoeffField<Type>& BlockConstraint<Type>::upperCoeffsOwner() const
{
if (!upperCoeffsOwnerPtr_ || !matrixCoeffsSet_)
{
FatalErrorIn
(
"const CoeffField<Type>& BlockConstraint<Type>::"
"upperCoeffsOwner() const"
) << "upper matrix coefficients not set"
<< abort(FatalError);
}
return *upperCoeffsOwnerPtr_;
}
template<class Type>
const CoeffField<Type>& BlockConstraint<Type>::upperCoeffsNeighbour() const
{
if (!upperCoeffsNeighbourPtr_ || !matrixCoeffsSet_)
{
FatalErrorIn
(
"const CoeffField<Type>& BlockConstraint<Type>::"
"upperCoeffsNeighbour() const"
) << "upper matrix coefficients not set"
<< abort(FatalError);
}
return *upperCoeffsNeighbourPtr_;
}
template<class Type>
const CoeffField<Type>& BlockConstraint<Type>::lowerCoeffsOwner() const
{
if (!lowerCoeffsOwnerPtr_ || !matrixCoeffsSet_)
{
FatalErrorIn
(
"const CoeffField<Type>& BlockConstraint<Type>::"
"lowerCoeffsOwner() const"
) << "lower matrix coefficients not set"
<< abort(FatalError);
}
return *lowerCoeffsOwnerPtr_;
}
template<class Type>
const CoeffField<Type>& BlockConstraint<Type>::lowerCoeffsNeighbour() const
{
if (!lowerCoeffsNeighbourPtr_ || !matrixCoeffsSet_)
{
FatalErrorIn
(
"const CoeffField<Type>& BlockConstraint<Type>::"
"lowerCoeffsNeighbour() const"
) << "lower matrix coefficients not set"
<< abort(FatalError);
}
return *lowerCoeffsNeighbourPtr_;
}
template<class Type>
void BlockConstraint<Type>::combine
(
const BlockConstraint<Type>& e
)
{
for
(
direction cmptI = 0;
cmptI < pTraits<Type>::nComponents;
cmptI++
)
{
if
(
e.fixedComponents_.component(cmptI)
> fixedComponents_.component(cmptI)
)
{
fixedComponents_.component(cmptI) =
e.fixedComponents_.component(cmptI);
value_.replace(cmptI, e.value_.component(cmptI));
}
}
}
template<class Type>
void BlockConstraint<Type>::clearMatrix()
{
matrixCoeffsSet_ = false;
diagCoeff_.clear();
b_ = pTraits<Type>::zero;
deleteDemandDrivenData(upperCoeffsOwnerPtr_);
deleteDemandDrivenData(upperCoeffsNeighbourPtr_);
deleteDemandDrivenData(lowerCoeffsOwnerPtr_);
deleteDemandDrivenData(lowerCoeffsNeighbourPtr_);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Type>
void BlockConstraint<Type>::operator=
(
const BlockConstraint<Type>& rhs
)
{
// Check for assignment to self
if (this == &rhs)
{
FatalErrorIn
(
"BlockConstraint::operator=(const BlockConstraint&)"
) << "attempted assignment to self"
<< abort(FatalError);
}
rowID_ = rhs.rowID_;
value_ = rhs.value_;
fixedComponents_ = rhs.fixedComponents_;
clearMatrix();
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
template<class Type>
Ostream& operator<<(Ostream& os, const BlockConstraint<Type>& e)
{
os << e.rowID_ << nl
<< e.value_ << nl
<< e.fixedComponents_ << nl;
os.check("Ostream& operator<<(Ostream&, BlockConstraint<Type>&");
return os;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,231 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
BlockConstraint
Description
A storage mechanism which allows setting of the fixed value and
consequently recovering the equation for a single row of the matrix as
well as the b. The equation is taken out of the matrix using a
variant of compact matrix storage mechanism.
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
BlockConstraint.C
\*---------------------------------------------------------------------------*/
#ifndef BlockConstraint_H
#define BlockConstraint_H
#include "BlockCoeff.H"
#include "coeffFields.H"
#include "blockLduMatrices.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<class Type>
class BlockConstraint;
template<class Type>
Ostream& operator<<(Ostream&, const BlockConstraint<Type>&);
/*---------------------------------------------------------------------------*\
Class BlockConstraint Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class BlockConstraint
{
// Public data types
typedef CoeffField<Type> TypeCoeffField;
typedef Field<Type> TypeField;
// Private data
//- Matrix row ID
label rowID_;
//- Fixed value
Type value_;
//- Fixed components (0-1) 1 = fixed, 0 = free
Type fixedComponents_;
//- Are matrix coefficients set?
bool matrixCoeffsSet_;
//- Diagonal coefficient
BlockCoeff<Type> diagCoeff_;
//- Right-hand side
Type b_;
//- Upper coefficients, owner side
TypeCoeffField* upperCoeffsOwnerPtr_;
//- Upper coefficients, neighbour side
TypeCoeffField* upperCoeffsNeighbourPtr_;
//- Lower coefficients, owner side
TypeCoeffField* lowerCoeffsOwnerPtr_;
//- Lower coefficients, neighbour side
TypeCoeffField* lowerCoeffsNeighbourPtr_;
public:
// Constructors
//- Construct from components
BlockConstraint
(
const label row,
const Type value,
const Type& fixedCmpts = pTraits<Type>::one
);
//- Construct as copy
BlockConstraint(const BlockConstraint&);
//- Construct from Istream
BlockConstraint(Istream&);
// Destructor
~BlockConstraint();
// Member Functions
//- Return matrix row ID
label rowID() const
{
return rowID_;
}
//- Return fixed value
Type value() const
{
return value_;
}
//- Return map of fixed components
const Type& fixedComponents() const
{
return fixedComponents_;
}
//- Return diagonal coefficient
const BlockCoeff<Type>& diagCoeff() const;
//- Return right-hand side
const Type& b() const;
//- Return off-diagonal coefficients
const TypeCoeffField& upperCoeffsOwner() const;
const TypeCoeffField& upperCoeffsNeighbour() const;
const TypeCoeffField& lowerCoeffsOwner() const;
const TypeCoeffField& lowerCoeffsNeighbour() const;
//- Combine with existing equation
void combine(const BlockConstraint<Type>&);
//- Set matrix coefficients
void setMatrix
(
const BlockLduMatrix<Type>& matrix,
const TypeField& x,
const TypeField& b
);
//- Eliminate equation
void eliminateEquation
(
BlockLduMatrix<Type>& matrix,
TypeField& b
) const;
//- Set x, b and diagonal in eliminated equation
void setSourceDiag
(
BlockLduMatrix<Type>&,
Field<Type>& x,
Field<Type>& b
) const;
//- Reconstruct matrix coefficients
void reconstructMatrix(BlockLduMatrix<Type>&) const;
//- Clear matrix coefficients
void clearMatrix();
// Member Operators
void operator=(const BlockConstraint<Type>&);
// Ostream Operator
friend Ostream& operator<< <Type>
(
Ostream&,
const BlockConstraint<Type>&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "BlockConstraint.C"
# include "BlockConstraintTools.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,345 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
A storage mechanism which allows setting of the fixed value and
consequently recovering the equation for a single row of the matrix as
well as b. The equation is taken out of the matrix using a
variant of compact matrix storage mechanism.
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "BlockConstraint.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void BlockConstraint<Type>::setMatrix
(
const BlockLduMatrix<Type>& matrix,
const TypeField& x,
const TypeField& b
)
{
if (matrixCoeffsSet_)
{
FatalErrorIn
(
"void BlockConstraint<Type>::setMatrix\n"
"(\n"
" const BlockLduMatrix<Type>& matrix,\n"
" const TypeField& x,\n"
" const TypeField& b\n"
")"
) << "matrix coefficients already set"
<< abort(FatalError);
}
matrixCoeffsSet_ = true;
if (matrix.thereIsDiag())
{
diagCoeff_ = matrix.diag().getCoeff(rowID_);
}
b_ = b[rowID_];
const label startFaceOwn =
matrix.lduAddr().ownerStartAddr()[rowID_];
const label endFaceOwn =
matrix.lduAddr().ownerStartAddr()[rowID_ + 1];
const label ownSize = endFaceOwn - startFaceOwn;
const label startFaceNbr =
matrix.lduAddr().losortStartAddr()[rowID_];
const label endFaceNbr =
matrix.lduAddr().losortStartAddr()[rowID_ + 1];
const label nbrSize = endFaceNbr - startFaceNbr;
const unallocLabelList& losort = matrix.lduAddr().losortAddr();
// Create losort addressing
labelList losortAddr(nbrSize);
forAll (losortAddr, laI)
{
losortAddr[laI] = losort[startFaceNbr + laI];
}
if (matrix.thereIsUpper())
{
// Get the upper coefficients
const TypeCoeffField& matrixUpper = matrix.upper();
// owner side
upperCoeffsOwnerPtr_ = new TypeCoeffField(ownSize);
TypeCoeffField& uOwn = *upperCoeffsOwnerPtr_;
matrixUpper.getSubset(uOwn, startFaceOwn, ownSize);
// neighbour side
upperCoeffsNeighbourPtr_ = new TypeCoeffField(nbrSize);
TypeCoeffField& uNbr = *upperCoeffsNeighbourPtr_;
matrixUpper.getSubset(uNbr, losortAddr);
}
if (matrix.thereIsLower())
{
// Get the lower coefficients
const TypeCoeffField& matrixLower = matrix.lower();
// owner side
lowerCoeffsOwnerPtr_ = new TypeCoeffField(ownSize);
TypeCoeffField& lOwn = *lowerCoeffsOwnerPtr_;
matrixLower.getSubset(lOwn, startFaceOwn, ownSize);
// neighbour side
lowerCoeffsNeighbourPtr_ = new TypeCoeffField(nbrSize);
TypeCoeffField& lNbr = *lowerCoeffsNeighbourPtr_;
matrixLower.getSubset(lNbr, losortAddr);
}
}
template<class Type>
void BlockConstraint<Type>::eliminateEquation
(
BlockLduMatrix<Type>& matrix,
TypeField& b
) const
{
const label startFaceOwn =
matrix.lduAddr().ownerStartAddr()[rowID_];
const label endFaceOwn =
matrix.lduAddr().ownerStartAddr()[rowID_ + 1];
const label ownSize = endFaceOwn - startFaceOwn;
const label startFaceNbr =
matrix.lduAddr().losortStartAddr()[rowID_];
const label endFaceNbr =
matrix.lduAddr().losortStartAddr()[rowID_ + 1];
const label nbrSize = endFaceNbr - startFaceNbr;
const unallocLabelList& owner = matrix.lduAddr().lowerAddr();
const unallocLabelList& neighbour = matrix.lduAddr().upperAddr();
const unallocLabelList& losort = matrix.lduAddr().losortAddr();
// Create losort addressing
labelList losortAddr(nbrSize);
forAll (losortAddr, laI)
{
losortAddr[laI] = losort[startFaceNbr + laI];
}
typename BlockCoeff<Type>::multiply mult;
// My index = rowID_
if (matrix.symmetric())
{
TypeField bOwn;
TypeField bNbr;
TypeCoeffField& upperLower = matrix.upper();
upperLower.zeroOutSubset(startFaceOwn, ownSize);
upperLower.zeroOutSubset(losortAddr);
bOwn = upperCoeffsOwner()*value_;
bNbr = upperCoeffsNeighbour()*value_;
// owner side
forAll (bOwn, soI)
{
// add contribution to b of the neighbour (I am the owner)
b[neighbour[startFaceOwn + soI]] -= bOwn[soI];
}
// neighbour side
forAll (bNbr, snI)
{
// add contribution to b of owner (I am the neighbour)
b[owner[losort[startFaceNbr + snI]]] -= bNbr[snI];
}
}
else if (matrix.asymmetric())
{
// Do upper
TypeCoeffField& matrixUpper = matrix.upper();
matrixUpper.zeroOutSubset(startFaceOwn, ownSize);
TypeField bOwn = lowerCoeffsOwner()*value_;
// Do lower
TypeCoeffField& matrixLower = matrix.lower();
matrixLower.zeroOutSubset(losortAddr);
TypeField bNbr = upperCoeffsNeighbour()*value_;
// owner side
forAll (bOwn, soI)
{
// add contribution to b of the neighbour (I am the owner)
b[neighbour[startFaceOwn + soI]] -= bOwn[soI];
}
// neighbour side
forAll (bNbr, snI)
{
// add contribution to b of owner (I am the neighbour)
b[owner[losort[startFaceNbr + snI]]] -= bNbr[snI];
}
}
}
template<class Type>
void BlockConstraint<Type>::setSourceDiag
(
BlockLduMatrix<Type>& matrix,
Field<Type>& x,
Field<Type>& b
) const
{
const Type& fc = fixedComponents();
typename BlockCoeff<Type>::multiply mult;
if (mag(fc) > SMALL)
{
b[rowID()] =
scale
(
fc,
mult(matrix.diag().getCoeff(rowID()), value())
);
// set the solution to the right value as well
x[rowID()] = scale(fc, value());
}
}
template<class Type>
void BlockConstraint<Type>::reconstructMatrix
(
BlockLduMatrix<Type>& matrix
) const
{
if (!matrixCoeffsSet_)
{
FatalErrorIn
(
"void BlockConstraint<Type>::reconstructMatrix("
"BlockLduMatrix<Type>& matrix)"
) << "matrix coefficients not set"
<< abort(FatalError);
}
if (matrix.thereIsDiag())
{
matrix.diag().setCoeff(rowID_, diagCoeff_);
}
const label startFaceOwn =
matrix.lduAddr().ownerStartAddr()[rowID_];
const label endFaceOwn =
matrix.lduAddr().ownerStartAddr()[rowID_ + 1];
const label ownSize = endFaceOwn - startFaceOwn;
const label startFaceNbr =
matrix.lduAddr().losortStartAddr()[rowID_];
const label endFaceNbr =
matrix.lduAddr().losortStartAddr()[rowID_ + 1];
const label nbrSize = endFaceNbr - startFaceNbr;
const unallocLabelList& losort = matrix.lduAddr().losortAddr();
// Create losort addressing
labelList losortAddr(nbrSize);
forAll (losortAddr, laI)
{
losortAddr[laI] = losort[startFaceNbr + laI];
}
if (matrix.thereIsUpper())
{
// Get the upper coefficients
TypeCoeffField& matrixUpper = matrix.upper();
// owner side
const TypeCoeffField& uOwn = upperCoeffsOwner();
matrixUpper.setSubset(uOwn, startFaceOwn, ownSize);
// neighbour side
const TypeCoeffField& uNbr = upperCoeffsNeighbour();
matrixUpper.setSubset(uNbr, losortAddr);
}
if (matrix.thereIsLower())
{
// Get the lower coefficients
TypeCoeffField& matrixLower = matrix.lower();
// owner side
const TypeCoeffField& lOwn = lowerCoeffsOwner();
matrixLower.setSubset(lOwn, startFaceOwn, ownSize);
// neighbour side
const TypeCoeffField& lNbr = lowerCoeffsNeighbour();
matrixLower.setSubset(lNbr, losortAddr);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,50 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
blockConstraints
Description
A storage mechanism which allows setting of the fixed value and
consequently recovering the equation for a single row of the matrix as
well as the source. The equation is taken out of the matrix using a
variant of compact matrix storage mechanism.
File to include template specialisation for scalar
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
\*---------------------------------------------------------------------------*/
#ifndef blockConstraints_H
#define blockConstraints_H
#include "scalarBlockConstraint.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,56 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "scalarBlockConstraint.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<>
void BlockConstraint<scalar>::combine
(
const BlockConstraint<scalar>& e
)
{
if (e.fixedComponents_ > fixedComponents_)
{
fixedComponents_ = e.fixedComponents_;
value_ = e.value_;
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,66 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
scalarBlockConstraint
Description
Template specialisation for scalar block constraint
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
scalarBlockConstraint.C
\*---------------------------------------------------------------------------*/
#ifndef scalarBlockConstraint_H
#define scalarBlockConstraint_H
#include "BlockConstraint.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<>
void BlockConstraint<scalar>::combine
(
const BlockConstraint<scalar>& e
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,116 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
BlockLduInterface
Description
An abstract base class for implicitly-coupled interface fields
e.g. processor and cyclic patch fields.
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
BlockLduInterface.C
\*---------------------------------------------------------------------------*/
#ifndef BlockLduInterface_H
#define BlockLduInterface_H
#include "primitiveFieldsFwd.H"
#include "FieldField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
class BlockLduMatrix;
/*---------------------------------------------------------------------------*\
Class BlockLduInterface Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class BlockLduInterface
{
// Private Member Functions
//- Disallow default bitwise copy construct
BlockLduInterface(const BlockLduInterface&);
//- Disallow default bitwise assignment
void operator=(const BlockLduInterface&);
public:
//- Runtime type information
TypeName("BlockLduInterface");
// Destructor
virtual ~BlockLduInterface()
{}
// Member Functions
// Coupled interface matrix update
//- Initialise matrix update
virtual void initMatrixUpdate
(
const BlockLduMatrix<Type>& matrix,
Field<Type>& Ax,
const Field<Type>& x
) const
{}
//- Update result based on interface functionality
virtual void updateMatrix
(
const BlockLduMatrix<Type>& matrix,
const FieldField<CoeffField, Type>& coeffs,
Field<Type>& Ax,
const Field<Type>& x
) const = 0;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,333 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
BlockLduMatrix is a general matrix class in which the coefficients are
stored as three arrays, one for the upper triangle, one for the
lower triangle and a third for the diagonal. Addressing object must
be supplied for the upper and lower triangles.
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "BlockLduMatrix.H"
#include "IOstreams.H"
#include "demandDrivenData.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
template<class Type>
const Foam::label Foam::BlockLduMatrix<Type>::fixFillIn
(
debug::optimisationSwitch("matrixConstraintFillIn", 4)
);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::BlockLduMatrix<Type>::BlockLduMatrix(const lduMesh& ldu)
:
lduMesh_(ldu),
diagPtr_(NULL),
upperPtr_(NULL),
lowerPtr_(NULL),
interfaces_(),
coupleUpper_(ldu.lduAddr().nPatches()),
coupleLower_(ldu.lduAddr().nPatches()),
fixedEqns_(ldu.lduAddr().size()/fixFillIn)
{
const lduAddressing& addr = ldu.lduAddr();
forAll (coupleUpper_, i)
{
coupleUpper_.set(i, new CoeffField<Type>(addr.patchAddr(i).size()));
coupleLower_.set(i, new CoeffField<Type>(addr.patchAddr(i).size()));
}
}
template<class Type>
Foam::BlockLduMatrix<Type>::BlockLduMatrix(const BlockLduMatrix<Type>& A)
:
refCount(),
lduMesh_(A.lduMesh_),
diagPtr_(NULL),
upperPtr_(NULL),
lowerPtr_(NULL),
interfaces_(),
coupleUpper_(),
coupleLower_(),
fixedEqns_(A.fixedEqns_)
{
if (A.diagPtr_)
{
diagPtr_ = new TypeCoeffField(*(A.diagPtr_));
}
if (A.upperPtr_)
{
upperPtr_ = new TypeCoeffField(*(A.upperPtr_));
}
if (A.lowerPtr_)
{
lowerPtr_ = new TypeCoeffField(*(A.lowerPtr_));
}
// Interface data
coupleUpper_ = A.coupleUpper_;
coupleLower_ = A.coupleUpper_;
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class Type>
Foam::BlockLduMatrix<Type>::~BlockLduMatrix()
{
deleteDemandDrivenData(diagPtr_);
deleteDemandDrivenData(upperPtr_);
deleteDemandDrivenData(lowerPtr_);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
typename Foam::BlockLduMatrix<Type>::TypeCoeffField&
Foam::BlockLduMatrix<Type>::diag()
{
if (!diagPtr_)
{
diagPtr_ = new TypeCoeffField(lduAddr().size());
}
return *diagPtr_;
}
template<class Type>
const typename Foam::BlockLduMatrix<Type>::TypeCoeffField&
Foam::BlockLduMatrix<Type>::diag() const
{
if (!diagPtr_)
{
FatalErrorIn
(
"const TypeCoeffField& BlockLduMatrix<Type>::diag() const"
) << "diagPtr_ unallocated"
<< abort(FatalError);
}
return *diagPtr_;
}
template<class Type>
typename Foam::BlockLduMatrix<Type>::TypeCoeffField&
Foam::BlockLduMatrix<Type>::upper()
{
if (!upperPtr_)
{
upperPtr_ = new TypeCoeffField(lduAddr().lowerAddr().size());
}
return *upperPtr_;
}
template<class Type>
const typename Foam::BlockLduMatrix<Type>::TypeCoeffField&
Foam::BlockLduMatrix<Type>::upper() const
{
if (!upperPtr_)
{
FatalErrorIn
(
"const TypeCoeffField& BlockLduMatrix<Type>::upper() const"
) << "upperPtr_ unallocated"
<< abort(FatalError);
}
return *upperPtr_;
}
template<class Type>
typename Foam::BlockLduMatrix<Type>::TypeCoeffField&
Foam::BlockLduMatrix<Type>::lower()
{
if (!lowerPtr_)
{
if (upperPtr_)
{
Info << "Manufacturing lower from upper transpose" << endl;
lowerPtr_ = new TypeCoeffField(upperPtr_->transpose());
}
else
{
lowerPtr_ = new TypeCoeffField(lduAddr().lowerAddr().size());
}
}
return *lowerPtr_;
}
template<class Type>
const typename Foam::BlockLduMatrix<Type>::TypeCoeffField&
Foam::BlockLduMatrix<Type>::lower() const
{
if (!lowerPtr_)
{
FatalErrorIn
(
"const TypeCoeffField& BlockLduMatrix<Type>::lower() const"
) << "lowerPtr_ unallocated"
<< abort(FatalError);
}
return *lowerPtr_;
}
template<class Type>
bool Foam::BlockLduMatrix<Type>::empty() const
{
return (!diagPtr_ && !lowerPtr_ && !upperPtr_);
}
template<class Type>
bool Foam::BlockLduMatrix<Type>::diagonal() const
{
return (diagPtr_ && !lowerPtr_ && !upperPtr_);
}
template<class Type>
bool Foam::BlockLduMatrix<Type>::symmetric() const
{
if (lowerPtr_ && !upperPtr_)
{
FatalErrorIn
(
"bool BlockLduMatrix<Type>::symmetric() const"
) << "Matrix assembly error: symmetric matrix but only lower "
<< "triangle is allocated. This is not allowed."
<< abort(FatalError);
}
return (diagPtr_ && (!lowerPtr_ && upperPtr_));
}
template<class Type>
bool Foam::BlockLduMatrix<Type>::asymmetric() const
{
return (diagPtr_ && lowerPtr_ && upperPtr_);
}
template<class Type>
bool Foam::BlockLduMatrix<Type>::componentCoupled() const
{
// Return true if the matrix coefficient couple the components
if (thereIsDiag())
{
if (diag().activeType() == blockCoeffBase::SQUARE)
{
return true;
}
}
if (thereIsUpper())
{
if (upper().activeType() == blockCoeffBase::SQUARE)
{
return true;
}
}
if (thereIsLower())
{
if (lower().activeType() == blockCoeffBase::SQUARE)
{
return true;
}
}
return false;
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
template<class Type>
Foam::Ostream& Foam::operator<<(Ostream& os, const BlockLduMatrix<Type>& ldum)
{
if (ldum.diagPtr_)
{
os << *ldum.diagPtr_ << nl;
}
else
{
// Dummy write for consistency
os << typename BlockLduMatrix<Type>::TypeCoeffField
(ldum.lduAddr().size()) << nl;
}
if (ldum.upperPtr_)
{
os << *ldum.upperPtr_ << nl;
}
else
{
// Dummy write for consistency
os << typename BlockLduMatrix<Type>::TypeCoeffField
(ldum.lduAddr().lowerAddr().size()) << nl;
}
if (ldum.lowerPtr_)
{
os << *ldum.lowerPtr_ << nl;
}
else
{
// Dummy write for consistency
os << typename BlockLduMatrix<Type>::TypeCoeffField
(ldum.lduAddr().lowerAddr().size()) << nl;
}
os << endl;
os.check("Ostream& operator<<(Ostream&, const BlockLduMatrix<Type>&");
return os;
}
// ************************************************************************* //

View file

@ -0,0 +1,484 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockLduMatrix
Description
BlockLduMatrix is a general matrix class in which the coefficients are
stored as three arrays, one for the upper triangle, one for the
lower triangle and a third for the diagonal. Addressing object must
be supplied for the upper and lower triangles.
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
BlockLduMatrix.C
BlockLduMatrixOperations.C
BlockLduMatrixUpdateInterfaces.C
BlockLduMatrixATmul.C
BlockLduMatrixHOps.C
BlockLduMatrixDecouple.C
BlockLduMatrixDecoupledHOps.C
\*---------------------------------------------------------------------------*/
#ifndef BlockLduMatrix_H
#define BlockLduMatrix_H
#include "coeffFields.H"
#include "lduMesh.H"
#include "BlockLduInterface.H"
#include "Map.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * Forward declaration of template friend fuctions * * * * * * * //
template<class Type>
class BlockLduMatrix;
template<class Type>
Ostream& operator<<(Ostream&, const BlockLduMatrix<Type>&);
template<class Type>
class BlockConstraint;
/*---------------------------------------------------------------------------*\
Class BlockLduMatrix Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class BlockLduMatrix
:
public refCount
{
public:
// Public data types
typedef CoeffField<Type> TypeCoeffField;
typedef Field<Type> TypeField;
typedef BlockConstraint<Type> ConstraintType;
private:
// Private data
// LDU mesh reference
const lduMesh& lduMesh_;
// Block matrix elements
//- Diagonal coefficients
CoeffField<Type>* diagPtr_;
//- Upper triangle coefficients. Also used for symmetric matrix
CoeffField<Type>* upperPtr_;
//- Lower triangle coefficients
CoeffField<Type> *lowerPtr_;
// Coupling
//- List of coupled interfaces
PtrList<BlockLduInterface<Type> > interfaces_;
//- Coupled interface coefficients, upper
FieldField<CoeffField, Type> coupleUpper_;
//- Coupled interface coefficients, lower
FieldField<CoeffField, Type> coupleLower_;
// Constraints
//- Equation triangle map
mutable Map<ConstraintType> fixedEqns_;
// Private static data
//- Matrix constraint fill-in
// Equals to the estimated fraction of fixed nodes in the matrix
static const label fixFillIn;
// Private member functions
// Decoupled versions of nmatrix operations
//- Sum off-diagonal coefficients and add to diagonal,
// decoupled version
void decoupledSumDiag();
//- Sum negative off-diagonal coefficients and add to diagonal,
// decoupled version
void decoupledNegSumDiag();
//- Check matrix for diagonal dominance, decoupled version
void decoupledCheck() const;
//- Relax matrix, decoupled version
void decoupledRelax
(
const TypeField& x,
TypeField& b,
const scalar alpha
);
//- Matrix scaling with scalar field, decoupled version
void decoupledMultEqOp(const scalarField& sf);
//- Matrix multiplication without coupled interface update,
// decoupled version
void decoupledAmulCore
(
TypeField& Ax,
const TypeField& x
) const;
//- Matrix transpose multiplication without coupled interface update
// decoupled version
void decoupledTmulCore
(
TypeField& Tx,
const TypeField& x
) const;
//- Return L-U vector-matrix multiplication in row-form,
// decoupled version
tmp<TypeField> decoupledH(const TypeField& x) const;
//- Return L-U vector-matrix multiplication in off-diagonal form,
// decoupled version
tmp<TypeField> decoupledFaceH(const TypeField& x) const;
protected:
// Access to constraints
//- Return constraint map
const Map<ConstraintType>& fixedEqns() const
{
return fixedEqns_;
}
//- Return access constraint map
Map<ConstraintType>& fixedEqns()
{
return fixedEqns_;
}
public:
//- Runtime type information
TypeName("BlockLduMatrix");
// Constructors
//- Construct given addressing
explicit BlockLduMatrix(const lduMesh&);
//- Construct as copy
BlockLduMatrix(const BlockLduMatrix<Type>&);
// Destructor
virtual ~BlockLduMatrix();
// Member functions
// Access to addressing
//- Return the LDU mesh from which the addressing is obtained
const lduMesh& mesh() const
{
return lduMesh_;
}
//- Return the LDU addressing
const lduAddressing& lduAddr() const
{
return lduMesh_.lduAddr();
}
//- Return the patch evaluation schedule
const lduSchedule& patchSchedule() const
{
return lduAddr().patchSchedule();
}
// Access to coefficients
//- Return access to diagonal coefficients
TypeCoeffField& diag();
//- Return diagonal coefficients
const TypeCoeffField& diag() const;
//- Return access to upper coefficients
// Also used for symmetric matrices
TypeCoeffField& upper();
//- Return upper coefficients
// Also used for symmetric matrices
const TypeCoeffField& upper() const;
//- Return access to lower coefficients
TypeCoeffField& lower();
//- Return lower coefficients
const TypeCoeffField& lower() const;
//- Return access to coupled interface coefficients, upper
FieldField<CoeffField, Type>& coupleUpper()
{
return coupleUpper_;
}
//- Return coupled interface coefficients, upper
const FieldField<CoeffField, Type>& coupleUpper() const
{
return coupleUpper_;
}
//- Return access to coupled interface coefficients, lower
FieldField<CoeffField, Type>& coupleLower()
{
return coupleLower_;
}
//- Return coupled interface coefficients, lower
const FieldField<CoeffField, Type>& coupleLower() const
{
return coupleLower_;
}
// Matrix structure
//- Return true if there is a diagonal
bool thereIsDiag() const
{
return (diagPtr_);
}
//- Return true if upper triangle is allocated
bool thereIsUpper() const
{
return (upperPtr_);
}
//- Return true if lower triangle is allocated
bool thereIsLower() const
{
return (lowerPtr_);
}
//- Return true if matrix is empty
bool empty() const;
//- Return true if matrix is diagonal-only
bool diagonal() const;
//- Return true if matrix is symmetric
bool symmetric() const;
//- Return true if matrix is asymmetric
bool asymmetric() const;
//- Return true if matrix is component-coupled
bool componentCoupled() const;
// Operations
//- Sum off-diagonal coefficients and add to diagonal
void sumDiag();
//- Sum negative off-diagonal coefficients and add to diagonal
void negSumDiag();
//- Check matrix for diagonal dominance
void check() const;
//- Relax matrix
void relax
(
const TypeField& x,
TypeField& b,
const scalar alpha
);
//- Matrix multiplication
void Amul
(
TypeField& Ax,
const TypeField& x
) const;
//- Matrix multiplication without coupled interface update
void AmulCore
(
TypeField& Ax,
const TypeField& x
) const;
//- Matrix transpose multiplication
void Tmul
(
TypeField& Ax,
const TypeField& x
) const;
//- Matrix transpose multiplication without
// coupled interface update
void TmulCore
(
TypeField& Ax,
const TypeField& x
) const;
//- Return decoupled b
void segregateB
(
TypeField& sMul,
const TypeField& x
) const;
// Coupled interface functionality
//- Initialise the update of coupled interfaces
// for Amul operations
void initInterfaces
(
TypeField& Ax,
const TypeField& x
) const;
//- Update coupled interfaces
void updateInterfaces
(
const FieldField<CoeffField, Type>& coeffs,
TypeField& Ax,
const TypeField& x
) const;
// Constraint manipulation
//- Set constrained value in a prescribed point
void setValue
(
const label eqnIndex,
const Type& value
);
// Residual calculation
//- Calculate residual
tmp<TypeField> residual
(
const TypeField& x
) const;
tmp<TypeField> residual
(
const TypeField& x,
const TypeField& b
) const;
// H-operations
//- Return L-U vector-matrix multiplication in row-form
tmp<TypeField> H(const TypeField&) const;
//- Return L-U vector-matrix multiplication in off-diagonal form
tmp<TypeField> faceH(const TypeField&) const;
// Member operators
void operator=(const BlockLduMatrix<Type>&);
void negate();
void operator+=(const BlockLduMatrix<Type>&);
void operator-=(const BlockLduMatrix<Type>&);
void operator*=(const scalarField&);
void operator*=(const scalar);
// Ostream operator
friend Ostream& operator<< <Type>
(
Ostream&,
const BlockLduMatrix<Type>&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "BlockLduMatrix.C"
# include "BlockLduMatrixOperations.C"
# include "BlockLduMatrixUpdateInterfaces.C"
# include "BlockLduMatrixATmul.C"
# include "BlockLduMatrixHOps.C"
# include "BlockLduMatrixDecouple.C"
# include "BlockLduMatrixDecoupledHOps.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,406 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
Vector-matrix multiplication operations for a block matrix
\*---------------------------------------------------------------------------*/
#include "BlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
void Foam::BlockLduMatrix<Type>::Amul
(
TypeField& Ax,
const TypeField& x
) const
{
// Initialise the update of coupled interfaces
initInterfaces(Ax, x);
AmulCore(Ax, x);
// Update coupled interfaces
updateInterfaces(coupleUpper_, Ax, x);
}
template<class Type>
void Foam::BlockLduMatrix<Type>::AmulCore
(
TypeField& Ax,
const TypeField& x
) const
{
typedef typename TypeCoeffField::scalarTypeField scalarTypeField;
typedef typename TypeCoeffField::linearTypeField linearTypeField;
typedef typename TypeCoeffField::squareTypeField squareTypeField;
const unallocLabelList& u = lduAddr().upperAddr();
const unallocLabelList& l = lduAddr().lowerAddr();
const TypeCoeffField& Diag = this->diag();
const TypeCoeffField& Upper = this->upper();
// Diagonal multiplication, no indirection
multiply(Ax, Diag, x);
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
// Lower multiplication
if (symmetric())
{
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeUpper = Upper.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Ax[u[coeffI]] += mult(activeUpper[coeffI], x[l[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeUpper = Upper.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Ax[u[coeffI]] += mult(activeUpper[coeffI], x[l[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::SQUARE)
{
const squareTypeField& activeUpper = Upper.asSquare();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
// Use transpose upper coefficient
Ax[u[coeffI]] +=
mult(activeUpper[coeffI].T(), x[l[coeffI]]);
}
}
}
else // Asymmetric matrix
{
const TypeCoeffField& Lower = this->lower();
if (Lower.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeLower = Lower.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Ax[u[coeffI]] += mult(activeLower[coeffI], x[l[coeffI]]);
}
}
else if (Lower.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeLower = Lower.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Ax[u[coeffI]] += mult(activeLower[coeffI], x[l[coeffI]]);
}
}
else if (Lower.activeType() == blockCoeffBase::SQUARE)
{
const squareTypeField& activeLower = Lower.asSquare();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Ax[u[coeffI]] += mult(activeLower[coeffI], x[l[coeffI]]);
}
}
}
// Upper multiplication
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeUpper = Upper.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Ax[l[coeffI]] += mult(activeUpper[coeffI], x[u[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeUpper = Upper.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Ax[l[coeffI]] += mult(activeUpper[coeffI], x[u[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::SQUARE)
{
const squareTypeField& activeUpper = Upper.asSquare();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Ax[l[coeffI]] += mult(activeUpper[coeffI], x[u[coeffI]]);
}
}
}
template<class Type>
void Foam::BlockLduMatrix<Type>::Tmul
(
TypeField& Ax,
const TypeField& x
) const
{
// Initialise the update of coupled interfaces
initInterfaces(Ax, x);
TmulCore(Ax, x);
// Update coupled interfaces
updateInterfaces(coupleLower_, Ax, x);
}
template<class Type>
void Foam::BlockLduMatrix<Type>::TmulCore
(
TypeField& Tx,
const TypeField& x
) const
{
typedef typename TypeCoeffField::scalarTypeField scalarTypeField;
typedef typename TypeCoeffField::linearTypeField linearTypeField;
typedef typename TypeCoeffField::squareTypeField squareTypeField;
const unallocLabelList& u = lduAddr().upperAddr();
const unallocLabelList& l = lduAddr().lowerAddr();
const TypeCoeffField& Diag = this->diag();
const TypeCoeffField& Upper = this->upper();
// Diagonal multiplication, no indirection
multiply(Tx, Diag, x);
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
// Upper multiplication
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeUpper = Upper.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Tx[u[coeffI]] += mult(activeUpper[coeffI], x[l[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeUpper = Upper.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Tx[u[coeffI]] += mult(activeUpper[coeffI], x[l[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::SQUARE)
{
const squareTypeField& activeUpper = Upper.asSquare();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Tx[u[coeffI]] += mult(activeUpper[coeffI], x[l[coeffI]]);
}
}
// Lower multiplication
if (symmetric())
{
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeUpper = Upper.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Tx[l[coeffI]] += mult(activeUpper[coeffI], x[u[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeUpper = Upper.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Tx[l[coeffI]] += mult(activeUpper[coeffI], x[u[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::SQUARE)
{
const squareTypeField& activeUpper = Upper.asSquare();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
// Use transpose upper coefficient
Tx[l[coeffI]] +=
mult(activeUpper[coeffI].T(), x[u[coeffI]]);
}
}
}
else // Asymmetric matrix
{
const TypeCoeffField& Lower = this->lower();
if (Lower.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeLower = Lower.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Tx[l[coeffI]] += mult(activeLower[coeffI], x[u[coeffI]]);
}
}
else if (Lower.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeLower = Lower.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Tx[l[coeffI]] += mult(activeLower[coeffI], x[u[coeffI]]);
}
}
else if (Lower.activeType() == blockCoeffBase::SQUARE)
{
const squareTypeField& activeLower = Lower.asSquare();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Tx[l[coeffI]] += mult(activeLower[coeffI], x[u[coeffI]]);
}
}
}
}
template<class Type>
void Foam::BlockLduMatrix<Type>::segregateB
(
TypeField& sMul,
const TypeField& x
) const
{
typedef typename TypeCoeffField::linearType linearType;
typedef typename TypeCoeffField::squareType squareType;
typedef typename TypeCoeffField::linearTypeField linearTypeField;
typedef typename TypeCoeffField::squareTypeField squareTypeField;
const unallocLabelList& u = lduAddr().upperAddr();
const unallocLabelList& l = lduAddr().lowerAddr();
// Diagonal multiplication
if (thereIsDiag())
{
if (diag().activeType() == blockCoeffBase::SQUARE)
{
const squareTypeField& activeDiag = this->diag().asSquare();
linearTypeField lf(activeDiag.size());
squareTypeField sf(activeDiag.size());
// Expand and contract
contractLinear(lf, activeDiag);
expandLinear(sf, lf);
sMul -= (activeDiag - sf) & x;
}
}
// Lower multiplication
if (thereIsLower())
{
if (lower().activeType() == blockCoeffBase::SQUARE)
{
const squareTypeField& activeLower = this->lower().asSquare();
// Auxiliary variables used in expand/contract
linearType lt;
squareType st;
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
contractLinear(lt, activeLower[coeffI]);
expandLinear(st, lt);
sMul[u[coeffI]] -= (activeLower[coeffI] - st) & x[l[coeffI]];
}
}
}
// Upper multiplication
if (thereIsUpper())
{
if (upper().activeType() == blockCoeffBase::SQUARE)
{
const squareTypeField& activeUpper = this->upper().asSquare();
// Auxiliary variables used in expand/contract
linearType lt;
squareType st;
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
contractLinear(lt, activeUpper[coeffI]);
expandLinear(st, lt);
sMul[l[coeffI]] -= (activeUpper[coeffI] - st) & x[u[coeffI]];
}
// If the matrix is symmetric, the lower triangular product
// is also needed
if (symmetric())
{
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
// Use transpose upper coefficient
contractLinear(lt, activeUpper[coeffI]);
expandLinear(st, lt);
sMul[u[coeffI]] -=
(activeUpper[coeffI].T() - st) & x[l[coeffI]];
}
}
}
}
}
// ************************************************************************* //

View file

@ -0,0 +1,797 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
Vector-matrix multiplication operations for a block matrix
\*---------------------------------------------------------------------------*/
#include "BlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
void Foam::BlockLduMatrix<Type>::decoupledSumDiag()
{
typedef typename TypeCoeffField::scalarTypeField scalarTypeField;
typedef typename TypeCoeffField::linearTypeField linearTypeField;
TypeCoeffField& Diag = this->diag();
const unallocLabelList& l = lduAddr().lowerAddr();
const unallocLabelList& u = lduAddr().upperAddr();
if (this->symmetric())
{
// Symmetric matrix: re-use upper for lower coefficients
const TypeCoeffField& Upper =
const_cast<const BlockLduMatrix<Type>&>(*this).upper();
if
(
Upper.activeType() == blockCoeffBase::LINEAR
|| Diag.activeType() == blockCoeffBase::LINEAR
)
{
const linearTypeField& activeUpper = Upper.asLinear();
linearTypeField& activeDiag = Diag.asLinear();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiag[l[coeffI]] += activeUpper[coeffI];
activeDiag[u[coeffI]] += activeUpper[coeffI];
}
}
else if
(
Upper.activeType() == blockCoeffBase::SCALAR
|| Diag.activeType() == blockCoeffBase::SCALAR
)
{
const scalarTypeField& activeUpper = Upper.asScalar();
scalarTypeField& activeDiag = Diag.asScalar();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiag[l[coeffI]] += activeUpper[coeffI];
activeDiag[u[coeffI]] += activeUpper[coeffI];
}
}
}
else if (this->asymmetric())
{
// Full asymmetric matrix
const TypeCoeffField& Lower =
const_cast<const BlockLduMatrix<Type>&>(*this).lower();
const TypeCoeffField& Upper =
const_cast<const BlockLduMatrix<Type>&>(*this).upper();
if
(
Lower.activeType() == blockCoeffBase::LINEAR
|| Upper.activeType() == blockCoeffBase::LINEAR
|| Diag.activeType() == blockCoeffBase::LINEAR
)
{
const linearTypeField& activeLower = Lower.asLinear();
const linearTypeField& activeUpper = Upper.asLinear();
linearTypeField& activeDiag = Diag.asLinear();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiag[l[coeffI]] += activeLower[coeffI];
activeDiag[u[coeffI]] += activeUpper[coeffI];
}
}
else if
(
Lower.activeType() == blockCoeffBase::SCALAR
|| Upper.activeType() == blockCoeffBase::SCALAR
|| Diag.activeType() == blockCoeffBase::SCALAR
)
{
const scalarTypeField& activeLower = Lower.asScalar();
const scalarTypeField& activeUpper = Upper.asScalar();
scalarTypeField& activeDiag = Diag.asScalar();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiag[l[coeffI]] += activeLower[coeffI];
activeDiag[u[coeffI]] += activeUpper[coeffI];
}
}
}
else
{
FatalErrorIn("void BlockLduMatrix<Type>::decoupledSumDiag()")
<< "No off-diagonal available"
<< abort(FatalError);
}
}
template<class Type>
void Foam::BlockLduMatrix<Type>::decoupledNegSumDiag()
{
typedef typename TypeCoeffField::scalarTypeField scalarTypeField;
typedef typename TypeCoeffField::linearTypeField linearTypeField;
TypeCoeffField& Diag = this->diag();
const unallocLabelList& l = lduAddr().lowerAddr();
const unallocLabelList& u = lduAddr().upperAddr();
if (this->symmetric())
{
// Symmetric matrix: re-use upper for lower coefficients
const TypeCoeffField& Upper =
const_cast<const BlockLduMatrix<Type>&>(*this).upper();
if
(
Upper.activeType() == blockCoeffBase::LINEAR
|| Diag.activeType() == blockCoeffBase::LINEAR
)
{
const linearTypeField& activeUpper = Upper.asLinear();
linearTypeField& activeDiag = Diag.asLinear();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiag[l[coeffI]] -= activeUpper[coeffI];
activeDiag[u[coeffI]] -= activeUpper[coeffI];
}
}
else if
(
Upper.activeType() == blockCoeffBase::SCALAR
|| Diag.activeType() == blockCoeffBase::SCALAR
)
{
const scalarTypeField& activeUpper = Upper.asScalar();
scalarTypeField& activeDiag = Diag.asScalar();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiag[l[coeffI]] -= activeUpper[coeffI];
activeDiag[u[coeffI]] -= activeUpper[coeffI];
}
}
}
else if (this->asymmetric())
{
// Full asymmetric matrix
const TypeCoeffField& Lower =
const_cast<const BlockLduMatrix<Type>&>(*this).lower();
const TypeCoeffField& Upper =
const_cast<const BlockLduMatrix<Type>&>(*this).upper();
if
(
Lower.activeType() == blockCoeffBase::LINEAR
|| Upper.activeType() == blockCoeffBase::LINEAR
|| Diag.activeType() == blockCoeffBase::LINEAR
)
{
const linearTypeField& activeLower = Lower.asLinear();
const linearTypeField& activeUpper = Upper.asLinear();
linearTypeField& activeDiag = Diag.asLinear();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiag[l[coeffI]] -= activeLower[coeffI];
activeDiag[u[coeffI]] -= activeUpper[coeffI];
}
}
else if
(
Lower.activeType() == blockCoeffBase::SCALAR
|| Upper.activeType() == blockCoeffBase::SCALAR
|| Diag.activeType() == blockCoeffBase::SCALAR
)
{
const scalarTypeField& activeLower = Lower.asScalar();
const scalarTypeField& activeUpper = Upper.asScalar();
scalarTypeField& activeDiag = Diag.asScalar();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiag[l[coeffI]] -= activeLower[coeffI];
activeDiag[u[coeffI]] -= activeUpper[coeffI];
}
}
}
else
{
FatalErrorIn("void BlockLduMatrix<Type>::decoupledNegSumDiag()")
<< "No off-diagonal available"
<< abort(FatalError);
}
}
template<class Type>
void Foam::BlockLduMatrix<Type>::decoupledCheck() const
{
typedef typename TypeCoeffField::scalarTypeField scalarTypeField;
typedef typename TypeCoeffField::linearTypeField linearTypeField;
// Copy the diagonal
TypeCoeffField DiagCopy(this->diag().size());
const unallocLabelList& l = lduAddr().lowerAddr();
const unallocLabelList& u = lduAddr().upperAddr();
if (this->symmetric())
{
// Symmetric matrix: re-use upper for lower coefficients
const TypeCoeffField& Upper = this->upper();
if
(
Upper.activeType() == blockCoeffBase::LINEAR
|| DiagCopy.activeType() == blockCoeffBase::LINEAR
)
{
const linearTypeField& activeUpper = Upper.asLinear();
linearTypeField& activeDiagCopy = DiagCopy.asLinear();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiagCopy[l[coeffI]] += activeUpper[coeffI];
activeDiagCopy[u[coeffI]] += activeUpper[coeffI];
}
Info<< "void BlockLduMatrix<Type>::decoupledCheck() const : "
<< "Symmetric matrix: raw matrix difference: "
<< sum(mag(activeDiagCopy))
<< " scaled: "
<< sum(mag(activeDiagCopy))/sum(mag(this->diag().asLinear()))
<< endl;
}
else if
(
Upper.activeType() == blockCoeffBase::SCALAR
|| DiagCopy.activeType() == blockCoeffBase::SCALAR
)
{
const scalarTypeField& activeUpper = Upper.asScalar();
scalarTypeField& activeDiagCopy = DiagCopy.asScalar();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiagCopy[l[coeffI]] += activeUpper[coeffI];
activeDiagCopy[u[coeffI]] += activeUpper[coeffI];
}
Info<< "void BlockLduMatrix<Type>::decoupledCheck() const : "
<< "Symmetric matrix: raw matrix difference: "
<< sum(mag(activeDiagCopy))
<< " scaled: "
<< sum(mag(activeDiagCopy))/sum(mag(this->diag().asScalar()))
<< endl;
}
}
else if (this->asymmetric())
{
// Full asymmetric matrix
const TypeCoeffField& Lower = this->lower();
const TypeCoeffField& Upper = this->upper();
if
(
Lower.activeType() == blockCoeffBase::LINEAR
|| Upper.activeType() == blockCoeffBase::LINEAR
|| DiagCopy.activeType() == blockCoeffBase::LINEAR
)
{
const linearTypeField& activeLower = Lower.asLinear();
const linearTypeField& activeUpper = Upper.asLinear();
linearTypeField& activeDiagCopy = DiagCopy.asLinear();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiagCopy[l[coeffI]] += activeLower[coeffI];
activeDiagCopy[u[coeffI]] += activeUpper[coeffI];
}
Info<< "void BlockLduMatrix<Type>::decoupledCheck() const : "
<< "Asymmetric matrix: raw matrix difference: "
<< sum(mag(activeDiagCopy))
<< " scaled: "
<< sum(mag(activeDiagCopy))/sum(mag(this->diag().asLinear()))
<< endl;
}
else if
(
Lower.activeType() == blockCoeffBase::SCALAR
|| Upper.activeType() == blockCoeffBase::SCALAR
|| DiagCopy.activeType() == blockCoeffBase::SCALAR
)
{
const scalarTypeField& activeLower = Lower.asScalar();
const scalarTypeField& activeUpper = Upper.asScalar();
scalarTypeField& activeDiagCopy = DiagCopy.asScalar();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiagCopy[l[coeffI]] += activeLower[coeffI];
activeDiagCopy[u[coeffI]] += activeUpper[coeffI];
}
Info<< "void BlockLduMatrix<Type>::decoupledCheck() const : "
<< "Asymmetric matrix: raw matrix difference: "
<< sum(mag(activeDiagCopy))
<< " scaled: "
<< sum(mag(activeDiagCopy))/sum(mag(this->diag().asScalar()))
<< endl;
}
}
else
{
Info<< "void BlockLduMatrix<Type>::decoupledCheck() const : "
<< "Diagonal matrix" << endl;
}
}
template<class Type>
void Foam::BlockLduMatrix<Type>::decoupledRelax
(
const TypeField& x,
TypeField& b,
const scalar alpha
)
{
typedef typename TypeCoeffField::scalarTypeField scalarTypeField;
typedef typename TypeCoeffField::linearTypeField linearTypeField;
//HJ Missing code: add coupling coefficients to under-relaxation
// HJ, 21/Feb/2008
if (alpha <= 0)
{
return;
}
TypeCoeffField& Diag = this->diag();
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
const unallocLabelList& l = lduAddr().lowerAddr();
const unallocLabelList& u = lduAddr().upperAddr();
if (this->symmetric())
{
// Symmetric matrix: re-use upper for lower coefficients
const TypeCoeffField& Upper =
const_cast<const BlockLduMatrix<Type>&>(*this).upper();
if
(
Upper.activeType() == blockCoeffBase::LINEAR
|| Diag.activeType() == blockCoeffBase::LINEAR
)
{
const linearTypeField& activeUpper = Upper.asLinear();
linearTypeField& activeDiag = Diag.asLinear();
// Make a copy of diagonal before relaxation
linearTypeField activeDiagOld = activeDiag;
linearTypeField sumOff
(
activeDiag.size(),
pTraits<typename TypeCoeffField::linearType>::zero
);
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
sumOff[u[coeffI]] += cmptMag(activeUpper[coeffI]);
sumOff[l[coeffI]] += cmptMag(activeUpper[coeffI]);
}
activeDiag = max(activeDiag, sumOff);
activeDiag *= 1.0/alpha;
// Add the relaxation contribution to b
forAll (b, i)
{
b[i] += mult(activeDiag[i] - activeDiagOld[i], x[i]);
}
}
else if
(
Upper.activeType() == blockCoeffBase::SCALAR
|| Diag.activeType() == blockCoeffBase::SCALAR
)
{
const scalarTypeField& activeUpper = Upper.asScalar();
scalarTypeField& activeDiag = Diag.asScalar();
// Make a copy of diagonal before relaxation
scalarTypeField activeDiagOld = activeDiag;
scalarTypeField sumOff
(
activeDiag.size(),
pTraits<typename TypeCoeffField::scalarType>::zero
);
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
sumOff[u[coeffI]] += mag(activeUpper[coeffI]);
sumOff[l[coeffI]] += mag(activeUpper[coeffI]);
}
activeDiag = max(activeDiag, sumOff);
activeDiag *= 1.0/alpha;
// Add the relaxation contribution to b
forAll (b, i)
{
b[i] += mult(activeDiag[i] - activeDiagOld[i], x[i]);
}
}
}
else if (this->asymmetric())
{
// Full asymmetric matrix
const TypeCoeffField& Lower =
const_cast<const BlockLduMatrix<Type>&>(*this).lower();
const TypeCoeffField& Upper =
const_cast<const BlockLduMatrix<Type>&>(*this).upper();
if
(
Lower.activeType() == blockCoeffBase::LINEAR
|| Upper.activeType() == blockCoeffBase::LINEAR
|| Diag.activeType() == blockCoeffBase::LINEAR
)
{
const linearTypeField& activeLower = Lower.asLinear();
const linearTypeField& activeUpper = Upper.asLinear();
linearTypeField& activeDiag = Diag.asLinear();
linearTypeField sumOff
(
activeDiag.size(),
pTraits<typename TypeCoeffField::linearType>::zero
);
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
sumOff[u[coeffI]] += cmptMag(activeLower[coeffI]);
sumOff[l[coeffI]] += cmptMag(activeUpper[coeffI]);
}
activeDiag = max(activeDiag, sumOff);
activeDiag *= 1.0/alpha;
}
else if
(
Lower.activeType() == blockCoeffBase::SCALAR
|| Upper.activeType() == blockCoeffBase::SCALAR
|| Diag.activeType() == blockCoeffBase::SCALAR
)
{
const scalarTypeField& activeLower = Lower.asScalar();
const scalarTypeField& activeUpper = Upper.asScalar();
scalarTypeField& activeDiag = Diag.asScalar();
// Make a copy of diagonal before relaxation
scalarTypeField activeDiagOld = activeDiag;
scalarTypeField sumOff
(
activeDiag.size(),
pTraits<typename TypeCoeffField::scalarType>::zero
);
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
sumOff[u[coeffI]] += mag(activeLower[coeffI]);
sumOff[l[coeffI]] += mag(activeUpper[coeffI]);
}
activeDiag = max(activeDiag, sumOff);
activeDiag *= 1.0/alpha;
forAll (b, i)
{
b[i] += (activeDiag[i] - activeDiagOld[i])*x[i];
}
}
}
}
template<class Type>
void Foam::BlockLduMatrix<Type>::decoupledMultEqOp(const scalarField& sf)
{
typedef typename TypeCoeffField::scalarTypeField scalarTypeField;
typedef typename TypeCoeffField::linearTypeField linearTypeField;
if (diagPtr_)
{
*diagPtr_ *= sf;
}
if (upperPtr_)
{
TypeCoeffField& Upper = *upperPtr_;
const unallocLabelList& l = lduAddr().lowerAddr();
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
scalarTypeField& activeUpper = Upper.asScalar();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeUpper[coeffI] *= sf[l[coeffI]];
}
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
linearTypeField& activeUpper = Upper.asLinear();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeUpper[coeffI] *= sf[l[coeffI]];
}
}
}
if (lowerPtr_)
{
TypeCoeffField& Lower = *lowerPtr_;
const unallocLabelList& u = lduAddr().upperAddr();
if (Lower.activeType() == blockCoeffBase::SCALAR)
{
scalarTypeField& activeLower = Lower.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
activeLower[coeffI] *= sf[u[coeffI]];
}
}
else if (Lower.activeType() == blockCoeffBase::LINEAR)
{
linearTypeField& activeLower = Lower.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
activeLower[coeffI] *= sf[u[coeffI]];
}
}
}
}
template<class Type>
void Foam::BlockLduMatrix<Type>::decoupledAmulCore
(
TypeField& Ax,
const TypeField& x
) const
{
typedef typename TypeCoeffField::scalarTypeField scalarTypeField;
typedef typename TypeCoeffField::linearTypeField linearTypeField;
const unallocLabelList& u = lduAddr().upperAddr();
const unallocLabelList& l = lduAddr().lowerAddr();
// In order to do automatic multiplication, diagonal needs to be recognised
// as a decoupled coeff field. HJ, 19/Feb/2008
// const TypeCoeffField& Diag = this->diag();
const DecoupledCoeffField<Type>& Diag = this->diag();
const TypeCoeffField& Upper = this->upper();
// Diagonal multiplication, no indirection
multiply(Ax, Diag, x);
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
// Lower multiplication
if (symmetric())
{
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeUpper = Upper.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Ax[u[coeffI]] += mult(activeUpper[coeffI], x[l[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeUpper = Upper.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Ax[u[coeffI]] += mult(activeUpper[coeffI], x[l[coeffI]]);
}
}
}
else // Asymmetric matrix
{
const TypeCoeffField& Lower = this->lower();
if (Lower.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeLower = Lower.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Ax[u[coeffI]] += mult(activeLower[coeffI], x[l[coeffI]]);
}
}
else if (Lower.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeLower = Lower.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Ax[u[coeffI]] += mult(activeLower[coeffI], x[l[coeffI]]);
}
}
}
// Upper multiplication
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeUpper = Upper.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Ax[l[coeffI]] += mult(activeUpper[coeffI], x[u[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeUpper = Upper.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Ax[l[coeffI]] += mult(activeUpper[coeffI], x[u[coeffI]]);
}
}
}
template<class Type>
void Foam::BlockLduMatrix<Type>::decoupledTmulCore
(
TypeField& Tx,
const TypeField& x
) const
{
typedef typename TypeCoeffField::scalarTypeField scalarTypeField;
typedef typename TypeCoeffField::linearTypeField linearTypeField;
const unallocLabelList& u = lduAddr().upperAddr();
const unallocLabelList& l = lduAddr().lowerAddr();
// In order to do automatic multiplication, diagonal needs to be recognised
// as a decoupled coeff field. HJ, 19/Feb/2008
const DecoupledCoeffField<Type>& Diag = this->diag();
const TypeCoeffField& Upper = this->upper();
// Diagonal multiplication, no indirection
multiply(Tx, Diag, x);
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
// Upper multiplication
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeUpper = Upper.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Tx[u[coeffI]] += mult(activeUpper[coeffI], x[l[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeUpper = Upper.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Tx[u[coeffI]] += mult(activeUpper[coeffI], x[l[coeffI]]);
}
}
// Lower multiplication
if (symmetric())
{
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeUpper = Upper.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Tx[l[coeffI]] += mult(activeUpper[coeffI], x[u[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeUpper = Upper.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Tx[l[coeffI]] += mult(activeUpper[coeffI], x[u[coeffI]]);
}
}
}
else // Asymmetric matrix
{
const TypeCoeffField& Lower = this->lower();
if (Lower.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeLower = Lower.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Tx[l[coeffI]] += mult(activeLower[coeffI], x[u[coeffI]]);
}
}
else if (Lower.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeLower = Lower.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
Tx[l[coeffI]] += mult(activeLower[coeffI], x[u[coeffI]]);
}
}
}
}
// ************************************************************************* //

View file

@ -0,0 +1,213 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
Vector-matrix multiplication operations for a block matrix
\*---------------------------------------------------------------------------*/
#include "BlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::BlockLduMatrix<Type>::decoupledH(const Field<Type>& x) const
{
typedef typename TypeCoeffField::scalarTypeField scalarTypeField;
typedef typename TypeCoeffField::linearTypeField linearTypeField;
// Create result
tmp<Field<Type> > tresult
(
new Field<Type>(lduAddr().size(), pTraits<Type>::zero)
);
Field<Type>& result = tresult();
const unallocLabelList& u = lduAddr().upperAddr();
const unallocLabelList& l = lduAddr().lowerAddr();
const TypeCoeffField& Upper = this->upper();
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
// Lower multiplication
if (symmetric())
{
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeUpper = Upper.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[u[coeffI]] -= mult(activeUpper[coeffI], x[l[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeUpper = Upper.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[u[coeffI]] -= mult(activeUpper[coeffI], x[l[coeffI]]);
}
}
}
else // Asymmetric matrix
{
const TypeCoeffField& Lower = this->lower();
if (Lower.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeLower = Lower.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[u[coeffI]] -= mult(activeLower[coeffI], x[l[coeffI]]);
}
}
else if (Lower.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeLower = Lower.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[u[coeffI]] -= mult(activeLower[coeffI], x[l[coeffI]]);
}
}
}
// Upper multiplication
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeUpper = Upper.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[l[coeffI]] -= mult(activeUpper[coeffI], x[u[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeUpper = Upper.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[l[coeffI]] -= mult(activeUpper[coeffI], x[u[coeffI]]);
}
}
return tresult;
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::BlockLduMatrix<Type>::decoupledFaceH(const Field<Type>& x) const
{
typedef typename TypeCoeffField::scalarTypeField scalarTypeField;
typedef typename TypeCoeffField::linearTypeField linearTypeField;
const unallocLabelList& u = lduAddr().upperAddr();
const unallocLabelList& l = lduAddr().lowerAddr();
// Create result
tmp<Field<Type> > tresult(new Field<Type>(u.size(), pTraits<Type>::zero));
Field<Type>& result = tresult();
const TypeCoeffField& Upper = this->upper();
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
// Lower multiplication
if (symmetric())
{
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeUpper = Upper.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
// This can be optimised with a subtraction.
// Currently not done for clarity. HJ, 31/Oct/2007
result[coeffI] =
mult(activeUpper[coeffI], x[u[coeffI]])
- mult(activeUpper[coeffI], x[l[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeUpper = Upper.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
// This can be optimised with a subtraction.
// Currently not done for clarity. HJ, 31/Oct/2007
result[coeffI] =
mult(activeUpper[coeffI], x[u[coeffI]])
- mult(activeUpper[coeffI], x[l[coeffI]]);
}
}
}
else // Asymmetric matrix
{
const TypeCoeffField& Lower = this->lower();
if (Lower.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeUpper = Upper.asScalar();
const scalarTypeField& activeLower = Lower.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[coeffI] =
mult(activeUpper[coeffI], x[u[coeffI]])
- mult(activeLower[coeffI], x[l[coeffI]]);
}
}
else if (Lower.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeUpper = Upper.asLinear();
const linearTypeField& activeLower = Lower.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[coeffI] =
mult(activeUpper[coeffI], x[u[coeffI]])
- mult(activeLower[coeffI], x[l[coeffI]]);
}
}
}
return tresult;
}
// ************************************************************************* //

View file

@ -0,0 +1,264 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
Vector-matrix multiplication operations for a block matrix
\*---------------------------------------------------------------------------*/
#include "BlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::BlockLduMatrix<Type>::H(const Field<Type>& x) const
{
typedef typename TypeCoeffField::scalarTypeField scalarTypeField;
typedef typename TypeCoeffField::linearTypeField linearTypeField;
typedef typename TypeCoeffField::squareTypeField squareTypeField;
// Create result
tmp<Field<Type> > tresult
(
new Field<Type>(lduAddr().size(), pTraits<Type>::zero)
);
Field<Type>& result = tresult();
const unallocLabelList& u = lduAddr().upperAddr();
const unallocLabelList& l = lduAddr().lowerAddr();
const TypeCoeffField& Upper = this->upper();
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
// Lower multiplication
if (symmetric())
{
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeUpper = Upper.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[u[coeffI]] -= mult(activeUpper[coeffI], x[l[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeUpper = Upper.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[u[coeffI]] -= mult(activeUpper[coeffI], x[l[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::SQUARE)
{
const squareTypeField& activeUpper = Upper.asSquare();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
// Use transpose upper coefficient
result[u[coeffI]] -=
mult(activeUpper[coeffI].T(), x[l[coeffI]]);
}
}
}
else // Asymmetric matrix
{
const TypeCoeffField& Lower = this->lower();
if (Lower.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeLower = Lower.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[u[coeffI]] -= mult(activeLower[coeffI], x[l[coeffI]]);
}
}
else if (Lower.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeLower = Lower.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[u[coeffI]] -= mult(activeLower[coeffI], x[l[coeffI]]);
}
}
else if (Lower.activeType() == blockCoeffBase::SQUARE)
{
const squareTypeField& activeLower = Lower.asSquare();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[u[coeffI]] -= mult(activeLower[coeffI], x[l[coeffI]]);
}
}
}
// Upper multiplication
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeUpper = Upper.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[l[coeffI]] -= mult(activeUpper[coeffI], x[u[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeUpper = Upper.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[l[coeffI]] -= mult(activeUpper[coeffI], x[u[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::SQUARE)
{
const squareTypeField& activeUpper = Upper.asSquare();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[l[coeffI]] -= mult(activeUpper[coeffI], x[u[coeffI]]);
}
}
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::BlockLduMatrix<Type>::faceH(const Field<Type>& x) const
{
typedef typename TypeCoeffField::scalarTypeField scalarTypeField;
typedef typename TypeCoeffField::linearTypeField linearTypeField;
typedef typename TypeCoeffField::squareTypeField squareTypeField;
const unallocLabelList& u = lduAddr().upperAddr();
const unallocLabelList& l = lduAddr().lowerAddr();
// Create result
tmp<Field<Type> > tresult(new Field<Type>(u.size(), pTraits<Type>::zero));
Field<Type>& result = tresult();
const TypeCoeffField& Upper = this->upper();
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
// Lower multiplication
if (symmetric())
{
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeUpper = Upper.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
// This can be optimised with a subtraction.
// Currently not done for clarity. HJ, 31/Oct/2007
result[coeffI] =
mult(activeUpper[coeffI], x[u[coeffI]])
- mult(activeUpper[coeffI], x[l[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeUpper = Upper.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
// This can be optimised with a subtraction.
// Currently not done for clarity. HJ, 31/Oct/2007
result[coeffI] =
mult(activeUpper[coeffI], x[u[coeffI]])
- mult(activeUpper[coeffI], x[l[coeffI]]);
}
}
else if (Upper.activeType() == blockCoeffBase::SQUARE)
{
const squareTypeField& activeUpper = Upper.asSquare();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
// Use transpose upper coefficient
result[coeffI] =
mult(activeUpper[coeffI], x[u[coeffI]])
- mult(activeUpper[coeffI].T(), x[l[coeffI]]);
}
}
}
else // Asymmetric matrix
{
const TypeCoeffField& Lower = this->lower();
if (Lower.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeUpper = Upper.asScalar();
const scalarTypeField& activeLower = Lower.asScalar();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[coeffI] =
mult(activeUpper[coeffI], x[u[coeffI]])
- mult(activeLower[coeffI], x[l[coeffI]]);
}
}
else if (Lower.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeUpper = Upper.asLinear();
const linearTypeField& activeLower = Lower.asLinear();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[coeffI] =
mult(activeUpper[coeffI], x[u[coeffI]])
- mult(activeLower[coeffI], x[l[coeffI]]);
}
}
else if (Lower.activeType() == blockCoeffBase::SQUARE)
{
const squareTypeField& activeUpper = Upper.asSquare();
const squareTypeField& activeLower = Lower.asSquare();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
result[coeffI] =
mult(activeUpper[coeffI], x[u[coeffI]])
- mult(activeLower[coeffI], x[l[coeffI]]);
}
}
}
}
// ************************************************************************* //

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,64 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
Update of block interfaces
\*---------------------------------------------------------------------------*/
#include "BlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
void Foam::BlockLduMatrix<Type>::initInterfaces
(
TypeField& Ax,
const TypeField& x
) const
{
forAll (interfaces_, interfaceI)
{
interfaces_[interfaceI].initMatrixUpdate(*this, Ax, x);
}
}
template<class Type>
void Foam::BlockLduMatrix<Type>::updateInterfaces
(
const FieldField<CoeffField, Type>& coeffs,
TypeField& Ax,
const TypeField& x
) const
{
forAll (interfaces_, interfaceI)
{
interfaces_[interfaceI].updateMatrix(*this, coeffs, Ax, x);
}
}
// ************************************************************************* //

View file

@ -0,0 +1,53 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
Block matrix member static data members
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
\*---------------------------------------------------------------------------*/
#include "blockLduMatrices.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineNamedTemplateTypeNameAndDebug(blockScalarMatrix, 0);
defineNamedTemplateTypeNameAndDebug(blockVectorMatrix, 0);
defineNamedTemplateTypeNameAndDebug(blockSphericalTensorMatrix, 0);
defineNamedTemplateTypeNameAndDebug(blockSymmTensorMatrix, 0);
defineNamedTemplateTypeNameAndDebug(blockTensorMatrix, 0);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,68 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockLduMatrix
Description
Typedefs for block matrices
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
\*---------------------------------------------------------------------------*/
#ifndef blockLduMatrices_H
#define blockLduMatrices_H
#include "scalarBlockLduMatrix.H"
#include "sphericalTensorBlockLduMatrix.H"
#include "symmTensorBlockLduMatrix.H"
#include "tensorBlockLduMatrix.H"
#include "Map.H"
#include "blockConstraints.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef BlockLduMatrix<scalar> blockScalarMatrix;
typedef BlockLduMatrix<vector> blockVectorMatrix;
typedef BlockLduMatrix<sphericalTensor> blockSphericalTensorMatrix;
typedef BlockLduMatrix<symmTensor> blockSymmTensorMatrix;
typedef BlockLduMatrix<tensor> blockTensorMatrix;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,430 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#ifndef scalarBlockLduMatrix_H
#define scalarBlockLduMatrix_H
#include "BlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void BlockLduMatrix<scalar>::sumDiag()
{
scalarField& activeDiag = this->diag();
const unallocLabelList& l = lduAddr().lowerAddr();
const unallocLabelList& u = lduAddr().upperAddr();
if (symmetric())
{
const scalarField& activeUpper = this->upper();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiag[l[coeffI]] += activeUpper[coeffI];
activeDiag[u[coeffI]] += activeUpper[coeffI];
}
}
else if (asymmetric())
{
const scalarField& activeLower = this->lower();
const scalarField& activeUpper = this->upper();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiag[l[coeffI]] += activeLower[coeffI];
activeDiag[u[coeffI]] += activeUpper[coeffI];
}
}
else
{
FatalErrorIn("void BlockLduMatrix<scalar>::sumDiag()")
<< "No off-diagonal available"
<< abort(FatalError);
}
}
template<>
void BlockLduMatrix<scalar>::negSumDiag()
{
scalarField& activeDiag = this->diag();
const unallocLabelList& l = lduAddr().lowerAddr();
const unallocLabelList& u = lduAddr().upperAddr();
if (symmetric())
{
const scalarField& activeUpper = this->upper();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiag[l[coeffI]] -= activeUpper[coeffI];
activeDiag[u[coeffI]] -= activeUpper[coeffI];
}
}
else if (asymmetric())
{
const scalarField& activeLower = this->lower();
const scalarField& activeUpper = this->upper();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiag[l[coeffI]] -= activeLower[coeffI];
activeDiag[u[coeffI]] -= activeUpper[coeffI];
}
}
else
{
FatalErrorIn("void BlockLduMatrix<scalar>::negSumDiag()")
<< "No off-diagonal available"
<< abort(FatalError);
}
}
template<>
void BlockLduMatrix<scalar>::check() const
{
// Copy the diagonal
scalarField activeDiagCopy = this->diag();
const unallocLabelList& l = lduAddr().lowerAddr();
const unallocLabelList& u = lduAddr().upperAddr();
if (symmetric())
{
const scalarField& activeUpper = this->upper();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiagCopy[l[coeffI]] -= activeUpper[coeffI];
activeDiagCopy[u[coeffI]] -= activeUpper[coeffI];
}
Info<< "void BlockLduMatrix<scalar>::check() const : "
<< "Symmetric matrix: raw matrix difference: "
<< sum(mag(activeDiagCopy))
<< " scaled: "
<< sum(mag(activeDiagCopy))/sum(mag(this->diag()))
<< endl;
}
else if (asymmetric())
{
const scalarField& activeLower = this->lower();
const scalarField& activeUpper = this->upper();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeDiagCopy[l[coeffI]] -= activeLower[coeffI];
activeDiagCopy[u[coeffI]] -= activeUpper[coeffI];
}
Info<< "void BlockLduMatrix<scalar>::check() const : "
<< "Asymmetric matrix: raw matrix difference: "
<< sum(mag(activeDiagCopy))
<< " scaled: "
<< sum(mag(activeDiagCopy))/sum(mag(this->diag()))
<< endl;
}
else
{
Info<< "void BlockLduMatrix<scalar>::check() const : "
<< "Diagonal matrix" << endl;
}
}
template<>
void BlockLduMatrix<scalar>::relax
(
const scalarField& x,
scalarField& b,
const scalar alpha
)
{
scalarField& activeDiag = this->diag();
scalarField activeDiagOld = this->diag();
const unallocLabelList& l = lduAddr().lowerAddr();
const unallocLabelList& u = lduAddr().upperAddr();
scalarField sumOff(activeDiag.size(), 0.0);
if (symmetric())
{
const scalarField& activeUpper = this->upper();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
sumOff[u[coeffI]] += mag(activeUpper[coeffI]);
sumOff[l[coeffI]] += mag(activeUpper[coeffI]);
}
}
else if (asymmetric())
{
const scalarField& activeLower = this->lower();
const scalarField& activeUpper = this->upper();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
sumOff[u[coeffI]] += mag(activeLower[coeffI]);
sumOff[l[coeffI]] += mag(activeUpper[coeffI]);
}
}
activeDiag = max(activeDiag, sumOff);
activeDiag *= 1.0/alpha;
// Add the relaxation contribution to b
b += (activeDiag - activeDiagOld)*x;
}
template<>
void BlockLduMatrix<scalar>::operator*=(const scalarField& sf)
{
if (diagPtr_)
{
*diagPtr_ *= sf;
}
if (upperPtr_)
{
scalarField& activeUpper = *upperPtr_;
const unallocLabelList& l = lduAddr().lowerAddr();
for (register label coeffI = 0; coeffI < l.size(); coeffI++)
{
activeUpper[coeffI] *= sf[l[coeffI]];
}
}
if (lowerPtr_)
{
scalarField& activeLower = *lowerPtr_;
const unallocLabelList& u = lduAddr().upperAddr();
for (register label coeffI = 0; coeffI < u.size(); coeffI++)
{
activeLower[coeffI] *= sf[u[coeffI]];
}
}
}
template<>
void BlockLduMatrix<scalar>::AmulCore
(
scalarField& Ax,
const scalarField& x
) const
{
const scalarField& Diag = diag();
for (register label rowI = 0; rowI < x.size(); rowI++)
{
Ax[rowI] = Diag[rowI]*x[rowI];
}
// Note: pointer looping
const label* const __restrict__ U = lduAddr().upperAddr().begin();
const label* const __restrict__ L = lduAddr().lowerAddr().begin();
if (symmetric())
{
const scalar* const __restrict__ Upper = upper().begin();
const scalar* const __restrict__ X = x.begin();
scalar* __restrict__ AX = Ax.begin();
for (register label coeffI = 0; coeffI < upper().size(); coeffI++)
{
AX[U[coeffI]] += Upper[coeffI]*X[L[coeffI]];
AX[L[coeffI]] += Upper[coeffI]*X[U[coeffI]];
}
}
else if (asymmetric())
{
const scalar* const __restrict__ Lower = lower().begin();
const scalar* const __restrict__ Upper = upper().begin();
const scalar* const __restrict__ X = x.begin();
scalar* __restrict__ AX = Ax.begin();
for (register label coeffI = 0; coeffI < upper().size(); coeffI++)
{
AX[U[coeffI]] += Lower[coeffI]*X[L[coeffI]];
AX[L[coeffI]] += Upper[coeffI]*X[U[coeffI]];
}
}
}
template<>
void BlockLduMatrix<scalar>::TmulCore
(
scalarField& Tx,
const scalarField& x
) const
{
const scalarField& Diag = diag();
for (register label rowI = 0; rowI < x.size(); rowI++)
{
Tx[rowI] = Diag[rowI]*x[rowI];
}
// Note: pointer looping
const label* const __restrict__ U = lduAddr().upperAddr().begin();
const label* const __restrict__ L = lduAddr().lowerAddr().begin();
if (symmetric())
{
const scalar* const __restrict__ Upper = upper().begin();
const scalar* const __restrict__ X = x.begin();
scalar* __restrict__ TX = Tx.begin();
for (register label coeffI = 0; coeffI < upper().size(); coeffI++)
{
TX[U[coeffI]] += Upper[coeffI]*X[L[coeffI]];
TX[L[coeffI]] += Upper[coeffI]*X[U[coeffI]];
}
}
else if (asymmetric())
{
const scalar* const __restrict__ Lower = lower().begin();
const scalar* const __restrict__ Upper = upper().begin();
const scalar* const __restrict__ X = x.begin();
scalar* __restrict__ TX = Tx.begin();
for (register label coeffI = 0; coeffI < upper().size(); coeffI++)
{
TX[U[coeffI]] += Upper[coeffI]*X[L[coeffI]];
TX[L[coeffI]] += Lower[coeffI]*X[U[coeffI]];
}
}
}
template<>
void BlockLduMatrix<scalar>::segregateB
(
scalarField&,
const scalarField&
) const
{
FatalErrorIn
(
"void BlockLduMatrix<scalar>::segregateB\n"
"(\n"
" scalarField&,\n"
" const scalarField&\n"
") const"
) << "Requested decoupling of scalar matrix - never coupled"
<< abort(FatalError);
}
template<>
tmp<scalarField> BlockLduMatrix<scalar>::H(const scalarField& x) const
{
tmp<scalarField> tresult(new scalarField(lduAddr().size(), 0));
scalarField& result = tresult();
if (thereIsUpper() || thereIsLower())
{
// Note: pointer looping
const label* const __restrict__ U = lduAddr().upperAddr().begin();
const label* const __restrict__ L = lduAddr().lowerAddr().begin();
const scalar* const __restrict__ Lower = lower().begin();
const scalar* const __restrict__ Upper = upper().begin();
const scalar* const __restrict__ X = x.begin();
scalar* __restrict__ R = result.begin();
for (register label coeffI = 0; coeffI < upper().size(); coeffI++)
{
R[U[coeffI]] -= Upper[coeffI]*X[U[coeffI]];
}
for (register label coeffI = 0; coeffI < upper().size(); coeffI++)
{
R[L[coeffI]] -= Lower[coeffI]*X[L[coeffI]];
}
}
return tresult;
}
template<>
tmp<scalarField> BlockLduMatrix<scalar>::faceH(const scalarField& x) const
{
tmp<scalarField> tresult(new scalarField(lduAddr().upperAddr().size(), 0));
scalarField& result = tresult();
if (thereIsUpper() || thereIsLower())
{
// Note: pointer looping
const label* const __restrict__ U = lduAddr().upperAddr().begin();
const label* const __restrict__ L = lduAddr().lowerAddr().begin();
const scalar* const __restrict__ Lower = lower().begin();
const scalar* const __restrict__ Upper = upper().begin();
const scalar* const __restrict__ X = x.begin();
scalar* __restrict__ R = result.begin();
for (register label coeffI = 0; coeffI < upper().size(); coeffI++)
{
R[coeffI] = Upper[coeffI]*X[U[coeffI]] - Lower[coeffI]*X[L[coeffI]];
}
}
return tresult;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,105 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockLduMatrix
Description
Template specialisation for scalar block matrix
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
scalarBlockLduMatrix.C
\*---------------------------------------------------------------------------*/
#ifndef scalarBlockLduMatrix_H
#define scalarBlockLduMatrix_H
#include "BlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void BlockLduMatrix<scalar>::sumDiag();
template<>
void BlockLduMatrix<scalar>::negSumDiag();
template<>
void BlockLduMatrix<scalar>::check() const;
template<>
void BlockLduMatrix<scalar>::relax
(
const scalarField& x,
scalarField& b,
const scalar alpha
);
template<>
void BlockLduMatrix<scalar>::operator*=(const scalarField& sf);
template<>
void BlockLduMatrix<scalar>::AmulCore
(
scalarField& mul,
const scalarField& x
) const;
template<>
void BlockLduMatrix<scalar>::TmulCore
(
scalarField& mul,
const scalarField& x
) const;
template<>
void BlockLduMatrix<scalar>::segregateB
(
scalarField& mul,
const scalarField& x
) const;
template<>
tmp<scalarField> BlockLduMatrix<scalar>::H(const scalarField& x) const;
template<>
tmp<scalarField> BlockLduMatrix<scalar>::faceH(const scalarField& x) const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,159 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#ifndef sphericalTensorBlockLduMatrix_H
#define sphericalTensorBlockLduMatrix_H
#include "BlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockLduMatrix<Foam::sphericalTensor>::sumDiag()
{
// Decoupled version
this->decoupledSumDiag();
}
template<>
void Foam::BlockLduMatrix<Foam::sphericalTensor>::negSumDiag()
{
// Decoupled version
this->decoupledNegSumDiag();
}
template<>
void Foam::BlockLduMatrix<sphericalTensor>::check() const
{
// Decoupled version
this->decoupledCheck();
}
template<>
void Foam::BlockLduMatrix<Foam::sphericalTensor>::relax
(
const sphericalTensorField& x,
sphericalTensorField& b,
const scalar alpha
)
{
// Decoupled version
this->decoupledRelax(x, b, alpha);
}
template<>
void Foam::BlockLduMatrix<Foam::sphericalTensor>::operator*=
(
const scalarField& sf
)
{
// Decoupled version
this->decoupledMultEqOp(sf);
}
template<>
void Foam::BlockLduMatrix<Foam::sphericalTensor>::AmulCore
(
sphericalTensorField& Ax,
const sphericalTensorField& x
) const
{
decoupledAmulCore(Ax, x);
}
template<>
void Foam::BlockLduMatrix<Foam::sphericalTensor>::TmulCore
(
sphericalTensorField& Tx,
const sphericalTensorField& x
) const
{
// Decoupled version
decoupledTmulCore(Tx, x);
}
template<>
void Foam::BlockLduMatrix<Foam::sphericalTensor>::segregateB
(
sphericalTensorField&,
const sphericalTensorField&
) const
{
FatalErrorIn
(
"void Foam::BlockLduMatrix<sphericalTensor>::segregateB\n"
"(\n"
" sphericalTensorField&,\n"
" const sphericalTensorField&\n"
") const"
) << "Requested decoupling of sphericalTensor matrix - never coupled"
<< abort(FatalError);
}
template<>
Foam::tmp<Foam::sphericalTensorField>
Foam::BlockLduMatrix<Foam::sphericalTensor>::H
(
const sphericalTensorField& x
) const
{
// Decoupled version
return decoupledH(x);
}
template<>
Foam::tmp<Foam::sphericalTensorField>
Foam::BlockLduMatrix<Foam::sphericalTensor>::faceH
(
const sphericalTensorField& x
) const
{
// Decoupled version
return decoupledFaceH(x);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,108 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockLduMatrix
Description
Template specialisation for sphericalTensor block matrix
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
sphericalTensorBlockLduMatrix.C
\*---------------------------------------------------------------------------*/
#ifndef sphericalTensorBlockLduMatrix_H
#define sphericalTensorBlockLduMatrix_H
#include "BlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void BlockLduMatrix<sphericalTensor>::sumDiag();
template<>
void BlockLduMatrix<sphericalTensor>::negSumDiag();
template<>
void BlockLduMatrix<sphericalTensor>::check() const;
template<>
void BlockLduMatrix<sphericalTensor>::relax
(
const sphericalTensorField& x,
sphericalTensorField& b,
const scalar alpha
);
template<>
void BlockLduMatrix<sphericalTensor>::operator*=(const scalarField& sf);
template<>
void BlockLduMatrix<sphericalTensor>::AmulCore
(
sphericalTensorField& mul,
const sphericalTensorField& x
) const;
template<>
void BlockLduMatrix<sphericalTensor>::TmulCore
(
sphericalTensorField& mul,
const sphericalTensorField& x
) const;
template<>
void BlockLduMatrix<sphericalTensor>::segregateB
(
sphericalTensorField& mul,
const sphericalTensorField& x
) const;
template<>
tmp<sphericalTensorField>
BlockLduMatrix<sphericalTensor>::H(const sphericalTensorField& x) const;
template<>
tmp<sphericalTensorField>
BlockLduMatrix<sphericalTensor>::faceH(const sphericalTensorField& x) const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,150 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#ifndef symmTensorBlockLduMatrix_H
#define symmTensorBlockLduMatrix_H
#include "BlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockLduMatrix<Foam::symmTensor>::sumDiag()
{
// Decoupled version
this->decoupledSumDiag();
}
template<>
void Foam::BlockLduMatrix<Foam::symmTensor>::negSumDiag()
{
// Decoupled version
this->decoupledNegSumDiag();
}
template<>
void Foam::BlockLduMatrix<symmTensor>::check() const
{
// Decoupled version
this->decoupledCheck();
}
template<>
void Foam::BlockLduMatrix<Foam::symmTensor>::relax
(
const symmTensorField& x,
symmTensorField& b,
const scalar alpha
)
{
// Decoupled version
this->decoupledRelax(x, b, alpha);
}
template<>
void Foam::BlockLduMatrix<Foam::symmTensor>::operator*=(const scalarField& sf)
{
// Decoupled version
this->decoupledMultEqOp(sf);
}
template<>
void Foam::BlockLduMatrix<Foam::symmTensor>::AmulCore
(
symmTensorField& Ax,
const symmTensorField& x
) const
{
decoupledAmulCore(Ax, x);
}
template<>
void Foam::BlockLduMatrix<Foam::symmTensor>::TmulCore
(
symmTensorField& Tx,
const symmTensorField& x
) const
{
// Decoupled version
decoupledTmulCore(Tx, x);
}
template<>
void Foam::BlockLduMatrix<Foam::symmTensor>::segregateB
(
symmTensorField&,
const symmTensorField&
) const
{
FatalErrorIn
(
"void Foam::BlockLduMatrix<symmTensor>::segregateB\n"
"(\n"
" symmTensorField&,\n"
" const symmTensorField&\n"
") const"
) << "Requested decoupling of symmTensor matrix - never coupled"
<< abort(FatalError);
}
template<>
Foam::tmp<Foam::symmTensorField>
Foam::BlockLduMatrix<Foam::symmTensor>::H(const symmTensorField& x) const
{
// Decoupled version
return decoupledH(x);
}
template<>
Foam::tmp<Foam::symmTensorField>
Foam::BlockLduMatrix<Foam::symmTensor>::faceH(const symmTensorField& x) const
{
// Decoupled version
return decoupledFaceH(x);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,108 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockLduMatrix
Description
Template specialisation for symmTensor block matrix
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
symmTensorBlockLduMatrix.C
\*---------------------------------------------------------------------------*/
#ifndef symmTensorBlockLduMatrix_H
#define symmTensorBlockLduMatrix_H
#include "BlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void BlockLduMatrix<symmTensor>::sumDiag();
template<>
void BlockLduMatrix<symmTensor>::negSumDiag();
template<>
void BlockLduMatrix<symmTensor>::check() const;
template<>
void BlockLduMatrix<symmTensor>::relax
(
const symmTensorField& x,
symmTensorField& b,
const scalar alpha
);
template<>
void BlockLduMatrix<symmTensor>::operator*=(const scalarField& sf);
template<>
void BlockLduMatrix<symmTensor>::AmulCore
(
symmTensorField& mul,
const symmTensorField& x
) const;
template<>
void BlockLduMatrix<symmTensor>::TmulCore
(
symmTensorField& mul,
const symmTensorField& x
) const;
template<>
void BlockLduMatrix<symmTensor>::segregateB
(
symmTensorField& mul,
const symmTensorField& x
) const;
template<>
tmp<symmTensorField>
BlockLduMatrix<symmTensor>::H(const symmTensorField& x) const;
template<>
tmp<symmTensorField>
BlockLduMatrix<symmTensor>::faceH(const symmTensorField& x) const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,150 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#ifndef tensorBlockLduMatrix_H
#define tensorBlockLduMatrix_H
#include "BlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockLduMatrix<Foam::tensor>::sumDiag()
{
// Decoupled version
this->decoupledSumDiag();
}
template<>
void Foam::BlockLduMatrix<Foam::tensor>::negSumDiag()
{
// Decoupled version
this->decoupledNegSumDiag();
}
template<>
void Foam::BlockLduMatrix<tensor>::check() const
{
// Decoupled version
this->decoupledCheck();
}
template<>
void Foam::BlockLduMatrix<Foam::tensor>::relax
(
const tensorField& x,
tensorField& b,
const scalar alpha
)
{
// Decoupled version
this->decoupledRelax(x, b, alpha);
}
template<>
void Foam::BlockLduMatrix<Foam::tensor>::operator*=(const scalarField& sf)
{
// Decoupled version
this->decoupledMultEqOp(sf);
}
template<>
void Foam::BlockLduMatrix<Foam::tensor>::AmulCore
(
tensorField& Ax,
const tensorField& x
) const
{
decoupledAmulCore(Ax, x);
}
template<>
void Foam::BlockLduMatrix<Foam::tensor>::TmulCore
(
tensorField& Tx,
const tensorField& x
) const
{
// Decoupled version
decoupledTmulCore(Tx, x);
}
template<>
void Foam::BlockLduMatrix<Foam::tensor>::segregateB
(
tensorField&,
const tensorField&
) const
{
FatalErrorIn
(
"void Foam::BlockLduMatrix<tensor>::segregateB\n"
"(\n"
" tensorField&,\n"
" const tensorField&\n"
") const"
) << "Requested decoupling of tensor matrix - never coupled"
<< abort(FatalError);
}
template<>
Foam::tmp<Foam::tensorField>
Foam::BlockLduMatrix<Foam::tensor>::H(const tensorField& x) const
{
// Decoupled version
return decoupledH(x);
}
template<>
Foam::tmp<Foam::tensorField>
Foam::BlockLduMatrix<Foam::tensor>::faceH(const tensorField& x) const
{
// Decoupled version
return decoupledFaceH(x);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,106 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockLduMatrix
Description
Template specialisation for tensor block matrix
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
tensorBlockLduMatrix.C
\*---------------------------------------------------------------------------*/
#ifndef tensorBlockLduMatrix_H
#define tensorBlockLduMatrix_H
#include "BlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void BlockLduMatrix<tensor>::sumDiag();
template<>
void BlockLduMatrix<tensor>::negSumDiag();
template<>
void BlockLduMatrix<tensor>::check() const;
template<>
void BlockLduMatrix<tensor>::relax
(
const tensorField& x,
tensorField& b,
const scalar alpha
);
template<>
void BlockLduMatrix<tensor>::operator*=(const scalarField& sf);
template<>
void BlockLduMatrix<tensor>::AmulCore
(
tensorField& mul,
const tensorField& x
) const;
template<>
void BlockLduMatrix<tensor>::TmulCore
(
tensorField& mul,
const tensorField& x
) const;
template<>
void BlockLduMatrix<tensor>::segregateB
(
tensorField& mul,
const tensorField& x
) const;
template<>
tmp<tensorField> BlockLduMatrix<tensor>::H(const tensorField& x) const;
template<>
tmp<tensorField> BlockLduMatrix<tensor>::faceH(const tensorField& x) const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,927 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "BlockCholeskyPrecon.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
void Foam::BlockCholeskyPrecon<Type>::calcPreconDiag()
{
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 (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
// Transpose multiplication
diagMultiplyCoeffT
(
preconDiag_.asSquare(),
UpperCoeff.asSquare()
);
}
}
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 if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
// Transpose multiplication
diagMultiplyCoeffT
(
preconDiag_.asSquare(),
UpperCoeff.asSquare()
);
}
}
else if (preconDiag_.activeType() == blockCoeffBase::SQUARE)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
diagMultiply
(
preconDiag_.asSquare(),
UpperCoeff.asScalar()
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
diagMultiply
(
preconDiag_.asSquare(),
UpperCoeff.asLinear()
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
// Transpose multiplication
diagMultiplyCoeffT
(
preconDiag_.asSquare(),
UpperCoeff.asSquare()
);
}
}
}
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 (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
diagMultiply
(
preconDiag_.asSquare(),
LowerCoeff.asSquare(),
UpperCoeff.asSquare()
);
}
}
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()
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
diagMultiply
(
preconDiag_.asSquare(),
LowerCoeff.asSquare(),
UpperCoeff.asSquare()
);
}
}
else if (preconDiag_.activeType() == blockCoeffBase::SQUARE)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
diagMultiply
(
preconDiag_.asSquare(),
LowerCoeff.asScalar(),
UpperCoeff.asScalar()
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
diagMultiply
(
preconDiag_.asSquare(),
LowerCoeff.asLinear(),
UpperCoeff.asLinear()
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
diagMultiply
(
preconDiag_.asSquare(),
LowerCoeff.asSquare(),
UpperCoeff.asSquare()
);
}
}
}
}
template<class Type>
template<class DiagType, class ULType>
void Foam::BlockCholeskyPrecon<Type>::diagMultiply
(
Field<DiagType>& dDiag,
const Field<ULType>& upper
)
{
// Precondition the diagonal
// Get addressing
const unallocLabelList& upperAddr = this->matrix_.lduAddr().upperAddr();
const unallocLabelList& lowerAddr = this->matrix_.lduAddr().lowerAddr();
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
forAll (upper, coeffI)
{
dDiag[upperAddr[coeffI]] -=
mult.tripleProduct
(
upper[coeffI],
dDiag[lowerAddr[coeffI]],
upper[coeffI]
);
}
// Invert the diagonal for future use
forAll (dDiag, i)
{
dDiag[i] = mult.inverse(dDiag[i]);
}
}
template<class Type>
template<class DiagType, class ULType>
void Foam::BlockCholeskyPrecon<Type>::diagMultiplyCoeffT
(
Field<DiagType>& dDiag,
const Field<ULType>& upper
)
{
// Precondition the diagonal
// Get addressing
const unallocLabelList& upperAddr = this->matrix_.lduAddr().upperAddr();
const unallocLabelList& lowerAddr = this->matrix_.lduAddr().lowerAddr();
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
forAll (upper, coeffI)
{
dDiag[upperAddr[coeffI]] -=
mult.tripleProduct
(
upper[coeffI].T(), // Upper coefficient transposed
dDiag[lowerAddr[coeffI]],
upper[coeffI]
);
}
// Invert the diagonal for future use
forAll (dDiag, i)
{
dDiag[i] = mult.inverse(dDiag[i]);
}
}
template<class Type>
template<class DiagType, class ULType>
void Foam::BlockCholeskyPrecon<Type>::diagMultiply
(
Field<DiagType>& dDiag,
const Field<ULType>& lower,
const Field<ULType>& upper
)
{
// Precondition the diagonal
// Get addressing
const unallocLabelList& upperAddr = this->matrix_.lduAddr().upperAddr();
const unallocLabelList& lowerAddr = this->matrix_.lduAddr().lowerAddr();
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
forAll (upper, coeffI)
{
dDiag[upperAddr[coeffI]] -=
mult.tripleProduct
(
lower[coeffI],
dDiag[lowerAddr[coeffI]],
upper[coeffI]
);
}
// Invert the diagonal for future use
forAll (dDiag, i)
{
dDiag[i] = mult.inverse(dDiag[i]);
}
}
template<class Type>
template<class DiagType, class ULType>
void Foam::BlockCholeskyPrecon<Type>::ILUmultiply
(
Field<Type>& x,
const Field<DiagType>& dDiag,
const Field<ULType>& upper,
const Field<Type>& b
) const
{
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
forAll(x, i)
{
x[i] = mult(dDiag[i], b[i]);
}
const unallocLabelList& upperAddr = this->matrix_.lduAddr().upperAddr();
const unallocLabelList& lowerAddr = this->matrix_.lduAddr().lowerAddr();
forAll (upper, coeffI)
{
x[upperAddr[coeffI]] -=
mult
(
dDiag[upperAddr[coeffI]],
mult(upper[coeffI], x[lowerAddr[coeffI]])
);
}
forAllReverse (upper, coeffI)
{
x[lowerAddr[coeffI]] -=
mult
(
dDiag[lowerAddr[coeffI]],
mult(upper[coeffI], x[upperAddr[coeffI]])
);
}
}
template<class Type>
template<class DiagType, class ULType>
void Foam::BlockCholeskyPrecon<Type>::ILUmultiplyCoeffT
(
Field<Type>& x,
const Field<DiagType>& dDiag,
const Field<ULType>& upper,
const Field<Type>& b
) const
{
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
forAll(x, i)
{
x[i] = mult(dDiag[i], b[i]);
}
const unallocLabelList& upperAddr = this->matrix_.lduAddr().upperAddr();
const unallocLabelList& lowerAddr = this->matrix_.lduAddr().lowerAddr();
forAll (upper, coeffI)
{
x[upperAddr[coeffI]] -=
mult
(
dDiag[upperAddr[coeffI]],
mult(upper[coeffI].T(), x[lowerAddr[coeffI]])
);
}
forAllReverse (upper, coeffI)
{
x[lowerAddr[coeffI]] -=
mult
(
dDiag[lowerAddr[coeffI]],
mult(upper[coeffI], x[upperAddr[coeffI]])
);
}
}
template<class Type>
template<class DiagType, class ULType>
void Foam::BlockCholeskyPrecon<Type>::ILUmultiply
(
Field<Type>& x,
const Field<DiagType>& dDiag,
const Field<ULType>& lower,
const Field<ULType>& upper,
const Field<Type>& b
) const
{
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
forAll(x, i)
{
x[i] = mult(dDiag[i], b[i]);
}
const unallocLabelList& upperAddr = this->matrix_.lduAddr().upperAddr();
const unallocLabelList& lowerAddr = this->matrix_.lduAddr().lowerAddr();
const unallocLabelList& losortAddr = this->matrix_.lduAddr().losortAddr();
register label losortCoeff;
forAll (lower, coeffI)
{
losortCoeff = losortAddr[coeffI];
x[upperAddr[losortCoeff]] -=
mult
(
dDiag[upperAddr[losortCoeff]],
mult(lower[losortCoeff], x[lowerAddr[losortCoeff]])
);
}
forAllReverse (upper, coeffI)
{
x[lowerAddr[coeffI]] -=
mult
(
dDiag[lowerAddr[coeffI]],
mult(upper[coeffI], x[upperAddr[coeffI]])
);
}
}
template<class Type>
template<class DiagType, class ULType>
void Foam::BlockCholeskyPrecon<Type>::ILUmultiplyTranspose
(
Field<Type>& x,
const Field<DiagType>& dDiag,
const Field<ULType>& lower,
const Field<ULType>& upper,
const Field<Type>& b
) const
{
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
forAll(x, i)
{
x[i] = mult(dDiag[i], b[i]);
}
const unallocLabelList& upperAddr = this->matrix_.lduAddr().upperAddr();
const unallocLabelList& lowerAddr = this->matrix_.lduAddr().lowerAddr();
const unallocLabelList& losortAddr = this->matrix_.lduAddr().losortAddr();
register label losortCoeff;
//HJ Not sure if the coefficient itself needs to be transposed.
// HJ, 30/Oct/2007
forAll (lower, coeffI)
{
x[upperAddr[coeffI]] -=
mult
(
dDiag[upperAddr[coeffI]],
mult(upper[coeffI], x[lowerAddr[coeffI]])
);
}
forAllReverse (upper, coeffI)
{
losortCoeff = losortAddr[coeffI];
x[lowerAddr[losortCoeff]] -=
mult
(
dDiag[lowerAddr[losortCoeff]],
mult(lower[losortCoeff], x[upperAddr[losortCoeff]])
);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::BlockCholeskyPrecon<Type>::BlockCholeskyPrecon
(
const BlockLduMatrix<Type>& matrix
)
:
BlockLduPrecon<Type>(matrix),
preconDiag_(matrix.diag())
{
calcPreconDiag();
}
template<class Type>
Foam::BlockCholeskyPrecon<Type>::BlockCholeskyPrecon
(
const BlockLduMatrix<Type>& matrix,
const dictionary& dict
)
:
BlockLduPrecon<Type>(matrix),
preconDiag_(matrix.diag())
{
calcPreconDiag();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class Type>
Foam::BlockCholeskyPrecon<Type>::~BlockCholeskyPrecon()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::BlockCholeskyPrecon<Type>::precondition
(
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 (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
// Multiplication using transposed upper square coefficient
ILUmultiplyCoeffT
(
x,
preconDiag_.asScalar(),
UpperCoeff.asSquare(),
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 if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
// Multiplication using transposed upper square coefficient
ILUmultiplyCoeffT
(
x,
preconDiag_.asLinear(),
UpperCoeff.asSquare(),
b
);
}
}
else if (preconDiag_.activeType() == blockCoeffBase::SQUARE)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
ILUmultiply
(
x,
preconDiag_.asSquare(),
UpperCoeff.asScalar(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
ILUmultiply
(
x,
preconDiag_.asSquare(),
UpperCoeff.asLinear(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
// Multiplication using transposed upper square coefficient
ILUmultiplyCoeffT
(
x,
preconDiag_.asSquare(),
UpperCoeff.asSquare(),
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 (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
ILUmultiply
(
x,
preconDiag_.asScalar(),
LowerCoeff.asSquare(),
UpperCoeff.asSquare(),
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
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
ILUmultiply
(
x,
preconDiag_.asLinear(),
LowerCoeff.asSquare(),
UpperCoeff.asSquare(),
b
);
}
}
else if (preconDiag_.activeType() == blockCoeffBase::SQUARE)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
ILUmultiply
(
x,
preconDiag_.asSquare(),
LowerCoeff.asScalar(),
UpperCoeff.asScalar(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
ILUmultiply
(
x,
preconDiag_.asSquare(),
LowerCoeff.asLinear(),
UpperCoeff.asLinear(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
ILUmultiply
(
x,
preconDiag_.asSquare(),
LowerCoeff.asSquare(),
UpperCoeff.asSquare(),
b
);
}
}
}
}
template<class Type>
void Foam::BlockCholeskyPrecon<Type>::preconditionT
(
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 (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
ILUmultiplyTranspose
(
xT,
preconDiag_.asScalar(),
LowerCoeff.asSquare(),
UpperCoeff.asSquare(),
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
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
ILUmultiplyTranspose
(
xT,
preconDiag_.asLinear(),
LowerCoeff.asSquare(),
UpperCoeff.asSquare(),
bT
);
}
}
else if (preconDiag_.activeType() == blockCoeffBase::SQUARE)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
ILUmultiplyTranspose
(
xT,
preconDiag_.asSquare(),
LowerCoeff.asScalar(),
UpperCoeff.asScalar(),
bT
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
ILUmultiplyTranspose
(
xT,
preconDiag_.asSquare(),
LowerCoeff.asLinear(),
UpperCoeff.asLinear(),
bT
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
ILUmultiplyTranspose
(
xT,
preconDiag_.asSquare(),
LowerCoeff.asSquare(),
UpperCoeff.asSquare(),
bT
);
}
}
}
}
// ************************************************************************* //

View file

@ -0,0 +1,226 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
BlockCholeskyPrecon
Description
Incomplete Cholesky preconditioning with no fill-in.
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
BlockCholeskyPrecon.C
BlockCholeskyPreconDecoupled.C
\*---------------------------------------------------------------------------*/
#ifndef BlockCholeskyPrecon_H
#define BlockCholeskyPrecon_H
#include "BlockLduPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class BlockCholeskyPrecon Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class BlockCholeskyPrecon
:
public BlockLduPrecon<Type>
{
// Private Data
//- Preconditioned diagonal
mutable CoeffField<Type> preconDiag_;
// Private Member Functions
//- Disallow default bitwise copy construct
BlockCholeskyPrecon(const BlockCholeskyPrecon&);
//- Disallow default bitwise assignment
void operator=(const BlockCholeskyPrecon&);
//- 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
BlockCholeskyPrecon
(
const BlockLduMatrix<Type>& matrix
);
//- Construct from components
BlockCholeskyPrecon
(
const BlockLduMatrix<Type>& matrix,
const dictionary& dict
);
// Destructor
virtual ~BlockCholeskyPrecon();
// 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 "BlockCholeskyPrecon.C"
# include "BlockCholeskyPreconDecoupled.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,328 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "BlockCholeskyPrecon.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
void Foam::BlockCholeskyPrecon<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()
);
}
}
}
}
template<class Type>
void Foam::BlockCholeskyPrecon<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::BlockCholeskyPrecon<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,43 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#include "blockLduMatrices.H"
#include "blockLduPrecons.H"
#include "blockCholeskyPrecons.H"
#include "addToRunTimeSelectionTable.H"
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makeBlockPrecons(blockCholeskyPrecon);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,64 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockCholeskyPrecon
Description
Typedefs for Incomplete Cholesky preconditioning with no fill-in.
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
blockCholeskyPrecons.C
\*---------------------------------------------------------------------------*/
#ifndef blockCholeskyPrecons_H
#define blockCholeskyPrecons_H
#include "scalarBlockCholeskyPrecon.H"
#include "tensorBlockCholeskyPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef BlockCholeskyPrecon<scalar> blockCholeskyPreconScalar;
typedef BlockCholeskyPrecon<vector> blockCholeskyPreconVector;
typedef BlockCholeskyPrecon<tensor> blockCholeskyPreconTensor;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,200 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#ifndef scalarBlockCholeskyPrecon_H
#define scalarBlockCholeskyPrecon_H
#include "BlockCholeskyPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockCholeskyPrecon<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::BlockCholeskyPrecon<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::BlockCholeskyPrecon<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,76 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockCholeskyPrecon
Description
Template specialisation for scalar block Cholesky preconditioning
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
scalarBlockCholeskyPrecon.C
\*---------------------------------------------------------------------------*/
#ifndef scalarBlockCholeskyPrecon_H
#define scalarBlockCholeskyPrecon_H
#include "BlockCholeskyPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockCholeskyPrecon<scalar>::calcPreconDiag();
template<>
void Foam::BlockCholeskyPrecon<scalar>::precondition
(
scalarField& x,
const scalarField& b
) const;
template<>
void Foam::BlockCholeskyPrecon<scalar>::preconditionT
(
scalarField& xT,
const scalarField& bT
) const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,77 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#ifndef tensorBlockCholeskyPrecon_H
#define tensorBlockCholeskyPrecon_H
#include "BlockCholeskyPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockCholeskyPrecon<tensor>::calcPreconDiag()
{
// Decoupled version
calcDecoupledPreconDiag();
}
template<>
void Foam::BlockCholeskyPrecon<tensor>::precondition
(
tensorField& x,
const tensorField& b
) const
{
// Decoupled version
decoupledPrecondition(x, b);
}
template<>
void Foam::BlockCholeskyPrecon<tensor>::preconditionT
(
tensorField& xT,
const tensorField& bT
) const
{
// Decoupled version
decoupledPreconditionT(xT, bT);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,76 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockCholeskyPrecon
Description
Template specialisation for tensor block Cholesky preconditioning
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
tensorBlockCholeskyPrecon.C
\*---------------------------------------------------------------------------*/
#ifndef tensorBlockCholeskyPrecon_H
#define tensorBlockCholeskyPrecon_H
#include "BlockCholeskyPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockCholeskyPrecon<tensor>::calcPreconDiag();
template<>
void Foam::BlockCholeskyPrecon<tensor>::precondition
(
tensorField& x,
const tensorField& b
) const;
template<>
void Foam::BlockCholeskyPrecon<tensor>::preconditionT
(
tensorField& xT,
const tensorField& bT
) const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,89 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "BlockDiagonalPrecon.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::BlockDiagonalPrecon<Type>::precondition
(
Field<Type>& x,
const Field<Type>& b
) const
{
typedef CoeffField<Type> TypeCoeffField;
typedef typename TypeCoeffField::scalarTypeField scalarTypeField;
typedef typename TypeCoeffField::linearTypeField linearTypeField;
typedef typename TypeCoeffField::squareTypeField squareTypeField;
const TypeCoeffField& diag = this->matrix_.diag();
if (diag.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeDiag = diag.asScalar();
forAll (x, i)
{
x[i] = b[i]/activeDiag[i];
}
}
else if (diag.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeDiag = diag.asLinear();
forAll (x, i)
{
x[i] = cmptDivide(b[i], activeDiag[i]);
}
}
else if (diag.activeType() == blockCoeffBase::SQUARE)
{
const squareTypeField& activeDiag = diag.asSquare();
forAll (x, i)
{
x[i] = (b[i] & inv(activeDiag[i]));
}
}
else
{
FatalErrorIn
(
"void BlockDiagonalPrecon<Type>:solve:\n"
"(\n"
" Field<Type>& x,\n"
" const Field<Type>& b\n"
") const"
) << "Problem with coefficient type morphing."
<< abort(FatalError);
}
}
// ************************************************************************* //

View file

@ -0,0 +1,129 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
BlockDiagonalPrecon
Description
Diagonal preconditioning
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
blockDiagonalPrecons.C
scalarBlockDiagonalPrecon.C
tensorBlockDiagonalPrecon.C
\*---------------------------------------------------------------------------*/
#ifndef BlockDiagonalPrecon_H
#define BlockDiagonalPrecon_H
#include "BlockLduPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class BlockDiagonalPrecon Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class BlockDiagonalPrecon
:
public BlockLduPrecon<Type>
{
// Private Member Functions
//- Disallow default bitwise copy construct
BlockDiagonalPrecon(const BlockDiagonalPrecon&);
//- Disallow default bitwise assignment
void operator=(const BlockDiagonalPrecon&);
public:
//- Runtime type information
TypeName("diagonal");
// Constructors
//- Construct from components
BlockDiagonalPrecon
(
const BlockLduMatrix<Type>& matrix,
const dictionary& dict
)
:
BlockLduPrecon<Type>(matrix)
{}
// Destructor
virtual ~BlockDiagonalPrecon()
{}
// Member Functions
//- Execute preconditioning
virtual void precondition
(
Field<Type>& x,
const Field<Type>& b
) const;
//- Execute preconditioning on a transposed matrix
virtual void preconditionT
(
Field<Type>& xT,
const Field<Type>& bT
) const
{
return precondition(xT, bT);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "BlockDiagonalPrecon.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#include "blockLduMatrices.H"
#include "blockLduPrecons.H"
#include "blockDiagonalPrecons.H"
#include "addToRunTimeSelectionTable.H"
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makeBlockPrecons(blockDiagonalPrecon);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,64 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockDiagonalPrecon
Description
Typedefs Diagonal preconditioning
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
blockDiagonalPrecons.C
\*---------------------------------------------------------------------------*/
#ifndef blockDiagonalPrecons_H
#define blockDiagonalPrecons_H
#include "scalarBlockDiagonalPrecon.H"
#include "tensorBlockDiagonalPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef BlockDiagonalPrecon<scalar> blockDiagonalPreconScalar;
typedef BlockDiagonalPrecon<vector> blockDiagonalPreconVector;
typedef BlockDiagonalPrecon<tensor> blockDiagonalPreconTensor;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,67 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockDiagonalPrecon
Description
Template specialisation for scalar block diagonal preconditioning
\*---------------------------------------------------------------------------*/
#ifndef scalarBlockDiagonalPrecon_H
#define scalarBlockDiagonalPrecon_H
#include "BlockDiagonalPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockDiagonalPrecon<scalar>::precondition
(
scalarField& x,
const scalarField& b
) const
{
const scalarField& diag = matrix_.diag();
forAll (x, i)
{
x[i] = b[i]/diag[i];
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,65 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockDiagonalPrecon
Description
Template specialisation for scalar block diagonal preconditioning
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
scalarBlockDiagonalPrecon.C
\*---------------------------------------------------------------------------*/
#ifndef scalarBlockDiagonalPrecon_H
#define scalarBlockDiagonalPrecon_H
#include "BlockDiagonalPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockDiagonalPrecon<scalar>::precondition
(
scalarField& x,
const scalarField& b
) const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,101 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockDiagonalPrecon
Description
Template specialisation for tensor block diagonal preconditioning
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
\*---------------------------------------------------------------------------*/
#ifndef tensorBlockDiagonalPrecon_H
#define tensorBlockDiagonalPrecon_H
#include "BlockDiagonalPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockDiagonalPrecon<tensor>::precondition
(
tensorField& x,
const tensorField& b
) const
{
typedef CoeffField<tensor> tensorCoeffField;
typedef tensorCoeffField::scalarTypeField scalarTypeField;
typedef tensorCoeffField::linearTypeField linearTypeField;
const tensorCoeffField& diag = matrix_.diag();
if (diag.activeType() == blockCoeffBase::SCALAR)
{
const scalarTypeField& activeDiag = diag.asScalar();
forAll (x, i)
{
x[i] = b[i]/activeDiag[i];
}
}
else if (diag.activeType() == blockCoeffBase::LINEAR)
{
const linearTypeField& activeDiag = diag.asLinear();
forAll (x, i)
{
x[i] = cmptDivide(b[i], activeDiag[i]);
}
}
else
{
FatalErrorIn
(
"void BlockDiagonalPrecon<tensor>::solve\n"
"(\n"
" tensorField& x,\n"
" const tensorField& b\n"
") const"
) << "Problem with coefficient type morphing."
<< abort(FatalError);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,65 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockDiagonalPrecon
Description
Template specialisation for tensor block diagonal preconditioning
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
tensorBlockDiagonalPrecon.C
\*---------------------------------------------------------------------------*/
#ifndef tensorBlockDiagonalPrecon_H
#define tensorBlockDiagonalPrecon_H
#include "BlockDiagonalPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockDiagonalPrecon<tensor>::precondition
(
tensorField& x,
const tensorField& b
) const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,689 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
Gauss-Seidel sweep as a preconditioner.
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "BlockGaussSeidelPrecon.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Block sweep, symmetric matrix
template<class Type>
template<class DiagType, class ULType>
void Foam::BlockGaussSeidelPrecon<Type>::BlockSweep
(
Field<Type>& x,
const Field<DiagType>& dD,
const Field<ULType>& upper,
const Field<Type>& b
) const
{
const unallocLabelList& u = this->matrix_.lduAddr().upperAddr();
const unallocLabelList& ownStart = this->matrix_.lduAddr().ownerStartAddr();
const label nRows = ownStart.size() - 1;
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
for (label sweep = 0; sweep < nSweeps_; sweep++)
{
bPrime_ = b;
register label fStart, fEnd, curCoeff;
// Forward sweep
for (register label rowI = 0; rowI < nRows; rowI++)
{
Type& curX = x[rowI];
// Grab the accumulated neighbour side
curX = bPrime_[rowI];
// Start and end of this row
fStart = ownStart[rowI];
fEnd = ownStart[rowI + 1];
// Accumulate the owner product side
for (curCoeff = fStart; curCoeff < fEnd; curCoeff++)
{
curX -= mult(upper[curCoeff], x[u[curCoeff]]);
}
// Finish current x
curX = mult(dD[rowI], curX);
// Distribute the neighbour side using current x
for (curCoeff = fStart; curCoeff < fEnd; curCoeff++)
{
// lower = upper transposed
bPrime_[u[curCoeff]] -=
mult(mult.transpose(upper[curCoeff]), curX);
}
}
// Reverse sweep
for (register label rowI = nRows - 1; rowI >= 0; rowI--)
{
Type& curX = x[rowI];
// Grab the accumulated neighbour side
curX = bPrime_[rowI];
// Start and end of this row
fStart = ownStart[rowI];
fEnd = ownStart[rowI + 1];
// Accumulate the owner product side
for (curCoeff = fStart; curCoeff < fEnd; curCoeff++)
{
curX -= mult(upper[curCoeff], x[u[curCoeff]]);
}
// Finish current x
curX = mult(dD[rowI], curX);
// Distribute the neighbour side using current x
for (curCoeff = fStart; curCoeff < fEnd; curCoeff++)
{
// lower = upper transposed
bPrime_[u[curCoeff]] -=
mult(mult.transpose(upper[curCoeff]), curX);
}
}
}
}
// Block sweep, asymmetric matrix
template<class Type>
template<class DiagType, class ULType>
void Foam::BlockGaussSeidelPrecon<Type>::BlockSweep
(
Field<Type>& x,
const Field<DiagType>& dD,
const Field<ULType>& lower,
const Field<ULType>& upper,
const Field<Type>& b
) const
{
const unallocLabelList& u = this->matrix_.lduAddr().upperAddr();
const unallocLabelList& ownStart = this->matrix_.lduAddr().ownerStartAddr();
const label nRows = ownStart.size() - 1;
// Create multiplication function object
typename BlockCoeff<Type>::multiply mult;
for (label sweep = 0; sweep < nSweeps_; sweep++)
{
bPrime_ = b;
register label fStart, fEnd, curCoeff;
// Forward sweep
for (register label rowI = 0; rowI < nRows; rowI++)
{
Type& curX = x[rowI];
// Grab the accumulated neighbour side
curX = bPrime_[rowI];
// Start and end of this row
fStart = ownStart[rowI];
fEnd = ownStart[rowI + 1];
// Accumulate the owner product side
for (curCoeff = fStart; curCoeff < fEnd; curCoeff++)
{
curX -= mult(upper[curCoeff], x[u[curCoeff]]);
}
// Finish current x
curX = mult(dD[rowI], curX);
// Distribute the neighbour side using current x
for (curCoeff = fStart; curCoeff < fEnd; curCoeff++)
{
bPrime_[u[curCoeff]] -= mult(lower[curCoeff], curX);
}
}
// Reverse sweep
for (register label rowI = nRows - 1; rowI >= 0; rowI--)
{
Type& curX = x[rowI];
// Grab the accumulated neighbour side
curX = bPrime_[rowI];
// Start and end of this row
fStart = ownStart[rowI];
fEnd = ownStart[rowI + 1];
// Accumulate the owner product side
for (curCoeff = fStart; curCoeff < fEnd; curCoeff++)
{
curX -= mult(upper[curCoeff], x[u[curCoeff]]);
}
// Finish current x
curX = mult(dD[rowI], curX);
// Distribute the neighbour side using current x
for (curCoeff = fStart; curCoeff < fEnd; curCoeff++)
{
bPrime_[u[curCoeff]] -= mult(lower[curCoeff], curX);
}
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::BlockGaussSeidelPrecon<Type>::precondition
(
Field<Type>& x,
const Field<Type>& b
) const
{
typedef CoeffField<Type> TypeCoeffField;
if (this->matrix_.diagonal())
{
TypeCoeffField dDCoeff = inv(this->matrix_.diag());
multiply(x, dDCoeff, b);
}
else if (this->matrix_.symmetric())
{
TypeCoeffField dDCoeff = inv(this->matrix_.diag());
const TypeCoeffField& UpperCoeff = this->matrix_.upper();
// Note
// Gauss-Seidel loops need to be executed in the specific
// order with direct access to the coefficients which can be
// of morphed type. Under normal circumstances, the
// operations are not inter-leaved and the decision can be
// made at the beginning of the loop. Here, the order needs
// to be enforced without the per-element if-condition, which
// makes for ugly code. HJ, 19/May/2005
//Note: Assuming lower and upper triangle have the same active type
if (dDCoeff.activeType() == blockCoeffBase::SCALAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
BlockSweep
(
x,
dDCoeff.asScalar(),
UpperCoeff.asScalar(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
BlockSweep
(
x,
dDCoeff.asScalar(),
UpperCoeff.asLinear(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
BlockSweep
(
x,
dDCoeff.asScalar(),
UpperCoeff.asSquare(),
b
);
}
}
else if (dDCoeff.activeType() == blockCoeffBase::LINEAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
BlockSweep
(
x,
dDCoeff.asLinear(),
UpperCoeff.asScalar(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
BlockSweep
(
x,
dDCoeff.asLinear(),
UpperCoeff.asLinear(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
BlockSweep
(
x,
dDCoeff.asLinear(),
UpperCoeff.asSquare(),
b
);
}
}
else if (dDCoeff.activeType() == blockCoeffBase::SQUARE)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
BlockSweep
(
x,
dDCoeff.asSquare(),
UpperCoeff.asScalar(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
BlockSweep
(
x,
dDCoeff.asSquare(),
UpperCoeff.asLinear(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
BlockSweep
(
x,
dDCoeff.asSquare(),
UpperCoeff.asSquare(),
b
);
}
}
else
{
FatalErrorIn
(
"void BlockGaussSeidelPrecon<Type>::precondition\n"
"(\n"
" Field<Type>& x,\n"
" const Field<Type>& b\n"
") const"
) << "Problem with coefficient type morphing."
<< abort(FatalError);
}
}
else if (this->matrix_.asymmetric())
{
TypeCoeffField dDCoeff = inv(this->matrix_.diag());
const TypeCoeffField& LowerCoeff = this->matrix_.lower();
const TypeCoeffField& UpperCoeff = this->matrix_.upper();
// Note
// Gauss-Seidel loops need to be executed in the specific
// order with direct access to the coefficients which can be
// of morphed type. Under normal circumstances, the
// operations are not inter-leaved and the decision can be
// made at the beginning of the loop. Here, the order needs
// to be enforced without the per-element if-condition, which
// makes for ugly code. HJ, 19/May/2005
//Note: Assuming lower and upper triangle have the same active type
if (dDCoeff.activeType() == blockCoeffBase::SCALAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
BlockSweep
(
x,
dDCoeff.asScalar(),
LowerCoeff.asScalar(),
UpperCoeff.asScalar(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
BlockSweep
(
x,
dDCoeff.asScalar(),
LowerCoeff.asLinear(),
UpperCoeff.asLinear(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
BlockSweep
(
x,
dDCoeff.asScalar(),
LowerCoeff.asSquare(),
UpperCoeff.asSquare(),
b
);
}
}
else if (dDCoeff.activeType() == blockCoeffBase::LINEAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
BlockSweep
(
x,
dDCoeff.asLinear(),
LowerCoeff.asScalar(),
UpperCoeff.asScalar(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
BlockSweep
(
x,
dDCoeff.asLinear(),
LowerCoeff.asLinear(),
UpperCoeff.asLinear(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
BlockSweep
(
x,
dDCoeff.asLinear(),
LowerCoeff.asSquare(),
UpperCoeff.asSquare(),
b
);
}
}
else if (dDCoeff.activeType() == blockCoeffBase::SQUARE)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
BlockSweep
(
x,
dDCoeff.asSquare(),
LowerCoeff.asScalar(),
UpperCoeff.asScalar(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
BlockSweep
(
x,
dDCoeff.asSquare(),
LowerCoeff.asLinear(),
UpperCoeff.asLinear(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
BlockSweep
(
x,
dDCoeff.asSquare(),
LowerCoeff.asSquare(),
UpperCoeff.asSquare(),
b
);
}
}
else
{
FatalErrorIn
(
"void BlockGaussSeidelPrecon<Type>::precondition\n"
"(\n"
" Field<Type>& x,\n"
" const Field<Type>& b\n"
") const"
) << "Problem with coefficient type morphing."
<< abort(FatalError);
}
}
else
{
FatalErrorIn
(
"void BlockGaussSeidelPrecon<Type>::precondition\n"
"(\n"
" Field<Type>& x,\n"
" const Field<Type>& b\n"
") const"
) << "cannot solve incomplete matrix, no diagonal"
<< abort(FatalError);
}
}
template<class Type>
void Foam::BlockGaussSeidelPrecon<Type>::preconditionT
(
Field<Type>& xT,
const Field<Type>& bT
) const
{
typedef CoeffField<Type> TypeCoeffField;
if (this->matrix_.diagonal())
{
TypeCoeffField dDCoeff = inv(this->matrix_.diag());
multiply(xT, dDCoeff, bT);
}
else if (this->matrix_.symmetric() || this->matrix_.asymmetric())
{
TypeCoeffField dDCoeff = inv(this->matrix_.diag());
const TypeCoeffField& LowerCoeff = this->matrix_.lower();
const TypeCoeffField& UpperCoeff = this->matrix_.upper();
// Note
// Gauss-Seidel loops need to be executed in the specific
// order with direct access to the coefficients which can be
// of morphed type. Under normal circumstances, the
// operations are not inter-leaved and the decision can be
// made at the beginning of the loop. Here, the order needs
// to be enforced without the per-element if-condition, which
// makes for ugly code. HJ, 19/May/2005
//Note: Assuming lower and upper triangle have the same active type
if (dDCoeff.activeType() == blockCoeffBase::SCALAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
// Transpose multiplication - swap lower and upper coeff arrays
BlockSweep
(
xT,
dDCoeff.asScalar(),
UpperCoeff.asScalar(),
LowerCoeff.asScalar(),
bT
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
// Transpose multiplication - swap lower and upper coeff arrays
BlockSweep
(
xT,
dDCoeff.asScalar(),
UpperCoeff.asLinear(),
LowerCoeff.asLinear(),
bT
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
// Transpose multiplication - swap lower and upper coeff arrays
BlockSweep
(
xT,
dDCoeff.asScalar(),
UpperCoeff.asSquare(),
LowerCoeff.asSquare(),
bT
);
}
}
else if (dDCoeff.activeType() == blockCoeffBase::LINEAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
// Transpose multiplication - swap lower and upper coeff arrays
BlockSweep
(
xT,
dDCoeff.asLinear(),
UpperCoeff.asScalar(),
LowerCoeff.asScalar(),
bT
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
// Transpose multiplication - swap lower and upper coeff arrays
BlockSweep
(
xT,
dDCoeff.asLinear(),
UpperCoeff.asLinear(),
LowerCoeff.asLinear(),
bT
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
// Transpose multiplication - swap lower and upper coeff arrays
BlockSweep
(
xT,
dDCoeff.asLinear(),
UpperCoeff.asSquare(),
LowerCoeff.asSquare(),
bT
);
}
}
else if (dDCoeff.activeType() == blockCoeffBase::SQUARE)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
// Transpose multiplication - swap lower and upper coeff arrays
BlockSweep
(
xT,
dDCoeff.asSquare(),
UpperCoeff.asScalar(),
LowerCoeff.asScalar(),
bT
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
// Transpose multiplication - swap lower and upper coeff arrays
BlockSweep
(
xT,
dDCoeff.asSquare(),
UpperCoeff.asLinear(),
LowerCoeff.asLinear(),
bT
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::SQUARE)
{
// Transpose multiplication - swap lower and upper coeff arrays
BlockSweep
(
xT,
dDCoeff.asSquare(),
UpperCoeff.asSquare(),
LowerCoeff.asSquare(),
bT
);
}
}
else
{
FatalErrorIn
(
"void BlockGaussSeidelPrecon<Type>::preconditionT\n"
"(\n"
" Field<Type>& xT,\n"
" const Field<Type>& bT\n"
") const"
) << "Problem with coefficient type morphing."
<< abort(FatalError);
}
}
else
{
FatalErrorIn
(
"void BlockGaussSeidelPrecon<Type>::preconditionT\n"
"(\n"
" Field<Type>& xT,\n"
" const Field<Type>& bT\n"
") const"
) << "cannot solve incomplete matrix, no diagonal"
<< abort(FatalError);
}
}
// ************************************************************************* //

View file

@ -0,0 +1,188 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
BlockGaussSeidelPrecon
Description
Gauss-Seidel preconditioning
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
BlockGaussSeidelPrecon.C
BlockGaussSeidelPrecon.C
BlockGaussSeidelPreconDecoupled.C
\*---------------------------------------------------------------------------*/
#ifndef BlockGaussSeidelPrecon_H
#define BlockGaussSeidelPrecon_H
#include "BlockLduPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class BlockGaussSeidelPrecon Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class BlockGaussSeidelPrecon
:
public BlockLduPrecon<Type>
{
// Private Data
//- Temporary space for solution intermediate
mutable Field<Type> bPrime_;
//- Number of sweeps
const label nSweeps_;
// Private Member Functions
//- Disallow default bitwise copy construct
BlockGaussSeidelPrecon(const BlockGaussSeidelPrecon&);
//- Disallow default bitwise assignment
void operator=(const BlockGaussSeidelPrecon&);
// Block Gauss-Seidel sweep, symetric matrix
template<class DiagType, class ULType>
void BlockSweep
(
Field<Type>& x,
const Field<DiagType>& dD,
const Field<ULType>& upper,
const Field<Type>& b
) const;
// Block Gauss-Seidel sweep, asymmetric matrix
template<class DiagType, class ULType>
void BlockSweep
(
Field<Type>& x,
const Field<DiagType>& dD,
const Field<ULType>& lower,
const Field<ULType>& upper,
const Field<Type>& b
) const;
// Decoupled operations, used in template specialisation
//- 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("GaussSeidel");
// Constructors
//- Construct from matrix for smoother use
BlockGaussSeidelPrecon
(
const BlockLduMatrix<Type>& matrix
)
:
BlockLduPrecon<Type>(matrix),
bPrime_(matrix.lduAddr().size()),
nSweeps_(1)
{}
//- Construct from components
BlockGaussSeidelPrecon
(
const BlockLduMatrix<Type>& matrix,
const dictionary& dict
)
:
BlockLduPrecon<Type>(matrix),
bPrime_(matrix.lduAddr().size()),
nSweeps_(readLabel(dict.lookup("nSweeps")))
{}
// Destructor
virtual ~BlockGaussSeidelPrecon()
{}
// 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 "BlockGaussSeidelPrecon.C"
# include "BlockGaussSeidelPreconDecoupled.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,264 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
Gauss-Seidel sweep as a preconditioner. Decoupled version, used in template
specialisation.
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
\*---------------------------------------------------------------------------*/
#include "BlockGaussSeidelPrecon.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
void Foam::BlockGaussSeidelPrecon<Type>::decoupledPrecondition
(
Field<Type>& x,
const Field<Type>& b
) const
{
typedef DecoupledCoeffField<Type> TypeCoeffField;
if (this->matrix_.diagonal())
{
TypeCoeffField dDCoeff = inv(this->matrix_.diag());
multiply(x, dDCoeff, b);
}
else if (this->matrix_.symmetric() || this->matrix_.asymmetric())
{
TypeCoeffField dDCoeff = inv(this->matrix_.diag());
const TypeCoeffField& LowerCoeff = this->matrix_.lower();
const TypeCoeffField& UpperCoeff = this->matrix_.upper();
// Note
// Gauss-Seidel loops need to be executed in the specific
// order with direct access to the coefficients which can be
// of morphed type. Under normal circumstances, the
// operations are not inter-leaved and the decision can be
// made at the beginning of the loop. Here, the order needs
// to be enforced without the per-element if-condition, which
// makes for ugly code. HJ, 19/May/2005
//Note: Assuming lower and upper triangle have the same active type
if (dDCoeff.activeType() == blockCoeffBase::SCALAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
BlockSweep
(
x,
dDCoeff.asScalar(),
LowerCoeff.asScalar(),
UpperCoeff.asScalar(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
BlockSweep
(
x,
dDCoeff.asScalar(),
LowerCoeff.asLinear(),
UpperCoeff.asLinear(),
b
);
}
}
else if (dDCoeff.activeType() == blockCoeffBase::LINEAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
BlockSweep
(
x,
dDCoeff.asLinear(),
LowerCoeff.asScalar(),
UpperCoeff.asScalar(),
b
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
BlockSweep
(
x,
dDCoeff.asLinear(),
LowerCoeff.asLinear(),
UpperCoeff.asLinear(),
b
);
}
}
else
{
FatalErrorIn
(
"void BlockGaussSeidelPrecon<Type>::precondition\n"
"(\n"
" Field<Type>& x,\n"
" const Field<Type>& b\n"
") const"
) << "Problem with coefficient type morphing."
<< abort(FatalError);
}
}
else
{
FatalErrorIn
(
"void BlockGaussSeidelPrecon<Type>::precondition\n"
"(\n"
" Field<Type>& x,\n"
" const Field<Type>& b\n"
") const"
) << "cannot solve incomplete matrix, no diagonal"
<< abort(FatalError);
}
}
template<class Type>
void Foam::BlockGaussSeidelPrecon<Type>::decoupledPreconditionT
(
Field<Type>& xT,
const Field<Type>& bT
) const
{
typedef DecoupledCoeffField<Type> TypeCoeffField;
if (this->matrix_.diagonal())
{
TypeCoeffField dDCoeff = inv(this->matrix_.diag());
multiply(xT, dDCoeff, bT);
}
else if (this->matrix_.symmetric() || this->matrix_.asymmetric())
{
TypeCoeffField dDCoeff = inv(this->matrix_.diag());
const TypeCoeffField& LowerCoeff = this->matrix_.lower();
const TypeCoeffField& UpperCoeff = this->matrix_.upper();
// Note
// Gauss-Seidel loops need to be executed in the specific
// order with direct access to the coefficients which can be
// of morphed type. Under normal circumstances, the
// operations are not inter-leaved and the decision can be
// made at the beginning of the loop. Here, the order needs
// to be enforced without the per-element if-condition, which
// makes for ugly code. HJ, 19/May/2005
//Note: Assuming lower and upper triangle have the same active type
if (dDCoeff.activeType() == blockCoeffBase::SCALAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
// Transpose multiplication - swap lower and upper coeff arrays
BlockSweep
(
xT,
dDCoeff.asScalar(),
UpperCoeff.asScalar(),
LowerCoeff.asScalar(),
bT
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
// Transpose multiplication - swap lower and upper coeff arrays
BlockSweep
(
xT,
dDCoeff.asScalar(),
UpperCoeff.asLinear(),
LowerCoeff.asLinear(),
bT
);
}
}
else if (dDCoeff.activeType() == blockCoeffBase::LINEAR)
{
if (UpperCoeff.activeType() == blockCoeffBase::SCALAR)
{
// Transpose multiplication - swap lower and upper coeff arrays
BlockSweep
(
xT,
dDCoeff.asLinear(),
UpperCoeff.asScalar(),
LowerCoeff.asScalar(),
bT
);
}
else if (UpperCoeff.activeType() == blockCoeffBase::LINEAR)
{
// Transpose multiplication - swap lower and upper coeff arrays
BlockSweep
(
xT,
dDCoeff.asLinear(),
UpperCoeff.asLinear(),
LowerCoeff.asLinear(),
bT
);
}
}
else
{
FatalErrorIn
(
"void BlockGaussSeidelPrecon<Type>::preconditionT\n"
"(\n"
" Field<Type>& xT,\n"
" const Field<Type>& bT\n"
") const"
) << "Problem with coefficient type morphing."
<< abort(FatalError);
}
}
else
{
FatalErrorIn
(
"void BlockGaussSeidelPrecon<Type>::preconditionT\n"
"(\n"
" Field<Type>& xT,\n"
" const Field<Type>& bT\n"
") const"
) << "cannot solve incomplete matrix, no diagonal"
<< abort(FatalError);
}
}
// ************************************************************************* //

View file

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
Gauss-Seidel preconditioning
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
\*---------------------------------------------------------------------------*/
#include "blockLduMatrices.H"
#include "blockLduPrecons.H"
#include "blockGaussSeidelPrecons.H"
#include "addToRunTimeSelectionTable.H"
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makeBlockPrecons(blockGaussSeidelPrecon);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,64 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockGaussSeidelPrecon
Description
Typedefs for Gauss-Seidel preconditioning
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
blockGaussSeidelPrecons.C
\*---------------------------------------------------------------------------*/
#ifndef blockGaussSeidelPrecons_H
#define blockGaussSeidelPrecons_H
#include "scalarBlockGaussSeidelPrecon.H"
#include "tensorBlockGaussSeidelPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef BlockGaussSeidelPrecon<scalar> blockGaussSeidelPreconScalar;
typedef BlockGaussSeidelPrecon<vector> blockGaussSeidelPreconVector;
typedef BlockGaussSeidelPrecon<tensor> blockGaussSeidelPreconTensor;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,123 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockGaussSeidelPrecon
Description
Template specialisation for scalar block Gauss-Seidel preconditioning
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
\*---------------------------------------------------------------------------*/
#ifndef scalarBlockGaussSeidelPrecon_H
#define scalarBlockGaussSeidelPrecon_H
#include "BlockGaussSeidelPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockGaussSeidelPrecon<scalar>::precondition
(
scalarField& x,
const scalarField& b
) const
{
if (matrix_.diagonal())
{
const scalarField& d = matrix_.diag();
forAll (x, i)
{
x[i] = b[i]/d[i];
}
}
else if (matrix_.symmetric() || matrix_.asymmetric())
{
scalarField dD = 1.0/matrix_.diag();
const scalarField& LowerCoeff = matrix_.lower();
const scalarField& UpperCoeff = matrix_.upper();
BlockSweep
(
x,
dD,
LowerCoeff,
UpperCoeff,
b
);
}
}
template<>
void Foam::BlockGaussSeidelPrecon<scalar>::preconditionT
(
scalarField& xT,
const scalarField& bT
) const
{
if (matrix_.diagonal())
{
const scalarField& d = matrix_.diag();
forAll (xT, i)
{
xT[i] = bT[i]/d[i];
}
}
else if (matrix_.symmetric() || matrix_.asymmetric())
{
scalarField dD = 1.0/matrix_.diag();
const scalarField& LowerCoeff = matrix_.lower();
const scalarField& UpperCoeff = matrix_.upper();
// Swap lower and upper coefficients, transposed matrix
BlockSweep
(
xT,
dD,
UpperCoeff,
LowerCoeff,
bT
);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,70 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockGaussSeidelPrecon
Description
Template specialisation for scalar block Gauss-Seidel preconditioning
SourceFiles
scalarBlockGaussSeidelPrecon.C
\*---------------------------------------------------------------------------*/
#ifndef scalarBlockGaussSeidelPrecon_H
#define scalarBlockGaussSeidelPrecon_H
#include "BlockGaussSeidelPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockGaussSeidelPrecon<scalar>::precondition
(
scalarField& x,
const scalarField& b
) const;
template<>
void Foam::BlockGaussSeidelPrecon<scalar>::preconditionT
(
scalarField& xT,
const scalarField& bT
) const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,81 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockGaussSeidelPrecon
Description
Template specialisation for tensor block Gauss-Seidel preconditioning
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
SourceFiles
tensorBlockGaussSeidelPrecon.C
\*---------------------------------------------------------------------------*/
#ifndef tensorBlockGaussSeidelPrecon_H
#define tensorBlockGaussSeidelPrecon_H
#include "BlockGaussSeidelPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockGaussSeidelPrecon<tensor>::precondition
(
tensorField& x,
const tensorField& b
) const
{
// Decoupled version
decoupledPrecondition(x, b);
}
template<>
void Foam::BlockGaussSeidelPrecon<tensor>::preconditionT
(
tensorField& xT,
const tensorField& bT
) const
{
// Decoupled version
decoupledPreconditionT(xT, bT);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,70 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockGaussSeidelPrecon
Description
Template specialisation for tensor block Gauss-Seidel preconditioning
SourceFiles
tensorBlockGaussSeidelPrecon.C
\*---------------------------------------------------------------------------*/
#ifndef tensorBlockGaussSeidelPrecon_H
#define tensorBlockGaussSeidelPrecon_H
#include "BlockGaussSeidelPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::BlockGaussSeidelPrecon<tensor>::precondition
(
tensorField& x,
const tensorField& b
) const;
template<>
void Foam::BlockGaussSeidelPrecon<tensor>::preconditionT
(
tensorField& xT,
const tensorField& bT
) const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,125 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "BlockLduPrecon.H"
#include "blockNoPrecons.H"
template<class Type>
class BlockNoPrecon;
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
template<class Type>
Foam::autoPtr<Foam::BlockLduPrecon<Type> > Foam::BlockLduPrecon<Type>::New
(
const BlockLduMatrix<Type>& matrix,
const dictionary& dict
)
{
word preconName;
// handle primitive or dictionary entry
const entry& e = dict.lookupEntry("preconditioner", false, false);
if (e.isDict())
{
e.dict().lookup("preconditioner") >> preconName;
}
else
{
e.stream() >> preconName;
}
const dictionary& controls = e.isDict() ? e.dict() : dictionary::null;
if (matrix.diagonal())
{
// No preconditioning for the diagonal matrix
return autoPtr<BlockLduPrecon<Type> >
(
new BlockNoPrecon<Type>
(
matrix,
dict
)
);
}
else
{
typename dictionaryConstructorTable::iterator constructorIter =
dictionaryConstructorTablePtr_->find(preconName);
if (constructorIter == dictionaryConstructorTablePtr_->end())
{
FatalIOErrorIn
(
"autoPtr<BlockLduPrecon> BlockLduPrecon::New\n"
"(\n"
" const BlockLduMatrix<Type>& matrix,\n"
" const dictionary& dict\n"
")",
dict
) << "Unknown matrix preconditioner " << preconName
<< endl << endl
<< "Valid matrix preconditioners are :" << endl
<< dictionaryConstructorTablePtr_->toc()
<< exit(FatalIOError);
}
return autoPtr<BlockLduPrecon<Type> >
(
constructorIter()
(
matrix,
dict
)
);
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::word Foam::BlockLduPrecon<Type>::getName(const dictionary& dict)
{
word name;
// handle primitive or dictionary entry
const entry& e = dict.lookupEntry("preconditioner", false, false);
if (e.isDict())
{
e.dict().lookup("preconditioner") >> name;
}
else
{
e.stream() >> name;
}
return name;
}
// ************************************************************************* //

View file

@ -0,0 +1,180 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
BlockLduPrecon
Description
Block LDU matrix preconditioner virtual base class
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
newBlockLduPrecon.C
\*---------------------------------------------------------------------------*/
#ifndef BlockLduPrecon_H
#define BlockLduPrecon_H
#include "BlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class BlockLduPrecon Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class BlockLduPrecon
{
// Private Member Functions
//- Disallow default bitwise copy construct
BlockLduPrecon(const BlockLduPrecon&);
//- Disallow default bitwise assignment
void operator=(const BlockLduPrecon&);
protected:
// Protected data
//- Matrix reference
const BlockLduMatrix<Type>& matrix_;
// Protected member functions
//- Find the smoother name (directly or from a sub-dictionary)
static word getName(const dictionary&);
public:
//- Runtime type information
TypeName("BlockLduPrecon");
// Declare run-time constructor selection tables
declareRunTimeSelectionTable
(
autoPtr,
BlockLduPrecon,
dictionary,
(
const BlockLduMatrix<Type>& matrix,
const dictionary& dict
),
(
matrix,
dict
)
);
// Constructors
//- Construct from matrix
BlockLduPrecon(const BlockLduMatrix<Type>& matrix)
:
matrix_(matrix)
{}
// Selectors
//- Select given matrix and dictionary
static autoPtr<BlockLduPrecon<Type> > New
(
const BlockLduMatrix<Type>& matrix,
const dictionary& dict
);
// Destructor
virtual ~BlockLduPrecon()
{}
// Member Functions
//- Execute preconditioning
virtual void precondition
(
Field<Type>& x,
const Field<Type>& b
) const = 0;
//- Execute preconditioning on a transposed matrix
virtual void preconditionT
(
Field<Type>& xT,
const Field<Type>& bT
) const
{
notImplemented
(
type() +"::preconditionT"
"(Field<Type>& xT, const Field<Type>& bT) const"
);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "BlockLduPrecon.C"
#endif
#define makeBlockPrecon(PreconType, typePreconType) \
\
defineNamedTemplateTypeNameAndDebug(typePreconType, 0); \
\
addToRunTimeSelectionTable(PreconType, typePreconType, dictionary);
#define makeBlockPrecons(preconType) \
\
makeBlockPrecon(blockScalarPrecon, preconType##Scalar); \
makeBlockPrecon(blockVectorPrecon, preconType##Vector); \
makeBlockPrecon(blockTensorPrecon, preconType##Tensor);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
Block precon member static data members
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
\*---------------------------------------------------------------------------*/
#include "blockLduPrecons.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineNamedTemplateTypeNameAndDebug(blockScalarPrecon, 0);
defineNamedTemplateTypeNameAndDebug(blockVectorPrecon, 0);
defineNamedTemplateTypeNameAndDebug(blockTensorPrecon, 0);
defineTemplateRunTimeSelectionTable(blockScalarPrecon, dictionary);
defineTemplateRunTimeSelectionTable(blockVectorPrecon, dictionary);
defineTemplateRunTimeSelectionTable(blockTensorPrecon, dictionary);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,64 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockLduPrecon
Description
Typedefs for block preconditioners
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
SourceFiles
blockLduPrecons.C
\*---------------------------------------------------------------------------*/
#ifndef blockLduPrecons_H
#define blockLduPrecons_H
#include "BlockLduPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef BlockLduPrecon<scalar> blockScalarPrecon;
typedef BlockLduPrecon<vector> blockVectorPrecon;
typedef BlockLduPrecon<tensor> blockTensorPrecon;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,125 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
BlockNoPrecon
Description
No preconditioning
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
BlockNoPrecon.C
\*---------------------------------------------------------------------------*/
#ifndef BlockNoPrecon_H
#define BlockNoPrecon_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<class Type>
class BlockLduPrecon;
/*---------------------------------------------------------------------------*\
Class BlockNoPrecon Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class BlockNoPrecon
:
public BlockLduPrecon<Type>
{
// Private Member Functions
//- Disallow default bitwise copy construct
BlockNoPrecon(const BlockNoPrecon&);
//- Disallow default bitwise assignment
void operator=(const BlockNoPrecon&);
public:
//- Runtime type information
TypeName("none");
// Constructors
//- Construct from components
BlockNoPrecon
(
const BlockLduMatrix<Type>& matrix,
const dictionary& dict
)
:
BlockLduPrecon<Type>(matrix)
{}
// Destructor
virtual ~BlockNoPrecon()
{}
// Member Functions
//- Execute preconditioning
virtual void precondition
(
Field<Type>& x,
const Field<Type>& b
) const
{
x = b;
}
//- Execute preconditioning
virtual void preconditionT
(
Field<Type>& xT,
const Field<Type>& bT
) const
{
precondition(xT, bT);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#include "blockLduMatrices.H"
#include "blockLduPrecons.H"
#include "addToRunTimeSelectionTable.H"
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makeBlockPrecons(blockNoPrecon);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,64 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockNoPrecon
Description
Typedefs for no preconditioning
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
blockNoPrecons.C
\*---------------------------------------------------------------------------*/
#ifndef blockNoPrecons_H
#define blockNoPrecons_H
#include "BlockNoPrecon.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef BlockNoPrecon<scalar> blockNoPreconScalar;
typedef BlockNoPrecon<vector> blockNoPreconVector;
typedef BlockNoPrecon<tensor> blockNoPreconTensor;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,126 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
BlockGaussSeidelSmoother
Description
Symmetric Gauss-Seidel smoother with prescribed number of smoothing sweeps
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
blockGaussSeidelSmoothers.C
\*---------------------------------------------------------------------------*/
#ifndef BlockGaussSeidelSmoother_H
#define BlockGaussSeidelSmoother_H
#include "BlockLduSmoother.H"
#include "blockGaussSeidelPrecons.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class BlockGaussSeidelSmoother Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class BlockGaussSeidelSmoother
:
public BlockLduSmoother<Type>
{
// Private Data
//- Gauss-Seidel preconditioner
BlockGaussSeidelPrecon<Type> gs_;
// Private Member Functions
//- Disallow default bitwise copy construct
BlockGaussSeidelSmoother(const BlockGaussSeidelSmoother&);
//- Disallow default bitwise assignment
void operator=(const BlockGaussSeidelSmoother&);
public:
//- Runtime type information
TypeName("GaussSeidel");
// Constructors
//- Construct from components
BlockGaussSeidelSmoother
(
const BlockLduMatrix<Type>& matrix,
const dictionary& dict
)
:
BlockLduSmoother<Type>(matrix),
gs_(matrix)
{}
// Destructor
virtual ~BlockGaussSeidelSmoother()
{}
// Member Functions
//- Execute smoothing
virtual void smooth
(
Field<Type>& x,
const Field<Type>& b,
const label nSweeps
) const
{
for (label sweep = 0; sweep < nSweeps; sweep++)
{
gs_.precondition(x, b);
}
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,46 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
Gauss-Seidel smoother
\*---------------------------------------------------------------------------*/
#include "blockLduMatrices.H"
#include "blockLduSmoothers.H"
#include "blockGaussSeidelSmoothers.H"
#include "addToRunTimeSelectionTable.H"
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makeBlockSmoothers(blockGaussSeidelSmoother);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,63 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockGaussSeidelSmoother
Description
Typedefs for Gauss-Seidel smoother
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
blockGaussSeidelSmoothers.C
\*---------------------------------------------------------------------------*/
#ifndef blockGaussSeidelSmoothers_H
#define blockGaussSeidelSmoothers_H
#include "BlockGaussSeidelSmoother.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef BlockGaussSeidelSmoother<scalar> blockGaussSeidelSmootherScalar;
typedef BlockGaussSeidelSmoother<vector> blockGaussSeidelSmootherVector;
typedef BlockGaussSeidelSmoother<tensor> blockGaussSeidelSmootherTensor;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,143 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
BlockILUSmoother
Description
Gauss-Seidel smoother
SourceFiles
blockILUSmoothers.C
\*---------------------------------------------------------------------------*/
#ifndef BlockILUSmoother_H
#define BlockILUSmoother_H
#include "BlockLduSmoother.H"
#include "blockCholeskyPrecons.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class BlockILUSmoother Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class BlockILUSmoother
:
public BlockLduSmoother<Type>
{
// Private Data
//- Cholesky preconditioner
BlockCholeskyPrecon<Type> precon_;
//- Correction array
mutable Field<Type> xCorr_;
//- Residual array
mutable Field<Type> residual_;
// Private Member Functions
//- Disallow default bitwise copy construct
BlockILUSmoother(const BlockILUSmoother&);
//- Disallow default bitwise assignment
void operator=(const BlockILUSmoother&);
public:
//- Runtime type information
TypeName("ILU");
// Constructors
//- Construct from components
BlockILUSmoother
(
const BlockLduMatrix<Type>& matrix,
const dictionary& dict
)
:
BlockLduSmoother<Type>(matrix),
precon_(matrix),
xCorr_(matrix.lduAddr().size()),
residual_(matrix.lduAddr().size())
{}
// Destructor
virtual ~BlockILUSmoother()
{}
// Member Functions
//- Execute smoothing
virtual void smooth
(
Field<Type>& x,
const Field<Type>& b,
const label nSweeps
) const
{
for (label sweep = 0; sweep < nSweeps; sweep++)
{
// Calculate residual
this-> matrix_.Amul(residual_, x);
// residual = b - Ax
forAll (b, i)
{
residual_[i] = b[i] - residual_[i];
}
precon_.precondition(xCorr_, residual_);
// Add correction to x
x += xCorr_;
}
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\*---------------------------------------------------------------------------*/
#include "blockLduMatrices.H"
#include "blockLduSmoothers.H"
#include "blockILUSmoothers.H"
#include "addToRunTimeSelectionTable.H"
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makeBlockSmoothers(blockILUSmoother);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,63 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockILUSmoother
Description
Typedefs for Incomplete Lower-Upper (ILU) smoother
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved.
SourceFiles
blockILUSmoothers.C
\*---------------------------------------------------------------------------*/
#ifndef blockILUSmoothers_H
#define blockILUSmoothers_H
#include "BlockILUSmoother.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef BlockILUSmoother<scalar> blockILUSmootherScalar;
typedef BlockILUSmoother<vector> blockILUSmootherVector;
typedef BlockILUSmoother<tensor> blockILUSmootherTensor;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,116 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
BlockLduSmoother
Description
Block LDU matrix smoother virtual base class
\*---------------------------------------------------------------------------*/
#include "BlockLduSmoother.H"
template<class Type>
class BlockNoSmoother;
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
template<class Type>
Foam::autoPtr<Foam::BlockLduSmoother<Type> > Foam::BlockLduSmoother<Type>::New
(
const BlockLduMatrix<Type>& matrix,
const dictionary& dict
)
{
word smootherName;
// Handle primitive or dictionary entry
const entry& e = dict.lookupEntry("smoother", false, false);
if (e.isDict())
{
e.dict().lookup("smoother") >> smootherName;
}
else
{
e.stream() >> smootherName;
}
// Not (yet?) needed:
// const dictionary& controls = e.isDict() ? e.dict() : dictionary::null;
typename dictionaryConstructorTable::iterator constructorIter =
dictionaryConstructorTablePtr_->find(smootherName);
if (constructorIter == dictionaryConstructorTablePtr_->end())
{
FatalIOErrorIn
(
"autoPtr<BlockLduSmoother> BlockLduSmoother::New\n"
"(\n"
" const BlockLduMatrix<Type>& matrix,\n"
" const dictionary& dict\n"
")",
dict
) << "Unknown matrix smoother " << smootherName
<< endl << endl
<< "Valid matrix smoothers are :" << endl
<< dictionaryConstructorTablePtr_->toc()
<< exit(FatalIOError);
}
return autoPtr<BlockLduSmoother<Type> >
(
constructorIter()
(
matrix,
dict
)
);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::word Foam::BlockLduSmoother<Type>::getName(const dictionary& dict)
{
word name;
// handle primitive or dictionary entry
const entry& e = dict.lookupEntry("preconditioner", false, false);
if (e.isDict())
{
e.dict().lookup("preconditioner") >> name;
}
else
{
e.stream() >> name;
}
return name;
}
// ************************************************************************* //

View file

@ -0,0 +1,164 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
BlockLduSmoother
Description
Block LDU matrix smoother virtual base class
SourceFiles
newBlockLduSmoother.C
\*---------------------------------------------------------------------------*/
#ifndef BlockLduSmoother_H
#define BlockLduSmoother_H
#include "blockLduMatrices.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class BlockLduSmoother Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class BlockLduSmoother
{
// Private Member Functions
//- Disallow default bitwise copy construct
BlockLduSmoother(const BlockLduSmoother&);
//- Disallow default bitwise assignment
void operator=(const BlockLduSmoother&);
protected:
// Protected data
//- Matrix reference
const BlockLduMatrix<Type>& matrix_;
// Protected member functions
//- Find the smoother name (directly or from a sub-dictionary)
static word getName(const dictionary&);
public:
//- Runtime type information
TypeName("BlockLduSmoother");
// Declare run-time constructor selection tables
declareRunTimeSelectionTable
(
autoPtr,
BlockLduSmoother,
dictionary,
(
const BlockLduMatrix<Type>& matrix,
const dictionary& dict
),
(
matrix,
dict
)
);
// Constructors
//- Construct from matrix
BlockLduSmoother(const BlockLduMatrix<Type>& matrix)
:
matrix_(matrix)
{}
// Selectors
//- Select given matrix and dictionary
static autoPtr<BlockLduSmoother<Type> > New
(
const BlockLduMatrix<Type>& matrix,
const dictionary& dict
);
// Destructor
virtual ~BlockLduSmoother()
{}
// Member Functions
//- Execute smoothing
virtual void smooth
(
Field<Type>& x,
const Field<Type>& b,
const label nSweeps
) const = 0;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "BlockLduSmoother.C"
#endif
#define makeBlockSmoother(SmootherType, typeSmootherType) \
\
defineNamedTemplateTypeNameAndDebug(typeSmootherType, 0); \
\
addToRunTimeSelectionTable(SmootherType, typeSmootherType, dictionary);
#define makeBlockSmoothers(smootherType) \
\
makeBlockSmoother(blockScalarSmoother, smootherType##Scalar); \
makeBlockSmoother(blockVectorSmoother, smootherType##Vector); \
makeBlockSmoother(blockTensorSmoother, smootherType##Tensor);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,52 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
Block smoother member static data members
\*---------------------------------------------------------------------------*/
#include "blockLduSmoothers.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineNamedTemplateTypeNameAndDebug(blockScalarSmoother, 0);
defineNamedTemplateTypeNameAndDebug(blockVectorSmoother, 0);
defineNamedTemplateTypeNameAndDebug(blockTensorSmoother, 0);
defineTemplateRunTimeSelectionTable(blockScalarSmoother, dictionary);
defineTemplateRunTimeSelectionTable(blockVectorSmoother, dictionary);
defineTemplateRunTimeSelectionTable(blockTensorSmoother, dictionary);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,64 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
BlockLduSmoother
Description
Typedefs for block LDU smoothers.
Author
Hrvoje Jasak, Wikki Ltd. All rights reserved
SourceFiles
blockLduSmoothers.C
\*---------------------------------------------------------------------------*/
#ifndef blockLduSmoothers_H
#define blockLduSmoothers_H
#include "BlockLduSmoother.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
typedef BlockLduSmoother<scalar> blockScalarSmoother;
typedef BlockLduSmoother<vector> blockVectorSmoother;
typedef BlockLduSmoother<tensor> blockTensorSmoother;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,172 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-6 H. Jasak All rights reserved
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Description
Preconditioned Bi-Conjugate Gradient stabilised solver.
\*---------------------------------------------------------------------------*/
#include "BlockBiCGStabSolver.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
//- Construct from matrix and solver data stream
template<class Type>
Foam::BlockBiCGStabSolver<Type>::BlockBiCGStabSolver
(
const word& fieldName,
const BlockLduMatrix<Type>& matrix,
const dictionary& dict
)
:
BlockIterativeSolver<Type>
(
fieldName,
matrix,
dict
),
preconPtr_
(
BlockLduPrecon<Type>::New
(
matrix,
this->dict().subDict("preconditioner")
)
)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
typename Foam::BlockSolverPerformance<Type>
Foam::BlockBiCGStabSolver<Type>::solve
(
Field<Type>& x,
const Field<Type>& b
)
{
// Create local references to avoid the spread this-> ugliness
const BlockLduMatrix<Type>& matrix = this->matrix_;
// Prepare solver performance
BlockSolverPerformance<Type> solverPerf
(
typeName,
this->fieldName()
);
scalar norm = this->normFactor(x, b);
// Multiplication helper
typename BlockCoeff<Type>::multiply mult;
Field<Type> p(x.size());
// Calculate initial residual
matrix.Amul(p, x);
Field<Type> r(b - p);
solverPerf.initialResidual() = gSum(cmptMag(r))/norm;
solverPerf.finalResidual() = solverPerf.initialResidual();
// Check convergence, solve if not converged
if (!solverPerf.checkConvergence(this->tolerance(), this->relTolerance()))
{
scalar rho = this->great_;
scalar rhoOld = rho;
scalar alpha = 0;
scalar omega = this->great_;
scalar beta;
p = pTraits<Type>::zero;
Field<Type> ph(x.size(), pTraits<Type>::zero);
Field<Type> v(x.size(), pTraits<Type>::zero);
Field<Type> s(x.size(), pTraits<Type>::zero);
Field<Type> sh(x.size(), pTraits<Type>::zero);
Field<Type> t(x.size(), pTraits<Type>::zero);
// Calculate transpose residual
Field<Type> rw(r);
do
{
rhoOld = rho;
// Update search directions
rho = gSumProd(rw, r);
beta = rho/rhoOld*(alpha/omega);
// Restart if breakdown occurs
if (rho == 0)
{
rw = r;
rho = gSumProd(rw, r);
alpha = 0;
omega = 0;
beta = 0;
}
forAll (p, i)
{
p[i] = r[i] + beta*p[i] - beta*omega*v[i];
}
preconPtr_->precondition(ph, p);
matrix.Amul(v, ph);
alpha = rho/gSumProd(rw, v);
forAll (s, i)
{
s[i] = r[i] - alpha*v[i];
}
preconPtr_->preconditionT(sh, s);
matrix.Amul(t, sh);
omega = gSumProd(t, s)/gSumProd(t, t);
forAll (x, i)
{
x[i] = x[i] + alpha*ph[i] + omega*sh[i];
}
forAll (r, i)
{
r[i] = s[i] - omega*t[i];
}
solverPerf.finalResidual() = gSum(cmptMag(r))/norm;
solverPerf.nIterations()++;
} while (!stop(solverPerf));
}
return solverPerf;
}
// ************************************************************************* //

Some files were not shown because too many files have changed in this diff Show more