Solve a multivariable first order ordinary differential equation (ODEs) using forward Euler method More...
#include <cmath>
#include <ctime>
#include <fstream>
#include <iostream>
#include <valarray>
Go to the source code of this file.
void problem (const double &x, std::valarray< double > *y, std::valarray< double > *dy) Problem statement for a system with first-order differential equations. Updates the system differential variables.Solve a multivariable first order ordinary differential equation (ODEs) using forward Euler method
The ODE being solved is:
\begin{eqnarray*} \dot{u} &=& v\\ \dot{v} &=& -\omega^2 u\\ \omega &=& 1\\ [x_0, u_0, v_0] &=& [0,1,0]\qquad\ldots\text{(initial values)} \end{eqnarray*}
The exact solution for the above problem is:
\begin{eqnarray*} u(x) &=& \cos(x)\\ v(x) &=& -\sin(x)\\ \end{eqnarray*}
The computation results are stored to a text file forward_euler.csv and the exact soltuion results in exact.csv for comparison.
To implement Van der Pol oscillator, change the problem function to:
const double mu = 2.0;
dy[0] = y[1];
dy[1] = mu * (1.f - y[0] * y[0]) * y[1] - y[0];
Definition in file ode_forward_euler.cpp.
◆ exact_solution() void exact_solution ( const double & x, std::valarray< double > * y )Exact solution of the problem. Used for solution comparison.
Definition at line 67 of file ode_forward_euler.cpp.
67 {
68 y[0][0] = std::cos(x);
69 y[0][1] = -std::sin(x);
70}
◆ main() int main ( int argc, char * argv[] )Main Function
Definition at line 189 of file ode_forward_euler.cpp.
189 {
190 double X0 = 0.f;
191 double X_MAX = 10.F;
192 std::valarray<double> Y0{1.f, 0.f};
193 double step_size = NAN;
194
195 if (argc == 1) {
196 std::cout << "\nEnter the step size: ";
197 std::cin >> step_size;
198 } else {
199
200 step_size = std::atof(argv[1]);
201 }
202
203
204 doubletotal_time =
forward_euler(step_size, X0, X_MAX, &Y0,
true);
205 std::cout << "\tTime = " << total_time << " ms\n";
206
207
209
210 return 0;
211}
double forward_euler(double dx, double x0, double x_max, std::valarray< double > *y, bool save_to_file=false)
Compute approximation using the forward-Euler method in the given limits.
void save_exact_solution(const double &X0, const double &X_MAX, const double &step_size, const std::valarray< double > &Y0)
◆ problem() void problem ( const double & x, std::valarray< double > * y, std::valarray< double > * dy )Problem statement for a system with first-order differential equations. Updates the system differential variables.
Definition at line 54 of file ode_forward_euler.cpp.
55 {
56 const double omega = 1.F;
57 (*dy)[0] = (*y)[1];
58 (*dy)[1] = -omega * omega * (*y)[0];
59}
◆ save_exact_solution() void save_exact_solution ( const double & X0, const double & X_MAX, const double & step_size, const std::valarray< double > & Y0 )Function to compute and save exact solution for comparison
Definition at line 153 of file ode_forward_euler.cpp.
155 {
156 double x = X0;
157 std::valarray<double> y(Y0);
158
159 std::ofstream fp("exact.csv", std::ostream::out);
160 if (!fp.is_open()) {
161 std::perror("Error! ");
162 return;
163 }
164 std::cout << "Finding exact solution\n";
165
166 std::clock_t t1 = std::clock();
167 do {
168 fp << x << ",";
169 for (int i = 0; i < y.size() - 1; i++) {
170 fp << y[i] << ",";
171 }
172 fp << y[y.size() - 1] << "\n";
173
175
176 x += step_size;
177 } while (x <= X_MAX);
178
179 std::clock_t t2 = std::clock();
180 double total_time = static_cast<double>(t2 - t1) / CLOCKS_PER_SEC;
181 std::cout << "\tTime = " << total_time << " ms\n";
182
183 fp.close();
184}
void exact_solution(const double &x, std::valarray< double > *y)
Exact solution of the problem. Used for solution comparison.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4