mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
added: MultisegmentWellEquations::extract(SparseMatrixAdapter)
this adds the well matrices to a sparse matrix adapter. this is the core of MultisegmentWell::addWellContributions. use the new method in the implementation.
This commit is contained in:
parent
4a2fcd5f09
commit
de8eedb9a6
@ -137,7 +137,7 @@ namespace Opm
|
|||||||
WellState& well_state,
|
WellState& well_state,
|
||||||
DeferredLogger& deferred_logger) const override;
|
DeferredLogger& deferred_logger) const override;
|
||||||
|
|
||||||
virtual void addWellContributions(SparseMatrixAdapter& jacobian) const override;
|
void addWellContributions(SparseMatrixAdapter& jacobian) const override;
|
||||||
|
|
||||||
virtual void addWellPressureEquations(PressureMatrix& mat,
|
virtual void addWellPressureEquations(PressureMatrix& mat,
|
||||||
const BVector& x,
|
const BVector& x,
|
||||||
|
@ -27,6 +27,9 @@
|
|||||||
#include <opm/common/ErrorMacros.hpp>
|
#include <opm/common/ErrorMacros.hpp>
|
||||||
|
|
||||||
#include <opm/simulators/linalg/bda/WellContributions.hpp>
|
#include <opm/simulators/linalg/bda/WellContributions.hpp>
|
||||||
|
#include <opm/simulators/linalg/istlsparsematrixadapter.hh>
|
||||||
|
#include <opm/simulators/linalg/matrixblock.hh>
|
||||||
|
#include <opm/simulators/linalg/SmallDenseMatrixUtils.hpp>
|
||||||
|
|
||||||
#include <opm/simulators/wells/MSWellHelpers.hpp>
|
#include <opm/simulators/wells/MSWellHelpers.hpp>
|
||||||
#include <opm/simulators/wells/MultisegmentWellGeneric.hpp>
|
#include <opm/simulators/wells/MultisegmentWellGeneric.hpp>
|
||||||
@ -248,8 +251,47 @@ extract(WellContributions& wellContribs) const
|
|||||||
Cvals);
|
Cvals);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Scalar, int numWellEq, int numEq>
|
||||||
|
template<class SparseMatrixAdapter>
|
||||||
|
void MultisegmentWellEquations<Scalar,numWellEq,numEq>::
|
||||||
|
extract(SparseMatrixAdapter& jacobian) const
|
||||||
|
{
|
||||||
|
const auto invDuneD = mswellhelpers::invertWithUMFPack<BVectorWell>(numWellEq,
|
||||||
|
numEq,
|
||||||
|
*duneDSolver_);
|
||||||
|
|
||||||
|
// We need to change matrix A as follows
|
||||||
|
// A -= C^T D^-1 B
|
||||||
|
// D is a (nseg x nseg) block matrix with (4 x 4) blocks.
|
||||||
|
// B and C are (nseg x ncells) block matrices with (4 x 4 blocks).
|
||||||
|
// They have nonzeros at (i, j) only if this well has a
|
||||||
|
// perforation at cell j connected to segment i. The code
|
||||||
|
// assumes that no cell is connected to more than one segment,
|
||||||
|
// i.e. the columns of B/C have no more than one nonzero.
|
||||||
|
for (size_t rowC = 0; rowC < duneC_.N(); ++rowC) {
|
||||||
|
for (auto colC = duneC_[rowC].begin(),
|
||||||
|
endC = duneC_[rowC].end(); colC != endC; ++colC) {
|
||||||
|
const auto row_index = colC.index();
|
||||||
|
for (size_t rowB = 0; rowB < duneB_.N(); ++rowB) {
|
||||||
|
for (auto colB = duneB_[rowB].begin(),
|
||||||
|
endB = duneB_[rowB].end(); colB != endB; ++colB) {
|
||||||
|
const auto col_index = colB.index();
|
||||||
|
OffDiagMatrixBlockWellType tmp1;
|
||||||
|
detail::multMatrixImpl(invDuneD[rowC][rowB], (*colB), tmp1, std::true_type());
|
||||||
|
typename SparseMatrixAdapter::MatrixBlock tmp2;
|
||||||
|
detail::multMatrixTransposedImpl((*colC), tmp1, tmp2, std::false_type());
|
||||||
|
jacobian.addToBlock(row_index, col_index, tmp2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define INSTANCE(numWellEq, numEq) \
|
#define INSTANCE(numWellEq, numEq) \
|
||||||
template class MultisegmentWellEquations<double,numWellEq,numEq>;
|
template class MultisegmentWellEquations<double,numWellEq,numEq>; \
|
||||||
|
template void MultisegmentWellEquations<double,numWellEq,numEq>:: \
|
||||||
|
extract(Linear::IstlSparseMatrixAdapter<MatrixBlock<double,numEq,numEq>>&) const;
|
||||||
|
|
||||||
INSTANCE(2,1)
|
INSTANCE(2,1)
|
||||||
INSTANCE(2,2)
|
INSTANCE(2,2)
|
||||||
|
@ -94,6 +94,10 @@ public:
|
|||||||
//! \brief Add the matrices of this well to the WellContributions object.
|
//! \brief Add the matrices of this well to the WellContributions object.
|
||||||
void extract(WellContributions& wellContribs) const;
|
void extract(WellContributions& wellContribs) const;
|
||||||
|
|
||||||
|
//! \brief Add the matrices of this well to the sparse matrix adapter.
|
||||||
|
template<class SparseMatrixAdapter>
|
||||||
|
void extract(SparseMatrixAdapter& jacobian) const;
|
||||||
|
|
||||||
// two off-diagonal matrices
|
// two off-diagonal matrices
|
||||||
OffDiagMatWell duneB_;
|
OffDiagMatWell duneB_;
|
||||||
OffDiagMatWell duneC_;
|
OffDiagMatWell duneC_;
|
||||||
|
@ -19,8 +19,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <opm/simulators/linalg/SmallDenseMatrixUtils.hpp>
|
|
||||||
#include <opm/simulators/wells/MSWellHelpers.hpp>
|
|
||||||
#include <opm/simulators/wells/WellBhpThpCalculator.hpp>
|
#include <opm/simulators/wells/WellBhpThpCalculator.hpp>
|
||||||
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
|
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
|
||||||
#include <opm/input/eclipse/Schedule/MSW/Valve.hpp>
|
#include <opm/input/eclipse/Schedule/MSW/Valve.hpp>
|
||||||
@ -722,35 +720,7 @@ namespace Opm
|
|||||||
MultisegmentWell<TypeTag>::
|
MultisegmentWell<TypeTag>::
|
||||||
addWellContributions(SparseMatrixAdapter& jacobian) const
|
addWellContributions(SparseMatrixAdapter& jacobian) const
|
||||||
{
|
{
|
||||||
const auto invDuneD = mswellhelpers::invertWithUMFPack<BVectorWell>(numWellEq,
|
this->linSys_.extract(jacobian);
|
||||||
Indices::numEq,
|
|
||||||
*this->linSys_.duneDSolver_);
|
|
||||||
|
|
||||||
// We need to change matrix A as follows
|
|
||||||
// A -= C^T D^-1 B
|
|
||||||
// D is a (nseg x nseg) block matrix with (4 x 4) blocks.
|
|
||||||
// B and C are (nseg x ncells) block matrices with (4 x 4 blocks).
|
|
||||||
// They have nonzeros at (i, j) only if this well has a
|
|
||||||
// perforation at cell j connected to segment i. The code
|
|
||||||
// assumes that no cell is connected to more than one segment,
|
|
||||||
// i.e. the columns of B/C have no more than one nonzero.
|
|
||||||
for (size_t rowC = 0; rowC < this->linSys_.duneC_.N(); ++rowC) {
|
|
||||||
for (auto colC = this->linSys_.duneC_[rowC].begin(),
|
|
||||||
endC = this->linSys_.duneC_[rowC].end(); colC != endC; ++colC) {
|
|
||||||
const auto row_index = colC.index();
|
|
||||||
for (size_t rowB = 0; rowB < this->linSys_.duneB_.N(); ++rowB) {
|
|
||||||
for (auto colB = this->linSys_.duneB_[rowB].begin(),
|
|
||||||
endB = this->linSys_.duneB_[rowB].end(); colB != endB; ++colB) {
|
|
||||||
const auto col_index = colB.index();
|
|
||||||
typename Equations::OffDiagMatrixBlockWellType tmp1;
|
|
||||||
detail::multMatrixImpl(invDuneD[rowC][rowB], (*colB), tmp1, std::true_type());
|
|
||||||
typename SparseMatrixAdapter::MatrixBlock tmp2;
|
|
||||||
detail::multMatrixTransposedImpl((*colC), tmp1, tmp2, std::false_type());
|
|
||||||
jacobian.addToBlock(row_index, col_index, tmp2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user