diff --git a/applications/solvers/conjugate/blockCoupledScalarTransportFoam/Make/files b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/Make/files new file mode 100644 index 000000000..e972ab9ea --- /dev/null +++ b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/Make/files @@ -0,0 +1,8 @@ +tensor2Field.C +blockVector2Matrix.C +blockVector2Solvers.C + +blockCoupledScalarTransportFoam.C + + +EXE = $(FOAM_APPBIN)/blockCoupledScalarTransportFoam diff --git a/applications/solvers/conjugate/blockCoupledScalarTransportFoam/Make/options b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/Make/options new file mode 100644 index 000000000..d537a0f46 --- /dev/null +++ b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/Make/options @@ -0,0 +1,8 @@ +EXE_INC = \ + -ftemplate-depth-100 \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/blockMatrix/lnInclude + +EXE_LIBS = \ + -lfiniteVolume \ + -lblockMatrix diff --git a/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockCoupledScalarTransportFoam.C b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockCoupledScalarTransportFoam.C new file mode 100644 index 000000000..c187fd12c --- /dev/null +++ b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockCoupledScalarTransportFoam.C @@ -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 blockM(mesh); + + // Grab block diagonal and set it to zero + Field& d = blockM.diag().asSquare(); + d = tensor2::zero; + + // Grab linear off-diagonal and set it to zero + Field& u = blockM.upper().asLinear(); + Field& 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 solverPerf = + BlockLduSolver::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); +} + + +// ************************************************************************* // diff --git a/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockMatrixTools.C b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockMatrixTools.C new file mode 100644 index 000000000..33d448e78 --- /dev/null +++ b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockMatrixTools.C @@ -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 +void blockInsert +( + const direction dir, + const scalarField& x, + Field& blockX +) +{ + forAll (x, i) + { + blockX[i](dir) = x[i]; + } +} + + +template +void blockRetrieve +( + const direction dir, + scalarField& x, + const Field& blockX +) +{ + forAll (x, i) + { + x[i] = blockX[i](dir); + } +} + + +template +void insertDiagSource +( + const direction dir, + const fvScalarMatrix& m, + BlockLduMatrix& blockM, + Field& 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::linearTypeField& blockDiag = + blockM.diag().asLinear(); + + forAll (diag, i) + { + blockDiag[i](dir) = diag[i]; + } + } + else if (blockM.diag().activeType() == blockCoeffBase::SQUARE) + { + typename CoeffField::squareTypeField& blockDiag = + blockM.diag().asSquare(); + + forAll (diag, i) + { + blockDiag[i](dir, dir) = diag[i]; + } + } + + blockInsert(dir, source, blockB); +} + + +template +void insertUpperLower +( + const direction dir, + const fvScalarMatrix& m, + BlockLduMatrix& 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::linearTypeField& blockUpper = + blockM.upper().asLinear(); + + forAll (upper, i) + { + blockUpper[i](dir) = upper[i]; + } + } + else if (blockM.upper().activeType() == blockCoeffBase::SQUARE) + { + typename CoeffField::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& 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::linearTypeField& blockLower = + blockM.lower().asLinear(); + + forAll (lower, i) + { + blockLower[i](dir) = lower[i]; + } + } + else if (blockM.lower().activeType() == blockCoeffBase::SQUARE) + { + typename CoeffField::squareTypeField& blockLower = + blockM.lower().asSquare(); + + forAll (lower, i) + { + blockLower[i](dir, dir) = lower[i]; + } + } + } +} + + +template +void insertEquation +( + const direction dir, + const fvScalarMatrix& m, + BlockLduMatrix& blockM, + Field& blockX, + Field& blockB +) +{ + insertDiagSource(dir, m, blockM, blockB); + insertUpperLower(dir, m, blockM); + blockInsert(dir, m.psi(), blockX); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace blockMatrixTools + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockMatrixTools.H b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockMatrixTools.H new file mode 100644 index 000000000..cb372a92a --- /dev/null +++ b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockMatrixTools.H @@ -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 + void blockInsert + ( + const direction dir, + const scalarField& x, + Field& blockX + ); + + //- Retrieve field from block field + template + void blockRetrieve + ( + const direction dir, + scalarField& x, + const Field& blockX + ); + + //- Insert matrix diagonal and source into the block system + template + void insertDiagSource + ( + const direction dir, + const fvScalarMatrix& m, + BlockLduMatrix& blockM, + Field& blockB + ); + + // Insert matrix into the block system + template + void insertUpperLower + ( + const direction dir, + const fvScalarMatrix& m, + BlockLduMatrix& blockM + ); + + // Insert matrix into the block system + template + void insertEquation + ( + const direction dir, + const fvScalarMatrix& m, + BlockLduMatrix& blockM, + Field& blockX, + Field& 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 + void updateCoupling + ( + BlockLduMatrix& blockM, + Field& x, + Field& b + ); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "blockMatrixTools.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockVector2Matrix.C b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockVector2Matrix.C new file mode 100644 index 000000000..b9711defb --- /dev/null +++ b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockVector2Matrix.C @@ -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 + +// ************************************************************************* // diff --git a/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockVector2Matrix.H b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockVector2Matrix.H new file mode 100644 index 000000000..a3d1092c8 --- /dev/null +++ b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockVector2Matrix.H @@ -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 blockVector2Matrix; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockVector2Solvers.C b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockVector2Solvers.C new file mode 100644 index 000000000..bacb5de58 --- /dev/null +++ b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/blockVector2Solvers.C @@ -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 blockVector2Precon; +defineNamedTemplateTypeNameAndDebug(blockVector2Precon, 0); +defineTemplateRunTimeSelectionTable(blockVector2Precon, dictionary); + +typedef BlockNoPrecon blockNoPreconVector2; +makeBlockPrecon(blockVector2Precon, blockNoPreconVector2); + +typedef BlockDiagonalPrecon blockDiagonalPreconVector2; +makeBlockPrecon(blockVector2Precon, blockDiagonalPreconVector2); + +typedef BlockGaussSeidelPrecon blockGaussSeidelPreconVector2; +makeBlockPrecon(blockVector2Precon, blockGaussSeidelPreconVector2); + +typedef BlockCholeskyPrecon blockCholeskyPreconVector2; +makeBlockPrecon(blockVector2Precon, blockCholeskyPreconVector2); + + +// Smoothers +typedef BlockLduSmoother blockVector2Smoother; +defineNamedTemplateTypeNameAndDebug(blockVector2Smoother, 0); +defineTemplateRunTimeSelectionTable(blockVector2Smoother, dictionary); + +typedef BlockGaussSeidelSmoother blockGaussSeidelSmootherVector2; +makeBlockSmoother(blockVector2Smoother, blockGaussSeidelSmootherVector2); + +typedef BlockILUSmoother blockILUSmootherVector2; +makeBlockSmoother(blockVector2Smoother, blockILUSmootherVector2); + + +// Solvers +typedef BlockLduSolver blockVector2Solver; +defineNamedTemplateTypeNameAndDebug(blockVector2Solver, 0); +defineTemplateRunTimeSelectionTable +( + blockVector2Solver, + symMatrix +); + +defineTemplateRunTimeSelectionTable +( + blockVector2Solver, + asymMatrix +); + +typedef BlockDiagonalSolver blockDiagonalSolverVector2; +defineNamedTemplateTypeNameAndDebug(blockDiagonalSolverVector2, 0); + +typedef BlockBiCGStabSolver blockBiCGStabSolverVector2; +makeBlockSolverTypeName(blockBiCGStabSolverVector2); +addSolverToBlockMatrix(Vector2, blockBiCGStabSolverVector2, symMatrix); +addSolverToBlockMatrix(Vector2, blockBiCGStabSolverVector2, asymMatrix); + +typedef BlockCGSolver blockCGSolverVector2; +makeBlockSolverTypeName(blockCGSolverVector2); +addSolverToBlockMatrix(Vector2, blockCGSolverVector2, symMatrix); + +typedef BlockGaussSeidelSolver blockGaussSeidelSolverVector2; +makeBlockSolverTypeName(blockGaussSeidelSolverVector2); +addSolverToBlockMatrix(Vector2, blockGaussSeidelSolverVector2, symMatrix); + +typedef BlockGMRESSolver blockGMRESSolverVector2; +makeBlockSolverTypeName(blockGMRESSolverVector2); +addSolverToBlockMatrix(Vector2, blockGMRESSolverVector2, symMatrix); +addSolverToBlockMatrix(Vector2, blockGMRESSolverVector2, asymMatrix); + + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/applications/solvers/conjugate/blockCoupledScalarTransportFoam/createFields.H b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/createFields.H new file mode 100644 index 000000000..ff8437703 --- /dev/null +++ b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/createFields.H @@ -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" diff --git a/applications/solvers/conjugate/blockCoupledScalarTransportFoam/tensor2.H b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/tensor2.H new file mode 100644 index 000000000..5df2d9bbb --- /dev/null +++ b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/tensor2.H @@ -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 tensor2; + +//- Specify data associated with tensor2 type is contiguous +template<> +inline bool contiguous() {return true;} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/solvers/conjugate/blockCoupledScalarTransportFoam/tensor2Field.C b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/tensor2Field.C new file mode 100644 index 000000000..50755762d --- /dev/null +++ b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/tensor2Field.C @@ -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" + +// ************************************************************************* // diff --git a/applications/solvers/conjugate/blockCoupledScalarTransportFoam/tensor2Field.H b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/tensor2Field.H new file mode 100644 index 000000000..045ac8c3e --- /dev/null +++ b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/tensor2Field.H @@ -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 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 tensor2Field; + +UNARY_FUNCTION(tensor2, tensor2, inv) + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "undefFieldFunctionsM.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/solvers/conjugate/blockCoupledScalarTransportFoam/testBlockMatrix.C b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/testBlockMatrix.C new file mode 100644 index 000000000..6beda2b7b --- /dev/null +++ b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/testBlockMatrix.C @@ -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 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 vector2Matrix(mesh); + + vector2Matrix.diag().asScalar() = + scalarField(vector2Matrix.diag().size(), 1); + + vector2Matrix.diag() += + Field(vector2Matrix.diag().size(), vector2::one); + + vector2Matrix.upper() = + Field(vector2Matrix.upper().size(), tensor2::one); + + Info<< "End\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/solvers/conjugate/blockCoupledScalarTransportFoam/vector2.H b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/vector2.H new file mode 100644 index 000000000..fd0976ab1 --- /dev/null +++ b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/vector2.H @@ -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 vector2; + + +//- Specify data associated with vector2 type is contiguous +template<> +inline bool contiguous() {return true;} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/solvers/conjugate/blockCoupledScalarTransportFoam/vector2Field.H b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/vector2Field.H new file mode 100644 index 000000000..51d78d8f2 --- /dev/null +++ b/applications/solvers/conjugate/blockCoupledScalarTransportFoam/vector2Field.H @@ -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 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 vector2Field; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "undefFieldFunctionsM.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/Allwmake b/src/Allwmake index f2ebba28d..baba34e42 100755 --- a/src/Allwmake +++ b/src/Allwmake @@ -36,6 +36,8 @@ wmake libso finiteVolume wmake libso finiteArea wmake libso lduSolvers +wmake libso blockMatrix + wmake libso dynamicMesh (cd tetDecompositionFiniteElement ; Allwmake) diff --git a/src/blockMatrix/BlockCoeff/BlockCoeff.C b/src/blockMatrix/BlockCoeff/BlockCoeff.C new file mode 100644 index 000000000..baef69781 --- /dev/null +++ b/src/blockMatrix/BlockCoeff/BlockCoeff.C @@ -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 +typename Foam::BlockCoeff::scalarType& +Foam::BlockCoeff::toScalar() +{ + if (!scalarCoeffPtr_) + { + // Debug check: demotion + if (linearCoeffPtr_ || squareCoeffPtr_) + { + FatalErrorIn + ( + "BlockCoeff::scalarType& " + "BlockCoeff::toScalar()" + ) << "Detected demotion to scalar. Probably an error" + << abort(FatalError); + } + + scalarCoeffPtr_ = new scalarType(pTraits::zero); + } + + return *scalarCoeffPtr_; +} + + +template +typename Foam::BlockCoeff::linearType& +Foam::BlockCoeff::toLinear() +{ + if (!linearCoeffPtr_) + { + // Debug check: demotion + if (squareCoeffPtr_) + { + FatalErrorIn + ( + "BlockCoeff::linearType& " + "BlockCoeff::toLinear()" + ) << "Detected demotion to linear. Probably an error" + << abort(FatalError); + } + + linearCoeffPtr_ = new linearType(pTraits::zero); + + // If scalar is active, promote to linear + if (scalarCoeffPtr_) + { + *linearCoeffPtr_ = (*scalarCoeffPtr_)*pTraits::one; + deleteDemandDrivenData(scalarCoeffPtr_); + } + } + + return *linearCoeffPtr_; +} + + +template +typename Foam::BlockCoeff::squareType& +Foam::BlockCoeff::toSquare() +{ + if (!squareCoeffPtr_) + { + squareCoeffPtr_ = new squareType(pTraits::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 +Foam::BlockCoeff::BlockCoeff() +: + scalarCoeffPtr_(NULL), + linearCoeffPtr_(NULL), + squareCoeffPtr_(NULL) +{} + + +template +Foam::BlockCoeff::BlockCoeff(const BlockCoeff& 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 +Foam::BlockCoeff::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::BlockCoeff(Istream& is)", + is + ) << "invalid keyword while reading: " << key + << exit(FatalIOError); + } +} + + +template +Foam::BlockCoeff Foam::BlockCoeff::clone() const +{ + return BlockCoeff(*this); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +template +Foam::BlockCoeff::~BlockCoeff() +{ + this->clear(); +} + + +template +inline void Foam::BlockCoeff::clear() +{ + deleteDemandDrivenData(scalarCoeffPtr_); + deleteDemandDrivenData(linearCoeffPtr_); + deleteDemandDrivenData(squareCoeffPtr_); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +Foam::blockCoeffBase::activeLevel +Foam::BlockCoeff::activeType() const +{ + if (scalarCoeffPtr_) + { + return blockCoeffBase::SCALAR; + } + else if (linearCoeffPtr_) + { + return blockCoeffBase::LINEAR; + } + else if (squareCoeffPtr_) + { + return blockCoeffBase::SQUARE; + } + else + { + return blockCoeffBase::UNALLOCATED; + } +} + + +template +void Foam::BlockCoeff::checkActive() const +{ + label nActive = 0; + + if (scalarCoeffPtr_) nActive++; + if (linearCoeffPtr_) nActive++; + if (squareCoeffPtr_) nActive++; + + if (nActive > 1) + { + FatalErrorIn("void Foam::BlockCoeff::checkActive() const") + << "Activation/deactivation error. nActive = " << nActive + << abort(FatalError); + } +} + + +template +const typename Foam::BlockCoeff::scalarType& +Foam::BlockCoeff::asScalar() const +{ + if (!scalarCoeffPtr_) + { + FatalErrorIn + ( + "BlockCoeff::scalarType& " + "BlockCoeff::asScalar()" + ) << "Requested scalar but active type is: " + << blockCoeffBase::activeLevelNames_[this->activeType()] + << ". This is not allowed." + << abort(FatalError); + } + + return *scalarCoeffPtr_; +} + + +template +const typename Foam::BlockCoeff::linearType& +Foam::BlockCoeff::asLinear() const +{ + if (!linearCoeffPtr_) + { + FatalErrorIn + ( + "BlockCoeff::linearType& " + "BlockCoeff::asLinear()" + ) << "Requested linear but active type is: " + << blockCoeffBase::activeLevelNames_[this->activeType()] + << ". This is not allowed." + << abort(FatalError); + } + + return *linearCoeffPtr_; +} + + +template +const typename Foam::BlockCoeff::squareType& +Foam::BlockCoeff::asSquare() const +{ + if (!squareCoeffPtr_) + { + FatalErrorIn + ( + "BlockCoeff::squareType& " + "BlockCoeff::asSquare()" + ) << "Requested square but active type is: " + << blockCoeffBase::activeLevelNames_[this->activeType()] + << ". This is not allowed." + << abort(FatalError); + } + + return *squareCoeffPtr_; +} + + +template +typename Foam::BlockCoeff::scalarType& +Foam::BlockCoeff::asScalar() +{ + if (linearCoeffPtr_ || squareCoeffPtr_) + { + FatalErrorIn + ( + "BlockCoeff::scalarType& " + "BlockCoeff::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 +typename Foam::BlockCoeff::linearType& +Foam::BlockCoeff::asLinear() +{ + if (squareCoeffPtr_) + { + FatalErrorIn + ( + "BlockCoeff::linearType& " + "BlockCoeff::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 +typename Foam::BlockCoeff::squareType& +Foam::BlockCoeff::asSquare() +{ + if (!squareCoeffPtr_) + { + return this->toSquare(); + } + + return *squareCoeffPtr_; +} + + +template +typename Foam::BlockCoeff::scalarType +Foam::BlockCoeff::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::scalarType>" + "BlockCoeff::component(const direction dir) const" + ) << " not allocated." + << abort(FatalError); + } + + // Dummy return to keep compiler happy + return *scalarCoeffPtr_; +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +template +void Foam::BlockCoeff::operator=(const BlockCoeff& f) +{ + if (this == &f) + { + FatalErrorIn("BlockCoeff::operator=(const BlockCoeff&)") + << "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 +Foam::Ostream& Foam::operator<<(Ostream& os, const BlockCoeff& 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; +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockCoeff/BlockCoeff.H b/src/blockMatrix/BlockCoeff/BlockCoeff.H new file mode 100644 index 000000000..69c5cef7b --- /dev/null +++ b/src/blockMatrix/BlockCoeff/BlockCoeff.H @@ -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 BlockCoeff; + +template +Ostream& operator<<(Ostream&, const BlockCoeff&); + +/*---------------------------------------------------------------------------*\ + Class BlockCoeff Declaration +\*---------------------------------------------------------------------------*/ + +template +class BlockCoeff +: + public blockCoeffBase +{ +public: + + // Public data types + + //- Component type + typedef Type xType; + typedef Field xTypeField; + + //- Coefficient type + typedef typename pTraits::cmptType scalarType; + typedef Type linearType; + typedef typename outerProduct::type squareType; + + //- Field type + typedef Field scalarTypeField; + typedef Field linearTypeField; + typedef Field 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& 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::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::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&); + + //- Construct from Istream + BlockCoeff(Istream&); + + //- Clone + BlockCoeff 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&); + + + // IOstream operators + + friend Ostream& operator<< + ( + Ostream&, + const BlockCoeff& + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "BlockCoeff.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockCoeff/DecoupledBlockCoeff.C b/src/blockMatrix/BlockCoeff/DecoupledBlockCoeff.C new file mode 100644 index 000000000..d875fe1a1 --- /dev/null +++ b/src/blockMatrix/BlockCoeff/DecoupledBlockCoeff.C @@ -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 +typename Foam::DecoupledBlockCoeff::scalarType& +Foam::DecoupledBlockCoeff::toScalar() +{ + if (!scalarCoeffPtr_) + { + // Debug check: demotion + if (linearCoeffPtr_) + { + FatalErrorIn + ( + "DecoupledBlockCoeff::scalarType& " + "DecoupledBlockCoeff::toScalar()" + ) << "Detected demotion to scalar. Probably an error" + << abort(FatalError); + } + + scalarCoeffPtr_ = new scalarType(pTraits::zero); + } + + return *scalarCoeffPtr_; +} + + +template +typename Foam::DecoupledBlockCoeff::linearType& +Foam::DecoupledBlockCoeff::toLinear() +{ + if (!linearCoeffPtr_) + { + linearCoeffPtr_ = new linearType(pTraits::zero); + + // If scalar is active, promote to linear + if (scalarCoeffPtr_) + { + *linearCoeffPtr_ = (*scalarCoeffPtr_)*pTraits::one; + deleteDemandDrivenData(scalarCoeffPtr_); + } + } + + return *linearCoeffPtr_; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +Foam::DecoupledBlockCoeff::DecoupledBlockCoeff() +: + scalarCoeffPtr_(NULL), + linearCoeffPtr_(NULL) +{} + + +template +Foam::DecoupledBlockCoeff::DecoupledBlockCoeff +( + const DecoupledBlockCoeff& f +) +: + scalarCoeffPtr_(NULL), + linearCoeffPtr_(NULL) +{ + if (f.scalarCoeffPtr_) + { + scalarCoeffPtr_ = new scalarType(*(f.scalarCoeffPtr_)); + } + else if (f.linearCoeffPtr_) + { + linearCoeffPtr_ = new linearType(*(f.linearCoeffPtr_)); + } +} + + +template +Foam::DecoupledBlockCoeff::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::DecoupledBlockCoeff(Istream& is)", + is + ) << "invalid keyword while reading: " << key + << exit(FatalIOError); + } +} + + +template +Foam::DecoupledBlockCoeff Foam::DecoupledBlockCoeff::clone() const +{ + return DecoupledBlockCoeff(*this); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +template +Foam::DecoupledBlockCoeff::~DecoupledBlockCoeff() +{ + this->clear(); +} + + +template +void Foam::DecoupledBlockCoeff::clear() +{ + deleteDemandDrivenData(scalarCoeffPtr_); + deleteDemandDrivenData(linearCoeffPtr_); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +Foam::blockCoeffBase::activeLevel +Foam::DecoupledBlockCoeff::activeType() const +{ + if (scalarCoeffPtr_) + { + return blockCoeffBase::SCALAR; + } + else if (linearCoeffPtr_) + { + return blockCoeffBase::LINEAR; + } + else + { + return blockCoeffBase::UNALLOCATED; + } +} + + +template +void Foam::DecoupledBlockCoeff::checkActive() const +{ + label nActive = 0; + + if (scalarCoeffPtr_) nActive++; + if (linearCoeffPtr_) nActive++; + + if (nActive > 1) + { + FatalErrorIn + ( + "void Foam::DecoupledBlockCoeff::checkActive() const" + ) << "Activation/deactivation error. nActive = " << nActive + << abort(FatalError); + } +} + + +template +const typename Foam::DecoupledBlockCoeff::scalarType& +Foam::DecoupledBlockCoeff::asScalar() const +{ + if (!scalarCoeffPtr_) + { + FatalErrorIn + ( + "DecoupledBlockCoeff::scalarType& " + "DecoupledBlockCoeff::asScalar()" + ) << "Requested scalar but active type is: " + << blockCoeffBase::activeLevelNames_[this->activeType()] + << ". This is not allowed." + << abort(FatalError); + } + + return *scalarCoeffPtr_; +} + + +template +const typename Foam::DecoupledBlockCoeff::linearType& +Foam::DecoupledBlockCoeff::asLinear() const +{ + if (!linearCoeffPtr_) + { + FatalErrorIn + ( + "DecoupledBlockCoeff::linearType& " + "DecoupledBlockCoeff::asLinear()" + ) << "Requested linear but active type is: " + << blockCoeffBase::activeLevelNames_[this->activeType()] + << ". This is not allowed." + << abort(FatalError); + } + + return *linearCoeffPtr_; +} + + +template +typename Foam::DecoupledBlockCoeff::scalarType& +Foam::DecoupledBlockCoeff::asScalar() +{ + if (linearCoeffPtr_) + { + FatalErrorIn + ( + "DecoupledBlockCoeff::scalarType& " + "DecoupledBlockCoeff::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 +typename Foam::DecoupledBlockCoeff::linearType& +Foam::DecoupledBlockCoeff::asLinear() +{ + if (!linearCoeffPtr_) + { + return this->toLinear(); + } + + return *linearCoeffPtr_; +} + + +template +typename Foam::DecoupledBlockCoeff::scalarType +Foam::DecoupledBlockCoeff::component(const direction dir) const +{ + if (scalarCoeffPtr_) + { + return *scalarCoeffPtr_; + } + else if (linearCoeffPtr_) + { + return linearCoeffPtr_->component(dir); + } + else + { + FatalErrorIn + ( + "tmp::scalarType>" + "DecoupledBlockCoeff::component(const direction dir) const" + ) << " not allocated." + << abort(FatalError); + } + + // Dummy return to keep compiler happy + return *scalarCoeffPtr_; +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +template +void Foam::DecoupledBlockCoeff::operator= +( + const DecoupledBlockCoeff& f +) +{ + if (this == &f) + { + FatalErrorIn + ( + "DecoupledBlockCoeff::operator=(" + "const DecoupledBlockCoeff&)" + ) << "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 +Foam::Ostream& Foam::operator<<(Ostream& os, const DecoupledBlockCoeff& 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; +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockCoeff/DecoupledBlockCoeff.H b/src/blockMatrix/BlockCoeff/DecoupledBlockCoeff.H new file mode 100644 index 000000000..462b6016c --- /dev/null +++ b/src/blockMatrix/BlockCoeff/DecoupledBlockCoeff.H @@ -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 DecoupledBlockCoeff; + +template +Ostream& operator<<(Ostream&, const DecoupledBlockCoeff&); + +/*---------------------------------------------------------------------------*\ + Class DecoupledBlockCoeff Declaration +\*---------------------------------------------------------------------------*/ + +template +class DecoupledBlockCoeff +: + public blockCoeffBase +{ +public: + + // Public data types + + //- Component type + typedef Type xType; + typedef Field xTypeField; + + //- Coefficient type + typedef scalar scalarType; + typedef Type linearType; + + //- Field type + typedef Field scalarTypeField; + typedef Field 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& 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::zero; + } + } + + + // Inverse functions + + scalarType inverse(const scalarType& c) const + { + return 1.0/c; + } + + linearType inverse(const linearType& c) const + { + return cmptDivide(pTraits::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&); + + //- Construct from Istream + DecoupledBlockCoeff(Istream&); + + //- Clone + DecoupledBlockCoeff 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&); + + + // IOstream operators + + friend Ostream& operator<< + ( + Ostream&, + const DecoupledBlockCoeff& + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "DecoupledBlockCoeff.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockCoeff/blockCoeffBase.C b/src/blockMatrix/BlockCoeff/blockCoeffBase.C new file mode 100644 index 000000000..0b6654c41 --- /dev/null +++ b/src/blockMatrix/BlockCoeff/blockCoeffBase.C @@ -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::names[] = +{ + "unallocated", + "scalar", + "linear", + "square" +}; + +const Foam::NamedEnum +Foam::blockCoeffBase::activeLevelNames_; + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockCoeff/blockCoeffBase.H b/src/blockMatrix/BlockCoeff/blockCoeffBase.H new file mode 100644 index 000000000..33b441c8a --- /dev/null +++ b/src/blockMatrix/BlockCoeff/blockCoeffBase.H @@ -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 activeLevelNames_; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockCoeff/blockCoeffs.H b/src/blockMatrix/BlockCoeff/blockCoeffs.H new file mode 100644 index 000000000..cfb1c51c5 --- /dev/null +++ b/src/blockMatrix/BlockCoeff/blockCoeffs.H @@ -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 scalarBlockCoeff; +typedef BlockCoeff vectorBlockCoeff; +typedef BlockCoeff sphericalTensorBlockCoeff; +typedef BlockCoeff symmTensorBlockCoeff; +typedef BlockCoeff tensorBlockCoeff; + + +/* * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * */ + +template +scalar sumMult +( + const Field& f1, + const Field& f2 +) +{ + Type result = pTraits::zero; + + typename BlockCoeff::multiply mult; + + for (register label i = 0; i < f1.size(); i++) + { + result += mult(f1[i], f2[i]); + } + + return cmptSum(result); +} + + +template +scalar gSumMult +( + const Field& f1, + const Field& f2 +) +{ + scalar SumProd = sumMult(f1, f2); + reduce(SumProd, sumOp()); + return SumProd; +} + + +template<> +inline scalar sumMult +( + const scalarField& f1, + const scalarField& f2 +) +{ + return sumProd(f1, f2); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockCoeff/scalarBlockCoeff.C b/src/blockMatrix/BlockCoeff/scalarBlockCoeff.C new file mode 100644 index 000000000..9576f9f33 --- /dev/null +++ b/src/blockMatrix/BlockCoeff/scalarBlockCoeff.C @@ -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::BlockCoeff() +: + scalarCoeff_(pTraits::zero) +{} + + +Foam::BlockCoeff::BlockCoeff(const BlockCoeff& f) +: + scalarCoeff_(f.scalarCoeff_) +{} + + +Foam::BlockCoeff::BlockCoeff(Istream& is) +: + scalarCoeff_(readScalar(is)) +{} + + +Foam::BlockCoeff Foam::BlockCoeff::clone() const +{ + return BlockCoeff(*this); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +Foam::BlockCoeff::~BlockCoeff() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +void Foam::BlockCoeff::operator=(const BlockCoeff& f) +{ + if (this == &f) + { + FatalErrorIn + ( + "BlockCoeff::operator=(const BlockCoeff&)" + ) << "attempted assignment to self" + << abort(FatalError); + } + + scalarCoeff_ = f.scalarCoeff_; +} + + +// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * // + +Foam::Ostream& Foam::operator<<(Ostream& os, const BlockCoeff& f) +{ + os << f.scalarCoeff_; + + return os; +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockCoeff/scalarBlockCoeff.H b/src/blockMatrix/BlockCoeff/scalarBlockCoeff.H new file mode 100644 index 000000000..e53f2305f --- /dev/null +++ b/src/blockMatrix/BlockCoeff/scalarBlockCoeff.H @@ -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 +: + 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& 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&); + + //- Construct from Istream + BlockCoeff(Istream&); + + //- Clone + BlockCoeff 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&); + + + // IOstream operators + + friend Ostream& operator<< + ( + Ostream&, + const BlockCoeff& + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockCoeff/sphericalTensorBlockCoeff.C b/src/blockMatrix/BlockCoeff/sphericalTensorBlockCoeff.C new file mode 100644 index 000000000..c0522bf2f --- /dev/null +++ b/src/blockMatrix/BlockCoeff/sphericalTensorBlockCoeff.C @@ -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::BlockCoeff() +: + DecoupledBlockCoeff() +{} + + +Foam::BlockCoeff::BlockCoeff +( + const BlockCoeff& f +) +: + DecoupledBlockCoeff(f) +{} + + +Foam::BlockCoeff::BlockCoeff(Istream& is) +: + DecoupledBlockCoeff(is) +{} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockCoeff/sphericalTensorBlockCoeff.H b/src/blockMatrix/BlockCoeff/sphericalTensorBlockCoeff.H new file mode 100644 index 000000000..fd72c7b3b --- /dev/null +++ b/src/blockMatrix/BlockCoeff/sphericalTensorBlockCoeff.H @@ -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 +: + public DecoupledBlockCoeff +{ +public: + + // Constructors + + //- Construct null + explicit BlockCoeff(); + + //- Construct as copy + BlockCoeff(const BlockCoeff&); + + //- Construct from Istream + BlockCoeff(Istream&); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockCoeff/symmTensorBlockCoeff.C b/src/blockMatrix/BlockCoeff/symmTensorBlockCoeff.C new file mode 100644 index 000000000..f51b08f78 --- /dev/null +++ b/src/blockMatrix/BlockCoeff/symmTensorBlockCoeff.C @@ -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::BlockCoeff() +: + DecoupledBlockCoeff() +{} + + +Foam::BlockCoeff::BlockCoeff +( + const BlockCoeff& f +) +: + DecoupledBlockCoeff(f) +{} + + +Foam::BlockCoeff::BlockCoeff(Istream& is) +: + DecoupledBlockCoeff(is) +{} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockCoeff/symmTensorBlockCoeff.H b/src/blockMatrix/BlockCoeff/symmTensorBlockCoeff.H new file mode 100644 index 000000000..b114ba8dd --- /dev/null +++ b/src/blockMatrix/BlockCoeff/symmTensorBlockCoeff.H @@ -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 +: + public DecoupledBlockCoeff +{ +public: + + // Constructors + + //- Construct null + explicit BlockCoeff(); + + //- Construct as copy + BlockCoeff(const BlockCoeff&); + + //- Construct from Istream + BlockCoeff(Istream&); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockCoeff/tensorBlockCoeff.C b/src/blockMatrix/BlockCoeff/tensorBlockCoeff.C new file mode 100644 index 000000000..ecf927fea --- /dev/null +++ b/src/blockMatrix/BlockCoeff/tensorBlockCoeff.C @@ -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::BlockCoeff() +: + DecoupledBlockCoeff() +{} + + +Foam::BlockCoeff::BlockCoeff(const BlockCoeff& f) +: + DecoupledBlockCoeff(f) +{} + + +Foam::BlockCoeff::BlockCoeff(Istream& is) +: + DecoupledBlockCoeff(is) +{} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockCoeff/tensorBlockCoeff.H b/src/blockMatrix/BlockCoeff/tensorBlockCoeff.H new file mode 100644 index 000000000..d8590975a --- /dev/null +++ b/src/blockMatrix/BlockCoeff/tensorBlockCoeff.H @@ -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 +: + public DecoupledBlockCoeff +{ +public: + + // Constructors + + //- Construct null + explicit BlockCoeff(); + + //- Construct as copy + BlockCoeff(const BlockCoeff&); + + //- Construct from Istream + BlockCoeff(Istream&); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/BlockConstraint/BlockConstraint.C b/src/blockMatrix/BlockLduMatrix/BlockConstraint/BlockConstraint.C new file mode 100644 index 000000000..21be2112a --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/BlockConstraint/BlockConstraint.C @@ -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 +BlockConstraint::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 +BlockConstraint::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 +BlockConstraint::BlockConstraint(Istream& is) +: + rowID_(is), + value_(is), + fixedComponents_(is), + matrixCoeffsSet_(false), + upperCoeffsOwnerPtr_(NULL), + upperCoeffsNeighbourPtr_(NULL), + lowerCoeffsOwnerPtr_(NULL), + lowerCoeffsNeighbourPtr_(NULL) +{} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +template +BlockConstraint::~BlockConstraint() +{ + deleteDemandDrivenData(upperCoeffsOwnerPtr_); + deleteDemandDrivenData(upperCoeffsNeighbourPtr_); + + deleteDemandDrivenData(lowerCoeffsOwnerPtr_); + deleteDemandDrivenData(lowerCoeffsNeighbourPtr_); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +const BlockCoeff& BlockConstraint::diagCoeff() const +{ + if (matrixCoeffsSet_) + { + FatalErrorIn + ( + "const BlockCoeff& BlockConstraint::diagCoeff() const" + ) << "matrix coefficients not set" + << abort(FatalError); + } + + return diagCoeff_; +} + + +template +const Type& BlockConstraint::b() const +{ + if (matrixCoeffsSet_) + { + FatalErrorIn + ( + "Type BlockConstraint::b() const" + ) << "matrix coefficients not set" + << abort(FatalError); + } + + return b_; +} + + +template +const CoeffField& BlockConstraint::upperCoeffsOwner() const +{ + if (!upperCoeffsOwnerPtr_ || !matrixCoeffsSet_) + { + FatalErrorIn + ( + "const CoeffField& BlockConstraint::" + "upperCoeffsOwner() const" + ) << "upper matrix coefficients not set" + << abort(FatalError); + } + + return *upperCoeffsOwnerPtr_; +} + + +template +const CoeffField& BlockConstraint::upperCoeffsNeighbour() const +{ + if (!upperCoeffsNeighbourPtr_ || !matrixCoeffsSet_) + { + FatalErrorIn + ( + "const CoeffField& BlockConstraint::" + "upperCoeffsNeighbour() const" + ) << "upper matrix coefficients not set" + << abort(FatalError); + } + + return *upperCoeffsNeighbourPtr_; +} + + +template +const CoeffField& BlockConstraint::lowerCoeffsOwner() const +{ + if (!lowerCoeffsOwnerPtr_ || !matrixCoeffsSet_) + { + FatalErrorIn + ( + "const CoeffField& BlockConstraint::" + "lowerCoeffsOwner() const" + ) << "lower matrix coefficients not set" + << abort(FatalError); + } + + return *lowerCoeffsOwnerPtr_; +} + + +template +const CoeffField& BlockConstraint::lowerCoeffsNeighbour() const +{ + if (!lowerCoeffsNeighbourPtr_ || !matrixCoeffsSet_) + { + FatalErrorIn + ( + "const CoeffField& BlockConstraint::" + "lowerCoeffsNeighbour() const" + ) << "lower matrix coefficients not set" + << abort(FatalError); + } + + return *lowerCoeffsNeighbourPtr_; +} + + +template +void BlockConstraint::combine +( + const BlockConstraint& e +) +{ + for + ( + direction cmptI = 0; + cmptI < pTraits::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 +void BlockConstraint::clearMatrix() +{ + matrixCoeffsSet_ = false; + + diagCoeff_.clear(); + + b_ = pTraits::zero; + + deleteDemandDrivenData(upperCoeffsOwnerPtr_); + deleteDemandDrivenData(upperCoeffsNeighbourPtr_); + + deleteDemandDrivenData(lowerCoeffsOwnerPtr_); + deleteDemandDrivenData(lowerCoeffsNeighbourPtr_); +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +template +void BlockConstraint::operator= +( + const BlockConstraint& 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 +Ostream& operator<<(Ostream& os, const BlockConstraint& e) +{ + os << e.rowID_ << nl + << e.value_ << nl + << e.fixedComponents_ << nl; + + os.check("Ostream& operator<<(Ostream&, BlockConstraint&"); + + return os; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/BlockConstraint/BlockConstraint.H b/src/blockMatrix/BlockLduMatrix/BlockConstraint/BlockConstraint.H new file mode 100644 index 000000000..502a3024f --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/BlockConstraint/BlockConstraint.H @@ -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 BlockConstraint; + +template +Ostream& operator<<(Ostream&, const BlockConstraint&); + + +/*---------------------------------------------------------------------------*\ + Class BlockConstraint Declaration +\*---------------------------------------------------------------------------*/ + +template +class BlockConstraint +{ + // Public data types + + typedef CoeffField TypeCoeffField; + typedef Field 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 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::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& 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&); + + //- Set matrix coefficients + void setMatrix + ( + const BlockLduMatrix& matrix, + const TypeField& x, + const TypeField& b + ); + + + //- Eliminate equation + void eliminateEquation + ( + BlockLduMatrix& matrix, + TypeField& b + ) const; + + //- Set x, b and diagonal in eliminated equation + void setSourceDiag + ( + BlockLduMatrix&, + Field& x, + Field& b + ) const; + + + //- Reconstruct matrix coefficients + void reconstructMatrix(BlockLduMatrix&) const; + + //- Clear matrix coefficients + void clearMatrix(); + + + // Member Operators + + void operator=(const BlockConstraint&); + + + // Ostream Operator + + friend Ostream& operator<< + ( + Ostream&, + const BlockConstraint& + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "BlockConstraint.C" +# include "BlockConstraintTools.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/BlockConstraint/BlockConstraintTools.C b/src/blockMatrix/BlockLduMatrix/BlockConstraint/BlockConstraintTools.C new file mode 100644 index 000000000..abc478715 --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/BlockConstraint/BlockConstraintTools.C @@ -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 +void BlockConstraint::setMatrix +( + const BlockLduMatrix& matrix, + const TypeField& x, + const TypeField& b +) +{ + if (matrixCoeffsSet_) + { + FatalErrorIn + ( + "void BlockConstraint::setMatrix\n" + "(\n" + " const BlockLduMatrix& 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 +void BlockConstraint::eliminateEquation +( + BlockLduMatrix& 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::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 +void BlockConstraint::setSourceDiag +( + BlockLduMatrix& matrix, + Field& x, + Field& b +) const +{ + const Type& fc = fixedComponents(); + + typename BlockCoeff::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 +void BlockConstraint::reconstructMatrix +( + BlockLduMatrix& matrix +) const +{ + if (!matrixCoeffsSet_) + { + FatalErrorIn + ( + "void BlockConstraint::reconstructMatrix(" + "BlockLduMatrix& 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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/BlockConstraint/blockConstraints.H b/src/blockMatrix/BlockLduMatrix/BlockConstraint/blockConstraints.H new file mode 100644 index 000000000..fa31e1c38 --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/BlockConstraint/blockConstraints.H @@ -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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/BlockConstraint/scalarBlockConstraint.C b/src/blockMatrix/BlockLduMatrix/BlockConstraint/scalarBlockConstraint.C new file mode 100644 index 000000000..d08fe3acf --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/BlockConstraint/scalarBlockConstraint.C @@ -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::combine +( + const BlockConstraint& e +) +{ + if (e.fixedComponents_ > fixedComponents_) + { + fixedComponents_ = e.fixedComponents_; + + value_ = e.value_; + } +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/BlockConstraint/scalarBlockConstraint.H b/src/blockMatrix/BlockLduMatrix/BlockConstraint/scalarBlockConstraint.H new file mode 100644 index 000000000..63348908b --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/BlockConstraint/scalarBlockConstraint.H @@ -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::combine +( + const BlockConstraint& e +); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/BlockLduInterface/BlockLduInterface.H b/src/blockMatrix/BlockLduMatrix/BlockLduInterface/BlockLduInterface.H new file mode 100644 index 000000000..bbeaf215a --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/BlockLduInterface/BlockLduInterface.H @@ -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 BlockLduMatrix; + +/*---------------------------------------------------------------------------*\ + Class BlockLduInterface Declaration +\*---------------------------------------------------------------------------*/ + +template +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& matrix, + Field& Ax, + const Field& x + ) const + {} + + //- Update result based on interface functionality + virtual void updateMatrix + ( + const BlockLduMatrix& matrix, + const FieldField& coeffs, + Field& Ax, + const Field& x + ) const = 0; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/BlockLduMatrix.C b/src/blockMatrix/BlockLduMatrix/BlockLduMatrix.C new file mode 100644 index 000000000..de72351d5 --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/BlockLduMatrix.C @@ -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 +const Foam::label Foam::BlockLduMatrix::fixFillIn +( + debug::optimisationSwitch("matrixConstraintFillIn", 4) +); + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +Foam::BlockLduMatrix::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(addr.patchAddr(i).size())); + coupleLower_.set(i, new CoeffField(addr.patchAddr(i).size())); + } +} + + +template +Foam::BlockLduMatrix::BlockLduMatrix(const BlockLduMatrix& 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 +Foam::BlockLduMatrix::~BlockLduMatrix() +{ + deleteDemandDrivenData(diagPtr_); + deleteDemandDrivenData(upperPtr_); + deleteDemandDrivenData(lowerPtr_); +} + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + + +template +typename Foam::BlockLduMatrix::TypeCoeffField& +Foam::BlockLduMatrix::diag() +{ + if (!diagPtr_) + { + diagPtr_ = new TypeCoeffField(lduAddr().size()); + } + + return *diagPtr_; +} + + +template +const typename Foam::BlockLduMatrix::TypeCoeffField& +Foam::BlockLduMatrix::diag() const +{ + if (!diagPtr_) + { + FatalErrorIn + ( + "const TypeCoeffField& BlockLduMatrix::diag() const" + ) << "diagPtr_ unallocated" + << abort(FatalError); + } + + return *diagPtr_; +} + + +template +typename Foam::BlockLduMatrix::TypeCoeffField& +Foam::BlockLduMatrix::upper() +{ + if (!upperPtr_) + { + upperPtr_ = new TypeCoeffField(lduAddr().lowerAddr().size()); + } + + return *upperPtr_; +} + + +template +const typename Foam::BlockLduMatrix::TypeCoeffField& +Foam::BlockLduMatrix::upper() const +{ + if (!upperPtr_) + { + FatalErrorIn + ( + "const TypeCoeffField& BlockLduMatrix::upper() const" + ) << "upperPtr_ unallocated" + << abort(FatalError); + } + + return *upperPtr_; +} + + +template +typename Foam::BlockLduMatrix::TypeCoeffField& +Foam::BlockLduMatrix::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 +const typename Foam::BlockLduMatrix::TypeCoeffField& +Foam::BlockLduMatrix::lower() const +{ + if (!lowerPtr_) + { + FatalErrorIn + ( + "const TypeCoeffField& BlockLduMatrix::lower() const" + ) << "lowerPtr_ unallocated" + << abort(FatalError); + } + + return *lowerPtr_; +} + + +template +bool Foam::BlockLduMatrix::empty() const +{ + return (!diagPtr_ && !lowerPtr_ && !upperPtr_); +} + + +template +bool Foam::BlockLduMatrix::diagonal() const +{ + return (diagPtr_ && !lowerPtr_ && !upperPtr_); +} + + +template +bool Foam::BlockLduMatrix::symmetric() const +{ + if (lowerPtr_ && !upperPtr_) + { + FatalErrorIn + ( + "bool BlockLduMatrix::symmetric() const" + ) << "Matrix assembly error: symmetric matrix but only lower " + << "triangle is allocated. This is not allowed." + << abort(FatalError); + } + + return (diagPtr_ && (!lowerPtr_ && upperPtr_)); +} + + +template +bool Foam::BlockLduMatrix::asymmetric() const +{ + return (diagPtr_ && lowerPtr_ && upperPtr_); +} + + +template +bool Foam::BlockLduMatrix::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 +Foam::Ostream& Foam::operator<<(Ostream& os, const BlockLduMatrix& ldum) +{ + if (ldum.diagPtr_) + { + os << *ldum.diagPtr_ << nl; + } + else + { + // Dummy write for consistency + os << typename BlockLduMatrix::TypeCoeffField + (ldum.lduAddr().size()) << nl; + } + + if (ldum.upperPtr_) + { + os << *ldum.upperPtr_ << nl; + } + else + { + // Dummy write for consistency + os << typename BlockLduMatrix::TypeCoeffField + (ldum.lduAddr().lowerAddr().size()) << nl; + } + + if (ldum.lowerPtr_) + { + os << *ldum.lowerPtr_ << nl; + } + else + { + // Dummy write for consistency + os << typename BlockLduMatrix::TypeCoeffField + (ldum.lduAddr().lowerAddr().size()) << nl; + } + + os << endl; + + os.check("Ostream& operator<<(Ostream&, const BlockLduMatrix&"); + + return os; +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/BlockLduMatrix.H b/src/blockMatrix/BlockLduMatrix/BlockLduMatrix.H new file mode 100644 index 000000000..6ba3112af --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/BlockLduMatrix.H @@ -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 BlockLduMatrix; + +template +Ostream& operator<<(Ostream&, const BlockLduMatrix&); + +template +class BlockConstraint; + + +/*---------------------------------------------------------------------------*\ + Class BlockLduMatrix Declaration +\*---------------------------------------------------------------------------*/ + +template +class BlockLduMatrix +: + public refCount +{ +public: + + // Public data types + + typedef CoeffField TypeCoeffField; + typedef Field TypeField; + typedef BlockConstraint ConstraintType; + + +private: + + // Private data + + // LDU mesh reference + const lduMesh& lduMesh_; + + + // Block matrix elements + + //- Diagonal coefficients + CoeffField* diagPtr_; + + //- Upper triangle coefficients. Also used for symmetric matrix + CoeffField* upperPtr_; + + //- Lower triangle coefficients + CoeffField *lowerPtr_; + + + // Coupling + + //- List of coupled interfaces + PtrList > interfaces_; + + //- Coupled interface coefficients, upper + FieldField coupleUpper_; + + //- Coupled interface coefficients, lower + FieldField coupleLower_; + + + // Constraints + + //- Equation triangle map + mutable Map 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 decoupledH(const TypeField& x) const; + + //- Return L-U vector-matrix multiplication in off-diagonal form, + // decoupled version + tmp decoupledFaceH(const TypeField& x) const; + + +protected: + + // Access to constraints + + //- Return constraint map + const Map& fixedEqns() const + { + return fixedEqns_; + } + + + //- Return access constraint map + Map& fixedEqns() + { + return fixedEqns_; + } + + +public: + + //- Runtime type information + TypeName("BlockLduMatrix"); + + + // Constructors + + //- Construct given addressing + explicit BlockLduMatrix(const lduMesh&); + + //- Construct as copy + BlockLduMatrix(const BlockLduMatrix&); + + + // 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& coupleUpper() + { + return coupleUpper_; + } + + //- Return coupled interface coefficients, upper + const FieldField& coupleUpper() const + { + return coupleUpper_; + } + + //- Return access to coupled interface coefficients, lower + FieldField& coupleLower() + { + return coupleLower_; + } + + //- Return coupled interface coefficients, lower + const FieldField& 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& 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 residual + ( + const TypeField& x + ) const; + + tmp residual + ( + const TypeField& x, + const TypeField& b + ) const; + + + // H-operations + + //- Return L-U vector-matrix multiplication in row-form + tmp H(const TypeField&) const; + + //- Return L-U vector-matrix multiplication in off-diagonal form + tmp faceH(const TypeField&) const; + + + // Member operators + + void operator=(const BlockLduMatrix&); + + void negate(); + + void operator+=(const BlockLduMatrix&); + void operator-=(const BlockLduMatrix&); + + void operator*=(const scalarField&); + void operator*=(const scalar); + + + // Ostream operator + + friend Ostream& operator<< + ( + Ostream&, + const BlockLduMatrix& + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // 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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/BlockLduMatrixATmul.C b/src/blockMatrix/BlockLduMatrix/BlockLduMatrixATmul.C new file mode 100644 index 000000000..51869f5c6 --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/BlockLduMatrixATmul.C @@ -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 +void Foam::BlockLduMatrix::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 +void Foam::BlockLduMatrix::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::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 +void Foam::BlockLduMatrix::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 +void Foam::BlockLduMatrix::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::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 +void Foam::BlockLduMatrix::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]]; + } + } + } + } +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/BlockLduMatrixDecouple.C b/src/blockMatrix/BlockLduMatrix/BlockLduMatrixDecouple.C new file mode 100644 index 000000000..5975bdd73 --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/BlockLduMatrixDecouple.C @@ -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 +void Foam::BlockLduMatrix::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&>(*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&>(*this).lower(); + + const TypeCoeffField& Upper = + const_cast&>(*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::decoupledSumDiag()") + << "No off-diagonal available" + << abort(FatalError); + } +} + + +template +void Foam::BlockLduMatrix::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&>(*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&>(*this).lower(); + + const TypeCoeffField& Upper = + const_cast&>(*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::decoupledNegSumDiag()") + << "No off-diagonal available" + << abort(FatalError); + } +} + + +template +void Foam::BlockLduMatrix::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::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::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::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::decoupledCheck() const : " + << "Asymmetric matrix: raw matrix difference: " + << sum(mag(activeDiagCopy)) + << " scaled: " + << sum(mag(activeDiagCopy))/sum(mag(this->diag().asScalar())) + << endl; + } + } + else + { + Info<< "void BlockLduMatrix::decoupledCheck() const : " + << "Diagonal matrix" << endl; + } +} + + +template +void Foam::BlockLduMatrix::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::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&>(*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::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::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&>(*this).lower(); + + const TypeCoeffField& Upper = + const_cast&>(*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::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::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 +void Foam::BlockLduMatrix::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 +void Foam::BlockLduMatrix::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& Diag = this->diag(); + const TypeCoeffField& Upper = this->upper(); + + // Diagonal multiplication, no indirection + multiply(Ax, Diag, x); + + // Create multiplication function object + typename BlockCoeff::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 +void Foam::BlockLduMatrix::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& Diag = this->diag(); + const TypeCoeffField& Upper = this->upper(); + + // Diagonal multiplication, no indirection + multiply(Tx, Diag, x); + + // Create multiplication function object + typename BlockCoeff::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]]); + } + } + } +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/BlockLduMatrixDecoupledHOps.C b/src/blockMatrix/BlockLduMatrix/BlockLduMatrixDecoupledHOps.C new file mode 100644 index 000000000..cbc371ca4 --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/BlockLduMatrixDecoupledHOps.C @@ -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 +Foam::tmp > +Foam::BlockLduMatrix::decoupledH(const Field& x) const +{ + typedef typename TypeCoeffField::scalarTypeField scalarTypeField; + typedef typename TypeCoeffField::linearTypeField linearTypeField; + + // Create result + tmp > tresult + ( + new Field(lduAddr().size(), pTraits::zero) + ); + Field& result = tresult(); + + const unallocLabelList& u = lduAddr().upperAddr(); + const unallocLabelList& l = lduAddr().lowerAddr(); + + const TypeCoeffField& Upper = this->upper(); + + // Create multiplication function object + typename BlockCoeff::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 +Foam::tmp > +Foam::BlockLduMatrix::decoupledFaceH(const Field& 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 > tresult(new Field(u.size(), pTraits::zero)); + Field& result = tresult(); + + const TypeCoeffField& Upper = this->upper(); + + // Create multiplication function object + typename BlockCoeff::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; +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/BlockLduMatrixHOps.C b/src/blockMatrix/BlockLduMatrix/BlockLduMatrixHOps.C new file mode 100644 index 000000000..6dd246e6a --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/BlockLduMatrixHOps.C @@ -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 +Foam::tmp > +Foam::BlockLduMatrix::H(const Field& x) const +{ + typedef typename TypeCoeffField::scalarTypeField scalarTypeField; + typedef typename TypeCoeffField::linearTypeField linearTypeField; + typedef typename TypeCoeffField::squareTypeField squareTypeField; + + // Create result + tmp > tresult + ( + new Field(lduAddr().size(), pTraits::zero) + ); + Field& result = tresult(); + + const unallocLabelList& u = lduAddr().upperAddr(); + const unallocLabelList& l = lduAddr().lowerAddr(); + + const TypeCoeffField& Upper = this->upper(); + + // Create multiplication function object + typename BlockCoeff::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 +Foam::tmp > +Foam::BlockLduMatrix::faceH(const Field& 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 > tresult(new Field(u.size(), pTraits::zero)); + Field& result = tresult(); + + const TypeCoeffField& Upper = this->upper(); + + // Create multiplication function object + typename BlockCoeff::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]]); + } + } + } +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/BlockLduMatrixOperations.C b/src/blockMatrix/BlockLduMatrix/BlockLduMatrixOperations.C new file mode 100644 index 000000000..0dd54321e --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/BlockLduMatrixOperations.C @@ -0,0 +1,1039 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 "BlockLduMatrix.H" +#include "tmp.H" + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +void Foam::BlockLduMatrix::sumDiag() +{ + typedef typename TypeCoeffField::scalarTypeField scalarTypeField; + typedef typename TypeCoeffField::linearTypeField linearTypeField; + typedef typename TypeCoeffField::squareTypeField squareTypeField; + + TypeCoeffField& Diag = this->diag(); + + const unallocLabelList& l = lduAddr().lowerAddr(); + const unallocLabelList& u = lduAddr().upperAddr(); + + if (this->symmetric()) + { + // Symmetric matrix: re-use upper transpose for lower coefficients + + const TypeCoeffField& Upper = + const_cast&>(*this).upper(); + + if + ( + Upper.activeType() == blockCoeffBase::SQUARE + || Diag.activeType() == blockCoeffBase::SQUARE + ) + { + const squareTypeField& activeUpper = Upper.asSquare(); + squareTypeField& activeDiag = Diag.asSquare(); + + for (register label coeffI = 0; coeffI < l.size(); coeffI++) + { + activeDiag[l[coeffI]] += activeUpper[coeffI].T(); + activeDiag[u[coeffI]] += activeUpper[coeffI]; + } + } + else 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&>(*this).lower(); + + const TypeCoeffField& Upper = + const_cast&>(*this).upper(); + + if + ( + Lower.activeType() == blockCoeffBase::SQUARE + || Upper.activeType() == blockCoeffBase::SQUARE + || Diag.activeType() == blockCoeffBase::SQUARE + ) + { + const squareTypeField& activeLower = Lower.asSquare(); + const squareTypeField& activeUpper = Upper.asSquare(); + squareTypeField& activeDiag = Diag.asSquare(); + + for (register label coeffI = 0; coeffI < l.size(); coeffI++) + { + activeDiag[l[coeffI]] += activeLower[coeffI]; + activeDiag[u[coeffI]] += activeUpper[coeffI]; + } + } + else 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::sumDiag()") + << "No off-diagonal available" + << abort(FatalError); + } +} + + +template +void Foam::BlockLduMatrix::negSumDiag() +{ + typedef typename TypeCoeffField::scalarTypeField scalarTypeField; + typedef typename TypeCoeffField::linearTypeField linearTypeField; + typedef typename TypeCoeffField::squareTypeField squareTypeField; + + TypeCoeffField& Diag = this->diag(); + + const unallocLabelList& l = lduAddr().lowerAddr(); + const unallocLabelList& u = lduAddr().upperAddr(); + + if (this->symmetric()) + { + // Symmetric matrix: re-use upper transpose for lower coefficients + + const TypeCoeffField& Upper = + const_cast&>(*this).upper(); + + if + ( + Upper.activeType() == blockCoeffBase::SQUARE + || Diag.activeType() == blockCoeffBase::SQUARE + ) + { + const squareTypeField& activeUpper = Upper.asSquare(); + squareTypeField& activeDiag = Diag.asSquare(); + + for (register label coeffI = 0; coeffI < l.size(); coeffI++) + { + activeDiag[l[coeffI]] -= activeUpper[coeffI].T(); + activeDiag[u[coeffI]] -= activeUpper[coeffI]; + } + } + else 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&>(*this).lower(); + + const TypeCoeffField& Upper = + const_cast&>(*this).upper(); + + if + ( + Lower.activeType() == blockCoeffBase::SQUARE + || Upper.activeType() == blockCoeffBase::SQUARE + || Diag.activeType() == blockCoeffBase::SQUARE + ) + { + const squareTypeField& activeLower = Lower.asSquare(); + const squareTypeField& activeUpper = Upper.asSquare(); + squareTypeField& activeDiag = Diag.asSquare(); + + for (register label coeffI = 0; coeffI < l.size(); coeffI++) + { + activeDiag[l[coeffI]] -= activeLower[coeffI]; + activeDiag[u[coeffI]] -= activeUpper[coeffI]; + } + } + else 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::negSumDiag()") + << "No off-diagonal available" + << abort(FatalError); + } +} + + +template +void Foam::BlockLduMatrix::check() const +{ + typedef typename TypeCoeffField::scalarTypeField scalarTypeField; + typedef typename TypeCoeffField::linearTypeField linearTypeField; + typedef typename TypeCoeffField::squareTypeField squareTypeField; + + // Copy the diagonal + TypeCoeffField DiagCopy(this->diag().size()); +// TypeCoeffField DiagCopy = this->diag(); + + const unallocLabelList& l = lduAddr().lowerAddr(); + const unallocLabelList& u = lduAddr().upperAddr(); + + if (this->symmetric()) + { + // Symmetric matrix: re-use upper transpose for lower coefficients + + const TypeCoeffField& Upper = this->upper(); + + if + ( + Upper.activeType() == blockCoeffBase::SQUARE + || DiagCopy.activeType() == blockCoeffBase::SQUARE + ) + { + const squareTypeField& activeUpper = Upper.asSquare(); + squareTypeField& activeDiagCopy = DiagCopy.asSquare(); + + for (register label coeffI = 0; coeffI < l.size(); coeffI++) + { + activeDiagCopy[l[coeffI]] += activeUpper[coeffI].T(); + activeDiagCopy[u[coeffI]] += activeUpper[coeffI]; + } + + Info<< "void BlockLduMatrix::check() const : " + << "Symmetric matrix: raw matrix difference: " + << sum(mag(activeDiagCopy)) + << " scaled: " + << sum(mag(activeDiagCopy))/sum(mag(this->diag().asSquare())) + << endl; + } + else 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::check() 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::check() 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::SQUARE + || Upper.activeType() == blockCoeffBase::SQUARE + || DiagCopy.activeType() == blockCoeffBase::SQUARE + ) + { + const squareTypeField& activeLower = Lower.asSquare(); + const squareTypeField& activeUpper = Upper.asSquare(); + squareTypeField& activeDiagCopy = DiagCopy.asSquare(); + + for (register label coeffI = 0; coeffI < l.size(); coeffI++) + { + activeDiagCopy[l[coeffI]] += activeLower[coeffI]; + activeDiagCopy[u[coeffI]] += activeUpper[coeffI]; + } + + Info<< "void BlockLduMatrix::check() const : " + << "Asymmetric matrix: raw matrix difference: " + << sum(mag(activeDiagCopy)) + << " scaled: " + << sum(mag(activeDiagCopy))/sum(mag(this->diag().asSquare())) + << endl; + } + else 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::check() 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::check() const : " + << "Asymmetric matrix: raw matrix difference: " + << sum(mag(activeDiagCopy)) + << " scaled: " + << sum(mag(activeDiagCopy))/sum(mag(this->diag().asScalar())) + << endl; + } + } + else + { + Info<< "void BlockLduMatrix::check() const : " + << "Diagonal matrix" << endl; + } +} + + +template +void Foam::BlockLduMatrix::relax +( + const Field& x, + Field& b, + const scalar alpha +) +{ + typedef typename TypeCoeffField::scalarTypeField scalarTypeField; + typedef typename TypeCoeffField::linearTypeField linearTypeField; + typedef typename TypeCoeffField::squareTypeField squareTypeField; + + //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::multiply mult; + + const unallocLabelList& l = lduAddr().lowerAddr(); + const unallocLabelList& u = lduAddr().upperAddr(); + + if (this->symmetric()) + { + // Symmetric matrix: re-use upper transpose for lower coefficients + + const TypeCoeffField& Upper = + const_cast&>(*this).upper(); + + if + ( + Upper.activeType() == blockCoeffBase::SQUARE + || Diag.activeType() == blockCoeffBase::SQUARE + ) + { + const squareTypeField& activeUpper = Upper.asSquare(); + squareTypeField& activeDiag = Diag.asSquare(); + + // Make a copy of diagonal before relaxation + squareTypeField activeDiagOld = activeDiag; + + // There are options for under-relaxing the block diagonal + // coefficient. Currently, the complete diagonal block is + // under-relaxed. There's no checking on the off-diag sum + + squareTypeField sumOff + ( + activeDiag.size(), + pTraits::zero + ); + + for (register label coeffI = 0; coeffI < l.size(); coeffI++) + { + sumOff[u[coeffI]] += cmptMag(activeUpper[coeffI].T()); + 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::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::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::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] += (activeDiag[i] - activeDiagOld[i])*x[i]; + } + } + } + else if (this->asymmetric()) + { + // Full asymmetric matrix + + const TypeCoeffField& Lower = + const_cast&>(*this).lower(); + + const TypeCoeffField& Upper = + const_cast&>(*this).upper(); + + if + ( + Lower.activeType() == blockCoeffBase::SQUARE + || Upper.activeType() == blockCoeffBase::SQUARE + || Diag.activeType() == blockCoeffBase::SQUARE + ) + { + const squareTypeField& activeLower = Lower.asSquare(); + const squareTypeField& activeUpper = Upper.asSquare(); + squareTypeField& activeDiag = Diag.asSquare(); + + // Make a copy of diagonal before relaxation + squareTypeField activeDiagOld = activeDiag; + + // There are options for under-relaxing the block diagonal + // coefficient. Currently, the complete diagonal block is + // under-relaxed. There's no checking on the off-diag sum + + squareTypeField sumOff + ( + activeDiag.size(), + pTraits::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; + + // Add the relaxation contribution to b + forAll (b, i) + { + b[i] += mult(activeDiag[i] - activeDiagOld[i], x[i]); + } + } + else 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(); + + // Make a copy of diagonal before relaxation + linearTypeField activeDiagOld = activeDiag; + + linearTypeField sumOff + ( + activeDiag.size(), + pTraits::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; + + // Add the relaxation contribution to b + forAll (b, i) + { + b[i] += mult(activeDiag[i] - activeDiagOld[i], x[i]); + } + } + 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::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; + + // Add the relaxation contribution to b + forAll (b, i) + { + b[i] += activeDiag[i] - activeDiagOld[i]*x[i]; + } + } + } +} + + +template +void Foam::BlockLduMatrix::setValue +( + const label eqnIndex, + const Type& value +) +{ + BlockConstraint cp(eqnIndex, value); + + if (!fixedEqns_.found(eqnIndex)) + { + fixedEqns_.insert(eqnIndex, cp); + } + else + { + WarningIn + ( + "void BlockLduMatrix::setValue(const label eqnIndex, " + "const Type& value)" + ) << "Adding constraint on an already constrained point." + << " Point: " << eqnIndex << endl; + + fixedEqns_[eqnIndex].combine(cp); + } +} + + +template +Foam::tmp > Foam::BlockLduMatrix::residual +( + const Field& x +) const +{ + Field Ax(x.size()); + Amul(Ax, x); + return -Ax; +} + + +template +typename Foam::tmp > Foam::BlockLduMatrix::residual +( + const Field& x, + const Field& b +) const +{ + return b + residual(x); +} + + +template +void Foam::BlockLduMatrix::negate() +{ + if (lowerPtr_) + { + lowerPtr_->negate(); + } + + if (upperPtr_) + { + upperPtr_->negate(); + } + + if (diagPtr_) + { + diagPtr_->negate(); + } + + // Do coupling coefficients + coupleUpper_.negate(); + coupleLower_.negate(); +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + + +template +void Foam::BlockLduMatrix::operator=(const BlockLduMatrix& A) +{ + if (this == &A) + { + FatalErrorIn + ( + "void BlockLduMatrix::operator=" + "(const BlockLduMatrix& A)" + ) << "attempted assignment to self" + << abort(FatalError); + } + + if (A.lowerPtr_) + { + lower() = A.lower(); + } + else if (lowerPtr_) + { + delete lowerPtr_; + lowerPtr_ = NULL; + } + + if (A.upperPtr_) + { + upper() = A.upper(); + } + else if (upperPtr_) + { + delete upperPtr_; + upperPtr_ = NULL; + } + + if (A.diagPtr_) + { + diag() = A.diag(); + } + + // Copy interface data + interfaces_ = A.interfaces_; + coupleUpper_ = A.coupleUpper_; + coupleLower_ = A.coupleLower_; + + // Copy constraints + fixedEqns_ = A.fixedEqns_; +} + + +template +void Foam::BlockLduMatrix::operator+=(const BlockLduMatrix& A) +{ + // Do diagonal first + if (A.thereIsDiag()) + { + diag() += A.diag(); + } + + if (A.symmetric()) + { + upper() += A.upper(); + + if (this->asymmetric()) + { + lower() += A.upper().transpose(); + } + } + + if (A.asymmetric()) + { + upper() += A.upper(); + lower() += A.lower(); + } + + // Interface data + coupleUpper_ += A.coupleUpper_; + coupleLower_ += A.coupleLower_; +} + + +template +void Foam::BlockLduMatrix::operator-=(const BlockLduMatrix& A) +{ + // Do diagonal first + if (A.thereIsDiag()) + { + diag() -= A.diag(); + } + + if (A.symmetric()) + { + upper() -= A.upper(); + + if (this->asymmetric()) + { + lower() -= A.upper().transpose(); + } + } + + if (A.asymmetric()) + { + upper() -= A.upper(); + lower() -= A.lower(); + } + + // Interface data + coupleUpper_ -= A.coupleUpper_; + coupleLower_ -= A.coupleLower_; +} + + +template +void Foam::BlockLduMatrix::operator*=(const scalarField& sf) +{ + typedef typename TypeCoeffField::scalarTypeField scalarTypeField; + typedef typename TypeCoeffField::linearTypeField linearTypeField; + typedef typename TypeCoeffField::squareTypeField squareTypeField; + + //HJ Missing code: add coupling coefficients op*= + // HJ, 21/Feb/2008 + + 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]]; + } + } + else if (Upper.activeType() == blockCoeffBase::SQUARE) + { + squareTypeField& activeUpper = Upper.asSquare(); + + 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]]; + } + } + else if (Lower.activeType() == blockCoeffBase::SQUARE) + { + squareTypeField& activeLower = Lower.asSquare(); + + for (register label coeffI = 0; coeffI < u.size(); coeffI++) + { + activeLower[coeffI] *= sf[u[coeffI]]; + } + } + } +} + + +template +void Foam::BlockLduMatrix::operator*=(const scalar s) +{ + if (diagPtr_) + { + *diagPtr_ *= s; + } + + if (upperPtr_) + { + *upperPtr_ *= s; + } + + if (lowerPtr_) + { + *lowerPtr_ *= s; + } + + // Interface data + coupleUpper_ *= s; + coupleLower_ *= s; +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/BlockLduMatrixUpdateInterfaces.C b/src/blockMatrix/BlockLduMatrix/BlockLduMatrixUpdateInterfaces.C new file mode 100644 index 000000000..dbefc0b75 --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/BlockLduMatrixUpdateInterfaces.C @@ -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 +void Foam::BlockLduMatrix::initInterfaces +( + TypeField& Ax, + const TypeField& x +) const +{ + forAll (interfaces_, interfaceI) + { + interfaces_[interfaceI].initMatrixUpdate(*this, Ax, x); + } +} + + +template +void Foam::BlockLduMatrix::updateInterfaces +( + const FieldField& coeffs, + TypeField& Ax, + const TypeField& x +) const +{ + forAll (interfaces_, interfaceI) + { + interfaces_[interfaceI].updateMatrix(*this, coeffs, Ax, x); + } + +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/blockLduMatrices.C b/src/blockMatrix/BlockLduMatrix/blockLduMatrices.C new file mode 100644 index 000000000..324f393e5 --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/blockLduMatrices.C @@ -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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/blockLduMatrices.H b/src/blockMatrix/BlockLduMatrix/blockLduMatrices.H new file mode 100644 index 000000000..14c265a56 --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/blockLduMatrices.H @@ -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 blockScalarMatrix; +typedef BlockLduMatrix blockVectorMatrix; +typedef BlockLduMatrix blockSphericalTensorMatrix; +typedef BlockLduMatrix blockSymmTensorMatrix; +typedef BlockLduMatrix blockTensorMatrix; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/scalarBlockLduMatrix.C b/src/blockMatrix/BlockLduMatrix/scalarBlockLduMatrix.C new file mode 100644 index 000000000..c60e0df54 --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/scalarBlockLduMatrix.C @@ -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::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::sumDiag()") + << "No off-diagonal available" + << abort(FatalError); + } +} + + +template<> +void BlockLduMatrix::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::negSumDiag()") + << "No off-diagonal available" + << abort(FatalError); + } +} + + +template<> +void BlockLduMatrix::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::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::check() const : " + << "Asymmetric matrix: raw matrix difference: " + << sum(mag(activeDiagCopy)) + << " scaled: " + << sum(mag(activeDiagCopy))/sum(mag(this->diag())) + << endl; + } + else + { + Info<< "void BlockLduMatrix::check() const : " + << "Diagonal matrix" << endl; + } +} + + +template<> +void BlockLduMatrix::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::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::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::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::segregateB +( + scalarField&, + const scalarField& +) const +{ + FatalErrorIn + ( + "void BlockLduMatrix::segregateB\n" + "(\n" + " scalarField&,\n" + " const scalarField&\n" + ") const" + ) << "Requested decoupling of scalar matrix - never coupled" + << abort(FatalError); +} + + +template<> +tmp BlockLduMatrix::H(const scalarField& x) const +{ + tmp 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 BlockLduMatrix::faceH(const scalarField& x) const +{ + tmp 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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/scalarBlockLduMatrix.H b/src/blockMatrix/BlockLduMatrix/scalarBlockLduMatrix.H new file mode 100644 index 000000000..1f08154ef --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/scalarBlockLduMatrix.H @@ -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::sumDiag(); + +template<> +void BlockLduMatrix::negSumDiag(); + +template<> +void BlockLduMatrix::check() const; + +template<> +void BlockLduMatrix::relax +( + const scalarField& x, + scalarField& b, + const scalar alpha +); + +template<> +void BlockLduMatrix::operator*=(const scalarField& sf); + +template<> +void BlockLduMatrix::AmulCore +( + scalarField& mul, + const scalarField& x +) const; + +template<> +void BlockLduMatrix::TmulCore +( + scalarField& mul, + const scalarField& x +) const; + +template<> +void BlockLduMatrix::segregateB +( + scalarField& mul, + const scalarField& x +) const; + +template<> +tmp BlockLduMatrix::H(const scalarField& x) const; + +template<> +tmp BlockLduMatrix::faceH(const scalarField& x) const; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/sphericalTensorBlockLduMatrix.C b/src/blockMatrix/BlockLduMatrix/sphericalTensorBlockLduMatrix.C new file mode 100644 index 000000000..cced53bec --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/sphericalTensorBlockLduMatrix.C @@ -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::sumDiag() +{ + // Decoupled version + this->decoupledSumDiag(); +} + + +template<> +void Foam::BlockLduMatrix::negSumDiag() +{ + // Decoupled version + this->decoupledNegSumDiag(); +} + + +template<> +void Foam::BlockLduMatrix::check() const +{ + // Decoupled version + this->decoupledCheck(); +} + + +template<> +void Foam::BlockLduMatrix::relax +( + const sphericalTensorField& x, + sphericalTensorField& b, + const scalar alpha +) +{ + // Decoupled version + this->decoupledRelax(x, b, alpha); +} + + +template<> +void Foam::BlockLduMatrix::operator*= +( + const scalarField& sf +) +{ + // Decoupled version + this->decoupledMultEqOp(sf); +} + + +template<> +void Foam::BlockLduMatrix::AmulCore +( + sphericalTensorField& Ax, + const sphericalTensorField& x +) const +{ + decoupledAmulCore(Ax, x); +} + + +template<> +void Foam::BlockLduMatrix::TmulCore +( + sphericalTensorField& Tx, + const sphericalTensorField& x +) const +{ + // Decoupled version + decoupledTmulCore(Tx, x); +} + + +template<> +void Foam::BlockLduMatrix::segregateB +( + sphericalTensorField&, + const sphericalTensorField& +) const +{ + FatalErrorIn + ( + "void Foam::BlockLduMatrix::segregateB\n" + "(\n" + " sphericalTensorField&,\n" + " const sphericalTensorField&\n" + ") const" + ) << "Requested decoupling of sphericalTensor matrix - never coupled" + << abort(FatalError); +} + + +template<> +Foam::tmp +Foam::BlockLduMatrix::H +( + const sphericalTensorField& x +) const +{ + // Decoupled version + return decoupledH(x); +} + + +template<> +Foam::tmp +Foam::BlockLduMatrix::faceH +( + const sphericalTensorField& x +) const +{ + // Decoupled version + return decoupledFaceH(x); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/sphericalTensorBlockLduMatrix.H b/src/blockMatrix/BlockLduMatrix/sphericalTensorBlockLduMatrix.H new file mode 100644 index 000000000..1bde229dd --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/sphericalTensorBlockLduMatrix.H @@ -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::sumDiag(); + +template<> +void BlockLduMatrix::negSumDiag(); + +template<> +void BlockLduMatrix::check() const; + +template<> +void BlockLduMatrix::relax +( + const sphericalTensorField& x, + sphericalTensorField& b, + const scalar alpha +); + +template<> +void BlockLduMatrix::operator*=(const scalarField& sf); + +template<> +void BlockLduMatrix::AmulCore +( + sphericalTensorField& mul, + const sphericalTensorField& x +) const; + +template<> +void BlockLduMatrix::TmulCore +( + sphericalTensorField& mul, + const sphericalTensorField& x +) const; + +template<> +void BlockLduMatrix::segregateB +( + sphericalTensorField& mul, + const sphericalTensorField& x +) const; + + +template<> +tmp +BlockLduMatrix::H(const sphericalTensorField& x) const; + +template<> +tmp +BlockLduMatrix::faceH(const sphericalTensorField& x) const; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/symmTensorBlockLduMatrix.C b/src/blockMatrix/BlockLduMatrix/symmTensorBlockLduMatrix.C new file mode 100644 index 000000000..1b3ebc3ff --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/symmTensorBlockLduMatrix.C @@ -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::sumDiag() +{ + // Decoupled version + this->decoupledSumDiag(); +} + + +template<> +void Foam::BlockLduMatrix::negSumDiag() +{ + // Decoupled version + this->decoupledNegSumDiag(); +} + + +template<> +void Foam::BlockLduMatrix::check() const +{ + // Decoupled version + this->decoupledCheck(); +} + + +template<> +void Foam::BlockLduMatrix::relax +( + const symmTensorField& x, + symmTensorField& b, + const scalar alpha +) +{ + // Decoupled version + this->decoupledRelax(x, b, alpha); +} + + +template<> +void Foam::BlockLduMatrix::operator*=(const scalarField& sf) +{ + // Decoupled version + this->decoupledMultEqOp(sf); +} + + +template<> +void Foam::BlockLduMatrix::AmulCore +( + symmTensorField& Ax, + const symmTensorField& x +) const +{ + decoupledAmulCore(Ax, x); +} + + +template<> +void Foam::BlockLduMatrix::TmulCore +( + symmTensorField& Tx, + const symmTensorField& x +) const +{ + // Decoupled version + decoupledTmulCore(Tx, x); +} + + +template<> +void Foam::BlockLduMatrix::segregateB +( + symmTensorField&, + const symmTensorField& +) const +{ + FatalErrorIn + ( + "void Foam::BlockLduMatrix::segregateB\n" + "(\n" + " symmTensorField&,\n" + " const symmTensorField&\n" + ") const" + ) << "Requested decoupling of symmTensor matrix - never coupled" + << abort(FatalError); +} + + +template<> +Foam::tmp +Foam::BlockLduMatrix::H(const symmTensorField& x) const +{ + // Decoupled version + return decoupledH(x); +} + + +template<> +Foam::tmp +Foam::BlockLduMatrix::faceH(const symmTensorField& x) const +{ + // Decoupled version + return decoupledFaceH(x); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/symmTensorBlockLduMatrix.H b/src/blockMatrix/BlockLduMatrix/symmTensorBlockLduMatrix.H new file mode 100644 index 000000000..cce4c7591 --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/symmTensorBlockLduMatrix.H @@ -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::sumDiag(); + +template<> +void BlockLduMatrix::negSumDiag(); + +template<> +void BlockLduMatrix::check() const; + +template<> +void BlockLduMatrix::relax +( + const symmTensorField& x, + symmTensorField& b, + const scalar alpha +); + +template<> +void BlockLduMatrix::operator*=(const scalarField& sf); + +template<> +void BlockLduMatrix::AmulCore +( + symmTensorField& mul, + const symmTensorField& x +) const; + +template<> +void BlockLduMatrix::TmulCore +( + symmTensorField& mul, + const symmTensorField& x +) const; + +template<> +void BlockLduMatrix::segregateB +( + symmTensorField& mul, + const symmTensorField& x +) const; + + +template<> +tmp +BlockLduMatrix::H(const symmTensorField& x) const; + +template<> +tmp +BlockLduMatrix::faceH(const symmTensorField& x) const; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/tensorBlockLduMatrix.C b/src/blockMatrix/BlockLduMatrix/tensorBlockLduMatrix.C new file mode 100644 index 000000000..68afb123d --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/tensorBlockLduMatrix.C @@ -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::sumDiag() +{ + // Decoupled version + this->decoupledSumDiag(); +} + + +template<> +void Foam::BlockLduMatrix::negSumDiag() +{ + // Decoupled version + this->decoupledNegSumDiag(); +} + + +template<> +void Foam::BlockLduMatrix::check() const +{ + // Decoupled version + this->decoupledCheck(); +} + + +template<> +void Foam::BlockLduMatrix::relax +( + const tensorField& x, + tensorField& b, + const scalar alpha +) +{ + // Decoupled version + this->decoupledRelax(x, b, alpha); +} + + +template<> +void Foam::BlockLduMatrix::operator*=(const scalarField& sf) +{ + // Decoupled version + this->decoupledMultEqOp(sf); +} + + +template<> +void Foam::BlockLduMatrix::AmulCore +( + tensorField& Ax, + const tensorField& x +) const +{ + decoupledAmulCore(Ax, x); +} + + +template<> +void Foam::BlockLduMatrix::TmulCore +( + tensorField& Tx, + const tensorField& x +) const +{ + // Decoupled version + decoupledTmulCore(Tx, x); +} + + +template<> +void Foam::BlockLduMatrix::segregateB +( + tensorField&, + const tensorField& +) const +{ + FatalErrorIn + ( + "void Foam::BlockLduMatrix::segregateB\n" + "(\n" + " tensorField&,\n" + " const tensorField&\n" + ") const" + ) << "Requested decoupling of tensor matrix - never coupled" + << abort(FatalError); +} + + +template<> +Foam::tmp +Foam::BlockLduMatrix::H(const tensorField& x) const +{ + // Decoupled version + return decoupledH(x); +} + + +template<> +Foam::tmp +Foam::BlockLduMatrix::faceH(const tensorField& x) const +{ + // Decoupled version + return decoupledFaceH(x); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduMatrix/tensorBlockLduMatrix.H b/src/blockMatrix/BlockLduMatrix/tensorBlockLduMatrix.H new file mode 100644 index 000000000..1b5a855e4 --- /dev/null +++ b/src/blockMatrix/BlockLduMatrix/tensorBlockLduMatrix.H @@ -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::sumDiag(); + +template<> +void BlockLduMatrix::negSumDiag(); + +template<> +void BlockLduMatrix::check() const; + +template<> +void BlockLduMatrix::relax +( + const tensorField& x, + tensorField& b, + const scalar alpha +); + +template<> +void BlockLduMatrix::operator*=(const scalarField& sf); + +template<> +void BlockLduMatrix::AmulCore +( + tensorField& mul, + const tensorField& x +) const; + +template<> +void BlockLduMatrix::TmulCore +( + tensorField& mul, + const tensorField& x +) const; + +template<> +void BlockLduMatrix::segregateB +( + tensorField& mul, + const tensorField& x +) const; + + +template<> +tmp BlockLduMatrix::H(const tensorField& x) const; + +template<> +tmp BlockLduMatrix::faceH(const tensorField& x) const; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/BlockCholeskyPrecon.C b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/BlockCholeskyPrecon.C new file mode 100644 index 000000000..4df40e088 --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/BlockCholeskyPrecon.C @@ -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 +void Foam::BlockCholeskyPrecon::calcPreconDiag() +{ + typedef CoeffField 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 +template +void Foam::BlockCholeskyPrecon::diagMultiply +( + Field& dDiag, + const Field& 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::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 +template +void Foam::BlockCholeskyPrecon::diagMultiplyCoeffT +( + Field& dDiag, + const Field& 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::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 +template +void Foam::BlockCholeskyPrecon::diagMultiply +( + Field& dDiag, + const Field& lower, + const Field& 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::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 +template +void Foam::BlockCholeskyPrecon::ILUmultiply +( + Field& x, + const Field& dDiag, + const Field& upper, + const Field& b +) const +{ + // Create multiplication function object + typename BlockCoeff::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 +template +void Foam::BlockCholeskyPrecon::ILUmultiplyCoeffT +( + Field& x, + const Field& dDiag, + const Field& upper, + const Field& b +) const +{ + // Create multiplication function object + typename BlockCoeff::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 +template +void Foam::BlockCholeskyPrecon::ILUmultiply +( + Field& x, + const Field& dDiag, + const Field& lower, + const Field& upper, + const Field& b +) const +{ + // Create multiplication function object + typename BlockCoeff::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 +template +void Foam::BlockCholeskyPrecon::ILUmultiplyTranspose +( + Field& x, + const Field& dDiag, + const Field& lower, + const Field& upper, + const Field& b +) const +{ + // Create multiplication function object + typename BlockCoeff::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 +Foam::BlockCholeskyPrecon::BlockCholeskyPrecon +( + const BlockLduMatrix& matrix +) +: + BlockLduPrecon(matrix), + preconDiag_(matrix.diag()) +{ + calcPreconDiag(); +} + + +template +Foam::BlockCholeskyPrecon::BlockCholeskyPrecon +( + const BlockLduMatrix& matrix, + const dictionary& dict +) +: + BlockLduPrecon(matrix), + preconDiag_(matrix.diag()) +{ + calcPreconDiag(); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +template +Foam::BlockCholeskyPrecon::~BlockCholeskyPrecon() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +void Foam::BlockCholeskyPrecon::precondition +( + Field& x, + const Field& b +) const +{ + typedef CoeffField 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 +void Foam::BlockCholeskyPrecon::preconditionT +( + Field& xT, + const Field& bT +) const +{ + typedef CoeffField 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 + ); + } + } + } +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/BlockCholeskyPrecon.H b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/BlockCholeskyPrecon.H new file mode 100644 index 000000000..079266017 --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/BlockCholeskyPrecon.H @@ -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 BlockCholeskyPrecon +: + public BlockLduPrecon +{ + // Private Data + + //- Preconditioned diagonal + mutable CoeffField 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 + void diagMultiply + ( + Field& dDiag, + const Field& upper + ); + + //- Diagonal multiplication with transpose upper square coeff + // for the symmetric matrix + template + void diagMultiplyCoeffT + ( + Field& dDiag, + const Field& upper + ); + + //- Diagonal multiplication, asymmetric matrix + template + void diagMultiply + ( + Field& dDiag, + const Field& lower, + const Field& upper + ); + + //- ILU multiplication, symmetric matrix + template + void ILUmultiply + ( + Field& x, + const Field& dDiag, + const Field& upper, + const Field& b + ) const; + + //- ILU multiplication, with transpose upper square coeff + // for a symmetric matrix + template + void ILUmultiplyCoeffT + ( + Field& x, + const Field& dDiag, + const Field& upper, + const Field& b + ) const; + + //- ILU multiplication, asymmetric matrix + template + void ILUmultiply + ( + Field& x, + const Field& dDiag, + const Field& lower, + const Field& upper, + const Field& b + ) const; + + //- ILU multiplication transposed asymmetric matrix + template + void ILUmultiplyTranspose + ( + Field& x, + const Field& dDiag, + const Field& lower, + const Field& upper, + const Field& b + ) const; + + + // Decoupled operations, used in template specialisation + + //- Precondition the diagonal, decoupled version + void calcDecoupledPreconDiag(); + + //- Execute preconditioning, decoupled version + void decoupledPrecondition + ( + Field& x, + const Field& b + ) const; + + //- Execute preconditioning with matrix transpose, decoupled version + void decoupledPreconditionT + ( + Field& xT, + const Field& bT + ) const; + + +public: + + //- Runtime type information + TypeName("Cholesky"); + + + // Constructors + + //- Construct from matrix for smoother use + BlockCholeskyPrecon + ( + const BlockLduMatrix& matrix + ); + + //- Construct from components + BlockCholeskyPrecon + ( + const BlockLduMatrix& matrix, + const dictionary& dict + ); + + + // Destructor + + virtual ~BlockCholeskyPrecon(); + + + // Member Functions + + //- Execute preconditioning + virtual void precondition + ( + Field& x, + const Field& b + ) const; + + //- Execute preconditioning with matrix transpose + virtual void preconditionT + ( + Field& xT, + const Field& bT + ) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "BlockCholeskyPrecon.C" +# include "BlockCholeskyPreconDecoupled.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/BlockCholeskyPreconDecoupled.C b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/BlockCholeskyPreconDecoupled.C new file mode 100644 index 000000000..39bb27f04 --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/BlockCholeskyPreconDecoupled.C @@ -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 +void Foam::BlockCholeskyPrecon::calcDecoupledPreconDiag() +{ + typedef CoeffField 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 +void Foam::BlockCholeskyPrecon::decoupledPrecondition +( + Field& x, + const Field& b +) const +{ + typedef CoeffField 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 +void Foam::BlockCholeskyPrecon::decoupledPreconditionT +( + Field& xT, + const Field& bT +) const +{ + typedef CoeffField 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 + ); + } + } + } +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/blockCholeskyPrecons.C b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/blockCholeskyPrecons.C new file mode 100644 index 000000000..244c35d81 --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/blockCholeskyPrecons.C @@ -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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/blockCholeskyPrecons.H b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/blockCholeskyPrecons.H new file mode 100644 index 000000000..fcd96ed86 --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/blockCholeskyPrecons.H @@ -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 blockCholeskyPreconScalar; +typedef BlockCholeskyPrecon blockCholeskyPreconVector; +typedef BlockCholeskyPrecon blockCholeskyPreconTensor; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/scalarBlockCholeskyPrecon.C b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/scalarBlockCholeskyPrecon.C new file mode 100644 index 000000000..8bc9130d5 --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/scalarBlockCholeskyPrecon.C @@ -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::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::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::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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/scalarBlockCholeskyPrecon.H b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/scalarBlockCholeskyPrecon.H new file mode 100644 index 000000000..0f222202a --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/scalarBlockCholeskyPrecon.H @@ -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::calcPreconDiag(); + +template<> +void Foam::BlockCholeskyPrecon::precondition +( + scalarField& x, + const scalarField& b +) const; + + +template<> +void Foam::BlockCholeskyPrecon::preconditionT +( + scalarField& xT, + const scalarField& bT +) const; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/tensorBlockCholeskyPrecon.C b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/tensorBlockCholeskyPrecon.C new file mode 100644 index 000000000..bb2f2a63b --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/tensorBlockCholeskyPrecon.C @@ -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::calcPreconDiag() +{ + // Decoupled version + calcDecoupledPreconDiag(); +} + + +template<> +void Foam::BlockCholeskyPrecon::precondition +( + tensorField& x, + const tensorField& b +) const +{ + // Decoupled version + decoupledPrecondition(x, b); +} + + +template<> +void Foam::BlockCholeskyPrecon::preconditionT +( + tensorField& xT, + const tensorField& bT +) const +{ + // Decoupled version + decoupledPreconditionT(xT, bT); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/tensorBlockCholeskyPrecon.H b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/tensorBlockCholeskyPrecon.H new file mode 100644 index 000000000..a5f0ca4ec --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockCholeskyPrecon/tensorBlockCholeskyPrecon.H @@ -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::calcPreconDiag(); + +template<> +void Foam::BlockCholeskyPrecon::precondition +( + tensorField& x, + const tensorField& b +) const; + + +template<> +void Foam::BlockCholeskyPrecon::preconditionT +( + tensorField& xT, + const tensorField& bT +) const; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/BlockDiagonalPrecon.C b/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/BlockDiagonalPrecon.C new file mode 100644 index 000000000..e675d7f58 --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/BlockDiagonalPrecon.C @@ -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 +void Foam::BlockDiagonalPrecon::precondition +( + Field& x, + const Field& b +) const +{ + typedef CoeffField 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:solve:\n" + "(\n" + " Field& x,\n" + " const Field& b\n" + ") const" + ) << "Problem with coefficient type morphing." + << abort(FatalError); + } +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/BlockDiagonalPrecon.H b/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/BlockDiagonalPrecon.H new file mode 100644 index 000000000..12e2941a0 --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/BlockDiagonalPrecon.H @@ -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 BlockDiagonalPrecon +: + public BlockLduPrecon +{ + // 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& matrix, + const dictionary& dict + ) + : + BlockLduPrecon(matrix) + {} + + + // Destructor + + virtual ~BlockDiagonalPrecon() + {} + + + // Member Functions + + //- Execute preconditioning + virtual void precondition + ( + Field& x, + const Field& b + ) const; + + //- Execute preconditioning on a transposed matrix + virtual void preconditionT + ( + Field& xT, + const Field& bT + ) const + { + return precondition(xT, bT); + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "BlockDiagonalPrecon.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/blockDiagonalPrecons.C b/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/blockDiagonalPrecons.C new file mode 100644 index 000000000..f3ff5321b --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/blockDiagonalPrecons.C @@ -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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/blockDiagonalPrecons.H b/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/blockDiagonalPrecons.H new file mode 100644 index 000000000..378a28f03 --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/blockDiagonalPrecons.H @@ -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 blockDiagonalPreconScalar; +typedef BlockDiagonalPrecon blockDiagonalPreconVector; +typedef BlockDiagonalPrecon blockDiagonalPreconTensor; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/scalarBlockDiagonalPrecon.C b/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/scalarBlockDiagonalPrecon.C new file mode 100644 index 000000000..52a183d3a --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/scalarBlockDiagonalPrecon.C @@ -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::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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/scalarBlockDiagonalPrecon.H b/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/scalarBlockDiagonalPrecon.H new file mode 100644 index 000000000..2774a614a --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/scalarBlockDiagonalPrecon.H @@ -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::precondition +( + scalarField& x, + const scalarField& b +) const; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/tensorBlockDiagonalPrecon.C b/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/tensorBlockDiagonalPrecon.C new file mode 100644 index 000000000..50aab32fe --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/tensorBlockDiagonalPrecon.C @@ -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::precondition +( + tensorField& x, + const tensorField& b +) const +{ + typedef CoeffField 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::solve\n" + "(\n" + " tensorField& x,\n" + " const tensorField& b\n" + ") const" + ) << "Problem with coefficient type morphing." + << abort(FatalError); + } +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/tensorBlockDiagonalPrecon.H b/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/tensorBlockDiagonalPrecon.H new file mode 100644 index 000000000..5a7939687 --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockDiagonalPrecon/tensorBlockDiagonalPrecon.H @@ -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::precondition +( + tensorField& x, + const tensorField& b +) const; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/BlockGaussSeidelPrecon.C b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/BlockGaussSeidelPrecon.C new file mode 100644 index 000000000..f3b09f639 --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/BlockGaussSeidelPrecon.C @@ -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 +template +void Foam::BlockGaussSeidelPrecon::BlockSweep +( + Field& x, + const Field& dD, + const Field& upper, + const Field& 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::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 +template +void Foam::BlockGaussSeidelPrecon::BlockSweep +( + Field& x, + const Field& dD, + const Field& lower, + const Field& upper, + const Field& 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::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 +void Foam::BlockGaussSeidelPrecon::precondition +( + Field& x, + const Field& b +) const +{ + typedef CoeffField 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::precondition\n" + "(\n" + " Field& x,\n" + " const Field& 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::precondition\n" + "(\n" + " Field& x,\n" + " const Field& b\n" + ") const" + ) << "Problem with coefficient type morphing." + << abort(FatalError); + } + } + else + { + FatalErrorIn + ( + "void BlockGaussSeidelPrecon::precondition\n" + "(\n" + " Field& x,\n" + " const Field& b\n" + ") const" + ) << "cannot solve incomplete matrix, no diagonal" + << abort(FatalError); + } +} + + +template +void Foam::BlockGaussSeidelPrecon::preconditionT +( + Field& xT, + const Field& bT +) const +{ + typedef CoeffField 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::preconditionT\n" + "(\n" + " Field& xT,\n" + " const Field& bT\n" + ") const" + ) << "Problem with coefficient type morphing." + << abort(FatalError); + } + } + else + { + FatalErrorIn + ( + "void BlockGaussSeidelPrecon::preconditionT\n" + "(\n" + " Field& xT,\n" + " const Field& bT\n" + ") const" + ) << "cannot solve incomplete matrix, no diagonal" + << abort(FatalError); + } +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/BlockGaussSeidelPrecon.H b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/BlockGaussSeidelPrecon.H new file mode 100644 index 000000000..251773c8f --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/BlockGaussSeidelPrecon.H @@ -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 BlockGaussSeidelPrecon +: + public BlockLduPrecon +{ + // Private Data + + //- Temporary space for solution intermediate + mutable Field 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 + void BlockSweep + ( + Field& x, + const Field& dD, + const Field& upper, + const Field& b + ) const; + + // Block Gauss-Seidel sweep, asymmetric matrix + template + void BlockSweep + ( + Field& x, + const Field& dD, + const Field& lower, + const Field& upper, + const Field& b + ) const; + + + // Decoupled operations, used in template specialisation + + //- Execute preconditioning, decoupled version + void decoupledPrecondition + ( + Field& x, + const Field& b + ) const; + + //- Execute preconditioning with matrix transpose, decoupled version + void decoupledPreconditionT + ( + Field& xT, + const Field& bT + ) const; + + +public: + + //- Runtime type information + TypeName("GaussSeidel"); + + + // Constructors + + //- Construct from matrix for smoother use + BlockGaussSeidelPrecon + ( + const BlockLduMatrix& matrix + ) + : + BlockLduPrecon(matrix), + bPrime_(matrix.lduAddr().size()), + nSweeps_(1) + {} + + //- Construct from components + BlockGaussSeidelPrecon + ( + const BlockLduMatrix& matrix, + const dictionary& dict + ) + : + BlockLduPrecon(matrix), + bPrime_(matrix.lduAddr().size()), + nSweeps_(readLabel(dict.lookup("nSweeps"))) + {} + + + // Destructor + + virtual ~BlockGaussSeidelPrecon() + {} + + + // Member Functions + + //- Execute preconditioning + virtual void precondition + ( + Field& x, + const Field& b + ) const; + + //- Execute preconditioning with matrix transpose + virtual void preconditionT + ( + Field& xT, + const Field& bT + ) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "BlockGaussSeidelPrecon.C" +# include "BlockGaussSeidelPreconDecoupled.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/BlockGaussSeidelPreconDecoupled.C b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/BlockGaussSeidelPreconDecoupled.C new file mode 100644 index 000000000..b5d105502 --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/BlockGaussSeidelPreconDecoupled.C @@ -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 +void Foam::BlockGaussSeidelPrecon::decoupledPrecondition +( + Field& x, + const Field& b +) const +{ + typedef DecoupledCoeffField 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::precondition\n" + "(\n" + " Field& x,\n" + " const Field& b\n" + ") const" + ) << "Problem with coefficient type morphing." + << abort(FatalError); + } + } + else + { + FatalErrorIn + ( + "void BlockGaussSeidelPrecon::precondition\n" + "(\n" + " Field& x,\n" + " const Field& b\n" + ") const" + ) << "cannot solve incomplete matrix, no diagonal" + << abort(FatalError); + } +} + + +template +void Foam::BlockGaussSeidelPrecon::decoupledPreconditionT +( + Field& xT, + const Field& bT +) const +{ + typedef DecoupledCoeffField 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::preconditionT\n" + "(\n" + " Field& xT,\n" + " const Field& bT\n" + ") const" + ) << "Problem with coefficient type morphing." + << abort(FatalError); + } + } + else + { + FatalErrorIn + ( + "void BlockGaussSeidelPrecon::preconditionT\n" + "(\n" + " Field& xT,\n" + " const Field& bT\n" + ") const" + ) << "cannot solve incomplete matrix, no diagonal" + << abort(FatalError); + } +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/blockGaussSeidelPrecons.C b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/blockGaussSeidelPrecons.C new file mode 100644 index 000000000..b204ddcbb --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/blockGaussSeidelPrecons.C @@ -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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/blockGaussSeidelPrecons.H b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/blockGaussSeidelPrecons.H new file mode 100644 index 000000000..89b2f8bdc --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/blockGaussSeidelPrecons.H @@ -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 blockGaussSeidelPreconScalar; +typedef BlockGaussSeidelPrecon blockGaussSeidelPreconVector; +typedef BlockGaussSeidelPrecon blockGaussSeidelPreconTensor; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/scalarBlockGaussSeidelPrecon.C b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/scalarBlockGaussSeidelPrecon.C new file mode 100644 index 000000000..2ff9d048f --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/scalarBlockGaussSeidelPrecon.C @@ -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::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::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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/scalarBlockGaussSeidelPrecon.H b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/scalarBlockGaussSeidelPrecon.H new file mode 100644 index 000000000..d36654b87 --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/scalarBlockGaussSeidelPrecon.H @@ -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::precondition +( + scalarField& x, + const scalarField& b +) const; + + +template<> +void Foam::BlockGaussSeidelPrecon::preconditionT +( + scalarField& xT, + const scalarField& bT +) const; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/tensorBlockGaussSeidelPrecon.C b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/tensorBlockGaussSeidelPrecon.C new file mode 100644 index 000000000..075f62210 --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/tensorBlockGaussSeidelPrecon.C @@ -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::precondition +( + tensorField& x, + const tensorField& b +) const +{ + // Decoupled version + decoupledPrecondition(x, b); +} + + +template<> +void Foam::BlockGaussSeidelPrecon::preconditionT +( + tensorField& xT, + const tensorField& bT +) const +{ + // Decoupled version + decoupledPreconditionT(xT, bT); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/tensorBlockGaussSeidelPrecon.H b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/tensorBlockGaussSeidelPrecon.H new file mode 100644 index 000000000..84465864e --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockGaussSeidelPrecon/tensorBlockGaussSeidelPrecon.H @@ -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::precondition +( + tensorField& x, + const tensorField& b +) const; + + +template<> +void Foam::BlockGaussSeidelPrecon::preconditionT +( + tensorField& xT, + const tensorField& bT +) const; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockLduPrecon/BlockLduPrecon.C b/src/blockMatrix/BlockLduPrecons/BlockLduPrecon/BlockLduPrecon.C new file mode 100644 index 000000000..96d351bef --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockLduPrecon/BlockLduPrecon.C @@ -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 BlockNoPrecon; + +// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * // + +template +Foam::autoPtr > Foam::BlockLduPrecon::New +( + const BlockLduMatrix& 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 > + ( + new BlockNoPrecon + ( + matrix, + dict + ) + ); + } + else + { + typename dictionaryConstructorTable::iterator constructorIter = + dictionaryConstructorTablePtr_->find(preconName); + + if (constructorIter == dictionaryConstructorTablePtr_->end()) + { + FatalIOErrorIn + ( + "autoPtr BlockLduPrecon::New\n" + "(\n" + " const BlockLduMatrix& matrix,\n" + " const dictionary& dict\n" + ")", + dict + ) << "Unknown matrix preconditioner " << preconName + << endl << endl + << "Valid matrix preconditioners are :" << endl + << dictionaryConstructorTablePtr_->toc() + << exit(FatalIOError); + } + + return autoPtr > + ( + constructorIter() + ( + matrix, + dict + ) + ); + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +Foam::word Foam::BlockLduPrecon::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; +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockLduPrecon/BlockLduPrecon.H b/src/blockMatrix/BlockLduPrecons/BlockLduPrecon/BlockLduPrecon.H new file mode 100644 index 000000000..9ba8f0aee --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockLduPrecon/BlockLduPrecon.H @@ -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 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& 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& matrix, + const dictionary& dict + ), + ( + matrix, + dict + ) + ); + + + // Constructors + + //- Construct from matrix + BlockLduPrecon(const BlockLduMatrix& matrix) + : + matrix_(matrix) + {} + + + // Selectors + + //- Select given matrix and dictionary + static autoPtr > New + ( + const BlockLduMatrix& matrix, + const dictionary& dict + ); + + + // Destructor + + virtual ~BlockLduPrecon() + {} + + + // Member Functions + + //- Execute preconditioning + virtual void precondition + ( + Field& x, + const Field& b + ) const = 0; + + //- Execute preconditioning on a transposed matrix + virtual void preconditionT + ( + Field& xT, + const Field& bT + ) const + { + notImplemented + ( + type() +"::preconditionT" + "(Field& xT, const Field& 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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockLduPrecon/blockLduPrecons.C b/src/blockMatrix/BlockLduPrecons/BlockLduPrecon/blockLduPrecons.C new file mode 100644 index 000000000..a16d2149a --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockLduPrecon/blockLduPrecons.C @@ -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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockLduPrecon/blockLduPrecons.H b/src/blockMatrix/BlockLduPrecons/BlockLduPrecon/blockLduPrecons.H new file mode 100644 index 000000000..47de4e804 --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockLduPrecon/blockLduPrecons.H @@ -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 blockScalarPrecon; +typedef BlockLduPrecon blockVectorPrecon; +typedef BlockLduPrecon blockTensorPrecon; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockNoPrecon/BlockNoPrecon.H b/src/blockMatrix/BlockLduPrecons/BlockNoPrecon/BlockNoPrecon.H new file mode 100644 index 000000000..519028140 --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockNoPrecon/BlockNoPrecon.H @@ -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 BlockLduPrecon; + +/*---------------------------------------------------------------------------*\ + Class BlockNoPrecon Declaration +\*---------------------------------------------------------------------------*/ + +template +class BlockNoPrecon +: + public BlockLduPrecon +{ + // 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& matrix, + const dictionary& dict + ) + : + BlockLduPrecon(matrix) + {} + + + // Destructor + + virtual ~BlockNoPrecon() + {} + + + // Member Functions + + //- Execute preconditioning + virtual void precondition + ( + Field& x, + const Field& b + ) const + { + x = b; + } + + //- Execute preconditioning + virtual void preconditionT + ( + Field& xT, + const Field& bT + ) const + { + precondition(xT, bT); + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockNoPrecon/blockNoPrecons.C b/src/blockMatrix/BlockLduPrecons/BlockNoPrecon/blockNoPrecons.C new file mode 100644 index 000000000..24e833d47 --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockNoPrecon/blockNoPrecons.C @@ -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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduPrecons/BlockNoPrecon/blockNoPrecons.H b/src/blockMatrix/BlockLduPrecons/BlockNoPrecon/blockNoPrecons.H new file mode 100644 index 000000000..20b84fd4b --- /dev/null +++ b/src/blockMatrix/BlockLduPrecons/BlockNoPrecon/blockNoPrecons.H @@ -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 blockNoPreconScalar; +typedef BlockNoPrecon blockNoPreconVector; +typedef BlockNoPrecon blockNoPreconTensor; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSmoothers/BlockGaussSeidelSmoother/BlockGaussSeidelSmoother.H b/src/blockMatrix/BlockLduSmoothers/BlockGaussSeidelSmoother/BlockGaussSeidelSmoother.H new file mode 100644 index 000000000..c6172f2d4 --- /dev/null +++ b/src/blockMatrix/BlockLduSmoothers/BlockGaussSeidelSmoother/BlockGaussSeidelSmoother.H @@ -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 BlockGaussSeidelSmoother +: + public BlockLduSmoother +{ + // Private Data + + //- Gauss-Seidel preconditioner + BlockGaussSeidelPrecon 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& matrix, + const dictionary& dict + ) + : + BlockLduSmoother(matrix), + gs_(matrix) + {} + + + // Destructor + + virtual ~BlockGaussSeidelSmoother() + {} + + + // Member Functions + + //- Execute smoothing + virtual void smooth + ( + Field& x, + const Field& b, + const label nSweeps + ) const + { + for (label sweep = 0; sweep < nSweeps; sweep++) + { + gs_.precondition(x, b); + } + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSmoothers/BlockGaussSeidelSmoother/blockGaussSeidelSmoothers.C b/src/blockMatrix/BlockLduSmoothers/BlockGaussSeidelSmoother/blockGaussSeidelSmoothers.C new file mode 100644 index 000000000..ef16df3ae --- /dev/null +++ b/src/blockMatrix/BlockLduSmoothers/BlockGaussSeidelSmoother/blockGaussSeidelSmoothers.C @@ -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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSmoothers/BlockGaussSeidelSmoother/blockGaussSeidelSmoothers.H b/src/blockMatrix/BlockLduSmoothers/BlockGaussSeidelSmoother/blockGaussSeidelSmoothers.H new file mode 100644 index 000000000..2ae494116 --- /dev/null +++ b/src/blockMatrix/BlockLduSmoothers/BlockGaussSeidelSmoother/blockGaussSeidelSmoothers.H @@ -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 blockGaussSeidelSmootherScalar; +typedef BlockGaussSeidelSmoother blockGaussSeidelSmootherVector; +typedef BlockGaussSeidelSmoother blockGaussSeidelSmootherTensor; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSmoothers/BlockILUSmoother/BlockILUSmoother.H b/src/blockMatrix/BlockLduSmoothers/BlockILUSmoother/BlockILUSmoother.H new file mode 100644 index 000000000..7bda49efb --- /dev/null +++ b/src/blockMatrix/BlockLduSmoothers/BlockILUSmoother/BlockILUSmoother.H @@ -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 BlockILUSmoother +: + public BlockLduSmoother +{ + // Private Data + + //- Cholesky preconditioner + BlockCholeskyPrecon precon_; + + //- Correction array + mutable Field xCorr_; + + //- Residual array + mutable Field 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& matrix, + const dictionary& dict + ) + : + BlockLduSmoother(matrix), + precon_(matrix), + xCorr_(matrix.lduAddr().size()), + residual_(matrix.lduAddr().size()) + {} + + + // Destructor + + virtual ~BlockILUSmoother() + {} + + + // Member Functions + + //- Execute smoothing + virtual void smooth + ( + Field& x, + const Field& 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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSmoothers/BlockILUSmoother/blockILUSmoothers.C b/src/blockMatrix/BlockLduSmoothers/BlockILUSmoother/blockILUSmoothers.C new file mode 100644 index 000000000..3b986c407 --- /dev/null +++ b/src/blockMatrix/BlockLduSmoothers/BlockILUSmoother/blockILUSmoothers.C @@ -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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSmoothers/BlockILUSmoother/blockILUSmoothers.H b/src/blockMatrix/BlockLduSmoothers/BlockILUSmoother/blockILUSmoothers.H new file mode 100644 index 000000000..827fc502d --- /dev/null +++ b/src/blockMatrix/BlockLduSmoothers/BlockILUSmoother/blockILUSmoothers.H @@ -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 blockILUSmootherScalar; +typedef BlockILUSmoother blockILUSmootherVector; +typedef BlockILUSmoother blockILUSmootherTensor; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSmoothers/BlockLduSmoother/BlockLduSmoother.C b/src/blockMatrix/BlockLduSmoothers/BlockLduSmoother/BlockLduSmoother.C new file mode 100644 index 000000000..26a54736d --- /dev/null +++ b/src/blockMatrix/BlockLduSmoothers/BlockLduSmoother/BlockLduSmoother.C @@ -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 BlockNoSmoother; + +// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * // + +template +Foam::autoPtr > Foam::BlockLduSmoother::New +( + const BlockLduMatrix& 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::New\n" + "(\n" + " const BlockLduMatrix& matrix,\n" + " const dictionary& dict\n" + ")", + dict + ) << "Unknown matrix smoother " << smootherName + << endl << endl + << "Valid matrix smoothers are :" << endl + << dictionaryConstructorTablePtr_->toc() + << exit(FatalIOError); + } + + return autoPtr > + ( + constructorIter() + ( + matrix, + dict + ) + ); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +Foam::word Foam::BlockLduSmoother::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; +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSmoothers/BlockLduSmoother/BlockLduSmoother.H b/src/blockMatrix/BlockLduSmoothers/BlockLduSmoother/BlockLduSmoother.H new file mode 100644 index 000000000..35f9ef0c7 --- /dev/null +++ b/src/blockMatrix/BlockLduSmoothers/BlockLduSmoother/BlockLduSmoother.H @@ -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 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& 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& matrix, + const dictionary& dict + ), + ( + matrix, + dict + ) + ); + + + // Constructors + + //- Construct from matrix + BlockLduSmoother(const BlockLduMatrix& matrix) + : + matrix_(matrix) + {} + + + // Selectors + + //- Select given matrix and dictionary + static autoPtr > New + ( + const BlockLduMatrix& matrix, + const dictionary& dict + ); + + + // Destructor + + virtual ~BlockLduSmoother() + {} + + + // Member Functions + + //- Execute smoothing + virtual void smooth + ( + Field& x, + const Field& 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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSmoothers/BlockLduSmoother/blockLduSmoothers.C b/src/blockMatrix/BlockLduSmoothers/BlockLduSmoother/blockLduSmoothers.C new file mode 100644 index 000000000..8e7cfec9a --- /dev/null +++ b/src/blockMatrix/BlockLduSmoothers/BlockLduSmoother/blockLduSmoothers.C @@ -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 + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSmoothers/BlockLduSmoother/blockLduSmoothers.H b/src/blockMatrix/BlockLduSmoothers/BlockLduSmoother/blockLduSmoothers.H new file mode 100644 index 000000000..377184e50 --- /dev/null +++ b/src/blockMatrix/BlockLduSmoothers/BlockLduSmoother/blockLduSmoothers.H @@ -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 blockScalarSmoother; +typedef BlockLduSmoother blockVectorSmoother; +typedef BlockLduSmoother blockTensorSmoother; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockBiCGStab/BlockBiCGStabSolver.C b/src/blockMatrix/BlockLduSolvers/BlockBiCGStab/BlockBiCGStabSolver.C new file mode 100644 index 000000000..c3acf2ac3 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockBiCGStab/BlockBiCGStabSolver.C @@ -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 +Foam::BlockBiCGStabSolver::BlockBiCGStabSolver +( + const word& fieldName, + const BlockLduMatrix& matrix, + const dictionary& dict +) +: + BlockIterativeSolver + ( + fieldName, + matrix, + dict + ), + preconPtr_ + ( + BlockLduPrecon::New + ( + matrix, + this->dict().subDict("preconditioner") + ) + ) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +typename Foam::BlockSolverPerformance +Foam::BlockBiCGStabSolver::solve +( + Field& x, + const Field& b +) +{ + // Create local references to avoid the spread this-> ugliness + const BlockLduMatrix& matrix = this->matrix_; + + // Prepare solver performance + BlockSolverPerformance solverPerf + ( + typeName, + this->fieldName() + ); + + scalar norm = this->normFactor(x, b); + + // Multiplication helper + typename BlockCoeff::multiply mult; + + Field p(x.size()); + + // Calculate initial residual + matrix.Amul(p, x); + Field 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::zero; + Field ph(x.size(), pTraits::zero); + Field v(x.size(), pTraits::zero); + Field s(x.size(), pTraits::zero); + Field sh(x.size(), pTraits::zero); + Field t(x.size(), pTraits::zero); + + // Calculate transpose residual + Field 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; +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockBiCGStab/BlockBiCGStabSolver.H b/src/blockMatrix/BlockLduSolvers/BlockBiCGStab/BlockBiCGStabSolver.H new file mode 100644 index 000000000..8d676de8c --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockBiCGStab/BlockBiCGStabSolver.H @@ -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 + BlockBiCGStabSolver + +Description + Preconditioned Bi-Conjugate Gradient stabilised solver. + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + BlockBiCGStabSolver.C + +\*---------------------------------------------------------------------------*/ + +#ifndef BlockBiCGStabSolver_H +#define BlockBiCGStabSolver_H + +#include "blockLduSolvers.H" +#include "BlockIterativeSolver.H" +#include "blockLduPrecons.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class BlockBiCGStabSolver Declaration +\*---------------------------------------------------------------------------*/ + +template +class BlockBiCGStabSolver +: + public BlockIterativeSolver +{ + // Private data + + //- Preconditioner + autoPtr > preconPtr_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + BlockBiCGStabSolver(const BlockBiCGStabSolver&); + + //- Disallow default bitwise assignment + void operator=(const BlockBiCGStabSolver&); + + +public: + + //- Runtime type information + TypeName("BiCGStab"); + + + // Constructors + + //- Construct from matrix components and solver data stream + BlockBiCGStabSolver + ( + const word& fieldName, + const BlockLduMatrix& matrix, + const dictionary& dict + ); + + + // Destructor + + virtual ~BlockBiCGStabSolver() + {} + + + // Member Functions + + //- Solve the matrix with this solver + virtual BlockSolverPerformance solve + ( + Field& x, + const Field& b + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "BlockBiCGStabSolver.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockBiCGStab/blockBiCGStabSolvers.C b/src/blockMatrix/BlockLduSolvers/BlockBiCGStab/blockBiCGStabSolvers.C new file mode 100644 index 000000000..c197ab6cf --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockBiCGStab/blockBiCGStabSolvers.C @@ -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 + Preconditioned Bi-Conjugate Gradient stabilised solver. + +\*---------------------------------------------------------------------------*/ + +#include "blockLduMatrices.H" +#include "blockBiCGStabSolvers.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +makeBlockSolvers(blockBiCGStabSolver); + +// BiCGStab as a symmetric solver: use where the diagonal coefficient block +// is assymetric. HJ, 24/Jan/2008 +addSymSolverToBlockMatrix(blockBiCGStabSolver); + +addAsymSolverToBlockMatrix(blockBiCGStabSolver); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockBiCGStab/blockBiCGStabSolvers.H b/src/blockMatrix/BlockLduSolvers/BlockBiCGStab/blockBiCGStabSolvers.H new file mode 100644 index 000000000..cb9e12418 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockBiCGStab/blockBiCGStabSolvers.H @@ -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 + BlockBiCGStabSolver + +Description + Typedefs Preconditioned Bi-Conjugate Gradient stabilised solver. + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + blockICBiCGStabSolvers.C + +\*---------------------------------------------------------------------------*/ + +#ifndef blockBiCGStabSolvers_H +#define blockBiCGStabSolvers_H + +#include "BlockBiCGStabSolver.H" +#include "fieldTypes.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +typedef BlockBiCGStabSolver blockBiCGStabSolverScalar; +typedef BlockBiCGStabSolver blockBiCGStabSolverVector; +typedef BlockBiCGStabSolver blockBiCGStabSolverTensor; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockCG/BlockCGSolver.C b/src/blockMatrix/BlockLduSolvers/BlockCG/BlockCGSolver.C new file mode 100644 index 000000000..90f3015be --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockCG/BlockCGSolver.C @@ -0,0 +1,154 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 Conjugate Gradient solver. + +\*---------------------------------------------------------------------------*/ + +#include "BlockCGSolver.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +//- Construct from matrix and solver data stream +template +Foam::BlockCGSolver::BlockCGSolver +( + const word& fieldName, + const BlockLduMatrix& matrix, + const dictionary& dict +) +: + BlockIterativeSolver + ( + fieldName, + matrix, + dict + ), + preconPtr_ + ( + BlockLduPrecon::New + ( + matrix, + this->dict().subDict("preconditioner") + ) + ) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +typename Foam::BlockSolverPerformance Foam::BlockCGSolver::solve +( + Field& x, + const Field& b +) +{ + // Create local references to avoid the spread this-> ugliness + const BlockLduMatrix& matrix = this->matrix_; + + // Prepare solver performance + BlockSolverPerformance solverPerf + ( + typeName, + this->fieldName() + ); + + scalar norm = this->normFactor(x, b); + + // Multiplication helper + typename BlockCoeff::multiply mult; + + Field wA(x.size()); + + // Calculate initial residual + matrix.Amul(wA, x); + Field rA(b - wA); + + solverPerf.initialResidual() = gSum(cmptMag(rA))/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, beta, wApA; + + Field pA(x.size()); + + do + { + rhoOld = rho; + + // Execute preconditioning + preconPtr_->precondition(wA, rA); + + // Update search directions + rho = gSumProd(wA, rA); + + beta = rho/rhoOld; + + forAll (pA, i) + { + pA[i] = wA[i] + beta*pA[i]; + } + + // Update preconditioner residual + matrix.Amul(wA, pA); + + wApA = gSumProd(wA, pA); + + // Check for singularity + if (solverPerf.checkSingularity(mag(wApA)/norm)) + { + break; + } + + // Update solution and raw residual + alpha = rho/wApA; + + forAll (x, i) + { + x[i] += alpha*pA[i]; + } + + forAll (rA, i) + { + rA[i] -= alpha*wA[i]; + } + + solverPerf.finalResidual() = gSum(cmptMag(rA))/norm; + solverPerf.nIterations()++; + } while (!stop(solverPerf)); + } + + return solverPerf; +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockCG/BlockCGSolver.H b/src/blockMatrix/BlockLduSolvers/BlockCG/BlockCGSolver.H new file mode 100644 index 000000000..a18d0a012 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockCG/BlockCGSolver.H @@ -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 + BlockCGSolver + +Description + Preconditioned Conjugate Gradient solver. + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + BlockCGSolver.C + +\*---------------------------------------------------------------------------*/ + +#ifndef BlockCGSolver_H +#define BlockCGSolver_H + +#include "blockLduSolvers.H" +#include "BlockIterativeSolver.H" +#include "blockLduPrecons.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class BlockCGSolver Declaration +\*---------------------------------------------------------------------------*/ + +template +class BlockCGSolver +: + public BlockIterativeSolver +{ + // Private data + + //- Preconditioner + autoPtr > preconPtr_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + BlockCGSolver(const BlockCGSolver&); + + //- Disallow default bitwise assignment + void operator=(const BlockCGSolver&); + + +public: + + //- Runtime type information + TypeName("CG"); + + + // Constructors + + //- Construct from matrix components and solver data stream + BlockCGSolver + ( + const word& fieldName, + const BlockLduMatrix& matrix, + const dictionary& dict + ); + + + // Destructor + + virtual ~BlockCGSolver() + {} + + + // Member Functions + + //- Solve the matrix with this solver + virtual BlockSolverPerformance solve + ( + Field& x, + const Field& b + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "BlockCGSolver.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockCG/blockCGSolvers.C b/src/blockMatrix/BlockLduSolvers/BlockCG/blockCGSolvers.C new file mode 100644 index 000000000..b783656b6 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockCG/blockCGSolvers.C @@ -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 + Preconditioned Conjugate Gradient solver. + +\*---------------------------------------------------------------------------*/ + +#include "blockLduMatrices.H" +#include "blockCGSolvers.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +makeBlockSolvers(blockCGSolver); + +addSymSolverToBlockMatrix(blockCGSolver); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockCG/blockCGSolvers.H b/src/blockMatrix/BlockLduSolvers/BlockCG/blockCGSolvers.H new file mode 100644 index 000000000..9be29cd94 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockCG/blockCGSolvers.H @@ -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 + BlockCGSolver + +Description + Typedefs for Preconditioned Conjugate Gradient solver. + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + blockCGSolvers.C + +\*---------------------------------------------------------------------------*/ + +#ifndef blockCGSolvers_H +#define blockCGSolvers_H + +#include "BlockCGSolver.H" +#include "fieldTypes.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +typedef BlockCGSolver blockCGSolverScalar; +typedef BlockCGSolver blockCGSolverVector; +typedef BlockCGSolver blockCGSolverTensor; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockDiagonal/BlockDiagonalSolver.C b/src/blockMatrix/BlockLduSolvers/BlockDiagonal/BlockDiagonalSolver.C new file mode 100644 index 000000000..663f62175 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockDiagonal/BlockDiagonalSolver.C @@ -0,0 +1,75 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + Solver for diagonal matrices. + +\*---------------------------------------------------------------------------*/ + +#include "BlockDiagonalSolver.H" +#include "BlockSolverPerformance.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +//- Construct from matrix +template +Foam::BlockDiagonalSolver::BlockDiagonalSolver +( + const word& fieldName, + const BlockLduMatrix& matrix, + const dictionary& dict +) +: + BlockLduSolver(fieldName, matrix, dict) +{} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +template +Foam::BlockSolverPerformance +Foam::BlockDiagonalSolver::solve +( + Field& x, + const Field& b +) +{ + CoeffField dD = inv(this->matrix_.diag()); + + multiply(x, b, dD); + + return BlockSolverPerformance + ( + this->typeName, + this->fieldName(), + pTraits::zero, + pTraits::zero, + 0, + true, + false + ); +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockDiagonal/BlockDiagonalSolver.H b/src/blockMatrix/BlockLduSolvers/BlockDiagonal/BlockDiagonalSolver.H new file mode 100644 index 000000000..64d2951c9 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockDiagonal/BlockDiagonalSolver.H @@ -0,0 +1,119 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + BlockDiagonalSolver + +Description + Solver for diagonal matrices + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + BlockDiagonalSolver.C + +\*---------------------------------------------------------------------------*/ + +#ifndef BlockDiagonalSolver_H +#define BlockDiagonalSolver_H + +#include "Field.H" +#include "typeInfo.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +template +class BlockLduMatrix; + +template +class BlockLduSolver; + +template +class BlockSolverPerformance; + +/*---------------------------------------------------------------------------*\ + Class BlockDiagonalSolver Declaration +\*---------------------------------------------------------------------------*/ + +template +class BlockDiagonalSolver +: + public BlockLduSolver +{ + // Private Member Functions + + //- Disallow default bitwise copy construct + BlockDiagonalSolver(const BlockDiagonalSolver&); + + //- Disallow default bitwise assignment + void operator=(const BlockDiagonalSolver&); + + +public: + + //- Runtime type information + TypeName("Diagonal"); + + + // Constructors + + //- Construct from matrix + BlockDiagonalSolver + ( + const word& fieldName, + const BlockLduMatrix& matrix, + const dictionary& dict + ); + + + // Member Functions + + //- Solve the matrix with this solver + virtual BlockSolverPerformance solve + ( + Field& x, + const Field& b + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "BlockDiagonalSolver.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockDiagonal/blockDiagonalSolvers.C b/src/blockMatrix/BlockLduSolvers/BlockDiagonal/blockDiagonalSolvers.C new file mode 100644 index 000000000..75bfe5deb --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockDiagonal/blockDiagonalSolvers.C @@ -0,0 +1,48 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + +\*---------------------------------------------------------------------------*/ + +#include "blockLduSolvers.H" +#include "blockDiagonalSolvers.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +defineNamedTemplateTypeNameAndDebug(blockDiagonalSolverScalar, 0); +defineNamedTemplateTypeNameAndDebug(blockDiagonalSolverVector, 0); +defineNamedTemplateTypeNameAndDebug(blockDiagonalSolverTensor, 0); + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockDiagonal/blockDiagonalSolvers.H b/src/blockMatrix/BlockLduSolvers/BlockDiagonal/blockDiagonalSolvers.H new file mode 100644 index 000000000..30d7c541c --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockDiagonal/blockDiagonalSolvers.H @@ -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 + BlockDiagonalSolvers + +Description + Typedefs for diagonal-only matrices + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + blockDiagonalSolvers.C + +\*---------------------------------------------------------------------------*/ + +#ifndef blockDiagonalSolvers_H +#define blockDiagonalSolvers_H + +#include "BlockDiagonalSolver.H" +#include "fieldTypes.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +typedef BlockDiagonalSolver blockDiagonalSolverScalar; +typedef BlockDiagonalSolver blockDiagonalSolverVector; +typedef BlockDiagonalSolver blockDiagonalSolverTensor; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockGMRES/BlockGMRESSolver.C b/src/blockMatrix/BlockLduSolvers/BlockGMRES/BlockGMRESSolver.C new file mode 100644 index 000000000..b91e1e56a --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockGMRES/BlockGMRESSolver.C @@ -0,0 +1,250 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 Generalised Minimal Residual solver with + run-time selectable preconditioning + +\*---------------------------------------------------------------------------*/ + +#include "BlockGMRESSolver.H" +#include "FieldField.H" +#include "scalarMatrices.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template +void Foam::BlockGMRESSolver::givensRotation +( + const scalar& h, + const scalar& beta, + scalar& c, + scalar& s +) const +{ + if (beta == 0) + { + c = 1; + s = 0; + } + else if (mag(beta) > mag(h)) + { + scalar tau = -h/beta; + s = 1.0/Foam::sqrt(1.0 + sqr(tau)); + c = s*tau; + } + else + { + scalar tau = -beta/h; + c = 1.0/Foam::sqrt(1.0 + sqr(tau)); + s = c*tau; + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +//- Construct from matrix and solver data stream +template +Foam::BlockGMRESSolver::BlockGMRESSolver +( + const word& fieldName, + const BlockLduMatrix& matrix, + const dictionary& dict +) +: + BlockIterativeSolver + ( + fieldName, + matrix, + dict + ), + preconPtr_ + ( + BlockLduPrecon::New + ( + matrix, + this->dict().subDict("preconditioner") + ) + ), + nDirs_(readLabel(this->dict().lookup("nDirections"))) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +typename Foam::BlockSolverPerformance +Foam::BlockGMRESSolver::solve +( + Field& x, + const Field& b +) +{ + // Create local references to avoid the spread this-> ugliness + const BlockLduMatrix& matrix = this->matrix_; + + // Prepare solver performance + BlockSolverPerformance solverPerf + ( + typeName, + this->fieldName() + ); + + scalar norm = this->normFactor(x, b); + + // Multiplication helper + typename BlockCoeff::multiply mult; + + Field wA(x.size()); + + // Calculate initial residual + matrix.Amul(wA, x); + Field rA(b - wA); + + solverPerf.initialResidual() = gSum(cmptMag(rA))/norm; + solverPerf.finalResidual() = solverPerf.initialResidual(); + + // Check convergence, solve if not converged + + if (!solverPerf.checkConvergence(this->tolerance(), this->relTolerance())) + { + // Create the Hesenberg matrix + scalarSquareMatrix H(nDirs_, 0); + + // Create y and b for Hessenberg matrix + scalarField yh(nDirs_, 0); + scalarField bh(nDirs_ + 1, 0); + + // Givens rotation vectors + scalarField c(nDirs_, 0); + scalarField s(nDirs_, 0); + + // Allocate Krylov space vectors + FieldField V(nDirs_ + 1); + + forAll (V, i) + { + V.set(i, new Field(x.size(), pTraits::zero)); + } + + do + { + // Execute preconditioning + preconPtr_->precondition(wA, rA); + + // Calculate beta and scale first vector + scalar beta = Foam::sqrt(gSumProd(wA, wA)); + + // Set initial rhs and bh[0] = beta + bh = 0; + bh[0] = beta; + + for (label i = 0; i < nDirs_; i++) + { + // Set search direction + V[i] = wA; + V[i] /= beta; + + // Arnoldi's method + matrix.Amul(rA, V[i]); + + // Execute preconditioning + preconPtr_->precondition(wA, rA); + + for (label j = 0; j <= i; j++) + { + beta = gSumProd(wA, V[j]); + + H[j][i] = beta; + + forAll (wA, wI) + { + wA[wI] -= beta*V[j][wI]; + } + } + + beta = Foam::sqrt(gSumProd(wA, wA)); + + // Apply previous Givens rotations to new column of H. + for (label j = 0; j < i; j++) + { + const scalar Hji = H[j][i]; + H[j][i] = c[j]*Hji - s[j]*H[j + 1][i]; + H[j + 1][i] = s[j]*Hji + c[j]*H[j + 1][i]; + } + + // Apply Givens rotation to current row. + givensRotation(H[i][i], beta, c[i], s[i]); + + const scalar bhi = bh[i]; + bh[i] = c[i]*bhi - s[i]*bh[i + 1]; + bh[i + 1] = s[i]*bhi + c[i]*bh[i + 1]; + H[i][i] = c[i]*H[i][i] - s[i]*beta; + } + + // Back substitute to solve Hy = b + for (label i = nDirs_ - 1; i >= 0; i--) + { + scalar sum = bh[i]; + + for (label j = i + 1; j < nDirs_; j++) + { + sum -= H[i][j]*yh[j]; + } + + yh[i] = sum/H[i][i]; + } + + // Update solution + + for (label i = 0; i < nDirs_; i++) + { + const Field& Vi = V[i]; + const scalar& yi = yh[i]; + + forAll (x, xI) + { + x[xI] += yi*Vi[xI]; + } + } + + // Re-calculate the residual + matrix.Amul(wA, x); + + forAll (rA, raI) + { + rA[raI] = b[raI] - wA[raI]; + } + + solverPerf.finalResidual() = gSum(cmptMag(rA))/norm; + solverPerf.nIterations()++; + } while (!stop(solverPerf)); + } + + return solverPerf; +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockGMRES/BlockGMRESSolver.H b/src/blockMatrix/BlockLduSolvers/BlockGMRES/BlockGMRESSolver.H new file mode 100644 index 000000000..2844cbffa --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockGMRES/BlockGMRESSolver.H @@ -0,0 +1,136 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + BlockGMRESSolver + +Description + Preconditioned Generalised Minimal Residual solver with + run-time selectable preconditioning + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + BlockGMRESSolver.C + +\*---------------------------------------------------------------------------*/ + +#ifndef BlockGMRESSolver_H +#define BlockGMRESSolver_H + +#include "blockLduSolvers.H" +#include "BlockIterativeSolver.H" +#include "blockLduPrecons.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class BlockGMRESSolver Declaration +\*---------------------------------------------------------------------------*/ + +template +class BlockGMRESSolver +: + public BlockIterativeSolver +{ + // Private data + + //- Preconditioner + autoPtr > preconPtr_; + + //- Krylov space dimension + label nDirs_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + BlockGMRESSolver(const BlockGMRESSolver&); + + //- Disallow default bitwise assignment + void operator=(const BlockGMRESSolver&); + + //- Givens rotation + void givensRotation + ( + const scalar& H, + const scalar& beta, + scalar& c, + scalar& s + ) const; + + +public: + + //- Runtime type information + TypeName("GMRES"); + + + // Constructors + + //- Construct from matrix components and solver data stream + BlockGMRESSolver + ( + const word& fieldName, + const BlockLduMatrix& matrix, + const dictionary& dict + ); + + + // Destructor + + virtual ~BlockGMRESSolver() + {} + + + // Member Functions + + //- Solve the matrix with this solver + virtual BlockSolverPerformance solve + ( + Field& x, + const Field& b + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "BlockGMRESSolver.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockGMRES/blockGMRESSolvers.C b/src/blockMatrix/BlockLduSolvers/BlockGMRES/blockGMRESSolvers.C new file mode 100644 index 000000000..fb2f72782 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockGMRES/blockGMRESSolvers.C @@ -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 + Preconditioned Generalised Minimal Residual solver with + run-time selectable preconditioning + +\*---------------------------------------------------------------------------*/ + +#include "blockLduMatrices.H" +#include "blockGMRESSolvers.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +makeBlockSolvers(blockGMRESsolver); + +addSymSolverToBlockMatrix(blockGMRESsolver); +addAsymSolverToBlockMatrix(blockGMRESsolver); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockGMRES/blockGMRESSolvers.H b/src/blockMatrix/BlockLduSolvers/BlockGMRES/blockGMRESSolvers.H new file mode 100644 index 000000000..867b32535 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockGMRES/blockGMRESSolvers.H @@ -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 + BlockGMRESSolver + +Description + Preconditioned Generalised Minimal Residual solver with + run-time selectable preconditioning + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + blockGMRESSolvers.C + +\*---------------------------------------------------------------------------*/ + +#ifndef blockGMRESSolvers_H +#define blockGMRESSolvers_H + +#include "BlockGMRESSolver.H" +#include "fieldTypes.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +typedef BlockGMRESSolver blockGMRESsolverScalar; +typedef BlockGMRESSolver blockGMRESsolverVector; +typedef BlockGMRESSolver blockGMRESsolverTensor; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockGaussSeidel/BlockGaussSeidelSolver.C b/src/blockMatrix/BlockLduSolvers/BlockGaussSeidel/BlockGaussSeidelSolver.C new file mode 100644 index 000000000..0819dc9d3 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockGaussSeidel/BlockGaussSeidelSolver.C @@ -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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Description + Gauss-Seidel solver for symmetric and asymmetric matrices. In + order to improve efficiency, the residual is evaluated after every + nSweeps sweeps. + +\*---------------------------------------------------------------------------*/ + +#include "BlockGaussSeidelSolver.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +// Construct from matrix and solver data stream +template +Foam::BlockGaussSeidelSolver::BlockGaussSeidelSolver +( + const word& fieldName, + const BlockLduMatrix& matrix, + const dictionary& dict +) +: + BlockIterativeSolver + ( + fieldName, + matrix, + dict + ), + gs_(matrix), + nResSweeps_(readLabel(this->dict().lookup("nResSweeps"))) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +typename Foam::BlockSolverPerformance +Foam::BlockGaussSeidelSolver::solve +( + Field& x, + const Field& b +) +{ + // Create local references to avoid the spread this-> ugliness + const BlockLduMatrix& matrix = this->matrix_; + + // Prepare solver performance + BlockSolverPerformance solverPerf + ( + typeName, + this->fieldName() + ); + + scalar norm = this->normFactor(x, b); + + Field wA(x.size()); + + // Calculate residual. Note: sign of residual swapped for efficiency + matrix.Amul(wA, x); + wA -= b; + + solverPerf.initialResidual() = gSum(cmptMag(wA))/norm; + solverPerf.finalResidual() = solverPerf.initialResidual(); + + // Check convergence, solve if not converged + + if (!solverPerf.checkConvergence(this->tolerance(), this->relTolerance())) + { + // Iteration loop + + do + { + for (label i = 0; i < nResSweeps_; i++) + { + gs_.precondition(x, b); + + solverPerf.nIterations()++; + } + + // Re-calculate residual. Note: sign of residual swapped + // for efficiency + matrix.Amul(wA, x); + wA -= b; + + solverPerf.finalResidual() = gSum(cmptMag(wA))/norm; + solverPerf.nIterations()++; + } while (!stop(solverPerf)); + } + + return solverPerf; +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockGaussSeidel/BlockGaussSeidelSolver.H b/src/blockMatrix/BlockLduSolvers/BlockGaussSeidel/BlockGaussSeidelSolver.H new file mode 100644 index 000000000..fde70d389 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockGaussSeidel/BlockGaussSeidelSolver.H @@ -0,0 +1,130 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + BlockGaussSeidelSolver + +Description + Gauss-Seidel solver + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + BlockGaussSeidelSolver.C + +\*---------------------------------------------------------------------------*/ + +#ifndef BlockGaussSeidelSolver_H +#define BlockGaussSeidelSolver_H + +#include "blockLduSolvers.H" +#include "BlockIterativeSolver.H" +#include "BlockSolverPerformance.H" +#include "blockGaussSeidelPrecons.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class BlockGaussSeidelSolver Declaration +\*---------------------------------------------------------------------------*/ + +template +class BlockGaussSeidelSolver +: + public BlockIterativeSolver +{ +private: + + // Private data + + //- Gauss-Seidel preconditioner + BlockGaussSeidelPrecon gs_; + + //- Number of sweeps before evaluating residual + label nResSweeps_; + + + + // Private Member Functions + + //- Disallow default bitwise copy construct + BlockGaussSeidelSolver(const BlockGaussSeidelSolver&); + + //- Disallow default bitwise assignment + void operator=(const BlockGaussSeidelSolver&); + + +public: + + //- Runtime type information + TypeName("GaussSeidel"); + + + // Constructors + + //- Construct from matrix components and solver data stream + BlockGaussSeidelSolver + ( + const word& fieldName, + const BlockLduMatrix& matrix, + const dictionary& dict + ); + + + // Destructor + + virtual ~BlockGaussSeidelSolver() + {} + + + // Member Functions + + //- Solve the matrix with this solver + virtual BlockSolverPerformance solve + ( + Field& x, + const Field& b + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "BlockGaussSeidelSolver.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockGaussSeidel/blockGaussSeidelSolvers.C b/src/blockMatrix/BlockLduSolvers/BlockGaussSeidel/blockGaussSeidelSolvers.C new file mode 100644 index 000000000..95cea89c9 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockGaussSeidel/blockGaussSeidelSolvers.C @@ -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 "blockLduMatrices.H" +#include "blockGaussSeidelSolvers.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +makeBlockSolvers(blockGaussSeidelSolver); + +addSymSolverToBlockMatrix(blockGaussSeidelSolver); + +addAsymSolverToBlockMatrix(blockGaussSeidelSolver); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockGaussSeidel/blockGaussSeidelSolvers.H b/src/blockMatrix/BlockLduSolvers/BlockGaussSeidel/blockGaussSeidelSolvers.H new file mode 100644 index 000000000..2270913b2 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockGaussSeidel/blockGaussSeidelSolvers.H @@ -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 + BlockGaussSeidelSolvers + +Description + Typedefs for BlockGaussSeidelSolvers + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + blockGaussSeidelSolvers.C + +\*---------------------------------------------------------------------------*/ + +#ifndef blockGaussSeidelSolvers_H +#define blockGaussSeidelSolvers_H + +#include "BlockGaussSeidelSolver.H" +#include "fieldTypes.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +typedef BlockGaussSeidelSolver blockGaussSeidelSolverScalar; +typedef BlockGaussSeidelSolver blockGaussSeidelSolverVector; +typedef BlockGaussSeidelSolver blockGaussSeidelSolverTensor; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockIterativeSolver/BlockIterativeSolver.C b/src/blockMatrix/BlockLduSolvers/BlockIterativeSolver/BlockIterativeSolver.C new file mode 100644 index 000000000..d4e8dd0e4 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockIterativeSolver/BlockIterativeSolver.C @@ -0,0 +1,118 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + Virtual base class for block iterative solvers + +\*---------------------------------------------------------------------------*/ + +#include "BlockIterativeSolver.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +//- Construct from matrix and solver data stream +template +Foam::BlockIterativeSolver::BlockIterativeSolver +( + const word& fieldName, + const BlockLduMatrix& matrix, + const dictionary& dict +) +: + BlockLduSolver(fieldName, matrix, dict), + tolerance_(readScalar(this->dict().lookup("tolerance"))), + relTolerance_(readScalar(this->dict().lookup("relTol"))), + minIter_(readLabel(this->dict().lookup("minIter"))), + maxIter_(readLabel(this->dict().lookup("maxIter"))) +{} + + +// * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * * // + +template +Foam::scalar Foam::BlockIterativeSolver::normFactor +( + Field& x, + const Field& b +) const +{ + const BlockLduMatrix& matrix = this->matrix_; + + // Calculate the normalisation factor + const label nRows = x.size(); + + Field pA(nRows); + Field wA(nRows); + + // Calculate reference value of x + Type xRef = gAverage(x); + + // Calculate A.x + matrix.Amul(wA, x); + + // Calculate A.xRef, temporarily using pA for storage + matrix.Amul + ( + pA, + Field(nRows, xRef) + ); + + scalar normFactor = gSum(mag(wA - pA) + mag(b - pA)) + this->small_; + + if (BlockLduMatrix::debug >= 2) + { + Info<< "Iterative solver normalisation factor = " << normFactor << endl; + } + + return normFactor; +} + + +template +bool Foam::BlockIterativeSolver::stop +( + BlockSolverPerformance& solverPerf +) const +{ + if (solverPerf.nIterations() < minIter_) + { + return false; + } + + if + ( + solverPerf.nIterations() >= maxIter_ + || solverPerf.checkConvergence(tolerance_, relTolerance_) + ) + { + return true; + } + else + { + return false; + } +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockIterativeSolver/BlockIterativeSolver.H b/src/blockMatrix/BlockLduSolvers/BlockIterativeSolver/BlockIterativeSolver.H new file mode 100644 index 000000000..c34033c48 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockIterativeSolver/BlockIterativeSolver.H @@ -0,0 +1,169 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + BlockIterativeSolver + +Description + Virtual base class for a block iterative solvers + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + BlockIterativeSolver.C + +\*---------------------------------------------------------------------------*/ + +#ifndef BlockIterativeSolver_H +#define BlockIterativeSolver_H + +#include "BlockLduSolver.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class BlockIterativeSolver Declaration +\*---------------------------------------------------------------------------*/ + +template +class BlockIterativeSolver +: + public BlockLduSolver +{ + // Private data + + //- Solver tolerance + scalar tolerance_; + + //- Relative tolerance + scalar relTolerance_; + + //- Minimum number of iterations + // (forced irrespective of convergence) + label minIter_; + + //- Maximum number of iterations + label maxIter_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + BlockIterativeSolver(const BlockIterativeSolver&); + + //- Disallow default bitwise assignment + void operator=(const BlockIterativeSolver&); + + +protected: + + // Protected Member Functions + + //- Return normalisation factor + scalar normFactor + ( + Field& x, + const Field& b + ) const; + + //- Is the stop criterion reached + bool stop(BlockSolverPerformance& solverPerf) const; + + +public: + + // Constructors + + //- Construct from matrix components and solver data stream + BlockIterativeSolver + ( + const word& fieldName, + const BlockLduMatrix& matrix, + const dictionary& dict + ); + + + // Destructor + + virtual ~BlockIterativeSolver() + {} + + + // Member Functions + + // Access + + //- Return tolerance + scalar tolerance() const + { + return tolerance_; + } + + //- Return relative tolerance + scalar relTolerance() const + { + return relTolerance_; + } + + //- Return minimum number of iterations + label minIter() const + { + return minIter_; + } + + //- Return maximum number of iterations + label maxIter() const + { + return maxIter_; + } + + + // Solve + + //- Solve the matrix with this solver + virtual BlockSolverPerformance solve + ( + Field& x, + const Field& b + ) = 0; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +#ifdef NoRepository +# include "BlockIterativeSolver.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockLduSolver/BlockLduSolver.C b/src/blockMatrix/BlockLduSolvers/BlockLduSolver/BlockLduSolver.C new file mode 100644 index 000000000..bd3ec1be7 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockLduSolver/BlockLduSolver.C @@ -0,0 +1,233 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + +\*---------------------------------------------------------------------------*/ + +#include "blockLduMatrices.H" +#include "BlockDiagonalSolver.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +template +const Foam::scalar Foam::BlockLduSolver::great_ = 1.0e+20; + +template +const Foam::scalar Foam::BlockLduSolver::small_ = 1.0e-20; + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template +template +void Foam::BlockLduSolver::readControl +( + const dictionary& dict, + T& control, + const word& controlName +) +{ + if (dict.found(controlName)) + { + dict.lookup(controlName) >> control; + } + else + { + FatalIOErrorIn + ( + "void BlockLduSolver::readControl::readControl\n" + "(\n" + " const dictionary& dict,\n" + " T& control,\n" + " const word& controlName\n" + ")", + dict + ) << "Cannot read control " << controlName + << abort(FatalIOError); + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +Foam::BlockLduSolver::BlockLduSolver +( + const word& fieldName, + const BlockLduMatrix& matrix +) +: + fieldName_(fieldName), + dict_(), + matrix_(matrix) +{} + + +template +Foam::BlockLduSolver::BlockLduSolver +( + const word& fieldName, + const BlockLduMatrix& matrix, + const dictionary& dict +) +: + fieldName_(fieldName), + dict_(dict), + matrix_(matrix) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +Foam::autoPtr > +Foam::BlockLduSolver::New +( + const word& fieldName, + BlockLduMatrix& matrix, + const dictionary& dict +) +{ + word solverName(dict.lookup("solver")); + + if (matrix.diagonal()) + { + return autoPtr > + ( + new BlockDiagonalSolver(fieldName, matrix, dict) + ); + } + else if (matrix.symmetric()) + { + if (!symMatrixConstructorTablePtr_) + { + FatalErrorIn + ( + "BlockLduSolver::New\n" + "(\n" + " const word& fieldName,\n" + " BlockLduMatrix& matrix,\n" + " const dictionary& dict\n" + ")" + ) << "Initialization problem." << endl; + } + + typename symMatrixConstructorTable::iterator constructorIter = + symMatrixConstructorTablePtr_->find(solverName); + + if (constructorIter == symMatrixConstructorTablePtr_->end()) + { + FatalIOErrorIn + ( + "BlockLduSolver::New\n" + "(\n" + " const word& fieldName,\n" + " BlockLduMatrix& matrix,\n" + " const dictionary& dict\n" + ")", + dict + ) << "Unknown symmetric matrix solver " << solverName + << endl << endl + << "Valid symmetric matrix solvers are :" << endl + << symMatrixConstructorTablePtr_->toc() + << exit(FatalIOError); + } + + return autoPtr > + ( + constructorIter() + ( + fieldName, + matrix, + dict + ) + ); + } + else if (matrix.asymmetric()) + { + if (!asymMatrixConstructorTablePtr_) + { + FatalErrorIn + ( + "BlockLduSolver::New\n" + "(\n" + " const word& fieldName,\n" + " BlockLduMatrix& matrix,\n" + " const dictionary& dict\n" + ")" + ) << "Initialization problem." << endl; + } + + typename asymMatrixConstructorTable::iterator constructorIter = + asymMatrixConstructorTablePtr_->find(solverName); + + if (constructorIter == asymMatrixConstructorTablePtr_->end()) + { + FatalIOErrorIn + ( + "BlockLduSolver::New\n" + "(\n" + " const word& fieldName,\n" + " BlockLduMatrix& matrix,\n" + " const dictionary& dict\n" + ")", + dict + ) << "Unknown asymmetric matrix solver " << solverName + << endl << endl + << "Valid asymmetric matrix solvers are :" << endl + << asymMatrixConstructorTablePtr_->toc() + << exit(FatalIOError); + } + + return autoPtr > + ( + constructorIter() + ( + fieldName, + matrix, + dict + ) + ); + } + else + { + FatalErrorIn + ( + "BlockLduSolver::New\n" + "(\n" + " const word& fieldName,\n" + " BlockLduMatrix& matrix,\n" + " const dictionary& dict\n" + ")" + ) << "cannot solve incomplete matrix, " + "no diagonal or off-diagonal coefficient" + << exit(FatalError); + + return autoPtr >(NULL); + } +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockLduSolver/BlockLduSolver.H b/src/blockMatrix/BlockLduSolvers/BlockLduSolver/BlockLduSolver.H new file mode 100644 index 000000000..62aa78379 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockLduSolver/BlockLduSolver.H @@ -0,0 +1,252 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + BlockLduSolver + +Description + Linear equation solver for BlockLduMatrix. + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + BlockLduSolver.C + +\*---------------------------------------------------------------------------*/ + +#ifndef BlockLduSolver_H +#define BlockLduSolver_H + +#include "blockLduMatrices.H" +#include "runTimeSelectionTables.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * Forward declaration of template friend fuctions * * * * * * * // + +template +class BlockSolverPerformance; + +/*---------------------------------------------------------------------------*\ + Class BlockLduSolver Declaration +\*---------------------------------------------------------------------------*/ + +template +class BlockLduSolver +{ + // Private data + + //- Name of field being solved for + word fieldName_; + + //- Control data dictionary + dictionary dict_; + + +protected: + + // Protected data types + + typedef Field TypeField; + + + // Protected data + + //- Matrix + const BlockLduMatrix& matrix_; + + + // Protected Member Functions + + //- Return dictionary + const dictionary& dict() const + { + return dict_; + } + + //- Read a control parameter from the dictionary + template + void readControl + ( + const dictionary& dict, + T& control, + const word& controlName + ); + + +public: + + //- Runtime type information + TypeName("BlockLduSolver"); + + + // Static data + + //- Large value for the use in solvers + static const scalar great_; + + //- Small value for the use in solvers + static const scalar small_; + + + // Declare run-time constructor selection tables + + declareRunTimeSelectionTable + ( + autoPtr, + BlockLduSolver, + symMatrix, + ( + const word& fieldName, + BlockLduMatrix& matrix, + const dictionary& dict + ), + ( + fieldName, + matrix, + dict + ) + ); + + declareRunTimeSelectionTable + ( + autoPtr, + BlockLduSolver, + asymMatrix, + ( + const word& fieldName, + BlockLduMatrix& matrix, + const dictionary& dict + ), + ( + fieldName, + matrix, + dict + ) + ); + + + + // Constructors + + //- Construct from field name and matrix + BlockLduSolver + ( + const word& fieldName, + const BlockLduMatrix& matrix + ); + + //- Construct from dictionary + BlockLduSolver + ( + const word& fieldName, + const BlockLduMatrix& matrix, + const dictionary& dict + ); + + + // Selectors + + //- Return a new solver + static autoPtr > New + ( + const word& fieldName, + BlockLduMatrix& matrix, + const dictionary& dict + ); + + + // Destructor + + virtual ~BlockLduSolver() + {} + + + // Member functions + + //- Return field name + const word& fieldName() const + { + return fieldName_; + } + + //- Solve + virtual BlockSolverPerformance solve + ( + TypeField& x, + const TypeField& b + ) = 0; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "BlockLduSolver.C" +#endif + + +#define makeBlockSolverTypeName(typeSolverType) \ + \ +defineNamedTemplateTypeNameAndDebug(typeSolverType, 0); + +#define makeBlockSolvers(solverType) \ + \ +makeBlockSolverTypeName(solverType##Scalar); \ +makeBlockSolverTypeName(solverType##Vector); \ +makeBlockSolverTypeName(solverType##Tensor); + + +#define addSolverToBlockMatrix(Type, typeSolverType, typeMatrix) \ + \ +addToRunTimeSelectionTable(block##Type##Solver, typeSolverType, typeMatrix); + +#define addSolversToBlockMatrix(solverType, typeMatrix) \ + \ +addSolverToBlockMatrix(Scalar, solverType##Scalar, typeMatrix); \ +addSolverToBlockMatrix(Vector, solverType##Vector, typeMatrix); \ +addSolverToBlockMatrix(Tensor, solverType##Tensor, typeMatrix); + +#define addSymSolverToBlockMatrix(solverType) \ + \ +addSolversToBlockMatrix(solverType, symMatrix); + +#define addAsymSolverToBlockMatrix(solverType) \ + \ +addSolversToBlockMatrix(solverType, asymMatrix); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockLduSolver/BlockSolverPerformance.C b/src/blockMatrix/BlockLduSolvers/BlockLduSolver/BlockSolverPerformance.C new file mode 100644 index 000000000..904ad340d --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockLduSolver/BlockSolverPerformance.C @@ -0,0 +1,107 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 "BlockSolverPerformance.H" + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +bool Foam::BlockSolverPerformance::checkConvergence +( + const scalar Tolerance, + const scalar RelTolerance +) +{ + if (BlockLduMatrix::debug >= 2) + { + Info<< solverName_ + << ": Iteration " << nIterations_ + << " residual = " << finalResidual_ + << endl; + } + + if + ( + mag(finalResidual_) < Tolerance + || ( + RelTolerance > SMALL + && mag(finalResidual_) <= RelTolerance*mag(initialResidual_) + ) + ) + { + converged_ = true; + } + else + { + converged_ = false; + } + + return converged_; +} + + +template +bool Foam::BlockSolverPerformance::checkSingularity +( + const scalar& residual +) +{ + if (mag(residual) > VSMALL) + { + singular_ = false; + } + else + { + singular_ = true; + } + + return singular_; +} + + +template +void Foam::BlockSolverPerformance::print() const +{ + if (BlockLduMatrix::debug) + { + Info<< solverName_ << ": Solving for " << fieldName_; + + if (singular()) + { + Info<< ": solution singularity" << endl; + } + else + { + Info<< ", Initial residual = " << initialResidual_ + << ", Final residual = " << finalResidual_ + << ", No Iterations " << nIterations_ + << endl; + } + } +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockLduSolver/BlockSolverPerformance.H b/src/blockMatrix/BlockLduSolvers/BlockLduSolver/BlockSolverPerformance.H new file mode 100644 index 000000000..5471dd54b --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockLduSolver/BlockSolverPerformance.H @@ -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 + +Class + BlockSolverPerformance + +Description + Class returned by a solver. + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved. + +SourceFiles + BlockSolverPerformance.C + +\*---------------------------------------------------------------------------*/ + +#ifndef BlockSolverPerformance_H +#define BlockSolverPerformance_H + +#include "error.H" +#include "runTimeSelectionTables.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * Forward declaration of template friend fuctions * * * * * * * // + +template +class BlockSolverPerformance; + +template +Ostream& operator<<(Ostream&, const BlockSolverPerformance&); + + +/*---------------------------------------------------------------------------*\ + Class BlockSolverPerformance Declaration +\*---------------------------------------------------------------------------*/ + +template +class BlockSolverPerformance +{ + // Private data + + //- Solver name + word solverName_; + + //- Field name + word fieldName_; + + //- Initial residual + Type initialResidual_; + + //- Final residual + Type finalResidual_; + + //- Number of iterations + label nIterations_; + + //- Has the solver converged? + bool converged_; + + //- Is the matrix singular? + bool singular_; + + +public: + + // Constructors + + //- Construct with solver and field name + BlockSolverPerformance + ( + const word& solverName, + const word& fieldName, + const Type& iRes = pTraits::zero, + const Type& fRes = pTraits::zero, + const label nIter = 0, + const bool converged = false, + const bool singular = false + ) + : + solverName_(solverName), + fieldName_(fieldName), + initialResidual_(iRes), + finalResidual_(fRes), + nIterations_(nIter), + converged_(converged), + singular_(singular) + {} + + + // Member functions + + //- Return solver name + const word& solverName() const + { + return solverName_; + } + + //- Return initial residual + const Type& initialResidual() const + { + return initialResidual_; + } + + //- Return initial residual + Type& initialResidual() + { + return initialResidual_; + } + + //- Return final residual + const Type& finalResidual() const + { + return finalResidual_; + } + + //- Return final residual + Type& finalResidual() + { + return finalResidual_; + } + + //- Return number of iterations + label nIterations() const + { + return nIterations_; + } + + //- Return number of iterations + label& nIterations() + { + return nIterations_; + } + + //- Has the solver converged? + bool converged() const + { + return converged_; + } + + //- Has the solver converged? + bool& converged() + { + return converged_; + } + + //- Is the matrix singular? + bool singular() const + { + return singular_; + } + + //- Is the matrix singular? + bool& singular() + { + return singular_; + } + + //- Convergence test + bool checkConvergence + ( + const scalar tolerance, + const scalar relTolerance + ); + + //- Singularity test + bool checkSingularity(const scalar& residual); + + //- Print summary of solver performance + void print() const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "BlockSolverPerformance.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockLduSolver/blockLduSolvers.C b/src/blockMatrix/BlockLduSolvers/BlockLduSolver/blockLduSolvers.C new file mode 100644 index 000000000..b40e7907f --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockLduSolver/blockLduSolvers.C @@ -0,0 +1,90 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 solvers static data + +\*---------------------------------------------------------------------------*/ + +#include "blockLduSolvers.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +defineNamedTemplateTypeNameAndDebug(blockScalarSolver, 0); +defineNamedTemplateTypeNameAndDebug(blockVectorSolver, 0); +defineNamedTemplateTypeNameAndDebug(blockTensorSolver, 0); + + +// Define the constructor function hash tables for symmetric solvers + +defineTemplateRunTimeSelectionTable +( + blockScalarSolver, + symMatrix +); + +defineTemplateRunTimeSelectionTable +( + blockVectorSolver, + symMatrix +); + +defineTemplateRunTimeSelectionTable +( + blockTensorSolver, + symMatrix +); + + +// Define the constructor function hash tables for asymmetric solvers + +defineTemplateRunTimeSelectionTable +( + blockScalarSolver, + asymMatrix +); + +defineTemplateRunTimeSelectionTable +( + blockVectorSolver, + asymMatrix +); + +defineTemplateRunTimeSelectionTable +( + blockTensorSolver, + asymMatrix +); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/BlockLduSolver/blockLduSolvers.H b/src/blockMatrix/BlockLduSolvers/BlockLduSolver/blockLduSolvers.H new file mode 100644 index 000000000..4d0f526cf --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/BlockLduSolver/blockLduSolvers.H @@ -0,0 +1,57 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + Typedefs for a BlockLduSolver + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +\*---------------------------------------------------------------------------*/ + +#ifndef blockLduSolvers_H +#define blockLduSolvers_H + +#include "BlockLduSolver.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +typedef BlockLduSolver blockScalarSolver; +typedef BlockLduSolver blockVectorSolver; +typedef BlockLduSolver blockTensorSolver; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/Segregated/SegregatedSolver.C b/src/blockMatrix/BlockLduSolvers/Segregated/SegregatedSolver.C new file mode 100644 index 000000000..46aa30edf --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/Segregated/SegregatedSolver.C @@ -0,0 +1,219 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + Segregated solver for symmetric and asymmetric matrices. + Calls scalar solver component-by-component + +\*---------------------------------------------------------------------------*/ + +#include "SegregatedSolver.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +// Construct from matrix and solver data stream +template +Foam::SegregatedSolver::SegregatedSolver +( + const word& fieldName, + const BlockLduMatrix& matrix, + const dictionary& dict +) +: + BlockLduSolver(fieldName, matrix, dict), + scalarX_(matrix.lduAddr().size()), + scalarMatrix_(matrix.mesh()), + scalarB_(matrix.lduAddr().size()) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +Foam::BlockSolverPerformance Foam::SegregatedSolver::solve +( + Field& x, + const Field& b +) +{ + // Get reference to matrix, x and b + const BlockLduMatrix& blockMatrix = this->matrix_; + + // Determine if the diagonal or off-diagonal is expanded + + // Check switching diagonal + bool switchingDiag = false; + + if (blockMatrix.diag().activeType() == blockCoeffBase::SCALAR) + { + scalarMatrix_.diag() = blockMatrix.diag().asScalar(); + } + else + { + switchingDiag = true; + } + + // Check switching upper + bool switchingUpper = false; + + if (blockMatrix.thereIsUpper()) + { + if (blockMatrix.upper().activeType() == blockCoeffBase::SCALAR) + { + scalarMatrix_.upper() = blockMatrix.upper().asScalar(); + } + else + { + switchingUpper = true; + } + } + + // Check switching lower + bool switchingLower = false; + + if (blockMatrix.thereIsLower()) + { + if (blockMatrix.lower().activeType() == blockCoeffBase::SCALAR) + { + scalarMatrix_.lower() = blockMatrix.lower().asScalar(); + } + else + { + switchingLower = true; + } + } + + // Decouple quadratic coupling by multiplying out the square coefficient + // coupling + Field* dBPtr = NULL; + + if (blockMatrix.componentCoupled()) + { + if (BlockLduMatrix::debug >= 2) + { + Info << " Component coupled segregation" << endl; + } + + dBPtr = new Field(b); + blockMatrix.segregateB(*dBPtr, x); + } + + // Prepare solver performance + word segSolverName(this->dict().lookup("solver")); + + BlockSolverPerformance solverPerf + ( + typeName + "_" + segSolverName, + this->fieldName() + ); + + // Loop through the form component by component and call the + // scalar solver + for + ( + direction cmpt = 0; + cmpt < pTraits::nComponents; + cmpt++ + ) + { + // Grab the x and b for the current component + scalarX_ = x.component(cmpt); + + // Handle b decoupling + if (dBPtr) + { + scalarB_ = dBPtr->component(cmpt); + } + else + { + scalarB_ = b.component(cmpt); + } + + // Switch diagonal, upper and lower + if (switchingDiag) + { + scalarMatrix_.diag() = blockMatrix.diag().component(cmpt); + } + + if (switchingUpper) + { + scalarMatrix_.upper() = blockMatrix.upper().component(cmpt); + } + + if (switchingLower) + { + scalarMatrix_.lower() = blockMatrix.lower().component(cmpt); + } + + // Call the scalar solver + BlockSolverPerformance scalarPerf = + blockScalarSolver::New + ( + this->fieldName(), + scalarMatrix_, + this->dict() + )->solve(scalarX_, scalarB_); + + // Replace the solution component + x.replace(cmpt, scalarX_); + + // Grab solver performance and combine + solverPerf.initialResidual().replace + ( + cmpt, + scalarPerf.initialResidual() + ); + + solverPerf.finalResidual().replace + ( + cmpt, + scalarPerf.finalResidual() + ); + + solverPerf.nIterations() = + max + ( + solverPerf.nIterations(), + scalarPerf.nIterations() + ); + + solverPerf.converged() = + (solverPerf.converged() && scalarPerf.converged()); + + solverPerf.singular() = + solverPerf.singular() && scalarPerf.singular(); + } + + // Clear decoupled b if allocated + if (dBPtr) + { + delete dBPtr; + dBPtr = NULL; + } + + return solverPerf; +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/Segregated/SegregatedSolver.H b/src/blockMatrix/BlockLduSolvers/Segregated/SegregatedSolver.H new file mode 100644 index 000000000..9a8d94972 --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/Segregated/SegregatedSolver.H @@ -0,0 +1,133 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + SegregatedSolver + +Description + Segregated solver for block matrices. Segregation decouples block + coefficients and calls a scalar solver for each component separately. + Cross-component coupling is lagged in rhs. + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + SegregatedSolver.C + +\*---------------------------------------------------------------------------*/ + +#ifndef SegregatedSolver_H +#define SegregatedSolver_H + +#include "blockLduSolvers.H" +#include "BlockIterativeSolver.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class SegregatedSolver Declaration +\*---------------------------------------------------------------------------*/ + +template +class SegregatedSolver +: + public BlockLduSolver +{ +private: + + // Private data + + //- Scalar x + scalarField scalarX_; + + //- Scalar matrix + blockScalarMatrix scalarMatrix_; + + //- Scalar b + scalarField scalarB_; + + + // Private Member Functions + + //- Disallow default bitwise copy construct + SegregatedSolver(const SegregatedSolver&); + + //- Disallow default bitwise assignment + void operator=(const SegregatedSolver&); + + +public: + + //- Runtime type information + TypeName("Segregated"); + + + // Constructors + + //- Construct from matrix components and solver data stream + SegregatedSolver + ( + const word& fieldName, + const BlockLduMatrix& matrix, + const dictionary& dict + ); + + + // Destructor + + virtual ~SegregatedSolver() + {} + + + // Member Functions + + //- Solve the matrix with this solver + virtual BlockSolverPerformance solve + ( + Field& x, + const Field& b + ); + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "SegregatedSolver.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/Segregated/segregatedSolvers.C b/src/blockMatrix/BlockLduSolvers/Segregated/segregatedSolvers.C new file mode 100644 index 000000000..57b39747d --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/Segregated/segregatedSolvers.C @@ -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 + +\*---------------------------------------------------------------------------*/ + +#include "blockLduMatrices.H" +#include "segregatedSolvers.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +// Segregated scalar solver makes no sense and is not instantiated +makeBlockSolverTypeName(segregatedSolverVector); +makeBlockSolverTypeName(segregatedSolverTensor); + +addSolverToBlockMatrix(Vector, segregatedSolverVector, symMatrix); +addSolverToBlockMatrix(Tensor, segregatedSolverTensor, symMatrix); + +addSolverToBlockMatrix(Vector, segregatedSolverVector, asymMatrix); +addSolverToBlockMatrix(Tensor, segregatedSolverTensor, asymMatrix); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/blockMatrix/BlockLduSolvers/Segregated/segregatedSolvers.H b/src/blockMatrix/BlockLduSolvers/Segregated/segregatedSolvers.H new file mode 100644 index 000000000..8a50f261d --- /dev/null +++ b/src/blockMatrix/BlockLduSolvers/Segregated/segregatedSolvers.H @@ -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 + Segregated + +Description + Segregated solver. + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + segregatedSolvers.C + +\*---------------------------------------------------------------------------*/ + +#ifndef segregatedSolvers_H +#define segregatedSolvers_H + +#include "SegregatedSolver.H" +#include "fieldTypes.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +typedef SegregatedSolver segregatedSolverScalar; +typedef SegregatedSolver segregatedSolverVector; +typedef SegregatedSolver segregatedSolverTensor; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/CoeffField/CoeffField.C b/src/blockMatrix/CoeffField/CoeffField.C new file mode 100644 index 000000000..91e987371 --- /dev/null +++ b/src/blockMatrix/CoeffField/CoeffField.C @@ -0,0 +1,1353 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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" +#include "expandTensorField.H" + +// * * * * * * * * * * * * * * * Static Members * * * * * * * * * * * * * * // + +template +const char* const Foam::CoeffField::typeName("CoeffField"); + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template +template +inline void Foam::CoeffField::checkSize(const UList& f) const +{ + if (f.size() != this->size()) + { + FatalErrorIn + ( + "void CoeffField::checkSize(const Field& f) const" + ) << "Incorrect field size: " << f.size() + << " local size: " << size() + << abort(FatalError); + } +} + + +template +typename Foam::CoeffField::scalarTypeField& +Foam::CoeffField::toScalar() +{ + if (!scalarCoeffPtr_) + { + // Debug check: demotion + if (linearCoeffPtr_ || squareCoeffPtr_) + { + FatalErrorIn + ( + "CoeffField::scalarTypeField& " + "CoeffField::toScalar()" + ) << "Detected demotion to scalar. Probably an error" + << abort(FatalError); + } + + scalarCoeffPtr_ = + new scalarTypeField(size(), pTraits::zero); + } + + return *scalarCoeffPtr_; +} + + +template +typename Foam::CoeffField::linearTypeField& +Foam::CoeffField::toLinear() +{ + if (!linearCoeffPtr_) + { + // Debug check: demotion + if (squareCoeffPtr_) + { + FatalErrorIn + ( + "CoeffField::linearTypeField& " + "CoeffField::toLinear()" + ) << "Detected demotion to linear. Probably an error" + << abort(FatalError); + } + + linearCoeffPtr_ = + new linearTypeField(size(), pTraits::zero); + + // If scalar is active, promote to linear + if (scalarCoeffPtr_) + { + expandScalar(*linearCoeffPtr_, *scalarCoeffPtr_); + deleteDemandDrivenData(scalarCoeffPtr_); + } + } + + return *linearCoeffPtr_; +} + + +template +typename Foam::CoeffField::squareTypeField& +Foam::CoeffField::toSquare() +{ + if (!squareCoeffPtr_) + { + squareCoeffPtr_ = + new squareTypeField(this->size(), pTraits::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 +Foam::CoeffField::CoeffField(const label size) +: + scalarCoeffPtr_(NULL), + linearCoeffPtr_(NULL), + squareCoeffPtr_(NULL), + size_(size) +{} + + +template +Foam::CoeffField::CoeffField(const CoeffField& f) +: + refCount(), + scalarCoeffPtr_(NULL), + linearCoeffPtr_(NULL), + squareCoeffPtr_(NULL), + size_(f.size()) +{ + if (f.scalarCoeffPtr_) + { + scalarCoeffPtr_ = new scalarTypeField(*(f.scalarCoeffPtr_)); + } + else if (f.linearCoeffPtr_) + { + linearCoeffPtr_ = new linearTypeField(*(f.linearCoeffPtr_)); + } + else if (f.squareCoeffPtr_) + { + squareCoeffPtr_ = new squareTypeField(*(f.squareCoeffPtr_)); + } +} + + +template +Foam::CoeffField::CoeffField(Istream& is) +: + scalarCoeffPtr_(NULL), + linearCoeffPtr_(NULL), + squareCoeffPtr_(NULL), + size_(0) +{ + // Read keyword and pick up allocated field + word key(is); + + if + ( + key + == blockCoeffBase::activeLevelNames_[blockCoeffBase::UNALLOCATED] + ) + { + size_ = readLabel(is); + } + else if + ( + key + == blockCoeffBase::activeLevelNames_[blockCoeffBase::SCALAR] + ) + { + scalarCoeffPtr_ = new scalarTypeField(is); + size_ = scalarCoeffPtr_->size(); + } + else if + ( + key + == blockCoeffBase::activeLevelNames_[blockCoeffBase::LINEAR] + ) + { + linearCoeffPtr_ = new linearTypeField(is); + size_ = linearCoeffPtr_->size(); + } + else if + ( + key + == blockCoeffBase::activeLevelNames_[blockCoeffBase::SQUARE] + ) + { + squareCoeffPtr_ = new squareTypeField(is); + size_ = squareCoeffPtr_->size(); + } + else + { + FatalIOErrorIn + ( + "CoeffField::CoeffField(Istream& is)", + is + ) << "invalid keyword while reading: " << key + << exit(FatalIOError); + } +} + + +template +Foam::tmp > Foam::CoeffField::clone() const +{ + return tmp >(new CoeffField(*this)); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +template +Foam::CoeffField::~CoeffField() +{ + this->clear(); +} + + +template +void Foam::CoeffField::clear() +{ + deleteDemandDrivenData(scalarCoeffPtr_); + deleteDemandDrivenData(linearCoeffPtr_); + deleteDemandDrivenData(squareCoeffPtr_); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +inline Foam::label Foam::CoeffField::size() const +{ + return size_; +} + + +template +void Foam::CoeffField::negate() +{ + if (scalarCoeffPtr_) + { + scalarCoeffPtr_->negate(); + } + else if (linearCoeffPtr_) + { + linearCoeffPtr_->negate(); + } + else if (squareCoeffPtr_) + { + squareCoeffPtr_->negate(); + } +} + + +template +Foam::tmp > Foam::CoeffField::transpose() const +{ + tmp > tt(new CoeffField(this->size())); + CoeffField& t = tt(); + + if (scalarCoeffPtr_) + { + t.toScalar() = *scalarCoeffPtr_; + } + else if (linearCoeffPtr_) + { + t.toLinear() = *linearCoeffPtr_; + } + else if (squareCoeffPtr_) + { + t.toSquare() = this->asSquare().T(); + } + else + { + // Not allocated - do nothing + } + + + return tt; +} + + +template +Foam::blockCoeffBase::activeLevel +Foam::CoeffField::activeType() const +{ + if (scalarCoeffPtr_) + { + return blockCoeffBase::SCALAR; + } + else if (linearCoeffPtr_) + { + return blockCoeffBase::LINEAR; + } + else if (squareCoeffPtr_) + { + return blockCoeffBase::SQUARE; + } + else + { + return blockCoeffBase::UNALLOCATED; + } +} + + +template +void Foam::CoeffField::checkActive() const +{ + label nActive = 0; + + if (scalarCoeffPtr_) nActive++; + if (linearCoeffPtr_) nActive++; + if (squareCoeffPtr_) nActive++; + + if (nActive > 1) + { + FatalErrorIn("void Foam::CoeffField::checkActive() const") + << "Activation/deactivation error. nActive = " << nActive + << abort(FatalError); + } +} + + +template +const typename Foam::CoeffField::scalarTypeField& +Foam::CoeffField::asScalar() const +{ + if (!scalarCoeffPtr_) + { + FatalErrorIn + ( + "CoeffField::scalarTypeField& " + "CoeffField::asScalar()" + ) << "Requested scalar but active type is: " + << blockCoeffBase::activeLevelNames_[this->activeType()] + << ". This is not allowed." + << abort(FatalError); + } + + return *scalarCoeffPtr_; +} + + +template +const typename Foam::CoeffField::linearTypeField& +Foam::CoeffField::asLinear() const +{ + if (!linearCoeffPtr_) + { + FatalErrorIn + ( + "CoeffField::linearTypeField& " + "CoeffField::asLinear()" + ) << "Requested linear but active type is: " + << blockCoeffBase::activeLevelNames_[this->activeType()] + << ". This is not allowed." + << abort(FatalError); + } + + return *linearCoeffPtr_; +} + + +template +const typename Foam::CoeffField::squareTypeField& +Foam::CoeffField::asSquare() const +{ + if (!squareCoeffPtr_) + { + FatalErrorIn + ( + "CoeffField::squareTypeField& " + "CoeffField::asSquare()" + ) << "Requested square but active type is: " + << blockCoeffBase::activeLevelNames_[this->activeType()] + << ". This is not allowed." + << abort(FatalError); + } + + return *squareCoeffPtr_; +} + + +template +typename Foam::CoeffField::scalarTypeField& +Foam::CoeffField::asScalar() +{ + if (linearCoeffPtr_ || squareCoeffPtr_) + { + FatalErrorIn + ( + "CoeffField::scalarTypeField& " + "CoeffField::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 +typename Foam::CoeffField::linearTypeField& +Foam::CoeffField::asLinear() +{ + if (squareCoeffPtr_) + { + FatalErrorIn + ( + "CoeffField::linearTypeField& " + "CoeffField::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 +typename Foam::CoeffField::squareTypeField& +Foam::CoeffField::asSquare() +{ + if (!squareCoeffPtr_) + { + return this->toSquare(); + } + + return *squareCoeffPtr_; +} + + +template +Foam::tmp::scalarTypeField> +Foam::CoeffField::component(const direction dir) const +{ + if (scalarCoeffPtr_) + { + return *scalarCoeffPtr_; + } + else if (linearCoeffPtr_) + { + return linearCoeffPtr_->component(dir); + } + else if (squareCoeffPtr_) + { + linearTypeField lc(this->size()); + contractLinear(lc, *squareCoeffPtr_); + + return lc.component(dir); + } + else + { + FatalErrorIn + ( + "tmp::scalarTypeField>" + "CoeffField::component(const direction dir) const" + ) << "Field not allocated." + << abort(FatalError); + } + + // Dummy return to keep compiler happy + return *scalarCoeffPtr_; +} + + +template +Foam::BlockCoeff +Foam::CoeffField::getCoeff(const label index) const +{ + BlockCoeff result; + + if (scalarCoeffPtr_) + { + result.asScalar() = (*scalarCoeffPtr_)[index]; + } + else if (linearCoeffPtr_) + { + result.asLinear() = (*linearCoeffPtr_)[index]; + } + else if (squareCoeffPtr_) + { + result.asSquare() = (*squareCoeffPtr_)[index]; + } + + return result; +} + + +template +void Foam::CoeffField::setCoeff +( + const label index, + const BlockCoeff& coeff +) +{ + BlockCoeff result; + + if (coeff.activeType() == blockCoeffBase::SCALAR) + { + (*scalarCoeffPtr_)[index] = result.asScalar(); + } + else if (coeff.activeType() == blockCoeffBase::LINEAR) + { + (*linearCoeffPtr_)[index] = result.asLinear(); + } + else if (coeff.activeType() == blockCoeffBase::SQUARE) + { + (*squareCoeffPtr_)[index] = result.asSquare(); + } +} + + +template +void Foam::CoeffField::getSubset +( + CoeffField& f, + const label start, + const label size +) const +{ + // Check sizes + if (f.size() != size) + { + FatalErrorIn + ( + "template\n" + "void Foam::CoeffField::getSubset\n" + "(\n" + " CoeffField& f,\n" + " const label start,\n" + " const label size\n" + ") const" + ) << "Incompatible sizes: " << f.size() << " and " << size + << abort(FatalError); + } + + if (scalarCoeffPtr_) + { + scalarTypeField& ff = f.asScalar(); + + const scalarTypeField& localF = (*scalarCoeffPtr_); + + forAll (ff, ffI) + { + ff[ffI] = localF[start + ffI]; + } + } + else if (linearCoeffPtr_) + { + linearTypeField& ff = f.asLinear(); + + const linearTypeField& localF = (*linearCoeffPtr_); + + forAll (ff, ffI) + { + ff[ffI] = localF[start + ffI]; + } + } + else if (squareCoeffPtr_) + { + squareTypeField& ff = f.asSquare(); + + const squareTypeField& localF = (*squareCoeffPtr_); + + forAll (ff, ffI) + { + ff[ffI] = localF[start + ffI]; + } + } +} + + +template +void Foam::CoeffField::getSubset +( + CoeffField& f, + const labelList& addr +) const +{ + // Check sizes + if (f.size() != addr.size()) + { + FatalErrorIn + ( + "template\n" + "void Foam::CoeffField::getSubset\n" + "(\n" + " CoeffField& f,\n" + " const labelList addr\n" + ") const" + ) << "Incompatible sizes: " << f.size() << " and " << addr.size() + << abort(FatalError); + } + + if (scalarCoeffPtr_) + { + scalarTypeField& ff = f.asScalar(); + + const scalarTypeField& localF = (*scalarCoeffPtr_); + + forAll (ff, ffI) + { + ff[ffI] = localF[addr[ffI]]; + } + } + else if (linearCoeffPtr_) + { + linearTypeField& ff = f.asLinear(); + + const linearTypeField& localF = (*linearCoeffPtr_); + + forAll (ff, ffI) + { + ff[ffI] = localF[addr[ffI]]; + } + } + else if (squareCoeffPtr_) + { + squareTypeField& ff = f.asSquare(); + + const squareTypeField& localF = (*squareCoeffPtr_); + + forAll (ff, ffI) + { + ff[ffI] = localF[addr[ffI]]; + } + } +} + + +template +void Foam::CoeffField::setSubset +( + const CoeffField& f, + const label start, + const label size +) +{ + // Check sizes + if (f.size() != size) + { + FatalErrorIn + ( + "template\n" + "void Foam::CoeffField::setSubset\n" + "(\n" + " const CoeffField& f,\n" + " const label start,\n" + " const label size\n" + ")" + ) << "Incompatible sizes: " << f.size() << " and " << size + << abort(FatalError); + } + + if (f.activeType() == blockCoeffBase::SCALAR) + { + const scalarTypeField& ff = f.asScalar(); + + scalarTypeField& localF = this->asScalar(); + + forAll (ff, ffI) + { + localF[start + ffI] = ff[ffI]; + } + } + else if (f.activeType() == blockCoeffBase::LINEAR) + { + const linearTypeField& ff = f.asLinear(); + + linearTypeField& localF = this->asLinear(); + + forAll (ff, ffI) + { + localF[start + ffI] = ff[ffI]; + } + } + else if (f.activeType() == blockCoeffBase::SQUARE) + { + const squareTypeField& ff = f.asSquare(); + + squareTypeField& localF = this->asSquare(); + + forAll (ff, ffI) + { + localF[start + ffI] = ff[ffI]; + } + } +} + + +template +void Foam::CoeffField::setSubset +( + const CoeffField& f, + const labelList& addr +) +{ + // Check sizes + if (f.size() != addr.size()) + { + FatalErrorIn + ( + "template\n" + "void Foam::CoeffField::setSubset\n" + "(\n" + " const CoeffField& f,\n" + " const labelList addr\n" + ")" + ) << "Incompatible sizes: " << f.size() << " and " << addr.size() + << abort(FatalError); + } + + if (f.activeType() == blockCoeffBase::SCALAR) + { + const scalarTypeField& ff = f.asScalar(); + + scalarTypeField& localF = this->asScalar(); + + forAll (ff, ffI) + { + localF[addr[ffI]] = ff[ffI]; + } + } + else if (f.activeType() == blockCoeffBase::LINEAR) + { + const linearTypeField& ff = f.asLinear(); + + linearTypeField& localF = this->asLinear(); + + forAll (ff, ffI) + { + localF[addr[ffI]] = ff[ffI]; + } + } + else if (f.activeType() == blockCoeffBase::SQUARE) + { + const squareTypeField& ff = f.asSquare(); + + squareTypeField& localF = this->asSquare(); + + forAll (ff, ffI) + { + localF[addr[ffI]] = ff[ffI]; + } + } +} + + +template +void Foam::CoeffField::zeroOutSubset +( + const label start, + const label size +) +{ + if (scalarCoeffPtr_) + { + scalarTypeField& localF = this->asScalar(); + + for (label ffI = 0; ffI < size; ffI++) + { + localF[start + ffI] = pTraits::zero; + } + } + else if (linearCoeffPtr_) + { + linearTypeField& localF = this->asLinear(); + + for (label ffI = 0; ffI < size; ffI++) + { + localF[start + ffI] = pTraits::zero; + } + } + else if (squareCoeffPtr_) + { + squareTypeField& localF = this->asSquare(); + + for (label ffI = 0; ffI < size; ffI++) + { + localF[start + ffI] = pTraits::zero; + } + } +} + + +template +void Foam::CoeffField::zeroOutSubset +( + const labelList& addr +) +{ + if (scalarCoeffPtr_) + { + scalarTypeField& localF = this->asScalar(); + + forAll (addr, ffI) + { + localF[addr[ffI]] = pTraits::zero; + } + } + else if (linearCoeffPtr_) + { + linearTypeField& localF = this->asLinear(); + + forAll (addr, ffI) + { + localF[addr[ffI]] = pTraits::zero; + } + } + else if (squareCoeffPtr_) + { + squareTypeField& localF = this->asSquare(); + + forAll (addr, ffI) + { + localF[addr[ffI]] = pTraits::zero; + } + } +} + + +template +void Foam::CoeffField::addSubset +( + const CoeffField& f, + const labelList& addr +) +{ + // Check sizes + if (f.size() != addr.size()) + { + FatalErrorIn + ( + "template\n" + "void Foam::CoeffField::addSubset\n" + "(\n" + " const CoeffField& f,\n" + " const labelList addr\n" + ")" + ) << "Incompatible sizes: " << f.size() << " and " << addr.size() + << abort(FatalError); + } + + if (this->activeType() == blockCoeffBase::SQUARE) + { + if (f.activeType() == blockCoeffBase::SQUARE) + { + squareTypeField& localF = this->asSquare(); + + const squareTypeField& ff = f.asSquare(); + + forAll (ff, ffI) + { + localF[addr[ffI]] += ff[ffI]; + } + } + else if (f.activeType() == blockCoeffBase::LINEAR) + { + squareTypeField& localF = this->asSquare(); + + squareTypeField ff(f.size()); + expandLinear(ff, f.asLinear()); + + forAll (ff, ffI) + { + localF[addr[ffI]] += ff[ffI]; + } + } + else if (f.activeType() == blockCoeffBase::SCALAR) + { + squareTypeField& localF = this->asSquare(); + + squareTypeField ff(f.size()); + expandScalar(ff, f.asScalar()); + + forAll (ff, ffI) + { + localF[addr[ffI]] += ff[ffI]; + } + } + } + else if (this->activeType() == blockCoeffBase::LINEAR) + { + if (f.activeType() == blockCoeffBase::SQUARE) + { + squareTypeField& localF = this->asSquare(); + + const squareTypeField& ff = f.asSquare(); + + forAll (ff, ffI) + { + localF[addr[ffI]] += ff[ffI]; + } + } + if (f.activeType() == blockCoeffBase::LINEAR) + { + linearTypeField& localF = this->asLinear(); + + const linearTypeField& ff = f.asLinear(); + + forAll (ff, ffI) + { + localF[addr[ffI]] += ff[ffI]; + } + } + else if (f.activeType() == blockCoeffBase::SCALAR) + { + linearTypeField& localF = this->asLinear(); + + linearTypeField ff(f.size()); + expandScalar(ff, f.asScalar()); + + forAll (ff, ffI) + { + localF[addr[ffI]] += ff[ffI]; + } + } + } + else if (this->activeType() == blockCoeffBase::SCALAR) + { + if (f.activeType() == blockCoeffBase::SQUARE) + { + squareTypeField& localF = this->asSquare(); + + const squareTypeField& ff = f.asSquare(); + + forAll (ff, ffI) + { + localF[addr[ffI]] += ff[ffI]; + } + } + if (f.activeType() == blockCoeffBase::LINEAR) + { + linearTypeField& localF = this->asLinear(); + + const linearTypeField& ff = f.asLinear(); + + forAll (ff, ffI) + { + localF[addr[ffI]] += ff[ffI]; + } + } + else if (f.activeType() == blockCoeffBase::SCALAR) + { + const scalarTypeField& ff = f.asScalar(); + + scalarTypeField& localF = this->asScalar(); + + forAll (ff, ffI) + { + localF[addr[ffI]] += ff[ffI]; + } + } + } + else + { + FatalErrorIn + ( + "template\n" + "void Foam::CoeffField::addSubset\n" + "(\n" + " const CoeffField& f,\n" + " const labelList addr\n" + ")" + ) << "Incompatible combination of types" + << abort(FatalError); + } +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +template +void Foam::CoeffField::operator=(const CoeffField& f) +{ + if (this == &f) + { + FatalErrorIn("CoeffField::operator=(const CoeffField&)") + << "attempted assignment to self" + << abort(FatalError); + } + + // Check field sizes + if (f.size() != this->size()) + { + FatalErrorIn + ( + "void CoeffField::operator=(const CoeffField& f)" + ) << "Incorrect field size: " << f.size() + << " local size: " << size() + << 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 + } +} + + +template +void Foam::CoeffField::operator=(const tmp& tf) +{ + if (this == &(tf())) + { + FatalErrorIn("CoeffField::operator=(const tmp&)") + << "attempted assignment to self" + << abort(FatalError); + } + + operator=(tf()); + tf.clear(); +} + + +#define COMPUTED_BASE_ASSIGNMENT(op) \ + \ +template \ +void Foam::CoeffField::operator op(const CoeffField& f) \ +{ \ + if (f.size() != this->size()) \ + { \ + FatalErrorIn \ + ( \ + "void CoeffField::operator " \ + "op(const CoeffField& f)" \ + ) << "Incorrect field size: " << f.size() \ + << " local size: " << size() \ + << abort(FatalError); \ + } \ + \ + if (this->activeType() == blockCoeffBase::SQUARE) \ + { \ + if (f.activeType() == blockCoeffBase::SQUARE) \ + { \ + this->asSquare() op f.asSquare(); \ + } \ + else if (f.activeType() == blockCoeffBase::LINEAR) \ + { \ + squareTypeField ff(f.size()); \ + expandLinear(ff, f.asLinear()); \ + \ + this->asSquare() op ff; \ + } \ + else if (f.activeType() == blockCoeffBase::SCALAR) \ + { \ + squareTypeField ff(f.size()); \ + expandScalar(ff, f.asScalar()); \ + \ + this->asSquare() op ff; \ + } \ + } \ + else if (this->activeType() == blockCoeffBase::LINEAR) \ + { \ + if (f.activeType() == blockCoeffBase::SQUARE) \ + { \ + this->asSquare() op f.asSquare(); \ + } \ + if (f.activeType() == blockCoeffBase::LINEAR) \ + { \ + this->asLinear() op f.asLinear(); \ + } \ + else if (f.activeType() == blockCoeffBase::SCALAR) \ + { \ + linearTypeField ff(f.size()); \ + expandScalar(ff, f.asScalar()); \ + \ + this->asLinear() op ff; \ + } \ + } \ + else if (this->activeType() == blockCoeffBase::SCALAR) \ + { \ + if (f.activeType() == blockCoeffBase::SQUARE) \ + { \ + this->asSquare() op f.asSquare(); \ + } \ + if (f.activeType() == blockCoeffBase::LINEAR) \ + { \ + this->asLinear() op f.asLinear(); \ + } \ + else if (f.activeType() == blockCoeffBase::SCALAR) \ + { \ + this->asScalar() op f.asScalar(); \ + } \ + } \ +} \ + \ +template \ +void Foam::CoeffField::operator op(const tmp >& tf) \ +{ \ + operator op(tf()); \ + tf.clear(); \ +} + + +#define COMPUTED_ARG_ASSIGNMENT(op) \ + \ +template \ +void Foam::CoeffField::operator op(const scalarTypeField& f) \ +{ \ + checkSize(f); \ + \ + const blockCoeffBase::activeLevel al = this->activeType(); \ + \ + if (al == blockCoeffBase::UNALLOCATED || al == blockCoeffBase::SCALAR) \ + { \ + this->toScalar() op f; \ + } \ + else if (al == blockCoeffBase::LINEAR) \ + { \ + this->toLinear() op f*pTraits::one; \ + } \ + else if (al == blockCoeffBase::SQUARE) \ + { \ + squareTypeField stf(f.size()); \ + expandScalar(stf, f); \ + this->toSquare() op stf; \ + } \ + else \ + { \ + } \ +} \ + \ +template \ +void Foam::CoeffField::operator op(const tmp& tf) \ +{ \ + operator op(tf()); \ + tf.clear(); \ +} \ + \ + \ +template \ +void Foam::CoeffField::operator op(const linearTypeField& f) \ +{ \ + checkSize(f); \ + \ + const blockCoeffBase::activeLevel al = this->activeType(); \ + \ + if \ + ( \ + al == blockCoeffBase::UNALLOCATED \ + || al == blockCoeffBase::SCALAR \ + || al == blockCoeffBase::LINEAR \ + ) \ + { \ + this->toLinear() op f; \ + } \ + else if (al == blockCoeffBase::SQUARE) \ + { \ + squareTypeField stf(f.size()); \ + expandLinear(stf, f); \ + this->toSquare() op stf; \ + } \ + else \ + { \ + } \ +} \ + \ +template \ +void Foam::CoeffField::operator op(const tmp& tf) \ +{ \ + operator op(tf()); \ + tf.clear(); \ +} \ + \ + \ +template \ +void Foam::CoeffField::operator op(const squareTypeField& f) \ +{ \ + checkSize(f); \ + this->toSquare() op f; \ +} \ + \ +template \ +void Foam::CoeffField::operator op(const tmp& tf) \ +{ \ + operator op(tf()); \ + tf.clear(); \ +} + +#define COMPUTED_BASE_OPERATOR(TYPE, op) \ + \ +template \ +void Foam::CoeffField::operator op(const TYPE& t) \ +{ \ + if (scalarCoeffPtr_) \ + { \ + *(scalarCoeffPtr_) op t; \ + } \ + else if (linearCoeffPtr_) \ + { \ + *(linearCoeffPtr_) op t; \ + } \ + else if (squareCoeffPtr_) \ + { \ + *(squareCoeffPtr_) op t; \ + } \ + else \ + { \ + } \ +} \ + \ +template \ +void Foam::CoeffField::operator op(const UList& tf) \ +{ \ + checkSize(tf); \ + \ + if (scalarCoeffPtr_) \ + { \ + *(scalarCoeffPtr_) op tf; \ + } \ + else if (linearCoeffPtr_) \ + { \ + *(linearCoeffPtr_) op tf; \ + } \ + else if (squareCoeffPtr_) \ + { \ + *(squareCoeffPtr_) op tf; \ + } \ + else \ + { \ + } \ +} \ + \ +template \ +void Foam::CoeffField::operator op(const tmp >& tf) \ +{ \ + operator op(tf()); \ + tf.clear(); \ +} + + +#define COMPUTED_ASSIGNMENT(op) \ +COMPUTED_BASE_ASSIGNMENT(op) \ +COMPUTED_ARG_ASSIGNMENT(op) + +// Remaining operator= +COMPUTED_ARG_ASSIGNMENT(=) + +COMPUTED_ASSIGNMENT(+=) +COMPUTED_ASSIGNMENT(-=) + +COMPUTED_BASE_OPERATOR(scalar, *=) +COMPUTED_BASE_OPERATOR(scalar, /=) + +#undef COMPUTED_BASE_OPERATOR +#undef COMPUTED_BASE_ASSIGNMENT +#undef COMPUTED_ARG_ASSIGNMENT +#undef COMPUTED_ASSIGNMENT + + +// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * // + +template +Foam::Ostream& Foam::operator<<(Ostream& os, const CoeffField& f) +{ + // Write active type + os << blockCoeffBase::activeLevelNames_[f.activeType()] << nl; + + if (f.activeType() == blockCoeffBase::SCALAR) + { + os << f.asScalar(); + } + else if (f.activeType() == blockCoeffBase::LINEAR) + { + os << f.asLinear(); + } + else if (f.activeType() == blockCoeffBase::SQUARE) + { + os << f.asSquare(); + } + else + { + // Not allocated: write size + os << f.size(); + } + + return os; +} + + +template +Foam::Ostream& Foam::operator<<(Ostream& os, const tmp >& tf) +{ + os << tf(); + tf.clear(); + return os; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +# include "CoeffFieldFunctions.C" + + +// ************************************************************************* // diff --git a/src/blockMatrix/CoeffField/CoeffField.H b/src/blockMatrix/CoeffField/CoeffField.H new file mode 100644 index 000000000..613b2d52a --- /dev/null +++ b/src/blockMatrix/CoeffField/CoeffField.H @@ -0,0 +1,330 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + CoeffField + +Description + Generic coefficient field type. Used in BlockLduMatrix. HJ, 2/Apr/2005 + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + CoeffField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef CoeffField_H +#define CoeffField_H + +#include "VectorSpace.H" +#include "primitiveFields.H" +#include "blockCoeffs.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * Forward declaration of template friend fuctions * * * * * * * // + +template +class CoeffField; + +template +Ostream& operator<<(Ostream&, const CoeffField&); + +template +Ostream& operator<<(Ostream&, const tmp >&); + + +/*---------------------------------------------------------------------------*\ + Class CoeffField Declaration +\*---------------------------------------------------------------------------*/ + +template +class CoeffField +: + public refCount +{ +public: + + // Public data types + + //- Component type + typedef typename BlockCoeff::scalarType scalarType; + typedef typename BlockCoeff::linearType linearType; + typedef typename BlockCoeff::squareType squareType; + + //- Field type + typedef typename BlockCoeff::scalarTypeField scalarTypeField; + typedef typename BlockCoeff::linearTypeField linearTypeField; + typedef typename BlockCoeff::squareTypeField squareTypeField; + + +private: + + // Private data + + //- Scalar coefficient + mutable scalarTypeField* scalarCoeffPtr_; + + //- Linear coefficient + mutable linearTypeField* linearCoeffPtr_; + + //- Square coefficient + mutable squareTypeField* squareCoeffPtr_; + + //- Number of elements + label size_; + + + // Private Member Functions + + //- Check size for arithmetic operations: resizing is not allowed! + template + inline void checkSize(const UList&) const; + + //- Promote to scalar + scalarTypeField& toScalar(); + + //- Promote to linear + linearTypeField& toLinear(); + + //- Promote to square + squareTypeField& toSquare(); + + +public: + + // Static data members + + static const char* const typeName; + + + // Constructors + + //- Construct given size + explicit CoeffField(const label); + + //- Construct as copy + CoeffField(const CoeffField&); + + //- Construct from Istream + explicit CoeffField(Istream&); + + //- Clone + tmp > clone() const; + + + // Destructor + + ~CoeffField(); + + //- Clear data + void clear(); + + + // Member functions + + //- Return size + inline label size() const; + + //- Return active type + blockCoeffBase::activeLevel activeType() const; + + //- Check pointers: only one type should be active (debug only) + void checkActive() const; + + //- Negate this field + void negate(); + + //- Return the field transpose + tmp > transpose() const; + + + // Return as typed. Fails when asked for the incorrect type + + //- Return as scalar field + const scalarTypeField& asScalar() const; + + //- Return as linear field + const linearTypeField& asLinear() const; + + //- Return as square field + const squareTypeField& asSquare() const; + + + // Return as typed. Fails when asked for demotion + + //- Return as scalar field + scalarTypeField& asScalar(); + + //- Return as linear field + linearTypeField& asLinear(); + + //- Return as square field + squareTypeField& asSquare(); + + + //- Return component + tmp component(const direction) const; + + //- Return coefficient as block + BlockCoeff getCoeff(const label index) const; + + //- Set coefficient from a block + void setCoeff(const label index, const BlockCoeff& coeff); + + + // Subset operations + + //- Get subset with offset and size and store in given field + void getSubset + ( + CoeffField& f, + const label start, + const label size + ) const; + + //- Get subset with addressing and store in given field + void getSubset + ( + CoeffField& f, + const labelList& addr + ) const; + + + //- Set subset with offset and size from given field + void setSubset + ( + const CoeffField& f, + const label start, + const label size + ); + + //- Get subset with addressing and store in target field + void setSubset + ( + const CoeffField& f, + const labelList& addr + ); + + //- Zero out subset with offset and size + void zeroOutSubset + ( + const label start, + const label size + ); + + //- Zero out subset with addressing + void zeroOutSubset + ( + const labelList& addr + ); + + //- Add subset with addressing to field + void addSubset + ( + const CoeffField& f, + const labelList& addr + ); + + + // Member operators + + void operator=(const CoeffField&); + void operator=(const tmp >&); + + void operator=(const scalarTypeField&); + void operator=(const tmp&); + void operator=(const linearTypeField&); + void operator=(const tmp&); + void operator=(const squareTypeField&); + void operator=(const tmp&); + + + void operator+=(const CoeffField&); + void operator+=(const tmp >&); + + void operator+=(const scalarTypeField&); + void operator+=(const tmp&); + void operator+=(const linearTypeField&); + void operator+=(const tmp&); + void operator+=(const squareTypeField&); + void operator+=(const tmp&); + + void operator-=(const CoeffField&); + void operator-=(const tmp >&); + + void operator-=(const scalarTypeField&); + void operator-=(const tmp&); + void operator-=(const linearTypeField&); + void operator-=(const tmp&); + void operator-=(const squareTypeField&); + void operator-=(const tmp&); + + void operator*=(const UList&); + void operator*=(const tmp >&); + void operator*=(const scalar&); + + void operator/=(const UList&); + void operator/=(const tmp >&); + void operator/=(const scalar&); + + + // IOstream operators + + friend Ostream& operator<< + ( + Ostream&, + const CoeffField& + ); + + friend Ostream& operator<< + ( + Ostream&, + const tmp >& + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "CoeffFieldFunctions.H" + +#ifdef NoRepository +# include "CoeffField.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/CoeffField/CoeffFieldFunctions.C b/src/blockMatrix/CoeffField/CoeffFieldFunctions.C new file mode 100644 index 000000000..899c0137e --- /dev/null +++ b/src/blockMatrix/CoeffField/CoeffFieldFunctions.C @@ -0,0 +1,344 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 "BlockCoeff.H" + +/* * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * */ + +template +Foam::tmp > Foam::inv(const CoeffField& f) +{ + // The inverse of a linear coefficient type is currently done "by + // hand". The need for this will disappear once the diagonal tensor + // type is introduced. HJ, 24/May/2005 + + typedef typename CoeffField::linearTypeField fieldType; + typedef typename CoeffField::linearType valueType; + + // Create result + tmp > tresult(new CoeffField(f.size())); + CoeffField& result = tresult(); + + if (f.activeType() == blockCoeffBase::SCALAR) + { + result = 1.0/f.asScalar(); + } + else if (f.activeType() == blockCoeffBase::LINEAR) + { + const fieldType& lf = f.asLinear(); + + fieldType inverse = + cmptDivide + ( + fieldType(lf.size(), pTraits::one), + lf + ); + + result = inverse; + } + else if (f.activeType() == blockCoeffBase::SQUARE) + { + result = inv(f.asSquare()); + } + + return tresult; +} + + +template +void Foam::multiply +( + Field& f, + const CoeffField& f1, + const Type& f2 +) +{ + if (f1.activeType() == blockCoeffBase::SCALAR) + { + f = f1.asScalar()*f2; + } + else if (f1.activeType() == blockCoeffBase::LINEAR) + { + f = cmptMultiply(f1.asLinear(), f2); + } + else if (f1.activeType() == blockCoeffBase::SQUARE) + { + f = f1.asSquare() & f2; + } +} + + +template +void Foam::multiply +( + Field& f, + const CoeffField& f1, + const Field& f2 +) +{ + if (f1.activeType() == blockCoeffBase::SCALAR) + { + f = f1.asScalar()*f2; + } + else if (f1.activeType() == blockCoeffBase::LINEAR) + { + f = cmptMultiply(f1.asLinear(), f2); + } + else if (f1.activeType() == blockCoeffBase::SQUARE) + { + f = f1.asSquare() & f2; + } +} + + +template +void Foam::multiply +( + Field& f, + const Field& f1, + const CoeffField& f2 +) +{ + if (f2.activeType() == blockCoeffBase::SCALAR) + { + f = f1*f2.asScalar(); + } + else if (f2.activeType() == blockCoeffBase::LINEAR) + { + f = cmptMultiply(f1, f2.asLinear()); + } + else if (f2.activeType() == blockCoeffBase::SQUARE) + { + f = f1 & f2.asSquare(); + } +} + + +/* * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * */ + +#define UNARY_OPERATOR(op, opFunc) \ + \ +template \ +void Foam::opFunc \ +( \ + CoeffField& f, \ + const CoeffField& f1 \ +) \ +{ \ + typedef CoeffField TypeCoeffField; \ + \ + typedef typename TypeCoeffField::scalarTypeField scalarTypeField; \ + typedef typename TypeCoeffField::linearTypeField linearTypeField; \ + typedef typename TypeCoeffField::squareTypeField squareTypeField; \ + \ + if (f.activeType() == blockCoeffBase::SCALAR) \ + { \ + scalarTypeField sf = f1.asScalar(); \ + sf.opFunc(); \ + f = sf; \ + } \ + else if (f.activeType() == blockCoeffBase::LINEAR) \ + { \ + linearTypeField sf = f1.asLinear(); \ + sf.opFunc(); \ + f = sf; \ + } \ + else if (f.activeType() == blockCoeffBase::SQUARE) \ + { \ + squareTypeField sf = f1.asSquare(); \ + sf.opFunc(); \ + f = sf; \ + } \ +} \ + \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const CoeffField& f1 \ +) \ +{ \ + tmp > tf(new CoeffField(f1.size())); \ + opFunc(tf(), f1); \ + return tf; \ +} \ + \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const tmp >& tf1 \ +) \ +{ \ + tmp > tf(tf1.ptr()); \ + opFunc(tf(), tf()); \ + return tf; \ +} + +UNARY_OPERATOR(-, negate) + +#undef UNARY_OPERATOR + + +#define BINARY_OPERATOR_FF(Type1, Type2, op, opFunc) \ + \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const CoeffField& f1, \ + const Type2& f2 \ +) \ +{ \ + tmp > tf(new Field(f1.size())); \ + opFunc(tf(), f1, f2); \ + return tf; \ +} \ + \ + \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const CoeffField& f1, \ + const Field& f2 \ +) \ +{ \ + tmp > tf(new Field(f1.size())); \ + opFunc(tf(), f1, f2); \ + return tf; \ +} \ + \ + \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const Field& f1, \ + const CoeffField& f2 \ +) \ +{ \ + tmp > tf(new Field(f1.size())); \ + opFunc(tf(), f1, f2); \ + return tf; \ +} + +#define BINARY_OPERATOR_FTR(Type1, Type2, op, opFunc) \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const CoeffField& f1, \ + const tmp >& tf2 \ +) \ +{ \ + tmp > tf(tf2.ptr()); \ + opFunc(tf(), f1, tf()); \ + return tf; \ +} + +#define BINARY_OPERATOR_FT(Type1, Type2, op, opFunc) \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const Field& f1, \ + const tmp >& tf2 \ +) \ +{ \ + tmp > tf = f1 op tf2(); \ + tf2.clear(); \ + return tf; \ +} + +#define BINARY_OPERATOR_TRF(Type1, Type2, op, opFunc) \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const tmp >& tf1, \ + const Field& f2 \ +) \ +{ \ + tmp > tf(tf1.ptr()); \ + opFunc(tf(), tf(), f2); \ + return tf; \ +} + +#define BINARY_OPERATOR_TF(Type1, Type2, op, opFunc) \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const tmp >& tf1, \ + const Field& f2 \ +) \ +{ \ + tmp > tf = tf1() op f2; \ + tf1.clear(); \ + return tf; \ +} + +#define BINARY_OPERATOR_TRT(Type1, Type2, op, opFunc) \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const tmp >& tf1, \ + const tmp >& tf2 \ +) \ +{ \ + tmp > tf(tf1.ptr()); \ + opFunc(tf(), tf(), tf2()); \ + tf2.clear(); \ + return tf; \ +} + +#define BINARY_OPERATOR_TTR(Type1, Type2, op, opFunc) \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const tmp >& tf1, \ + const tmp >& tf2 \ +) \ +{ \ + tmp > tf(tf2.ptr()); \ + opFunc(tf(), tf1(), tf()); \ + tf1.clear(); \ + return tf; \ +} + +#define BINARY_OPERATOR_R(Type1, Type2, op, opFunc) \ + BINARY_OPERATOR_FF(Type1, Type2, op, opFunc) \ + BINARY_OPERATOR_FTR(Type1, Type2, op, opFunc) \ + BINARY_OPERATOR_TRF(Type1, Type2, op, opFunc) \ + BINARY_OPERATOR_TRT(Type1, Type2, op, opFunc) + +// Operator multiply is not available for all types, as it expands rank +// HJ, 17/Jun/2010 +// BINARY_OPERATOR_R(Type, Type, *, multiply) + +#undef BINARY_OPERATOR_R +#undef BINARY_OPERATOR_FF +#undef BINARY_OPERATOR_FTR +#undef BINARY_OPERATOR_TF +#undef BINARY_OPERATOR_TTR +#undef BINARY_OPERATOR_FT +#undef BINARY_OPERATOR_TRF +#undef BINARY_OPERATOR_TRT + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/blockMatrix/CoeffField/CoeffFieldFunctions.H b/src/blockMatrix/CoeffField/CoeffFieldFunctions.H new file mode 100644 index 000000000..7a4ebe396 --- /dev/null +++ b/src/blockMatrix/CoeffField/CoeffFieldFunctions.H @@ -0,0 +1,197 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 coefficient field type. + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/* * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * */ + +template +tmp > inv(const CoeffField& f); + + +template +void multiply +( + Field& f, + const CoeffField& f1, + const Type& f2 +); + + +template +void multiply +( + Field& f, + const CoeffField& f1, + const Field& f2 +); + + +template +void multiply +( + Field& f, + const Field& f1, + const CoeffField& f2 +); + + +/* * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * */ + +#define UNARY_OPERATOR(op, opFunc) \ + \ +template \ +void opFunc \ +( \ + CoeffField& f, \ + const CoeffField& f1 \ +); \ + \ +template \ +tmp > operator op \ +( \ + const CoeffField& f1 \ +); \ + \ +template \ +tmp > operator op \ +( \ + const tmp >& tf1 \ +); + +UNARY_OPERATOR(-, negate) + +#undef UNARY_OPERATOR + + +/* * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * */ + +#define BINARY_OPERATOR_FF(Type1, Type2, op, opFunc) \ + \ +template \ +tmp > operator op \ +( \ + const CoeffField& f1, \ + const Type2& f2 \ +); \ + \ + \ +template \ +tmp > operator op \ +( \ + const CoeffField& f1, \ + const Field& f2 \ +); \ + \ + \ +template \ +tmp > operator op \ +( \ + const Field& f1, \ + const CoeffField& f2 \ +); + + +#define BINARY_OPERATOR_FTR(Type1, Type2, op, opFunc) \ +template \ +tmp > operator op \ +( \ + const CoeffField& f1, \ + const tmp >& tf2 \ +); + +#define BINARY_OPERATOR_FT(Type1, Type2, op, opFunc) \ +template \ +tmp > operator op \ +( \ + const Field& f1, \ + const tmp >& tf2 \ +); + +#define BINARY_OPERATOR_TRF(Type1, Type2, op, opFunc) \ +template \ +tmp > operator op \ +( \ + const tmp >& tf1, \ + const CoeffField& f2 \ +); + +#define BINARY_OPERATOR_TF(Type1, Type2, op, opFunc) \ +template \ +tmp > operator op \ +( \ + const tmp >& tf1, \ + const Field& f2 \ +); + +#define BINARY_OPERATOR_TRT(Type1, Type2, op, opFunc) \ +template \ +tmp > operator op \ +( \ + const tmp >& tf1, \ + const tmp >& tf2 \ +); + +#define BINARY_OPERATOR_TTR(Type1, Type2, op, opFunc) \ +template \ +tmp > operator op \ +( \ + const tmp >& tf1, \ + const tmp >& tf2 \ +); + +#define BINARY_OPERATOR_R(Type1, Type2, op, opFunc) \ + BINARY_OPERATOR_FF(Type1, Type2, op, opFunc) \ + BINARY_OPERATOR_FTR(Type1, Type2, op, opFunc) \ + BINARY_OPERATOR_TRF(Type1, Type2, op, opFunc) \ + BINARY_OPERATOR_TRT(Type1, Type2, op, opFunc) + +BINARY_OPERATOR_R(Type, Type, *, multiply) + +#undef BINARY_OPERATOR_R +#undef BINARY_OPERATOR_FF +#undef BINARY_OPERATOR_FTR +#undef BINARY_OPERATOR_TF +#undef BINARY_OPERATOR_TTR +#undef BINARY_OPERATOR_FT +#undef BINARY_OPERATOR_TRF +#undef BINARY_OPERATOR_TRT + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/blockMatrix/CoeffField/DecoupledCoeffField.C b/src/blockMatrix/CoeffField/DecoupledCoeffField.C new file mode 100644 index 000000000..efab1e7fe --- /dev/null +++ b/src/blockMatrix/CoeffField/DecoupledCoeffField.C @@ -0,0 +1,1047 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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" +#include "expandTensorField.H" + +// * * * * * * * * * * * * * * * Static Members * * * * * * * * * * * * * * // + +template +const char* const +Foam::DecoupledCoeffField::typeName("DecoupledCoeffField"); + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template +template +inline void Foam::DecoupledCoeffField::checkSize +( + const UList& f +) const +{ + if (f.size() != this->size()) + { + FatalErrorIn + ( + "void DecoupledCoeffField::checkSize(" + "const Field& f) const" + ) << "Incorrect field size: " << f.size() + << " local size: " << size() + << abort(FatalError); + } +} + + +template +typename Foam::DecoupledCoeffField::scalarTypeField& +Foam::DecoupledCoeffField::toScalar() +{ + if (!scalarCoeffPtr_) + { + // Debug check: demotion + if (linearCoeffPtr_) + { + FatalErrorIn + ( + "DecoupledCoeffField::scalarTypeField& " + "DecoupledCoeffField::toScalar()" + ) << "Detected demotion to scalar. Probably an error" + << abort(FatalError); + } + + scalarCoeffPtr_ = + new scalarTypeField(size(), pTraits::zero); + } + + return *scalarCoeffPtr_; +} + + +template +typename Foam::DecoupledCoeffField::linearTypeField& +Foam::DecoupledCoeffField::toLinear() +{ + if (!linearCoeffPtr_) + { + linearCoeffPtr_ = + new linearTypeField(size(), pTraits::zero); + + // If scalar is active, promote to linear + if (scalarCoeffPtr_) + { + *linearCoeffPtr_ = (*scalarCoeffPtr_)*pTraits::one; + deleteDemandDrivenData(scalarCoeffPtr_); + } + } + + return *linearCoeffPtr_; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +Foam::DecoupledCoeffField::DecoupledCoeffField(const label size) +: + scalarCoeffPtr_(NULL), + linearCoeffPtr_(NULL), + size_(size) +{} + + +template +Foam::DecoupledCoeffField::DecoupledCoeffField +( + const DecoupledCoeffField& f +) +: + refCount(), + scalarCoeffPtr_(NULL), + linearCoeffPtr_(NULL), + size_(f.size()) +{ + if (f.scalarCoeffPtr_) + { + scalarCoeffPtr_ = new scalarTypeField(*(f.scalarCoeffPtr_)); + } + else if (f.linearCoeffPtr_) + { + linearCoeffPtr_ = new linearTypeField(*(f.linearCoeffPtr_)); + } +} + + +template +Foam::DecoupledCoeffField::DecoupledCoeffField(Istream& is) +: + scalarCoeffPtr_(NULL), + linearCoeffPtr_(NULL), + size_(0) +{ + // Read keyword and pick up allocated field + word key(is); + + if + ( + key + == blockCoeffBase::activeLevelNames_[blockCoeffBase::UNALLOCATED] + ) + { + size_ = readLabel(is); + } + else if + ( + key + == blockCoeffBase::activeLevelNames_[blockCoeffBase::SCALAR] + ) + { + scalarCoeffPtr_ = new scalarTypeField(is); + size_ = scalarCoeffPtr_->size(); + } + else if + ( + key + == blockCoeffBase::activeLevelNames_[blockCoeffBase::LINEAR] + ) + { + linearCoeffPtr_ = new linearTypeField(is); + size_ = linearCoeffPtr_->size(); + } + else + { + FatalIOErrorIn + ( + "DecoupledCoeffField::DecoupledCoeffField(Istream& is)", + is + ) << "invalid keyword while reading: " << key + << exit(FatalIOError); + } +} + + +template +Foam::tmp > +Foam::DecoupledCoeffField::clone() const +{ + return tmp > + ( + new DecoupledCoeffField(*this) + ); +} + + +// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // + +template +Foam::DecoupledCoeffField::~DecoupledCoeffField() +{ + this->clear(); +} + + +template +void Foam::DecoupledCoeffField::clear() +{ + deleteDemandDrivenData(scalarCoeffPtr_); + deleteDemandDrivenData(linearCoeffPtr_); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +inline Foam::label Foam::DecoupledCoeffField::size() const +{ + return size_; +} + + +template +void Foam::DecoupledCoeffField::negate() +{ + if (scalarCoeffPtr_) + { + scalarCoeffPtr_->negate(); + } + else if (linearCoeffPtr_) + { + linearCoeffPtr_->negate(); + } +} + + +template +Foam::tmp > +Foam::DecoupledCoeffField::transpose() const +{ + tmp > tt + ( + new DecoupledCoeffField(this->size()) + ); + DecoupledCoeffField& t = tt(); + + if (scalarCoeffPtr_) + { + t.toScalar() = *scalarCoeffPtr_; + } + else if (linearCoeffPtr_) + { + t.toLinear() = *linearCoeffPtr_; + } + else + { + // Not allocated - do nothing + } + + + return tt; +} + + +template +Foam::blockCoeffBase::activeLevel +Foam::DecoupledCoeffField::activeType() const +{ + if (scalarCoeffPtr_) + { + return blockCoeffBase::SCALAR; + } + else if (linearCoeffPtr_) + { + return blockCoeffBase::LINEAR; + } + else + { + return blockCoeffBase::UNALLOCATED; + } +} + + +template +void Foam::DecoupledCoeffField::checkActive() const +{ + label nActive = 0; + + if (scalarCoeffPtr_) nActive++; + if (linearCoeffPtr_) nActive++; + + if (nActive > 1) + { + FatalErrorIn + ( + "void Foam::DecoupledCoeffField::checkActive() const" + ) << "Activation/deactivation error. nActive = " << nActive + << abort(FatalError); + } +} + + +template +const typename Foam::DecoupledCoeffField::scalarTypeField& +Foam::DecoupledCoeffField::asScalar() const +{ + if (!scalarCoeffPtr_) + { + FatalErrorIn + ( + "DecoupledCoeffField::scalarTypeField& " + "DecoupledCoeffField::asScalar()" + ) << "Requested scalar but active type is: " + << blockCoeffBase::activeLevelNames_[this->activeType()] + << ". This is not allowed." + << abort(FatalError); + } + + return *scalarCoeffPtr_; +} + + +template +const typename Foam::DecoupledCoeffField::linearTypeField& +Foam::DecoupledCoeffField::asLinear() const +{ + if (!linearCoeffPtr_) + { + FatalErrorIn + ( + "DecoupledCoeffField::linearTypeField& " + "DecoupledCoeffField::asLinear()" + ) << "Requested linear but active type is: " + << blockCoeffBase::activeLevelNames_[this->activeType()] + << ". This is not allowed." + << abort(FatalError); + } + + return *linearCoeffPtr_; +} + + +template +typename Foam::DecoupledCoeffField::scalarTypeField& +Foam::DecoupledCoeffField::asScalar() +{ + if (linearCoeffPtr_) + { + FatalErrorIn + ( + "DecoupledCoeffField::scalarTypeField& " + "DecoupledCoeffField::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 +typename Foam::DecoupledCoeffField::linearTypeField& +Foam::DecoupledCoeffField::asLinear() +{ + if (!linearCoeffPtr_) + { + return this->toLinear(); + } + + return *linearCoeffPtr_; +} + + +template +Foam::tmp::scalarTypeField> +Foam::DecoupledCoeffField::component(const direction dir) const +{ + if (scalarCoeffPtr_) + { + return *scalarCoeffPtr_; + } + else if (linearCoeffPtr_) + { + return linearCoeffPtr_->component(dir); + } + else + { + FatalErrorIn + ( + "tmp::scalarTypeField>" + "DecoupledCoeffField::component(const direction dir) const" + ) << "Field not allocated." + << abort(FatalError); + } + + // Dummy return to keep compiler happy + return *scalarCoeffPtr_; +} + + +template +Foam::BlockCoeff +Foam::DecoupledCoeffField::getCoeff(const label index) const +{ + BlockCoeff result; + + if (scalarCoeffPtr_) + { + result.asScalar() = (*scalarCoeffPtr_)[index]; + } + else if (linearCoeffPtr_) + { + result.asLinear() = (*linearCoeffPtr_)[index]; + } + + return result; +} + + +template +void Foam::DecoupledCoeffField::setCoeff +( + const label index, + const BlockCoeff& coeff +) +{ + BlockCoeff result; + + if (coeff.activeType() == blockCoeffBase::SCALAR) + { + (*scalarCoeffPtr_)[index] = result.asScalar(); + } + else if (coeff.activeType() == blockCoeffBase::LINEAR) + { + (*linearCoeffPtr_)[index] = result.asLinear(); + } +} + + +template +void Foam::DecoupledCoeffField::getSubset +( + DecoupledCoeffField& f, + const label start, + const label size +) const +{ + // Check sizes + if (f.size() != size) + { + FatalErrorIn + ( + "template\n" + "void Foam::DecoupledCoeffField::getSubset\n" + "(\n" + " DecoupledCoeffField& f,\n" + " const label start,\n" + " const label size\n" + ") const" + ) << "Incompatible sizes: " << f.size() << " and " << size + << abort(FatalError); + } + + if (scalarCoeffPtr_) + { + scalarTypeField& ff = f.asScalar(); + + const scalarTypeField& localF = (*scalarCoeffPtr_); + + forAll (ff, ffI) + { + ff[ffI] = localF[start + ffI]; + } + } + else if (linearCoeffPtr_) + { + linearTypeField& ff = f.asLinear(); + + const linearTypeField& localF = (*linearCoeffPtr_); + + forAll (ff, ffI) + { + ff[ffI] = localF[start + ffI]; + } + } +} + + +template +void Foam::DecoupledCoeffField::getSubset +( + DecoupledCoeffField& f, + const labelList& addr +) const +{ + // Check sizes + if (f.size() != addr.size()) + { + FatalErrorIn + ( + "template\n" + "void Foam::DecoupledCoeffField::getSubset\n" + "(\n" + " DecoupledCoeffField& f,\n" + " const labelList addr\n" + ") const" + ) << "Incompatible sizes: " << f.size() << " and " << addr.size() + << abort(FatalError); + } + + if (scalarCoeffPtr_) + { + scalarTypeField& ff = f.asScalar(); + + const scalarTypeField& localF = (*scalarCoeffPtr_); + + forAll (ff, ffI) + { + ff[ffI] = localF[addr[ffI]]; + } + } + else if (linearCoeffPtr_) + { + linearTypeField& ff = f.asLinear(); + + const linearTypeField& localF = (*linearCoeffPtr_); + + forAll (ff, ffI) + { + ff[ffI] = localF[addr[ffI]]; + } + } +} + + +template +void Foam::DecoupledCoeffField::setSubset +( + const DecoupledCoeffField& f, + const label start, + const label size +) +{ + // Check sizes + if (f.size() != size) + { + FatalErrorIn + ( + "template\n" + "void Foam::DecoupledCoeffField::setSubset\n" + "(\n" + " const DecoupledCoeffField& f,\n" + " const label start,\n" + " const label size\n" + ")" + ) << "Incompatible sizes: " << f.size() << " and " << size + << abort(FatalError); + } + + if (f.activeType() == blockCoeffBase::SCALAR) + { + const scalarTypeField& ff = f.asScalar(); + + scalarTypeField& localF = this->asScalar(); + + forAll (ff, ffI) + { + localF[start + ffI] = ff[ffI]; + } + } + else if (f.activeType() == blockCoeffBase::LINEAR) + { + const linearTypeField& ff = f.asLinear(); + + linearTypeField& localF = this->asLinear(); + + forAll (ff, ffI) + { + localF[start + ffI] = ff[ffI]; + } + } +} + + +template +void Foam::DecoupledCoeffField::setSubset +( + const DecoupledCoeffField& f, + const labelList& addr +) +{ + // Check sizes + if (f.size() != addr.size()) + { + FatalErrorIn + ( + "template\n" + "void Foam::DecoupledCoeffField::setSubset\n" + "(\n" + " const DecoupledCoeffField& f,\n" + " const labelList addr\n" + ")" + ) << "Incompatible sizes: " << f.size() << " and " << addr.size() + << abort(FatalError); + } + + if (f.activeType() == blockCoeffBase::SCALAR) + { + const scalarTypeField& ff = f.asScalar(); + + scalarTypeField& localF = this->asScalar(); + + forAll (ff, ffI) + { + localF[addr[ffI]] = ff[ffI]; + } + } + else if (f.activeType() == blockCoeffBase::LINEAR) + { + const linearTypeField& ff = f.asLinear(); + + linearTypeField& localF = this->asLinear(); + + forAll (ff, ffI) + { + localF[addr[ffI]] = ff[ffI]; + } + } +} + + +template +void Foam::DecoupledCoeffField::zeroOutSubset +( + const label start, + const label size +) +{ + if (scalarCoeffPtr_) + { + scalarTypeField& localF = this->asScalar(); + + for (label ffI = 0; ffI < size; ffI++) + { + localF[start + ffI] = pTraits::zero; + } + } + else if (linearCoeffPtr_) + { + linearTypeField& localF = this->asLinear(); + + for (label ffI = 0; ffI < size; ffI++) + { + localF[start + ffI] = pTraits::zero; + } + } +} + + +template +void Foam::DecoupledCoeffField::zeroOutSubset +( + const labelList& addr +) +{ + if (scalarCoeffPtr_) + { + scalarTypeField& localF = this->asScalar(); + + forAll (addr, ffI) + { + localF[addr[ffI]] = pTraits::zero; + } + } + else if (linearCoeffPtr_) + { + linearTypeField& localF = this->asLinear(); + + forAll (addr, ffI) + { + localF[addr[ffI]] = pTraits::zero; + } + } +} + + +template +void Foam::DecoupledCoeffField::addSubset +( + const DecoupledCoeffField& f, + const labelList& addr +) +{ + // Check sizes + if (f.size() != addr.size()) + { + FatalErrorIn + ( + "template\n" + "void Foam::DecoupledCoeffField::addSubset\n" + "(\n" + " const DecoupledCoeffField& f,\n" + " const labelList addr\n" + ")" + ) << "Incompatible sizes: " << f.size() << " and " << addr.size() + << abort(FatalError); + } + + if + ( + f.activeType() == blockCoeffBase::LINEAR + || this->activeType() == blockCoeffBase::LINEAR + ) + { + const linearTypeField& ff = f.asLinear(); + + linearTypeField& localF = this->asLinear(); + + forAll (ff, ffI) + { + localF[addr[ffI]] += ff[ffI]; + } + } + else if + ( + f.activeType() == blockCoeffBase::SCALAR + && this->activeType() == blockCoeffBase::SCALAR + ) + { + const scalarTypeField& ff = f.asScalar(); + + scalarTypeField& localF = this->asScalar(); + + forAll (ff, ffI) + { + localF[addr[ffI]] += ff[ffI]; + } + } + else + { + FatalErrorIn + ( + "template\n" + "void Foam::DecoupledCoeffField::addSubset\n" + "(\n" + " const DecoupledCoeffField& f,\n" + " const labelList addr\n" + ")" + ) << "Incompatible combination of types" + << abort(FatalError); + } +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +template +void Foam::DecoupledCoeffField::operator= +( + const DecoupledCoeffField& f +) +{ + if (this == &f) + { + FatalErrorIn + ( + "DecoupledCoeffField::operator=(" + "const DecoupledCoeffField&)" + ) << "attempted assignment to self" + << abort(FatalError); + } + + // Check field sizes + if (f.size() != this->size()) + { + FatalErrorIn + ( + "DecoupledCoeffField::operator=(" + "const DecoupledCoeffField&)" + ) << "Incorrect field size: " << f.size() + << " local size: " << size() + << abort(FatalError); + } + + if (f.scalarCoeffPtr_) + { + this->toScalar() = *(f.scalarCoeffPtr_); + } + else if (f.linearCoeffPtr_) + { + this->toLinear() = *(f.linearCoeffPtr_); + } + else + { + // Not allocated - do nothing + } +} + + +template +void Foam::DecoupledCoeffField::operator= +( + const tmp& tf +) +{ + if (this == &(tf())) + { + FatalErrorIn + ( + "DecoupledCoeffField::operator=(" + "const tmp&)" + ) << "attempted assignment to self" + << abort(FatalError); + } + + operator=(tf()); + tf.clear(); +} + + +#define COMPUTED_BASE_ASSIGNMENT(op) \ + \ +template \ +void Foam::DecoupledCoeffField::operator op \ +( \ + const DecoupledCoeffField& f \ +) \ +{ \ + if (f.size() != this->size()) \ + { \ + FatalErrorIn \ + ( \ + "void DecoupledCoeffField::operator " \ + "op(const DecoupledCoeffField& f)" \ + ) << "Incorrect field size: " << f.size() \ + << " local size: " << size() \ + << abort(FatalError); \ + } \ + \ + \ + if (f.scalarCoeffPtr_) \ + { \ + this->toScalar() op *(f.scalarCoeffPtr_); \ + } \ + else if (f.linearCoeffPtr_) \ + { \ + this->toLinear() op *(f.linearCoeffPtr_); \ + } \ + else \ + { \ + } \ +} \ + \ +template \ +void Foam::DecoupledCoeffField::operator op \ +( \ + const tmp >& tf \ +) \ +{ \ + operator op(tf()); \ + tf.clear(); \ +} + + +#define COMPUTED_ARG_ASSIGNMENT(op) \ + \ +template \ +void Foam::DecoupledCoeffField::operator op(const scalarTypeField& f) \ +{ \ + checkSize(f); \ + \ + const blockCoeffBase::activeLevel al = this->activeType(); \ + \ + if (al == blockCoeffBase::UNALLOCATED || al == blockCoeffBase::SCALAR) \ + { \ + this->toScalar() op f; \ + } \ + else if (al == blockCoeffBase::LINEAR) \ + { \ + this->toLinear() op f*pTraits::one; \ + } \ + else \ + { \ + } \ +} \ + \ +template \ +void Foam::DecoupledCoeffField::operator op \ +( \ + const tmp& tf \ +) \ +{ \ + operator op(tf()); \ + tf.clear(); \ +} \ + \ + \ +template \ +void Foam::DecoupledCoeffField::operator op(const linearTypeField& f) \ +{ \ + checkSize(f); \ + \ + const blockCoeffBase::activeLevel al = this->activeType(); \ + \ + if \ + ( \ + al == blockCoeffBase::UNALLOCATED \ + || al == blockCoeffBase::SCALAR \ + || al == blockCoeffBase::LINEAR \ + ) \ + { \ + this->toLinear() op f; \ + } \ + else \ + { \ + } \ +} \ + \ +template \ +void Foam::DecoupledCoeffField::operator op \ +( \ + const tmp& tf \ +) \ +{ \ + operator op(tf()); \ + tf.clear(); \ +} \ + + +#define COMPUTED_BASE_OPERATOR(TYPE, op) \ + \ +template \ +void Foam::DecoupledCoeffField::operator op(const TYPE& t) \ +{ \ + if (scalarCoeffPtr_) \ + { \ + *(scalarCoeffPtr_) op t; \ + } \ + else if (linearCoeffPtr_) \ + { \ + *(linearCoeffPtr_) op t; \ + } \ + else \ + { \ + } \ +} \ + \ +template \ +void Foam::DecoupledCoeffField::operator op(const UList& tf) \ +{ \ + checkSize(tf); \ + \ + if (scalarCoeffPtr_) \ + { \ + *(scalarCoeffPtr_) op tf; \ + } \ + else if (linearCoeffPtr_) \ + { \ + *(linearCoeffPtr_) op tf; \ + } \ + else \ + { \ + } \ +} \ + \ +template \ +void Foam::DecoupledCoeffField::operator op \ +( \ + const tmp >& tf \ +) \ +{ \ + operator op(tf()); \ + tf.clear(); \ +} + + +#define COMPUTED_ASSIGNMENT(op) \ +COMPUTED_BASE_ASSIGNMENT(op) \ +COMPUTED_ARG_ASSIGNMENT(op) + +// Remaining operator= +COMPUTED_ARG_ASSIGNMENT(=) + +COMPUTED_ASSIGNMENT(+=) +COMPUTED_ASSIGNMENT(-=) + +COMPUTED_BASE_OPERATOR(scalar, *=) +COMPUTED_BASE_OPERATOR(scalar, /=) + +#undef COMPUTED_BASE_OPERATOR +#undef COMPUTED_BASE_ASSIGNMENT +#undef COMPUTED_ARG_ASSIGNMENT +#undef COMPUTED_ASSIGNMENT + + +// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * // + +template +Foam::Ostream& Foam::operator<<(Ostream& os, const DecoupledCoeffField& f) +{ + // Write active type + os << blockCoeffBase::activeLevelNames_[f.activeType()] << nl; + + if (f.activeType() == blockCoeffBase::SCALAR) + { + os << f.asScalar(); + } + else if (f.activeType() == blockCoeffBase::LINEAR) + { + os << f.asLinear(); + } + else + { + // Not allocated: write size + os << f.size(); + } + + return os; +} + + +template +Foam::Ostream& Foam::operator<< +( + Ostream& os, + const tmp >& tf +) +{ + os << tf(); + tf.clear(); + return os; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +# include "DecoupledCoeffFieldFunctions.C" + + +// ************************************************************************* // diff --git a/src/blockMatrix/CoeffField/DecoupledCoeffField.H b/src/blockMatrix/CoeffField/DecoupledCoeffField.H new file mode 100644 index 000000000..d3bda8aea --- /dev/null +++ b/src/blockMatrix/CoeffField/DecoupledCoeffField.H @@ -0,0 +1,310 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + DecoupledCoeffField + +Description + Generic coefficient field type. Used in BlockLduMatrix. HJ, 2/Apr/2005 + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + DecoupledCoeffField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef DecoupledCoeffField_H +#define DecoupledCoeffField_H + +#include "VectorSpace.H" +#include "primitiveFields.H" +#include "blockCoeffs.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * Forward declaration of template friend fuctions * * * * * * * // + +template +class DecoupledCoeffField; + +template +Ostream& operator<<(Ostream&, const DecoupledCoeffField&); + +template +Ostream& operator<<(Ostream&, const tmp >&); + + +/*---------------------------------------------------------------------------*\ + Class DecoupledCoeffField Declaration +\*---------------------------------------------------------------------------*/ + +template +class DecoupledCoeffField +: + public refCount +{ +public: + + // Public data types + + //- Component type + typedef typename BlockCoeff::scalarType scalarType; + typedef typename BlockCoeff::linearType linearType; + + //- Field type + typedef typename BlockCoeff::scalarTypeField scalarTypeField; + typedef typename BlockCoeff::linearTypeField linearTypeField; + + +private: + + // Private data + + //- Scalar coefficient + mutable scalarTypeField* scalarCoeffPtr_; + + //- Linear coefficient + mutable linearTypeField* linearCoeffPtr_; + + //- Number of elements + label size_; + + + // Private Member Functions + + //- Check size for arithmetic operations: resizing is not allowed! + template + inline void checkSize(const UList&) const; + + //- Promote to scalar + scalarTypeField& toScalar(); + + //- Promote to linear + linearTypeField& toLinear(); + + +public: + + // Static data members + + static const char* const typeName; + + + // Constructors + + //- Construct given size + explicit DecoupledCoeffField(const label); + + //- Construct as copy + DecoupledCoeffField(const DecoupledCoeffField&); + + //- Construct from Istream + explicit DecoupledCoeffField(Istream&); + + //- Clone + tmp > clone() const; + + + // Destructor + + ~DecoupledCoeffField(); + + //- Clear data + void clear(); + + + // Member functions + + //- Return size + inline label size() const; + + //- Return active type + blockCoeffBase::activeLevel activeType() const; + + //- Check pointers: only one type should be active (debug only) + void checkActive() const; + + //- Negate this field + void negate(); + + //- Return the field transpose + tmp > transpose() const; + + + // Return as typed. Fails when asked for the incorrect type + + //- Return as scalar field + const scalarTypeField& asScalar() const; + + //- Return as linear field + const linearTypeField& asLinear() const; + + + // Return as typed. Fails when asked for demotion + + //- Return as scalar field + scalarTypeField& asScalar(); + + //- Return as linear field + linearTypeField& asLinear(); + + + //- Return component + tmp component(const direction) const; + + //- Return coefficient as block + BlockCoeff getCoeff(const label index) const; + + //- Set coefficient from a block + void setCoeff(const label index, const BlockCoeff& coeff); + + + // Subset operations + + //- Get subset with offset and size and store in given field + void getSubset + ( + DecoupledCoeffField& f, + const label start, + const label size + ) const; + + //- Get subset with addressing and store in given field + void getSubset + ( + DecoupledCoeffField& f, + const labelList& addr + ) const; + + + //- Set subset with offset and size from given field + void setSubset + ( + const DecoupledCoeffField& f, + const label start, + const label size + ); + + //- Get subset with addressing and store in target field + void setSubset + ( + const DecoupledCoeffField& f, + const labelList& addr + ); + + //- Zero out subset with offset and size + void zeroOutSubset + ( + const label start, + const label size + ); + + //- Zero out subset with addressing + void zeroOutSubset + ( + const labelList& addr + ); + + //- Add subset with addressing to field + void addSubset + ( + const DecoupledCoeffField& f, + const labelList& addr + ); + + + // Member operators + + void operator=(const DecoupledCoeffField&); + void operator=(const tmp >&); + + void operator=(const scalarTypeField&); + void operator=(const tmp&); + void operator=(const linearTypeField&); + void operator=(const tmp&); + + + void operator+=(const DecoupledCoeffField&); + void operator+=(const tmp >&); + + void operator+=(const scalarTypeField&); + void operator+=(const tmp&); + void operator+=(const linearTypeField&); + void operator+=(const tmp&); + + void operator-=(const DecoupledCoeffField&); + void operator-=(const tmp >&); + + void operator-=(const scalarTypeField&); + void operator-=(const tmp&); + void operator-=(const linearTypeField&); + void operator-=(const tmp&); + + void operator*=(const UList&); + void operator*=(const tmp >&); + void operator*=(const scalar&); + + void operator/=(const UList&); + void operator/=(const tmp >&); + void operator/=(const scalar&); + + + // IOstream operators + + friend Ostream& operator<< + ( + Ostream&, + const DecoupledCoeffField& + ); + + friend Ostream& operator<< + ( + Ostream&, + const tmp >& + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "DecoupledCoeffFieldFunctions.H" + +#ifdef NoRepository +# include "DecoupledCoeffField.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/CoeffField/DecoupledCoeffFieldFunctions.C b/src/blockMatrix/CoeffField/DecoupledCoeffFieldFunctions.C new file mode 100644 index 000000000..bfa1123aa --- /dev/null +++ b/src/blockMatrix/CoeffField/DecoupledCoeffFieldFunctions.C @@ -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 "BlockCoeff.H" + +/* * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * */ + +template +Foam::tmp > Foam::inv +( + const DecoupledCoeffField& f +) +{ + // The inverse of a linear coefficient type is currently done "by + // hand". The need for this will disappear once the diagonal tensor + // type is introduced. HJ, 24/May/2005 + + typedef typename DecoupledCoeffField::linearTypeField fieldType; + typedef typename DecoupledCoeffField::linearType valueType; + + // Create result + tmp > tresult + ( + new DecoupledCoeffField(f.size()) + ); + DecoupledCoeffField& result = tresult(); + + if (f.activeType() == blockCoeffBase::SCALAR) + { + result = 1.0/f.asScalar(); + } + else if (f.activeType() == blockCoeffBase::LINEAR) + { + const fieldType& lf = f.asLinear(); + + fieldType inverse = + cmptDivide + ( + fieldType(lf.size(), pTraits::one), + lf + ); + + result = inverse; + } + + return tresult; +} + + +template +void Foam::multiply +( + Field& f, + const DecoupledCoeffField& f1, + const Type& f2 +) +{ + if (f1.activeType() == blockCoeffBase::SCALAR) + { + f = f1.asScalar()*f2; + } + else if (f1.activeType() == blockCoeffBase::LINEAR) + { + f = cmptMultiply(f1.asLinear(), f2); + } +} + + +template +void Foam::multiply +( + Field& f, + const DecoupledCoeffField& f1, + const Field& f2 +) +{ + if (f1.activeType() == blockCoeffBase::SCALAR) + { + f = f1.asScalar()*f2; + } + else if (f1.activeType() == blockCoeffBase::LINEAR) + { + f = cmptMultiply(f1.asLinear(), f2); + } +} + + +template +void Foam::multiply +( + Field& f, + const Field& f1, + const DecoupledCoeffField& f2 +) +{ + if (f2.activeType() == blockCoeffBase::SCALAR) + { + f = f1*f2.asScalar(); + } + else if (f2.activeType() == blockCoeffBase::LINEAR) + { + f = cmptMultiply(f1, f2.asLinear()); + } +} + + +/* * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * */ + +#define UNARY_OPERATOR(op, opFunc) \ + \ +template \ +void Foam::opFunc \ +( \ + DecoupledCoeffField& f, \ + const DecoupledCoeffField& f1 \ +) \ +{ \ + typedef DecoupledCoeffField TypeDecoupledCoeffField; \ + \ + typedef typename TypeDecoupledCoeffField::scalarTypeField scalarTypeField;\ + typedef typename TypeDecoupledCoeffField::linearTypeField linearTypeField;\ + \ + if (f.activeType() == blockCoeffBase::SCALAR) \ + { \ + scalarTypeField sf = f1.asScalar(); \ + sf.opFunc(); \ + f = sf; \ + } \ + else if (f.activeType() == blockCoeffBase::LINEAR) \ + { \ + linearTypeField sf = f1.asLinear(); \ + sf.opFunc(); \ + f = sf; \ + } \ +} \ + \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const DecoupledCoeffField& f1 \ +) \ +{ \ + tmp > tf \ + ( \ + new DecoupledCoeffField(f1.size()) \ + ); \ + opFunc(tf(), f1); \ + return tf; \ +} \ + \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const tmp >& tf1 \ +) \ +{ \ + tmp > tf(tf1.ptr()); \ + opFunc(tf(), tf()); \ + return tf; \ +} + +UNARY_OPERATOR(-, negate) + +#undef UNARY_OPERATOR + + +#define BINARY_OPERATOR_FF(Type1, Type2, op, opFunc) \ + \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const DecoupledCoeffField& f1, \ + const Type2& f2 \ +) \ +{ \ + tmp > tf(new Field(f1.size())); \ + opFunc(tf(), f1, f2); \ + return tf; \ +} \ + \ + \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const DecoupledCoeffField& f1, \ + const Field& f2 \ +) \ +{ \ + tmp > tf(new Field(f1.size())); \ + opFunc(tf(), f1, f2); \ + return tf; \ +} \ + \ + \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const Field& f1, \ + const DecoupledCoeffField& f2 \ +) \ +{ \ + tmp > tf(new Field(f1.size())); \ + opFunc(tf(), f1, f2); \ + return tf; \ +} + +#define BINARY_OPERATOR_FTR(Type1, Type2, op, opFunc) \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const DecoupledCoeffField& f1, \ + const tmp >& tf2 \ +) \ +{ \ + tmp > tf(tf2.ptr()); \ + opFunc(tf(), f1, tf()); \ + return tf; \ +} + +#define BINARY_OPERATOR_FT(Type1, Type2, op, opFunc) \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const Field& f1, \ + const tmp >& tf2 \ +) \ +{ \ + tmp > tf = f1 op tf2(); \ + tf2.clear(); \ + return tf; \ +} + +#define BINARY_OPERATOR_TRF(Type1, Type2, op, opFunc) \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const tmp >& tf1, \ + const Field& f2 \ +) \ +{ \ + tmp > tf(tf1.ptr()); \ + opFunc(tf(), tf(), f2); \ + return tf; \ +} + +#define BINARY_OPERATOR_TF(Type1, Type2, op, opFunc) \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const tmp >& tf1, \ + const Field& f2 \ +) \ +{ \ + tmp > tf = tf1() op f2; \ + tf1.clear(); \ + return tf; \ +} + +#define BINARY_OPERATOR_TRT(Type1, Type2, op, opFunc) \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const tmp >& tf1, \ + const tmp >& tf2 \ +) \ +{ \ + tmp > tf(tf1.ptr()); \ + opFunc(tf(), tf(), tf2()); \ + tf2.clear(); \ + return tf; \ +} + +#define BINARY_OPERATOR_TTR(Type1, Type2, op, opFunc) \ +template \ +Foam::tmp > Foam::operator op \ +( \ + const tmp >& tf1, \ + const tmp >& tf2 \ +) \ +{ \ + tmp > tf(tf2.ptr()); \ + opFunc(tf(), tf1(), tf()); \ + tf1.clear(); \ + return tf; \ +} + +#define BINARY_OPERATOR_R(Type1, Type2, op, opFunc) \ + BINARY_OPERATOR_FF(Type1, Type2, op, opFunc) \ + BINARY_OPERATOR_FTR(Type1, Type2, op, opFunc) \ + BINARY_OPERATOR_TRF(Type1, Type2, op, opFunc) \ + BINARY_OPERATOR_TRT(Type1, Type2, op, opFunc) + +// BINARY_OPERATOR_R(Type, Type, *, multiply) + +#undef BINARY_OPERATOR_R +#undef BINARY_OPERATOR_FF +#undef BINARY_OPERATOR_FTR +#undef BINARY_OPERATOR_TF +#undef BINARY_OPERATOR_TTR +#undef BINARY_OPERATOR_FT +#undef BINARY_OPERATOR_TRF +#undef BINARY_OPERATOR_TRT + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/blockMatrix/CoeffField/DecoupledCoeffFieldFunctions.H b/src/blockMatrix/CoeffField/DecoupledCoeffFieldFunctions.H new file mode 100644 index 000000000..c2ed4fdd7 --- /dev/null +++ b/src/blockMatrix/CoeffField/DecoupledCoeffFieldFunctions.H @@ -0,0 +1,197 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 coefficient field type. + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved. + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/* * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * */ + +template +tmp > inv(const DecoupledCoeffField& f); + + +template +void multiply +( + Field& f, + const DecoupledCoeffField& f1, + const Type& f2 +); + + +template +void multiply +( + Field& f, + const DecoupledCoeffField& f1, + const Field& f2 +); + + +template +void multiply +( + Field& f, + const Field& f1, + const DecoupledCoeffField& f2 +); + + +/* * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * */ + +#define UNARY_OPERATOR(op, opFunc) \ + \ +template \ +void opFunc \ +( \ + DecoupledCoeffField& f, \ + const DecoupledCoeffField& f1 \ +); \ + \ +template \ +tmp > operator op \ +( \ + const DecoupledCoeffField& f1 \ +); \ + \ +template \ +tmp > operator op \ +( \ + const tmp >& tf1 \ +); + +UNARY_OPERATOR(-, negate) + +#undef UNARY_OPERATOR + + +/* * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * */ + +#define BINARY_OPERATOR_FF(Type1, Type2, op, opFunc) \ + \ +template \ +tmp > operator op \ +( \ + const DecoupledCoeffField& f1, \ + const Type2& f2 \ +); \ + \ + \ +template \ +tmp > operator op \ +( \ + const DecoupledCoeffField& f1, \ + const Field& f2 \ +); \ + \ + \ +template \ +tmp > operator op \ +( \ + const Field& f1, \ + const DecoupledCoeffField& f2 \ +); + + +#define BINARY_OPERATOR_FTR(Type1, Type2, op, opFunc) \ +template \ +tmp > operator op \ +( \ + const DecoupledCoeffField& f1, \ + const tmp >& tf2 \ +); + +#define BINARY_OPERATOR_FT(Type1, Type2, op, opFunc) \ +template \ +tmp > operator op \ +( \ + const Field& f1, \ + const tmp >& tf2 \ +); + +#define BINARY_OPERATOR_TRF(Type1, Type2, op, opFunc) \ +template \ +tmp > operator op \ +( \ + const tmp >& tf1, \ + const DecoupledCoeffField& f2 \ +); + +#define BINARY_OPERATOR_TF(Type1, Type2, op, opFunc) \ +template \ +tmp > operator op \ +( \ + const tmp >& tf1, \ + const Field& f2 \ +); + +#define BINARY_OPERATOR_TRT(Type1, Type2, op, opFunc) \ +template \ +tmp > operator op \ +( \ + const tmp >& tf1, \ + const tmp >& tf2 \ +); + +#define BINARY_OPERATOR_TTR(Type1, Type2, op, opFunc) \ +template \ +tmp > operator op \ +( \ + const tmp >& tf1, \ + const tmp >& tf2 \ +); + +#define BINARY_OPERATOR_R(Type1, Type2, op, opFunc) \ + BINARY_OPERATOR_FF(Type1, Type2, op, opFunc) \ + BINARY_OPERATOR_FTR(Type1, Type2, op, opFunc) \ + BINARY_OPERATOR_TRF(Type1, Type2, op, opFunc) \ + BINARY_OPERATOR_TRT(Type1, Type2, op, opFunc) + +BINARY_OPERATOR_R(Type, Type, *, multiply) + +#undef BINARY_OPERATOR_R +#undef BINARY_OPERATOR_FF +#undef BINARY_OPERATOR_FTR +#undef BINARY_OPERATOR_TF +#undef BINARY_OPERATOR_TTR +#undef BINARY_OPERATOR_FT +#undef BINARY_OPERATOR_TRF +#undef BINARY_OPERATOR_TRT + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/blockMatrix/CoeffField/coeffFields.H b/src/blockMatrix/CoeffField/coeffFields.H new file mode 100644 index 000000000..f4baba1db --- /dev/null +++ b/src/blockMatrix/CoeffField/coeffFields.H @@ -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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Class + coeffFields + +Description + Typedefs for coefficient field + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved. + +\*---------------------------------------------------------------------------*/ + +#ifndef coeffFields_H +#define coeffFields_H + +#include "scalarCoeffField.H" +#include "sphericalTensorCoeffField.H" +#include "symmTensorCoeffField.H" +#include "tensorCoeffField.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +typedef CoeffField scalarCoeffField; +typedef CoeffField vectorCoeffField; +typedef CoeffField sphericalTensorCoeffField; +typedef CoeffField symmTensorCoeffField; +typedef CoeffField tensorCoeffField; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/CoeffField/scalarCoeffField.C b/src/blockMatrix/CoeffField/scalarCoeffField.C new file mode 100644 index 000000000..1b7b17c52 --- /dev/null +++ b/src/blockMatrix/CoeffField/scalarCoeffField.C @@ -0,0 +1,383 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + scalarCoeffField + +Description + +\*---------------------------------------------------------------------------*/ + +#include "scalarCoeffField.H" + +// * * * * * * * * * * * * * * * Static Members * * * * * * * * * * * * * * // + +const char* const Foam::CoeffField::typeName("CoeffField"); + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::blockCoeffBase::activeLevel +Foam::CoeffField::activeType() const +{ + return blockCoeffBase::SCALAR; +} + + +Foam::tmp > +Foam::CoeffField::transpose() const +{ + return tmp >(new CoeffField(*this)); +} + + +const Foam::scalarField& +Foam::CoeffField::asScalar() const +{ + return *this; +} + + +Foam::scalarField& +Foam::CoeffField::asScalar() +{ + return *this; +} + + +const Foam::scalarField& +Foam::CoeffField::asLinear() const +{ + return *this; +} + + +Foam::scalarField& +Foam::CoeffField::asLinear() +{ + return *this; +} + + +Foam::BlockCoeff +Foam::CoeffField::getCoeff(const label index) const +{ + BlockCoeff result; + + result.asScalar() = (operator[](index)); + + return result; +} + + +void Foam::CoeffField::setCoeff +( + const label index, + const BlockCoeff& coeff +) +{ + operator[](index) = coeff.asScalar(); +} + + +void Foam::CoeffField::getSubset +( + CoeffField& f, + const label start, + const label size +) const +{ + // Check sizes + if (f.size() != size) + { + FatalErrorIn + ( + "void Foam::CoeffField::getSubset\n" + "(\n" + " CoeffField& f,\n" + " const label start,\n" + " const label size\n" + ") const" + ) << "Incompatible sizes: " << f.size() << " and " << size + << abort(FatalError); + } + + const scalarField& localF = *this; + + forAll (f, fI) + { + f[fI] = localF[start + fI]; + } +} + + +void Foam::CoeffField::getSubset +( + CoeffField& f, + const labelList& addr +) const +{ + // Check sizes + if (f.size() != addr.size()) + { + FatalErrorIn + ( + "void Foam::CoeffField::getSubset\n" + "(\n" + " CoeffField& f,\n" + " const labelList addr\n" + ") const" + ) << "Incompatible sizes: " << f.size() << " and " << addr.size() + << abort(FatalError); + } + + const scalarField& localF = *this; + + forAll (f, fI) + { + f[fI] = localF[addr[fI]]; + } +} + + +void Foam::CoeffField::setSubset +( + const CoeffField& f, + const label start, + const label size +) +{ + // Check sizes + if (f.size() != size) + { + FatalErrorIn + ( + "void Foam::CoeffField::setSubset\n" + "(\n" + " const CoeffField& f,\n" + " const label start,\n" + " const label size\n" + ")" + ) << "Incompatible sizes: " << f.size() << " and " << size + << abort(FatalError); + } + + scalarField& localF = *this; + + forAll (f, fI) + { + localF[start + fI] = f[fI]; + } +} + + +void Foam::CoeffField::setSubset +( + const CoeffField& f, + const labelList& addr +) +{ + // Check sizes + if (f.size() != addr.size()) + { + FatalErrorIn + ( + "void Foam::CoeffField::setSubset\n" + "(\n" + " const CoeffField& f,\n" + " const labelList addr\n" + ")" + ) << "Incompatible sizes: " << f.size() << " and " << addr.size() + << abort(FatalError); + } + + scalarField& localF = this->asScalar(); + + forAll (f, fI) + { + localF[addr[fI]] = f[fI]; + } +} + + +void Foam::CoeffField::zeroOutSubset +( + const label start, + const label size +) +{ + scalarField& localF = *this; + + for (label ffI = 0; ffI < size; ffI++) + { + localF[start + ffI] = pTraits::zero; + } +} + + +void Foam::CoeffField::zeroOutSubset +( + const labelList& addr +) +{ + scalarField& localF = *this; + + forAll (addr, ffI) + { + localF[addr[ffI]] = pTraits::zero; + } +} + + +void Foam::CoeffField::addSubset +( + const CoeffField& f, + const labelList& addr +) +{ + // Check sizes + if (f.size() != addr.size()) + { + FatalErrorIn + ( + "void Foam::CoeffField::addSubset\n" + "(\n" + " const CoeffField& f,\n" + " const labelList addr\n" + ")" + ) << "Incompatible sizes: " << f.size() << " and " << addr.size() + << abort(FatalError); + } + + scalarField& localF = this->asScalar(); + + forAll (f, fI) + { + localF[addr[fI]] += f[fI]; + } +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +void Foam::CoeffField::operator=(const scalarField& f) +{ + scalarField::operator=(f); +} + + +void Foam::CoeffField::operator=(const tmp& tf) +{ + scalarField::operator=(tf); +} + + +// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * // + +Foam::Ostream& Foam::operator<<(Ostream& os, const CoeffField& f) +{ + os << static_cast(f); + + return os; +} + + +Foam::Ostream& Foam::operator<< +( + Ostream& os, + const tmp >& tf +) +{ + os << tf(); + tf.clear(); + return os; +} + + +/* * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * */ + +template<> +Foam::tmp > +Foam::inv(const CoeffField& f) +{ + tmp > tresult(new CoeffField(f.size())); + scalarField& result = tresult(); + result = 1.0/f; + + return tresult; +} + + +template<> +void Foam::negate +( + CoeffField& f, + const CoeffField& f1 +) +{ + f = f1; + f.negate(); +} + + +template<> +void Foam::multiply +( + scalarField& f, + const CoeffField& f1, + const scalar& f2 +) +{ + const scalarField& sf = f1; + f = sf*f2; +} + + +template<> +void Foam::multiply +( + scalarField& f, + const CoeffField& f1, + const scalarField& f2 +) +{ + const scalarField& sf = f1; + f = sf*f2; +} + + +template<> +void Foam::multiply +( + scalarField& f, + const scalarField& f1, + const CoeffField& f2 +) +{ + const scalarField& sf = f2; + f = f1*sf; +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/CoeffField/scalarCoeffField.H b/src/blockMatrix/CoeffField/scalarCoeffField.H new file mode 100644 index 000000000..a11c5852f --- /dev/null +++ b/src/blockMatrix/CoeffField/scalarCoeffField.H @@ -0,0 +1,245 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + CoeffField + +Description + Template specialisation for scalar coefficients + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved. + +SourceFiles + tensorCoeffField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef scalarCoeffField_H +#define scalarCoeffField_H + +#include "CoeffField.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +template<> +class CoeffField +: + public scalarField +{ +public: + + // Public data types + + //- Component type + typedef scalar scalarType; + typedef scalar linearType; + + //- Field type + typedef scalarField scalarTypeField; + typedef scalarField linearTypeField; + + + // Static data members + + static const char* const typeName; + + + // Constructors + + //- Construct given size + explicit CoeffField(const label size) + : + scalarField(size, pTraits::zero) + {} + + //- Construct as copy + CoeffField(const CoeffField& f) + : + scalarField(f) + {} + + //- Construct from Istream + CoeffField(Istream& is) + : + scalarField(is) + {} + + + // Member functions + + //- Return active type + blockCoeffBase::activeLevel activeType() const; + + //- Return the field transpose + tmp > transpose() const; + + + // Return as typed. Fails when asked for the incorrect type + + //- Return as scalar field + const scalarField& asScalar() const; + scalarField& asScalar(); + + //- Return as linear field. Equal to scalar field + const scalarField& asLinear() const; + scalarField& asLinear(); + + + //- Return coefficient as a block + BlockCoeff getCoeff(const label index) const; + + //- Set coefficient from a block + void setCoeff(const label index, const BlockCoeff& coeff); + + + // Subset operations + + //- Get subset with offset and size and store in given field + void getSubset + ( + CoeffField& f, + const label start, + const label size + ) const; + + //- Get subset with addressing and store in given field + void getSubset + ( + CoeffField& f, + const labelList& addr + ) const; + + + //- Set subset with offset and size from given field + void setSubset + ( + const CoeffField& f, + const label start, + const label size + ); + + //- Get subset with addressing and store in target field + void setSubset + ( + const CoeffField& f, + const labelList& addr + ); + + //- Zero out subset with offset and size + void zeroOutSubset + ( + const label start, + const label size + ); + + //- Zero out subset with addressing + void zeroOutSubset + ( + const labelList& addr + ); + + //- Add subset with addressing to field + void addSubset + ( + const CoeffField& f, + const labelList& addr + ); + + + // Member operators + + void operator=(const scalarField&); + void operator=(const tmp&); + + + // IOstream operators + + friend Ostream& operator<< + ( + Ostream&, + const CoeffField& + ); + + friend Ostream& operator<< + ( + Ostream&, + const tmp >& + ); +}; + + +/* * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * */ + +template<> +tmp > inv(const CoeffField& f); + + +template<> +void negate +( + CoeffField& f, + const CoeffField& f1 +); + + +template<> +void multiply +( + scalarField& f, + const CoeffField& f1, + const scalar& f2 +); + + +template<> +void multiply +( + scalarField& f, + const CoeffField& f1, + const scalarField& f2 +); + + +template<> +void multiply +( + scalarField& f, + const scalarField& f1, + const CoeffField& f2 +); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/CoeffField/sphericalTensorCoeffField.C b/src/blockMatrix/CoeffField/sphericalTensorCoeffField.C new file mode 100644 index 000000000..fab13e923 --- /dev/null +++ b/src/blockMatrix/CoeffField/sphericalTensorCoeffField.C @@ -0,0 +1,142 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 "sphericalTensorCoeffField.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::CoeffField::CoeffField(const label size) +: + DecoupledCoeffField(size) +{} + + +Foam::CoeffField::CoeffField +( + const CoeffField& f +) +: + DecoupledCoeffField(f) +{} + + +Foam::CoeffField::CoeffField +( + const DecoupledCoeffField& f +) +: + DecoupledCoeffField(f) +{} + + +Foam::CoeffField::CoeffField +( + const tmp >& tf +) +: + DecoupledCoeffField(tf()) +{} + + +Foam::CoeffField::CoeffField(Istream& is) +: + DecoupledCoeffField(is) +{} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +void Foam::CoeffField::operator= +( + const CoeffField& f +) +{ + DecoupledCoeffField::operator=(f); +} + + +void Foam::CoeffField::operator= +( + const tmp >& f +) +{ + DecoupledCoeffField::operator=(f); +} + + +void Foam::CoeffField::operator= +( + const CoeffField::scalarTypeField& f +) +{ + DecoupledCoeffField::operator=(f); +} + + +void Foam::CoeffField::operator= +( + const tmp::scalarTypeField>& f +) +{ + DecoupledCoeffField::operator=(f); +} + + +void Foam::CoeffField::operator= +( + const CoeffField::linearTypeField& f +) +{ + DecoupledCoeffField::operator=(f); +} + + +void Foam::CoeffField::operator= +( + const tmp::linearTypeField>& f +) +{ + DecoupledCoeffField::operator=(f); +} + + +/* * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * */ + +Foam::tmp > Foam::inv +( + const CoeffField& f +) +{ + const DecoupledCoeffField& df = f; + + return tmp > + ( + new CoeffField(inv(df)()) + ); +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/CoeffField/sphericalTensorCoeffField.H b/src/blockMatrix/CoeffField/sphericalTensorCoeffField.H new file mode 100644 index 000000000..fc991a133 --- /dev/null +++ b/src/blockMatrix/CoeffField/sphericalTensorCoeffField.H @@ -0,0 +1,102 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + CoeffField + +Description + Template specialisation for sphericalTensor coefficients + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved. + +SourceFiles + sphericalTensorCoeffField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef sphericalTensorCoeffField_H +#define sphericalTensorCoeffField_H + +#include "CoeffField.H" +#include "DecoupledCoeffField.H" +#include "sphericalTensor.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +template<> +class CoeffField +: + public DecoupledCoeffField +{ +public: + + // Constructors + + //- Construct given size + explicit CoeffField(const label); + + //- Construct as copy + CoeffField(const CoeffField&); + + //- Construct as copy of base + explicit CoeffField(const DecoupledCoeffField&); + + //- Construct as copy of base + explicit CoeffField(const tmp >&); + + //- Construct from Istream + explicit CoeffField(Istream&); + + + // Member operators + + void operator=(const CoeffField&); + void operator=(const tmp >&); + + void operator=(const scalarTypeField&); + void operator=(const tmp&); + void operator=(const linearTypeField&); + void operator=(const tmp&); + +}; + + +/* * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * */ + +tmp > inv(const CoeffField& f); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/CoeffField/symmTensorCoeffField.C b/src/blockMatrix/CoeffField/symmTensorCoeffField.C new file mode 100644 index 000000000..a53826d8c --- /dev/null +++ b/src/blockMatrix/CoeffField/symmTensorCoeffField.C @@ -0,0 +1,142 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 "symmTensorCoeffField.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::CoeffField::CoeffField(const label size) +: + DecoupledCoeffField(size) +{} + + +Foam::CoeffField::CoeffField +( + const CoeffField& f +) +: + DecoupledCoeffField(f) +{} + + +Foam::CoeffField::CoeffField +( + const DecoupledCoeffField& f +) +: + DecoupledCoeffField(f) +{} + + +Foam::CoeffField::CoeffField +( + const tmp >& tf +) +: + DecoupledCoeffField(tf()) +{} + + +Foam::CoeffField::CoeffField(Istream& is) +: + DecoupledCoeffField(is) +{} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +void Foam::CoeffField::operator= +( + const CoeffField& f +) +{ + DecoupledCoeffField::operator=(f); +} + + +void Foam::CoeffField::operator= +( + const tmp >& f +) +{ + DecoupledCoeffField::operator=(f); +} + + +void Foam::CoeffField::operator= +( + const CoeffField::scalarTypeField& f +) +{ + DecoupledCoeffField::operator=(f); +} + + +void Foam::CoeffField::operator= +( + const tmp::scalarTypeField>& f +) +{ + DecoupledCoeffField::operator=(f); +} + + +void Foam::CoeffField::operator= +( + const CoeffField::linearTypeField& f +) +{ + DecoupledCoeffField::operator=(f); +} + + +void Foam::CoeffField::operator= +( + const tmp::linearTypeField>& f +) +{ + DecoupledCoeffField::operator=(f); +} + + +/* * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * */ + +Foam::tmp > Foam::inv +( + const CoeffField& f +) +{ + const DecoupledCoeffField& df = f; + + return tmp > + ( + new CoeffField(inv(df)()) + ); +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/CoeffField/symmTensorCoeffField.H b/src/blockMatrix/CoeffField/symmTensorCoeffField.H new file mode 100644 index 000000000..bb111b1fc --- /dev/null +++ b/src/blockMatrix/CoeffField/symmTensorCoeffField.H @@ -0,0 +1,102 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + CoeffField + +Description + Template specialisation for symmTensor coefficients + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved. + +SourceFiles + symmTensorCoeffField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef symmTensorCoeffField_H +#define symmTensorCoeffField_H + +#include "CoeffField.H" +#include "DecoupledCoeffField.H" +#include "symmTensor.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +template<> +class CoeffField +: + public DecoupledCoeffField +{ +public: + + // Constructors + + //- Construct given size + explicit CoeffField(const label); + + //- Construct as copy + CoeffField(const CoeffField&); + + //- Construct as copy of base + explicit CoeffField(const DecoupledCoeffField&); + + //- Construct as copy of base + explicit CoeffField(const tmp >&); + + //- Construct from Istream + explicit CoeffField(Istream&); + + + // Member operators + + void operator=(const CoeffField&); + void operator=(const tmp >&); + + void operator=(const scalarTypeField&); + void operator=(const tmp&); + void operator=(const linearTypeField&); + void operator=(const tmp&); + +}; + + +/* * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * */ + +tmp > inv(const CoeffField& f); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/CoeffField/tensorCoeffField.C b/src/blockMatrix/CoeffField/tensorCoeffField.C new file mode 100644 index 000000000..dc22a63d2 --- /dev/null +++ b/src/blockMatrix/CoeffField/tensorCoeffField.C @@ -0,0 +1,130 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 "tensorCoeffField.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::CoeffField::CoeffField(const label size) +: + DecoupledCoeffField(size) +{} + + +Foam::CoeffField::CoeffField(const CoeffField& f) +: + DecoupledCoeffField(f) +{} + + +Foam::CoeffField::CoeffField(const DecoupledCoeffField& f) +: + DecoupledCoeffField(f) +{} + + +Foam::CoeffField::CoeffField +( + const tmp >& tf +) +: + DecoupledCoeffField(tf()) +{} + + +Foam::CoeffField::CoeffField(Istream& is) +: + DecoupledCoeffField(is) +{} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +void Foam::CoeffField::operator=(const CoeffField& f) +{ + DecoupledCoeffField::operator=(f); +} + + +void Foam::CoeffField::operator= +( + const tmp >& f +) +{ + DecoupledCoeffField::operator=(f); +} + + +void Foam::CoeffField::operator= +( + const CoeffField::scalarTypeField& f +) +{ + DecoupledCoeffField::operator=(f); +} + + +void Foam::CoeffField::operator= +( + const tmp::scalarTypeField>& f +) +{ + DecoupledCoeffField::operator=(f); +} + + +void Foam::CoeffField::operator= +( + const CoeffField::linearTypeField& f +) +{ + DecoupledCoeffField::operator=(f); +} + + +void Foam::CoeffField::operator= +( + const tmp::linearTypeField>& f +) +{ + DecoupledCoeffField::operator=(f); +} + + +/* * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * */ + +Foam::tmp > Foam::inv +( + const CoeffField& f +) +{ + const DecoupledCoeffField& df = f; + + return tmp >(new CoeffField(inv(df)())); +} + + +// ************************************************************************* // diff --git a/src/blockMatrix/CoeffField/tensorCoeffField.H b/src/blockMatrix/CoeffField/tensorCoeffField.H new file mode 100644 index 000000000..ea2ff5afe --- /dev/null +++ b/src/blockMatrix/CoeffField/tensorCoeffField.H @@ -0,0 +1,102 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + CoeffField + +Description + Template specialisation for tensor coefficients + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved. + +SourceFiles + tensorCoeffField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef tensorCoeffField_H +#define tensorCoeffField_H + +#include "CoeffField.H" +#include "DecoupledCoeffField.H" +#include "tensor.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +template<> +class CoeffField +: + public DecoupledCoeffField +{ +public: + + // Constructors + + //- Construct given size + explicit CoeffField(const label); + + //- Construct as copy + CoeffField(const CoeffField&); + + //- Construct as copy of base + explicit CoeffField(const DecoupledCoeffField&); + + //- Construct as copy of base + explicit CoeffField(const tmp >&); + + //- Construct from Istream + explicit CoeffField(Istream&); + + + // Member operators + + void operator=(const CoeffField&); + void operator=(const tmp >&); + + void operator=(const scalarTypeField&); + void operator=(const tmp&); + void operator=(const linearTypeField&); + void operator=(const tmp&); + +}; + + +/* * * * * * * * * * * * * * * * Global functions * * * * * * * * * * * * * */ + +tmp > inv(const CoeffField& f); + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/Make/files b/src/blockMatrix/Make/files new file mode 100644 index 000000000..78fb9dabf --- /dev/null +++ b/src/blockMatrix/Make/files @@ -0,0 +1,48 @@ +BlockCoeff/blockCoeffBase.C +BlockCoeff/scalarBlockCoeff.C +BlockCoeff/sphericalTensorBlockCoeff.C +BlockCoeff/symmTensorBlockCoeff.C +BlockCoeff/tensorBlockCoeff.C + +expandContract/expandTensorField.C + +CoeffField/scalarCoeffField.C +CoeffField/sphericalTensorCoeffField.C +CoeffField/symmTensorCoeffField.C +CoeffField/tensorCoeffField.C + +BlockLduMatrix/blockLduMatrices.C +BlockLduMatrix/scalarBlockLduMatrix.C +BlockLduMatrix/sphericalTensorBlockLduMatrix.C +BlockLduMatrix/symmTensorBlockLduMatrix.C +BlockLduMatrix/tensorBlockLduMatrix.C +BlockLduMatrix/BlockConstraint/scalarBlockConstraint.C + +BlockLduPrecons/BlockLduPrecon/blockLduPrecons.C +BlockLduPrecons/BlockNoPrecon/blockNoPrecons.C + +BlockLduPrecons/BlockDiagonalPrecon/scalarBlockDiagonalPrecon.C +BlockLduPrecons/BlockDiagonalPrecon/tensorBlockDiagonalPrecon.C +BlockLduPrecons/BlockDiagonalPrecon/blockDiagonalPrecons.C + +BlockLduPrecons/BlockGaussSeidelPrecon/scalarBlockGaussSeidelPrecon.C +BlockLduPrecons/BlockGaussSeidelPrecon/tensorBlockGaussSeidelPrecon.C +BlockLduPrecons/BlockGaussSeidelPrecon/blockGaussSeidelPrecons.C + +BlockLduPrecons/BlockCholeskyPrecon/scalarBlockCholeskyPrecon.C +BlockLduPrecons/BlockCholeskyPrecon/tensorBlockCholeskyPrecon.C +BlockLduPrecons/BlockCholeskyPrecon/blockCholeskyPrecons.C + +BlockLduSmoothers/BlockLduSmoother/blockLduSmoothers.C +BlockLduSmoothers/BlockGaussSeidelSmoother/blockGaussSeidelSmoothers.C +BlockLduSmoothers/BlockILUSmoother/blockILUSmoothers.C + +BlockLduSolvers/BlockLduSolver/blockLduSolvers.C +BlockLduSolvers/BlockDiagonal/blockDiagonalSolvers.C +BlockLduSolvers/Segregated/segregatedSolvers.C +BlockLduSolvers/BlockGaussSeidel/blockGaussSeidelSolvers.C +BlockLduSolvers/BlockCG/blockCGSolvers.C +BlockLduSolvers/BlockBiCGStab/blockBiCGStabSolvers.C +BlockLduSolvers/BlockGMRES/blockGMRESSolvers.C + +LIB = $(FOAM_LIBBIN)/libblockMatrix diff --git a/src/blockMatrix/Make/options b/src/blockMatrix/Make/options new file mode 100644 index 000000000..e69de29bb diff --git a/src/blockMatrix/expandContract/expandTensor.H b/src/blockMatrix/expandContract/expandTensor.H new file mode 100644 index 000000000..32439ee08 --- /dev/null +++ b/src/blockMatrix/expandContract/expandTensor.H @@ -0,0 +1,100 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + +Description + Global functions for expansion and contraction of tensor coefficient + to diagonal type + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +\*---------------------------------------------------------------------------*/ + +#ifndef expandTensor_H +#define expandTensor_H + +#include "Tensor.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +//- Return the diagonal of a tensor as a scalar +template +inline void contractScalar(Cmpt& result, const Tensor& t) +{ + result = 1.0/3.0*(t.xx() + t.yy() + t.zz()); +} + + +//- Return the diagonal of a tensor as a vector +template +inline void contractLinear(Vector& result, const Tensor& t) +{ + result = Vector(t.xx(), t.yy(), t.zz()); +} + + +//- Return the vector given a scalar +template +inline void expandScalar(Vector& result, const Cmpt& v) +{ + result = Vector(v, v, v); +} + + +//- Return the tensor given a scalar +template +inline void expandScalar(Tensor& result, const Cmpt& v) +{ + result = Tensor + ( + v, pTraits::zero, pTraits::zero, + pTraits::zero, v, pTraits::zero, + pTraits::zero, pTraits::zero, v + ); +} + + +//- Return the tensor given a diagonal vector +template +inline void expandLinear(Tensor& result, const Vector& v) +{ + result = Tensor + ( + v.x(), pTraits::zero, pTraits::zero, + pTraits::zero, v.y(), pTraits::zero, + pTraits::zero, pTraits::zero, v.z() + ); +} + + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/expandContract/expandTensorField.C b/src/blockMatrix/expandContract/expandTensorField.C new file mode 100644 index 000000000..a89c23678 --- /dev/null +++ b/src/blockMatrix/expandContract/expandTensorField.C @@ -0,0 +1,95 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + +Description + Global functions for expansion and contraction of tensor field + to diagonal type + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +\*---------------------------------------------------------------------------*/ + +#include "tensorField.H" +#include "expandTensor.H" + +#define TEMPLATE +#include "FieldFunctionsM.C" + +namespace Foam +{ + +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +void contractScalar(Field& res, const UList& f) +{ + forAll (res, i) + { + contractScalar(res[i], f[i]); + } +} + + +void contractLinear(Field& res, const UList& f) +{ + forAll (res, i) + { + contractLinear(res[i], f[i]); + } +} + + +void expandScalar(Field& res, const UList& f) +{ + forAll (res, i) + { + expandScalar(res[i], f[i]); + } +} + + +void expandScalar(Field& res, const UList& f) +{ + forAll (res, i) + { + expandScalar(res[i], f[i]); + } +} + + +void expandLinear(Field& res, const UList& f) +{ + forAll (res, i) + { + expandLinear(res[i], f[i]); + } +} + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "undefFieldFunctionsM.H" + +// ************************************************************************* // diff --git a/src/blockMatrix/expandContract/expandTensorField.H b/src/blockMatrix/expandContract/expandTensorField.H new file mode 100644 index 000000000..58b841360 --- /dev/null +++ b/src/blockMatrix/expandContract/expandTensorField.H @@ -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 + +Description + Global functions for expansion and contraction of tensor field + to diagonal type + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + expandTensorField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef expandTensorField_H +#define expandTensorField_H + +#include "tensorField.H" + +#define TEMPLATE +#include "FieldFunctionsM.H" + +namespace Foam +{ + +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +void contractScalar(Field& res, const UList& f); +void contractLinear(Field& res, const UList& f); + +void expandScalar(Field& res, const UList& f); + +void expandScalar(Field& res, const UList& f); +void expandLinear(Field& res, const UList& f); + +} // End namespace Foam + +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "undefFieldFunctionsM.H" + +// ************************************************************************* // diff --git a/src/blockMatrix/vectorN/ExpandTensorN.H b/src/blockMatrix/vectorN/ExpandTensorN.H new file mode 100644 index 000000000..87030583f --- /dev/null +++ b/src/blockMatrix/vectorN/ExpandTensorN.H @@ -0,0 +1,126 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + +Description + Global functions for expansion and contraction of tensor8 coefficient + to diagonal type + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +\*---------------------------------------------------------------------------*/ + +#ifndef expandTensorN_H +#define expandTensorN_H + +#include "VectorN.H" +#include "TensorN.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +//- Return the diagonal of a TensorN as a scalar +template +inline void contractScalar(Cmpt& result, const TensorN& t) +{ + result = pTraits::zero; + + for (int i = 0; i < TensorN::rowLength; i++) + { + result += t(i, i); + } + + result *= 1.0/8.0; +} + + +//- Return the diagonal of a TensorN as a vector +template +inline void contractLinear +( + VectorN& result, + const TensorN& t +) +{ + result = VectorN::zero; + + for (int i = 0; i < TensorN::rowLength; i++) + { + result(i) = t(i, i); + } +} + + +//- Return the VectorN given a scalar +template +inline void expandScalar(VectorN& result, const Cmpt& v) +{ + result = VectorN::zero; + + for (int i = 0; i < VectorN::nComponents; i++) + { + result(i) = v; + } +} + + +//- Return the TensorN given a scalar +template +inline void expandScalar(TensorN& result, const Cmpt& v) +{ + result = TensorN::zero; + + for (int i = 0; i < TensorN::rowLength; i++) + { + result(i, i) = v; + } +} + + +//- Return the TensorN given a diagonal vector8 +template +inline void expandLinear +( + TensorN& result, + const VectorN& v +) +{ + result = TensorN::zero; + + for (int i = 0; i < TensorN::rowLength; i++) + { + result(i, i) = v(i); + } +} + + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/vectorN/ExpandTensorNField.C b/src/blockMatrix/vectorN/ExpandTensorNField.C new file mode 100644 index 000000000..4f918571f --- /dev/null +++ b/src/blockMatrix/vectorN/ExpandTensorNField.C @@ -0,0 +1,122 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + +Description + Global functions for expansion and contraction of tensor field + to diagonal type + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +\*---------------------------------------------------------------------------*/ + +#include "Field.H" +#include "VectorN.H" +#include "VectorN.H" +#include "ExpandTensorN.H" + +#define TEMPLATE +#include "FieldFunctionsM.C" + +namespace Foam +{ + +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +template +void contractScalar +( + Field& res, + const UList >& f +) +{ + forAll (res, i) + { + contractScalar(res[i], f[i]); + } +} + + +template +void contractLinear +( + Field >& res, + const UList >& f +) +{ + forAll (res, i) + { + contractLinear(res[i], f[i]); + } +} + + +template +void expandScalar +( + Field >& res, + const UList& f +) +{ + forAll (res, i) + { + expandScalar(res[i], f[i]); + } +} + + +template +void expandScalar +( + Field >& res, + const UList& f +) +{ + forAll (res, i) + { + expandScalar(res[i], f[i]); + } +} + + +template +void expandLinear +( + Field >& res, + const UList >& f +) +{ + forAll (res, i) + { + expandLinear(res[i], f[i]); + } +} + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "undefFieldFunctionsM.H" + +// ************************************************************************* // diff --git a/src/blockMatrix/vectorN/ExpandTensorNField.H b/src/blockMatrix/vectorN/ExpandTensorNField.H new file mode 100644 index 000000000..9a73c3b21 --- /dev/null +++ b/src/blockMatrix/vectorN/ExpandTensorNField.H @@ -0,0 +1,101 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + +Description + Global functions for expansion and contraction of tensor field + to diagonal type + +Author + Hrvoje Jasak, Wikki Ltd. All rights reserved + +SourceFiles + ExpandTensorNField.C + +\*---------------------------------------------------------------------------*/ + +#ifndef expandTensorNField_H +#define expandTensorNField_H + +#include "Field.H" +#include "VectorN.H" +#include "TensorN.H" + +#define TEMPLATE +#include "FieldFunctionsM.H" + +namespace Foam +{ + +// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // + +template +void contractScalar +( + Field& res, + const UList >& f +); + +template +void contractLinear +( + Field >& res, + const UList >& f +); + +template +void expandScalar +( + Field >& res, + const UList& f +); + +template +void expandScalar +( + Field >& res, + const UList& f +); + +template +void expandLinear +( + Field >& res, + const UList >& f +); + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "undefFieldFunctionsM.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "ExpandTensorNField.C" +#endif + +// ************************************************************************* // + +#endif diff --git a/src/blockMatrix/vectorN/TensorN.H b/src/blockMatrix/vectorN/TensorN.H new file mode 100644 index 000000000..23466aeb2 --- /dev/null +++ b/src/blockMatrix/vectorN/TensorN.H @@ -0,0 +1,126 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + TensorN + +Description + +SourceFiles + TensorNI.H + +\*---------------------------------------------------------------------------*/ + +#ifndef TensorN_H +#define TensorN_H + +#include "VectorN.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class TensorN Declaration +\*---------------------------------------------------------------------------*/ + +template +class TensorN +: + public VectorSpace, Cmpt, length*length> +{ + +public: + + // Member constants + + enum + { + rank = 2, // Rank of TensorN is 2 + rowLength = length // Number of components in a row + }; + + + // Static data members + + static const char* const typeName; + + static const TensorN zero; + static const TensorN one; + + + // Constructors + + //- Construct null + inline TensorN(); + + //- Construct given VectorSpace + inline TensorN + ( + const VectorSpace, Cmpt, length*length>& + ); + + //- Construct given component value. Special use only! + explicit inline TensorN(const Cmpt& tx); + + //- Construct from Istream + TensorN(Istream&); + + + // Member Functions + + //- Return (i, j) component + inline const Cmpt& operator() + ( + const direction i, + const direction j + ) const; + + //- Return access to (i, j) component + inline Cmpt& operator() + ( + const direction i, + const direction j + ); + + //- Transpose + inline TensorN T() const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Include inline implementations +#include "TensorNI.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/vectorN/TensorNField.H b/src/blockMatrix/vectorN/TensorNField.H new file mode 100644 index 000000000..33e064a2b --- /dev/null +++ b/src/blockMatrix/vectorN/TensorNField.H @@ -0,0 +1,68 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 + TensorNField + +Description + Field of tensorN + +SourceFiles + +\*---------------------------------------------------------------------------*/ + +#ifndef TensorNField_H +#define TensorNField_H + +#include "TensorN.H" +#include "Field.H" + +#define TEMPLATE template +#include "FieldFunctionsM.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +typedef TensorN TensorNType; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +UNARY_FUNCTION(TensorNType, TensorNType, inv) + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "undefFieldFunctionsM.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/blockMatrix/vectorN/TensorNI.H b/src/blockMatrix/vectorN/TensorNI.H new file mode 100644 index 000000000..335a48b48 --- /dev/null +++ b/src/blockMatrix/vectorN/TensorNI.H @@ -0,0 +1,479 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 +{ + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +template +const char* const TensorN::typeName = + string("tensor" + name(length)).c_str(); + +template +const TensorN TensorN::zero(0); + +template +const TensorN TensorN::one(1); + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +//- Construct null +template +inline TensorN::TensorN() +{} + + +//- Construct given VectorSpace +template +inline TensorN::TensorN +( + const VectorSpace, Cmpt, length*length>& vs +) +: + VectorSpace, Cmpt, length*length>(vs) +{} + + +//- Construct from component +template +inline TensorN::TensorN(const Cmpt& tx) +{ + for (register label i = 0; i < TensorN::nComponents; i++) + { + this->v_[i] = tx; + } +} + + +//- Construct from Istream +template +inline TensorN::TensorN(Istream& is) +: + VectorSpace, Cmpt, length*length>(is) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +//- Return tensor transpose +template +inline TensorN TensorN::T() const +{ + TensorN transpose; + + for (register label i = 0; i < TensorN::rowLength; i++) + { + for (register label j = 0; j < TensorN::rowLength; j++) + { + transpose(i, j) = this->operator()(j, i); + } + } + + return transpose; +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +template +inline const Cmpt& TensorN::operator() +( + const direction i, + const direction j +) const +{ + return this->operator[](i*TensorN::rowLength + j); +} + + +template +inline Cmpt& TensorN::operator() +( + const direction i, + const direction j +) +{ + return this->operator[](i*TensorN::rowLength + j); +} + + +// * * * * * * * * * * * * * * * Global Operators * * * * * * * * * * * * * // + +//- Inner-product between two tensors +template +inline typename +innerProduct, TensorN >::type +operator&(const TensorN& t1, const TensorN& t2) +{ + TensorN result(TensorN::zero); + + for (register label i = 0; i < TensorN::rowLength; i++) + { + for (register label j = 0; j < TensorN::rowLength; j++) + { + Cmpt& r = result(i, j); + + for (int k = 0; k < TensorN::rowLength; k++) + { + r += t1(i, k)*t2(k, j); + } + } + } + + return result; +} + + +//- Inner-product between a tensor and a vector +template +inline typename +innerProduct, VectorN >::type +operator&(const TensorN& t, const VectorN& v) +{ + VectorN result(VectorN::zero); + + for (register label i = 0; i < TensorN::rowLength; i++) + { + Cmpt& r = result(i); + + for (register label j = 0; j < TensorN::rowLength; j++) + { + r += t(i, j)*v(j); + } + } + + return result; +} + + +//- Inner-product between a vector and a tensor +template +inline typename +innerProduct, TensorN >::type +operator&(const VectorN& v, const TensorN& t) +{ + VectorN result(VectorN::zero); + + for (register label i = 0; i < TensorN::rowLength; i++) + { + Cmpt& r = result(i); + + for (register label j = 0; j < TensorN::rowLength; j++) + { + r += v(i)*t(j, i); + } + } + + return result; +} + + +//- Outer-product between two vectors +template +inline typename +outerProduct, VectorN >::type +operator*(const VectorN& v1, const VectorN& v2) +{ + TensorN result(TensorN::zero); + + for (register label i = 0; i < TensorN::rowLength; i++) + { + for (register label j = 0; j < TensorN::rowLength; j++) + { + result(i, j) = v1(i)*v2(j); + } + } + + return result; +} + + +// UNOPTIMIZED VERSION +/* +//- Return the inverse of a tensor give the determinant +// Uses Gauss-Jordan Elimination with full pivoting +template +inline TensorN inv(const TensorN& t) +{ + TensorN result(t); + + label i, j, k, iRow=0, iCol=0; + Cmpt bigValue, temp, pivotInv; + + // Lists used for bookkeeping on the pivoting + List