Third version of BlockILUCp preconditioner - still not working properly

This commit is contained in:
Vuko Vukcevic 2015-07-14 10:03:19 +02:00 committed by Hrvoje Jasak
parent 6824cfda9c
commit 63506b5c81
20 changed files with 1285 additions and 238 deletions

View file

@ -663,7 +663,11 @@ matrices/blockLduMatrix/BlockLduMatrix/symmTensorBlockLduMatrix.C
matrices/blockLduMatrix/BlockLduMatrix/tensorBlockLduMatrix.C matrices/blockLduMatrix/BlockLduMatrix/tensorBlockLduMatrix.C
matrices/blockLduMatrix/BlockLduMatrix/blockVectorNMatrices.C matrices/blockLduMatrix/BlockLduMatrix/blockVectorNMatrices.C
matrices/blockLduMatrix/BlockLduMatrix/BlockConstraint/scalarBlockConstraint.C matrices/blockLduMatrix/BlockLduMatrix/BlockConstraint/scalarBlockConstraint.C
matrices/blockLduMatrix/BlockLduMatrix/extendedBlockLduMatrix/extendedBlockLduMatrices.C matrices/blockLduMatrix/BlockLduMatrix/extendedBlockLduMatrix/extendedBlockLduMatrices.C
matrices/blockLduMatrix/BlockLduMatrix/extendedBlockLduMatrix/sphericalTensorExtendedBlockLduMatrix.C
matrices/blockLduMatrix/BlockLduMatrix/extendedBlockLduMatrix/symmTensorExtendedBlockLduMatrix.C
matrices/blockLduMatrix/BlockLduMatrix/extendedBlockLduMatrix/tensorExtendedBlockLduMatrix.C
matrices/blockLduMatrix/BlockLduMatrix/extendedBlockLduMatrix/extendedBlockVectorNMatrices.C matrices/blockLduMatrix/BlockLduMatrix/extendedBlockLduMatrix/extendedBlockVectorNMatrices.C
BlockLduInterfaceField = matrices/blockLduMatrix/BlockLduMatrix/BlockLduInterfaceField BlockLduInterfaceField = matrices/blockLduMatrix/BlockLduMatrix/BlockLduInterfaceField

View file

@ -35,7 +35,9 @@ Author
#ifndef extendedBlockLduMatrices_H #ifndef extendedBlockLduMatrices_H
#define extendedBlockLduMatrices_H #define extendedBlockLduMatrices_H
#include "extendedBlockLduMatrix.H" #include "sphericalTensorExtendedBlockLduMatrix.H"
#include "symmTensorExtendedBlockLduMatrix.H"
#include "tensorExtendedBlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View file

@ -25,36 +25,14 @@ License
#include "extendedBlockLduMatrix.H" #include "extendedBlockLduMatrix.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type> template<class Type>
Foam::extendedBlockLduMatrix<Type>::extendedBlockLduMatrix void Foam::extendedBlockLduMatrix<Type>::mapOffDiagCoeffs
( (
const BlockLduMatrix<Type>& blockLdum, const BlockLduMatrix<Type>& blockLdum
const label extensionLevel,
const polyMesh& polyMesh
) )
:
basicBlockLduMatrix_(blockLdum),
extLduAddr_
(
extendedLduAddressing::New
(
polyMesh,
blockLdum.lduAddr(),
extensionLevel
)
),
extendedLowerPtr_(NULL),
extendedUpperPtr_(NULL)
{ {
if (debug)
{
Info<< "extendedBlockLduMatrix(lduMatrix&, label, polyMesh&) :"
"Constructing extendedBlockLduMatrix."
<< endl;
}
if (blockLdum.diagonal()) if (blockLdum.diagonal())
{ {
WarningIn("extendedBlockLduMatrix(lduMatrix&, label, polyMesh&)") WarningIn("extendedBlockLduMatrix(lduMatrix&, label, polyMesh&)")
@ -299,6 +277,42 @@ Foam::extendedBlockLduMatrix<Type>::extendedBlockLduMatrix
} }
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::extendedBlockLduMatrix<Type>::extendedBlockLduMatrix
(
const BlockLduMatrix<Type>& blockLdum,
const label extensionLevel,
const polyMesh& polyMesh
)
:
basicBlockLduMatrix_(blockLdum),
extLduAddr_
(
extendedLduAddressing::New
(
polyMesh,
blockLdum.lduAddr(),
extensionLevel
)
),
extendedLowerPtr_(NULL),
extendedUpperPtr_(NULL)
{
if (debug)
{
Info<< "extendedBlockLduMatrix(lduMatrix&, label, polyMesh&) :"
"Constructing extendedBlockLduMatrix."
<< endl;
}
// Map off diag coeffs from original block matrix to this extended block
// matrix
mapOffDiagCoeffs(blockLdum);
}
// * * * * * * * * * * * * * * * * Destructor* * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor* * * * * * * * * * * * * * * * //
template<class Type> template<class Type>

View file

@ -86,6 +86,10 @@ private:
//- Disallow default bitwise assignement //- Disallow default bitwise assignement
void operator=(const extendedBlockLduMatrix<Type>&); void operator=(const extendedBlockLduMatrix<Type>&);
//- Map upper and lower coeffs from ordinary block matrix to extended
// block matrix
void mapOffDiagCoeffs(const BlockLduMatrix<Type>&);
public: public:

View file

@ -0,0 +1,249 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef sphericalTensorExtendedBlockLduMatrix_H
#define sphericalTensorExtendedBlockLduMatrix_H
#include "extendedBlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::extendedBlockLduMatrix<Foam::sphericalTensor>::mapOffDiagCoeffs
(
const BlockLduMatrix<sphericalTensor>& blockLdum
)
{
if (blockLdum.diagonal())
{
WarningIn("extendedBlockLduMatrix(lduMatrix&, label, polyMesh&)")
<< "Attempted to create extended lower/upper coeffs for block "
<< "matrix that is diagonal."
<< nl << endl;
}
else if (blockLdum.symmetric())
{
// Get reference to faceMap in extended addressing
const unallocLabelList& faceMap = extLduAddr_.faceMap();
// Avoid assuming it's upper if the matrix is symmetric
if (blockLdum.thereIsUpper())
{
// Allocate extended upper only
extendedUpperPtr_ = new TypeCoeffField
(
extLduAddr_.extendedUpperAddr().size()
);
TypeCoeffField& extUpper = *extendedUpperPtr_;
// Get upper coeffs from underlying lduMatrix
const TypeCoeffField& upper = blockLdum.upper();
if (upper.activeType() == blockCoeffBase::SCALAR)
{
// Helper type definition
typedef typename CoeffField<sphericalTensor>::scalarTypeField
activeType;
// Get references to fields
const activeType& activeUpper = upper.asScalar();
activeType& activeExtUpper = extUpper.asScalar();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (upper, faceI)
{
activeExtUpper[faceMap[faceI]] = activeUpper[faceI];
}
}
else if (upper.activeType() == blockCoeffBase::LINEAR)
{
// Helper type definition
typedef typename CoeffField<sphericalTensor>::linearTypeField
activeType;
// Get references to fields
const activeType& activeUpper = upper.asLinear();
activeType& activeExtUpper = extUpper.asLinear();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (upper, faceI)
{
activeExtUpper[faceMap[faceI]] = activeUpper[faceI];
}
}
else
{
FatalErrorIn
(
"extendedBlockLduMatrix(lduMatrix&, label, polyMesh&)"
) << "Problem between ordinary block matrix and extended"
<< " block matrix upper coeffs type morphing."
<< abort(FatalError);
}
}
else
{
// Allocate extended lower only
extendedLowerPtr_ = new TypeCoeffField
(
extLduAddr_.extendedLowerAddr().size()
);
TypeCoeffField& extLower = *extendedLowerPtr_;
// Get lower coeffs from underlying lduMatrix
const TypeCoeffField& lower = blockLdum.lower();
if (lower.activeType() == blockCoeffBase::SCALAR)
{
// Helper type definition
typedef typename CoeffField<sphericalTensor>::scalarTypeField
activeType;
// Get references to fields
const activeType& activeLower = lower.asScalar();
activeType& activeExtLower = extLower.asScalar();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (lower, faceI)
{
activeExtLower[faceMap[faceI]] = activeLower[faceI];
}
}
else if (lower.activeType() == blockCoeffBase::LINEAR)
{
// Helper type definition
typedef typename CoeffField<sphericalTensor>::linearTypeField
activeType;
// Get references to fields
const activeType& activeLower = lower.asLinear();
activeType& activeExtLower = extLower.asLinear();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (lower, faceI)
{
activeExtLower[faceMap[faceI]] = activeLower[faceI];
}
}
else
{
FatalErrorIn
(
"extendedBlockLduMatrix(lduMatrix&, label, polyMesh&)"
) << "Problem between ordinary block matrix and extended"
<< " block matrix lower coeffs type morphing."
<< abort(FatalError);
}
}
}
else
{
// Get reference to faceMap in extended addressing
const unallocLabelList& faceMap = extLduAddr_.faceMap();
// Get number of extended faces
const label nExtFaces = extLduAddr_.extendedUpperAddr().size();
// Allocate extended upper and lower
extendedUpperPtr_ = new TypeCoeffField(nExtFaces);
TypeCoeffField& extUpper = *extendedUpperPtr_;
extendedLowerPtr_ = new TypeCoeffField(nExtFaces);
TypeCoeffField& extLower = *extendedLowerPtr_;
// Get upper and lower coeffs from underlying lduMatrix
const TypeCoeffField& upper = blockLdum.upper();
const TypeCoeffField& lower = blockLdum.lower();
// Assuming lower and upper have the same active type
if (upper.activeType() == blockCoeffBase::SCALAR)
{
// Helper type definition
typedef typename CoeffField<sphericalTensor>::scalarTypeField
activeType;
// Get references to fields
const activeType& activeUpper = upper.asScalar();
activeType& activeExtUpper = extUpper.asScalar();
const activeType& activeLower = lower.asScalar();
activeType& activeExtLower = extLower.asScalar();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (upper, faceI)
{
activeExtUpper[faceMap[faceI]] = activeUpper[faceI];
activeExtLower[faceMap[faceI]] = activeLower[faceI];
}
}
else if (upper.activeType() == blockCoeffBase::LINEAR)
{
// Helper type definition
typedef typename CoeffField<sphericalTensor>::linearTypeField
activeType;
// Get references to fields
const activeType& activeUpper = upper.asLinear();
activeType& activeExtUpper = extUpper.asLinear();
const activeType& activeLower = lower.asLinear();
activeType& activeExtLower = extLower.asLinear();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (upper, faceI)
{
activeExtUpper[faceMap[faceI]] = activeUpper[faceI];
activeExtLower[faceMap[faceI]] = activeLower[faceI];
}
}
else
{
FatalErrorIn
(
"extendedBlockLduMatrix(lduMatrix&, label, polyMesh&)"
) << "Problem between ordinary block matrix and extended"
<< " block matrix upper/lower coeffs type morphing."
<< abort(FatalError);
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,63 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
extendedBlockLduMatrix
Description
Template specialisation for sphericalTensor extended block matrix
Author
Vuko Vukcevic. All rights reserved.
SourceFiles
sphericalTensorExtendedBlockLduMatrix.C
\*---------------------------------------------------------------------------*/
#ifndef sphericalTensorExtendedBlockLduMatrix_H
#define sphericalTensorExtendedBlockLduMatrix_H
#include "extendedBlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void extendedBlockLduMatrix<sphericalTensor>::mapOffDiagCoeffs
(
const BlockLduMatrix<sphericalTensor>& blockLdum
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,247 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef symmTensorExtendedBlockLduMatrix_H
#define symmTensorExtendedBlockLduMatrix_H
#include "extendedBlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::extendedBlockLduMatrix<Foam::symmTensor>::mapOffDiagCoeffs
(
const BlockLduMatrix<symmTensor>& blockLdum
)
{
if (blockLdum.diagonal())
{
WarningIn("extendedBlockLduMatrix(lduMatrix&, label, polyMesh&)")
<< "Attempted to create extended lower/upper coeffs for block "
<< "matrix that is diagonal."
<< nl << endl;
}
else if (blockLdum.symmetric())
{
// Get reference to faceMap in extended addressing
const unallocLabelList& faceMap = extLduAddr_.faceMap();
// Avoid assuming it's upper if the matrix is symmetric
if (blockLdum.thereIsUpper())
{
// Allocate extended upper only
extendedUpperPtr_ = new TypeCoeffField
(
extLduAddr_.extendedUpperAddr().size()
);
TypeCoeffField& extUpper = *extendedUpperPtr_;
// Get upper coeffs from underlying lduMatrix
const TypeCoeffField& upper = blockLdum.upper();
if (upper.activeType() == blockCoeffBase::SCALAR)
{
// Helper type definition
typedef typename CoeffField<symmTensor>::scalarTypeField
activeType;
// Get references to fields
const activeType& activeUpper = upper.asScalar();
activeType& activeExtUpper = extUpper.asScalar();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (upper, faceI)
{
activeExtUpper[faceMap[faceI]] = activeUpper[faceI];
}
}
else if (upper.activeType() == blockCoeffBase::LINEAR)
{
// Helper type definition
typedef typename CoeffField<symmTensor>::linearTypeField
activeType;
// Get references to fields
const activeType& activeUpper = upper.asLinear();
activeType& activeExtUpper = extUpper.asLinear();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (upper, faceI)
{
activeExtUpper[faceMap[faceI]] = activeUpper[faceI];
}
}
else
{
FatalErrorIn
(
"extendedBlockLduMatrix(lduMatrix&, label, polyMesh&)"
) << "Problem between ordinary block matrix and extended"
<< " block matrix upper coeffs type morphing."
<< abort(FatalError);
}
}
else
{
// Allocate extended lower only
extendedLowerPtr_ = new TypeCoeffField
(
extLduAddr_.extendedLowerAddr().size()
);
TypeCoeffField& extLower = *extendedLowerPtr_;
// Get lower coeffs from underlying lduMatrix
const TypeCoeffField& lower = blockLdum.lower();
if (lower.activeType() == blockCoeffBase::SCALAR)
{
// Helper type definition
typedef typename CoeffField<symmTensor>::scalarTypeField
activeType;
// Get references to fields
const activeType& activeLower = lower.asScalar();
activeType& activeExtLower = extLower.asScalar();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (lower, faceI)
{
activeExtLower[faceMap[faceI]] = activeLower[faceI];
}
}
else if (lower.activeType() == blockCoeffBase::LINEAR)
{
// Helper type definition
typedef typename CoeffField<symmTensor>::linearTypeField
activeType;
// Get references to fields
const activeType& activeLower = lower.asLinear();
activeType& activeExtLower = extLower.asLinear();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (lower, faceI)
{
activeExtLower[faceMap[faceI]] = activeLower[faceI];
}
}
else
{
FatalErrorIn
(
"extendedBlockLduMatrix(lduMatrix&, label, polyMesh&)"
) << "Problem between ordinary block matrix and extended"
<< " block matrix lower coeffs type morphing."
<< abort(FatalError);
}
}
}
else
{
// Get reference to faceMap in extended addressing
const unallocLabelList& faceMap = extLduAddr_.faceMap();
// Get number of extended faces
const label nExtFaces = extLduAddr_.extendedUpperAddr().size();
// Allocate extended upper and lower
extendedUpperPtr_ = new TypeCoeffField(nExtFaces);
TypeCoeffField& extUpper = *extendedUpperPtr_;
extendedLowerPtr_ = new TypeCoeffField(nExtFaces);
TypeCoeffField& extLower = *extendedLowerPtr_;
// Get upper and lower coeffs from underlying lduMatrix
const TypeCoeffField& upper = blockLdum.upper();
const TypeCoeffField& lower = blockLdum.lower();
// Assuming lower and upper have the same active type
if (upper.activeType() == blockCoeffBase::SCALAR)
{
// Helper type definition
typedef typename CoeffField<symmTensor>::scalarTypeField activeType;
// Get references to fields
const activeType& activeUpper = upper.asScalar();
activeType& activeExtUpper = extUpper.asScalar();
const activeType& activeLower = lower.asScalar();
activeType& activeExtLower = extLower.asScalar();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (upper, faceI)
{
activeExtUpper[faceMap[faceI]] = activeUpper[faceI];
activeExtLower[faceMap[faceI]] = activeLower[faceI];
}
}
else if (upper.activeType() == blockCoeffBase::LINEAR)
{
// Helper type definition
typedef typename CoeffField<symmTensor>::linearTypeField activeType;
// Get references to fields
const activeType& activeUpper = upper.asLinear();
activeType& activeExtUpper = extUpper.asLinear();
const activeType& activeLower = lower.asLinear();
activeType& activeExtLower = extLower.asLinear();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (upper, faceI)
{
activeExtUpper[faceMap[faceI]] = activeUpper[faceI];
activeExtLower[faceMap[faceI]] = activeLower[faceI];
}
}
else
{
FatalErrorIn
(
"extendedBlockLduMatrix(lduMatrix&, label, polyMesh&)"
) << "Problem between ordinary block matrix and extended"
<< " block matrix upper/lower coeffs type morphing."
<< abort(FatalError);
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,63 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
extendedBlockLduMatrix
Description
Template specialisation for symmTensor extended block matrix
Author
Vuko Vukcevic. All rights reserved.
SourceFiles
symmTensorExtendedBlockLduMatrix.C
\*---------------------------------------------------------------------------*/
#ifndef symmTensorExtendedBlockLduMatrix_H
#define symmTensorExtendedBlockLduMatrix_H
#include "extendedBlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void extendedBlockLduMatrix<symmTensor>::mapOffDiagCoeffs
(
const BlockLduMatrix<symmTensor>& blockLdum
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,243 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef tensorExtendedBlockLduMatrix_H
#define tensorExtendedBlockLduMatrix_H
#include "extendedBlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void Foam::extendedBlockLduMatrix<Foam::tensor>::mapOffDiagCoeffs
(
const BlockLduMatrix<tensor>& blockLdum
)
{
if (blockLdum.diagonal())
{
WarningIn("extendedBlockLduMatrix(lduMatrix&, label, polyMesh&)")
<< "Attempted to create extended lower/upper coeffs for block "
<< "matrix that is diagonal."
<< nl << endl;
}
else if (blockLdum.symmetric())
{
// Get reference to faceMap in extended addressing
const unallocLabelList& faceMap = extLduAddr_.faceMap();
// Avoid assuming it's upper if the matrix is symmetric
if (blockLdum.thereIsUpper())
{
// Allocate extended upper only
extendedUpperPtr_ = new TypeCoeffField
(
extLduAddr_.extendedUpperAddr().size()
);
TypeCoeffField& extUpper = *extendedUpperPtr_;
// Get upper coeffs from underlying lduMatrix
const TypeCoeffField& upper = blockLdum.upper();
if (upper.activeType() == blockCoeffBase::SCALAR)
{
// Helper type definition
typedef typename CoeffField<tensor>::scalarTypeField activeType;
// Get references to fields
const activeType& activeUpper = upper.asScalar();
activeType& activeExtUpper = extUpper.asScalar();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (upper, faceI)
{
activeExtUpper[faceMap[faceI]] = activeUpper[faceI];
}
}
else if (upper.activeType() == blockCoeffBase::LINEAR)
{
// Helper type definition
typedef typename CoeffField<tensor>::linearTypeField activeType;
// Get references to fields
const activeType& activeUpper = upper.asLinear();
activeType& activeExtUpper = extUpper.asLinear();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (upper, faceI)
{
activeExtUpper[faceMap[faceI]] = activeUpper[faceI];
}
}
else
{
FatalErrorIn
(
"extendedBlockLduMatrix(lduMatrix&, label, polyMesh&)"
) << "Problem between ordinary block matrix and extended"
<< " block matrix upper coeffs type morphing."
<< abort(FatalError);
}
}
else
{
// Allocate extended lower only
extendedLowerPtr_ = new TypeCoeffField
(
extLduAddr_.extendedLowerAddr().size()
);
TypeCoeffField& extLower = *extendedLowerPtr_;
// Get lower coeffs from underlying lduMatrix
const TypeCoeffField& lower = blockLdum.lower();
if (lower.activeType() == blockCoeffBase::SCALAR)
{
// Helper type definition
typedef typename CoeffField<tensor>::scalarTypeField activeType;
// Get references to fields
const activeType& activeLower = lower.asScalar();
activeType& activeExtLower = extLower.asScalar();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (lower, faceI)
{
activeExtLower[faceMap[faceI]] = activeLower[faceI];
}
}
else if (lower.activeType() == blockCoeffBase::LINEAR)
{
// Helper type definition
typedef typename CoeffField<tensor>::linearTypeField activeType;
// Get references to fields
const activeType& activeLower = lower.asLinear();
activeType& activeExtLower = extLower.asLinear();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (lower, faceI)
{
activeExtLower[faceMap[faceI]] = activeLower[faceI];
}
}
else
{
FatalErrorIn
(
"extendedBlockLduMatrix(lduMatrix&, label, polyMesh&)"
) << "Problem between ordinary block matrix and extended"
<< " block matrix lower coeffs type morphing."
<< abort(FatalError);
}
}
}
else
{
// Get reference to faceMap in extended addressing
const unallocLabelList& faceMap = extLduAddr_.faceMap();
// Get number of extended faces
const label nExtFaces = extLduAddr_.extendedUpperAddr().size();
// Allocate extended upper and lower
extendedUpperPtr_ = new TypeCoeffField(nExtFaces);
TypeCoeffField& extUpper = *extendedUpperPtr_;
extendedLowerPtr_ = new TypeCoeffField(nExtFaces);
TypeCoeffField& extLower = *extendedLowerPtr_;
// Get upper and lower coeffs from underlying lduMatrix
const TypeCoeffField& upper = blockLdum.upper();
const TypeCoeffField& lower = blockLdum.lower();
// Assuming lower and upper have the same active type
if (upper.activeType() == blockCoeffBase::SCALAR)
{
// Helper type definition
typedef typename CoeffField<tensor>::scalarTypeField activeType;
// Get references to fields
const activeType& activeUpper = upper.asScalar();
activeType& activeExtUpper = extUpper.asScalar();
const activeType& activeLower = lower.asScalar();
activeType& activeExtLower = extLower.asScalar();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (upper, faceI)
{
activeExtUpper[faceMap[faceI]] = activeUpper[faceI];
activeExtLower[faceMap[faceI]] = activeLower[faceI];
}
}
else if (upper.activeType() == blockCoeffBase::LINEAR)
{
// Helper type definition
typedef typename CoeffField<tensor>::linearTypeField activeType;
// Get references to fields
const activeType& activeUpper = upper.asLinear();
activeType& activeExtUpper = extUpper.asLinear();
const activeType& activeLower = lower.asLinear();
activeType& activeExtLower = extLower.asLinear();
// Copy non-zero coeffs from basic lduMatrix into corresponding
// positions
forAll (upper, faceI)
{
activeExtUpper[faceMap[faceI]] = activeUpper[faceI];
activeExtLower[faceMap[faceI]] = activeLower[faceI];
}
}
else
{
FatalErrorIn
(
"extendedBlockLduMatrix(lduMatrix&, label, polyMesh&)"
) << "Problem between ordinary block matrix and extended"
<< " block matrix upper/lower coeffs type morphing."
<< abort(FatalError);
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,63 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
extendedBlockLduMatrix
Description
Template specialisation for tensor extended block matrix
Author
Vuko Vukcevic. All rights reserved.
SourceFiles
tensorExtendedBlockLduMatrix.C
\*---------------------------------------------------------------------------*/
#ifndef tensorExtendedBlockLduMatrix_H
#define tensorExtendedBlockLduMatrix_H
#include "extendedBlockLduMatrix.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<>
void extendedBlockLduMatrix<tensor>::mapOffDiagCoeffs
(
const BlockLduMatrix<tensor>& blockLdum
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -41,20 +41,25 @@ Author
template<class Type> template<class Type>
template<class LDUType> template<class LDUType>
void Foam::BlockILUCpPrecon<Type>::calcFactorization void Foam::BlockILUCpPrecon<Type>::calcActiveTypeFactorization
( (
Field<LDUType>& preconD, Field<LDUType>& preconD,
Field<LDUType>& extUpper, Field<LDUType>& extUpper,
Field<LDUType>& extLower, Field<LDUType>& extLower
Field<LDUType>& zDiag, ) const
Field<LDUType>& z,
Field<LDUType>& w
)
{ {
if (!this->matrix_.diagonal()) if (!this->matrix_.diagonal())
{ {
// Get number of rows
const label nRows = preconD.size();
// Allocate working fields
Field<LDUType> z(nRows, pTraits<LDUType>::zero);
Field<LDUType> w(nRows, pTraits<LDUType>::zero);
LDUType zDiag(pTraits<LDUType>::zero);
// Create multiplication function object // Create multiplication function object
typename BlockCoeff<LDUType>::multiply mult; typename BlockCoeff<Type>::multiply mult;
// Get necessary const access to extended ldu addressing // Get necessary const access to extended ldu addressing
const extendedLduAddressing& addr = extBlockMatrix_.extendedLduAddr(); const extendedLduAddressing& addr = extBlockMatrix_.extendedLduAddr();
@ -81,10 +86,6 @@ void Foam::BlockILUCpPrecon<Type>::calcFactorization
// Get access to working fields // Get access to working fields
LDUType* __restrict__ zPtr = z.begin(); LDUType* __restrict__ zPtr = z.begin();
LDUType* __restrict__ wPtr = w.begin(); LDUType* __restrict__ wPtr = w.begin();
LDUType& zDiagI = zDiag[0];
// Get number of rows
const label nRows = preconD.size();
// Define start and end face ("virtual" face when extended addressing is // Define start and end face ("virtual" face when extended addressing is
// used) of this row/column. // used) of this row/column.
@ -98,8 +99,9 @@ void Foam::BlockILUCpPrecon<Type>::calcFactorization
// Start and end of k-th row (upper) and k-th column (lower) // Start and end of k-th row (upper) and k-th column (lower)
fStart = ownStartPtr[rowI]; fStart = ownStartPtr[rowI];
fEnd = ownStartPtr[rowI + 1]; fEnd = ownStartPtr[rowI + 1];
// Initialize temporary working diagonal // Initialize temporary working diagonal
zDiagI = diagPtr[rowI]; zDiag = diagPtr[rowI];
// Initialize temporary working row and column fields // Initialize temporary working row and column fields
for (register label faceI = fStart; faceI < fEnd; ++faceI) for (register label faceI = fStart; faceI < fEnd; ++faceI)
@ -132,7 +134,7 @@ void Foam::BlockILUCpPrecon<Type>::calcFactorization
// Update diagonal // Update diagonal
// WARNING: Not sure about order of multiplication. // WARNING: Not sure about order of multiplication.
// Check it. VV, 3/Jul/2015 // Check it. VV, 3/Jul/2015
zDiagI -= mult zDiag -= mult.activeTypeMultiply
( (
lowerPtr[losortCoeff], lowerPtr[losortCoeff],
upperPtr[losortCoeff] upperPtr[losortCoeff]
@ -153,7 +155,7 @@ void Foam::BlockILUCpPrecon<Type>::calcFactorization
{ {
// WARNING: Not sure about order of multiplication. // WARNING: Not sure about order of multiplication.
// Check it. VV, 3/Jul/2015 // Check it. VV, 3/Jul/2015
zPtr[uPtr[faceI]] -= mult zPtr[uPtr[faceI]] -= mult.activeTypeMultiply
( (
lowerPtr[losortCoeff], lowerPtr[losortCoeff],
upperPtr[faceI] upperPtr[faceI]
@ -161,17 +163,22 @@ void Foam::BlockILUCpPrecon<Type>::calcFactorization
// WARNING: Not sure about order of multiplication. // WARNING: Not sure about order of multiplication.
// Check it. VV, 3/Jul/2015 // Check it. VV, 3/Jul/2015
wPtr[uPtr[faceI]] -= mult wPtr[uPtr[faceI]] -= mult.activeTypeMultiply
( (
upperPtr[losortCoeff], lowerPtr[faceI],
lowerPtr[faceI] mult.activeTypeMultiply
(
// diagPtr[lPtr[losortCoeff]], // Note: diag already inverted
mult.inverse(zDiag), // Note: diag already inverted
upperPtr[losortCoeff]
)
); );
} }
} }
// Update diagonal entry, inverting it for future use // Update diagonal entry, inverting it for future use
LDUType& diagRowI = diagPtr[rowI]; LDUType& diagRowI = diagPtr[rowI];
diagRowI = mult.inverse(zDiagI); diagRowI = mult.inverse(zDiag);
// Index for updating L and U // Index for updating L and U
register label zwIndex; register label zwIndex;
@ -187,15 +194,16 @@ void Foam::BlockILUCpPrecon<Type>::calcFactorization
// WARNING: Not sure about order of multiplication. // WARNING: Not sure about order of multiplication.
// Check it. VV, 3/Jul/2015 // Check it. VV, 3/Jul/2015
lowerPtr[faceI] = mult // lowerPtr[faceI] = mult.activeTypeMultiply
( // (
diagRowI, // diagRowI,
wPtr[zwIndex] // wPtr[zwIndex]
); // );
lowerPtr[faceI] = wPtr[zwIndex];
} }
// Reset temporary working fields // Reset temporary working fields
zDiagI = pTraits<LDUType>::zero; zDiag = pTraits<LDUType>::zero;
// Only reset parts of the working fields that have been updated in // Only reset parts of the working fields that have been updated in
// this step (for this row and column) // this step (for this row and column)
@ -234,7 +242,7 @@ void Foam::BlockILUCpPrecon<Type>::calcFactorization
( (
"template <class Type>\n" "template <class Type>\n"
"template <class LDUType>\n" "template <class LDUType>\n"
"void BlockILUCpPrecon<Type>::calcFactorization\n" "void BlockILUCpPrecon<Type>::calcActiveTypeFactorization\n"
"(\n" "(\n"
" Field<LDUType>& preconD,\n" " Field<LDUType>& preconD,\n"
" Field<LDUType>& extUpper,\n" " Field<LDUType>& extUpper,\n"
@ -252,6 +260,109 @@ void Foam::BlockILUCpPrecon<Type>::calcFactorization
} }
template<class Type>
void Foam::BlockILUCpPrecon<Type>::calcFactorization() const
{
// Get upper and lower matrix factors
CoeffField<Type>& Lower = extBlockMatrix_.extendedLower();
CoeffField<Type>& Upper = extBlockMatrix_.extendedUpper();
// Calculate factorization
// Note: lower, diag and upper must have same type as required by the
// algorithm. This is handled by lowest possible promotion
if (preconDiag_.activeType() == blockCoeffBase::SCALAR)
{
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
calcActiveTypeFactorization
(
preconDiag_.asScalar(),
Upper.asScalar(),
Lower.asScalar()
);
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
calcActiveTypeFactorization
(
preconDiag_.asLinear(), // Promotes to linear
Upper.asLinear(),
Lower.asLinear()
);
}
else if (Upper.activeType() == blockCoeffBase::SQUARE)
{
calcActiveTypeFactorization
(
preconDiag_.asSquare(), // Promotes to square
Upper.asSquare(),
Lower.asSquare()
);
}
}
else if (preconDiag_.activeType() == blockCoeffBase::LINEAR)
{
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
calcActiveTypeFactorization
(
preconDiag_.asLinear(),
Upper.asLinear(), // Promotes to linear
Lower.asLinear() // Promotes to linear
);
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
calcActiveTypeFactorization
(
preconDiag_.asLinear(),
Upper.asLinear(),
Lower.asLinear()
);
}
else if (Upper.activeType() == blockCoeffBase::SQUARE)
{
calcActiveTypeFactorization
(
preconDiag_.asSquare(), // Promotes to square
Upper.asSquare(),
Lower.asSquare()
);
}
}
else if (preconDiag_.activeType() == blockCoeffBase::SQUARE)
{
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
calcActiveTypeFactorization
(
preconDiag_.asSquare(),
Upper.asSquare(), // Promotes to square
Lower.asSquare() // Promotes to square
);
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
calcActiveTypeFactorization
(
preconDiag_.asSquare(),
Upper.asSquare(), // Promotes to square
Lower.asSquare() // Promotes to square
);
}
else if (Upper.activeType() == blockCoeffBase::SQUARE)
{
calcActiveTypeFactorization
(
preconDiag_.asSquare(),
Upper.asSquare(),
Lower.asSquare()
);
}
}
}
template<class Type> template<class Type>
template<class LDUType> template<class LDUType>
void Foam::BlockILUCpPrecon<Type>::LUSubstitute void Foam::BlockILUCpPrecon<Type>::LUSubstitute
@ -420,135 +531,9 @@ Foam::BlockILUCpPrecon<Type>::BlockILUCpPrecon
( (
polyMesh::defaultRegion polyMesh::defaultRegion
) )
), )
zDiag_(1),
z_(preconDiag_.size()),
w_(preconDiag_.size())
{ {
// Get upper and lower matrix factors calcFactorization();
CoeffField<Type>& Lower = extBlockMatrix_.extendedLower();
CoeffField<Type>& Upper = extBlockMatrix_.extendedUpper();
// Calculate factorization
// Note: lower, diag and upper must have same type as required by the
// algorithm. This is handled by lowest possible promotion
if (preconDiag_.activeType() == blockCoeffBase::SCALAR)
{
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
calcFactorization
(
preconDiag_.asScalar(),
Upper.asScalar(),
Lower.asScalar(),
zDiag_.asScalar(),
z_.asScalar(),
w_.asScalar()
);
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
calcFactorization
(
preconDiag_.asLinear(), // Promotes to linear
Upper.asLinear(),
Lower.asLinear(),
zDiag_.asLinear(),
z_.asLinear(),
w_.asLinear()
);
}
else if (Upper.activeType() == blockCoeffBase::SQUARE)
{
calcFactorization
(
preconDiag_.asSquare(), // Promotes to square
Upper.asSquare(),
Lower.asSquare(),
zDiag_.asSquare(),
z_.asSquare(),
w_.asSquare()
);
}
}
else if (preconDiag_.activeType() == blockCoeffBase::LINEAR)
{
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
calcFactorization
(
preconDiag_.asLinear(),
Upper.asLinear(), // Promotes to linear
Lower.asLinear(), // Promotes to linear
zDiag_.asLinear(), // Promotes to linear
z_.asLinear(), // Promotes to linear
w_.asLinear() // Promotes to linear
);
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
calcFactorization
(
preconDiag_.asLinear(),
Upper.asLinear(),
Lower.asLinear(),
zDiag_.asLinear(),
z_.asLinear(),
w_.asLinear()
);
}
else if (Upper.activeType() == blockCoeffBase::SQUARE)
{
calcFactorization
(
preconDiag_.asSquare(), // Promotes to square
Upper.asSquare(),
Lower.asSquare(),
zDiag_.asSquare(),
z_.asSquare(),
w_.asSquare()
);
}
}
else if (preconDiag_.activeType() == blockCoeffBase::SQUARE)
{
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
calcFactorization
(
preconDiag_.asSquare(),
Upper.asSquare(), // Promotes to square
Lower.asSquare(), // Promotes to square
zDiag_.asSquare(), // Promotes to square
z_.asSquare(), // Promotes to square
w_.asSquare() // Promotes to square
);
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
calcFactorization
(
preconDiag_.asSquare(),
Upper.asSquare(), // Promotes to square
Lower.asSquare(), // Promotes to square
zDiag_.asSquare(), // Promotes to square
z_.asSquare(), // Promotes to square
w_.asSquare() // Promotes to square
);
}
else if (Upper.activeType() == blockCoeffBase::SQUARE)
{
calcFactorization
(
preconDiag_.asSquare(),
Upper.asSquare(),
Lower.asSquare(),
zDiag_.asSquare(),
z_.asSquare(),
w_.asSquare()
);
}
}
} }

View file

@ -63,22 +63,13 @@ class BlockILUCpPrecon
// Private Data // Private Data
//- Preconditioned diagonal //- Preconditioned diagonal
CoeffField<Type> preconDiag_; mutable CoeffField<Type> preconDiag_;
//- Fill in level //- Fill in level
const label p_; const label p_;
//- Extended lduMarix //- Extended lduMarix
extendedBlockLduMatrix<Type> extBlockMatrix_; mutable extendedBlockLduMatrix<Type> extBlockMatrix_;
//- Temporary working diagonal
CoeffField<Type> zDiag_;
//- Temporary working row field
CoeffField<Type> z_;
//- Temporary working column field
CoeffField<Type> w_;
// Private Member Functions // Private Member Functions
@ -89,18 +80,18 @@ class BlockILUCpPrecon
//- Disallow default bitwise assignment //- Disallow default bitwise assignment
void operator=(const BlockILUCpPrecon&); void operator=(const BlockILUCpPrecon&);
//- Calculate LU factorization. //- Calculate active type dependant factorization.
// Note: both lower, diag and upper have to be of same type // Note: both lower, diag and upper have to be of same type
template<class LDUType> template<class LDUType>
void calcFactorization void calcActiveTypeFactorization
( (
Field<LDUType>& preconD, Field<LDUType>& preconD,
Field<LDUType>& extUpper, Field<LDUType>& extUpper,
Field<LDUType>& extLower, Field<LDUType>& extLower
Field<LDUType>& zDiag, ) const;
Field<LDUType>& z,
Field<LDUType>& w //- Calculate LU factorization (constructor helper)
); void calcFactorization() const;
//- Performs forward/backward LU substitution //- Performs forward/backward LU substitution
// Note: both lower, diag and upper have to be of same type // Note: both lower, diag and upper have to be of same type

View file

@ -39,10 +39,7 @@ namespace Foam
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// Excluded tensor, need reduced version. VV, 3/Jul/2015. makeBlockPrecons(blockILUCpPrecon);
makeBlockPrecon(blockScalarPrecon, blockILUCpPreconScalar);
makeBlockPrecon(blockVectorPrecon, blockILUCpPreconVector);
//makeBlockPrecon(blockTensorPrecon, blockILUCpPreconTensor);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View file

@ -42,8 +42,6 @@ SourceFiles
#include "scalarBlockILUCpPrecon.H" #include "scalarBlockILUCpPrecon.H"
#include "tensorBlockILUCpPrecon.H" #include "tensorBlockILUCpPrecon.H"
#include "BlockILUCpPrecon.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam

View file

@ -45,18 +45,23 @@ namespace Foam
template<> template<>
template<> template<>
void BlockILUCpPrecon<scalar>::calcFactorization void BlockILUCpPrecon<scalar>::calcActiveTypeFactorization
( (
scalarField& preconD, scalarField& preconD,
scalarField& extUpper, scalarField& extUpper,
scalarField& extLower, scalarField& extLower
scalarField& zDiag, ) const
scalarField& z,
scalarField& w
)
{ {
if (!matrix_.diagonal()) if (!matrix_.diagonal())
{ {
// Get number of rows
const label nRows = preconD.size();
// Allocate working fields
scalarField z(nRows, 0.0);
scalarField w(nRows, 0.0);
scalar zDiag = 0.0;
// Get necessary const access to extended ldu addressing // Get necessary const access to extended ldu addressing
const extendedLduAddressing& addr = extBlockMatrix_.extendedLduAddr(); const extendedLduAddressing& addr = extBlockMatrix_.extendedLduAddr();
@ -82,10 +87,6 @@ void BlockILUCpPrecon<scalar>::calcFactorization
// Get access to working fields // Get access to working fields
scalar* __restrict__ zPtr = z.begin(); scalar* __restrict__ zPtr = z.begin();
scalar* __restrict__ wPtr = w.begin(); scalar* __restrict__ wPtr = w.begin();
scalar& zDiagI = zDiag[0];
// Get number of rows
const label nRows = preconD.size();
// Define start and end face ("virtual" face when extended addressing is // Define start and end face ("virtual" face when extended addressing is
// used) of this row/column. // used) of this row/column.
@ -101,7 +102,7 @@ void BlockILUCpPrecon<scalar>::calcFactorization
fEnd = ownStartPtr[rowI + 1]; fEnd = ownStartPtr[rowI + 1];
// Initialize temporary working diagonal // Initialize temporary working diagonal
zDiagI = diagPtr[rowI]; zDiag = diagPtr[rowI];
// Initialize temporary working row field // Initialize temporary working row field
for (register label faceI = fStart; faceI < fEnd; ++faceI) for (register label faceI = fStart; faceI < fEnd; ++faceI)
@ -132,7 +133,7 @@ void BlockILUCpPrecon<scalar>::calcFactorization
const label i = lPtr[losortCoeff]; const label i = lPtr[losortCoeff];
// Update diagonal // Update diagonal
zDiagI -= lowerPtr[losortCoeff]*upperPtr[losortCoeff]; zDiag -= lowerPtr[losortCoeff]*upperPtr[losortCoeff];
// Get end of row for cell i // Get end of row for cell i
const register label fEndRowi = ownStartPtr[i + 1]; const register label fEndRowi = ownStartPtr[i + 1];
@ -154,7 +155,7 @@ void BlockILUCpPrecon<scalar>::calcFactorization
// Update diagonal entry, inverting it for future use // Update diagonal entry, inverting it for future use
scalar& diagRowI = diagPtr[rowI]; scalar& diagRowI = diagPtr[rowI];
diagRowI = 1.0/zDiagI; diagRowI = 1.0/zDiag;
// Index for updating L and U // Index for updating L and U
register label zwIndex; register label zwIndex;
@ -171,7 +172,7 @@ void BlockILUCpPrecon<scalar>::calcFactorization
} }
// Reset temporary working fields // Reset temporary working fields
zDiagI = 0; zDiag = 0;
// Only reset parts of the working fields that have been updated in // Only reset parts of the working fields that have been updated in
// this step (for this row and column) // this step (for this row and column)
@ -228,6 +229,18 @@ void BlockILUCpPrecon<scalar>::calcFactorization
} }
template<>
void BlockILUCpPrecon<scalar>::calcFactorization() const
{
calcActiveTypeFactorization
(
preconDiag_.asScalar(),
extBlockMatrix_.extendedUpper().asScalar(),
extBlockMatrix_.extendedLower().asScalar()
);
}
template<> template<>
void BlockILUCpPrecon<scalar>::precondition void BlockILUCpPrecon<scalar>::precondition
( (

View file

@ -45,18 +45,21 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Calculate factorization // Calculate active type factorization
template<> template<>
template<> template<>
void BlockILUCpPrecon<scalar>::calcFactorization void BlockILUCpPrecon<scalar>::calcActiveTypeFactorization
( (
scalarField& preconD, scalarField& preconD,
scalarField& extUpper, scalarField& extUpper,
scalarField& extLower, scalarField& extLower
scalarField& zDiag, ) const;
scalarField& z,
scalarField& w
); // Calculate factorization (constructor helper)
template<>
void BlockILUCpPrecon<scalar>::calcFactorization() const;
// Precondition // Precondition
template<> template<>

View file

@ -43,24 +43,75 @@ Author
namespace Foam namespace Foam
{ {
// Calculate factorization
template<> template<>
template<> template<>
void BlockILUCpPrecon<tensor>::calcFactorization void BlockILUCpPrecon<tensor>::calcActiveTypeFactorization
( (
tensorField& preconD, tensorField& preconD,
tensorField& extUpper, tensorField& extUpper,
tensorField& extLower, tensorField& extLower
tensorField& zDiag, ) const
tensorField& z,
tensorField& w
)
{ {
// Decoupled version // Decoupled version
notImplemented("void Foam::BlockILUCpPrecon<tensor>::calcFactorization"); notImplemented("void Foam::BlockILUCpPrecon<tensor>::calcFactorization");
} }
template<>
void BlockILUCpPrecon<tensor>::calcFactorization() const
{
// Get upper and lower matrix factors
CoeffField<tensor>& Lower = extBlockMatrix_.extendedLower();
CoeffField<tensor>& Upper = extBlockMatrix_.extendedUpper();
// Calculate factorization
// Note: lower, diag and upper must have same type as required by the
// algorithm. This is handled by lowest possible promotion
if (preconDiag_.activeType() == blockCoeffBase::SCALAR)
{
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
calcActiveTypeFactorization
(
preconDiag_.asScalar(),
Upper.asScalar(),
Lower.asScalar()
);
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
calcActiveTypeFactorization
(
preconDiag_.asLinear(), // Promotes to linear
Upper.asLinear(),
Lower.asLinear()
);
}
}
else if (preconDiag_.activeType() == blockCoeffBase::LINEAR)
{
if (Upper.activeType() == blockCoeffBase::SCALAR)
{
calcActiveTypeFactorization
(
preconDiag_.asLinear(),
Upper.asLinear(), // Promotes to linear
Lower.asLinear() // Promotes to linear
);
}
else if (Upper.activeType() == blockCoeffBase::LINEAR)
{
calcActiveTypeFactorization
(
preconDiag_.asLinear(),
Upper.asLinear(),
Lower.asLinear()
);
}
}
}
template<> template<>
void BlockILUCpPrecon<tensor>::precondition void BlockILUCpPrecon<tensor>::precondition
( (

View file

@ -45,20 +45,23 @@ SourceFiles
namespace Foam namespace Foam
{ {
// Calculate factorization // Calculate active type factorization
template<> template<>
template<> template<>
void BlockILUCpPrecon<tensor>::calcFactorization void BlockILUCpPrecon<tensor>::calcActiveTypeFactorization
( (
tensorField& preconD, tensorField& preconD,
tensorField& extUpper, tensorField& extUpper,
tensorField& extLower, tensorField& extLower
tensorField& zDiag, ) const;
tensorField& z,
tensorField& w
);
// Calculate factorization (constructor helper)
template<>
void BlockILUCpPrecon<tensor>::calcFactorization() const;
// Precondition
template<> template<>
void BlockILUCpPrecon<tensor>::precondition void BlockILUCpPrecon<tensor>::precondition
( (
@ -67,6 +70,7 @@ void BlockILUCpPrecon<tensor>::precondition
) const; ) const;
// Precondition transpose
template<> template<>
void BlockILUCpPrecon<tensor>::preconditionT void BlockILUCpPrecon<tensor>::preconditionT
( (

View file

@ -126,6 +126,37 @@ public:
} }
// Coefficient times coefficient multiplication. Needed for BlockILUCp
// preconditioner. VV, 12/Jul/2015.
scalarType activeTypeMultiply
(
const scalarType& a,
const scalarType& b
) const
{
return a*b;
}
linearType activeTypeMultiply
(
const linearType& a,
const linearType& b
) const
{
return cmptMultiply(a, b);
}
squareType activeTypeMultiply
(
const squareType& a,
const squareType& b
) const
{
return (a & b);
}
// Transpose functions // Transpose functions
scalarType transpose(const scalarType& c) const scalarType transpose(const scalarType& c) const

View file

@ -113,6 +113,28 @@ public:
} }
// Coefficient times coefficient multiplication. Needed for BlockILUCp
// preconditioner. VV, 12/Jul/2015.
scalarType activeTypeMultiply
(
const scalarType& a,
const scalarType& b
) const
{
return a*b;
}
linearType activeTypeMultiply
(
const linearType& a,
const linearType& b
) const
{
return cmptMultiply(a, b);
}
// Inverse functions // Inverse functions
scalarType inverse(const scalarType& c) const scalarType inverse(const scalarType& c) const