-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfwd_euler.cpp
85 lines (65 loc) · 2.13 KB
/
fwd_euler.cpp
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
/* Forward Euler time stepper class implementation file.
Class to perform time evolution of the IVP
y' = f(t,y), t in [t0, Tf], y(t0) = y0
using the forward Euler (explicit Euler) time stepping method.
D.R. Reynolds
Math 6321 @ SMU
Fall 2020 */
#include "fwd_euler.hpp"
using namespace std;
using namespace arma;
// The forward Euler time step evolution routine
//
// Inputs: tspan holds the time intervals, [t0, t1, ..., tN]
// h holds the desired time step size
// y holds the initial condition, y(t0)
// Outputs: the output matrix holds the computed solution at
// all tspan values,
// [y(t0), y(t1), ..., y(tN)]
mat ForwardEulerStepper::Evolve(vec tspan, double h, vec y) {
// store sizes
size_t m = y.n_elem;
size_t N = tspan.n_elem-1;
// initialize output
mat Y(m, N+1, fill::zeros);
Y.col(0) = y;
// reset nsteps counter, current time value
nsteps = 0;
double t = tspan(0);
// check for legal inputs
if (h <= 0.0) {
cerr << "ForwardEulerStepper: Illegal h\n";
return Y;
}
for (size_t tstep=0; tstep<N; tstep++) {
if (tspan(tstep+1) < tspan(tstep)) {
cerr << "ForwardEulerStepper: Illegal tspan\n";
return Y;
}
}
// iterate over output time steps
for (size_t tstep=0; tstep<N; tstep++) {
// figure out how many time steps in this output interval
size_t Nint = (tspan(tstep+1)-tspan(tstep)) / h;
if ((tspan(tstep+1) - (tspan(tstep)+Nint*h)) > sqrt(eps(tspan(tstep+1)))) Nint++;
// loop over internal steps to get to desired output time
for (size_t i=0; i<Nint; i++) {
// last step only: update h to stop directly at final time
double hcur = h;
if (i == Nint-1) hcur = tspan(tstep+1)-t;
// compute ODE RHS
if (frhs->Evaluate(t, y, f) != 0) {
cerr << "ForwardEulerStepper: Error in ODE RHS function\n";
return Y;
}
// update solution with forward Euler step
y += (hcur*f);
// update current time, nsteps counter
t += hcur;
nsteps++;
}
// store updated solution in output array
Y.col(tstep+1) = y;
}
return Y;
}