Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Producing residual maps #3107

Open
wants to merge 16 commits into
base: develop
Choose a base branch
from
Open

Producing residual maps #3107

wants to merge 16 commits into from

Conversation

jafranc
Copy link
Contributor

@jafranc jafranc commented May 3, 2024

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

@jafranc jafranc self-assigned this May 3, 2024
@jafranc jafranc requested a review from paveltomin May 3, 2024 08:06
@jafranc jafranc added spe11 spe11-required-feature type: feature New feature or request labels May 3, 2024
Copy link

codecov bot commented May 3, 2024

Codecov Report

Attention: Patch coverage is 5.30973% with 107 lines in your changes are missing coverage. Please review.

Project coverage is 53.53%. Comparing base (7ace2fc) to head (73c2fc1).

Files Patch % Lines
src/coreComponents/physicsSolvers/SolverBase.cpp 3.22% 30 Missing ⚠️
...mponents/physicsSolvers/fluidFlow/ResidualTask.cpp 0.00% 29 Missing ⚠️
...w/IsothermalCompositionalMultiphaseBaseKernels.hpp 0.00% 27 Missing ⚠️
...csSolvers/fluidFlow/CompositionalMultiphaseFVM.cpp 0.00% 15 Missing ⚠️
...mponents/physicsSolvers/fluidFlow/ResidualTask.hpp 16.66% 5 Missing ⚠️
src/coreComponents/physicsSolvers/SolverBase.hpp 0.00% 1 Missing ⚠️
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     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@paveltomin
Copy link
Contributor

thanks @jafranc
could you please share an xml with example how to use it?

@jafranc
Copy link
Contributor Author

jafranc commented May 3, 2024

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.

deadoil_3ph_corey_1d_dump.csv

Copy link
Contributor

@klevzoff klevzoff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>

@@ -243,12 +243,13 @@ bool SolverBase::execute( real64 const time_n,
real64 nextDt = dt;

integer const maxSubSteps = m_nonlinearSolverParameters.m_maxSubSteps;
m_rootFlag = new BitNodes< SolverGroupFlags >( nullptr );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of these raw news seem to have a corresponding delete, so it seems like memory is leaked (correct me if I'm wrong).

In general, I have a hard time understanding what this convergence tree is needed for, is there a short explanation? Just curious.

On a surface level it seems the residual dump event only cares if any node in the tree has a flag set (and nodes are never removed/reset), so why couldn't we just track this with a single variable bool m_thisStepEncounteredConvergenceDifficultiesSomewhereAlongTheWay (name exaggerated but you get the idea)? I'm pretty sure I'm missing something after a cursory look.

Copy link
Contributor Author

@jafranc jafranc May 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • You are perfectly right, I forgot to include corresponding delete that will result in mem leak. I will fix it
  • I am unsure it is required to have a tree struct, though if the time step gets cut, then the flag is set to struggling and the residual updated. The solver then retry with a series of smaller time-steps that hopefully are not cut though the flag is still set to struggle and the residual updated. I guess a clean reset would have been the solution. However, I went for the solution that we might want to exploit further down the road to output some convergence history. I thought it could have been useful in case of some remediation based on flag presences or not.

@jafranc
Copy link
Contributor Author

jafranc commented May 6, 2024

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.

@jafranc jafranc added ci: run integrated tests Allows to run the integrated tests in GEOS CI ci: upload test baselines labels May 17, 2024
@jafranc jafranc requested a review from klevzoff May 17, 2024 09:14
@jafranc jafranc removed the ci: run integrated tests Allows to run the integrated tests in GEOS CI label May 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
spe11 spe11-required-feature type: feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants