19 #ifndef OPM_ISTLSOLVERSYSTEM_HEADER_INCLUDED 20 #define OPM_ISTLSOLVERSYSTEM_HEADER_INCLUDED 22 #include <opm/simulators/linalg/system/SystemTypes.hpp> 23 #include <opm/simulators/linalg/system/SystemPreconditionerFactory.hpp> 24 #include <opm/simulators/linalg/system/WellMatrixMerger.hpp> 26 #include <opm/simulators/linalg/FlexibleSolver.hpp> 27 #include <opm/simulators/linalg/ISTLSolver.hpp> 32 template <
class TypeTag>
39 using Matrix =
typename SparseMatrixAdapter::IstlMatrix;
46 static_assert(Indices::numEq == 3,
47 "ISTLSolverSystem (with system_cpr preconditioner) only supports " 48 "3-equation blackoil models. This model has different equation count.");
50 constexpr
static std::size_t pressureIndex
51 = Indices::pressureSwitchIdx;
53 enum { enablePolymerMolarWeight = getPropValue<TypeTag, Properties::EnablePolymerMW>() };
54 constexpr
static bool isIncompatibleWithCprw = enablePolymerMolarWeight;
57 using CommunicationType = Dune::OwnerOverlapCopyCommunication<int, int>;
59 using CommunicationType = Dune::Communication<int>;
63 static constexpr
auto _0 = Dune::Indices::_0;
64 static constexpr
auto _1 = Dune::Indices::_1;
69 bool forceSerial =
false)
70 :
Parent(simulator, parameters, forceSerial)
79 void prepare(
const SparseMatrixAdapter& M, Vector& b)
override 81 OPM_TIMEBLOCK(istlSolverPrepare);
82 this->initPrepare(M.istlMatrix(), b);
83 prepareSystemSolver();
86 void prepare(
const Matrix& M, Vector& b)
override 88 OPM_TIMEBLOCK(istlSolverPrepare);
89 this->initPrepare(M, b);
90 prepareSystemSolver();
93 bool solve(Vector& x)
override 95 OPM_TIMEBLOCK(istlSolverSolve);
98 const std::size_t numRes = Parent::matrix_->N();
99 const std::size_t numWell = cachedWellStructure_.totalWellBlocks;
101 sysX_[_0].resize(numRes);
103 sysX_[_1].resize(numWell);
106 sysRhs_[_0].resize(numRes);
107 sysRhs_[_0] = *Parent::rhs_;
108 sysRhs_[_1].resize(numWell);
111 Dune::InverseOperatorResult result;
112 sysSolver_->apply(sysX_, sysRhs_, result);
113 this->iterations_ = result.iterations;
117 return this->checkConvergence(result);
121 bool sysInitialized_ =
false;
125 std::vector<WRMatrix<Scalar>> wellBMatrices_;
126 std::vector<RWMatrix<Scalar>> wellCMatrices_;
127 std::vector<WWMatrix<Scalar>> wellDMatrices_;
131 WRMatrix<Scalar> mergedB_;
132 RWMatrix<Scalar> mergedC_;
133 WWMatrix<Scalar> mergedD_;
136 SystemVector<Scalar> sysX_;
137 SystemVector<Scalar> sysRhs_;
140 std::unique_ptr<SystemSeqOp<Scalar>> sysOp_;
141 std::unique_ptr<Dune::FlexibleSolver<SystemSeqOp<Scalar>>> sysFlexSolverSeq_;
145 using WellComm = Dune::JacComm;
146 std::unique_ptr<WellComm> wellComm_;
147 std::unique_ptr<SystemComm> systemComm_;
148 std::unique_ptr<SystemParOp<Scalar>> sysOpPar_;
149 std::unique_ptr<Dune::FlexibleSolver<SystemParOp<Scalar>>> sysFlexSolverPar_;
152 using SysSolverType = Dune::InverseOperator<SystemVector<Scalar>, SystemVector<Scalar>>;
158 SysSolverType* sysSolver_ =
nullptr;
161 void prepareSystemSolver()
163 OPM_TIMEBLOCK(flexibleSolverPrepare);
165 wellBMatrices_.clear();
166 wellCMatrices_.clear();
167 wellDMatrices_.clear();
170 this->simulator_.problem().wellModel().addBCDMatrix(
171 wellBMatrices_, wellCMatrices_, wellDMatrices_, wellCells_);
174 Parent::matrix_->N(), wellBMatrices_, wellCMatrices_, wellDMatrices_, wellCells_);
176 const bool localStructureChanged = !sysInitialized_
177 || !merger.hasSameStructure(cachedWellStructure_);
183 const bool globalStructureChanged = this->comm_->communicator().max(
184 static_cast<int>(localStructureChanged)) > 0;
186 const bool globalStructureChanged = localStructureChanged;
188 const bool needStructureRefresh = !sysInitialized_ || globalStructureChanged;
190 const auto& prm = this->prm_[this->activeSolverNum_];
192 if (needStructureRefresh) {
193 OPM_TIMEBLOCK(flexibleSolverCreate);
194 merger.buildMatrices(mergedB_, mergedC_, mergedD_);
195 sysMatrix_.A = Parent::matrix_;
196 sysMatrix_.B = &mergedB_;
197 sysMatrix_.C = &mergedC_;
198 sysMatrix_.D = &mergedD_;
199 cachedWellStructure_ = merger.buildStructure();
201 refreshSystemSolverForChangedWellStructure(prm);
202 sysInitialized_ =
true;
204 OPM_TIMEBLOCK(flexibleSolverUpdate);
207 merger.updateValues(mergedB_, mergedC_, mergedD_);
210 sysMatrix_.A = Parent::matrix_;
211 sysMatrix_.B = &mergedB_;
212 sysMatrix_.C = &mergedC_;
213 sysMatrix_.D = &mergedD_;
214 sysPrecond_->update();
220 if (!sysInitialized_ || !sysPrecond_) {
221 createSystemSolver(prm);
226 if (this->comm_->communicator().size() > 1) {
227 if (
auto* precond = dynamic_cast<ParSysPrecondType*>(sysPrecond_)) {
228 precond->updateForChangedWellStructure();
231 createSystemSolver(prm);
237 if (
auto* precond = dynamic_cast<SeqSysPrecondType*>(sysPrecond_)) {
238 precond->updateForChangedWellStructure();
241 createSystemSolver(prm);
248 auto resSolverPrm = prm.
get_child(
"preconditioner.reservoir_solver");
249 std::function<ResVector<Scalar>()> resWeightCalc
250 = this->getWeightsCalculator(resSolverPrm, this->getMatrix(), pressureIndex);
252 std::function<SystemVector<Scalar>()> sysWeightCalc;
254 sysWeightCalc = [resWeightCalc]() {
255 SystemVector<Scalar> w;
256 w[_0] = resWeightCalc();
262 const bool is_parallel = this->comm_->communicator().size() > 1;
264 wellComm_ = std::make_unique<WellComm>();
265 systemComm_ = std::make_unique<SystemComm>(*(this->comm_), *wellComm_);
267 sysOpPar_ = std::make_unique<SystemParOp<Scalar>>(sysMatrix_, *systemComm_);
269 sysFlexSolverPar_ = std::make_unique<Dune::FlexibleSolver<SystemParOp<Scalar>>>(
270 *sysOpPar_, *systemComm_, prm, sysWeightCalc, pressureIndex);
272 sysSolver_ = sysFlexSolverPar_.get();
273 sysPrecond_ = &sysFlexSolverPar_->preconditioner();
278 sysOp_ = std::make_unique<SystemSeqOp<Scalar>>(sysMatrix_);
280 sysFlexSolverSeq_ = std::make_unique<Dune::FlexibleSolver<SystemSeqOp<Scalar>>>(
281 *sysOp_, prm, sysWeightCalc, pressureIndex);
283 sysSolver_ = sysFlexSolverSeq_.get();
284 sysPrecond_ = &sysFlexSolverSeq_->preconditioner();
291 #endif // OPM_ISTLSOLVERSYSTEM_HEADER_INCLUDED PropertyTree get_child(const std::string &key) const
Retrieve copy of sub tree rooted at node.
Definition: PropertyTree.cpp:82
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
Definition: SystemTypes.hpp:76
This class solves the fully implicit black-oil system by solving the reduced system (after eliminatin...
Definition: FlowLinearSolverParameters.hpp:40
Definition: SystemPreconditioner.hpp:56
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
Definition: WellMatrixMerger.hpp:163
This class carries all parameters for the NewtonIterationBlackoilInterleaved class.
Definition: FlowLinearSolverParameters.hpp:97
Definition: ISTLSolverSystem.hpp:33
Hierarchical collection of key/value pairs.
Definition: PropertyTree.hpp:38
Definition: WellMatrixMerger.hpp:65