МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ
„ЛЬВІВСЬКА ПОЛІТЕХНІКА”
ІКТА
Кафедра БІТ
Курсова робота
з курсу:
" Комп'ютерні методи дослідження інформаційних процесів і систем "
на тему:
" СЛІДКУЮЧА СИСТЕМА ЛІТАКОВОГО ВИТРАТОМІРА "
Тема 6, варіант 10
В даній роботі розглянено застосування методу Рунге-Кутта-Мерсона та Рунге-Кутта-Фербельга для дослідження перехідного процесу автоматичного потенціометра з диференціюючим контуром. Розв’язок поставленої задачі представлений в середовищі С# і платформі Visual Studio 2010. Графіки уточнень побудовані в середовищі С#.
Зміст
1. Постановка задачі……………………………………………………………….. 4
2. Перетворення рівнянь………………………………………………………….. 6
3. Теоретичні відомості……………………………………………………………. 8
3.1 Метод Рунге-Кутта-Мерсона……………………………………………….….. 8
3.2 Метод Рунге-Кутта-Фербельга…………………………...…………………… 9
4. Лістинг програм………………………………………………………………… 10
4.1 Метод Рунге-Кутта-Мерсона………………………….………………………. 10
4.2 Метод Рунге-Кутта-Фербельга….……………………………………………. 15
5. Результати виконання програми……………………………………………... 21
5.1 Метод Рунге-Кутта-Мерсона……………………………...…………………… 21
5.2 Метод Рунге-Кутта-Фербельга……...………………………………………… 23
6. Графік перехідного процесу…………………………………………………… 25
7. Список літератури………………………………………………………………. 26
1. Постановка задачі
Схема:
Рівняння ланок :
вимірювальна схема
електронний підсилювач
двигун
редуктор
При початкових параметрах
Параметри
10
TМ. (сек)
0.2
TЕ (сек)
0.05
С (рад/в.сек)
1
KУ
10
S (рад/в.сек)
10
i
10
Звести систему алгебро-диференціальних рівнянь до системи трьох диференціальних рівнянь першого порядку, представити її у нормальній формі та розв’язати цю систему вказаними методами. Початкові умови - =1 радіан, решта початкових умов – нульові. Числові значення сталих параметрів, заданих в таблиці, виразити з допомогою одиниць системи СІ.
Побудувати графік зміни величини
2. Перетворення рівнянь
= ( - )
=i ; =
Щоб звести друге рівняння системи до системи рівнянь першого порядку, введемо змінну y = .
Таблиця ідентифікаторів
– Y[1]; y – Y[2];
= F[1]; = F[2]; = F[3];
C – C; S – S; - KU; - TM; - II; - TE;
Праві частини рівнянь системи запишемо у наступному вигляді
F[1]:= Y[2];
F[2]:=(C*S*KU*(1-Y[3])-Y[1] – YM*Y[2])/(TM*TE);
F[3]:= Y[1]/II;
3. Теоретичні відомості
3.1 Метод Рунге-Кутта-Мерсона з автоматичною зміною кроку
Метод дозволяє оцінити похибку на кожному кроці інтегрування. При цьому не потрібно зберігати в пам’яті обчислення значень функцій на кроці і для оцінки похибки.
Алгоритм методу
1. Задаємо число рівнянь , похибку , початковий крок інтегрування , початкові умови .
2. За допомогою п’яти циклів з керуючою змінною обчислюємо коефіцієнти
3. Знаходимо значення
та похибку
4. Перевіряємо виконання умов
Можливі випадки:
а) Якщо перша умова не виконується, тобто , то ділимо крок на 2 та повторюємо обчислення з п.2, встановивши початкові значення .
б) Якщо виконується перша та друга умови, значення та виводяться на друк.
Якщо друга умова не виконується, крок збільшується вдвічі і тоді обчислення знову повторюється з п.2.
Треба відмітити, що похибка на кожному кроці методу Рунге-Кутта-Мерсона оцінюється приблизно. При розв’язуванні нелінійних ДР істинна похибка може відрізнятися в декілька разів від заданої .
, де .
- крок поділити на 2 і повернутися на початок.
для всіх рівнянь: виводимо на друк , а крок збільшуємо удвічі.
3.2 Метод Рунге-Кутта-Фельберга з автоматичною зміною кроку
Це метод четвертого порядку, дає більш точну оцінку похибки (порівняно з методом Рунге-Кутта-Мерсона) на кожному кроці і реалізується послідовним циклічним обчисленням за наступними формулами:
Похибка
Якщо
а) , крок зменшується в двічі
б) Якщо , крок збільшується вдвічі.
Час розрахунку для однієї точки удвічі більший, ніж для методу Рунге-Кутта-Мерсона.
4. Лістинг програм
4.1 Метод Рунге-Кутта-Мерсона
using System;
using System.IO;
class Data
{
double C;
double S;
double Kp;
double Tm;
double I;
double Te;
double Qin;
double a;
double b;
double dt;
int k;
double[,] y = new double[3, 10000000];
double[,] Y = new double[3, 10000000];
double[] t = new double[10000000];
double[] p = new double[10000000];
double[] m = new double[6];
double[] l = new double[6];
double[] n = new double[6];
double z1;
double z2;
double z0;
double e;
public Data()
{
dt = 0.001;
e = 0.0001;
a = 0;
b = 5.0;
t[0] = a;
Kp = 1.3;
Qin = 1.0;
Tm = 0.2;
Te = 0.05;
C = 2;
S = 10.0;
I = 10.0;
}
public double F2(double t, double y1, double y2, double y3)
{
return (C * S * Kp * (Qin - y3) - y1 - Tm * y2) / (Tm * Te);
}
public double F1(double t, double y1, double y2, double y3)
{
return y2;
}
public double F3(double t, double y1, double y2, double y3)
{
return y1 / I;
}
public void Pohidni(double t, double y1, double y2, double y3)
{
Y[0, k] = F1(t, y1, y2, y3);
Y[1, k] = F2(t, y1, y2, y3);
Y[2, k] = F3(t, y1, y2, y3);
}
public void Zmin()
{
y[0, k + 1] = y[0, k] + (m[0] + 4.0 * m[3] + m[4]) / 6.0;
y[1, k + 1] = y[1, k] + (n[0] + 4.0 * n[3] + n[4]) / 6.0;
y[2, k + 1] = y[2, k] + (l[0] + 4.0 * l[3] + l[4]) / 6.0;
}
public void Kof(double t, double y1, double y2, double y3, double h)
{
m[0] = F1(t, y1, y2, y3) * h;
n[0] = F2(t, y1, y2, y3) * h;
l[0] = F3(t, y1, y2, y3) * h;
m[1] = F1(t + h / 3.0, y1 + m[0] / 3.0, y2 + n[0] / 3.0, y3 + l[0] / 3.0) * h;
n[1] = F2(t + h / 3.0, y1 + m[0] / 3.0, y2 + n[0] / 3.0, y3 + l[0] / 3.0) * h;
l[1] = F3(t + h / 3.0, y1 + m[0] / 3.0, y2 + n[0] / 3.0, y3 + l[0] / 3.0) * h;
m[2] = F1(t + h / 3.0, y1 + m[1] / 6.0 + m[0] / 6.0, y2 + n[1] / 6.0 + n[0] / 6.0, y3 + l[1] / 6.0 + l[0] / 6.0) * h;
n[2] = F2(t + h / 3.0, y1 + m[1] / 6.0 + m[0] / 6.0, y2 + n[1] / 6.0 + n[0] / 6.0, y3 + l[1] / 6.0 + l[0] / 6.0) * h;
l[2] = F3(t + h / 3.0, y1 + m[1] / 6.0 + m[0] / 6.0, y2 + n[1] / 6.0 + n[0] / 6.0, y3 + l[1] / 6.0 + l[0] / 6.0) * h;
m[3] = F1(t + h / 2.0, y1 + 3.0 * m[2] / 8.0 + m[0] / 8.0, y2 + 3.0 * n[2] / 8.0 + n[0] / 8.0, y3 + 3.0 * l[2] / 8.0 + l[0] / 8.0) * h;
n[3] = F2(t + h / 2.0, y1 + 3.0 * m[2] / 8.0 + m[0] / 8.0, y2 + 3.0 * n[2] / 8.0 + n[0] / 8.0, y3 + 3.0 * l[2] / 8.0 + l[0] / 8.0) * h;
l[3] = F3(t + h / 2.0, y1 + 3.0 * m[2] / 8.0 + m[0] / 8.0, y2 + 3.0 * n[2] / 8.0 + n[0] / 8.0, y3 + 3.0 * l[2] / 8.0 + l[0] / 8.0) * h;
m[4] = F1(t + h, y1 + m[0] / 2.0 - 3.0 * m[2] / 2.0 + 2.0 * m[3], y2 + n[0] / 2.0 - 3.0 * n[2] / 2.0 + 2.0 * n[3], y3 + l[0] / 2.0 - 3.0 * l[2] / 2.0 + 2.0 * l[3]) * h;
n[4] = F2(t + h, y1 + m[0] / 2.0 - 3.0 * m[2] / 2.0 + 2.0 * m[3], y2 + n[0] / 2.0 - 3.0 * n[2] / 2.0 + 2.0 * n[3], y3 + l[0] / 2.0 - 3.0 * l[2] / 2.0 + 2.0 * l[3]) * h;
l[4] = F3(t + h, y1 + m[0] / 2.0 - 3.0 * m[2] / 2.0 + 2.0 * m[3], y2 + n[0] / 2.0 - 3.0 * n[2] / 2.0 + 2.0 * n[3], y3 + l[0] / 2.0 - 3.0 * l[2] / 2.0 + 2.0 * l[3]) * h;
}
public void Zminna(double t, double y1, double y2, double y3, double h)
{
Kof(t, y1, y2, y3, h);
Zmin();
}
public void Perevirka(double t, double y1, double y2, double y3, double h)
{
A1: Zminna(t, y1, y2, y3, dt);
z0 = y[2, k + 1];
z1 = y[2, k] + (l[0] - 3.0 * l[2] + 4.0 * l[3]) / 2.0;
z2 = Math.Abs(z0 - z1) / 2.0;
if (z1 > e)
{
dt = dt / 2.0;
goto A1;
}
if (z1 < e / 30.0)
{
dt = dt * 2.0;
goto A1;
}
y[2, k + 1] = z0;
}
public void Prod()
{
k = 1;
do
{
Pohidni(t[k], y[0, k], y[1, k], y[2, k]);
Zminna(t[k], y[0, k], y[1, k], y[2, k], dt);
t[k + 1] = t[k] + dt;
k++;
} while (t[k] < b);
Pohidni(t[k], y[0, k], y[1, k], y[2, k]);
}
public void vuvid()
{
int j;
Random rand = new Random();
StreamWriter log_out;
log_out = new StreamWriter("logfile.txt");
Console.SetOut(log_out);
Console.WriteLine("t\ty1'");
for (j = 0; j < k; j += rand.Next(1, 40))
{
Console.WriteLine("{0:0.####}\t\t{1:0.####}", t[j], y[2, j]);
}
log_out.Close();
}
public void vuv()
{
Console.WriteLine("t\ty1\ty1'");
for (int j = 0; j < k; j += 30)
{
Console.WriteLine("{0:0.######}\t\t\t{1:0.#####}", t[j], y[2, j]);
}
}
}
class Program
{
static void Main(string[] args)
{
Data d = new Data();
d.Prod();
d.vuv();
d.vuvid();
Console.ReadLine();
}
}
4.2 Метод Рунге-Кутта-Фербельга
using System;
using System.IO;
class Data
{
double C;
double S;
double Kp;
double Tm;
double I;
double Te;
double Qin;
double a;
double b;
double dt;
int k;
double[,] y = new double[3, 10000000];
double[,] Y = new double[3, 10000000];
double[] t = new double[10000000];
double[] p = new double[10000000];
double[] m = new double[6];
double[] l = new double[6];
double[] n = new double[6];
double e;
double d;
public Data()
{
dt = 0.001;
e = 0.0001;
a = 0;
b = 5.0;
t[0] = a;
Kp = 1.3;
Qin = 1.0;
Tm = 0.2;
Te = 0.05;
C = 2;
S = 10.0;
I = 10.0;
}
public double F2(double t, double y1, double y2, double y3)
{
return (C * S * Kp * (Qin - y3) - y1 - Tm * y2) / (Tm * Te);
}
public double F1(double t, double y1, double y2, double y3)
{
return y2;
}
public double F3(double t, double y1, double y2, double y3)
{
return y1 / I;
}
public void Pohidni()
{
Y[0, k] = F1(t[k], y[0, k], y[1, k], y[2, k]);
Y[1, k] = F2(t[k], y[0, k], y[1, k], y[2, k]);
Y[2, k] = F3(t[k], y[0, k], y[1, k], y[2, k]);
}
public void Zmin()
{
y[0, k + 1] = y[0, k] + m[0] / 9.0 + m[2] * 9.0 / 20.0 + m[3] * 16.0 / 45.0 + m[4] / 12.0;
y[1, k + 1] = y[1, k] + n[0] / 9.0 + n[2] * 9.0 / 20.0 + n[3] * 16.0 / 45.0 + n[4] / 12.0;
y[2, k + 1] = y[2, k] + l[0] / 9.0 + l[2] * 9.0 / 20.0 + l[3] * 16.0 / 45.0 + l[4] / 12.0;
}
public void K0(double x, double h)
{
m[0] = F1(x, y[0, k], y[1, k], y[2, k]) * h;
n[0] = F2(x, y[0, k], y[1, k], y[2, k]) * h;
l[0] = F3(x, y[0, k], y[1, k], y[2, k]) * h;
}
public void K1(double x, double h)
{
m[1] = F1(x + h * 2.0 / 9.0, y[0, k] + m[0] * 2.0 / 9.0, y[1, k] + n[0] * 2.0 / 9.0, y[2, k] + l[0] * 2.0 / 9.0) * h;
n[1] = F2(x + h * 2.0 / 9.0, y[0, k] + m[0] * 2.0 / 9.0, y[1, k] + n[0] * 2.0 / 9.0, y[2, k] + l[0] * 2.0 / 9.0) * h;
l[1] = F3(x + h * 2.0 / 9.0, y[0, k] + m[0] * 2.0 / 9.0, y[1, k] + n[0] * 2.0 / 9.0, y[2, k] + l[0] * 2.0 / 9.0) * h;
}
public void K2(double x, double h)
{
m[2] = F1(x + h / 3.0, y[0, k] + m[0] / 12.0 + m[1] / 4.0, y[1, k] + n[0] / 12.0 + n[1] / 4.0, y[2, k] + l[0] / 12.0 + l[1] / 4.0) * h;
n[2] = F2(x + h / 3.0, y[0, k] + m[0] / 12.0 + m[1] / 4.0, y[1, k] + n[0] / 12.0 + n[1] / 4.0, y[2, k] + l[0] / 12.0 + l[1] / 4.0) * h;
l[2] = F3(x + h / 3.0, y[0, k] + m[0] / 12.0 + m[1] / 4.0, y[1, k] + n[0] / 12.0 + n[1] / 4.0, y[2, k] + l[0] / 12.0 + l[1] / 4.0) * h;
}
public void K3(double x, double h)
{
m[3] = F1(x + h * 3.0 / 4.0, y[0, k] + m[0] * 69.0 / 128.0 - m[1] * 143.0 / 128.0 + m[2] * 135.0 / 64.0, y[1, k] + n[0] * 69.0 / 128.0 - n[1] * 143.0 / 128.0 + n[2] * 135.0 / 64.0, y[2, k] + l[0] * 69.0 / 128.0 - l[1] * 143.0 / 128.0 + l[2] * 135.0 / 64.0) * h;
n[3] = F2(x + h * 3.0 / 4.0, y[0, k] + m[0] * 69.0 / 128.0 - m[1] * 143.0 / 128.0 + m[2] * 135.0 / 64.0, y[1, k] + n[0] * 69.0 / 128.0 - n[1] * 143.0 / 128.0 + n[2] * 135.0 / 64.0, y[2, k] + l[0] * 69.0 / 128.0 - l[1] * 143.0 / 128.0 + l[2] * 135.0 / 64.0) * h;
l[3] = F3(x + h * 3.0 / 4.0, y[0, k] + m[0] * 69.0 / 128.0 - m[1] * 143.0 / 128.0 + m[2] * 135.0 / 64.0, y[1, k] + n[0] * 69.0 / 128.0 - n[1] * 143.0 / 128.0 + n[2] * 135.0 / 64.0, y[2, k] + l[0] * 69.0 / 128.0 - l[1] * 143.0 / 128.0 + l[2] * 135.0 / 64.0) * h;
}
public void K4(double x, double h)
{
m[4] = F1(x + h, y[0, k] + m[0] * 17.0 / 12.0 + m[1] * 27.0 / 4.0 - m[2] * 27.0 / 5.0 + m[3] * 16.0 / 15.0, y[1, k] + n[0] * 17.0 / 12.0 + n[1] * 27.0 / 4.0 - n[2] * 27.0 / 5.0 + n[3] * 16.0 / 15.0, y[2, k] + l[0] * 17.0 / 12.0 + l[1] * 27.0 / 4.0 - l[2] * 27.0 / 5.0 + l[3] * 16.0 / 15.0) * h;
n[4] = F2(x + h, y[0, k] + m[0] * 17.0 / 12.0 + m[1] * 27.0 / 4.0 - m[2] * 27.0 / 5.0 + m[3] * 16.0 / 15.0, y[1, k] + n[0] * 17.0 / 12.0 + n[1] * 27.0 / 4.0 - n[2] * 27.0 / 5.0 + n[3] * 16.0 / 15.0, y[2, k] + l[0] * 17.0 / 12.0 + l[1] * 27.0 / 4.0 - l[2] * 27.0 / 5.0 + l[3] * 16.0 / 15.0) * h;
l[4] = F3(x + h, y[0, k] + m[0] * 17.0 / 12.0 + m[1] * 27.0 / 4.0 - m[2] * 27.0 / 5.0 + m[3] * 16.0 / 15.0, y[1, k] + n[0] * 17.0 / 12.0 + n[1] * 27.0 / 4.0 - n[2] * 27.0 / 5.0 + n[3] * 16.0 / 15.0, y[2, k] + l[0] * 17.0 / 12.0 + l[1] * 27.0 / 4.0 - l[2] * 27.0 / 5.0 + l[3] * 16.0 / 15.0) * h;
}
public void K5(double x, double h)
{
m[5] = F1(x + h * 5.0 / 6.0, y[0, k] + m[0] * 65.0 / 432.0 - m[1] * 5.0 / 16.0 + m[2] * 13.0 / 16.0 + m[3] * 4.0 / 27.0 + m[4] * 5.0 / 144.0, y[1, k] + n[0] * 65.0 / 432.0 - n[1] * 5.0 / 16.0 + n[2] * 13.0 / 16.0 + n[3] * 4.0 / 27.0 + n[4] * 5.0 / 144.0, y[2, k] + l[0] * 65.0 / 432.0 - l[1] * 5.0 / 16.0 + l[2] * 13.0 / 16.0 + l[3] * 4.0 / 27.0 + l[4] * 5.0 / 144.0) * h;
n[5] = F2(x + h * 5.0 / 6.0, y[0, k] + m[0] * 65.0 / 432.0 - m[1] * 5.0 / 16.0 + m[2] * 13.0 / 16.0 + m[3] * 4.0 / 27.0 + m[4] * 5.0 / 144.0, y[1, k] + n[0] * 65.0 / 432.0 - n[1] * 5.0 / 16.0 + n[2] * 13.0 / 16.0 + n[3] * 4.0 / 27.0 + n[4] *