Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
MatMatRix
1 / 1 / 0
Регистрация: 13.03.2013
Сообщений: 24
#1

Странная работа прогонки - C++

29.10.2013, 22:55. Просмотров 462. Ответов 0
Метки нет (Все метки)

Добрый вечер. Уже целую неделю бьюсь над программой, которая должна решать одномерное уравнение теплопроводности. Задача поставлена так:

Ut = Uxx + f(x,t), 0<x<1, 0<t<2
Ux(0,t)=mu1(t), 0<t<2
U(1,t)=mu2(t), 0<t<2
U(x,0)=fi(x), 0<x<1

Я написала программу для решения данной задачи с помощью неявной схемы и схемы Кранка-Николсона (то есть когда параметр "сигма" есть единица или одна вторая соответственно), но проблема в том, что погрешности при одних и тех же шагах по времени и координатам получаются одинаковые. В чём моя ошибка, понять не могу.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <iostream>
#include <math.h>
#include <fstream>
#include <iomanip>
using namespace std;
 
//f(x,t)
double fin(double x, double t){
    return -(6.0+cos(4.0*x)+16.0*t*cos(4.0*x));
}
 
//mu1(t)
double muleft(double t){
    return 0.0;
}
 
//mu2(t)
double muright(double t){
    return 6.0-t*cos(4.0);
}
 
//u(x,0)
double ubegin(double x){
    return 3.0*x*x+3.0;
}
 
//Истинное решение.
double ureal(double x, double t){
    return 3.0*x*x+3.0-t*cos(4.0*x);
}
 
