Обновил содержание вопроса,так как некоторые моменты я сам понял и исправил. И так есть следующие переменные:
hx (шаг по пространству)= 0.1
ht (шаг по времени) = 0.5
Nx (Количество шагов по пространству) = 10;
Nt (Количество шагов по времени) = 12;
wx[i] - массив содержит все шаги по пространству
wt[j] - массив содержит все шаги по времени
wht[j][i]-двумерный массив по которому будет строится результирующий график;
И так найдены несколько проблем:
1) Найдена в коде
for(int i = 0; i < Nx; i++)
{
wx[i+1] = wx[i] + hx; //массив
wht[0][i] = fn(T, i * hx); //i * hx//Исправлено.
}
где fn это:
//Функция Хэвисайда - Начальное условие(Граничное условие) а начальное 0-1
public:static double fn(int T, double x)
{
if (x >= 0)
return T;
else if(x < 0)
return 0;
}
Я неправильно задаю начальные условия
Как вино на графике, среди безобразия там где-то видно общее решение "волна", но остальное там неправильно как раз из за того что я в коде неправильно задаю начальные условия
2) Циклы и массивы, а именно:
Идёт обращение к несуществующему элементу массива и следовательно возникают страшные цифры и скачок графика, но я изменить индексы не могу так как есть определённая формула.
for(int j = 0;j<Nt;j++)
{
for(int i = 1;i<Nx-1;i++)///Исправлено с помощью ответа пользователя Denis Protopopov(и график немного изменился)
{
wht[j+1][i] =
((wht[j + 1][i] - wht[j][i]) / ht) + a * ((wht[j][i+1] - wht[j][i]) / hx);
wht[j+1][i] = -a * (ht * (wht[j][i+1] + wht[j][i]) / hx) + (wht[j][i]);
}
}
Если я напишу вместо i = 0, i = 2 или j = 2, то отрисовка графика будет ужасной.
Весь код:
public:static double qx0(double x)//ось пространства
{
if (x<=0)
return 0;
else
return x;
}
public:static double qt0(double t)//ось по времени
{
if (t<=0)
return 0;
else
return t;
}
public:static double fn(int T,double x)//Функция Хэвисайда - Начальное условие
{
if (x>=0)
return T;
else if(x<0)
return 0;
}
public: void drawfunc(double T)
{
double xmin = -5;
double xmax = 10;
for(double x = xmin;x<xmax;x+=0.01)
{
chart1->Series["Функция Хэвисайда"]->BorderWidth=3;
chart1->Series["Функция Хэвисайда"]->Points->AddXY(x,fn(T,x));
}
}
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
///-------Переменные для работы с разностными схемами
double a;//скорость переноса
double hx,ht;//шаги по пространству и времени
int Nx,Nt;//На сколько частей разбивае отрезок сетки
int T;//Входной параметр для искомой функции(Хэвисайд)
double wx[20]={0};//массив точек x
double wt[20]={0};//массив точек t
double wht[20][20]={0};// массив для разностной схемы(сетки)
//double res[20][20]={0};//результирующий массив
if(textBox1->Text!="" && textBox2->Text!="" && textBox3->Text!="" && textBox4->Text!="" && textBox5->Text!="" && textBox6->Text!="" && textBox6->Text!="")
{
///-----Ввод данных-----
a=Convert::ToDouble(textBox1->Text);
hx=Convert::ToDouble(textBox2->Text);
q=Convert::ToDouble(textBox3->Text);
ht=Convert::ToDouble(textBox4->Text);
Nx=Convert::ToInt32(textBox5->Text);
Nt=Convert::ToInt32(textBox6->Text);
T=Convert::ToInt32(textBox7->Text);
//----Построение сетки,узлов
for(int i = 0;i<Nx;i++)
{
wx[i+1]=wx[i]+hx;//массив
wht[0][i]=qx0(wx[i]);
}
for(int j = 0;j<Nt;j++) //
{
wt[j+1]=wt[j]+ht;
wht[j+1][0] = qt0(wt[j+1]);
}
///-----------------Вычисление основых формул с разностной схемой
for(int j = 0;j<Nt;j++)
{
for(int i = 1;i<Nx-1;i++)///Вывод формул wht[j+1][i]
{
wht[j+1][i]=((wht[j+1][i]-wht[j][i])/ht)+a*((wht[j][i+1]-wht[j][i])/hx);
wht[j+1][i]=-a*(ht*(wht[j][i+1] + wht[j][i])/hx) + (wht[j][i])+ht*fn(wt[j],hx);
}
}
//----Для записи в простой текстовый файл
String^ fileName = "results.txt";
StreamWriter^ sw = gcnew StreamWriter(fileName);
for(int j = 0;j<Nt;j++)
{
for(int i = 0 ;i<Nx;i++)
{
sw->Write("{0} ",wht[j][i]);
}
sw->WriteLine();
}
sw->Close();
//Тестовые функции для отображения
drawfunc(T);// Вызов функции для рисования
///---------------Построение графика
for(int j = 0;j<Nt;j++)
{
for(int i = 0;i<Nx-1;i++)
{
chart2->Series["Series2"]->BorderWidth=3;
chart2->Series["Series2"]->Points->AddXY(i,wht[j][i]);
}
}
}
else MessageBox::Show("Ошибка!Не все поля заполнены!");
}



Но проблема номер 1, мешает выводу графика и поэтому мне интересно узнать какие действия мне нужно сделать чтобы правильно задать начальные условия и работать с формулой.
Дело в том что я пытаюсь значение функции fn записать в массив где хранятся шаги по пространству,что в корне неправильно.
– beginner Feb 20 '17 at 19:10wht[j+1][i]перезаписывается вторым присваиванием. Во-вторых, второе присваивание эквивалентно соотношению(wht[j+1][i] - wht[j][i])/ht == -a * ( wht[j][i+1] + wht[j][i]) / hx. Это с точностью до O(hx) эквивалентноhx * du/dt = -2au- жесткое дифференциальное уравнение. Напомню, что уравнение переноса, этоdu/dt = -a*du/dx. Прежде, чем решать с разрывным начальным условием, убедитесь, что у вас гладкая функция - синус, побежит в нужную сторону с нужной скоростью. – Dima Chubarov Feb 23 '17 at 09:29Эквивалентно.
Дело в том что по заданию мне это сказали выразить аналитически(я это сделал,проверили и сказали аналитически правильно - программируйте) я и запрограммировал её.
С sin(x) такая же проблема(так же отображается)-сейчас проверил Плюс я 1-ое присваивание wht[j+1][i] убрал.
– beginner Feb 23 '17 at 09:57