Feature: block coupled updates
This commit is contained in:
parent
76b941e7ff
commit
95fb99d2a6
2 changed files with 44 additions and 265 deletions
|
@ -30,7 +30,7 @@ License
|
|||
|
||||
template<class Type>
|
||||
template<class fieldType>
|
||||
void fvBlockMatrix<Type>::insertSolutionVector
|
||||
void Foam::fvBlockMatrix<Type>::insertSolutionVector
|
||||
(
|
||||
const direction dir,
|
||||
const Field<fieldType>& xSingle
|
||||
|
@ -59,7 +59,7 @@ void fvBlockMatrix<Type>::insertSolutionVector
|
|||
|
||||
template<class Type>
|
||||
template<class matrixType>
|
||||
void fvBlockMatrix<Type>::insertDiagSource
|
||||
void Foam::fvBlockMatrix<Type>::insertDiagSource
|
||||
(
|
||||
const direction dir,
|
||||
fvMatrix<matrixType>& matrix
|
||||
|
@ -162,7 +162,7 @@ void fvBlockMatrix<Type>::insertDiagSource
|
|||
|
||||
template<class Type>
|
||||
template<class matrixType>
|
||||
void fvBlockMatrix<Type>::insertUpperLower
|
||||
void Foam::fvBlockMatrix<Type>::insertUpperLower
|
||||
(
|
||||
const direction dir,
|
||||
const fvMatrix<matrixType>& matrix
|
||||
|
@ -290,7 +290,7 @@ void fvBlockMatrix<Type>::insertUpperLower
|
|||
|
||||
template<class Type>
|
||||
template<class matrixType>
|
||||
void fvBlockMatrix<Type>::updateCouplingCoeffs
|
||||
void Foam::fvBlockMatrix<Type>::updateCouplingCoeffs
|
||||
(
|
||||
const direction dir,
|
||||
const fvMatrix<matrixType>& matrix
|
||||
|
@ -299,7 +299,9 @@ void fvBlockMatrix<Type>::updateCouplingCoeffs
|
|||
const direction nCmpts = pTraits<matrixType>::nComponents;
|
||||
direction localDir = dir;
|
||||
|
||||
const GeometricField<matrixType, fvPatchField, volMesh>& psi = matrix.psi();
|
||||
const GeometricField<matrixType, fvPatchField, volMesh>& psi =
|
||||
matrix.psi();
|
||||
|
||||
forAll(psi.boundaryField(), patchI)
|
||||
{
|
||||
const fvPatchField<matrixType>& pf = psi.boundaryField()[patchI];
|
||||
|
@ -373,7 +375,7 @@ void fvBlockMatrix<Type>::updateCouplingCoeffs
|
|||
|
||||
template<class Type>
|
||||
template<class blockType, class fieldType>
|
||||
void fvBlockMatrix<Type>::insertBlock
|
||||
void Foam::fvBlockMatrix<Type>::insertBlock
|
||||
(
|
||||
const direction dirI,
|
||||
const direction dirJ,
|
||||
|
@ -471,7 +473,7 @@ void fvBlockMatrix<Type>::insertBlock
|
|||
|
||||
template<class Type>
|
||||
template<class blockType, class fieldType>
|
||||
void fvBlockMatrix<Type>::insertBoundaryContributions
|
||||
void Foam::fvBlockMatrix<Type>::insertBoundaryContributions
|
||||
(
|
||||
const direction dirI,
|
||||
const direction dirJ,
|
||||
|
@ -561,39 +563,30 @@ void fvBlockMatrix<Type>::insertBoundaryContributions
|
|||
|
||||
|
||||
template<class Type>
|
||||
void fvBlockMatrix<Type>::insertCouplingDiagSource
|
||||
void Foam::fvBlockMatrix<Type>::insertCouplingDiag
|
||||
(
|
||||
const direction dirI,
|
||||
const direction dirJ,
|
||||
const fvScalarMatrix& matrix
|
||||
const scalarField& coeffIJ
|
||||
)
|
||||
{
|
||||
// Prepare the diagonal and source
|
||||
scalarField diag = matrix.diag();
|
||||
scalarField source = matrix.source();
|
||||
|
||||
// Add boundary source contribution
|
||||
matrix.addBoundaryDiag(diag, 0);
|
||||
matrix.addBoundarySource(source, false);
|
||||
|
||||
// Get reference to block diagonal of the block system
|
||||
typename CoeffField<Type>::squareTypeField& blockDiag =
|
||||
this->diag().asSquare();
|
||||
|
||||
// Get reference to this source field of the block system
|
||||
Field<Type>& b = this->source();
|
||||
|
||||
// Set off-diagonal coefficient
|
||||
forAll(diag, cellI)
|
||||
forAll(coeffIJ, cellI)
|
||||
{
|
||||
blockDiag[cellI](dirI, dirJ) += diag[cellI];
|
||||
b[cellI](dirI) += source[cellI];
|
||||
blockDiag[cellI](dirI, dirJ) += coeffIJ[cellI];
|
||||
}
|
||||
|
||||
// Source compensation is done in function updateSourceCoupling()
|
||||
// after all coupling terms are added. HJ, 27/Apr/2015
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void fvBlockMatrix<Type>::insertCouplingUpperLower
|
||||
void Foam::fvBlockMatrix<Type>::insertCouplingUpperLower
|
||||
(
|
||||
const direction dirI,
|
||||
const direction dirJ,
|
||||
|
@ -707,7 +700,7 @@ Foam::fvBlockMatrix<Type>::fvBlockMatrix
|
|||
|
||||
template<class Type>
|
||||
template<class fieldType>
|
||||
void fvBlockMatrix<Type>::retrieveSolution
|
||||
void Foam::fvBlockMatrix<Type>::retrieveSolution
|
||||
(
|
||||
const direction dir,
|
||||
Field<fieldType>& xSingle
|
||||
|
@ -736,7 +729,7 @@ void fvBlockMatrix<Type>::retrieveSolution
|
|||
|
||||
template<class Type>
|
||||
template<class matrixType>
|
||||
void fvBlockMatrix<Type>::insertEquation
|
||||
void Foam::fvBlockMatrix<Type>::insertEquation
|
||||
(
|
||||
const direction dir,
|
||||
fvMatrix<matrixType>& matrix
|
||||
|
@ -751,7 +744,7 @@ void fvBlockMatrix<Type>::insertEquation
|
|||
|
||||
template<class Type>
|
||||
template<class blockType, class fieldType>
|
||||
void fvBlockMatrix<Type>::insertBlockCoupling
|
||||
void Foam::fvBlockMatrix<Type>::insertBlockCoupling
|
||||
(
|
||||
const direction dirI,
|
||||
const direction dirJ,
|
||||
|
@ -765,20 +758,22 @@ void fvBlockMatrix<Type>::insertBlockCoupling
|
|||
|
||||
|
||||
template<class Type>
|
||||
void fvBlockMatrix<Type>::insertEquationCoupling
|
||||
void Foam::fvBlockMatrix<Type>::insertEquationCoupling
|
||||
(
|
||||
const direction dirI,
|
||||
const direction dirJ,
|
||||
const fvScalarMatrix& matrix
|
||||
const scalarField& coeffIJ
|
||||
)
|
||||
{
|
||||
insertCouplingDiagSource(dirI, dirJ, matrix);
|
||||
insertCouplingUpperLower(dirI, dirJ, matrix);
|
||||
// Multiply coefficients by volume
|
||||
scalarField coeffIJVol = coeffIJ*psi_.mesh().V();
|
||||
|
||||
insertCouplingDiag(dirI, dirJ, coeffIJVol);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void fvBlockMatrix<Type>::blockAdd
|
||||
void Foam::fvBlockMatrix<Type>::blockAdd
|
||||
(
|
||||
const direction dir,
|
||||
const scalarField& xSingle,
|
||||
|
@ -793,7 +788,7 @@ void fvBlockMatrix<Type>::blockAdd
|
|||
|
||||
|
||||
template<class Type>
|
||||
void fvBlockMatrix<Type>::updateSourceCoupling()
|
||||
void Foam::fvBlockMatrix<Type>::updateSourceCoupling()
|
||||
{
|
||||
// Eliminate off-diagonal block coefficients from the square diagonal
|
||||
// With this change, the segregated matrix can be assembled with complete
|
||||
|
@ -827,215 +822,7 @@ void fvBlockMatrix<Type>::updateSourceCoupling()
|
|||
|
||||
|
||||
template<class Type>
|
||||
void fvBlockMatrix<Type>::insertPicardTensor
|
||||
(
|
||||
const direction UEqnDir,
|
||||
const volVectorField& U,
|
||||
const surfaceScalarField& phi
|
||||
)
|
||||
{
|
||||
const direction nCmpts = pTraits<vector>::nComponents;
|
||||
direction localDirI = UEqnDir;
|
||||
direction localDirJ = UEqnDir;
|
||||
|
||||
// Sanity check
|
||||
{
|
||||
const direction blockMatrixSize = pTraits<Type>::nComponents;
|
||||
|
||||
if (nCmpts > blockMatrixSize)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void fvBlockMatrix<Type>::insertPicardTensor\n"
|
||||
"(\n"
|
||||
" const direction UEqnDir,\n"
|
||||
" const volVectorField& U,\n"
|
||||
" const surfaceScalarField& phi\n"
|
||||
")"
|
||||
) << "Trying to insert Picard tensor term into smaller "
|
||||
<< "fvBlockMatrix. Do you have momentum equation?"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
// Get weights for U which makes the implicit flux part
|
||||
const fvMesh& mesh = U.mesh();
|
||||
|
||||
tmp<surfaceInterpolationScheme<vector> > tinterpScheme =
|
||||
fvc::scheme<vector>(mesh, U.name());
|
||||
|
||||
tmp<surfaceScalarField> tweights = tinterpScheme().weights(U);
|
||||
const scalarField& wIn = tweights().internalField();
|
||||
|
||||
// Calculate the Pi tensor. Consider hard coding the interpolation scheme to
|
||||
// correspond to the div(U, phi) interpolation scheme for consistency.
|
||||
// VV, 21/July/2014.
|
||||
const surfaceTensorField pi(mesh.Sf()*fvc::interpolate(U, phi, "(phi,U)"));
|
||||
// const surfaceTensorField pi(fvc::interpolate(U, phi, "(phi,U)")*mesh.Sf());
|
||||
const tensorField& piIn = pi.internalField();
|
||||
|
||||
BlockLduSystem<vector, vector> piSystem(mesh);
|
||||
|
||||
// Get references to ldu fields of pi block system always as square
|
||||
typename CoeffField<vector>::squareTypeField& piDiag =
|
||||
piSystem.diag().asSquare();
|
||||
typename CoeffField<vector>::squareTypeField& piUpper =
|
||||
piSystem.upper().asSquare();
|
||||
typename CoeffField<vector>::squareTypeField& piLower =
|
||||
piSystem.lower().asSquare();
|
||||
|
||||
vectorField& piSource = piSystem.source();
|
||||
|
||||
piLower = -wIn*piIn;
|
||||
piUpper = piLower + piIn;
|
||||
piSystem.negSumDiag();
|
||||
|
||||
Info << "Diag coeff: " << piDiag[125] << nl
|
||||
<< "Lower coeff: " << piLower[125] << nl
|
||||
<< "Upper coeff: " << piUpper[125] << endl;
|
||||
|
||||
// Boundary contributions - treated explicitly because of the problem with
|
||||
// inconsistent return type of internalCoeffs. VV, 21/July/2014.
|
||||
forAll(U.boundaryField(), patchI)
|
||||
{
|
||||
const fvPatchVectorField& Ub = U.boundaryField()[patchI];
|
||||
const fvPatch& patch = Ub.patch();
|
||||
const tensorField& pib = pi.boundaryField()[patchI];
|
||||
const fvsPatchScalarField& wb = tweights().boundaryField()[patchI];
|
||||
const unallocLabelList& fc = patch.faceCells();
|
||||
|
||||
// const vectorField internalCoeffs(Ub.valueInternalCoeffs(wb));
|
||||
|
||||
// Explicit diag boundary contribution
|
||||
// forAll(Ub, faceI)
|
||||
// {
|
||||
// piSource[fc[faceI]] -= pib[faceI] & Ub[faceI];
|
||||
// piSource[fc[faceI]] -= Ub[faceI] & pib[faceI];
|
||||
// }
|
||||
|
||||
// Hard coded zeroGradient if patch does not fix value
|
||||
if (!U.boundaryField()[patchI].fixesValue())
|
||||
{
|
||||
forAll(Ub, faceI)
|
||||
{
|
||||
piDiag[fc[faceI]] += pib[faceI];
|
||||
}
|
||||
}
|
||||
// Coupled patches treated implicitly
|
||||
else if (patch.coupled())
|
||||
{
|
||||
typename CoeffField<vector>::squareTypeField& pipCoupleUpper =
|
||||
piSystem.coupleUpper()[patchI].asSquare();
|
||||
typename CoeffField<vector>::squareTypeField& pipCoupleLower =
|
||||
piSystem.coupleLower()[patchI].asSquare();
|
||||
|
||||
const tensorField pcl = -wb*pib;
|
||||
const tensorField pcu = pcl + pib;
|
||||
|
||||
// Coupling contributions
|
||||
pipCoupleLower -= pcl;
|
||||
pipCoupleUpper -= pcu;
|
||||
}
|
||||
else
|
||||
{
|
||||
const vectorField boundaryCoeffs(Ub.valueBoundaryCoeffs(wb));
|
||||
|
||||
// Boundary contribution
|
||||
forAll(Ub, faceI)
|
||||
{
|
||||
piSource[fc[faceI]] -= pib[faceI] & boundaryCoeffs[faceI];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Consider chucking the above code into fvm::picardTensor operator.
|
||||
// VV, 21/July/2014.
|
||||
|
||||
// Finally add Picard piSystem into this fvBlockMatrix
|
||||
typename CoeffField<Type>::squareTypeField& blockDiag =
|
||||
this->diag().asSquare();
|
||||
typename CoeffField<Type>::squareTypeField& blockUpper =
|
||||
this->upper().asSquare();
|
||||
typename CoeffField<Type>::squareTypeField& blockLower =
|
||||
this->lower().asSquare();
|
||||
|
||||
Field<Type>& blockSource = this->source();
|
||||
|
||||
// Add diagonal, source, lower and upper
|
||||
for (direction cmptI = 0; cmptI < nCmpts; cmptI++)
|
||||
{
|
||||
for (direction cmptJ = 0; cmptJ < nCmpts; cmptJ++)
|
||||
{
|
||||
forAll(piDiag, cellI)
|
||||
{
|
||||
blockDiag[cellI](localDirI, localDirJ) +=
|
||||
piDiag[cellI](cmptI, cmptJ);
|
||||
// blockSource[cellI](localDirI, localDirJ) +=
|
||||
// piSource[cellI](cmptI, cmptJ);
|
||||
}
|
||||
|
||||
forAll(piUpper, faceI)
|
||||
{
|
||||
blockUpper[faceI](localDirI, localDirJ) +=
|
||||
piUpper[faceI](cmptI, cmptJ);
|
||||
blockLower[faceI](localDirI, localDirJ) +=
|
||||
piLower[faceI](cmptI, cmptJ);
|
||||
}
|
||||
|
||||
localDirJ++;
|
||||
}
|
||||
|
||||
forAll(piSource, cellI)
|
||||
{
|
||||
blockSource[cellI](localDirI) += piSource[cellI](cmptI);
|
||||
}
|
||||
|
||||
localDirI++;
|
||||
}
|
||||
|
||||
// Reset local direction for coupling contributions
|
||||
localDirI = UEqnDir;
|
||||
localDirJ = UEqnDir;
|
||||
|
||||
// Add coupling contributions
|
||||
forAll(U.boundaryField(), patchI)
|
||||
{
|
||||
if (U.boundaryField()[patchI].patch().coupled())
|
||||
{
|
||||
typename CoeffField<Type>::squareTypeField& pcoupleUpper =
|
||||
this->coupleUpper()[patchI].asSquare();
|
||||
typename CoeffField<Type>::squareTypeField& pcoupleLower =
|
||||
this->coupleLower()[patchI].asSquare();
|
||||
|
||||
const typename CoeffField<vector>::squareTypeField& pipcu =
|
||||
piSystem.coupleUpper()[patchI].asSquare();
|
||||
const typename CoeffField<vector>::squareTypeField& pipcl =
|
||||
piSystem.coupleLower()[patchI].asSquare();
|
||||
|
||||
for (direction cmptI = 0; cmptI < nCmpts; cmptI++)
|
||||
{
|
||||
for (direction cmptJ = 0; cmptJ < nCmpts; cmptJ++)
|
||||
{
|
||||
forAll(pipcu, faceI)
|
||||
{
|
||||
pcoupleUpper[faceI](localDirI, localDirJ) +=
|
||||
pipcu[faceI](cmptI, cmptJ);
|
||||
pcoupleLower[faceI](localDirI, localDirJ) +=
|
||||
pipcl[faceI](cmptI, cmptJ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reset local directions for other patches
|
||||
localDirI = UEqnDir;
|
||||
localDirJ = UEqnDir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::BlockSolverPerformance<Type> fvBlockMatrix<Type>::solve
|
||||
Foam::BlockSolverPerformance<Type> Foam::fvBlockMatrix<Type>::solve
|
||||
(
|
||||
const dictionary& solverControls
|
||||
)
|
||||
|
@ -1057,7 +844,7 @@ Foam::BlockSolverPerformance<Type> fvBlockMatrix<Type>::solve
|
|||
|
||||
|
||||
template<class Type>
|
||||
Foam::BlockSolverPerformance<Type> fvBlockMatrix<Type>::solve()
|
||||
Foam::BlockSolverPerformance<Type> Foam::fvBlockMatrix<Type>::solve()
|
||||
{
|
||||
return solve(psi_.mesh().solutionDict().solverDict(psi_.name()));
|
||||
}
|
||||
|
|
|
@ -26,11 +26,12 @@ Class
|
|||
|
||||
Description
|
||||
fvBlockMatrix is an extension of fvMatrix for block coupled types. It holds
|
||||
general insertion and retrieval tools for block coupling along with specific
|
||||
general insertion and retrieval tools for block coupling and specific
|
||||
functions for p-U coupling.
|
||||
|
||||
Author
|
||||
Vuko Vukcevic, FMENA Zagreb.
|
||||
Update by Hrvoje Jasak
|
||||
|
||||
SourceFiles
|
||||
fvBlockMatrix.C
|
||||
|
@ -112,14 +113,13 @@ class fvBlockMatrix
|
|||
|
||||
// Insertion functions for fvScalarMatrix into off-diagonal positions
|
||||
// (coupling matrices)
|
||||
// These two functions are dubious. Reconsider. HJ, 17/July/2014.
|
||||
|
||||
//- Insert coupling matrix diag and source into this fvBlockMatrix
|
||||
void insertCouplingDiagSource
|
||||
//- Insert coupling matrix diag element into this fvBlockMatrix
|
||||
void insertCouplingDiag
|
||||
(
|
||||
const direction dirI,
|
||||
const direction dirJ,
|
||||
const fvScalarMatrix& matrix
|
||||
const scalarField& coeffIJ
|
||||
);
|
||||
|
||||
//- Insert coupling matrix lower and upper into this fvBlockMatrix
|
||||
|
@ -144,8 +144,8 @@ class fvBlockMatrix
|
|||
const bool incrementColumnDir
|
||||
);
|
||||
|
||||
//- Insert source and coupling coeffs of BlockLduSystem (obtained by
|
||||
// implicit grad/div operator) into this fvBlockMatrix
|
||||
//- Insert source and coupling coeffs of BlockLduSystem
|
||||
// (eg. obtained by implicit grad/div operator)
|
||||
template<class blockType, class fieldType>
|
||||
void insertBoundaryContributions
|
||||
(
|
||||
|
@ -192,7 +192,7 @@ public:
|
|||
|
||||
// Insertion and retrieval public tools
|
||||
|
||||
//- Retrieve part of internal (solved) field from this fvBlockMatrix
|
||||
//- Retrieve part of internal field from this fvBlockMatrix
|
||||
template<class fieldType>
|
||||
void retrieveSolution
|
||||
(
|
||||
|
@ -220,12 +220,13 @@ public:
|
|||
);
|
||||
|
||||
//- Insert scalar equation coupling into this fvBlockMatrix
|
||||
// Not tested: VV, 10/July/2014
|
||||
// Source compensation is done in function updateSourceCoupling()
|
||||
// after all coupling terms are added. HJ, 27/Apr/2015
|
||||
void insertEquationCoupling
|
||||
(
|
||||
const direction dirI,
|
||||
const direction dirJ,
|
||||
const fvScalarMatrix& matrix
|
||||
const scalarField& coeffIJ
|
||||
);
|
||||
|
||||
//- Add field into block field
|
||||
|
@ -237,20 +238,11 @@ public:
|
|||
);
|
||||
|
||||
//- Update coupling of block system.
|
||||
// Subtracts the block-coefficient coupling as specified by the user
|
||||
// from the source, leaving the implicit update given by
|
||||
// Subtracts the block-coefficient coupling as specified by the
|
||||
// user from the source, leaving the implicit update given by
|
||||
// linearisation
|
||||
void updateSourceCoupling();
|
||||
|
||||
//- Insert Picard tensor term that comes from Picard linearisation
|
||||
// of convection term in momentum equation. VV, 21/July/2014.
|
||||
void insertPicardTensor
|
||||
(
|
||||
const direction UEqnDir,
|
||||
const volVectorField& U,
|
||||
const surfaceScalarField& phi
|
||||
);
|
||||
|
||||
|
||||
// Solver calls for fvBlockMatrix
|
||||
|
||||
|
|
Reference in a new issue