FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

KRR4.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "KRR4.H"
00027 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00028 
00029 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00030 
00031 defineTypeNameAndDebug(Foam::KRR4, 0);
00032 
00033 namespace Foam
00034 {
00035     addToRunTimeSelectionTable(ODESolver, KRR4, ODE);
00036 
00037 const scalar
00038     KRR4::safety = 0.9, KRR4::grow = 1.5, KRR4::pgrow = -0.25,
00039     KRR4::shrink = 0.5, KRR4::pshrink = (-1.0/3.0), KRR4::errcon = 0.1296;
00040 
00041 const scalar
00042     KRR4::gamma = 1.0/2.0,
00043     KRR4::a21 = 2.0, KRR4::a31 = 48.0/25.0, KRR4::a32 = 6.0/25.0,
00044     KRR4::c21 = -8.0, KRR4::c31 = 372.0/25.0, KRR4::c32 = 12.0/5.0,
00045     KRR4::c41 = -112.0/125.0, KRR4::c42 = -54.0/125.0, KRR4::c43 = -2.0/5.0,
00046     KRR4::b1 = 19.0/9.0, KRR4::b2 = 1.0/2.0, KRR4::b3 = 25.0/108.0,
00047     KRR4::b4 = 125.0/108.0,
00048     KRR4::e1 = 17.0/54.0, KRR4::e2 = 7.0/36.0, KRR4::e3 = 0.0,
00049     KRR4::e4 = 125.0/108.0,
00050     KRR4::c1X = 1.0/2.0, KRR4::c2X = -3.0/2.0, KRR4::c3X = 121.0/50.0,
00051     KRR4::c4X = 29.0/250.0,
00052     KRR4::a2X = 1.0, KRR4::a3X = 3.0/5.0;
00053 };
00054 
00055 
00056 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00057 
00058 Foam::KRR4::KRR4(const ODE& ode)
00059 :
00060     ODESolver(ode),
00061     yTemp_(n_, 0.0),
00062     dydxTemp_(n_, 0.0),
00063     g1_(n_, 0.0),
00064     g2_(n_, 0.0),
00065     g3_(n_, 0.0),
00066     g4_(n_, 0.0),
00067     yErr_(n_, 0.0),
00068     dfdx_(n_, 0.0),
00069     dfdy_(n_, n_, 0.0),
00070     a_(n_, n_, 0.0),
00071     pivotIndices_(n_, 0.0)
00072 {}
00073 
00074 
00075 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00076 
00077 void Foam::KRR4::solve
00078 (
00079     const ODE& ode,
00080     scalar& x,
00081     scalarField& y,
00082     scalarField& dydx,
00083     const scalar eps,
00084     const scalarField& yScale,
00085     const scalar hTry,
00086     scalar& hDid,
00087     scalar& hNext
00088 ) const
00089 {
00090     scalar xTemp = x;
00091     yTemp_ = y;
00092     dydxTemp_ = dydx;
00093 
00094     ode.jacobian(xTemp, yTemp_, dfdx_, dfdy_);
00095 
00096     scalar h = hTry;
00097 
00098     for (register label jtry=0; jtry<maxtry; jtry++)
00099     {
00100         for (register label i=0; i<n_; i++)
00101         {
00102             for (register label j=0; j<n_; j++)
00103             {
00104                 a_[i][j] = -dfdy_[i][j];
00105             }
00106 
00107             a_[i][i] += 1.0/(gamma*h);
00108         }
00109 
00110         LUDecompose(a_, pivotIndices_);
00111 
00112         for (register label i=0; i<n_; i++)
00113         {
00114             g1_[i] = dydxTemp_[i] + h*c1X*dfdx_[i];
00115         }
00116 
00117         LUBacksubstitute(a_, pivotIndices_, g1_);
00118 
00119         for (register label i=0; i<n_; i++)
00120         {
00121             y[i] = yTemp_[i] + a21*g1_[i];
00122         }
00123 
00124         x = xTemp + a2X*h;
00125         ode.derivatives(x, y, dydx_);
00126 
00127         for (register label i=0; i<n_; i++)
00128         {
00129             g2_[i] = dydx_[i] + h*c2X*dfdx_[i] + c21*g1_[i]/h;
00130         }
00131 
00132         LUBacksubstitute(a_, pivotIndices_, g2_);
00133 
00134         for (register label i=0; i<n_; i++)
00135         {
00136             y[i] = yTemp_[i] + a31*g1_[i] + a32*g2_[i];
00137         }
00138 
00139         x = xTemp + a3X*h;
00140         ode.derivatives(x, y, dydx_);
00141 
00142         for (register label i=0; i<n_; i++)
00143         {
00144             g3_[i] = dydx[i] + h*c3X*dfdx_[i] + (c31*g1_[i] + c32*g2_[i])/h;
00145         }
00146 
00147         LUBacksubstitute(a_, pivotIndices_, g3_);
00148 
00149         for (register label i=0; i<n_; i++)
00150         {
00151             g4_[i] = dydx_[i] + h*c4X*dfdx_[i]
00152                 + (c41*g1_[i] + c42*g2_[i] + c43*g3_[i])/h;
00153         }
00154 
00155         LUBacksubstitute(a_, pivotIndices_, g4_);
00156 
00157         for (register label i=0; i<n_; i++)
00158         {
00159             y[i] = yTemp_[i] + b1*g1_[i] + b2*g2_[i] + b3*g3_[i] + b4*g4_[i];
00160             yErr_[i] = e1*g1_[i] + e2*g2_[i] + e3*g3_[i] + e4*g4_[i];
00161         }
00162 
00163         x = xTemp + h;
00164 
00165         if (x == xTemp)
00166         {
00167             FatalErrorIn("ODES::KRR4")
00168                 << "stepsize not significant"
00169                 << exit(FatalError);
00170         }
00171 
00172         scalar maxErr = 0.0;
00173         for (register label i=0; i<n_; i++)
00174         {
00175             maxErr = max(maxErr, mag(yErr_[i]/yScale[i]));
00176         }
00177         maxErr /= eps;
00178 
00179         if (maxErr <= 1.0)
00180         {
00181             hDid = h;
00182             hNext = (maxErr > errcon ? safety*h*pow(maxErr, pgrow) : grow*h);
00183             return;
00184         }
00185         else
00186         {
00187             hNext = safety*h*pow(maxErr, pshrink);
00188             h = (h >= 0.0 ? max(hNext, shrink*h) : min(hNext, shrink*h));
00189         }
00190     }
00191 
00192     FatalErrorIn("ODES::KRR4")
00193         << "exceeded maxtry"
00194         << exit(FatalError);
00195 }
00196 
00197 
00198 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines