19#ifndef OPM_ISTLSOLVERSYSTEM_HEADER_INCLUDED
20#define OPM_ISTLSOLVERSYSTEM_HEADER_INCLUDED
30#include <opm/common/ErrorMacros.hpp>
32#include <dune/common/fmatrix.hh>
33#include <dune/common/fvector.hh>
46template <
class TypeTag>
53 using Matrix =
typename SparseMatrixAdapter::IstlMatrix;
60 static_assert(Indices::numEq == 3,
61 "ISTLSolverSystem (with system_cpr preconditioner) only supports "
62 "3-equation blackoil models. This model has different equation count.");
65 = Indices::pressureSwitchIdx;
77 static constexpr auto _0 = Dune::Indices::_0;
78 static constexpr auto _1 = Dune::Indices::_1;
83 bool forceSerial =
false)
84 :
Parent(simulator, parameters, forceSerial)
95 OPM_TIMEBLOCK(istlSolverPrepare);
97 prepareSystemSolver();
102 OPM_TIMEBLOCK(istlSolverPrepare);
104 prepareSystemSolver();
109 OPM_TIMEBLOCK(istlSolverSolve);
124 sysX_[
_0].resize(numRes);
126 sysX_[
_1].resize(numWell);
129 sysRhs_[
_0].resize(numRes);
131 sysRhs_[
_1].resize(numWell);
135 sysSolver_->apply(sysX_, sysRhs_, result);
144 bool sysInitialized_ =
false;
152 std::string wellWeightType_ =
"quasiimpes";
155 std::vector<WRMatrix<Scalar>> wellBMatrices_;
156 std::vector<RWMatrix<Scalar>> wellCMatrices_;
157 std::vector<WWMatrix<Scalar>> wellDMatrices_;
158 Opm::SparseTable<int> wellCells_;
170 std::unique_ptr<SystemSeqOp<Scalar>> sysOp_;
171 std::unique_ptr<Dune::FlexibleSolver<SystemSeqOp<Scalar>>> sysFlexSolverSeq_;
176 std::unique_ptr<WellComm> wellComm_;
177 std::unique_ptr<SystemComm> systemComm_;
178 std::unique_ptr<SystemParOp<Scalar>> sysOpPar_;
179 std::unique_ptr<Dune::FlexibleSolver<SystemParOp<Scalar>>> sysFlexSolverPar_;
188 SysSolverType* sysSolver_ =
nullptr;
189 SysPrecondType* sysPrecond_ =
nullptr;
191 void prepareSystemSolver()
193 OPM_TIMEBLOCK(flexibleSolverPrepare);
200 wellWeightType_ = prm.get(
"preconditioner.well_weight_type", std::string{
"cellavg"});
201 if (wellWeightType_ !=
"unit" && wellWeightType_ !=
"cellavg"
202 && wellWeightType_ !=
"cellblockavg" && wellWeightType_ !=
"quasiimpes") {
203 OPM_THROW(std::invalid_argument,
204 "Unknown preconditioner.well_weight_type '" + wellWeightType_
205 +
"'. Valid values are 'unit', 'cellavg', "
206 "'cellblockavg' and 'quasiimpes'.");
211 = prm.get(
"preconditioner.well_identity_on_pressure_control",
false);
213 wellBMatrices_.clear();
214 wellCMatrices_.clear();
215 wellDMatrices_.clear();
218 this->
simulator_.problem().wellModel().addBCDMatrix(
219 wellBMatrices_, wellCMatrices_, wellDMatrices_, wellCells_);
221 buildWellDofLayout();
224 Parent::matrix_->N(), wellBMatrices_, wellCMatrices_, wellDMatrices_, wellCells_);
226 const bool localStructureChanged = !sysInitialized_
227 || !merger.hasSameStructure(cachedWellStructure_);
233 const bool globalStructureChanged = this->
comm_->communicator().max(
234 static_cast<int>(localStructureChanged)) > 0;
236 const bool globalStructureChanged = localStructureChanged;
238 const bool needStructureRefresh = !sysInitialized_ || globalStructureChanged;
240 if (needStructureRefresh) {
241 OPM_TIMEBLOCK(flexibleSolverCreate);
242 merger.buildMatrices(mergedB_, mergedC_, mergedD_);
244 sysMatrix_.
B = &mergedB_;
245 sysMatrix_.
C = &mergedC_;
246 sysMatrix_.
D = &mergedD_;
248 cachedWellStructure_ = merger.buildStructure();
250 refreshSystemSolverForChangedWellStructure(prm);
251 sysInitialized_ =
true;
253 OPM_TIMEBLOCK(flexibleSolverUpdate);
256 merger.updateValues(mergedB_, mergedC_, mergedD_);
260 sysMatrix_.
B = &mergedB_;
261 sysMatrix_.
C = &mergedC_;
262 sysMatrix_.
D = &mergedD_;
264 sysPrecond_->update();
272 void buildWellDofLayout()
276 offsets.reserve(wellDMatrices_.size() + 1);
277 offsets.push_back(0);
278 std::size_t total = 0;
279 for (
const auto& d : wellDMatrices_) {
281 offsets.push_back(total);
290 const auto& wellModel = this->
simulator_.problem().wellModel();
291 const auto& wellState = wellModel.wellState();
293 for (
const auto& well : wellModel) {
295 well->isPressureControlled(wellState) ? 1 : 0);
298 OPM_THROW(std::logic_error,
299 "System CPRW: the well container and the extracted well "
300 "matrices disagree on the number of wells.");
310 WellVector<Scalar> computeWellWeights(
const ResVector<Scalar>& resWeights)
const
312 const std::size_t numBlocks = mergedD_.N();
316 WellVector<Scalar> weights(numBlocks);
318 if (wellWeightType_ ==
"cellavg") {
321 for (std::size_t j = 0; j < wellLayout_.
numWells(); ++j) {
322 const auto lambda = averagePerforatedCellWeights(
324 for (std::size_t wb = wellLayout_.
firstBlock(j); wb < wellLayout_.
endBlock(j); ++wb) {
325 weights[wb] = lambda;
331 if (wellWeightType_ ==
"cellblockavg") {
333 for (std::size_t wb = 0; wb < numBlocks; ++wb) {
334 weights[wb] = averagePerforatedCellWeights(resWeights, wb, wb + 1);
339 for (std::size_t wb = 0; wb < numBlocks; ++wb) {
340 auto& lambda = weights[wb];
343 if (wellWeightType_ ==
"unit") {
353 Dune::FieldVector<Scalar, numWellDofs> rhs(0.0);
356 if (mergedD_.exists(wb, wb)) {
358 const auto dt = mergedD_[wb][wb].transposed();
359 dt.solve(lambda, rhs);
362 absMax = std::max(absMax, std::abs(lambda[i]));
364 if (absMax > 0.0 && std::isfinite(absMax)) {
368 }
catch (
const Dune::FMatrixError&) {
384 Dune::FieldVector<Scalar, numWellDofs>
385 averagePerforatedCellWeights(
const ResVector<Scalar>& resWeights,
386 const std::size_t first,
387 const std::size_t last)
const
389 Dune::FieldVector<Scalar, numWellDofs> lambda(0.0);
391 for (std::size_t b = first; b < last; ++b) {
392 for (
auto col = mergedB_[b].begin(), end = mergedB_[b].end(); col != end; ++col) {
393 const auto& cw = resWeights[col.index()];
394 for (
int conservation_eq_index = 0; conservation_eq_index <
numResDofs;
395 ++conservation_eq_index) {
396 lambda[conservation_eq_index] += cw[conservation_eq_index];
401 for (
int conservation_eq_index = 0; conservation_eq_index <
numResDofs;
402 ++conservation_eq_index) {
404 lambda[conservation_eq_index] = numPerfs > 0
405 ? lambda[conservation_eq_index] / numPerfs
414 if (!sysInitialized_ || !sysPrecond_) {
415 createSystemSolver(prm);
420 if (this->
comm_->communicator().size() > 1) {
421 if (
auto* precond =
dynamic_cast<ParSysPrecondType*
>(sysPrecond_)) {
422 precond->updateForChangedWellStructure();
425 createSystemSolver(prm);
431 if (
auto* precond =
dynamic_cast<SeqSysPrecondType*
>(sysPrecond_)) {
432 precond->updateForChangedWellStructure();
435 createSystemSolver(prm);
442 auto resSolverPrm = prm.
get_child(
"preconditioner.reservoir_solver");
443 std::function<ResVector<Scalar>()> resWeightCalc
449 std::function<SystemVector<Scalar>()> sysWeightCalc;
451 sysWeightCalc = [
this, resWeightCalc]() {
452 SystemVector<Scalar> w;
453 w[
_0] = resWeightCalc();
454 w[
_1] = this->computeWellWeights(w[
_0]);
460 const bool is_parallel = this->
comm_->communicator().size() > 1;
462 wellComm_ = std::make_unique<WellComm>();
463 systemComm_ = std::make_unique<SystemComm>(*(this->
comm_), *wellComm_);
465 sysOpPar_ = std::make_unique<SystemParOp<Scalar>>(sysMatrix_, *systemComm_);
467 sysFlexSolverPar_ = std::make_unique<Dune::FlexibleSolver<SystemParOp<Scalar>>>(
468 *sysOpPar_, *systemComm_, prm, sysWeightCalc,
pressureIndex);
470 sysSolver_ = sysFlexSolverPar_.get();
471 sysPrecond_ = &sysFlexSolverPar_->preconditioner();
476 sysOp_ = std::make_unique<SystemSeqOp<Scalar>>(sysMatrix_);
478 sysFlexSolverSeq_ = std::make_unique<Dune::FlexibleSolver<SystemSeqOp<Scalar>>>(
481 sysSolver_ = sysFlexSolverSeq_.get();
482 sysPrecond_ = &sysFlexSolverSeq_->preconditioner();
Definition: MultiComm.hpp:75
Interface class adding the update() method to the preconditioner interface.
Definition: PreconditionerWithUpdate.hpp:34
Definition: ISTLSolver.hpp:152
std::shared_ptr< CommunicationType > comm_
Definition: ISTLSolver.hpp:739
std::function< Vector()> getWeightsCalculator(const PropertyTree &prm, std::size_t pressIndex) const
Definition: ISTLSolver.hpp:634
typename SparseMatrixAdapter::IstlMatrix Matrix
Definition: ISTLSolver.hpp:161
int solveCount_
Definition: ISTLSolver.hpp:715
Matrix & getMatrix()
Definition: ISTLSolver.hpp:703
GetPropType< TypeTag, Properties::SparseMatrixAdapter > SparseMatrixAdapter
Definition: ISTLSolver.hpp:156
Dune::OwnerOverlapCopyCommunication< int, int > CommunicationType
Definition: ISTLSolver.hpp:181
Matrix * matrix_
Definition: ISTLSolver.hpp:719
bool checkConvergence(const Dune::InverseOperatorResult &result) const
Definition: ISTLSolver.hpp:507
GetPropType< TypeTag, Properties::GlobalEqVector > Vector
Definition: ISTLSolver.hpp:157
void initPrepare(const Matrix &M, Vector &b)
Definition: ISTLSolver.hpp:365
int iterations_
Definition: ISTLSolver.hpp:714
GetPropType< TypeTag, Properties::Simulator > Simulator
Definition: ISTLSolver.hpp:160
Vector * rhs_
Definition: ISTLSolver.hpp:720
int activeSolverNum_
Definition: ISTLSolver.hpp:722
GetPropType< TypeTag, Properties::Indices > Indices
Definition: ISTLSolver.hpp:158
const Simulator & simulator_
Definition: ISTLSolver.hpp:713
std::vector< PropertyTree > prm_
Definition: ISTLSolver.hpp:737
Definition: ISTLSolverSystem.hpp:48
void prepare(const SparseMatrixAdapter &M, Vector &b) override
Definition: ISTLSolverSystem.hpp:93
@ enablePolymerMolarWeight
Definition: ISTLSolverSystem.hpp:67
static constexpr auto _1
Definition: ISTLSolverSystem.hpp:78
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition: ISTLSolverSystem.hpp:50
static constexpr std::size_t pressureIndex
Definition: ISTLSolverSystem.hpp:65
ISTLSolverSystem(const Simulator &simulator, const FlowLinearSolverParameters ¶meters, bool forceSerial=false)
Definition: ISTLSolverSystem.hpp:81
static constexpr bool isIncompatibleWithCprw
Definition: ISTLSolverSystem.hpp:68
static constexpr auto _0
Definition: ISTLSolverSystem.hpp:77
ISTLSolverSystem(const Simulator &simulator)
Definition: ISTLSolverSystem.hpp:88
void prepare(const Matrix &M, Vector &b) override
Definition: ISTLSolverSystem.hpp:100
bool solve(Vector &x) override
Definition: ISTLSolverSystem.hpp:107
Hierarchical collection of key/value pairs.
Definition: PropertyTree.hpp:39
PropertyTree get_child(const std::string &key) const
Definition: SystemTypes.hpp:166
const WellDofLayout * wellLayout
Definition: SystemTypes.hpp:182
const WRMatrix< Scalar > * B
Definition: SystemTypes.hpp:177
const RWMatrix< Scalar > * C
Definition: SystemTypes.hpp:176
const RRMatrix< Scalar > * A
Definition: SystemTypes.hpp:175
const WWMatrix< Scalar > * D
Definition: SystemTypes.hpp:178
Definition: SystemPreconditioner.hpp:62
Definition: WellMatrixMerger.hpp:124
void writeSystem(const SimulatorType &simulator, const MatrixType &matrix, const VectorType &rhs, const std::string &sysName, const Communicator *comm)
Definition: WriteSystemMatrixHelper.hpp:197
Definition: blackoilbioeffectsmodules.hh:45
Dune::MultiTypeBlockVector< ResVector< Scalar >, WellVector< Scalar > > SystemVector
Definition: SystemTypes.hpp:65
Dune::BCRSMatrix< Dune::FieldMatrix< Scalar, numWellDofs, numWellDofs > > WWMatrix
Definition: SystemTypes.hpp:58
Dune::InverseOperatorResult InverseOperatorResult
Definition: GpuBridge.hpp:32
Dune::BCRSMatrix< Dune::FieldMatrix< Scalar, numResDofs, numWellDofs > > RWMatrix
Definition: SystemTypes.hpp:54
Dune::OwnerOverlapCopyCommunication< int, int > ParResComm
Definition: SystemPreconditioner.hpp:45
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:233
Dune::BCRSMatrix< Dune::FieldMatrix< Scalar, numWellDofs, numResDofs > > WRMatrix
Definition: SystemTypes.hpp:56
constexpr int numWellDofs
Definition: SystemTypes.hpp:49
constexpr int numResDofs
Definition: SystemTypes.hpp:48
This class carries all parameters for the NewtonIterationBlackoilInterleaved class.
Definition: FlowLinearSolverParameters.hpp:98
Definition: SystemTypes.hpp:82
std::vector< char > pressureControlled
Definition: SystemTypes.hpp:106
std::vector< std::size_t > wellBlockOffsets
Definition: SystemTypes.hpp:84
std::size_t firstBlock(const std::size_t j) const
Definition: SystemTypes.hpp:123
int pressureVariableIndex
Definition: SystemTypes.hpp:96
bool identityOnPressureControl
Definition: SystemTypes.hpp:107
std::size_t endBlock(const std::size_t j) const
Definition: SystemTypes.hpp:128
std::size_t numWells() const
Definition: SystemTypes.hpp:116
Definition: WellMatrixMerger.hpp:63
std::size_t totalWellBlocks
Definition: WellMatrixMerger.hpp:65