OpenFOAM для чайников

от автора

Некоторое время назад, впрочем, и до сих пор, я искал описание операций, процессов, которые происходят в OpenFOAM. Да, много написано про метод конечных объёмов, классические разностные схемы, различные сложные физические модели. Мне же хотелось узнать детали — откуда в таком-то выходном файле на такой-то итерации получились эти значения, какие выражения стоят за теми или иными параметрами в файлах настроек fvSchemes, fvSolution?
Для тех, кому это тоже интересно — эта статья. Те, кто хорошо знаком с OpenFOAM или с методами в нём реализованными — пишите о найденных ошибках, если таковые имеются — лучше в личку.

В данной статье я на простом примере-задаче опишу операции, которые происходят в ходе расчёта в OpenFOAM.

Итак, дана геометрия — куб со стороной 1 метр:

Граничные условия следующие: вход, выход, остальные грани — гладкие стенки.


Построение сетки — делим куб на 5 равных частей вдоль оси Z.

Поведение потока задаётся уравнением переноса (1).

(1)
image,

где image выражает концентрацию некоторого вещества, а image выражает перенос вещества, поток.

Если читатель не знаком или забыл оператор дивергенции

оператор image.
Напомню, что существует оператор набла (оператор Гамильтона), который записывается следующим образом:
image,

где i, j, k — единичные векторы.
Если скалярно умножить оператор набла на векторную величину, то мы получим дивергенцию данного вектора:
image
«С точки зрения физики, дивергенция векторного поля является показателем того, в какой степени данная точка пространства является источником или стоком этого поля»

Если умножить оператор набла на скаляр, получается градиент этого скаляра:

image
Градиент показывает увеличение или уменьшение по какому-либо направлению величины скаляра image.

Разбиение по пространству

Метод конечных объёмов предусматривает, что (1) в интегральной форме (2) будет выполняться для каждого конечного объёма image.

(2)
image,

где image — центр конечного объёма.

Упростим, преобразуем первое слагаемое выражения (2) следующим образом:

(2.1) (HJ-3.12)*
image

image

image

Как видно — мы приняли, что значение величины image в некоторой точке image внутри конечного объёма можно вычислить как:

image,

где image

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

image,

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

Учитывая то, что конечный объём ограничен набором плоских граней, можно выражение (2.3) преобразовать к сумме интегралов по поверхности:

(2.4) (HJ-3.13)
image,

где image выражает значение переменной в центре грани,
image — вектор площади, выходит из центра грани, направлен от центра ячейки.

Вектор площади image указывает от центра image, если мы его рассматриваем относительно нашей ячейки (в OpenFOAM такое отношение между ячейкой и вектором image, а точнее между ячейкой и гранью, обозначается owner). Для соседних ячеек этот вектор image указывает внутрь (отношение neighbour). Направление влияет на знак величины и это важно при суммировании.

(HJ-3.16)
image

Численно image это площадь одной грани. А вот значение image выражается через значения image в других ячейках — способ такого выражения носит название разностной схемы. В нашей задаче в файле fvSchemes тип разностной схемы задан следующим образом:

divSchemes {     default         none;     div(phi,psi) Gauss linear; } 

Gauss — означает, что выбрана центральная разностная схема;
linear — означает, что интерполяция с центров ячеек на центры поверхностей будет происходить линейно.

Значение в центре грани будет вычисляться по следующей схеме:

(HJ-3.19)
image,

image

Учитывая (2.1) и (2.4) выражение (2) принимает вид:

(3)
image

Дискретизация по времени

Согласно методу конечных объёмов проводится дискретизация по времени и выражение (3) записывается как:

(4)
image

Проинтегрируем (4):

(4.1)
image

Разделим левую и правую часть на image:

(5)
image

Формирование матрицы дискретизации

Теперь мы можем получить систему линейных уравнений для каждого конечного объёма image.
Для P = 0 выражение (5) примет вид:

image

image

image

Для P=1:

image

image

image

Для P=4:

image

image

image

Так как на выходе задано граничное условие

outlet {     type		zeroGradient; } 

то получаем

image

Система линейных алгебраических уравнений (СЛАУ) может быть представлена в матричном виде как

image,

где

=== A(i,j) === 40.5 0.5 0 0 0  -0.5 40 0.5 0 0  0 -0.5 40 0.5 0  0 0 -0.5 40 0.5  0 0 0 -0.5 40.5  
=== b(i,j) === 1  0  0  0  0  

Далее полученная СЛАУ решается решателем, указанным в fvSchemes.
И в итоге получается вектор значений image

psi = dimensions      [0 0 0 0 0 0 0];  internalField   nonuniform List<scalar> 5(0.0246875 0.000308546 3.85622e-06 4.81954e-08 5.95005e-10); 

на основе которого получаются значения для вектора image

image

image

image

Затем вектор image подставляется в СЛАУ image и происходит новая итерация расчёта вектора image.

И так до тех пор, пока невязка не достигнет требуемых пределов.

Ссылки

* Некоторые уравнения в этой статье взяты из диссертации Ясака Хрвое (HJ — номер уравнения) и если кому-то захочется прочитать про них подробнее (http://powerlab.fsb.hr/ped/kturbo/OpenFOAM/docs/HrvojeJasakPhD.pdf)

Скачать файлы задачи можно здесь:
github.com/j-avdeev/case
Файлы решателя:
github.com/j-avdeev/matrHyper1Foam

В качестве бонуса — видео, как распространяется концентрация image.

ссылка на оригинал статьи http://habrahabr.ru/post/218483/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *