ЛАБОРАТОРНА РОБОТА 2. ЧИСЕЛЬНЕ РОЗВ’ЯЗАННЯ РІВНЯННЯ КОЛИВАНЬ СТРУНИ МЕТОДОМ СІТОК
Студента ИТ 14-1 Красовского Абхая
Мета роботи – здобути практичні навички розроблення алгоритмів і програм чисельних методів розв’язання змішаної крайової задачі для ди- ференційного рівняння коливань струни методом сіток.
Вариант №11
Блок-схема метода сеток
Код:
#include <math.h>
#include <float.h>
#include <time.h>
double H, k, lamda, L, left, right, center, bottom;
int D_x, D_y, MaxTime, x, i, j, t;
double D[10000][10000];
using namespace System::Windows::Forms::DataVisualization::Charting;
//Гранична умова на лівому кінці
double p (double t)
{ return 0.4 * t; }
//Гранична умова на правому кінці
double q (double t) { return 0; }
//Початкова форма струни
double f (double x) { return (2 + x) * sin(M_PI * x); }
//Початкова швидкість
double g (double x) { return pow(x + 0.3, 2); }
//Заповнення нульового прошарку із умови 3 - U(x,0) = f (x)
void zero_level (int x) {
for (x = 0; x <= D_x; x++)
D[x][0] = f(x * H);
}
//Заповнення першого прошарку із умови 3 - U(x,1) = f(x) + k * g(x)
void first_level (int x) {
for (x = 0; x <=D_x; x++)
D[x][1] = f(x * H) + k * g(x * H);
}
//Заповнення лівої сторони із умови 1 - U(0,t) = p(t)
void left_side (int t) {
for (t = 0; t <= D_y; t++)
D[0][t] = p(t * k);
}
//Заповнення правої сторони із умови 2 - U(L,t) = q(t)
void right_side (int t){
for (t = 0; t <= D_y; t++)
D[D_x][t] = q(t * k);
}
// Обнуление массива D
void clearD (int i,int j) {
for (i = 0; i <= D_x; i++)
for (j = 0; j <= D_y; j++)
D[i][j] = 0;
}
//функція розрахунку масиву D
void all_levels (int t, int x, double left, double right, double center, double bottom) {
clearD(i,j);
zero_level(x);
left_side(t);
right_side(t);
first_level(x);
for (t = 1; t <= D_y; t++)
for (x = 1; x <= (D_x - 1); x++)
{
left = D[x-1][t-1]*(lamda*lamda);
right = D[x+1][t-1]*(lamda*lamda);
center = D[x][t-1]*2*(1-(lamda*lamda));
bottom = D[x][t-2]*(-1);
D[x][t] = left + right + center + bottom;
}
}
//функція побудови графіка коливання струни
void Build_Graph (int t)
{
int x;
Series^ plot1 = chart1->Series[0];
plot1->Points->Clear();
for (x = 0; x <= D_x; x++)
plot1->Points->AddXY(x*H,D[x][t]);
}
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
toolStripStatusLabel1->Text = "";
toolStripStatusLabel2->Text = "";
}
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
H = Convert::ToDouble(textBox3->Text);
k = Convert::ToDouble(textBox4->Text);
L = Convert::ToDouble(textBox1->Text);
MaxTime = Convert::ToInt32(textBox2->Text);
D_x = int(L / H);
D_y = int (MaxTime / k);
lamda = float(k) / float(H);
button2->Enabled = true;
}
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {
timer1->Enabled = true;
all_levels(t, x, left, right, center, bottom);
Build_Graph(x);
button1->Enabled = false;
}
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) {
timer1->Start();
timer1->Enabled = true;
if (int(clock()) / 10 <= D_y)
if (fabs((int(clock() / 10) * k) - int(int(clock() / 10) * k)) <0.000001) {
if (int(int(clock())*k) == 10) {
timer1->Enabled = false;
button1->Enabled = false; }
if (int(int(clock() / 10) * k) == 0) {
timer1->Enabled = false;
button1->Enabled = false; }
Build_Graph(int(clock() / 10));
toolStripStatusLabel1->Text = "Час - " + Convert::ToString(int(clock()/10*k)) + " сек ";
toolStripStatusLabel2->Text = " кількість ітерацій - " + Convert::ToString(int(clock() / 10));
} }
private: System::Void button3_Click_1(System::Object^ sender, System::EventArgs^ e) {
Application::Exit();
}
Результат: