Problem with nl_rel_tol

111 views
Skip to first unread message

Chakraborty (Non-US), Pritam

unread,
Mar 12, 2015, 2:41:47 PM3/12/15
to moose-users
Does anyone know how the reference residual value is calculated. I ran a 2D (unit square 1 element) solid mechanics problem with plasticity and found that the reference residual value is much lower than the initial residual. I printed it from FEProblem.C.

Here's what I get:

Time Step  1, time = 1

                dt = 1

    |residual|_2 of individual variables:

                     disp_x: 111.855

                     disp_y: 0


 0 Nonlinear |R| = 1.118551e+02

Reference residual 0.00141421

      0 Linear |R| = 1.118551e+02

      1 Linear |R| = 7.504710e-10

    |residual|_2 of individual variables:

                     disp_x: 6.10436

                     disp_y: 0


 1 Nonlinear |R| = 6.104356e+00

Reference residual 0.00141421

      0 Linear |R| = 6.104356e+00

      1 Linear |R| = 8.433227e-12

    |residual|_2 of individual variables:

                     disp_x: 0.00816995

                     disp_y: 0


 2 Nonlinear |R| = 8.169954e-03

Reference residual 0.00141421

      0 Linear |R| = 8.169954e-03

      1 Linear |R| = 8.389994e-15

    |residual|_2 of individual variables:

                     disp_x: 1.61589e-08

                     disp_y: 0


 3 Nonlinear |R| = 1.615890e-08


Reference residual 0.00141421

Converged due to function norm 1.61589e-08 <  (relative tolerance)

 0.00141421 0.01

 Solve Converged!


0.01 is the nl_rel_tol I used in the simulation.

Regards
Pritam

Cody Permann

unread,
Mar 12, 2015, 5:22:04 PM3/12/15
to moose-users
The reference residual or "initial residual" is the first residual calculation performed each time you ask the NonlinearSystem to solve(). It is computed before applying the present nodal BCs or predictors so it can vary from the initial residual. I know that Ben, Jason and others have seen wide variation in certain solid mechanics problems. I'm not sure if there's been consensus on whether we need to compute a different l2_norm() in the presence of present BCs or not. Does anyone else want to chime in here?

Cody

--
You received this message because you are subscribed to the Google Groups "moose-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to moose-users...@googlegroups.com.
Visit this group at http://groups.google.com/group/moose-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/moose-users/CAKe0TuPksrYUK1tEv2E9wxT1422kFcFs5LQtd5s6_xsO6FQo4g%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Benjamin Spencer

unread,
Mar 12, 2015, 6:41:45 PM3/12/15
to moose-users
I took a look at his problem earlier in the day, and it's doing something weird.  I would have expected it to be using the initial residual as the reference quantity, but it had a number that was orders of magnitude lower than the reported number. It needs further investigation.  I'm not sure what is going on there.

The discussion of whether using the initial residual is a good idea is off-topic, but I'll go ahead and discuss it here.  Using the initial residual as a reference for convergence can be unreliable because it really just quantifies how close the initial guess is to the converged solution, rather than anything meaningful about the physics being modeled. If the model doesn't change much from its state in the previous step, the initial residual can be very low, which forces the model to converge to an unreasonably tight tolerance. That is problematic for fuel models, which can sit at an essentially steady state for long periods of time.  You'd have the same problem if you had a really good predictor that put your initial guess close to the actual solution.

Because of that, a while ago I wrote the ReferenceResidualProblem, which overwrites the method on Problem that calculates nonlinear convergence.  ReferenceResidualProblem looks at the norms of the solution variables, and compares them individually to the norms of user-supplied variables that contain the conjugates to the solution variables where BCs are applied (reaction loads at BCs for mechanics, or integrated fluxes for heat conduction). Those are physically meaningful quantities that give a measure of the effect of the BCs on the model.

We use ReferenceResidualProblem pretty often, typically with significant speedup and robustness compared to what we get using the initial residual since we're not converging to needlessly tight tolerances.  The problem is that it's kind of a pain for users to set up.  They have to set up an AuxVariable corresponding to each solution variable to store the reaction loads, and then they have to add a "save_in" line to each Kernel.  Then they have to add a Problem block and tell it the name of those vectors.  We talked a while ago with Derek about doing some things to streamline things, but it was so long ago I can't even remember what the proposed solution was.  I'd be in favor of bringing the code in ReferenceResidualProblem in as an option in FEProblem if you guys are in favor of that.

Ben

Andrew....@csiro.au

unread,
Mar 12, 2015, 6:54:00 PM3/12/15
to moose...@googlegroups.com

Getting further away from the initial question, but still relevant….

 

I agree with you, Ben, that setting tolerances is a mystery to many people, and it can result in much frustration.  It would be nice if we could make it easier.  One thing that’s surely possible to address is that I frequently find that users (myself included) have set the tolerance too low and hence convergence is never established because of precision loss.  I somehow think that if the computer had some brains it would see that only the last significant figure of the variable is changing every nonlinear step, and the residual is tiny, and it would take appropriate action.  Any robust ideas?

 

a

 

Ph: +61 7 3327 4497.  Fax: +61 7 3327 4666
Queensland Centre for Advanced Technologies
PO Box 883, Kenmore, Qld, 4069 
 

Wang (Non-US), Yaqi

unread,
Mar 12, 2015, 7:06:13 PM3/12/15
to moose-users
Is there a way to check |dx|/|x| every newton iteration?

Andrs, David

unread,
Mar 13, 2015, 10:44:00 AM3/13/15
to moose...@googlegroups.com
On Thu, Mar 12, 2015 at 5:06 PM, Wang (Non-US), Yaqi <yaqi...@inl.gov> wrote:
Is there a way to check |dx|/|x| every newton iteration?

PETSC has a c​allback that can be called every newton iteration, so this should be possible to do...
--
David

 

Derek Gaston

unread,
Mar 13, 2015, 10:59:04 AM3/13/15
to moose...@googlegroups.com
That option already exists: Executioner/nl_abs_step_tol

_HOWEVER_: Be warned that this can be just as precarious to set.  If the nonlinear solver stalls for some reason other than because it reached its convergence limit then this will still get triggered and the solve will be counted as _converged_!

There is no silver bullet here guys.  That's the reason we have all of these options.  If there was a simple solution then PETSc would have already implemented it 20 years ago and we wouldn't even have all of these options.  There is no way around it: users need to have some idea of what they're doing and how their models are acting and how solver tolerances play into that.

BTW: It's not any better in commercial software.  If you use Abaqus, for instance, it exposes all of the same options to users... with a sane set of defaults just like we have.  And they primarily have a _single_ type of physics to solve!

Derek


Cody Permann

unread,
Mar 13, 2015, 3:04:16 PM3/13/15
to moose...@googlegroups.com
Ben,

If ReferenceResidualProblem works well for some types of problems I don't see any reason why it needs to be difficult to set up. We should be able to create additional Actions or just have the problem itself add additional aux variables and append the necessary options to all of the kernels to just make it work out of the box.



Benjamin Spencer

unread,
Mar 13, 2015, 3:13:47 PM3/13/15
to moose-users
Yes, you're probably right.  If we can use an Action to modify objects that were already created (which I haven't ever done), then that should be fairly easily do-able.  I'll put it on my list of things I'd like to do when I can get around to them.

-Ben

Derek Gaston

unread,
Mar 13, 2015, 4:53:51 PM3/13/15
to moose-users
Part of the problem is that the implementation of "save_in" is not right. For instance: it requires thread locking in every object's computeResidual() call... which will destroy any threaded speed up. It also does a LOT of dof ID lookups which are way slow.

I implemented it to solve a particular problem (get the residual of a particular object) and now it's being used for more than that.

I had always planned on changing it... I really thought we would implement the "residual tagging" capability at some point (so objects could naturally contribute to more than one residual vector for different purposes). But that has yet to materialize.

Before we go relying on this capability we need to redesign it and make it right...

Derek

Chakraborty (Non-US), Pritam

unread,
Mar 13, 2015, 5:18:13 PM3/13/15
to moose-users
Just want to put a quick observation. The reference residual value matches with initial residual of the DirichletBC even when a PresetBC is specified.

Pritam

Reply all
Reply to author
Forward
0 new messages