//s=tau/h*h - число Куранта.
int main(){
 
    const int Nh=100; const double h=1.0/double(Nh); const double s=10.0; const double tau=s*h*h; const double sigma=0.5; const int Tp=2.0/tau;
    double u1[Nh+2],u0[Nh+2],F[Nh+2],G[Nh+2],a[Nh+2],b[Nh+2],c[Nh+2],d[Nh+2],epsilon;
    ofstream res;
 
    //Нулевой слой.
    for(int i=0;i<=Nh;i++){
        double ku = double(i)*h;
 
        u0[i]=ubegin(ku);
    }
 
    cout<<endl;
 
    for(int j=1;j<=Tp;j++){
        double tu = double(j)*tau;
 
        //Прогонка начинается. Здесь a[i]u1[i-1]+b[i]u1[i]+c[i]u1[i+1]=d[i], u1[i-1]=u1[i]*F[i]+G[i].
 
        for(int k=1;k<Nh;k++){
            double ku = double(k)*h;
 
            a[k]=s*sigma;
            b[k]=-1.0-2.0*sigma*s;
            c[k]=s*sigma;
            d[k]=(u0[k-1]+u0[k+1])*s*(sigma-1.0)+u0[k]*(-1.0+2.0*s*(1.0-sigma))-tau*(sigma*fin(ku,tu)+(1.0-sigma)*fin(ku,tu-tau));  
        }
 
        //Из аппроксимации левого граничного условия следует:
        F[0]=2.0*s/(1.0+2.0*s);
        G[0]=(-2.0*s*h*muleft(tu)+u0[0]+h*h*s*fin(0.0,tu))/(2.0*s+1.0);
 
        //Искусственным образом я коэффициенты a[1] и c[n-1] обнуляю, подставляя нужные формулы для аппроксимации граничных условий, которые точно верные.
 
        d[1]-=a[1]*G[0];
        b[1]+=a[1]*F[0];
        a[1]=0.0;
 
        u1[Nh]=muright(tu);
        d[Nh-1]-=c[Nh-1]*u1[Nh];
        c[Nh-1]=0.0;
 
        for(int k=1;k<Nh;k++){
            F[k]=-c[k]/(a[k]*F[k-1]+b[k]);
            G[k]=(d[k]-a[k]*G[k-1])/(a[k]*F[k-1]+b[k]);
        }
 
        for(int l=Nh-1;l>0;l--){
            u1[l]=u1[l+1]*F[l]+G[l];
        }
 
        u1[0]=u1[1]*F[0]+G[0];
        //u1[0]=u1[1]*2.0*s/(1.0+2.0*s)+(-2.0*s*h*muleft(tu)+u0[0]+h*h*s*fin(0.0,tu))/(2.0*s+1.0);
 
        //Вывод информации о слое на времени t=2.0 и максимальной погрешности.
 
        if(j==Tp){
            epsilon=0.0;
 
            for(int s=0;s<=Nh;s++){
                double neu;
 
                neu=abs(u1[s]-ureal(double(s)*h,double(Tp)*tau));
                if(neu>epsilon) epsilon=neu;
            }
 
            res.open("C:\\Heat equation (Sigma-weight=0.5_h=100)_not mine.txt",ios::out);
            res<<"x  U0(x,t)  U1(x,t)"<<endl;
            res<<endl;
 
            for(int s=0;s<=Nh;s++){
                res<<setprecision(10)<<fixed<<h*s;
                res<<"  ";
 
                res<<setprecision(10)<<fixed<<ureal(double(s)*h,Tp*tau);
                res<<"  ";
 
                res<<setprecision(10)<<fixed<<u1[s];
                res<<endl;
            }
 
            res<<endl;
            res<<Nh<<" "<<h<<" "<<s<<" "<<tau<<" "<<Tp<<endl;
            res<<"time=";
            res<<setprecision(10)<<fixed<<Tp*tau;
            res<<", epsilon=";
            res<<setprecision(10)<<fixed<<epsilon;
    
            res.close();
        }
 
        for(int k=0;k<=Nh;k++){
            u0[k]=u1[k];
        }
    }
 
    cout<<"This is the end!"<<endl;
    return 0;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.10.2013, 22:55     Странная работа прогонки
Посмотрите здесь:

Странная работа getch - C++
#include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; int main() { int m; m=getch(); switch (m)

Странная(или не странная, незнаю) реакция на буквы, знаки операций - C++
Всем добрый день. Делаю маленькую наработку, пока есть только начало. Ниже код: #include &lt;iostream&gt; #include &lt;cstdlib&gt; using...

Мусорка или "странная" работа массива указателей - C++
Всем привет. Постепенно поглащаю C++. Знания пока на уровне нуля. Учусь по дейтелу + шилду + интернет. &quot;Пишу&quot; в Dev-C++. Дошёл до объектов....

метод прогонки С++ - C++
Запрограммировать краевую задачу методом прогонки(тридиагональнои матрицы) Добавлено через 4 минуты Очень срочно надо^_^ ...

Метод прогонки - C++
Здравствуйте, пытаюсь реализовать метод прогонки, не могу проверить работу, не понимаю как заполнять, и как сделать массив чтобы высчитывал...

Метод обратной прогонки - C++
Нужно реализовать метод обратной прогонки на с++.МОЖНО ВЗЯТЬ ЛЮБОЙ ПРИМЕР.КТО МОЖЕТ ПОМОГИТЕ!!

Метод прогонки для СЛАУ - C++
Народ, я почти умер. Писал метод прогонки, работает неправильно, выдает что-то близкое, но неточно. код: #include...

Метод прогонки - исправить код - C++
Всем здравствуйте!!! Друзья, передо мной стоит задача, программная реализация метода прогонки. У меня есть код, который реализует это...

Ошибка в коде метода прогонки - C++
(Метод прогонки) Ответ выводит неправильный #include &lt;iostream&gt; #include &lt;iomanip&gt; #include &lt;math.h&gt; using namespace std; ...

Решение СЛАУ методом прогонки - C++
Добрый день,нужно решить СЛАУ методом прогонки,вот СЛАУ и ее решение. коэфф перед х1считается как за а1. перед х2считается...

Метод прогонки с разделяемой памятью на CUDA - C++
Здравствуйте. Есть метод прогонки на CUDA для глобальной памяти. Не могу реализовать то же самое для разделяемой ,пишет ошибки и всё. ...

Динамическое программирование. Метод прямой прогонки - C++
Мне нужно реализовать граф с поиском минимального пути из начала графа в конец путем прямой прогонки.Сделал граф, как список ребер,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru