mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: DMD: apply various optimisations
This commit is contained in:
committed by
Andrew Heather
parent
cf3c4f26ce
commit
44ba2d868d
@ -82,13 +82,34 @@ Foam::RectangularMatrix<Foam::scalar> Foam::DMDModels::STDMD::orthonormalise
|
|||||||
RMatrix ez
|
RMatrix ez
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
RMatrix dz(Q_.n(), 1, Zero);
|
List<scalar> dz(Q_.n());
|
||||||
|
const label sz0 = ez.m();
|
||||||
|
const label sz1 = dz.size();
|
||||||
|
|
||||||
for (label i = 0; i < nGramSchmidt_; ++i)
|
for (label i = 0; i < nGramSchmidt_; ++i)
|
||||||
{
|
{
|
||||||
dz = Q_ & ez;
|
// dz = Q_ & ez;
|
||||||
reduce(dz, sumOp<RMatrix>());
|
dz = Zero;
|
||||||
ez -= Q_*dz;
|
for (label i = 0; i < sz0; ++i)
|
||||||
|
{
|
||||||
|
for (label j = 0; j < sz1; ++j)
|
||||||
|
{
|
||||||
|
dz[j] += Q_(i,j)*ez(i,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce(dz, sumOp<List<scalar>>());
|
||||||
|
|
||||||
|
// ez -= Q_*dz;
|
||||||
|
for (label i = 0; i < sz0; ++i)
|
||||||
|
{
|
||||||
|
scalar t = 0;
|
||||||
|
for (label j = 0; j < sz1; ++j)
|
||||||
|
{
|
||||||
|
t += Q_(i,j)*dz[j];
|
||||||
|
}
|
||||||
|
ez(i,0) -= t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ez;
|
return ez;
|
||||||
@ -109,6 +130,34 @@ void Foam::DMDModels::STDMD::expand(const RMatrix& ez, const scalar ezNorm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::DMDModels::STDMD::updateG(const RMatrix& z)
|
||||||
|
{
|
||||||
|
List<scalar> zTilde(Q_.n(), Zero);
|
||||||
|
const label sz0 = z.m();
|
||||||
|
const label sz1 = zTilde.size();
|
||||||
|
|
||||||
|
// zTilde = Q_ & z;
|
||||||
|
for (label i = 0; i < sz0; ++i)
|
||||||
|
{
|
||||||
|
for (label j = 0; j < sz1; ++j)
|
||||||
|
{
|
||||||
|
zTilde[j] += Q_(i,j)*z(i,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce(zTilde, sumOp<List<scalar>>());
|
||||||
|
|
||||||
|
// G_ += SMatrix(zTilde^zTilde);
|
||||||
|
for (label i = 0; i < G_.m(); ++i)
|
||||||
|
{
|
||||||
|
for (label j = 0; j < G_.n(); ++j)
|
||||||
|
{
|
||||||
|
G_(i, j) += zTilde[i]*zTilde[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::DMDModels::STDMD::compress()
|
void Foam::DMDModels::STDMD::compress()
|
||||||
{
|
{
|
||||||
Info<< tab << "Compressing orthonormal basis for field: " << fieldName_
|
Info<< tab << "Compressing orthonormal basis for field: " << fieldName_
|
||||||
@ -234,9 +283,10 @@ reducedKoopmanOperator()
|
|||||||
// on Rx of receiver subset masters
|
// on Rx of receiver subset masters
|
||||||
QRMatrix<RMatrix> QRM
|
QRMatrix<RMatrix> QRM
|
||||||
(
|
(
|
||||||
Rx,
|
|
||||||
QRMatrix<RMatrix>::modes::ECONOMY,
|
QRMatrix<RMatrix>::modes::ECONOMY,
|
||||||
QRMatrix<RMatrix>::outputs::ONLY_R
|
QRMatrix<RMatrix>::outputs::ONLY_R,
|
||||||
|
QRMatrix<RMatrix>::pivoting::FALSE,
|
||||||
|
Rx
|
||||||
);
|
);
|
||||||
RMatrix& R = QRM.R();
|
RMatrix& R = QRM.R();
|
||||||
Rx.transfer(R);
|
Rx.transfer(R);
|
||||||
@ -258,6 +308,7 @@ reducedKoopmanOperator()
|
|||||||
|
|
||||||
pBufs.finishedSends();
|
pBufs.finishedSends();
|
||||||
|
|
||||||
|
|
||||||
// Receive interim Rx by the master, and apply final operations
|
// Receive interim Rx by the master, and apply final operations
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
@ -289,9 +340,10 @@ reducedKoopmanOperator()
|
|||||||
{
|
{
|
||||||
QRMatrix<RMatrix> QRM
|
QRMatrix<RMatrix> QRM
|
||||||
(
|
(
|
||||||
Rx,
|
|
||||||
QRMatrix<RMatrix>::modes::ECONOMY,
|
QRMatrix<RMatrix>::modes::ECONOMY,
|
||||||
QRMatrix<RMatrix>::outputs::ONLY_R
|
QRMatrix<RMatrix>::outputs::ONLY_R,
|
||||||
|
QRMatrix<RMatrix>::pivoting::FALSE,
|
||||||
|
Rx
|
||||||
);
|
);
|
||||||
RMatrix& R = QRM.R();
|
RMatrix& R = QRM.R();
|
||||||
Rx.transfer(R);
|
Rx.transfer(R);
|
||||||
@ -410,8 +462,6 @@ bool Foam::DMDModels::STDMD::eigendecomposition(SMatrix& Atilde)
|
|||||||
Pstream::scatter(evals_);
|
Pstream::scatter(evals_);
|
||||||
Pstream::scatter(evecs_);
|
Pstream::scatter(evecs_);
|
||||||
|
|
||||||
Atilde.clear();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,7 +510,7 @@ void Foam::DMDModels::STDMD::frequencies()
|
|||||||
|
|
||||||
void Foam::DMDModels::STDMD::amplitudes()
|
void Foam::DMDModels::STDMD::amplitudes()
|
||||||
{
|
{
|
||||||
const IOField<scalar> snapshot0
|
IOField<scalar> snapshot0
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
@ -473,29 +523,47 @@ void Foam::DMDModels::STDMD::amplitudes()
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
RMatrix snapshot(1, 1, Zero);
|
// RxInv^T*(Qupper^T*snapshot0)
|
||||||
if (!empty_)
|
// tmp = (Qupper^T*snapshot0)
|
||||||
{
|
List<scalar> tmp(Qupper_.n(), Zero);
|
||||||
snapshot.resize(Qupper_.m(), 1);
|
const label sz0 = snapshot0.size();
|
||||||
std::copy(snapshot0.cbegin(), snapshot0.cend(), snapshot.begin());
|
const label sz1 = tmp.size();
|
||||||
}
|
|
||||||
|
|
||||||
RMatrix R((RxInv_.T()^Qupper_)*snapshot);
|
for (label i = 0; i < sz0; ++i)
|
||||||
reduce(R, sumOp<RMatrix>());
|
{
|
||||||
|
for (label j = 0; j < sz1; ++j)
|
||||||
|
{
|
||||||
|
tmp[j] += Qupper_(i,j)*snapshot0[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
snapshot0.clear();
|
||||||
|
|
||||||
|
// R = RxInv^T*tmp
|
||||||
|
List<scalar> R(Qupper_.n(), Zero);
|
||||||
|
for (label i = 0; i < sz1; ++i)
|
||||||
|
{
|
||||||
|
for (label j = 0; j < R.size(); ++j)
|
||||||
|
{
|
||||||
|
R[j] += RxInv_(i,j)*tmp[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tmp.clear();
|
||||||
|
|
||||||
|
reduce(R, sumOp<List<scalar>>());
|
||||||
|
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
Info<< tab << "Computing amplitudes" << endl;
|
Info<< tab << "Computing amplitudes" << endl;
|
||||||
|
|
||||||
amps_.resize(R.m());
|
amps_.resize(R.size());
|
||||||
const RCMatrix pEvecs(MatrixTools::pinv(evecs_));
|
const RCMatrix pEvecs(MatrixTools::pinv(evecs_));
|
||||||
|
|
||||||
// amps_ = pEvecs*R;
|
// amps_ = pEvecs*R;
|
||||||
for (label i = 0; i < amps_.size(); ++i)
|
for (label i = 0; i < amps_.size(); ++i)
|
||||||
{
|
{
|
||||||
for (label j = 0; j < R.m(); ++j)
|
for (label j = 0; j < R.size(); ++j)
|
||||||
{
|
{
|
||||||
amps_[i] += pEvecs(i, j)*R(j, 0);
|
amps_[i] += pEvecs(i,j)*R[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -635,6 +703,8 @@ bool Foam::DMDModels::STDMD::dynamics()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Atilde.clear();
|
||||||
|
|
||||||
frequencies();
|
frequencies();
|
||||||
|
|
||||||
amplitudes();
|
amplitudes();
|
||||||
@ -945,12 +1015,7 @@ bool Foam::DMDModels::STDMD::update(const RMatrix& z)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update "G" before the potential orthonormal basis compression
|
// Update "G" before the potential orthonormal basis compression
|
||||||
{
|
updateG(z);
|
||||||
RMatrix zTilde(Q_ & z);
|
|
||||||
reduce(zTilde, sumOp<RMatrix>());
|
|
||||||
|
|
||||||
G_ += SMatrix(zTilde^zTilde);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compress the orthonormal basis if required
|
// Compress the orthonormal basis if required
|
||||||
if (Q_.n() >= maxRank_)
|
if (Q_.n() >= maxRank_)
|
||||||
|
|||||||
@ -349,6 +349,9 @@ class STDMD
|
|||||||
//- to 'G' if '(ezNorm/zNorm > minBasis)'
|
//- to 'G' if '(ezNorm/zNorm > minBasis)'
|
||||||
void expand(const RMatrix& ez, const scalar ezNorm);
|
void expand(const RMatrix& ez, const scalar ezNorm);
|
||||||
|
|
||||||
|
//- Update 'G' before the potential orthonormal basis compression
|
||||||
|
void updateG(const RMatrix& z);
|
||||||
|
|
||||||
//- Compress orthonormal basis for 'Q' and 'G' if '(Q.n()>maxRank)'
|
//- Compress orthonormal basis for 'Q' and 'G' if '(Q.n()>maxRank)'
|
||||||
void compress();
|
void compress();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user