МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ
„ЛЬВІВСЬКА ПОЛІТЕХНІКА”
ІКТА
Кафедра БІТ
Курсова робота
з курсу:
" Комп'ютерні методи дослідження інформаційних процесів і систем "
на тему:
" СИСТЕМА РЕГУЛЮВАННЯ НАПРУГИ ГЕНЕРАТОРА "
Тема 3, варіант 9
Львів- 2013
В даній роботі розглянено застосування модифікованого методу Ейлера та методу Рунге-Кутта-Фербельга для дослідження перехідного процесу автоматичного потенціометра з диференціюючим контуром. Розв’язок поставленої задачі представлений в середовищі С# і платформі Visual Studio 2010. Графіки уточнень побудовані в середовищі С#.
Зміст
1. Постановка задачі………………………………………………………………. 4
2. Перетворення рівнянь………………………………………………………….. 6
3. Теоретичні відомості……………………………………………………………. 7
3.1 Модифікований метод Ейлера……………………………………………...... 7
3.2 Метод Рунге-Кутта-Фербельга……………………………………………….. 9
4. Лістинг програм………………………………………………………………… 10
4.1 Модифікований метод Ейлера………………………………………………… 10
4.2 Метод Рунге-Кутта-Фербельга…..……………………………………………. 14
5. Результати виконання програми……………………………………………... 20
5.1 Модифікований метод Ейлера………………………………………………… 20
5.2 Метод Рунге-Кутта-Фербельга……………………………………………….. 54
6. Графік перехідного процесу…………………………………………………… 58
7. Список літератури………………………………………………………………. 59
1. Постановка задачі
Схема:
Рівняння ланок :
вимірювальна схема
обмотка збудження ЕМП (електромашинного підсилювача)
короткозамкнута обмотка ЕМП
обмотка збудження генератора
При початкових параметрах
Параметри
T1. (сек)
Tk (сек)
T2 (сек)
KI
KП
KШ
Звести систему алгебро-диференціальних рівнянь до системи трьох диференціальних рівнянь першого порядку, представити її у нормальній формі та розв’язати цю систему вказаними методами. Початкові умови - =1 В, решта початкових умов – нульові. Числові значення сталих параметрів, заданих в таблиці, слід зобразити з допомогою одиниць системи СІ.
Побудувати графік зміни величини
2. Перетворення рівнянь
1)вимірювальна схема
U1=E—U
Ця напруга подається на обмотку збудження ЕМП
2) Обмотка збудження ЕМП
T1 · +Uk=KIU1
3) Короткозамкнута обмотка ЕМП
Tк + U2 = KIIUk
4) Обмотка збудження генератора з незалежним збудженням
T2 +U = KIIIU2
= =
= =
= =
y1(0)=0
y2(0)=0
y3(0)=0
E=1
3. Теоретичні відомості
3.1 Модифікований метод Ейлера
для розв’язку систем диференціальних рівнянь
Метод Ейлера є найпростішим методом розв’язування задачі Коші. Він дозволяє інтегрувати ДР першого порядку виду.
(4)
Метод Ейлера базується на розкладі функції в ряд Тейлора в околі точки
(5)
Якщо мале, то, знехтувавши членам розкладу, що містять в собі і т.д. отримаємо
(6)
Похідну знаходимо з рівняння (4), підставивши в нього початкову умову. Таким чином можна знайти наближене значення залежної змінної при малому зміщенні від початкової точки. Цей процес можна продовжувати, використовуючи співвідношення.
,
роблячи як завгодно багато кроків.
Похибка методу має порядок , оскільки відкинуті члени, що містять в другій і вище степенях.
Недолік методу Ейлера - нагромадження похибок, а також збільшення об’ємів обчислень при виборі малого кроку з метою забезпечення заданої точності.
В методі Ейлера на всьому інтервалі тангенс кута нахилу дотичної приймається незмінним і рівним . Очевидно, що це призводить до похибки, оскільки кути нахилу дотичної в точках та різні. Точність методу можна підвищити, якщо покращити апроксимацію похідної.
Модифікований метод Ейлера з перерахунком
Обчислення за методом Ейлера з перерахунком робляться в два етапи.
Прогноз:
.
Корекція:
.
Модифікований метод Ейлера з перерахунком має другий порядок точності, проте для його реалізації необхідно двічі обчислювати праву частину функції. Зауважимо, що метод Ейлера з перерахунком являє собою різновид методів Рунге-Кутта (предиктор-коректор).
Метод Ейлера з автоматичною зміною кроку
Після обчислення з кроком всі обчислення виконуються повторно з кроком . Після цього порівнюються результати, отримані в точці хn+1 з кроком і . Якщо модуль різниці менший , то обчислення продовжуються з кроком , в іншому випадку крок зменшують. Якщо нерівність дуже сильна, то крок збільшують.
- значення функції в точці
- значення функції в точці , обчислене з кроком
- значення функції в точці , обчислене з кроком
- значення функції , обчислене з кроком
1) Якщо
То,
обчислення повторюються доки не виконається умова .
2) Якщо виконується ця умова, то можливі два варіанти, в залежності від значення K, де K – ознака поділу кроку.
Початкове значенняі залишається таким після першого поділу кроку на два. Надалі, якщо крок ділиться, то K приймає значення одиниці.
а) Якщо , то навіть коли виконалась умова , крок не змінюється, тобто лишається тим самим (обчислення далі проводяться з попереднім кроком).
б) Якщо і виконалась умова , тоді .
В обох випадках а) і б) результат виводиться на друк.
Для розв’язку системи диференціальних рівнянь використовують цей самий метод, за виключенням того, що всі рівняння системи необхідно розв’язувати паралельно.
3.2 Метод Рунге-Кутта-Фельберга з автоматичною зміною кроку
Це метод четвертого порядку, дає більш точну оцінку похибки (порівняно з методом Рунге-Кутта-Мерсона) на кожному кроці і реалізується послідовним циклічним обчисленням за наступними формулами:
Похибка
Якщо
а) , крок зменшується в двічі
б) Якщо , крок збільшується вдвічі.
Час розрахунку для однієї точки удвічі більший, ніж для методу Рунге-Кутта-Мерсона.
4. Лістинг програм
4.1 Модифікований метод Ейлера
using System;
using System.IO;
class Data
{
double d;
double T1;
double Tk;
double T2;
double K_1;
double K_2;
double K_3;
double E;
double a;
double b;
double dt;
int k;
int Kr;
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 z1;
double z2;
double z3;
double z4;
double z5;
double z6;
public Data()
{
dt = 0.0001;
e = 0.00001;
a = 0;
b = 3.0;
t[0] = a;
T1 = 0.005;
Tk = 0.02;
T2 = 0.4;
K_1 = 8.0;
K_2 = 3.0;
K_3 = 3.0;
E = 1.0;
}
public double F1(double t, double y1, double y2, double y3)
{
return (K_1 * (E - y3) - y1) / T1;
}
public double F2(double t, double y1, double y2, double y3)
{
return (K_2 * y1 - y2) / Tk;
}
public double F3(double t, double y1, double y2, double y3)
{
return (K_3 * y2 - y3) / T2;
}
public void Pohidni(double x, double y1, double y2, double y3)
{
Y[0, k] = F1(x, y1, y2, y3);
Y[1, k] = F2(x, y1, y2, y3);
Y[2, k] = F3(x, y1, y2, y3);
}
public void Znach(double x, double y1, double y2, double y3)
{
y[0, k + 1] = y[0, k] + dt * F1(x + dt / 2.0, y1, y2, y3);
y[1, k + 1] = y[1, k] + dt * F2(x + dt / 2.0, y1, y2, y3);
y[2, k + 1] = y[2, k] + dt * F3(x + dt / 2.0, y1, y2, y3);
}
public void Mod(double x, double y1, double y2, double y3)
{
Kr = 0;
Znach(x, y1, y2, y3);
z1 = y[0, k + 1];
z2 = y[1, k + 1];
z3 = y[2, k + 1];
z4 = y[0, k] + dt * (F1(x, y1, y2, y3) + F1(x + dt, z1, z2, z3)) / 2.0;
z5 = y[1, k] + dt * (F2(x, y1, y2, y3) + F2(x + dt, z1, z2, z3)) / 2.0;
z6 = y[2, k] + dt * (F3(x, y1, y2, y3) + F3(x + dt, z1, z2, z3)) / 2.0;
while (Math.Abs(z1 - z4) > e)
{
z1 = z4;
z2 = z5;
z3 = z6;
z4 = y[0, k] + dt * (F1(x, y1, y2, y3) + F1(x + dt, z1, z2, z3)) / 2.0;
z5 = y[1, k] + dt * (F2(x, y1, y2, y3) + F2(x + dt, z1, z2, z3)) / 2.0;
z6 = y[2, k] + dt * (F3(x, y1, y2, y3) + F3(x + dt, z1, z2, z3)) / 2.0;
if (Kr % 4 == 0)
dt = dt / 2.0;
Kr++;
}
y[0, k + 1] = z4;
y[1, k + 1] = z5;
y[2, k + 1] = z6;
}
public void Prod()
{
do
{
Mod(t[k], y[0, k], y[1, k], y[2, k]);
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, 50))
{
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 += 60)
{
Console.WriteLine("{0:0.####}\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 d;
double T1;
double Tk;
double T2;
double K_1;
double K_2;
double K_3;
double E;
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;
public Data()
{
dt = 0.0001;
e = 0.00001;
a = 0;
b = 3.0;
t[0] = a;
T1 = 0.005;
Tk = 0.02;
T2 = 0.4;
K_1 = 8.0;
K_2 = 3.0;
K_3 = 3.0;
E = 1.0;
}
public double F1(double t, double y1, double y2, double y3)
{
return (K_1 * (E - y3) - y1) / T1;
}
public double F2(double t, double y1, double y2, double y3)
{
return (K_2 * y1 - y2) / Tk;
}
public double F3(double t, double y1, double y2, double y3)
{
return (K_3 * y2 - y3) / T2;
}
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] * 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;
l[5] = F3(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;
}
public void Zminna(double x, double h)
{
K0(x, h);
K1(x, h);
K2(x, h);
K3(x, h);
K4(x, h);
K5(x, h);
Zmin();
}
public void Provirka()
{
do
{
Zminna(t[k], dt);
d = l[0] / 150.0 - l[2] * 3.0 / 100.0 + l[3] * 16.0 / 75.0 + l[4] / 20.0 - l[5] * 6.0 / 25.0;
if (Math.Abs(d) > e)
dt = dt / 2.0;
if (Math.Abs(d) < e / 30.0)
dt = 2.0 * dt;
} while (Math.Abs(d) > e || Math.Abs(d) < e / 30.0);
}
public void Prod()
{
do
{
Pohidni();
Zminna(t[k], dt);
t[k + 1] = t[k] + dt;
k++;
} while (t[k] < b);
Pohidni();
}
public void vuvid()
{
int j;
Random rand = new Random();
StreamWriter log_out;