Сетевое издание
Международный студенческий научный вестник
ISSN 2409-529X

IMPLEMENTATION OF RUNGE-KUTTA METHODS FOR SOLVING FIRST-ORDER ORDINARY DIFFERENTIAL EQUATIONS IN THE C++ PROGRAMMING LANGUAGE

1
1
In this paper, we consider the implementation of the numerical solution of the Cauchy problem for an ordinary first-order differential equation by two-stage, three-stage and four-stage Runge-Kutta difference methods of the second, third and fourth order approximation, respectively, in the C++ programming language. This program can be useful in the modern world due to computerization in various fields of technology, production science. To solve many problems faced by a person in various fields of activity, it is necessary to make mathematical models of real situations. Very often, these mathematical models are reduced to solving differential equations, which are sufficient to solve numerically. The program provides a choice of one of the listed Runge-Kutta methods at the user's request. In addition, part of the program code is the code for creating a window with visualization of the trace of the exact solution and the difference solution of this Cauchy problem. Therefore, this work will also be useful for students involved in computational methods to better understand what is happening: what is the difference solution of the Cauchy problem, and what is the trace of the exact solution of the Cauchy problem; which of the listed Runge-Kutta methods is more accurate.
customer’s loyalty
nps
market research
market review
c++

Введение

Применение дифференциальных уравнений в математических моделях реальных процессов позволяет решать задачи в различных областях техники, науки, производства. Например, в ядерной физике – при изучении процессов радиоактивного распада веществ. Поэтому в силу компьютеризации очень полезно иметь программу, позволяющую численно решить ОДУ.

Цель исследования

Целью исследования является решение задачи Коши (1)

(1)

численными методами – методами Рунге-Кутты второго, третьего и четвёртого порядков аппроксимации.

Материал и методы исследования

Рассмотрим равномерную разностную сетку отрезка :

, где – заданное количество равных частей, на которые разбит отрезок , – шаг разбиения.

Пусть , . Тогда будут справедливы явные разностные методы Рунге-Кутты [1,2]:

явный двухэтапный метод Рунге-Кутты второго порядка аппроксимации:

явный трёхэтапный метод Рунге-Кутты третьего порядка аппроксимации:

явный четырёхэтапный метод Рунге-Кутты четвёртого порядка аппроксимации:

Будет продемонстрирована реализация на языке программирования C++ сформулированных выше методов Рунге-Кутты для решения задачи Коши (1) в случае, когда , а также будет рассмотрена визуализация следа точного решения и визуализация разностного решение задачи Коши (1) в одном окне. Однако эти данные можно несложно быстро поменять и решить задачу Коши (1) с другими данными .

Результаты исследования и их обсуждение

Программный код для решения задачи Коши

если мелкость разбиения :

#include <SFML/Graphics.hpp>

#include <cmath>

#include <iostream>

using namespace sf;

using namespace std;

//ширина окна для визуализации решения

const int W = 752;

//высота окна для визуализации решения

const int H = 802;

//следующие данные можно изменить, если необходимо решить другую задачу Коши (1)

const int N = 10;

const double a = 0;

const double b = 1;

const double y_0 = 1; //начальное условие u(0)=1

//объявление функции f(t,u)

double f(double t, double u) {

return t + u;

}

//обявление функции - точного решения задачи Коши (1)

double ExactSolution(double x) {

return 2 * exp(x) - x - 1;

}

int main() {

setlocale(LC_ALL, "Russian");

//tau - мелкость разбиения, T - массив значений равномерной разностной сетки, Y - массив значений разностного решения (1)

double tau = (b - a) / N;

double T[N + 1] = {};

for (int i = 1; i <= N; i++) T[i] = a + i * tau;

double Y[N + 1] = {};

Y[0] = y_0;

//z - условие проверки корректности введённых данных пользователем программы

double z = 0;

while (z == 0) {

cout << "Метод Рунге-Кутта какого порядка аппроксимации Вы хотите использовать для приближённого решения задачи Коши?" << endl << "Нажмите:" << endl << "2, если второго порядка аппроксимации;" << endl << "3, если третего порядка аппроксимации;" << endl << "4, если четвёртого порядка аппроксимации" << endl;

int p;

cin >> p;

if (p == 2)

for (int i = 0; i < N; i++) {

double k1 = f(T[i], Y[i]);

double k2 = f(T[i] + tau / 2, Y[i] + tau / 2 * k1);

Y[i + 1] = Y[i] + tau * k2;

z = 1;

}

else if (p == 3)

for (int i = 0; i < N; i++) {

double k1 = f(T[i], Y[i]);

double k2 = f(T[i] + tau / 2, Y[i] + tau / 2 * k1);

double k3 = f(T[i] + tau, Y[i] - tau * k1 + 2 * tau * k2);

Y[i + 1] = Y[i] + tau / 6 * (k1 + 4 * k2 + k3);

z = 1;

}

else if (p == 4)

for (int i = 0; i < N; i++) {

double k1 = f(T[i], Y[i]);

double k2 = f(T[i] + tau / 2, Y[i] + tau / 2 * k1);

double k3 = f(T[i] + tau / 2, Y[i] + tau / 2 * k2);

double k4 = f(T[i] + tau, Y[i] + tau * k3);

Y[i + 1] = Y[i] + tau / 6 * (k1 + 2 * k2 + 2 * k3 + k4);

z = 1;

}

else {

cout << "Такого варианта нет, повторите попытку" << endl;

}

}

//вывод разностного решения и следа точного решения (1)

cout << "t y_n (разностное решение) u_n (след точного решения)" <<endl;

for (int i = 0; i <= N; i++) cout << T[i] << " " << Y[i] <<" "<< ExactSolution(a+tau*i)<< endl;

//следующий фрагмент программы программы написан для визуализации разностного решения и следа точного решения (1), большая часть кода заимствована в [3]

RenderWindow window(VideoMode(W, H), "Exact (black line) and inexact (blue line) solutions of a differential equation");

//центр координатной плоскости

int x0 = W / 2;

int y0 = H / 2;

//ось ox

RectangleShape OsX(Vector2f(W, 1));

OsX.setFillColor(Color::Black);

OsX.setPosition(0, y0);

//ось oy

RectangleShape OsY(Vector2f(1, H));

OsY.setFillColor(Color::Black);

OsY.setPosition(x0, 0);

//стрелки на осях

RectangleShape strel[4];

for (int i = 0; i < 4; i++) {

strel[i].setSize(Vector2f(1, 25));

strel[i].setFillColor(Color::Black);

 

if (i < 2)

strel[i].setPosition(x0, 0);

else

strel[i].setPosition(W, y0);

}

strel[0].setRotation(25);

strel[1].setRotation(-25);

strel[2].setRotation(60);

strel[3].setRotation(-250);

//выполнение действий, когда открыто окно

while (window.isOpen())

{

Event event;

//закрытие окна - нажать на крестик

while (window.pollEvent(event))

{

if (event.type == Event::Closed)

window.close();

}

//вид окна: белый экран

window.clear(Color::White);

//изображение в окне стрелок

window.draw(OsX);

window.draw(OsY);

for (int i = 0; i < 4; i++)

window.draw(strel[i]);

//масштабирование графика по оси ox

int scalex = 100;

//масштабирование графика по оси oy

int scaley = 100;

//визуализация разностного решения задачи Коши (1)

//синие точки радиуса 2 для визуализации разностного решения (1)

CircleShape point1(2.f);

point1.setFillColor(Color::Blue);

for (int i = 0; i <= N; i++) {

float x = T[i];

float y = Y[i]; // наш график

//меняем ориентацию системы координат, т.к. по опциям окна она не является "стандартной"

float x1 = x0 + x * scalex;

float y1 = y0 - y * scaley;

//выводим на экран разностное решение задачи Коши(1)

point1.setPosition(x1, y1);

window.draw(point1);

}

//визуализация следа точного решения задачи Коши (1)

//чёрные точки радиуса 1 для визуализации следа точного решения (1)

CircleShape point2(1.f);

point2.setFillColor(Color::Black);

float c = 1000;

int mass = (b - a) * c + 1;

for (int i = 0; i < mass; i++) {

float x = a + i / c;

float y = ExactSolution(x);

float x1 = x0 + x * scalex;

float y1 = y0 - y * scaley;

point2.setPosition(x1, y1);

window.draw(point2);

}

window.display();

}

return 0;

}

В результате выполнения программы, если пользователь сначала ошибётся и на вопрос о выборе метода Рунге-Кутты нажмёт 0, а затем исправится и выберет третий порядок аппроксимации будет выведено два окна (рис. 1 и рис. 2).

Рис. 1.

Рис. 2.

Заключение

Таким образом, в работе продемонстрирована программа, реализованная на языке программирования C++ для решения задачи Коши (1). Данный результат можно использовать для сравнения точности методов Рунге-Кутты второго, третьего и четвёртого порядков аппроксимации опытным путём, а также применять в различных областях техники, науки, производства.