CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Running, Solving & CFD (https://www.cfd-online.com/Forums/openfoam-solving/)
-   -   Residual Control and InitialResidual: How does it exactly work? (https://www.cfd-online.com/Forums/openfoam-solving/150201-residual-control-initialresidual-how-does-exactly-work.html)

hrushi.397 March 17, 2015 11:15

Residual Control and InitialResidual: How does it exactly work?
 
Dear all,

Could someone please clarify to me how residualControl in fvSolution works? As far as I know, residualControl helps you control the flow of the simulation based on the InitialResidual. If the initialResidual during successive corrector steps falls below the level as specified in the residualControl, then the corrector should stop, irrespective of number of corrector steps specified in nCorrectors specified. Is my interpretation correct?

Regards,

Hrushi

agustinvo March 18, 2015 03:09

Hi,

in each variable

Code:

    U
    {
        solver          GAMG;
        ...
   
      tolerance      1e-12;
      relTol          0.;
    }

tolerance will stop you iterations for that equation in function of the Final Residual.
Then the residualControl is working with the InitialResidual, as you said.

I think this is what you were asking.

hrushi.397 March 18, 2015 05:12

Hi Augstin,

Thank you for the reply. I understand the tolerance and how it works. And if I understand what you are saying, then the residualControl in fvSolution specifies the control on the initialResidual.

In my solver, I tried to set residualControl for pressure at 0.1. But I could see that even after such a relaxed residualControl, my simulations ran for 15 correctors that I had specified earlier. I do not understand why this is happening. Any suggestions?

Regards,

Hrushikesh

alexeym March 18, 2015 05:39

Hi,

resildualControl limits number of outer correctors (nOuterCorrectors). Just take a look at pimpleFoam source:

Code:

        // --- Pressure-velocity PIMPLE corrector loop
        while (pimple.loop())
        {
            ...
            // --- Pressure corrector loop
            while (pimple.correct())
            {
                #include "pEqn.H"
            }
            ...
        }

You have got two while loops, inner stops when pimple.correct() returns false, outer stops when pimple.loop() returns false. So take a look at pimpleControl sources:

pimpleControl.C
Code:

void Foam::pimpleControl::read()
{
    ...
    nCorrPIMPLE_ = pimpleDict.lookupOrDefault<label>("nOuterCorrectors", 1);
    nCorrPISO_ = pimpleDict.lookupOrDefault<label>("nCorrectors", 1);
    ...
}

pimpleControlI.H
Code:

inline bool Foam::pimpleControl::correct()
{
    corrPISO_++;

    if (debug)
    {
        Info<< algorithmName_ << " correct: corrPISO = " << corrPISO_ << endl;
    }

    if (corrPISO_ <= nCorrPISO_)
    {
        return true;
    }
    else
    {
        corrPISO_ = 0;
        return false;
    }
}

So pimple.correct will return false only when number of corrector iterations exceed nCorrectors. While pimple.loop

Code:

bool Foam::pimpleControl::loop()
{
    ...

    if (corr_ == nCorrPIMPLE_ + 1)
    {
        if ((!residualControl_.empty()) && (nCorrPIMPLE_ != 1))
        {
            Info<< algorithmName_ << ": not converged within "
                << nCorrPIMPLE_ << " iterations" << endl;
        }

        corr_ = 0;
        mesh_.data::remove("finalIteration");
        return false;
    }

    bool completed = false;
    if (converged_ || criteriaSatisfied())
    {
        if (converged_)
        {
            Info<< algorithmName_ << ": converged in " << corr_ - 1
                << " iterations" << endl;

            mesh_.data::remove("finalIteration");
            corr_ = 0;
            converged_ = false;

            completed = true;
        }
        else
        {
            Info<< algorithmName_ << ": iteration " << corr_ << endl;
            storePrevIterFields();

            mesh_.data::add("finalIteration", true);
            converged_ = true;
        }
    }
    ...
    return !completed;
}

will continue till number of iterations exceed nOutetCorrectors or this condition becomes true

Code:

converged_ || criteriaSatisfied()
and it is criteriaSatisfied() that checks initial residuals:

Code:

bool Foam::pimpleControl::criteriaSatisfied()
{
    ...
            const bool absCheck = residual < residualControl_[fieldI].absTol;
            bool relCheck = false;

            scalar relative = 0.0;
            if (!storeIni)
            {
                const scalar iniRes =
                    residualControl_[fieldI].initialResidual
                  + ROOTVSMALL;

                relative = residual/iniRes;
                relCheck = relative < residualControl_[fieldI].relTol;
            }

            achieved = achieved && (absCheck || relCheck);
    ...
    return checked && achieved;
}

Though IIRC it was already explained several times on the forum.

hrushi.397 March 18, 2015 07:53

Hi Alexey,

Thank you very much for your response. It is pretty clear to me now.

Regards,

Hrushi

chriss85 March 18, 2015 12:10

Also see http://www.cfd-online.com/Forums/blo...hm-part-i.html and http://www.cfd-online.com/Forums/blo...m-part-ii.html for a good explanation.


All times are GMT -4. The time now is 10:28.