mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: improve procLduMatrix streaming and assembly of LUscalarMatrix
- reduce local overhead prior to sending for master assembly - non-blocking mode when assembling solution vector - automatic resizing of pivots
This commit is contained in:
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
Copyright (C) 2020 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2024 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -42,17 +42,16 @@ namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::LUscalarMatrix::LUscalarMatrix()
|
||||
Foam::LUscalarMatrix::LUscalarMatrix() noexcept
|
||||
:
|
||||
comm_(UPstream::worldComm)
|
||||
{}
|
||||
|
||||
|
||||
Foam::LUscalarMatrix::LUscalarMatrix(const scalarSquareMatrix& matrix)
|
||||
Foam::LUscalarMatrix::LUscalarMatrix(const scalarSquareMatrix& mat)
|
||||
:
|
||||
scalarSquareMatrix(matrix),
|
||||
comm_(UPstream::worldComm),
|
||||
pivotIndices_(m())
|
||||
scalarSquareMatrix(mat),
|
||||
comm_(UPstream::worldComm)
|
||||
{
|
||||
LUDecompose(*this, pivotIndices_);
|
||||
}
|
||||
@ -69,13 +68,14 @@ Foam::LUscalarMatrix::LUscalarMatrix
|
||||
{
|
||||
if (UPstream::parRun())
|
||||
{
|
||||
PtrList<procLduMatrix> lduMatrices(UPstream::nProcs(comm_));
|
||||
|
||||
label lduMatrixi = 0;
|
||||
PtrList<procLduMatrix> lduMatrices
|
||||
(
|
||||
UPstream::master(comm_) ? UPstream::nProcs(comm_) : 1
|
||||
);
|
||||
|
||||
lduMatrices.set
|
||||
(
|
||||
lduMatrixi++,
|
||||
0, // rank-local matrix (and/or master)
|
||||
new procLduMatrix
|
||||
(
|
||||
ldum,
|
||||
@ -88,101 +88,66 @@ Foam::LUscalarMatrix::LUscalarMatrix
|
||||
{
|
||||
for (const int proci : UPstream::subProcs(comm_))
|
||||
{
|
||||
lduMatrices.set
|
||||
(
|
||||
lduMatrixi++,
|
||||
new procLduMatrix
|
||||
(
|
||||
IPstream
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
proci,
|
||||
0, // bufSize
|
||||
UPstream::msgType(),
|
||||
comm_
|
||||
)()
|
||||
)
|
||||
);
|
||||
auto& mat = lduMatrices.emplace_set(proci);
|
||||
|
||||
IPstream::recv(mat, proci, UPstream::msgType(), comm_);
|
||||
}
|
||||
|
||||
convert(lduMatrices);
|
||||
}
|
||||
else
|
||||
{
|
||||
OPstream toMaster
|
||||
OPstream::send
|
||||
(
|
||||
UPstream::commsTypes::scheduled,
|
||||
lduMatrices[0], // rank-local matrix
|
||||
UPstream::masterNo(),
|
||||
0, // bufSize
|
||||
UPstream::msgType(),
|
||||
comm_
|
||||
);
|
||||
procLduMatrix cldum
|
||||
(
|
||||
ldum,
|
||||
interfaceCoeffs,
|
||||
interfaces
|
||||
);
|
||||
toMaster<< cldum;
|
||||
|
||||
}
|
||||
|
||||
if (UPstream::master(comm_))
|
||||
{
|
||||
label nCells = 0;
|
||||
forAll(lduMatrices, i)
|
||||
{
|
||||
nCells += lduMatrices[i].size();
|
||||
}
|
||||
|
||||
scalarSquareMatrix m(nCells, 0.0);
|
||||
transfer(m);
|
||||
convert(lduMatrices);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
label nCells = ldum.lduAddr().size();
|
||||
scalarSquareMatrix m(nCells, Zero);
|
||||
transfer(m);
|
||||
convert(ldum, interfaceCoeffs, interfaces);
|
||||
}
|
||||
|
||||
|
||||
if (debug && UPstream::master(comm_))
|
||||
{
|
||||
const label numRows = nRows();
|
||||
const label numCols = nCols();
|
||||
|
||||
Pout<< "LUscalarMatrix : size:" << numRows << endl;
|
||||
for (label rowi = 0; rowi < numRows; ++rowi)
|
||||
{
|
||||
const scalar* row = operator[](rowi);
|
||||
|
||||
Pout<< "cell:" << rowi << " diagCoeff:" << row[rowi] << nl;
|
||||
|
||||
Pout<< " connects to upper cells :";
|
||||
for (label coli = rowi+1; coli < numCols; ++coli)
|
||||
{
|
||||
if (mag(row[coli]) > SMALL)
|
||||
{
|
||||
Pout<< ' ' << coli << " (coeff:" << row[coli] << ')';
|
||||
}
|
||||
}
|
||||
Pout<< nl;
|
||||
Pout<< " connects to lower cells :";
|
||||
for (label coli = 0; coli < rowi; ++coli)
|
||||
{
|
||||
if (mag(row[coli]) > SMALL)
|
||||
{
|
||||
Pout<< ' ' << coli << " (coeff:" << row[coli] << ')';
|
||||
}
|
||||
}
|
||||
Pout<< nl;
|
||||
}
|
||||
Pout<< endl;
|
||||
}
|
||||
|
||||
if (UPstream::master(comm_))
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
const label numRows = m();
|
||||
const label numCols = n();
|
||||
|
||||
Pout<< "LUscalarMatrix : size:" << numRows << endl;
|
||||
for (label rowi = 0; rowi < numRows; ++rowi)
|
||||
{
|
||||
const scalar* row = operator[](rowi);
|
||||
|
||||
Pout<< "cell:" << rowi << " diagCoeff:" << row[rowi] << endl;
|
||||
|
||||
Pout<< " connects to upper cells :";
|
||||
for (label coli = rowi+1; coli < numCols; ++coli)
|
||||
{
|
||||
if (mag(row[coli]) > SMALL)
|
||||
{
|
||||
Pout<< ' ' << coli << " (coeff:" << row[coli] << ')';
|
||||
}
|
||||
}
|
||||
Pout<< endl;
|
||||
Pout<< " connects to lower cells :";
|
||||
for (label coli = 0; coli < rowi; ++coli)
|
||||
{
|
||||
if (mag(row[coli]) > SMALL)
|
||||
{
|
||||
Pout<< ' ' << coli << " (coeff:" << row[coli] << ')';
|
||||
}
|
||||
}
|
||||
Pout<< nl;
|
||||
}
|
||||
Pout<< nl;
|
||||
}
|
||||
|
||||
pivotIndices_.setSize(m());
|
||||
LUDecompose(*this, pivotIndices_);
|
||||
}
|
||||
}
|
||||
@ -197,6 +162,10 @@ void Foam::LUscalarMatrix::convert
|
||||
const lduInterfaceFieldPtrsList& interfaces
|
||||
)
|
||||
{
|
||||
// Resize and fill with zero
|
||||
scalarSquareMatrix::resize_nocopy(ldum.lduAddr().size());
|
||||
scalarSquareMatrix::operator=(Foam::zero{});
|
||||
|
||||
const label* __restrict__ uPtr = ldum.lduAddr().upperAddr().begin();
|
||||
const label* __restrict__ lPtr = ldum.lduAddr().lowerAddr().begin();
|
||||
|
||||
@ -259,14 +228,26 @@ void Foam::LUscalarMatrix::convert
|
||||
const PtrList<procLduMatrix>& lduMatrices
|
||||
)
|
||||
{
|
||||
procOffsets_.setSize(lduMatrices.size() + 1);
|
||||
procOffsets_[0] = 0;
|
||||
procOffsets_.resize_nocopy(lduMatrices.size() + 1);
|
||||
|
||||
forAll(lduMatrices, ldumi)
|
||||
{
|
||||
procOffsets_[ldumi+1] = procOffsets_[ldumi] + lduMatrices[ldumi].size();
|
||||
auto iter = procOffsets_.begin();
|
||||
|
||||
label nCellsTotal = 0;
|
||||
*iter++ = nCellsTotal;
|
||||
|
||||
for (const auto& mat : lduMatrices)
|
||||
{
|
||||
nCellsTotal += mat.size();
|
||||
*iter++ = nCellsTotal;
|
||||
}
|
||||
|
||||
// Resize and fill with zero
|
||||
scalarSquareMatrix::resize_nocopy(nCellsTotal);
|
||||
scalarSquareMatrix::operator=(Foam::zero{});
|
||||
}
|
||||
|
||||
|
||||
forAll(lduMatrices, ldumi)
|
||||
{
|
||||
const procLduMatrix& lduMatrixi = lduMatrices[ldumi];
|
||||
@ -400,10 +381,9 @@ void Foam::LUscalarMatrix::printDiagonalDominance() const
|
||||
}
|
||||
|
||||
|
||||
void Foam::LUscalarMatrix::decompose(const scalarSquareMatrix& M)
|
||||
void Foam::LUscalarMatrix::decompose(const scalarSquareMatrix& mat)
|
||||
{
|
||||
scalarSquareMatrix::operator=(M);
|
||||
pivotIndices_.setSize(m());
|
||||
scalarSquareMatrix::operator=(mat);
|
||||
LUDecompose(*this, pivotIndices_);
|
||||
}
|
||||
|
||||
|
||||
@ -34,8 +34,8 @@ SourceFiles
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef LUscalarMatrix_H
|
||||
#define LUscalarMatrix_H
|
||||
#ifndef Foam_LUscalarMatrix_H
|
||||
#define Foam_LUscalarMatrix_H
|
||||
|
||||
#include "scalarMatrices.H"
|
||||
#include "labelList.H"
|
||||
@ -47,6 +47,7 @@ SourceFiles
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class lduMatrix;
|
||||
class procLduMatrix;
|
||||
|
||||
@ -58,7 +59,7 @@ class LUscalarMatrix
|
||||
:
|
||||
public scalarSquareMatrix
|
||||
{
|
||||
// Private data
|
||||
// Private Data
|
||||
|
||||
//- Communicator to use
|
||||
const label comm_;
|
||||
@ -70,7 +71,7 @@ class LUscalarMatrix
|
||||
labelList pivotIndices_;
|
||||
|
||||
|
||||
// Private member functions
|
||||
// Private Member Functions
|
||||
|
||||
//- Convert the given lduMatrix into this LUscalarMatrix
|
||||
void convert
|
||||
@ -81,12 +82,12 @@ class LUscalarMatrix
|
||||
);
|
||||
|
||||
//- Convert the given list of procLduMatrix into this LUscalarMatrix
|
||||
// on the master processor
|
||||
//- on the master processor
|
||||
void convert(const PtrList<procLduMatrix>& lduMatrices);
|
||||
|
||||
|
||||
//- Print the ratio of the mag-sum of the off-diagonal coefficients
|
||||
// to the mag-diagonal
|
||||
//- to the mag-diagonal
|
||||
void printDiagonalDominance() const;
|
||||
|
||||
|
||||
@ -98,13 +99,14 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct null
|
||||
LUscalarMatrix();
|
||||
//- Default construct
|
||||
LUscalarMatrix() noexcept;
|
||||
|
||||
//- Construct from and perform LU decomposition of the matrix M
|
||||
LUscalarMatrix(const scalarSquareMatrix& M);
|
||||
//- Construct from and perform LU decomposition of the given matrix
|
||||
explicit LUscalarMatrix(const scalarSquareMatrix& mat);
|
||||
|
||||
//- Construct from lduMatrix and perform LU decomposition
|
||||
//- Construct from lduMatrix and perform LU decomposition.
|
||||
//- In parallel it assembles the matrix on the master.
|
||||
LUscalarMatrix
|
||||
(
|
||||
const lduMatrix& ldum,
|
||||
@ -115,8 +117,8 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Perform the LU decomposition of the matrix M
|
||||
void decompose(const scalarSquareMatrix& M);
|
||||
//- Perform the LU decomposition of the matrix
|
||||
void decompose(const scalarSquareMatrix& mat);
|
||||
|
||||
//- Solve the linear system with the given source
|
||||
// and returning the solution in the Field argument x.
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||
Copyright (C) 2019-2020 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2024 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -44,79 +44,141 @@ void Foam::LUscalarMatrix::solve
|
||||
x = source;
|
||||
}
|
||||
|
||||
if (Pstream::parRun())
|
||||
const auto tag = UPstream::msgType();
|
||||
|
||||
if (UPstream::parRun())
|
||||
{
|
||||
List<Type> X; // scratch space (on master)
|
||||
List<Type> allx; // scratch space (on master)
|
||||
|
||||
if (Pstream::master(comm_))
|
||||
const label startOfRequests = UPstream::nRequests();
|
||||
|
||||
// Like globalIndex::gather()
|
||||
if (UPstream::master(comm_))
|
||||
{
|
||||
X.resize(m());
|
||||
allx.resize(m());
|
||||
|
||||
SubList<Type>(X, x.size()) = x;
|
||||
SubList<Type>(allx, x.size()) = x;
|
||||
|
||||
for (const int proci : Pstream::subProcs(comm_))
|
||||
for (const int proci : UPstream::subProcs(comm_))
|
||||
{
|
||||
UIPstream::read
|
||||
SubList<Type> procSlot
|
||||
(
|
||||
Pstream::commsTypes::scheduled,
|
||||
proci,
|
||||
reinterpret_cast<char*>
|
||||
(
|
||||
&(X[procOffsets_[proci]])
|
||||
),
|
||||
(procOffsets_[proci+1]-procOffsets_[proci])*sizeof(Type),
|
||||
Pstream::msgType(),
|
||||
comm_
|
||||
allx,
|
||||
procOffsets_[proci+1]-procOffsets_[proci],
|
||||
procOffsets_[proci]
|
||||
);
|
||||
|
||||
if (procSlot.empty())
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
else if (is_contiguous<Type>::value)
|
||||
{
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::nonBlocking,
|
||||
proci,
|
||||
procSlot.data_bytes(),
|
||||
procSlot.size_bytes(),
|
||||
tag,
|
||||
comm_
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPstream::recv(procSlot, proci, tag, comm_);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UOPstream::write
|
||||
(
|
||||
Pstream::commsTypes::scheduled,
|
||||
Pstream::masterNo(),
|
||||
x.cdata_bytes(),
|
||||
x.byteSize(),
|
||||
Pstream::msgType(),
|
||||
comm_
|
||||
);
|
||||
}
|
||||
|
||||
if (Pstream::master(comm_))
|
||||
{
|
||||
LUBacksubstitute(*this, pivotIndices_, X);
|
||||
|
||||
x = SubList<Type>(X, x.size());
|
||||
|
||||
for (const int proci : Pstream::subProcs(comm_))
|
||||
if (x.empty())
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
else if (is_contiguous<Type>::value)
|
||||
{
|
||||
UOPstream::write
|
||||
(
|
||||
Pstream::commsTypes::scheduled,
|
||||
proci,
|
||||
reinterpret_cast<const char*>
|
||||
(
|
||||
&(X[procOffsets_[proci]])
|
||||
),
|
||||
(procOffsets_[proci+1]-procOffsets_[proci])*sizeof(Type),
|
||||
Pstream::msgType(),
|
||||
UPstream::commsTypes::nonBlocking,
|
||||
UPstream::masterNo(),
|
||||
x.cdata_bytes(),
|
||||
x.size_bytes(),
|
||||
tag,
|
||||
comm_
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
OPstream::send(x, UPstream::masterNo(), tag, comm_);
|
||||
}
|
||||
}
|
||||
|
||||
UPstream::waitRequests(startOfRequests);
|
||||
|
||||
// LUBacksubstitute and then like globalIndex::scatter()
|
||||
if (UPstream::master(comm_))
|
||||
{
|
||||
LUBacksubstitute(*this, pivotIndices_, allx);
|
||||
|
||||
x = SubList<Type>(allx, x.size());
|
||||
|
||||
for (const int proci : UPstream::subProcs(comm_))
|
||||
{
|
||||
SubList<Type> procSlot
|
||||
(
|
||||
allx,
|
||||
procOffsets_[proci+1]-procOffsets_[proci],
|
||||
procOffsets_[proci]
|
||||
);
|
||||
|
||||
if (procSlot.empty())
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
else if (is_contiguous<Type>::value)
|
||||
{
|
||||
UOPstream::write
|
||||
(
|
||||
UPstream::commsTypes::nonBlocking,
|
||||
proci,
|
||||
procSlot.cdata_bytes(),
|
||||
procSlot.size_bytes(),
|
||||
tag,
|
||||
comm_
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
OPstream::send(procSlot, proci, tag, comm_);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UIPstream::read
|
||||
(
|
||||
Pstream::commsTypes::scheduled,
|
||||
Pstream::masterNo(),
|
||||
x.data_bytes(),
|
||||
x.byteSize(),
|
||||
Pstream::msgType(),
|
||||
comm_
|
||||
);
|
||||
if (x.empty())
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
else if (is_contiguous<Type>::value)
|
||||
{
|
||||
UIPstream::read
|
||||
(
|
||||
UPstream::commsTypes::nonBlocking,
|
||||
UPstream::masterNo(),
|
||||
x.data_bytes(),
|
||||
x.size_bytes(),
|
||||
tag,
|
||||
comm_
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
IPstream::recv(x, UPstream::masterNo(), tag, comm_);
|
||||
}
|
||||
}
|
||||
|
||||
UPstream::waitRequests(startOfRequests);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -131,7 +193,7 @@ Foam::tmp<Foam::Field<Type>> Foam::LUscalarMatrix::solve
|
||||
const UList<Type>& source
|
||||
) const
|
||||
{
|
||||
auto tx(tmp<Field<Type>>::New(m()));
|
||||
auto tx = tmp<Field<Type>>::New(m());
|
||||
|
||||
solve(tx.ref(), source);
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||
Copyright (C) 2024 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -69,27 +70,47 @@ Foam::procLduInterface::procLduInterface
|
||||
|
||||
|
||||
Foam::procLduInterface::procLduInterface(Istream& is)
|
||||
:
|
||||
faceCells_(is),
|
||||
coeffs_(is),
|
||||
myProcNo_(readLabel(is)),
|
||||
neighbProcNo_(readLabel(is)),
|
||||
tag_(readLabel(is)),
|
||||
comm_(readLabel(is))
|
||||
{}
|
||||
{
|
||||
read(is);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::procLduInterface::read(Istream& is)
|
||||
{
|
||||
is >> faceCells_
|
||||
>> coeffs_
|
||||
>> myProcNo_
|
||||
>> neighbProcNo_
|
||||
>> tag_
|
||||
>> comm_;
|
||||
}
|
||||
|
||||
|
||||
void Foam::procLduInterface::write(Ostream& os) const
|
||||
{
|
||||
os << faceCells_
|
||||
<< coeffs_
|
||||
<< myProcNo_
|
||||
<< neighbProcNo_
|
||||
<< tag_
|
||||
<< comm_;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const procLduInterface& cldui)
|
||||
Foam::Istream& Foam::operator>>(Istream& is, procLduInterface& intf)
|
||||
{
|
||||
os << cldui.faceCells_
|
||||
<< cldui.coeffs_
|
||||
<< cldui.myProcNo_
|
||||
<< cldui.neighbProcNo_
|
||||
<< cldui.tag_
|
||||
<< cldui.comm_;
|
||||
intf.read(is);
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const procLduInterface& intf)
|
||||
{
|
||||
intf.write(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2024 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -49,10 +50,11 @@ namespace Foam
|
||||
class lduInterfaceField;
|
||||
class procLduInterface;
|
||||
|
||||
Istream& operator>>(Istream&, procLduInterface&);
|
||||
Ostream& operator<<(Ostream&, const procLduInterface&);
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class procLduInterface Declaration
|
||||
Class procLduInterface Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class procLduInterface
|
||||
@ -68,6 +70,7 @@ class procLduInterface
|
||||
|
||||
public:
|
||||
|
||||
//- Friendship
|
||||
friend class LUscalarMatrix;
|
||||
|
||||
|
||||
@ -85,7 +88,8 @@ public:
|
||||
const scalarField& coeffs
|
||||
);
|
||||
|
||||
procLduInterface(Istream& is);
|
||||
//- Read construct from Istream
|
||||
explicit procLduInterface(Istream& is);
|
||||
|
||||
autoPtr<procLduInterface> clone()
|
||||
{
|
||||
@ -99,8 +103,12 @@ public:
|
||||
}
|
||||
|
||||
|
||||
// Ostream Operator
|
||||
// IO Operations
|
||||
|
||||
void read(Istream& is);
|
||||
void write(Ostream& os) const;
|
||||
|
||||
friend Istream& operator>>(Istream&, procLduInterface&);
|
||||
friend Ostream& operator<<(Ostream&, const procLduInterface&);
|
||||
};
|
||||
|
||||
|
||||
@ -50,7 +50,7 @@ Foam::procLduMatrix::procLduMatrix
|
||||
|
||||
forAll(interfaces, i)
|
||||
{
|
||||
if (interfaces.set(i))
|
||||
if (interfaces.test(i))
|
||||
{
|
||||
interfaces_.set
|
||||
(
|
||||
@ -67,27 +67,48 @@ Foam::procLduMatrix::procLduMatrix
|
||||
|
||||
|
||||
Foam::procLduMatrix::procLduMatrix(Istream& is)
|
||||
:
|
||||
upperAddr_(is),
|
||||
lowerAddr_(is),
|
||||
diag_(is),
|
||||
upper_(is),
|
||||
lower_(is),
|
||||
interfaces_(is)
|
||||
{}
|
||||
{
|
||||
read(is);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
// void Foam::procLduMatrix::clear()
|
||||
// {
|
||||
// upperAddr_.clear();
|
||||
// lowerAddr_.clear();
|
||||
// diag_.clear();
|
||||
// upper_.clear();
|
||||
// lower_.clear();
|
||||
// interfaces_.clear();
|
||||
// }
|
||||
|
||||
|
||||
void Foam::procLduMatrix::read(Istream& is)
|
||||
{
|
||||
is >> upperAddr_ >> lowerAddr_ >> diag_ >> upper_ >> lower_ >> interfaces_;
|
||||
}
|
||||
|
||||
|
||||
void Foam::procLduMatrix::write(Ostream& os) const
|
||||
{
|
||||
os << upperAddr_ << lowerAddr_ << diag_ << upper_ << lower_ << interfaces_;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const procLduMatrix& cldum)
|
||||
Foam::Istream& Foam::operator>>(Istream& is, procLduMatrix& mat)
|
||||
{
|
||||
os << cldum.upperAddr_
|
||||
<< cldum.lowerAddr_
|
||||
<< cldum.diag_
|
||||
<< cldum.upper_
|
||||
<< cldum.lower_
|
||||
<< cldum.interfaces_;
|
||||
mat.read(is);
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const procLduMatrix& mat)
|
||||
{
|
||||
mat.write(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
Copyright (C) 2024 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -34,8 +35,8 @@ SourceFiles
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef procLduMatrix_H
|
||||
#define procLduMatrix_H
|
||||
#ifndef Foam_procLduMatrix_H
|
||||
#define Foam_procLduMatrix_H
|
||||
|
||||
#include "labelList.H"
|
||||
#include "scalarField.H"
|
||||
@ -47,23 +48,21 @@ SourceFiles
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class procLduMatrix;
|
||||
class procLduInterface;
|
||||
class lduMatrix;
|
||||
|
||||
// Forward declaration of friend functions and operators
|
||||
|
||||
class procLduMatrix;
|
||||
|
||||
Istream& operator>>(Istream&, procLduMatrix&);
|
||||
Ostream& operator<<(Ostream&, const procLduMatrix&);
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class procLduMatrix Declaration
|
||||
Class procLduMatrix Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class procLduMatrix
|
||||
{
|
||||
// Private data
|
||||
// Private Data
|
||||
|
||||
labelList upperAddr_;
|
||||
labelList lowerAddr_;
|
||||
@ -72,20 +71,24 @@ class procLduMatrix
|
||||
scalarField lower_;
|
||||
PtrList<procLduInterface> interfaces_;
|
||||
|
||||
public:
|
||||
|
||||
// Private Member Functions
|
||||
//- Friendship
|
||||
friend class LUscalarMatrix;
|
||||
|
||||
|
||||
// Generated Methods
|
||||
|
||||
//- Default construct
|
||||
procLduMatrix() = default;
|
||||
|
||||
//- No copy construct
|
||||
procLduMatrix(const procLduMatrix&) = delete;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
friend class LUscalarMatrix;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components. Extracts active interfaces
|
||||
procLduMatrix
|
||||
(
|
||||
const lduMatrix& ldum,
|
||||
@ -93,19 +96,26 @@ public:
|
||||
const lduInterfaceFieldPtrsList& interfaces
|
||||
);
|
||||
|
||||
procLduMatrix(Istream& is);
|
||||
//- Read construct from Istream
|
||||
explicit procLduMatrix(Istream& is);
|
||||
|
||||
|
||||
// Member functions
|
||||
// Member Functions
|
||||
|
||||
label size() const
|
||||
label size() const noexcept
|
||||
{
|
||||
return diag_.size();
|
||||
}
|
||||
|
||||
// void clear();
|
||||
|
||||
// Ostream operator
|
||||
|
||||
// IO Operations
|
||||
|
||||
void read(Istream& is);
|
||||
void write(Ostream& os) const;
|
||||
|
||||
friend Istream& operator>>(Istream&, procLduMatrix&);
|
||||
friend Ostream& operator<<(Ostream&, const procLduMatrix&);
|
||||
};
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2013-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2024 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -124,7 +124,7 @@ scalar det(const SquareMatrix<Type>& matrix)
|
||||
{
|
||||
SquareMatrix<Type> matrixTmp = matrix;
|
||||
|
||||
labelList pivotIndices(matrix.m());
|
||||
labelList pivotIndices;
|
||||
label sign;
|
||||
LUDecompose(matrixTmp, pivotIndices, sign);
|
||||
|
||||
@ -136,7 +136,7 @@ scalar det(const SquareMatrix<Type>& matrix)
|
||||
template<class Type>
|
||||
scalar det(SquareMatrix<Type>& matrix)
|
||||
{
|
||||
labelList pivotIndices(matrix.m());
|
||||
labelList pivotIndices;
|
||||
label sign;
|
||||
LUDecompose(matrix, pivotIndices, sign);
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2024 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -48,17 +49,20 @@ void Foam::LUDecompose
|
||||
label& sign
|
||||
)
|
||||
{
|
||||
label m = matrix.m();
|
||||
scalar vv[m];
|
||||
const label size = matrix.m();
|
||||
|
||||
pivotIndices.resize_nocopy(size);
|
||||
|
||||
List<scalar> vv(size);
|
||||
sign = 1;
|
||||
|
||||
for (label i = 0; i < m; ++i)
|
||||
for (label i = 0; i < size; ++i)
|
||||
{
|
||||
scalar largestCoeff = 0.0;
|
||||
scalar temp;
|
||||
const scalar* __restrict__ matrixi = matrix[i];
|
||||
|
||||
for (label j = 0; j < m; ++j)
|
||||
for (label j = 0; j < size; ++j)
|
||||
{
|
||||
if ((temp = mag(matrixi[j])) > largestCoeff)
|
||||
{
|
||||
@ -75,7 +79,7 @@ void Foam::LUDecompose
|
||||
vv[i] = 1.0/largestCoeff;
|
||||
}
|
||||
|
||||
for (label j = 0; j < m; ++j)
|
||||
for (label j = 0; j < size; ++j)
|
||||
{
|
||||
scalar* __restrict__ matrixj = matrix[j];
|
||||
|
||||
@ -94,7 +98,7 @@ void Foam::LUDecompose
|
||||
label iMax = 0;
|
||||
|
||||
scalar largestCoeff = 0.0;
|
||||
for (label i = j; i < m; ++i)
|
||||
for (label i = j; i < size; ++i)
|
||||
{
|
||||
scalar* __restrict__ matrixi = matrix[i];
|
||||
scalar sum = matrixi[j];
|
||||
@ -120,7 +124,7 @@ void Foam::LUDecompose
|
||||
{
|
||||
scalar* __restrict__ matrixiMax = matrix[iMax];
|
||||
|
||||
for (label k = 0; k < m; ++k)
|
||||
for (label k = 0; k < size; ++k)
|
||||
{
|
||||
std::swap(matrixj[k], matrixiMax[k]);
|
||||
}
|
||||
@ -134,11 +138,11 @@ void Foam::LUDecompose
|
||||
matrixj[j] = SMALL;
|
||||
}
|
||||
|
||||
if (j != m-1)
|
||||
if (j != size-1)
|
||||
{
|
||||
scalar rDiag = 1.0/matrixj[j];
|
||||
|
||||
for (label i = j + 1; i < m; ++i)
|
||||
for (label i = j + 1; i < size; ++i)
|
||||
{
|
||||
matrix(i, j) *= rDiag;
|
||||
}
|
||||
@ -150,7 +154,7 @@ void Foam::LUDecompose
|
||||
void Foam::LUDecompose(scalarSymmetricSquareMatrix& matrix)
|
||||
{
|
||||
// Store result in upper triangular part of matrix
|
||||
label size = matrix.m();
|
||||
const label size = matrix.m();
|
||||
|
||||
// Set upper triangular parts to zero.
|
||||
for (label j = 0; j < size; ++j)
|
||||
@ -223,7 +227,7 @@ void Foam::multiply
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
ans = scalarRectangularMatrix(A.m(), C.n(), Zero);
|
||||
ans = scalarRectangularMatrix(A.m(), C.n(), Foam::zero{});
|
||||
|
||||
for (label i = 0; i < A.m(); ++i)
|
||||
{
|
||||
|
||||
@ -74,19 +74,21 @@ void solve
|
||||
const List<Type>& source
|
||||
);
|
||||
|
||||
//- LU decompose the matrix with pivoting
|
||||
//- LU decompose the matrix with pivoting.
|
||||
void LUDecompose
|
||||
(
|
||||
scalarSquareMatrix& matrix,
|
||||
//! [out] size is adjusted as required
|
||||
labelList& pivotIndices
|
||||
);
|
||||
|
||||
//- LU decompose the matrix with pivoting.
|
||||
//- sign is -1 for odd number of row interchanges and 1 for even number.
|
||||
void LUDecompose
|
||||
(
|
||||
scalarSquareMatrix& matrix,
|
||||
//! [out] size is adjusted as required
|
||||
labelList& pivotIndices,
|
||||
//! [out] is -1 for odd number of row interchanges and 1 for even number
|
||||
label& sign
|
||||
);
|
||||
|
||||
|
||||
@ -216,7 +216,7 @@ void Foam::LUsolve
|
||||
List<Type>& sourceSol
|
||||
)
|
||||
{
|
||||
labelList pivotIndices(matrix.m());
|
||||
labelList pivotIndices;
|
||||
LUDecompose(matrix, pivotIndices);
|
||||
LUBacksubstitute(matrix, pivotIndices, sourceSol);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user