mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
LLTMatrix, LUscalarMatrix, QRMatrix: Provided consistent 'solve' interface
This commit is contained in:
@ -24,6 +24,7 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "scalarMatrices.H"
|
#include "scalarMatrices.H"
|
||||||
|
#include "LUscalarMatrix.H"
|
||||||
#include "LLTMatrix.H"
|
#include "LLTMatrix.H"
|
||||||
#include "QRMatrix.H"
|
#include "QRMatrix.H"
|
||||||
#include "vector.H"
|
#include "vector.H"
|
||||||
@ -113,70 +114,53 @@ int main(int argc, char *argv[])
|
|||||||
Info<< "Solution = " << rhs << endl;
|
Info<< "Solution = " << rhs << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
scalarSquareMatrix squareMatrix(3, Zero);
|
||||||
|
|
||||||
|
squareMatrix(0, 0) = 4;
|
||||||
|
squareMatrix(0, 1) = 12;
|
||||||
|
squareMatrix(0, 2) = -16;
|
||||||
|
squareMatrix(1, 0) = 12;
|
||||||
|
squareMatrix(1, 1) = 37;
|
||||||
|
squareMatrix(1, 2) = -43;
|
||||||
|
squareMatrix(2, 0) = -16;
|
||||||
|
squareMatrix(2, 1) = -43;
|
||||||
|
squareMatrix(2, 2) = 98;
|
||||||
|
|
||||||
|
Info<< nl << "Square Matrix = " << squareMatrix << endl;
|
||||||
|
|
||||||
|
const scalarField source(3, 1);
|
||||||
|
|
||||||
{
|
{
|
||||||
scalarSquareMatrix squareMatrix(3, Zero);
|
{
|
||||||
|
scalarSquareMatrix sm(squareMatrix);
|
||||||
squareMatrix(0, 0) = 4;
|
Info<< "det = " << det(sm) << endl;
|
||||||
squareMatrix(0, 1) = 12;
|
}
|
||||||
squareMatrix(0, 2) = -16;
|
|
||||||
squareMatrix(1, 0) = 12;
|
|
||||||
squareMatrix(1, 1) = 37;
|
|
||||||
squareMatrix(1, 2) = -43;
|
|
||||||
squareMatrix(2, 0) = -16;
|
|
||||||
squareMatrix(2, 1) = -43;
|
|
||||||
squareMatrix(2, 2) = 98;
|
|
||||||
|
|
||||||
const scalarSquareMatrix squareMatrixCopy = squareMatrix;
|
|
||||||
Info<< nl << "Square Matrix = " << squareMatrix << endl;
|
|
||||||
|
|
||||||
Info<< "det = " << det(squareMatrixCopy) << endl;
|
|
||||||
|
|
||||||
|
scalarSquareMatrix sm(squareMatrix);
|
||||||
labelList rhs(3, 0);
|
labelList rhs(3, 0);
|
||||||
label sign;
|
label sign;
|
||||||
LUDecompose(squareMatrix, rhs, sign);
|
LUDecompose(sm, rhs, sign);
|
||||||
|
|
||||||
Info<< "Decomposition = " << squareMatrix << endl;
|
Info<< "Decomposition = " << sm << endl;
|
||||||
Info<< "Pivots = " << rhs << endl;
|
Info<< "Pivots = " << rhs << endl;
|
||||||
Info<< "Sign = " << sign << endl;
|
Info<< "Sign = " << sign << endl;
|
||||||
Info<< "det = " << detDecomposed(squareMatrix, sign) << endl;
|
Info<< "det = " << detDecomposed(sm, sign) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
scalarSquareMatrix squareMatrix(3, Zero);
|
LUscalarMatrix LU(squareMatrix);
|
||||||
|
scalarField x((LU.solve(source));
|
||||||
squareMatrix(0, 0) = 4;
|
Info<< "LU solve residual " << (squareMatrix*x - source) << endl;
|
||||||
squareMatrix(0, 1) = 12;
|
}
|
||||||
squareMatrix(0, 2) = -16;
|
|
||||||
squareMatrix(1, 0) = 12;
|
|
||||||
squareMatrix(1, 1) = 37;
|
|
||||||
squareMatrix(1, 2) = -43;
|
|
||||||
squareMatrix(2, 0) = -16;
|
|
||||||
squareMatrix(2, 1) = -43;
|
|
||||||
squareMatrix(2, 2) = 98;
|
|
||||||
|
|
||||||
scalarField source(3, 1);
|
|
||||||
|
|
||||||
|
{
|
||||||
LLTMatrix<scalar> LLT(squareMatrix);
|
LLTMatrix<scalar> LLT(squareMatrix);
|
||||||
scalarField x(LLT.solve(source));
|
scalarField x(LLT.solve(source));
|
||||||
|
|
||||||
Info<< "LLT solve residual " << (squareMatrix*x - source) << endl;
|
Info<< "LLT solve residual " << (squareMatrix*x - source) << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
scalarSquareMatrix squareMatrix(3, Zero);
|
|
||||||
|
|
||||||
squareMatrix(0, 0) = 4;
|
|
||||||
squareMatrix(0, 1) = 12;
|
|
||||||
squareMatrix(0, 2) = -16;
|
|
||||||
squareMatrix(1, 0) = 12;
|
|
||||||
squareMatrix(1, 1) = 37;
|
|
||||||
squareMatrix(1, 2) = -43;
|
|
||||||
squareMatrix(2, 0) = -16;
|
|
||||||
squareMatrix(2, 1) = -43;
|
|
||||||
squareMatrix(2, 2) = 98;
|
|
||||||
|
|
||||||
scalarField source(3, 1);
|
|
||||||
|
|
||||||
QRMatrix<scalarSquareMatrix> QR(squareMatrix);
|
QRMatrix<scalarSquareMatrix> QR(squareMatrix);
|
||||||
scalarField x(QR.solve(source));
|
scalarField x(QR.solve(source));
|
||||||
|
|
||||||
@ -184,8 +168,7 @@ int main(int argc, char *argv[])
|
|||||||
<< (squareMatrix*x - source) << endl;
|
<< (squareMatrix*x - source) << endl;
|
||||||
|
|
||||||
Info<< "QR inverse solve residual "
|
Info<< "QR inverse solve residual "
|
||||||
<< (x - QR.inverse()*source) << endl;
|
<< (x - QR.inv()*source) << endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "\nEnd\n" << endl;
|
Info<< "\nEnd\n" << endl;
|
||||||
|
|||||||
@ -95,6 +95,12 @@ void Foam::LLTMatrix<Type>::solve
|
|||||||
const Field<Type>& source
|
const Field<Type>& source
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
// If x and source are different initialize x = source
|
||||||
|
if (&x != &source)
|
||||||
|
{
|
||||||
|
x = source;
|
||||||
|
}
|
||||||
|
|
||||||
const SquareMatrix<Type>& LLT = *this;
|
const SquareMatrix<Type>& LLT = *this;
|
||||||
const label m = LLT.m();
|
const label m = LLT.m();
|
||||||
|
|
||||||
|
|||||||
@ -116,10 +116,16 @@ public:
|
|||||||
//- Perform the LU decomposition of the matrix M
|
//- Perform the LU decomposition of the matrix M
|
||||||
void decompose(const scalarSquareMatrix& M);
|
void decompose(const scalarSquareMatrix& M);
|
||||||
|
|
||||||
//- Solve the matrix using the LU decomposition with pivoting
|
//- Solve the linear system with the given source
|
||||||
// returning the solution in the source
|
// and returning the solution in the Field argument x.
|
||||||
template<class T>
|
// This function may be called with the same field for x and source.
|
||||||
void solve(Field<T>& source) const;
|
template<class Type>
|
||||||
|
void solve(Field<Type>& x, const Field<Type>& source) const;
|
||||||
|
|
||||||
|
//- Solve the linear system with the given source
|
||||||
|
// returning the solution
|
||||||
|
template<class Type>
|
||||||
|
tmp<Field<Type>> solve(const Field<Type>& source) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -24,23 +24,34 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "LUscalarMatrix.H"
|
#include "LUscalarMatrix.H"
|
||||||
|
#include "SubField.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::LUscalarMatrix::solve(Field<Type>& sourceSol) const
|
void Foam::LUscalarMatrix::solve
|
||||||
|
(
|
||||||
|
Field<Type>& x,
|
||||||
|
const Field<Type>& source
|
||||||
|
) const
|
||||||
{
|
{
|
||||||
|
// If x and source are different initialize x = source
|
||||||
|
if (&x != &source)
|
||||||
|
{
|
||||||
|
x = source;
|
||||||
|
}
|
||||||
|
|
||||||
if (Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
Field<Type> completeSourceSol(m());
|
Field<Type> X(m());
|
||||||
|
|
||||||
if (Pstream::master(comm_))
|
if (Pstream::master(comm_))
|
||||||
{
|
{
|
||||||
typename Field<Type>::subField
|
typename Field<Type>::subField
|
||||||
(
|
(
|
||||||
completeSourceSol,
|
X,
|
||||||
sourceSol.size()
|
x.size()
|
||||||
).assign(sourceSol);
|
).assign(x);
|
||||||
|
|
||||||
for
|
for
|
||||||
(
|
(
|
||||||
@ -55,7 +66,7 @@ void Foam::LUscalarMatrix::solve(Field<Type>& sourceSol) const
|
|||||||
slave,
|
slave,
|
||||||
reinterpret_cast<char*>
|
reinterpret_cast<char*>
|
||||||
(
|
(
|
||||||
&(completeSourceSol[procOffsets_[slave]])
|
&(X[procOffsets_[slave]])
|
||||||
),
|
),
|
||||||
(procOffsets_[slave+1]-procOffsets_[slave])*sizeof(Type),
|
(procOffsets_[slave+1]-procOffsets_[slave])*sizeof(Type),
|
||||||
Pstream::msgType(),
|
Pstream::msgType(),
|
||||||
@ -69,8 +80,8 @@ void Foam::LUscalarMatrix::solve(Field<Type>& sourceSol) const
|
|||||||
(
|
(
|
||||||
Pstream::scheduled,
|
Pstream::scheduled,
|
||||||
Pstream::masterNo(),
|
Pstream::masterNo(),
|
||||||
reinterpret_cast<const char*>(sourceSol.begin()),
|
reinterpret_cast<const char*>(x.begin()),
|
||||||
sourceSol.byteSize(),
|
x.byteSize(),
|
||||||
Pstream::msgType(),
|
Pstream::msgType(),
|
||||||
comm_
|
comm_
|
||||||
);
|
);
|
||||||
@ -78,12 +89,12 @@ void Foam::LUscalarMatrix::solve(Field<Type>& sourceSol) const
|
|||||||
|
|
||||||
if (Pstream::master(comm_))
|
if (Pstream::master(comm_))
|
||||||
{
|
{
|
||||||
LUBacksubstitute(*this, pivotIndices_, completeSourceSol);
|
LUBacksubstitute(*this, pivotIndices_, X);
|
||||||
|
|
||||||
sourceSol = typename Field<Type>::subField
|
x = typename Field<Type>::subField
|
||||||
(
|
(
|
||||||
completeSourceSol,
|
X,
|
||||||
sourceSol.size()
|
x.size()
|
||||||
);
|
);
|
||||||
|
|
||||||
for
|
for
|
||||||
@ -99,7 +110,7 @@ void Foam::LUscalarMatrix::solve(Field<Type>& sourceSol) const
|
|||||||
slave,
|
slave,
|
||||||
reinterpret_cast<const char*>
|
reinterpret_cast<const char*>
|
||||||
(
|
(
|
||||||
&(completeSourceSol[procOffsets_[slave]])
|
&(X[procOffsets_[slave]])
|
||||||
),
|
),
|
||||||
(procOffsets_[slave + 1]-procOffsets_[slave])*sizeof(Type),
|
(procOffsets_[slave + 1]-procOffsets_[slave])*sizeof(Type),
|
||||||
Pstream::msgType(),
|
Pstream::msgType(),
|
||||||
@ -113,8 +124,8 @@ void Foam::LUscalarMatrix::solve(Field<Type>& sourceSol) const
|
|||||||
(
|
(
|
||||||
Pstream::scheduled,
|
Pstream::scheduled,
|
||||||
Pstream::masterNo(),
|
Pstream::masterNo(),
|
||||||
reinterpret_cast<char*>(sourceSol.begin()),
|
reinterpret_cast<char*>(x.begin()),
|
||||||
sourceSol.byteSize(),
|
x.byteSize(),
|
||||||
Pstream::msgType(),
|
Pstream::msgType(),
|
||||||
comm_
|
comm_
|
||||||
);
|
);
|
||||||
@ -122,9 +133,24 @@ void Foam::LUscalarMatrix::solve(Field<Type>& sourceSol) const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LUBacksubstitute(*this, pivotIndices_, sourceSol);
|
LUBacksubstitute(*this, pivotIndices_, x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::tmp<Foam::Field<Type>> Foam::LUscalarMatrix::solve
|
||||||
|
(
|
||||||
|
const Field<Type>& source
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
tmp<Field<Type>> tx(new Field<Type>(m()));
|
||||||
|
Field<Type>& x = tx.ref();
|
||||||
|
|
||||||
|
solve(x, source);
|
||||||
|
|
||||||
|
return tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -225,7 +225,7 @@ Foam::QRMatrix<MatrixType>::solve
|
|||||||
|
|
||||||
template<class MatrixType>
|
template<class MatrixType>
|
||||||
typename Foam::QRMatrix<MatrixType>::QMatrixType
|
typename Foam::QRMatrix<MatrixType>::QMatrixType
|
||||||
Foam::QRMatrix<MatrixType>::inverse() const
|
Foam::QRMatrix<MatrixType>::inv() const
|
||||||
{
|
{
|
||||||
const label m = Q_.m();
|
const label m = Q_.m();
|
||||||
|
|
||||||
|
|||||||
@ -108,7 +108,7 @@ public:
|
|||||||
tmp<Field<cmptType>> solve(const Field<cmptType>& source) const;
|
tmp<Field<cmptType>> solve(const Field<cmptType>& source) const;
|
||||||
|
|
||||||
//- Return the inverse of a square matrix
|
//- Return the inverse of a square matrix
|
||||||
QMatrixType inverse() const;
|
QMatrixType inv() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -533,8 +533,7 @@ void Foam::GAMGSolver::solveCoarsestLevel
|
|||||||
|
|
||||||
if (directSolveCoarsest_)
|
if (directSolveCoarsest_)
|
||||||
{
|
{
|
||||||
coarsestCorrField = coarsestSource;
|
coarsestLUMatrixPtr_->solve(coarsestCorrField, coarsestSource);
|
||||||
coarsestLUMatrixPtr_->solve(coarsestCorrField);
|
|
||||||
}
|
}
|
||||||
//else if
|
//else if
|
||||||
//(
|
//(
|
||||||
|
|||||||
Reference in New Issue
Block a user