1 #ifndef OPM_FLOW_NONLINEAR_SYSTEM_IMPL_HEADER_INCLUDED 2 #define OPM_FLOW_NONLINEAR_SYSTEM_IMPL_HEADER_INCLUDED 21 #ifndef OPM_FLOW_NONLINEAR_SYSTEM_HEADER_INCLUDED 23 #include <opm/simulators/flow/NonlinearSystem.hpp> 26 #include <dune/common/timer.hh> 28 #include <opm/common/ErrorMacros.hpp> 29 #include <opm/common/TimingMacros.hpp> 38 template <
class TypeTag>
40 NonlinearSystem<TypeTag>::
41 assembleReservoir(
const SimulatorTimerInterface&)
43 return assembleReservoir(well_model_);
46 template <
class TypeTag>
48 NonlinearSystem<TypeTag>::
49 updateTUNING(
const Tuning& tuning)
51 applyTUNING(param_, tuning);
54 template <
class TypeTag>
56 NonlinearSystem<TypeTag>::
57 updateTUNINGDP(
const TuningDp& tuning_dp)
59 applyTUNINGDP(param_, tuning_dp);
62 template <
class TypeTag>
64 NonlinearSystem<TypeTag>::
65 updateSolution(
const GlobalEqVector& dx)
67 OPM_TIMEBLOCK(updateSolution);
69 const bool shouldStore = shouldStoreSolutionUpdate();
71 prepareSolutionUpdate();
74 auto& newtonMethod = simulator_.model().newtonMethod();
75 auto& solution = simulator_.model().solution(0);
77 newtonMethod.applyUpdate(solution,
83 OPM_TIMEBLOCK(invalidateAndUpdateIntensiveQuantities);
84 simulator_.model().invalidateAndUpdateIntensiveQuantities(0);
88 storeSolutionUpdate(dx);
92 template <
class TypeTag>
93 template <
class LogFailure>
95 NonlinearSystem<TypeTag>::
96 addReservoirConvergenceMetrics(ConvergenceReport& report,
97 const int componentIdx,
98 const std::string_view componentName,
99 const std::span<const Scalar> residuals,
100 const std::span<const ConvergenceReport::ReservoirFailure::Type> types,
101 const std::span<const Scalar> tolerances,
102 const Scalar maxResidualAllowed,
103 LogFailure&& logFailure)
const 105 if (residuals.size() != types.size() || residuals.size() != tolerances.size()) {
106 OPM_THROW(std::logic_error,
"Mismatched reservoir convergence metric sizes.");
109 using CR = ConvergenceReport;
110 for (std::size_t metricIdx = 0; metricIdx < residuals.size(); ++metricIdx) {
111 const auto residual = residuals[metricIdx];
112 const auto type = types[metricIdx];
113 const auto tolerance = tolerances[metricIdx];
115 if (std::isnan(residual)) {
116 report.setReservoirFailed({type, CR::Severity::NotANumber, componentIdx});
117 logFailure(
"NaN residual for " + std::string(componentName) +
" equation.");
119 else if (residual > maxResidualAllowed) {
120 report.setReservoirFailed({type, CR::Severity::TooLarge, componentIdx});
121 logFailure(
"Too large residual for " + std::string(componentName) +
" equation.");
123 else if (residual < 0.0) {
124 report.setReservoirFailed({type, CR::Severity::Normal, componentIdx});
125 logFailure(
"Negative residual for " + std::string(componentName) +
" equation.");
127 else if (residual > tolerance) {
128 report.setReservoirFailed({type, CR::Severity::Normal, componentIdx});
131 report.setReservoirConvergenceMetric(type, componentIdx, residual, tolerance);
135 template <
class TypeTag>
136 NonlinearSystem<TypeTag>::
137 NonlinearSystem(Simulator& simulator,
138 const ModelParameters& param,
139 WellModel& wellModel,
140 const bool terminal_output)
141 : simulator_(simulator)
142 , grid_(simulator_.vanguard().grid())
143 , terminal_output_(terminal_output)
145 , well_model_(wellModel)
146 , current_relaxation_(1.0)
147 , dx_old_(simulator_.model().numGridDof())
150 template <
class TypeTag>
152 NonlinearSystem<TypeTag>::
153 initialLinearization(SimulatorReportSingle& report,
156 const SimulatorTimerInterface&)
158 failureReport_ = SimulatorReportSingle();
160 Dune::Timer perfTimer;
162 report.total_linearizations = 1;
165 report += this->assembleReservoir(well_model_);
166 report.assemble_time += perfTimer.stop();
170 simulator_.problem().markTimestepInitialized();
173 report.assemble_time += perfTimer.stop();
174 failureReport_ += report;
179 template <
class TypeTag>
180 SimulatorReportSingle
181 NonlinearSystem<TypeTag>::
182 prepareStep(
const SimulatorTimerInterface& timer)
184 SimulatorReportSingle report;
185 Dune::Timer perfTimer;
188 const int lastStepFailed = timer.lastStepFailed();
189 if (grid_.comm().size() > 1 && grid_.comm().max(lastStepFailed) != grid_.comm().min(lastStepFailed)) {
190 OPM_THROW(std::runtime_error,
191 "Misalignment of the parallel simulation run in prepareStep " 192 "- the previous step succeeded on some ranks but failed on others.");
195 if (lastStepFailed) {
196 simulator_.problem().updateFailed();
199 simulator_.problem().advanceTimeLevel();
203 simulator_.setTime(timer.simulationTimeElapsed());
204 simulator_.setTimeStepSize(timer.currentStepLength());
206 simulator_.problem().resetIterationForNewTimestep();
207 simulator_.problem().beginTimeStep();
209 report.pre_post_time += perfTimer.stop();
213 template <
class TypeTag>
214 template <
class WellModelType>
215 SimulatorReportSingle
216 NonlinearSystem<TypeTag>::
217 assembleReservoir(WellModelType& wellModel)
219 simulator_.problem().beginIteration();
220 simulator_.model().linearizer().linearizeDomain();
221 simulator_.problem().endIteration();
222 return wellModel.lastReport();
225 template <
class TypeTag>
226 template <
class ModelParametersType>
228 NonlinearSystem<TypeTag>::
229 applyTUNING(ModelParametersType& param,
230 const Tuning& tuning)
232 param.tolerance_cnv_ = tuning.TRGCNV;
233 param.tolerance_cnv_relaxed_ = tuning.XXXCNV;
234 param.tolerance_mb_ = tuning.TRGMBE;
235 param.tolerance_mb_relaxed_ = tuning.XXXMBE;
236 param.newton_max_iter_ = tuning.NEWTMX;
237 param.newton_min_iter_ = tuning.NEWTMN;
240 template <
class TypeTag>
241 template <
class ModelParametersType>
243 NonlinearSystem<TypeTag>::
244 applyTUNINGDP(ModelParametersType& param,
245 const TuningDp& tuning_dp)
247 param.tolerance_max_dp_ = tuning_dp.TRGDDP;
248 param.tolerance_max_ds_ = tuning_dp.TRGDDS;
249 param.tolerance_max_drs_ = tuning_dp.TRGDDRS;
250 param.tolerance_max_drv_ = tuning_dp.TRGDDRV;
253 template <
class TypeTag>
254 template <
class ValueType>
255 std::tuple<ValueType, ValueType>
256 NonlinearSystem<TypeTag>::
257 convergenceReduction(Parallel::Communication comm,
258 const ValueType primaryVolumeLocal,
259 const ValueType secondaryVolumeLocal,
260 std::vector<ValueType>& sumValues,
261 std::vector<ValueType>& maxValues,
262 std::vector<ValueType>& averagedValues)
264 OPM_TIMEBLOCK(convergenceReduction);
266 ValueType primaryVolume = primaryVolumeLocal;
267 ValueType secondaryVolume = secondaryVolumeLocal;
269 if (comm.size() > 1) {
270 std::vector<ValueType> sumBuffer;
271 std::vector<ValueType> maxBuffer;
272 const int numComp = averagedValues.size();
273 sumBuffer.reserve(2 * numComp + 2);
274 maxBuffer.reserve(numComp);
276 for (
int compIdx = 0; compIdx < numComp; ++compIdx) {
277 sumBuffer.push_back(averagedValues[compIdx]);
278 sumBuffer.push_back(sumValues[compIdx]);
279 maxBuffer.push_back(maxValues[compIdx]);
282 sumBuffer.push_back(primaryVolume);
283 sumBuffer.push_back(secondaryVolume);
285 comm.sum(sumBuffer.data(), sumBuffer.size());
286 comm.max(maxBuffer.data(), maxBuffer.size());
288 for (
int compIdx = 0, buffIdx = 0; compIdx < numComp; ++compIdx, ++buffIdx) {
289 averagedValues[compIdx] = sumBuffer[buffIdx];
291 sumValues[compIdx] = sumBuffer[buffIdx];
294 for (
int compIdx = 0; compIdx < numComp; ++compIdx) {
295 maxValues[compIdx] = maxBuffer[compIdx];
298 primaryVolume = sumBuffer[sumBuffer.size() - 2];
299 secondaryVolume = sumBuffer.back();
302 return {primaryVolume, secondaryVolume};
307 #endif // OPM_FLOW_NONLINEAR_SYSTEM_IMPL_HEADER_INCLUDED Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45