1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
|
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
// Global variables (hmmm) - all needed by f and fprime
double L; // length of domain in m
double x; // position
double Tfactor; // temperature ratio
struct dataset
{
double TL; // temperature at left-hand end
double TR; // temperature at right-hand end (ambient)
double T; // intermediate temperature
double x; // position where that temperature is measured
};
//======================================================================
double f( double m ) // function
{
return cosh( m * ( L - x ) ) / cosh( m * L ) - Tfactor;
}
//======================================================================
double fprime( double m ) // derivative of f
{
double arg = m * L;
double argx = m * ( L - x );
return ( L - x ) * sinh( argx ) / cosh( arg ) - L * tanh( arg ) * ( f( m ) + Tfactor );
}
//======================================================================
double NewtonRaphson( double m0 )
{
const int MAXITER = 100; // maximum number of iterations
const double TOLERANCE = 1.0e-10; // tolerance for successive m values
int iter = 0; // number of iterations
double change = 1.0; // anything large
double m = m0; // eventual solution
while ( iter < MAXITER && change > TOLERANCE )
{
iter++;
double mprev = m;
m = m - f( m ) / fprime( m ); // Newton-Raphson iteration
change = abs( m - mprev );
}
if ( change > TOLERANCE && iter >= MAXITER ) cout << "Not converged.\n";
return m;
}
//======================================================================
int main()
{
const double m0 = 7.4; // starting guess
L = 0.4; // length of domain
vector<dataset> tests = { { 46.3, 20.7, 38.9, 0.05 }, // Sets of values of T1, T9, T, x
{ 46.3, 20.7, 26.7, 0.20 },
{ 46.3, 20.7, 23.4, 0.35 },
};
for ( auto e : tests )
{
Tfactor = ( e.T - e.TR ) / ( e.TL - e.TR );
x = e.x;
double m = NewtonRaphson( m0 );
cout << "Case is:\n"
<< "TL = " << e.TL << '\n'
<< "TR = " << e.TR << '\n'
<< "T = " << e.T << '\n'
<< "x = " << e.x << '\n'
<< "Value of m = " << m << "\n\n";
}
}
|