IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

 
 Ответить  Открыть новую тему 
> Расчет поля температур С++.
сообщение
Сообщение #1


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


В общем,я как всегда радую всех,новыми веселыми задачами.Сегодня на повеске дня следующая.
Рассчитать стационарное поле температур в пластине заданной формы. Предусмотреть возможность задания произвольных граничных условий (первого рода) и произвольной правой части (в коде программы).
ПОРЯДОК РЕШЕНИЯ ЗАДАЧИ:
1. Составить разностную схему “крест” для уравнения Пуассона в области заданной формы.
2. Проанализировать структуру получившейся системы линейных алгебраических уравнений и составить алгоритм расчета температурного поля.
3. Выписать расчетные формулы метода Зейделя и выбрать начальное приближение на основе задания граничного условия.
4. В качестве критерия окончания использовать условие . Предусмотреть подсчет числа итераций, потребовавшихся для достижения точности .
5. Решить задачу методом Зейделя.
6. Решить задачу методом релаксации. Параметр релаксации подобрать экспериментально.

Все фигуры составлены из квадратов с единичной стороной (т.о. вся фигура вписывается в квадрат 3х3). Начало координат выбирается в любом удобном для заданной фигуры месте.

Даааа,планы, как говорится грандиозные,не знаешь, как начинать разгребать.
Вот фото самой пластины.
Изображение

К написанию кода я еще не приступил,нужна помощ в выборе реализации,а именно:
1)Как лучше реализовать хранение данных?одним массивом или как 7 массивов,которые с последствии будут склеиваться,чтоб выполнить пункт 1 задания,в общем,на данный момент я не совсем понимаю как лучше реализовать хранение данных,чтобы ими было удобно в последствии оперировать.

Буду рад любым идеям.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(Krjuger @ 27.04.2011 22:17) *
К написанию кода я еще не приступил,нужна помощ в выборе реализации,а именно:
1)Как лучше реализовать хранение данных?одним массивом или как 7 массивов,которые с последствии будут склеиваться,чтоб выполнить пункт 1 задания,в общем,на данный момент я не совсем понимаю как лучше реализовать хранение данных,чтобы ими было удобно в последствии оперировать.

В самом условии задачи содержится прозрачный и весьма недвусмысленный намек на реализацию по частям (по квадратам). Конечно, нужно делать именно так.


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Ну просто можно использовать 1 большой массив и те кубики,что не входят в пластину заполнить * например,а можно разбить на 3 (например) фигуры и обрабатывать их отдельно, а потом отдельно просмотреть те точки, что находятся на стыке фигур.Затем я не могу определиться,что лучше использовать либо массивы,тогда проще разбить,либо std:vector,тогда целиком всю фигуру будет проще,но с вектором я знаком весьма посредственно,вполне возможно что его можно инициализировать вообще без лишних элементов....

Сообщение отредактировано: Krjuger -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

Репутация: -  159  +


Цитата(Krjuger @ 28.04.2011 20:07) *
Ну просто можно использовать 1 большой массив и те кубики,что не входят в пластину заполнить * например,а можно разбить на 3 (например) фигуры и обрабатывать их отдельно, а потом отдельно просмотреть те точки, что находятся на стыке фигур.

В самом условии задачи содержится прозрачный и весьма недвусмысленный намек на реализацию по частям (по квадратам). Конечно, нужно делать именно так.

Цитата
Затем я не могу определиться,что лучше использовать либо массивы,тогда проще разбить,либо std:vector,тогда целиком всю фигуру будет проще,но с вектором я знаком весьма посредственно,вполне возможно что его можно инициализировать вообще без лишних элементов....
Зачем тут векторы??
Не парься.
Начини делать.


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


В общем я начал делать и пришел пока что к следующему.

#include<iostream>
#include<fstream>
#include<vector>
#include<math.h>
using namespace std;
const int N=2,m=3;
const double Eps=0.001;
vector<vector<double>> U,dU;

double Insert(double x,double y)
{
return x*y;
}

double f(double x,double y)
{
return x*(x*(y-x)+y);
}
double Cross(int i, int j)
{
double temp=(1.0/4.0)*(U[i+1][j]+U[i-1][j]+U[i][j-1]+U[i][j+1]+(1.0/N*N)*f(double(j)/double(N),double(i)/double(N)));
return temp;
}
double normi(vector<vector<double>> U)
{
double S1=0;
for(int i=1;i<U.size()-1;i++)
{
double S2=0;
double n=min(U[i].size(),min(U[i-1].size(),U[i+1].size()));
for(int j=1;j<n-1;j++)
{
S2+=abs(U[i][j]);
}
if (S2>S1) S1=S2;
}
return S1;
}
int main()
{
freopen("info.txt","w",stdout);
for(int i=0;i<=N;i++)
{
U.push_back(vector<double>(0));
for(int j=N;j<=3*N;j++)
{
U[i].push_back(Insert(double(j)/double(N),double(i)/double(N)));
}
}
for(int i=N+1;i<2*N;i++)
{
U.push_back(vector<double>(0));
for(int j=0;j<=2*N;j++)
{
U[i].push_back(Insert(double(j)/double(N),double(i)/double(N)));
}
}
for(int i=2*N;i<=3*N;i++)
{
U.push_back(vector<double>(0));
for(int j=0;j<=3*N;j++)
{
U[i].push_back(Insert(double(j)/double(N),double(i)/double(N)));
}
}
cout<<'\n';
for(int i=0;i<U.size();i++)
{
for(int j=0;j<=(U[i].size()-1);j++)
{
cout<<U[i][j]<<"\t ";
}
cout<<'\n';
}
fclose(stdout);

dU=U;
double norm=normi(dU);
int k=0;
for(;norm>Eps;k++)
{

for(int i=1;i<U.size()-1;i++)
{
double n=min(U[i].size(),min(U[i-1].size(),U[i+1].size()));
for(int j=1;j<n-1;j++)
{
dU[i][j]=U[i][j];
U[i][j]=Cross(i,j);
dU[i][j]=abs(dU[i][j]-U[i][j]);
}
}
norm=normi(dU);
freopen("info.txt","a",stdout);
cout<<'\n';
for(int i=0;i<U.size();i++)
{
for(int j=0;j<U[i].size();j++)
{
cout<<U[i][j]<<"\t ";
}
cout<<'\n';
}
cout<<"\n"<<"kol-vo iteraciy="<<k;
fclose(stdout);
}
return 0;
}
}


Так как не важно, как можно повернуть фигуру и с какой угол(сторону) считать точкой отсчета,я развернул фигуру на 90 градусов против часовой оси и за начало взял верхний левый угол.
Но тут возникли некоторые проблемы, если N изменить на 2 или более,то начинается пересчет точек,которые считаться не должны,т.к не хватает 1 данного.
                                  0	 0	 0	 0	 0	 
0.5 0.75 1 1.25 1.5
1 1.5 2 2.5 3
0 0.75 1.5 2.25 3
0 1 2 3 4 5 6
0 1.25 2.5 3.75 5 6.25 7.5
0 1.5 3 4.5 6 7.5 9

Исходная матрица.
0 0 0 0 0
0.5 0.8125 1.01563 0.878906 1.5
1 1.29688 1.82813 2.08301 3
0 1.19922 2.31934 3.16309 3
0 1.45605 3.06885 4.52673 4 5 6
0 1.80151 3.90509 5.98296 7.30824 8.38956 7.5
0 1.5 3 4.5 6 7.5 9
Матрица после первой итерации.

Как видно элементы 0.75(нижний левый) и 2.5(верхний правый) не должны пересчитываться так,как не хватает по 1 числу.Да и в общем то я не совсем уверен,что представление данных в памати компьютера верное и в уравнение Пуассона подставляются именно необходимые элементы.Руками я подставлял и считал для матрици с N=1,там вроде верно,а дальше я не уверен,что будет правильно при других N.

Сообщение отредактировано: Krjuger -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Вопрос снимается, задача решена,но представленный выше код был переделан практически полнстью.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Профи
****

Группа: Пользователи
Сообщений: 652
Пол: Мужской
Реальное имя: Алексей

Репутация: -  20  +


Собственно пришлось вернуться к этой задаче.Нужна помощ в оптимизации,потому что при N=25 (76х76 матрица) время выполнения порядка 20 секунд,а если учесть что оно должно считаться для N=100,я даже боюсь запускать.Файл с кодом прилагается,скажу только то, что все те функции что отдельно описаны для каждой граници и само f должны задаваться отдельно внутри программы.Собственно
Цитата
Предусмотреть возможность задания произвольных граничных условий (первого рода) и произвольной правой части (в коде программы).


Сообщение отредактировано: Krjuger -


Прикрепленные файлы
Прикрепленный файл  ChMet_Laba_4.cpp ( 4.51 килобайт ) Кол-во скачиваний: 422
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 17.04.2024 6:56
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name