Producing residual maps
This PR intends at implementing a mechanism to produce residual maps in addition to other fields produce by the CompositionalMultiphaseFVM solver. The desirable features are:
- Storing residual systematically at each output step for a particular newton iteration (here the last one)
- Storing residual when the non-linear convergence struggles at an exceptional output step
First point is tacked in:
Residual are for now store through the call at SolverBase::updateResidualField() 's overload in CompositionalMultiphaseFVM if m_logLevel is greater that level 0 and at the last iteration.
Second point is tacked in:
~~An extra event ResidualDumpEvent that inherits from PeriodicEvent with an extra m_secondaryTarget is introduced. It also conditional triggering of second target on a flag from the (main) target, i.e. solver. A n-tree struct templated (BitNodes<T>) on an enum flag (SolverBase::SolverGroupFlags) is used to tack nonlinear convergence history and then trigger exceptional output.~~
A new ResidualTask is added to be triggered from a PeriodicEvent. It has an extra m_secondaryTarget is introduced and set to vtkOutput. The (main) target, i.e. solver, is holding a flag m_hasNonLinearIssues to trigger this secondary target if needed and to dump the residual when convergence is struggling.
Limitations/To go further:
- The residual formula might need some rework, for instance to fit spe11 prescription
- The output fields (apart from residual) are the fields at convergence. It might be more meaningfull to output the fields at the residual struggle
Codecov Report
Attention: Patch coverage is 5.30973% with 107 lines in your changes missing coverage. Please review.
Project coverage is 53.53%. Comparing base (
7ace2fc) to head (73c2fc1). Report is 276 commits behind head on develop.
Additional details and impacted files
@@ Coverage Diff @@
## develop #3107 +/- ##
===========================================
- Coverage 53.57% 53.53% -0.05%
===========================================
Files 1003 1005 +2
Lines 85289 85374 +85
===========================================
+ Hits 45696 45702 +6
- Misses 39593 39672 +79
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
🚀 New features to boost your workflow:
- ❄ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
thanks @jafranc could you please share an xml with example how to use it?
thanks @jafranc could you please share an xml with example how to use it?
Of course,
<Events
maxTime="2e7">
<PeriodicEvent
name="outputs"
timeFrequency="2e7"
target="/Outputs/vtkOutput"/>
<PeriodicEvent
name="solverApplications1"
forceDt="1e5"
endTime="1e5"
target="/Solvers/compflow" />
<ResidualDumpEvent
name="solverApplications2"
forceDt="2.5e6"
beginTime="1e5"
endTime="2e7"
target="/Solvers/compflow"
secondaryTarget="/Outputs/vtkOutput" />
</Events>
for an example in on the deadoil_3ph_dorey_1d (added here as csv as xml is unrecognized by github).
I did split the time-step applications into two part so it cut at another place than 0.
Note that the residuals output are not huge though present.
Another way of testing it is to stop with the debugger in a t>0 newton and manually triggering SolverBase::SolverGroupFlags::StruggleCvg for it to register a rather big residual.
Sorry about an unsolicited review. I wonder if you considered implementing residual dump as a task instead of a new event type. Reason being events are meant to be general and not have solver-specific semantics in them, while tasks can be specialized for a single purpose.
<Events maxTime="2e7"> <PeriodicEvent name="outputs" timeFrequency="2e7" target="/Outputs/vtkOutput"/> <PeriodicEvent name="solverApplications1" forceDt="1e5" endTime="1e5" target="/Solvers/compflow" /> <PeriodicEvent name="residualDumpEvent" forceDt="2.5e6" beginTime="1e5" endTime="2e7" target="/Tasks/residualDump"/> </Events> <Tasks> <ResidualDump name="residualDump" solverTarget="/Solvers/compflow" outputTarget="/Outputs/vtkOutput"/> </Tasks>
No worries, it is really useful. This is results of a first attempt and I definitively overlooked that semantic. I will recast in a Task . That makes more sense.