Newton Secant root. Aleks Jemcov
This commit is contained in:
parent
31a876c71f
commit
ceabdbb728
3 changed files with 239 additions and 2 deletions
|
@ -34,6 +34,7 @@ Description
|
||||||
#include "IOmanip.H"
|
#include "IOmanip.H"
|
||||||
#include "BisectionRoot.H"
|
#include "BisectionRoot.H"
|
||||||
#include "RiddersRoot.H"
|
#include "RiddersRoot.H"
|
||||||
|
#include "NewtonSecantRoot.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
@ -50,15 +51,38 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class testFunctionDerivative
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
testFunctionDerivative()
|
||||||
|
{}
|
||||||
|
|
||||||
|
scalar operator()(const scalar& x) const
|
||||||
|
{
|
||||||
|
return 0.5*Foam::pow(x,-1.5) - Foam::cos(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
testFunction tf;
|
testFunction tf;
|
||||||
|
testFunctionDerivative df;
|
||||||
|
|
||||||
Info<< setprecision(10)
|
Info<< setprecision(10)
|
||||||
<< "Bisection root "
|
<< "Bisection root "
|
||||||
<< BisectionRoot<testFunction>(tf, 1e-5).root(0, 10) << nl
|
<< BisectionRoot<testFunction>(tf, 1e-5).root(0, 10) << nl
|
||||||
<< "Ridders root "
|
<< "Ridders root "
|
||||||
<< RiddersRoot<testFunction>(tf, 1e-5).root(0, 10) << endl;
|
<< RiddersRoot<testFunction>(tf, 1e-5).root(0, 10) << nl
|
||||||
|
<< "NewtonSecant root "
|
||||||
|
<< NewtonSecantRoot<testFunction,testFunctionDerivative>
|
||||||
|
(
|
||||||
|
tf,
|
||||||
|
df,
|
||||||
|
1e-5
|
||||||
|
).root(1.5) << endl;
|
||||||
|
|
||||||
|
|
||||||
Info<< "End\n" << endl;
|
Info<< "End\n" << endl;
|
||||||
|
|
105
src/ODE/findRoot/NewtonSecantRoot/NewtonSecantRoot.C
Normal file
105
src/ODE/findRoot/NewtonSecantRoot/NewtonSecantRoot.C
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright held by original author
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Class
|
||||||
|
NewtonSecantRoot
|
||||||
|
|
||||||
|
Description
|
||||||
|
NewtonSecant root finder for better stability.
|
||||||
|
Function is provided as a template parameter function object, evaluated
|
||||||
|
using operator()(const scalar x)
|
||||||
|
|
||||||
|
Author
|
||||||
|
Aleksandar Jemcov. All rights reserved.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "NewtonSecantRoot.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<typename Func, typename Deriv>
|
||||||
|
const Foam::label Foam::NewtonSecantRoot<Func,Deriv>::maxIter = 60;
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<typename Func, typename Deriv>
|
||||||
|
Foam::NewtonSecantRoot<Func,Deriv>::NewtonSecantRoot
|
||||||
|
(
|
||||||
|
const Func& f,
|
||||||
|
const Deriv& d,
|
||||||
|
const scalar eps
|
||||||
|
)
|
||||||
|
:
|
||||||
|
f_(f),
|
||||||
|
d_(d),
|
||||||
|
eps_(eps)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<typename Func, typename Deriv>
|
||||||
|
Foam::scalar Foam::NewtonSecantRoot<Func,Deriv>::root
|
||||||
|
(
|
||||||
|
scalar xN
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (0 == d_(xN))
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"Foam::scalar Foam::NewtonSecantRoot<Func,Deriv>::root\n"
|
||||||
|
"(\n"
|
||||||
|
" const scalar xN,\n"
|
||||||
|
") const"
|
||||||
|
) << "Jacobian equal to zero. f'(xN) = " << d_(xN)
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
scalar xNp1;
|
||||||
|
|
||||||
|
for (label nIter = 0; nIter < maxIter; ++nIter)
|
||||||
|
{
|
||||||
|
scalar fN = this->f_(xN);
|
||||||
|
scalar dN = this->d_(xN);
|
||||||
|
scalar dx = fN/dN;
|
||||||
|
|
||||||
|
scalar xBar = xN - dx;
|
||||||
|
|
||||||
|
xNp1 = xN - fN*fN/(dN*(fN - f_(xBar)));
|
||||||
|
if (mag(xN - xNp1) <= this->eps_)
|
||||||
|
{
|
||||||
|
return xNp1;
|
||||||
|
}
|
||||||
|
|
||||||
|
xN = xNp1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xNp1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
108
src/ODE/findRoot/NewtonSecantRoot/NewtonSecantRoot.H
Normal file
108
src/ODE/findRoot/NewtonSecantRoot/NewtonSecantRoot.H
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright held by original author
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Class
|
||||||
|
NewtonSecantRoot
|
||||||
|
|
||||||
|
Description
|
||||||
|
NewtonSecant root is based on combination of Newton and Secant methods.
|
||||||
|
Function and the funciton derivative are provided as a template parameter
|
||||||
|
function object, evaluated using operator()(const scalar x)
|
||||||
|
|
||||||
|
Author
|
||||||
|
Aleksandar Jemcov. All rights reserved.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
NewtonSecantRoot.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef NewtonSecantRoot_H
|
||||||
|
#define NewtonSecantRoot_H
|
||||||
|
|
||||||
|
#include "scalar.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class NewtonSecantRoot Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template<typename Func, typename Deriv>
|
||||||
|
class NewtonSecantRoot
|
||||||
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- Reference to a function
|
||||||
|
const Func& f_;
|
||||||
|
|
||||||
|
//- Reference to a derivative
|
||||||
|
const Deriv& d_;
|
||||||
|
|
||||||
|
//- Required accuracy
|
||||||
|
const scalar eps_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Static data members
|
||||||
|
|
||||||
|
//- Maximum number of iterations
|
||||||
|
static const label maxIter;
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct given a function
|
||||||
|
NewtonSecantRoot(const Func& f, const Deriv& d, const scalar eps);
|
||||||
|
|
||||||
|
|
||||||
|
// Destructor - default
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Return root
|
||||||
|
scalar root(scalar xN) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
# include "NewtonSecantRoot.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
Reference in a new issue