28 #ifndef OPM_FLOW_EXP_NEWTON_METHOD_HPP 29 #define OPM_FLOW_EXP_NEWTON_METHOD_HPP 31 #include <opm/common/Exceptions.hpp> 32 #include <opm/common/OpmLog/OpmLog.hpp> 42 template<
class Scalar>
52 template<
class Scalar>
55 template<
class Scalar>
59 template<
class Scalar>
69 template <
class TypeTag>
86 static constexpr
unsigned numEq = getPropValue<TypeTag, Properties::NumEq>();
88 static constexpr
int contiSolventEqIdx = Indices::contiSolventEqIdx;
89 static constexpr
int contiPolymerEqIdx = Indices::contiPolymerEqIdx;
90 static constexpr
int contiEnergyEqIdx = Indices::contiEnergyEqIdx;
93 friend DiscNewtonMethod;
99 errorPvFraction_ = 1.0;
100 relaxedMaxPvFraction_ = Parameters::Get<Parameters::EclNewtonRelaxedVolumeFraction<Scalar>>();
103 relaxedTolerance_ = Parameters::Get<Parameters::EclNewtonRelaxedTolerance<Scalar>>();
105 numStrictIterations_ = Parameters::Get<Parameters::EclNewtonStrictIterations>();
115 Parameters::Register<Parameters::EclNewtonSumTolerance<Scalar>>
116 (
"The maximum error tolerated by the Newton " 117 "method for considering a solution to be converged");
118 Parameters::Register<Parameters::EclNewtonStrictIterations>
119 (
"The number of Newton iterations where the " 120 "volumetric error is considered.");
121 Parameters::Register<Parameters::EclNewtonRelaxedVolumeFraction<Scalar>>
122 (
"The fraction of the pore volume of the reservoir " 123 "where the volumetric error may be violated during strict Newton iterations.");
124 Parameters::Register<Parameters::EclNewtonSumToleranceExponent<Scalar>>
125 (
"The the exponent used to scale the sum tolerance by " 126 "the total pore volume of the reservoir.");
127 Parameters::Register<Parameters::EclNewtonRelaxedTolerance<Scalar>>
128 (
"The maximum error which the volumetric residual " 129 "may exhibit if it is in a 'relaxed' region during a strict iteration.");
138 if (errorPvFraction_ < relaxedMaxPvFraction_
139 || this->problem().iterationContext().shouldRelax(numStrictIterations_ + 1)) {
140 return (this->error_ < relaxedTolerance_ && errorSum_ < sumTolerance_);
143 return this->error_ <= this->tolerance() && errorSum_ <= sumTolerance_;
146 void preSolve_(
const SolutionVector&,
147 const GlobalEqVector& currentResidual)
149 const auto& constraintsMap = this->model().linearizer().constraintsMap();
150 this->lastError_ = this->error_;
151 Scalar newtonMaxError = this->params_.maxError_;
156 Dune::FieldVector<Scalar, numEq> componentSumError;
157 std::ranges::fill(componentSumError, 0.0);
159 errorPvFraction_ = 0.0;
160 const Scalar dt = this->simulator_.timeStepSize();
161 for (
unsigned dofIdx = 0; dofIdx < currentResidual.size(); ++dofIdx) {
163 if (dofIdx >= this->model().numGridDof()
164 || this->model().dofTotalVolume(dofIdx) <= 0.0) {
168 if (!this->model().isLocalDof(dofIdx)) {
173 if (this->enableConstraints_()) {
174 if (constraintsMap.count(dofIdx) > 0) {
179 const auto& r = currentResidual[dofIdx];
180 Scalar pvValue = this->simulator_.problem().referencePorosity(dofIdx, 0) *
181 this->model().dofTotalVolume(dofIdx);
183 bool cnvViolated =
false;
185 Scalar dofVolume = this->model().dofTotalVolume(dofIdx);
187 for (
unsigned eqIdx = 0; eqIdx < r.size(); ++eqIdx) {
188 Scalar tmpError = r[eqIdx] * dt * this->model().eqWeight(dofIdx, eqIdx) / pvValue;
189 Scalar tmpError2 = r[eqIdx] * this->model().eqWeight(dofIdx, eqIdx);
193 if (getPropValue<TypeTag, Properties::UseVolumetricResidual>()) {
194 tmpError *= dofVolume;
195 tmpError2 *= dofVolume;
198 this->error_ = max(std::abs(tmpError), this->error_);
200 if (std::abs(tmpError) > this->params_.tolerance_) {
204 componentSumError[eqIdx] += std::abs(tmpError2);
207 errorPvFraction_ += pvValue;
212 this->error_ = this->comm_.max(this->error_);
213 componentSumError = this->comm_.sum(componentSumError);
214 sumPv = this->comm_.sum(sumPv);
215 errorPvFraction_ = this->comm_.sum(errorPvFraction_);
217 componentSumError /= sumPv;
218 componentSumError *= dt;
220 errorPvFraction_ /= sumPv;
223 for (
unsigned eqIdx = 0; eqIdx < numEq; ++eqIdx) {
224 errorSum_ = std::max(std::abs(componentSumError[eqIdx]), errorSum_);
229 Scalar x = Parameters::Get<Parameters::EclNewtonSumTolerance<Scalar>>();
230 Scalar y = Parameters::Get<Parameters::EclNewtonSumToleranceExponent<Scalar>>();
231 sumTolerance_ = x*std::pow(sumPv, y);
233 this->endIterMsg() <<
" (max: " << this->params_.tolerance_
234 <<
", violated for " << errorPvFraction_ * 100
235 <<
"% of the pore volume), aggegate error: " 236 << errorSum_ <<
" (max: " << sumTolerance_ <<
")";
240 if (this->error_ > newtonMaxError) {
241 throw NumericalProblem(
"Newton: Error "+std::to_string(
double(this->error_))
242 +
" is larger than maximum allowed error of " 243 + std::to_string(
double(newtonMaxError)));
248 if (errorSum_ > newtonMaxError) {
249 throw NumericalProblem(
"Newton: Sum of the error "+std::to_string(
double(errorSum_))
250 +
" is larger than maximum allowed error of " 251 + std::to_string(
double(newtonMaxError)));
255 void endIteration_(SolutionVector& nextSolution,
256 const SolutionVector& currentSolution)
259 OpmLog::debug(
"Newton iteration " + std::to_string(this->problem().iterationContext().iteration()) +
"" 260 +
" error: " + std::to_string(
double(this->error_))
261 + this->endIterMsg().str());
262 this->endIterMsg().str(
"");
266 Scalar errorPvFraction_;
269 Scalar relaxedTolerance_;
270 Scalar relaxedMaxPvFraction_;
272 Scalar sumTolerance_;
274 int numStrictIterations_;
The value for the error below which convergence is declared.
Definition: newtonmethodparams.hpp:53
A newton solver.
Definition: FlowExpNewtonMethod.hpp:70
The multi-dimensional Newton method.
Definition: newtonmethod.hh:64
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: FlowExpNewtonMethod.hpp:48
Definition: FlowExpNewtonMethod.hpp:53
static void registerParameters()
Register all run-time parameters for the Newton method.
Definition: FlowExpNewtonMethod.hpp:111
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
Definition: blackoilnewtonmethodparams.hpp:31
Definition: FlowExpNewtonMethod.hpp:43
A newton solver which is specific to the black oil model.
Definition: blackoilnewtonmethod.hpp:63
Definition: FlowExpNewtonMethod.hpp:60
static void registerParameters()
Register all run-time parameters for the blackoil newton method.
Definition: blackoilnewtonmethod.hpp:100
void endIteration_(SolutionVector &uCurrentIter, const SolutionVector &uLastIter)
Indicates that one Newton iteration was finished.
Definition: blackoilnewtonmethod.hpp:132
bool converged() const
Returns true if the error of the solution is below the tolerance.
Definition: FlowExpNewtonMethod.hpp:136
Definition: FlowExpNewtonMethod.hpp:56
A newton solver which is specific to the black oil model.