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 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
#include "ScalarIVPSolver.h"
// Solve y’ = y, with y(0) = 1
// G0 is just the value of y(tau)
double G0(vector<double> &x)
{
return x[1];
}
// This is nothing but the right hand side of the ODE
double G1(vector<double> &x)
{
return x[1];
}
double G2(vector<double> &x)
{
return x[2];
}
double G3(vector<double> &x)
{
return x[3];
}
int main()
{
int order = 3;
ScalarIVPSolver *ts;
ts = new TaylorSeriesMethod(order);
// Set mathematical expression for calculation of y^(k), k=0,...,order
ts->set_function_G(0, G0);
ts->set_function_G(1, G1);
ts->set_function_G(2, G2);
ts->set_function_G(3, G3);
double t0 = 0.0;
double y0 = 1.0;
double te = 2.0;
int N = 20;
double h = (te - t0) / N;
vector<double> t(N + 1);
vector<double> Y(N + 1);
t[0] = t0;
Y[0] = y0;
for (int j = 1; j <= N; j++)
{
Y[j] = ts->one_step_march(h, t[j - 1], Y[j - 1]);
t[j] = t[j - 1] + h;
}
delete ts;
ofstream fileout;
fileout.open("solts.txt");
fileout << setprecision(10) << setiosflags(ios::scientific | ios::showpos);
for (int j = 0; j <= N; j++)
{
fileout << t[j] << " " << Y[j] << " " << exp(t[j]) << endl;
}
fileout.close();
// Run again with Euler Scheme (first order)
ts = new EulerScheme;
ts->set_function_G(0, G0);
ts->set_function_G(1, G1);
for (int j = 1; j <= N; j++)
{
Y[j] = ts->one_step_march(h, t[j - 1], Y[j - 1]);
t[j] = t[j - 1] + h;
}
delete ts;
fileout.open("soleuler.txt");
fileout << setprecision(10) << setiosflags(ios::scientific | ios::showpos);
for (int j = 0; j <= N; j++)
{
fileout << t[j] << " " << Y[j] << " " << exp(t[j]) << endl;
}
fileout.close();
// Run again with Backward Euler Scheme (first order)
ts = new BackwardEulerScheme;
ts->set_function_G(0, G0);
ts->set_function_G(1, G1);
ts->set_function_G(2, G2);
for (int j = 1; j <= N; j++)
{
Y[j] = ts->one_step_march(h, t[j - 1], Y[j - 1]);
t[j] = t[j - 1] + h;
}
delete ts;
fileout.open("solbackeuler.txt");
fileout << setprecision(10) << setiosflags(ios::scientific | ios::showpos);
for (int j = 0; j <= N; j++)
{
fileout << t[j] << " " << Y[j] << " " << exp(t[j]) << endl;
}
fileout.close();
// Run again with Trapezoidal Scheme (second order)
ts = new TrapezoidalScheme;
ts->set_function_G(0, G0);
ts->set_function_G(1, G1);
ts->set_function_G(2, G2);
for (int j = 1; j <= N; j++)
{
Y[j] = ts->one_step_march(h, t[j - 1], Y[j - 1]);
t[j] = t[j - 1] + h;
}
delete ts;
fileout.open("soltrapezoid.txt");
fileout << setprecision(10) << setiosflags(ios::scientific | ios::showpos);
for (int j = 0; j <= N; j++)
{
fileout << t[j] << " " << Y[j] << " " << exp(t[j]) << endl;
}
fileout.close();
// Run again with Runge-Kutta (variable order)
int stage = 4;
double *weight = new double[stage] { (1/6),(1/3),(1/3),(1/6) }; // standard RK4 Butcher Table
double *a = new double[6]{ 0.5,0,0.5,0,0,1 };
double *c = new double[stage] {0, 0.5, 0.5, 1};
ts = new ExplicitRKScheme(stage, a, weight, c);
ts->set_function_G(0, G0);
ts->set_function_G(1, G1);
for (int j = 1; j <= N; j++)
{
Y[j] = ts->one_step_march(h, t[j - 1], Y[j - 1]);
t[j] = t[j - 1] + h;
}
delete ts;
delete c;
delete a;
delete weight;
fileout.open("solrk.txt");
fileout << setprecision(10) << setiosflags(ios::scientific | ios::showpos);
for (int j = 0; j <= N; j++)
{
fileout << t[j] << " " << Y[j] << " " << exp(t[j]) << endl;
}
fileout.close();
return 0;
}
|