時間刻み幅の自動調整

2011年9月1日

はじめに

時間刻み幅の自動調整について。

使用バージョン

OpenFOAM 1.7.1

時間刻み幅の自動調整

system/controlDict の "adjustTimeStep" を "yes" に設定すると、時間刻み幅が自動調整される。関係する設定は次のとおり。

  • deltaT : 初期時間刻み幅
  • maxDeltaT : 最大時間刻み幅
  • maxCo : 最大クーラン数
  • writeControl adjustableRunTime : データ保存時間間隔の指定

writeControl の adjustableRunTime を使うと、時間刻み幅の大きさに関係なく一定の時間間隔で結果を保存できるので便利だが、時間刻み幅調整がクーラン数とはあまり関係がなくなる。

時間刻み幅の決定は setDeltaT.H で行われる。

if (adjustTimeStep)
{
    scalar maxDeltaTFact = maxCo/(CoNum + StCoNum + SMALL);
    scalar deltaTFact = min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);

    runTime.setDeltaT
    (
        min
        (
            deltaTFact*runTime.deltaTValue(),
            maxDeltaT
        )
    );

    Info<< "deltaT = " <<  runTime.deltaTValue() << endl;
}

時間刻み幅の拡大率が最大 1.2 に制限されている。

writeControl に adjustableRunTime を使った場合、Time の adjustDeltaT() で時間幅が調整される (Time.C)。

void Foam::Time::adjustDeltaT()
{
    if (writeControl_ == wcAdjustableRunTime)
    {
        scalar timeToNextWrite = max
        (
            0.0,
            (outputTimeIndex_ + 1)*writeInterval_ - (value() - startTime_)
        );

        scalar nSteps = timeToNextWrite/deltaT_ - SMALL;

        // For tiny deltaT the label can overflow!
        if (nSteps < labelMax)
        {
            label nStepsToNextWrite = label(nSteps) + 1;

            scalar newDeltaT = timeToNextWrite/nStepsToNextWrite;

            // Control the increase of the time step to within a factor of 2
            // and the decrease within a factor of 5.
            if (newDeltaT >= deltaT_)
            {
                deltaT_ = min(newDeltaT, 2.0*deltaT_);
            }
            else
            {
                deltaT_ = max(newDeltaT, 0.2*deltaT_);
            }
        }
    }
}

...

void Foam::Time::setDeltaT(const scalar deltaT)
{
    deltaT_ = deltaT;
    deltaTchanged_ = true;
    adjustDeltaT();
}

この場合、deltaT をどんなに大きくしたくても 0.2*deltaT に制限されてしまう。