Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.06.2016, 21:02   #1
Katyam
 
Регистрация: 24.05.2016
Сообщений: 7
По умолчанию c++ Решение уравнения теплопроводности конечно-разностными методами. Неправильно печатается массив массивов(строка из матрицы)

Здравствуйте.
Есть уравнение теплопроводности, оно решается двумя методами и сравнивается с точным решением. Каждый метод оформлен как отдельная функция, принимающая на вход двумерный массив. В этом массивае я накапливаю все шаги метода. Внутри функций все работает и печатается верно. Как только вызываю из главной программы—крайние элементы начинают выводится неправильно, а некоторые строки вообще нулевые.
Где ошибка?

PHP код:
#include <iostream>
#include <math.h>
#include <cmath>

using namespace std;

void yavn (double piint Ndouble Tdouble hdouble taudouble alphadouble betadouble kint zexpdouble** explic);
void tochn (double piint Ndouble Tdouble hdouble taudouble alphadouble betadouble kint zexdouble** ex);
void neyav (double piint Ndouble Tdouble hdouble taudouble alphadouble betadouble kint zimpdouble** impl);

int main() {
    
double pi 3.14159265358979323846;
    
double htautau2;
    
double Talphabeta;
    
int kNzexp 0zimp 0zex 0koef;

    
cin >> N;
    
cin >> T;
    
cin >> alpha;
    
cin >> beta;
    
cin >> k;

    
//посчитали шаг по x
    
1.0 N;
    
cout << "h=" << << ", ";

    
//посчитали шаг по t
    
tau 2;
    
cout << "tau=" << tau << endl;

    
cout << "Введите во сколько раз больше шаг по t для неявного метода: ";
    
cin >> koef;
    
tau2 koef tau;


    
//массивы, где будут записаны все слои каждого метода
    
double **explic = new double *[N];
    
double **impl = new double *[N];
    
double **ex = new double *[N];

    
cout << "• Явный" << endl;
    
yavn(piNThtaualphabetakzexpexplic);
    
cout << "• Неявный" << endl;
    
neyav(piNThtau2alphabetakzimpimpl);
    
cout << "• Точное" << endl;
    
tochn(piNThtaualphabetakzexex);

    
cout<<"➤➤➤ Выше методы. Ниже результат печати массивов в главной прогорамме" << endl;

    for (
int i=0i<=koef;i++)
    {
        
cout<< "• СЛОЙ="<< << endl;
        
cout<<"Явный метод:    ";
        for(
int j=0j<=Nj++){
            
int p;
            
p=koef*i;
            
cout<<explic[p][j]<< ",  ";
        }

        
cout<<endl;
        
cout<<"Неявный метод:  ";
        for(
int j=0j<=Nj++){
            
int q;
            
q=koef*i;
            
cout<<impl[q][j]<< ",  ";
        }
        
cout<<endl;
        
cout<<"Точное решение: ";
        for(
int j=0j<=Nj++){
            
int r;
            
r=koef*i;
            
cout<<ex[r][j]<< ",  ";
        }
        
cout<<endl;
    }
    return 
0;
}


//ЯВНАЯ СХЕМА
void yavn (double piint Ndouble Tdouble hdouble taudouble alphadouble betadouble kint zexpdouble** explic) {
    
double timing=0;
    
double u0[N], u[N];

    
//нулевой слой: начальные условия
    
for (int i 0<= Ni++)
    {
        
u0[i]=sin(pi*k*i*h);
    }

    
//переопределяем значения на границах нулевого слоя
    
u0[0]=0// u=a*t
    
u0[N]=0// u=b*t

    //выводим весь нулевой слой
    
cout<< "СЛОЙ=" << zexp <<"    ";
    for (
int i 0<= Ni++)
    {
        
explic[i] = new double[N];
        
explic[zexp][i]=u0[i];
        
cout <<u0[i] << ",  ";
    }

    
cout << endl;
    while(
timing<T)
    {
        
timing timing+tau;
        
zexp=zexp+1;

        for (
int i 1<= Ni++)
        {
            
u[i]=u0[i]+(timing/(h*h))*(u0[i+1]-2*u0[i]+u0[i-1]);

        }
        
u[0]=alpha*timing;
        
u[N]=beta*timing;

        
cout<< "СЛОЙ=" << zexp << "    ";
        for (
int i 0<= Ni++)
        {
            
cout << u[i] << ",  ";
        }

        for(
int i 0<= Ni++)
        {
            
u0[i] = u[i];
            
explic[zexp][i]=u[i];
        }
//
        
cout<<endl;
        
cout<< "—————" << zexp << "    ";
        for (
int i 0<= Ni++)
        {
            
cout << explic[zexp][i] << ",  ";
        }

        
cout << endl;
    }

}

//НЕЯВНАЯ СХЕМА
void neyav (double piint Ndouble Tdouble hdouble tau2double alphadouble betadouble kint zimpdouble** impl) {
    
double timing=0;
    
double u0[N], u[N];
    
double abc//коэффициенты в системе
    
double Ai[N],Bi[N]; //массивы коэффициентов

    //нулевой слой
    
cout << "СЛОЙ=" << zimp << "    ";

    
//начальные условия
    
for (int i 0<= Ni++)
    {
        
impl[i] = new double[N];
        
u0[i]=sin(pi*k*i*h);
        
impl[0][i]=u0[i];
    }

    
//переопределяем значения на границах нулевого слоя
    
u0[0]=0// u=a*t
    
u0[N]=0// u=b*t
    
impl[0][0]=u0[0];
    
impl[0][N]=u0[N];

    
//выводим нулевой слой с учетом граничных
    
for (int i 0<= Ni++)
    {
        
cout << u0[i] << ",  ";
    }

    
//коэффициенты системы
    
a=(-1.0)*((2.0/(h*h)+1.0/tau2));
    
b=1.0/(h*h);
    
c=(-1.0)/tau2;

    
cout << endl;
    while(
timing<T)
    {
        
timing timing+tau2;
        
zimp=zimp+1;

        
//A1 и B1
        
Ai[1]=-b/a;
        
Bi[1]=(c*u0[1]-b*alpha*timing)/a;

        
//Ai и Bi
        
for (int i 1<= N-3i++)
        {
            
Ai[i+1]=-b/(b*Ai[i]+a);
            
Bi[i+1]=(c*u0[i+1]-b*Bi[i])/(b*Ai[i]+a);
        }

        
//An-1 и Bn-1
        
Ai[N-1]=0;
        
Bi[N-1]=(c*u0[N-1]-b*beta*timing)/(b*Ai[N-2]+a);

        
//Прогонка
        
u[0]=alpha*timing;
        
u[N-1]=Bi[N-1];
        
u[N]=beta*timing;
        
impl[zimp][0]=u[0];
        
impl[zimp][N-1]=u[N-1];
        
impl[zimp][N]=u[N];

        for (
int i=1i<=N-2;i++)
        {
            
u[N-i-1]=Ai[N-i-1]*u[N-i]+Bi[N-i-1];
            
impl[zimp][N-i-1]=u[N-i-1];
        }
        
impl[zimp][0]=u[0];
        
impl[zimp][N-1]=u[N-1];
        
impl[zimp][N]=u[N];

        
//Выводим решение
        
cout << "СЛОЙ=" << zimp << "    ";
        for (
int i=0i<=Ni++)
        {
            
cout << u[i] << ",  ";
        }

        
//Запоминаем этот слой
        
for(int i 0<= Ni++)
        {
            
impl[zimp][i]=u[i];
            
u0[i] = u[i];
        }

        
cout<<endl;
        
cout << "—————" << zimp << "    ";
        for (
int i=0i<=Ni++)
        {
            
cout << impl[zimp][i] << ",  ";
        }

        
cout << endl;

    }
}

//ТОЧНОЕ РЕШЕНИЕ
void tochn (double piint Ndouble Tdouble hdouble taudouble alphadouble betadouble kint zexdouble** ex) {
    
double homogeneousinhomogeneous=0timing=0;
    
double u[N];
    
int n=10;

    
//начальные условия
    
for (int i 0<= Ni++)
    {
        
ex[i] = new double[N];
        
u[i]=sin(pi*k*i*h);
        
ex[0][i]=u[i];
    }

    
u[0]=0;
    
u[N]=0;
    
ex[0][0]=0;
    
ex[0][N]=0;

    
cout<< "СЛОЙ=" << zex << "    ";
    for (
int i 0<= Ni++)
    {
        
cout << ex[0][i] << ",  ";
    }


    
cout << endl;
    while (
timing<T) {
        
timing=timing+tau;
        
zex=zex+1;
        
cout<< "СЛОЙ=" << zex << "    ";
        for (
int i=0i<=Ni++)
        {
            
homogeneous=alpha*timing*(1-h*i)+beta*timing*h*i+(exp(-pow(pi*k,2)*timing))*sin(pi*k*h*i);
            for(
int j=1j<=nj++)
            {
                
inhomogeneous=inhomogeneous+(2/(pow(pi*j,3)))*(alpha-(pow(-1j))*beta)*sin(pi*j*h*i)*(exp(-pow(pi*j,2)*timing)-1);
            }
            
u[i]=homogeneous+inhomogeneous;
            
u[0]=alpha*timing;
            
u[N]=beta*timing;
            
ex[zex][i]=u[i];
            
ex[zex][0]=u[0];
            
ex[zex][N]=u[N];

            
cout << u[i] << ",  ";
        }
        
cout<<endl;
        
cout<< "—————" << zex << "    ";
        for(
int i=0i<=Ni++)
        {
cout << ex[zex][i] << ",  ";}
        
cout << endl;
    }

Katyam вне форума Ответить с цитированием
Старый 07.06.2016, 21:04   #2
Katyam
 
Регистрация: 24.05.2016
Сообщений: 7
По умолчанию

Выдача выглядит так:
Код:
Введите разбиение по x: 10
Введите конечное время: 0.02
Введите коэффициент левого гр. усл.: 1
Введите коэффициент правого гр. усл.: 1
Введите коэффициент начального условия u(x,0)=sin(pi*k*x): 1
h=0.1, tau=0.005
Введите во сколько раз больше шаг по t для неявного метода: 2

• Явный
СЛОЙ=0    0,  0.309017,  0.587785,  0.809017,  0.951057,  1,  0.951057,  0.809017,  0.587785,  0.309017,  0,  
СЛОЙ=1    0.005,  0.293893,  0.559017,  0.769421,  0.904508,  0.951057,  0.904508,  0.769421,  0.559017,  0.293893,  0.005,  
—————1    0.005,  0.293893,  0.559017,  0.769421,  0.904508,  0.951057,  0.904508,  0.769421,  0.559017,  0.293893,  0.005,  
СЛОЙ=2    0.01,  0.270124,  0.504297,  0.694105,  0.815969,  0.85796,  0.815969,  0.694105,  0.504297,  0.270124,  0.01,  
—————2    0.01,  0.270124,  0.504297,  0.694105,  0.815969,  0.85796,  0.815969,  0.694105,  0.504297,  0.270124,  0.01,  
СЛОЙ=3    0.015,  0.231196,  0.43775,  0.592189,  0.69616,  0.731986,  0.69616,  0.592189,  0.43775,  0.231196,  0.015,  
—————3    0.015,  0.231196,  0.43775,  0.592189,  0.69616,  0.731986,  0.69616,  0.592189,  0.43775,  0.231196,  0.015,  
СЛОЙ=4    0.02,  0.211913,  0.333519,  0.491254,  0.55987,  0.588682,  0.55987,  0.491254,  0.333519,  0.211913,  0.02,  
—————4    0.02,  0.211913,  0.333519,  0.491254,  0.55987,  0.588682,  0.55987,  0.491254,  0.333519,  0.211913,  0.02,  

• Неявный
СЛОЙ=0    0,  0.309017,  0.587785,  0.809017,  0.951057,  1,  0.951057,  0.809017,  0.587785,  0.309017,  0,  
СЛОЙ=1    0.01,  0.285223,  0.536652,  0.736949,  0.865177,  0.907525,  0.857397,  0.71361,  0.474416,  0.121854,  0.01,  
—————1    0.01,  0.285223,  0.536652,  0.736949,  0.865177,  0.907525,  0.857397,  0.71361,  0.474416,  0.121854,  0.01,  
СЛОЙ=2    0.02,  0.265428,  0.49106,  0.6711,  0.78529,  0.819595,  0.76597,  0.620917,  0.383172,  0.0541833,  0.02,  
—————2    0.02,  0.265428,  0.49106,  0.6711,  0.78529,  0.819595,  0.76597,  0.620917,  0.383172,  0.0541833,  0.02,  

• Точное
СЛОЙ=0    0,  0.309017,  0.587785,  0.809017,  0.951057,  1,  0.951057,  0.809017,  0.587785,  0.309017,  0,  
СЛОЙ=1    0.005,  0.29477,  0.555262,  0.760772,  0.891036,  0.932562,  0.881038,  0.740768,  0.525336,  0.255622,  0.005,  
—————1    0.005,  0.29477,  0.555262,  0.760772,  0.891036,  0.932562,  0.881038,  0.740768,  0.525336,  0.255622,  0.005,  
СЛОЙ=2    0.01,  0.239137,  0.482363,  0.672811,  0.791573,  0.825857,  0.771584,  0.632902,  0.42312,  0.163228,  0.01,  
—————2    0.01,  0.239137,  0.482363,  0.672811,  0.791573,  0.825857,  0.771584,  0.632902,  0.42312,  0.163228,  0.01,  
СЛОЙ=3    0.015,  0.14505,  0.37214,  0.548227,  0.655853,  0.683019,  0.625942,  0.488746,  0.284639,  0.0345349,  0.015,  
—————3    0.015,  0.14505,  0.37214,  0.548227,  0.655853,  0.683019,  0.625942,  0.488746,  0.284639,  0.0345349,  0.015,  
СЛОЙ=4    0.02,  0.0149671,  0.226903,  0.389348,  0.486246,  0.506457,  0.446583,  0.310831,  0.112332,  -0.128236,  0.02,  
—————4    0.02,  0.0149671,  0.226903,  0.389348,  0.486246,  0.506457,  0.446583,  0.310831,  0.112332,  -0.128236,  0.02,  


➤➤➤ Выше методы. Ниже результат печати массивов в главной прогорамме
• СЛОЙ=0
Явный метод:    6.94476e-310,  0.309017,  0.587785,  0.809017,  0.951057,  1,  0.951057,  0.809017,  0.587785,  0.309017,  0.005,  
Неявный метод:  0,  0.309017,  0.587785,  0.809017,  0.951057,  1,  0.951057,  0.809017,  0.587785,  0.309017,  0.01,  
Точное решение: 0,  0.309017,  0.587785,  0.809017,  0.951057,  1,  0.951057,  0.809017,  0.587785,  0.309017,  0.005,  
• СЛОЙ=1
Явный метод:    0.01,  0.270124,  0.504297,  0.694105,  0.815969,  0.85796,  0.815969,  0.694105,  0.504297,  0.270124,  0.015,  
Неявный метод:  0.02,  0.265428,  0.49106,  0.6711,  0.78529,  0.819595,  0.76597,  0.620917,  0.383172,  0.0541833,  0.02,  
Точное решение: 0.01,  0.239137,  0.482363,  0.672811,  0.791573,  0.825857,  0.771584,  0.632902,  0.42312,  0.163228,  0.015,  
• СЛОЙ=2
Явный метод:    0.02,  0.211913,  0.333519,  0.491254,  0.55987,  0.588682,  0.55987,  0.491254,  0.333519,  0.211913,  0.02,  
Неявный метод:  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  
Точное решение: 0.02,  0.0149671,  0.226903,  0.389348,  0.486246,  0.506457,  0.446583,  0.310831,  0.112332,  -0.128236,  0.02,
Katyam вне форума Ответить с цитированием
Старый 07.06.2016, 22:25   #3
ura_111
Участник клуба
 
Регистрация: 14.05.2016
Сообщений: 1,793
По умолчанию

ura_111 вне форума Ответить с цитированием
Старый 08.06.2016, 07:16   #4
Katyam
 
Регистрация: 24.05.2016
Сообщений: 7
По умолчанию

Поменяла q, выдача стала лучше, спасибо. Но проблема с границами так и не ушла.
Katyam вне форума Ответить с цитированием
Старый 08.06.2016, 15:02   #5
ura_111
Участник клуба
 
Регистрация: 14.05.2016
Сообщений: 1,793
По умолчанию

1) Я подумал, что изменения которые я сделал "в неявном методе" справедливо только для соотношения 2/4. А если будет другое?
В этом месте нужно просто q=i; (см. фотографию)

2) Для научных результатов больше подходит ф-ций вывода printf, в которой можно задать количество знаков после запятой (в моем примере выведен 3-й знак после запятой). Тогда вывод получится более аккуратным. Анаже убрала значение 6.94476e-310 (хотя мне всегда говорили, что это и так есть 0-ль, а поэтому я особо не комплексовал по выводу 6.94476e-310).

3) По остальному вопросу мне непонятно что должно выводить. Может быть это (см. фотографию). Но тогда не понятно зачем вообще рассчитывать 3 и 4 слой если их не выводить. Короче, я думал, что в этом месте все правильно выводило, только нужно отодразить что это 3 и 4 слой.

4) Ещё мне не понятно зачем дублировать информацию в внешних функциях (там где "-------")? Зачем захломлять экран одинаковой информацией, например от СЛОЙ=4 и —————4 ? И зачем вообще выводить во внешних функциях? Я бы вывел все в main() в сравнении 0,1,2 слой (как сейчас), а чуть ниже сопоставление 3,4. В этом случае вывод стал бы компактней в 2 раза, а информации никакой не потерял (см. фото №2).






Последний раз редактировалось ura_111; 08.06.2016 в 16:11.
ura_111 вне форума Ответить с цитированием
Старый 08.06.2016, 17:57   #6
Katyam
 
Регистрация: 24.05.2016
Сообщений: 7
По умолчанию

Задача: сравнить, как считают методы, и сравнить с точным решением. Т.к. шаг неявного больше, то итерация будет меньше (меньше слоев). Поэтому пляшем от неявного метода, и выбираем из всех слоев явного метода и точного решения, только те, которые есть в неявном. А чтобы удобнее было сравнивать, выводим их друг под другом. Для этого в каждом методе я и накапливаю все результаты в матрицу.
Слой 1:
явный метод x x x
неявный метод: x x x
точное (эталон): x x x

Функциями все оформлено, чтобы можно было переиспользовать в любой момент, в любой программе, т.е. задача изначально так стояла. И на самом деле, вывод результатов внутри методов нужен только для проверки, все ли считается верно, и как записывается в матрицу, потому что есть проблема, что в main результаты выводятся неверно, и, если увеличить конечное время, то только до 3 слоя, хотя их становится 10.

Katyam вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
C++ Решение уравнения теплопроводности разными методами. Оформление функциями не работает. Katyam Помощь студентам 4 25.05.2016 10:29
Решение трехмерного уравнения теплопроводности E90 Помощь студентам 2 08.08.2012 21:44
Разностное решение уравнения теплопроводности.Явный метод(Delphi) Helene Lee Помощь студентам 0 27.05.2012 21:16
Решение уравнения.массив SilAs Помощь студентам 9 22.02.2011 11:27
Решения одномерного дифференциального уравнения теплопроводности в частных производных (delphi) Denzloy Помощь студентам 1 27.01.2009 14:51