Конечно-разностные схемы моделирования распространения волн

Система гиперболических дифференциальных уравнений в частных производных. Таблица идентификаторов для программы. Реализация программы на языке С++. Исходный код программы для вывода в среде MATLAB. Тестовые примеры для программы, реализующей явную схему.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 19.03.2012
Размер файла 1,2 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Размещено на http://www.allbest.ru/

Оглавление

Оглавление

1. Введение

2. Явная схема

2.1 Постановка задачи

2.2 Теоретическая часть

2.3 Начальные условия

2.4 Граничные условия

2.5 Условие Куранта -- Фридрихса -- Леви

2.6 Условие устойчивости

2.7 Алгоритм решения

2.8 Блок-схема

2.9 Реализация

2.9.1 Таблица идентификаторов для программы

2.9.2 Реализация на языке С/С++ программы

2.9.3 Исходный код программы для вывода в среде MATLAB

2.10 Тестовые примеры для программы, реализующей явную схему

3. Неявная схема

3.1 Постановка задачи

3.2 Теоретическая часть

3.3 Начальные условия

3.4 Граничные условия

3.5 Алгоритм решения

3.6 Блок-схема

3.7 Реализация

3.7.1 Таблица идентификаторов для программы

3.7.2 Реализация на языке С/С++ программы

3.7.3 Исходный код программы для вывода в среде MATLAB

3.8 Тестовые примеры для программы, реализующей явную схему

4. Заключение

1. Введение

Разностная схема -- это конечная система алгебраических уравнений, поставленная в соответствие какой-либо дифференциальной задаче, содержащей дифференциальное уравнение и дополнительные условия (например краевые условия и/или начальное распределение). Таким образом, разностные схемы применяются для сведения дифференциальной задачи, имеющей континуальный характер, к конечной системе уравнений, численное решение которых принципиально возможно на вычислительных машинах. Алгебраические уравнения, поставленные в соответствие дифференциальному уравнению, получаются применением разностного метода, что отличает теорию разностных схем от других численных методов решения дифференциальных задач[1].

Уравнения мелкой воды -- система гиперболических дифференциальных уравнений в частных производных, которая описывает потоки под поверхностью жидкости[2].

2. Явная схема

2.1 Постановка задачи

Пусть система дифференциальных уравнений, моделирующая поведение волн, имеет вид

(1)

Для этой системы выберем разностную схему №11 [3]

(2)

Шаги по горизонтальным осям (?x и ?y) возьмём равными, выразив их как h = ?x = ?y.

С помощью полученной схемы реализовать программу, позволяющую моделировать поведение волн.

2.2 Теоретическая часть

Для моделирования поведения волн, как уже было описано выше, мы использовали систему дифференциальных уравнений (1) и построенную к ней конечно-разностную схему в которой: c - фазовая скорость, u и v -векторы скорости, а ? - высота волны.

Легко заметить, что данная схема является явной, а использование осреднения по пространственным переменным придёт схеме параболический характер.

Для её решения будем использовать алгоритм бегущего счёта. Что по первому слою (который задаётся из начальных условий), мы можем вычислить второй, по второму - третий и т.д. пока не добьёмся желаемого результата. Для этого нам потребуется однозначно выразить искомые значения через уже известные:

(3)

Теперь, когда уравнения для поиска новых значений построены, требуется задать начальные и граничные условия.

2.3 Начальные условия

В качестве начального состояния поверхности рассмотрим гладкую поверхность с «колокольчиком» в центре.

Для того, что бы её задать будем использовать следующую формулу.

(2)

где - высота «колокольчика», - радиус, H - глубина бассейна, a и - координаты центра. Для конкретного примера зададим высоту равную 1, радиус равный 5, глубину равной 1, а расположен он будет в центре расчётной области. В итоге, поверхность в начальный момент времени будет иметь такой вид (Рисунок 1):

Рисунок 1 - поверхность в начальный момент.

2.4 Граничные условия

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

Для описания «свободных» границ в задачах о распространении волн цунами было выбрано условие Зоммерфельда, согласно которому предполагается перенос в направлении внешней нормы с постоянной скоростью, определяемой глубиной бассейна у границы и без изменения формы волны:

(3)

В тех случаях, когда это необходимо, нормальная компонента скорости у свободной границы рассчитывается из соотношения

(4)

а касательная компонента скорости

(5)

Переходя к рассмотрению численных алгоритмов, реализующих условия свободного прохода, предположим, что в приграничных точках поведение волны описывается уравнением (3). Тогда значение на границе в момент времени (n+1)?t определяется из соотношения

(6)

где - значение высоты волны в точке, ближайшей к границе по направлению . Соотношение (6) является интерполяционной формулой, устойчивость которой обеспечивается выполнением критерия Куранта .

Для простоты расчётов будем считать, что , тогда уравнение (6) принимает вид

(7)

На рисунке 2 графически изображён этот принцип: красными показаны искомые граничные узлы, зелёными - граничные узлы на предыдущем слое, синие - ближайшие узлы предыдущего слоя к искомым граничным узлам.

Рисунок 2 - наглядное изображение выбранного принципа отыскания граничных условий

2.5 Условие Куранта -- Фридрихса -- Леви

Критерий Куранта-Фридрихса-Леви -- необходимое условие устойчивости явного численного решения некоторых дифференциальных уравнений в частных производных. Как следствие, во многих компьютерных симуляциях временной шаг должен быть меньше определённого значения, иначе результаты будут неправильными[1].

Критерий КФЛ применяется к гиперболическим уравнениям. В двумерном случае он будет иметь вид:

(8)

2.6 Условие устойчивости

Параболический характер данной схемы так же отражается и на условии устойчивости. В данном случае оно выгляди как

(10)

где - шаг по времени, h - шаг по пространственным осям, g - ускорение силы тяжести, H - глубина.

Исследует нашу схему на устойчивость.

Уравнение 1.

Заменим .

Для этого должно выполняться условие

Выразим отсюда ?t:

Уравнение 2.

Заменим .

Для этого должно выполняться условие

Выразим отсюда ?t:

Уравнение 3.

Заменим .

Для этого должно выполняться условие

Выразим отсюда ?t:

Условие является самым сильным из полученных. Если усилить его до (при h < 1), то получим искомое неравенство.

2.7 Алгоритм решения

1) Задать параметры расчётной сетки.

2) Задать начальные значения.

3) Рассчитать следующий слой.

4) Задать граничные условия на новом слою.

5) Вернуться к пункту 3, если слой не последний.

6) Вывести полученные данные о высотах и характеристиках в файлы.

7) Отобразить поведение волн.

2.8 Блок-схема

На рисунке 3 изображена блок-схема алгоритма.

Рисунок 3 - блок-схема алгоритма

2.9 Реализация

2.9.1 Таблица идентификаторов для программы

В таблице 1 представлены идентификаторы переменных, функций и процедур для языков C/C++, используемых в реализации программ.

Таблица 1 - Идентификаторы

Данные

Идентификатор на языке C/C++

Переменные и методы Scheme:

Массив значений u

double *** u

Массив значений v

double *** v

Массив значений высот

double *** eta

Кол-во моментов времени

t_num

Кол-во точек на осях

x_num

Шаг по времени (секунды)

dt

Шаг по оси (метры)

dx

Глубина бассейна

H

Вывод массива значений

outArray(char *, double ***)

Очистка массивов

clear()

Вывод информации о схеме

ouput()

Переменные и методы SchemeN:

Фазовая скорость

c

Задать начальные условия

setInitialConditions()

Задать граничные условия на n шагу

setBoundaryConditions(int n)

Начать расчёты

calculate()

Переменные:

Счётчики

i, j, k

Начальная координата x

x0

Начальная координата y

y0

Начальная высота

eta0

a

a

Тестовая схема

test

2.9.2 Реализация на языке С/С++ программы

Представлена реализация алгоритма на языке C/C++.

Реализация явной схемы на языке C/C++

#include <stdlib.h>

#include <stdio.h>

#include <math.h>

class Scheme{

protected:

double *** u; // Массив значений u

double *** v; // Массив значений v

double *** eta; // Массив значений eta

double H; // Глубина бассейна

int t_num; // Кол-во моментов времени

int x_num; // Кол-во точек на оси X

double dt; // Шаг по времени (секунды)

double dx; // Шаг по оси (метры)

void outArray(char * name, double *** out_array){

FILE * fout = fopen(name, "w");

for(int i = 0; i < t_num; i++){

for(int j = 0; j < x_num; j++){

for(int k = 0; k < x_num; k++){

fprintf(fout, "%f\t", out_array[i][j][k]);

}

fprintf(fout, "\n");

}

fprintf(fout, "\n\n");

}

fclose(fout);

}

public:

virtual void setInitialConditions() = 0;

virtual void setBoundaryConditions(int n) = 0;

virtual void calculate() = 0;

Scheme(int N, int M, double Dx, double H_temp){

dx = Dx;

H = H_temp;

dt = (dx*dx)/(10*H*10);

t_num = N;

x_num = M;

u = new double**[t_num];

v = new double**[t_num];

eta = new double**[t_num];

for(int i = 0; i < t_num; i++){

u[i] = new double*[x_num];

v[i] = new double*[x_num];

eta[i] = new double*[x_num];

for(int j = 0; j < x_num; j++){

u[i][j] = new double[x_num];

v[i][j] = new double[x_num];

eta[i][j] = new double[x_num];

}

}

}

~Scheme(){

for(int i = 0; i < t_num; i++){

for(int j = 0; j < x_num; j++){

delete[] u[i][j];

delete[] v[i][j];

delete[] eta[i][j];

}

delete[] u[i];

delete[] v[i];

delete[] eta[i];

}

delete[] u;

delete[] v;

delete[] eta;

}

void clear(){

for(int i = 0; i < t_num; i++){

for(int j = 0; j < x_num; j++){

for(int k = 0; k < x_num; k++){

eta[i][j][k] = 0.0;

u[i][j][k] = 0.0;

v[i][j][k] = 0.0;

}

}

}

}

void ouput(){

FILE * foutConfig = fopen("config.txt", "w");

fprintf(foutConfig, "%d\n%lf\n", x_num, dx);

fprintf(foutConfig, "%d\n%lf\n", t_num, dt);

fclose(foutConfig);

outArray("eta.txt", eta);

}

};

class SchemeN: public Scheme {

double c;

public:

virtual void setInitialConditions(){

double x0 = double(x_num)*dx/2.0;

double y0 = double(x_num)*dx/2.0;

double eta0 = 1.0;

double a = 0.2;

for(int i = 0; i < x_num; i++){

for(int j = 0; j < x_num; j++){

v[0][i][j] = 0.0;

u[0][i][j] = 0.0;

eta[0][i][j] = H + eta0*exp( - a*a*((dx*i-x0)*(dx*i-x0) + (dx*j-y0)*(dx*j-y0)));

}

}

}

virtual void setBoundaryConditions(int n){

if(n < 1 || n > t_num - 1)

return;

for(int i = 1; i < x_num-1; i++){

eta[n][0][i] = eta[n-1][1][i];

eta[n][x_num-1][i] = eta[n-1][x_num-2][i];

eta[n][i][0] = eta[n-1][i][1];

eta[n][i][x_num-1] = eta[n-1][i][x_num-2];

u[n][0][i] = u[n-1][1][i];

u[n][x_num-1][i] = u[n-1][x_num-2][i];

u[n][i][0] = u[n-1][i][1];

u[n][i][x_num-1] = u[n-1][i][x_num-2];

v[n][0][i] = v[n-1][1][i];

v[n][x_num-1][i] = v[n-1][x_num-2][i];

v[n][i][0] = v[n-1][i][1];

v[n][i][x_num-1] = v[n-1][i][x_num-2];

}

eta[n][0][0] = eta[n-1][1][1];

eta[n][x_num-1][0] = eta[n-1][x_num-2][1];

eta[n][0][x_num-1] = eta[n-1][1][x_num-2];

eta[n][x_num-1][x_num-1] = eta[n-1][x_num-2][x_num-2];

u[n][0][0] = u[n-1][1][1];

u[n][x_num-1][0] = u[n-1][x_num-2][1];

u[n][0][x_num-1] = u[n-1][1][x_num-2];

u[n][x_num-1][x_num-1] = u[n-1][x_num-2][x_num-2];

v[n][0][0] = v[n-1][1][1];

v[n][x_num-1][0] = v[n-1][x_num-2][1];

v[n][0][x_num-1] = v[n-1][1][x_num-2];

v[n][x_num-1][x_num-1] = v[n-1][x_num-2][x_num-2];

}

virtual void calculate(){

for(int i = 0; i < t_num-1; i++){

for(int j = 1; j < x_num-1; j++){

for(int k = 1; k < x_num-1; k++){

u[i+1][j][k] = u[i][j][k] -

((c*c*dt)/2.0)*((eta[i][j+1][k+1] - eta[i][j-1][k+1])/(2.0*dx) +

(eta[i][j+1][k-1] - eta[i][j-1][k-1])/(2.0*dx));

v[i+1][j][k] = v[i][j][k] -

((c*c*dt)/2.0)*((eta[i][j+1][k+1] - eta[i][j+1][k-1])/(2.0*dx) +

(eta[i][j-1][k+1] - eta[i][j-1][k-1])/(2.0*dx));

eta[i+1][j][k] = eta[i][j][k] +

dt*(-0.5*((u[i][j+1][k+1] - u[i][j-1][k+1])/(2.0*dx) + (u[i][j+1][k-1] -

u[i][j-1][k-1])/(2.0*dx)) - 0.5*((v[i][j+1][k+1] - v[i][j+1][k-1])/(2.0*dx)

+ (v[i][j-1][k+1] - v[i][j-1][k-1])/(2.0*dx)));

if(dt*(u[i+1][j][k] + v[i+1][j][k])/dx >= c){

printf("Courant-Friedrichs-Lewy condition failed/n");

exit();

}

}

}

setBoundaryConditions(i+1);

}

setBoundaryConditions(t_num-1);

}

SchemeN(int N, int M, double Dx, double H_temp): Scheme(N, M, Dx, H_temp), c(sqrt(10*H_temp)) {}

};

int main(){

SchemeN test(600, 100, 1.0, 1.0);

test.clear();

test.setInitialConditions();

test.calculate();

test.ouput();

system("pause");

return 1;

}

2.9.3 Исходный код программы для вывода в среде MATLAB

Представлен исходный код программы для вывода в среде MATLAB.

Исходный код программы для вывода в среде MATLAB

clear;

load config.txt;

dx = config(2);

dt = config(4);

x = 0:dx:(config(1)-1)*dx;

y = x;

num = config(3);

M = moviein(num);

n = 1;

load eta.txt;

xmin = 0;

xmax = dx*(config(1)-1);

for r = 1:num

z = eta(n:n+config(1)-1,:);

mesh(x,y,z);

axis([0 xmax 0 xmax -0 2]);

xlabel('x');

ylabel('y');

zlabel('z');

M(:,r) = getframe;

n = n+config(1);

end

repeat = 0;

fps = 10;

movie(M, repeat, fps);

2.10 Тестовые примеры для программы, реализующей явную схему

Программа реализованная на C/C++ в качестве выходных данных имеет 2 файла: config.txt - содержащий информацию о расчётной сетке и eta.txt - содержащую карту высот. Примеры выходных данных можно посмотреть в прикреплённых файлах.

На рисунках 4 - 9 изображены результаты работы программы строящей графики в среде MATLAB в разные моменты времени:

Рисунок 4 - состояние волны в начальный момент времени

Рисунок 5 - состояние волны в момент времени t = 1с

Рисунок 6 - состояние волны в момент времени t=1,5c

Рисунок 7 - состояние волны в момент времени t=2c

Рисунок 8 - состояние волны в момент времени t=3c

Рисунок 9 - состояние волны в момент времени t=6c

3. Неявная схема

3.1 Постановка задачи

Пусть система дифференциальных уравнений, моделирующая поведение волн, имеет вид

(11)

Для этой системы выберем неявную конечно-разностную схему с пересчётом

(12)

(13)

(14)

(15)

Шаги по горизонтальным осям (?x и ?y) возьмём равными, выразив их как h = ?x = ?y, а глубину бассейна будем считать постоянной, т.е. H = const.

С помощью полученной схемы реализовать программу, позволяющую моделировать поведение волн.

3.2 Теоретическая часть

Для моделирования поведения волн, как уже было описано выше, мы использовали систему дифференциальных уравнений (11) и построенную к ней конечно-разностную схему в которой: u и v -векторы скорости, а ? - высота волны, ?* - вспомогательное значение высота волны, H - глубина бассейна.

Данная схема является неявной с пересчётом. Главной особенностью неявных схем является то, что они являются безусловно устойчивыми.

Мы выделили ?*, которая не зависит от элементов на следующем слое. Пользуясь этим приёмом, мы может находить скорости независимо от значения скоростей на следующем шаге. Это позволяет нам использовать метод прогонки для отыскания значений скоростей на новом слое. Для этого нам потребуется выразить скорости из уравнений (13) и (14), а заодно и однозначно выразить ? и ?*:

(16)

(17)

(18)

(19)

Для того, что бы отыскать значения на n+1 слое, опираясь на предыдущий слой, нужно будет решать систему линейных уравнений. Обычно, для этого используются итерационные методы, вместо более долгих точных методов. То такие методы имеют один большой недостаток - они решают систему приближенно. Но особый вид неявной схемы позволяет нам использовать решать всего лишь трёхдиагональную матрицу. Для этого используется метод «прогонки».

Теперь, когда уравнения для поиска новых значений построены, требуется задать начальные и граничные условия.

3.3 Начальные условия

В данной задаче начальное состояние волны зададим при помощи функции

(20)

Скорости начальный момент равны 0. h = 0.1, , а высота бассейна равна 1.

На рисунке 10 изображено начальное состояние волны.

Рисунок 10 - состояние в начальный момент времени

3.4 Граничные условия

Для данной схемы рассмотрим в качестве граничных условий «свободные» границы. Для этого будем использовать условие протекания:

(21)

3.5 Алгоритм решения

1) Задать параметры расчётной сетки.

2) Задать начальные значения.

3) Рассчитать временные высоты.

4) Рассчитать используя метод прогонки распределение скоростей на новом слою

5) .Рассчитать высоты на новом слою.

6) Задать граничные условия на новом слою.

7) Вернуться к пункту 3, если слой не последний.

8) Вывести полученные данные о высотах и характеристиках в файлы.

9) Отобразить полученные результаты.

3.6 Блок-схема

На рисунке 11 изображена блок-схема алгоритма.

Рисунок 11 - блок-схема алгоритма

3.7 Реализация

3.7.1 Таблица идентификаторов для программы

В таблице 4 представлены идентификаторы переменных, функций и процедур для языков C/C++, используемых в реализации программ.

Таблица 4 - Идентификаторы

Данные

Идентификатор на языке C/C++

Переменные и методы Scheme:

Массив значений u

double *** u

Массив значений v

double *** v

Массив значений высот

double *** eta

Временный массив значений высот

double ** etaTemp

Кол-во моментов времени

t_num

Кол-во точек на осях

x_num

Шаг по времени (секунды)

dt

Шаг по оси (метры)

dx

Глубина бассейна

H

Вывод массива значений

outArray(char *, double ***)

Очистка массивов

clear()

Вывод информации о схеме

ouput()

Переменные и методы SchemeN:

Фазовая скорость

c

Задать начальные условия

setInitialConditions()

Задать граничные условия на n шагу

setBoundaryConditions(int n)

Начать расчёты

calculate()

Подготовить временные высоты

prepareEtaTemp()

Метод прогонки

solveMatrix()

Рассчитать значений высот

calculateEta()

Рассчитать Ux

calculateUx()

Рассчитать Uy

calculateUy()

Рассчитать Vx

calculateVx()

Рассчитать Vy

calculateVy()

Переменные:

Счётчики

i, j, k

Начальная координата x

x0

Начальная координата y

y0

Начальная высота

eta0

Вспомогательные массивы

a, b, c, f, d, e

Тестовая схема

test

3.7.2 Реализация на языке С/С++ программы

Gредставлена реализация алгоритма на языке C/C++.

Реализация явной схемы на языке C/C++

#include <stdlib.h>

#include <stdio.h>

#include <math.h>

const double g = 9.8;

class Scheme{

protected:

double *** u; // Массив значений u

double *** v; // Массив значений v

double *** eta; // Массив значений eta

double ** etaTemp; // Массив вспомогательных значений eta

double H; // Глубина бассейна

int t_num; // Кол-во моментов времени

int x_num; // Кол-во точек на оси X

double dt; // Шаг по времени (секунды)

double dx; // Шаг по оси (метры)

void outArray(char * name, double *** out_array){

FILE * fout = fopen(name, "w");

for(int i = 0; i < t_num; i++){

for(int j = 0; j < x_num; j++){

for(int k = 0; k < x_num; k++){

fprintf(fout, "%f\t", out_array[i][j][k]);

}

fprintf(fout, "\n");

}

fprintf(fout, "\n\n");

}

fclose(fout);

}

public:

virtual void setInitialConditions() = 0;

virtual void setBoundaryConditions(int n) = 0;

virtual void calculate() = 0;

Scheme(int N, int M, double Dx, double H_temp){

dx = Dx;

H = H_temp;

dt = dx/100;

t_num = N;

x_num = M;

u = new double**[t_num];

v = new double**[t_num];

eta = new double**[t_num];

for(int i = 0; i < t_num; i++){

u[i] = new double*[x_num];

v[i] = new double*[x_num];

eta[i] = new double*[x_num];

for(int j = 0; j < x_num; j++){

u[i][j] = new double[x_num];

v[i][j] = new double[x_num];

eta[i][j] = new double[x_num];

}

}

etaTemp = new double*[x_num];

for(int i = 0; i < x_num; i++){

etaTemp[i] = new double[x_num];

}

}

Scheme() {}

~Scheme(){

for(int i = 0; i < t_num; i++){

for(int j = 0; j < x_num; j++){

delete[] u[i][j];

delete[] v[i][j];

delete[] eta[i][j];

}

delete[] u[i];

delete[] v[i];

delete[] eta[i];

}

delete[] u;

delete[] v;

delete[] eta;

for(int i = 0; i < x_num; i++){

delete[] etaTemp[i];

}

delete[] etaTemp;

}

void clear(){

for(int i = 0; i < t_num; i++){

for(int j = 0; j < x_num; j++){

for(int k = 0; k < x_num; k++){

eta[i][j][k] = 0.0;

u[i][j][k] = 0.0;

v[i][j][k] = 0.0;

}

}

}

for(int j = 0; j < x_num; j++){

for(int k = 0; k < x_num; k++){

etaTemp[j][k] = 0.0;

}

}

}

void ouput(){

FILE * foutConfig = fopen("config.txt", "w");

fprintf(foutConfig, "%d\n%lf\n", x_num, dx);

fprintf(foutConfig, "%d\n%lf\n", t_num, dt);

fclose(foutConfig);

outArray("eta.txt", eta);

}

};

class SchemeN: public Scheme {

double * a;

double * b;

double * c;

double * f;

double * u_temp;

double * v_temp;

double * d;

double * e;

public:

virtual void setInitialConditions(){

int x0 = x_num/2;

int y0 = x_num/2;

double eta0 = 1.0;

double a = 0.2;

for(int i = 0; i < x_num; i++){

for(int j = 0; j < x_num; j++){

v[0][i][j] = 0.0;

u[0][i][j] = 0.0;

//eta[0][i][j] = H + eta0*exp( - a*a*((dx*i-x0)*(dx*i-x0) + (dx*j-y0)*(dx*j-y0)));

eta[0][i][j]= exp(-dx*(i-x0)*3*dx*(i-x0)-dx*(j-y0)*dx*3*(j-y0));

eta[1][i][j] = eta[0][i][j];

}

}

}

virtual void setBoundaryConditions(int n){

for(int i = 1; i < x_num-1; i++){

eta[n][0][i] = 2*eta[n][1][i] - eta[n][2][i];

eta[n][x_num-1][i] = 2*eta[n][x_num-2][i] - eta[n][x_num-3][i];

eta[n][i][0] = 2*eta[n][i][1] - eta[n][i][2];

eta[n][i][x_num-1] = 2*eta[n][i][x_num-2] - eta[n][i][x_num-3];

u[n][0][i] = 2*u[n][1][i] - u[n][2][i];

u[n][x_num-1][i] = 2*u[n][x_num-2][i] - u[n][x_num-3][i];

u[n][i][0] = 2*u[n][i][1] - u[n][i][2];

u[n][i][x_num-1] = 2*u[n][i][x_num-2] - u[n][i][x_num-3];

v[n][0][i] = 2*v[n][1][i] - v[n][2][i];

v[n][x_num-1][i] = 2*v[n][x_num-2][i] - v[n][x_num-3][i];

v[n][i][0] = 2*v[n][i][1] - v[n][i][2];

v[n][i][x_num-1] = 2*v[n][i][x_num-2] - v[n][i][x_num-3];

}

eta[n][0][0] = 2*eta[n][1][0] - eta[n][2][0];

eta[n][x_num-1][0] = 2*eta[n][x_num-1][1] - eta[n][x_num-1][2];

eta[n][0][x_num-1] = 2*eta[n][1][x_num-1] - eta[n][2][x_num-1];

eta[n][x_num-1][x_num-1] = 2*eta[n][x_num-1][x_num-2] - eta[n][x_num-1][x_num-3];

u[n][0][0] = 2*u[n][1][0] - u[n][2][0];

u[n][x_num-1][0] = 2*u[n][x_num-1][1] - u[n][x_num-1][2];

u[n][0][x_num-1] = 2*u[n][1][x_num-1] - u[n][2][x_num-1];

u[n][x_num-1][x_num-1] = 2*u[n][x_num-1][x_num-2] - u[n][x_num-1][x_num-3];

v[n][0][0] = 2*v[n][1][0] - v[n][2][0];

v[n][x_num-1][0] = 2*v[n][x_num-1][1] - v[n][x_num-1][2];

v[n][0][x_num-1] = 2*v[n][1][x_num-1] - v[n][2][x_num-1];

v[n][x_num-1][x_num-1] = 2*v[n][x_num-1][x_num-2] - v[n][x_num-1][x_num-3];

}

void solveMatrix(double * a, double * b, double *c, double * f, double * x){

d[1] = -b[0]/c[0];

e[1] = f[0]/c[0];

for(int i = 1; i < x_num-1; ++i) {

d[i+1] = -b[i] / (a[i]*d[i]+c[i]);

e[i+1] = (f[i] - a[i]*e[i]) / (c[i]+a[i]*d[i]);

}

x[x_num-1] = (f[x_num-1] - a[x_num-1]*e[x_num-1]) / (c[x_num-1]+a[x_num-1]*d[x_num-1]);

for(int i = x_num-2; i > 0; --i) {

x[i] = d[i+1]*x[i+1]+e[i+1];

}

}

void prepareEtaTemp(int n){

for(int i = 1; i < x_num-1; i++){

for(int j = 1; j < x_num-1; j++){

etaTemp[i][j] = eta[n][i][j] - dt*((H + eta[n][i][j])*(u[n][i+1][j] - u[n][i-1][j])/(2.0*dx)

+ (H + eta[n][i][j])*(v[n][i][j+1] - u[n][i][j-1])/(2.0*dx)

+ u[n][i][j]*(eta[n][i+1][j] - eta[n][i-1][j])/(2.0*dx));

}

}

}

void calculateEta(int n){

for(int i = 1; i < x_num-1; i++){

for(int j = 1; j < x_num-1; j++){

eta[n+1][i][j] = eta[n][i][j] - dt*((H + eta[n][i][j])*(u[n+1][i+1][j] - u[n+1][i-1][j] + u[n][i+1][j] - u[n][i-1][j])/dx

+ (H + eta[n][i][j])*(v[n+1][i][j+1] - v[n+1][i][j-1] + v[n][i][j+1] - v[n][i][j-1])/dx

+ ((v[n+1][i][j] + v[n][i][j])/2.0)*((eta[n][i][j] - eta[n][i][j-1])/(2*dx)));

}

}

}

void calculateVx(int n){

for(int j = 1; j < x_num-1; j++){

a[0] = a[x_num-1] = 0;

b[0] = b[x_num-1] = 0;

c[0] = c[x_num-1] = 1;

for(int i = 0; i < x_num; i++) {

v_temp[i] = v[n][i][j];

}

f[0] = v_temp[0];

f[x_num-1] = v_temp[x_num-1];

for(int i = 1; i < x_num-1; i++) {

a[i] = -u[n][i][j]/(4.0*dx);

c[i] = 1.0/dt;

b[i] = u[n][i][j]/(4.0*dx);

f[i] = -v[n][i][j]/(4.0*dx)*v[n+1][i][j+1] + v[n][i][j]/(4.0*dx)*v[n+1][i][j-1]

+ v[n][i][j]/dt-u[n][i][j]*(v[n][i+1][j] - v[n][i-1][j])/(4.0*dx)

- v[n][i][j]*(v[n][i][j+1] - v[n][i][j-1])/(4.0*dx)

- g*(etaTemp[i][j+1] - etaTemp[i][j-1] + eta[n][i][j+1] - eta[n][i][j-1])/(4.0*dx);

}

solveMatrix(a, b, c, f, v_temp);

for(int i = 0; i < x_num; i++) {

v[n+1][i][j] = v_temp[i];

}

}

}

void calculateVy(int n){

for(int i = 1; i < x_num-1; i++){

a[0] = a[x_num-1] = 0;

b[0] = b[x_num-1] = 0;

c[0] = c[x_num-1] = 1;

for(int j = 0; j < x_num; j++) {

v_temp[j] = v[n][i][j];

}

f[0] = v_temp[0];

f[x_num-1] = v_temp[x_num-1];

for(int j = 1; j < x_num-1; j++) {

a[j] = -v[n][i][j]/(4.0*dx);

c[j] = 1.0/dt;

b[j] = v[n][i][j]/(4.0*dx);

f[j] = (-v[n][i][j]/(4.0*dx))*v[n+1][i+1][j] + (u[n][i][j]/(4.0*dx))*v[n+1][i-1][j]

+ v[n][i][j]/dt - u[n][i][j]*(v[n][i+1][j]-v[n][i-1][j])/(4.0*dx)

- v[n][i][j]*(v[n][i][j+1] - v[n][i][j-1])/(4.0*dx)

- g*(etaTemp[i][j+1] - etaTemp[i][j-1] + eta[n][i][j+1] - eta[n][i][j-1])/(4.0*dx);

}

solveMatrix(a, b, c, f, v_temp);

for(int j = 0; j < x_num; j++) {

v[n+1][i][j] = v_temp[j];

}

}

}

void calculateUx(int n){

for(int j = 1; j < x_num-1; j++){

a[0] = a[x_num-1] = 0;

b[0] = b[x_num-1] = 0;

c[0] = c[x_num-1] = 1;

for(int i = 0; i < x_num; i++) {

u_temp[i] = u[n][i][j];

}

f[0] = u_temp[0];

f[x_num-1] = u_temp[x_num-1];

for(int i = 1; i < x_num-1; i++) {

a[i] = -u[n][i][j]/(4.0*dx);

c[i] = 1.0/dt;

b[i] = u[n][i][j]/(4.0*dx);

f[i] = (-v[n][i][j]/(4.0*dx))*u[n+1][i][j+1] + (v[n][i][j]/(4.0*dx))*u[n+1][i][j-1]

+ u[n][i][j]/dt - u[n][i][j]*(u[n][i+1][j] - u[n][i-1][j])/(4.0*dx)

- v[n][i][j]*(u[n][i][j+1] - u[n][i][j-1])/(4.0*dx)

- g*(etaTemp[i+1][j] - etaTemp[i-1][j] + eta[n][i+1][j] - eta[n][i-1][j])/(4.0*dx);

}

solveMatrix(a, b, c, f, u_temp);

for(int i = 0; i < x_num; i++) {

u[n+1][i][j] = u_temp[i];

}

}

}

void calculateUy(int n){

for(int i = 1; i < x_num-1; i++){

a[0] = a[x_num-1] = 0;

b[0] = b[x_num-1] = 0;

c[0] = c[x_num-1] = 1;

for(int j = 0; j < x_num; j++) {

u_temp[j] = u[n][i][j];

}

f[0] = u_temp[0];

f[x_num-1] = u_temp[x_num-1];

for(int j = 1; j < x_num-1; j++) {

a[j] = -v[n][i][j]/(4.0*dx);

c[j] = 1.0/dt;

b[j] = v[n][i][j]/(4.0*dx);

f[j] = (-u[n][i][j]/(4.0*dx))*u[n+1][i+1][j] + (u[n][i][j]/(4.0*dx))*u[n+1][i-1][j]

+ u[n][i][j]/dt - u[n][i][j]*(u[n][i+1][j] - u[n][i-1][j])/(4.0*dx)

- v[n][i][j]*(u[n][i][j+1] - u[n][i][j-1])/(4.0*dx)

- g*(etaTemp[i+1][j] - etaTemp[i-1][j] + eta[n][i+1][j] - eta[n][i-1][j])/(4.0*dx);

}

solveMatrix(a, b, c, f, u_temp);

for(int j = 0; j < x_num; j++) {

u[n+1][i][j] = u_temp[j];

}

}

}

virtual void calculate(){

for(int i = 0; i < t_num-1; i++){

prepareEtaTemp(i);

calculateVx(i);

calculateUx(i);

calculateVy(i);

calculateUy(i);

calculateEta(i);

setBoundaryConditions(i);

}

}

SchemeN(int N, int M, double Dx, double H_temp){

dx = Dx;

H = H_temp;

dt = dx/100;

t_num = N;

x_num = M;

u = new double**[t_num];

v = new double**[t_num];

eta = new double**[t_num];

for(int i = 0; i < t_num; i++){

u[i] = new double*[x_num];

v[i] = new double*[x_num];

eta[i] = new double*[x_num];

for(int j = 0; j < x_num; j++){

u[i][j] = new double[x_num];

v[i][j] = new double[x_num];

eta[i][j] = new double[x_num];

}

}

etaTemp = new double*[x_num];

for(int i = 0; i < x_num; i++){

etaTemp[i] = new double[x_num];

}

d = new double[x_num];

e = new double[x_num];

a = new double[x_num];

b = new double[x_num];

c = new double[x_num];

f = new double[x_num];

u_temp = new double[x_num];

v_temp = new double[x_num];

}

};

int main(){

SchemeN test(200, 50, 0.1, 1.0);

test.clear();

test.setInitialConditions();

test.calculate();

test.ouput();

system("pause");

return 1;

}

3.7.3 Исходный код программы для вывода в среде MATLAB

Представлен исходный код программы для вывода в среде MATLAB.

код программа дифференциальный уравнение

Исходный код программы для вывода в среде MATLAB

clear;

load config.txt;

dx = config(2);

dt = config(4);

x = 0:dx:(config(1)-1)*dx;

y = x;

num = config(3);

M = moviein(num);

n = 1;

load eta.txt;

xmin = 0;

xmax = dx*(config(1)-1);

for r = 1:num

z = eta(n:n+config(1)-1,:);

mesh(x,y,z);

axis([0 xmax 0 xmax -0 2]);

xlabel('x');

ylabel('y');

zlabel('z');

M(:,r) = getframe;

n = n+config(1);

end

repeat = 0;

fps = 10;

movie(M, repeat, fps);

3.8 Тестовые примеры для программы, реализующей явную схему

Программа реализованная на C/C++ в качестве выходных данных имеет 2 файла: config.txt - содержащий информацию о расчётной сетке и u.txt - содержащую распределение температур. Примеры выходных данных можно посмотреть в прикреплённых файлах.

На рисунках 12 - 13 изображены результаты работы программы строящей графики в среде MATLAB в разные моменты времени.

Рисунок 12 - состояние волны в начальный момент времени

Рисунок 13 - состояние волны в момент времени t = 0.2с

Рисунок 14 - состояние волны в момент времени t=0.5с

Рисунок 15 - состояние волны в момент времени t=0.75c

Рисунок 16 - состояние волны в момент времени t=1c.

Рисунок 17 - состояние волны в момент времени t=2c.

4. Заключение

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

Например, моделирование волн цунами, позволяет прогнозировать распространение волн в мировом океане, а следовательно, избежать разрушений и жертв среди мирного населения.

Основной сложностью является подбор корректных начальных и краевых условий.

Никогда не стоит забывать о верно подобранных параметрах схемы, удовлетворяющих критерию устойчивости.

Единственная сложность, которую сейчас всё ещё трудно обойти - высокие требование к вычислительной машине. Требования к большому количеству оперативной памяти и нагрузки на процессор, но позволяют оперативно получать данные.

Размещено на Allbest.ru


Подобные документы

  • Создание программы, реализующей игру "Линии". Среда разработки программы, описание ее общего вида. Основные алгоритмы программы. Реализация программы в среде разработки Microsoft Visual Studio 2008 на языке объектно-ориентированного программирования С++.

    курсовая работа [639,0 K], добавлен 16.03.2012

  • Разработка программы на языке Turbo Pascal 7.0 для преобразования кинетической схемы протекания химических реакций при изотермических условиях в систему дифференциальных уравнений. Ее решение в численном виде методом Рунге-Кутта четвертого порядка.

    курсовая работа [929,7 K], добавлен 06.01.2013

  • Разработка программы игры в крестики-нолики. Примеры игровой ситуации на игровом поле. Описание входных и выходных данных, переменных и функций программы. Реализация алгоритма работы программы на языке C++. Текст программы и примеры ее выполнения.

    курсовая работа [352,8 K], добавлен 14.04.2011

  • Создание блок-схемы алгоритма и реализующей его программы, снабженных пояснениями, для решения задач. Реализация программы в среде Delphi как проекта консольного приложения. Основные алгоритмические структуры, соответствующие операторы для их реализации.

    контрольная работа [447,4 K], добавлен 08.10.2012

  • Составление программы на алгоритмическом языке Turbo Pascal. Разработка блок-схемы алгоритма её решения. Составление исходной Pascal-программы и реализация вычислений по составленной программе. Применение методов Рунге-Кутта и Рунге-Кутта-Мерсона.

    курсовая работа [385,0 K], добавлен 17.09.2009

  • Метод Гаусса-Зейделя как модификация метода Якоби, его сущность и применение. Разработка программы решения системы линейных алгебраических уравнений на языке VB, проверка правильности работы программы в MS Excel и математических пакетах MathCad и MatLab.

    курсовая работа [325,5 K], добавлен 27.10.2013

  • Основные сведения о языке программирования Pascal. Листинг программы с комментариями. Диагональ элементов вектора и матрицы. Использование команд ввода-вывода информации. Быстродействие выполнения программы при компиляции. Отражение процессов вычисления.

    курсовая работа [1,9 M], добавлен 05.05.2009

  • Решение дифференциальных уравнений с использованием классических алгоритмов численных методов Эйлера и Рунге-Кутта 4-го порядка. Команды, используемые при решении обыкновенных дифференциальных уравнений в системе вычислений. Результат работы программы.

    курсовая работа [226,6 K], добавлен 05.04.2013

  • Разработка и тестирование программы класса Точка. Спецификация программы. Сценарий диалога с пользователем. Разработка структур данных и алгоритмов. Таблица параметров функций программы. Текст программы на языке C++. Особенности тестирования программы.

    лабораторная работа [43,1 K], добавлен 21.07.2012

  • Создание программы для обработки информации об объектах предметной области "Бытовая техника" в среде визуального программирования C++. Иерархия родственных классов. Описание логической структуры программы. Реализация файлового ввода/вывода данных.

    курсовая работа [711,4 K], добавлен 27.07.2014

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.