Вы находитесь на странице: 1из 54

Санкт-Петербургский Политехнический Университет Петра Великого

Физико-механический институт
Высшая школа прикладной математики и вычислительной физики

Курсовая работа по курсу


«Вычислительная гидродинамика и теплофизика»
Расчет пространственных дифференциальных операторов по
методу конечных объемов

Выполнил
студент гр. 5040301/10201 Ле Мань Дат ___________

Проверил Колесник Е.В. ___________

«___» __________ 2021 г.

Санкт-Петербург
2021
Оглавление

1. Краткая характеристика используемого подхода (МКО)................................3

2.Описание расчета геометрических характеристик (центры граней, вектора


граней, центры ячеек, объемы ячеек)....................................................................4

3. Описание численных алгоритмов расчета пространственных


дифференциальных операторов, включая детали расчета для граничных ячеек
и способы введения различных поправок.............................................................7

4. Описание реализованной программы и ее блок схема..................................18

5. Результаты исследований реализованных методов расчета


пространственных дифференциальных операторов..........................................18

6. Заключение........................................................................................................40

7. Код в Fortran.......................................................................................................41

Список литературы...............................................................................................54

2
1. Краткая характеристика используемого подхода (МКО)

МКО - численный метод интегрирования систем дифференциальных


уравнений в частных производных. Как видно из названия, метод
основывается и работает с замкнутыми объемами пространства. Поэтому
дифференциальные уравнения необходимо привести в нужную форму.
Основные положения МКО удобно излагать, рассматривая
«стандартное» уравнение баланса некой величины φ в контрольном объеме
Ω, ограниченном поверхностью S = ∑Sk с внешней нормалью n⃗ :

∂ ρφ
∫ ∂t
ⅆΩ+ ∑ ∫ ⃗n ∙ ⃗q ⅆs=∫ QⅆΩ ( 1.1 ) ,
k S
Ω k Ω

q⃗ =ρ ⃗
V ϕ−α ∇ φ (1.1)

Здесь q⃗ – вектор плотности потока величины φ, включающий


конвективную и диффузионную составляющие, Q – плотность распределения
объемных источников, ⃗
V – вектор скорости, ρ – плотность среды, α –
коэффициент диффузии.
В качестве φ может фигурировать, например, внутренняя энергия
текущей среды, концентрация примеси, кинетическая энергия
турбулентности и т. д. В пределе, при стягивании объема в точку, можно на
основании формулы Остроградского-Гаусса переписать это уравнение в
дифференциальной форме: ∂ ρφ ∕ ∂ t+ ∇ ⋅ q⃗ =Q Отметим, что последняя, в силу
более частого использования в литературе, иногда считается первичной, а
интегральная формулировка закона сохранения (1.1) «выводится» из
дифференциальной путем интегрирования по объему. Согласно МКО
пространственная дискретизация задачи осуществляется путем разбиения
расчетной области на небольшие соприкасающиеся объемы, для каждого из
которых записывается балансовое соотношение (1.1). Внутри каждого

3
контрольного объема находится одна (и только одна) точка «привязки»
искомого сеточного решения. В большинстве разработок, ориентированных
на решение трехмерных задач для областей сложной геометрии, в качестве
контрольного объема используются ячейки расчетной сетки: узлы сетки
располагаются в вершинах многогранника (для структурированных сеток –
гексаэдра, см. рис.1), сеточные линии идут вдоль его ребер, а значения
искомых величин приписываются геометрическому центру ячейки. [Error:
Reference source not found]

Рис.1. Структурированная сетка контрольных объемов с «привязкой»


переменных к центру ячеек: •– узел сетки, … – центр ячейки, – ° центр грани.

2.Описание расчета геометрических характеристик (центры


граней, вектора граней, центры ячеек, объемы ячеек)

Теперь рассмотрим подробнее как вычисляются геометрические


характеристики. Как уже было сказано геометрическими характеристиками
являются P – центр ячейки (⃗r p – радиус-вектор, определяющий положение
центра объема ячейки), f – центр грани (⃗ r f – радиус-вектор, определяющий
положение центр грани), площадь грани Sf и объем ячейки Ω . Все нормали к
граням ячейки должны быть направленны в одну сторону (будем считать
нормаль внешняя).

4
Рис. 2 Ячейка разностной сетки.

Для начала введем такое понятие как вектор площади грани ⃗


Sf . Это
внешняя нормаль грани, умноженная на площадь грани:


Sf =⃗
n f ⋅S f

Для вычисления вектора площади грани произвольной ячейки


используется следующая формула:

N
1
Sf =∑ ( r⃗ i +1−⃗r o ) × ( ⃗r i−⃗r o )

i=1 2

Где r⃗i – радиус-вектор i-го узла грани, “o” – произвольная точка,


которая часто строится как среднее арифметическое координат узлов грани.
При вычислении положения центра грани как центра тяжести каркаса
для произвольной ячейки применяется формула:

→ ∑ 12 ( r⃗i +⃗
r i+1 ) li , i+1
r f = i=1 N
,
∑ li ,i+1
i=1

где li ,i +1 – длина ребра грани, построенная по узлам i и i+1.


Объем будет складываться из объемов пирамидок, на которые был
разбит объем:

1⃗
Ω=∑ S ×( ⃗ ro )
r f −⃗
f 3 f
Для вычисления центра объема (ячейки):

5
∑ r f|S f|
→ →


f
r p=
∑ |S f|

В рамках курсовой работы (двухмерный случай) внешнюю нормаль в


формуле ⃗
Sf можно получить с помощью поворота векторов на 90 градусов с
помощью умножения матрицы поворота на вектор:

( )
π π
cos sin
2 2
π π
- для поворота по часовой стрелке,
−sin cos
2 2

( )
π π T
cos sin
2 2
π π - для поворота против часовой стрелки.
−sin cos
2 2


Центры граней r f находятся как полсуммы координат узлов этой
грани:

1
r fi = ( x ( i , j )+ x ( i+1 , j ) ) ,
2

1
r fj = ( y (i , j)+ y (i, j+1))
2
Для вычисления объема ячейки представим ее в виде двух
треугольников и объем ячейки будем вычислять как сумму этих
треугольников. Воспользуемся следующей формулой:

→ → → →
Sf ⋅ r + Sf ⋅ r
Ω= i j
,
2

S f - вектор площади грани в направлении i,
i


S f - вектор площади грани в направлении j,
j

→ → →
r =r i+1 , j+1−r i , j - диагональ.
Центр объема произвольной ячейки вычисляется как центр тяжести
этой ячейки:

∑⃗
r Ω f Ωf
f
r p=

Ω

6
где ⃗
r Ωf – положение центра тяжести объема, построенного на грани f;
Ω f – объем пирамиды, опирающейся на грань f.
На границах достраиваем граничные ячейки. Значением центра
граничной ячейки будет значение в центре грани ячейки, для которой она
была построена.

3. Описание численных алгоритмов расчета пространственных


дифференциальных операторов, включая детали расчета для граничных
ячеек и способы введения различных поправок

3.1 Расчет градиента скалярного поля

Рассмотрим вычисление градиента по методу МКО. Допустим у нас


есть градиент величины ∇ φ. Для вычисления градиента по всему объему
запишем интеграл:

∫ ∇ φ dΩ (3.1)
Ω

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


теоремой Гаусса-Остроградского:

∫ ∇ φ dΩ=∫ ⃗n φ dσ (3.2)
Ω σ

Теперь мы имеем объем, который ограничен поверхностью.


Поверхность в свою очередь состоит из граней. Проведем дискретизацию и
перейдем к сумме по граням:

∫ ⃗n φ dσ=∑ ∫ ⃗nf φ d S f (3.3)


σ f Sf

Применяем к правой части теорему о среднем и перейдем к сумме


произведения нормали, площади грани и значения функции на грани:
7
∑ ∫ ⃗nf φ d S f =∑ n⃗ f φ f S f (3.4)
f Sf f

И воспользуемся ранее введенным обозначением и запишем формулу


через вектор грани:

∑ ⃗nf φ f S f =∑ φ f ⃗S f (3.5)
f f

Таким образом осталось определить значение функции на грани. Это


значение находится с помощью линейной интерполяции:

φ f =β φ p+(1−β ) φN ,

где φ p , φ N - значение величины в центре текущей ячейки Р и значение в


соседней ячейке N, для которой грань f является общей. Коэффициент
линейной интерполяции β определяется следующим образом:

|⃗
fN|
β=
|⃗
fP|+|⃗
fN |

Левая часть уравнения (3.2) по теореме о среднем преобразуется


следующим образом:

∫ ∇ φ dΩ=¿ (3.6)
Ω

Получаем формулу для вычисления градиента.


¿ (3.7)

Такой способ нахождения градиента называется методом Грина-


Гаусса. Он хорошо работает для ортогональных не скошенных ячеек. Если

8
ячейки скошены, то этот метод дает сильную погрешность. Что бы этого
избежать используют метод Грина-Гаусса с итерациями.

Рис.3 Скошенная ячейка

Когда на скошенной ячейке мы пытаемся определить значение


величины на грани с помощью линейной интерполяции, то получаем
значение в точке M, а не в f. Поэтому необходимо ввести некоторую
поправку. Допустим мы возьмем некоторое приближение величины в точке f,
относительно M. Разложим в ряд Тейлора первого порядка:

φ f =φ M +¿

Теперь нужно определить саму величину и градиент в точке М. Для


этого опять используем формулу линейной интерполяции через известные
величины в точках Р и N:

φ M =β φ P +(1−β)φ N

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


при учете скошенности ячейки, зависит сам от себя. Образуется
итерационный процесс:

9
¿

На первом шаге значение градиента считается по «неправильному»


значению через линейную интерполяцию. Но начиная со второго шага
вводится поправка.

3.2 Расчет дивергенции

Для начала можно вычислить дивергенцию от поля скорости.


Действуем по аналогии с градиентом. Запишем уравнение, где левую часть
сразу представим в виде интеграла по поверхности:

∫ ∇ ⋅( V⃗ )dΩ=∫ n⃗ ⋅( ⃗V )dσ
Ω σ

Затем перейдем к суммированию по всем граням и применяем


теорему о среднем:

∫ ⃗n ⋅(⃗V )dσ =∑ (⃗
V f ) ⋅ ⃗S f
σ f

Преобразуем правую часть первого уравнения и запишем


окончательную формулу для вычисления дивергенции скорости:

где ⃗
V f вычисляется методом линейной интерполяцией.

Центральная схема
Получим формулу для вычисления дивергенции произведения
скалярного поля давления на векторное поле скорости - p ⃗
V , по методу

конечных объемов. Согласно теореме Остроградского-Гаусса, имеем:

10
∫ ∇ ⋅( p ⃗V )dΩ=∫ ⃗n ⋅( p ⃗V )dσ (3.8)
Ω σ

Перейдем от интеграла по поверхности ячейки к сумме интегралов по


поверхности грани, применяя теорему о среднем:

∫ ⃗n ⋅ ( p V⃗ ) dσ =∑ ( p f ⃗
V f )⋅ ⃗S f
σ f

К интегралу в правой части уравнения (3.8) также применяем теорему


о среднем и получим:


Величина V на грани находится с помощью линейной интерполяции:


V f =β ⃗
V p+ ( 1−β ) ⃗
VN

Величина p на грани при использовании центральной схемы также


находится путем линейной интерполяции:
pf =β p p+(1−β ) p N

First OU
Для нахождения значения pf по схеме First Oder Upwind используем
следующее условие:

pf =
{
¿ p P , если⃗
V
⋅ ⃗S f ≥ 0
¿ p N , если⃗ ⋅ S
f

⃗f <0
Vf
}

11
Для вычисления величины p на внутренних гранях имеем P P. Если
грань внешняя, то строим противопоточную схему на границе. Предполагая
линейность изменения величины p, для граничных граней имеем при ⃗
V f ⋅ ⃗S f <0 :

Pf =P N =2 Pb−P P ,

где Pb - значение в центре грани f граничной ячейки.

Рис. 4 Граничная ячейка


Second OU
Противопоточная схема второго порядка точности для внутренних
граней получается в случае, если использовать градиент этой величины.
Экстраполируем значение переносимой величины из центра ячейки на грань
по формуле:

где r⃗ −¿вектор от центра грани к центру соответствующей ячейки.

Рис. 5 Интерполяция давления на центр грани со вторым порядком

Для определения величины на границе необходимо узнать значение


градиента в центе соседней ячейки. Пусть расстояние от точки Р до грани

12
обозначим d. Тогда X - произведение градиента на радиус вектор в точке d/2
будет вычисляться как:

X b/ 2=P p−P B

Учитывая это составляем систему:

{
3
¿ X N = X b/ 2 + dX
2
¿ X N =X P+ 2 dX

Получаем:

X N =4 X b /2−3 X p

Следовательно, для граничных ячеек в случае, когда ⃗


V f ⋅ ⃗S f <0 :

Pf =P N +4 (P P−Pb )−3 ¿

3.3 Расчет лапласиана скалярного поля

Получим формулу для вычисления лапласиана скалярного поля φ по


методу конечных объемов. Под величиной φ будем понимать поле давления.
Согласно теореме Остроградского-Гаусса, имеем:

∫ ∇ ⋅ ( ∇ φ ) dΩ=∫ ⃗n ( ∇ φ ) dσ
Ω σ

Заменяя интеграл по поверхности ячейки из (20) суммой интегралов


по граням и применяя теорему о среднем, имеем:

13
∫ ⃗n ( ∇ φ ) dσ =∑ ( ∂∂ φn ) Sf
σ f f

Здесь следует отметить, что Sf это не вектор, а скаляр, площадь грани.

Применяя теорему о среднем к правой части уравнения (20), получим


формулу для вычисления лапласиана:

Получили формулу, где осталось определить производную ∂ n (∂φ) f

Производная на грани находится следующим образом:

( )
∂φ φ N −φ P
=
∂ n f |⃗ PN |

Внутри области такая аппроксимация дает второй порядок точности,


а на границах – первый. Для получения второго порядка аппроксимации
производной на границах в случае равномерной сетки необходимо
достраивать фиктивную ячейку N:
N, P, B – центры приграничной, граничной ячеек и центр грани
граничной ячейки, соответственно.
d – шаг сетки.

Рис.6 Аппроксимация производной на граничных гранях

14
( φ P + φN )
−φ B
( )
∂φ
∂n p
=
2
d

( ∂∂ φn ) = 9( φ −φ 3)−(φ
B
P B
d
−φ )
N P

( ∂∂ φn ) = 53 (φ d−φ/2 )− 23 ( ∂∂nφ )
B
B P

При работе на неортогональных сетках возникает большая ошибка.


Следовательно, необходимо ввести поправку для не ортогональности ячеек с
помощью гибридного подхода:
где ζ – вектор, соединяющий центры соседних ячеек.

Рис.7 Аппроксимация производной в случае скошенной сетки

На рис.7 представлен пример неортогональных ячеек. Видно, что


нормаль не совпадает с направлением вектора центров ячеек Р и N. Поэтому
производная функции давления вдоль оси ξ записывается следующим
образом:

∂ φ φ N −φP
=
∂ξ |⃗
PN|

Необходимо найти производную функции давления по нормали.


Запишем:

15
∂φ
=( ∇ φ ) M ⋅ ξ⃗ = ( ∇ φ )M ⃗n +( ⃗ξ −⃗n ) ( ∇ φ ) M
∂ξ

Следовательно, можем записать значение производной давления по


нормали. Таким образом имеем:

∂ φ φ N −φP
= + ( n⃗ −ξ⃗ ) ( ∇ φ )M ,
∂n |⃗
PN|

где:

( ∇ φ ) M =β ¿

В случае расчёта на граничной ячейке, значение по нормали на


граничной грани получается из разложения в ряд Тейлора относительно
точки b при аппроксимации значений в точке Р и N (центре фиктивной
ячейки):

( ∂∂φn ) = 9(φ −φ3 |)−(φ 3 ( |⃗


Pb| ) 3
P B −φ ) 5 (φ −φ )
N B 2 P B
= − ¿
B ⃗Pb| f
2

где n⃗¿ =−⃗n


3.4 Расчет ротора векторного поля от вектора скорости

От интеграла ротора вектора скорости по объему переходим к


интегралу по поверхности с помощью формулы Остроградского - Гаусса:

∫ ∇ × V⃗ dΩ=∫ ⃗n × ⃗V dσ
Ω σ

Затем преобразуем правую часть


16
1
∇×⃗
V= ∫ ⃗n × ⃗V dσ
Ω σ

Перейдем к суммированию по граням и запишем формулу через


вектор грани:

1 1
∑ ∫
Ω f S
V S f = ∑ ⃗S f × ⃗
n⃗ f × ⃗
Ω f
Vf
f

Векторное произведение вычислим через определитель:

| |
i j k

S x S y S z =⃗S x ⃗
⃗ ⃗ V y − ⃗S y ⃗
Vx

Vx V⃗y V⃗z

Так как задача двумерная, берется только z-компонента вихря.


Получаем формулу вычисления ротора:

1
∇× ⃗
V= ∑ ⃗S V⃗ − ⃗S ⃗V
Ω f x y y x

4. Описание реализованной программы и ее блок схема

Программа была написана на языке Fortran с помощью среды Cygwin.


Программа состоит из нескольких основных блоков:
• главный, который взаимодействует с остальными,
• блок вычисления геометрических характеристик,
• блок, содержащий в себе функции полей скорости, давления и
аналитическое решение,
• блок вывода данных,

17
• блоки для вычисления пространственных операторов.
В главном блоке так же осуществляется чтение сетки и полей
скорости и давления, которые были получены с помощью программы Flos.

5. Результаты исследований реализованных методов расчета


пространственных дифференциальных операторов

5.1 Определение наибольшей степени полинома, для которой


метод дает точное решение

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

Максимальная
погрешность на
Функция, P Точное значение
границах (внутри
области)
x+y GradPx, GradPy= 1 (5.12599945E-06)
0.250087798
x2 + у2 GradPx = 2х, GradPy = 2у
(3.17891427E-05)
1.33570647
x3 + у3 GradPx = 3х2, GradPy = 3у2
(0.148161694)

18
A) GradPerrorX Б) GradPerrorY
Рис 8. Расчетное поле погрешности градиента для функции P(x,y)=x+y

A) GradPerrorX Б) GradPerrorY
Рис 9. Расчетное поле погрешности градиента для функции P(x,y)=x2+y2

A) GradPerrorX Б) GradPerrorY
Рис 10. Расчетное поле погрешности градиента для функции P(x,y)=x3+y3
Дивергенция скорости
Для дивергенции от поля скорости машинная точность достигается
для полинома первой степени. Для полинома второй машинная точность

19
теряется на границах. Для полинома третьей степеней машинная точность не
достигается во всех областях.
Максимальная
погрешность на
Функция, V Точное значение
границах (внутри
области)
Vx = 1+x, Vy = 1+y 2 (5.12599945E-06)
0.249968827
Vx = 1+x2, Vy = 1+y2 2x + 2y
(1.04308128E-05)
1.33332253
Vx = 1+x3, Vy = 1+y3 3(x2+ y2)
(0.148117751)

Рис 11. Расчетное поле погрешности дивергенции для полинома первой


степени

Рис 12. Расчетное поле погрешности дивергенции для полинома второй


степени

20
Рис 13. Расчетное поле погрешности дивергенции для полинома треьтей
степени
Дивергенция функции PV
Для дивергенции от поля скорости-давления рассматривалось три
случая: центральная схема, противопоточная схема первого порядка и
противопоточная схема второго порядка. Для центральной схемы машинная
точность теряется начиная с полинома третьей степени. Для FOU для
полинома второй степени. И для противопоточной схемы второго порядка
для полинома третьей степени.
Максимальная
Максимальная Максимальная
погрешность
погрешность погрешность
Функция Точное схемы Сentral на
схемы FOU на схемы SOU на
, PV значение границах
границах (внутри границах (внутри
(внутри области)
области) области)
P=x+y
Vx = 1, 2 (4.52995300E-06) (4.35113907E-06) (5.48362732E-06)
Vy = 1
P=x+y
3(x + y) 2.32556798E-02
Vx =1+ x, (3.87935324E-06) (3.91687627E-06)
+2 (2.04082411E-02)
Vy = 1+y
P=x+y
3(x2+ y2) 4.07437002E-03 1.24932267E-02 4.07437002E-03
Vx = 1+x ,
2
+4xy+2 (1.21583324E-03) (1.05731534E-02) (1.21571729E-03)
Vy =1+ y2

21
A) по схеме Central

Б) по схеме FOU В) по схеме SOU


Рис 14. Расчетное поле погрешности дивергенции для полинома первой
степени

A) по схеме Central

22
Б) по схеме FOU В) по схеме SOU
Рис 15. Расчетное поле погрешности дивергенции для полинома второй
степени

A) по схеме Central

Б) по схеме FOU В) по схеме SOU


Рис 16. Расчетное поле погрешности дивергенции для полинома третьей
степени
Ротор
Погрешность ротора скорости на границах области достигает
значения машинной точности для полинома первой степени, машинная
23
точность теряется при полиноме выше степени. Внутри области машинная
точность достигается при полиноме первой и второй степеней.
Максимальная
погрешность на
Функция, V Точное значение
границах (внутри
области)
1.90734863E-06
Vx = 1-y, Vy = 1+x 2
(3.33786011E-06)
0.249999896
Vx = 1-y2, Vy = 1+x2 2x+2y
(6.25848816E-06)
1.33306849
Vx = 1-y3, Vy = 1+x3 3x2+3y2
(0.148139060)

Рис 17. Расчетное поле погрешности ротора для полинома первой степени

Рис 18. Расчетное поле погрешности ротора для полинома второй степени

24
Рис 19. Расчетное поле погрешности ротора для полинома третей степени
Лапласиан
Лапласиан от полинома первой степени обращается в ноль.
Рассмотрим полином второй степени. Здесь, машинная точность достигается.
Для полинома второй степени машинная точность теряется на границах но
достигается внутри ячейки. Для полинома больше степени машинная
точность теряется.

Максимальная
погрешность на
Функция, P Точное значение
границах (внутри
области)
Р = х2+у2 4 (7.36713409E-05)
0.333333194
Р = х3+у3 6(x+y)
(4.81605566E-05)
1.16666627
Р = х4+у4 12(x2+y2)
(7.40742236E-02)

25
Рис 20. Расчетное поле погрешности лапласиана для полинома второй
степени

Рис 21. Расчетное поле погрешности лапласиана для полинома третей


степени

Рис 22. Расчетное поле погрешности лапласиана для полинома четвертой


степени

26
5.2 Результаты расчета на исходной и измельченной сетках и
вычисление порядка точности метода

Порядок точности метода вычисляется по этой формуле:

log
( N2
N1
() err
err 2 )
1
,

где N 1 - размерность базовой сетки, N 2 - размерность измельченной сетки,


равные 20 и 60 узел соответственно. Рассчитав задачу необходимо взять
значение ошибки в одной и той же точке на базовой и измельченной сетках.
Подставив эти значения в логарифм, получим порядок точности метода.
Точка выбиралась в том месте, где значение погрешности было наибольшим.
Функция выбиралась такой, чтобы полученное решение не было вычислено с
машинной точностью.

Максимальная Погрешность в
погрешность на соответствующей Порядок
Оператор Функция
измельченной точке на базовой точности
сетке сетке
Grad(P)x
P= x2 + у2 2.73417E-02 0.14816 1.54 ≈ 2
(Grad(P)y)
Div(V) Vx = 1+x3, 1.52 ≈ 2
2.79971E-02 0.14812
Vy = 1+y3
P=x+y,
Div(PV),
Vx = 1+x2, 1.36555E-04 1.21583E-03 1.99 ≈ 2
central
Vy =1+ y2
P=x+y,
Div(PV),
Vx = 1+x2, 3.66006E-03 1.05732E-02 0.97 ≈ 1
FOU
Vy =1+ y2
P=x+y,
Div(PV),
Vx = 1+x2, 1.36555E-04 1.21572E-03 1.99 ≈ 2
SOU
Vy =1+ y2
Vx = 1-y3,
Rot(V) 2.76326E-02 0.14814 1.52 ≈ 2
Vy = 1+x3
LapP Р = х4+у4 1.36046363E-02 7.40742236E-02 1.54 ≈ 2

27
5.3 Расчет на сетке со скошенными и неортогональными
ячейками. Анализ распределения ошибки (для разных линейных и
нелинейных функций). Тестирование поправок на скошенность и
неортогональность

Рассчитаем поле погрешности градиента от функции P=x+y без


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

А) GradPerrorX Б) GradPerrorY
Рис 23. Поле погрешности градиента функции P=x+y без поправки на
скошенность.

С применением поправки на скошенность решение было получено


близко к решению с машинной точностью.

А) GradPerrorX Б) GradPerrorY
Рис 24. Поле погрешности градиента функции P=x+y с итерациями

28
Построим график зависимости погрешности градиента давления от
количества итераций метода Грина-Гаусса, полученный на скошенной сетке.
Из графика видно, что машинная точность достигается за 4 итераций и с
увеличением итераций остается неизменной.

Рис 25 График зависимости погрешности градиента давления от количества


итераций метода Грина-Гаусса, полученный на скошенной сетке

Для нелинейной функции погрешности больше. В зависимости от оси


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

29
А) GradPerrorX Б) GradPerrorY
Рис 26. Поле погрешности градиента от функции P=x2+y2 без итераций

А) GradPerrorX Б) GradPerrorY
Рис 27 Поле погрешности градиента от функции P=x2+y2 с итерациями

Рассчитаем дивергенции функции PV (линейная функция: P=x+y


,Vx= 1, Vy = 1; и нелинейная функция: P=x+y, Vx =1+ x, Vy = 1+y).

А) Линейная функция Б) Нелинейная функция


Рис 28. Поле погрешности дивергенции на скошенность (схема Central)

При применении схемы FOU погрешность на границе гораздо


больше, чем для схемы Central. Но среднее значение ошибки стало ниже.

30
А) Линейная функция Б) Нелинейная функция
Рис 29. Поле погрешности дивергенции на скошенность (схема FOU)
Применим схему со вторым порядком точности SOU. Видим, что
погрешность сильно уменьшилась.

А) Линейная функция Б) Нелинейная функция


Рис 30. Поле погрешности дивергенции на скошенность (схема SOU)

При всех схемах (схема Central и FOU) погрешность нелинейной


функции отказывают несколько меньше чем для линейной функции.
Рассчитаем поле ротора для линейной (Vx = 1-y, Vy = 1+x) и
нелинейной функции (Vx = 1-y2, Vy = 1+x2). Для нелинейной функции
погрешность больше.

31
А) Линейная функция Б) Нелинейная функция
Рис 31. Поле погрешности ротора от линейной функции и нелинейной

Расчет лапласиана проводился для полинома второй степени (Р =


х +у ) в таких случаях:
2 2

 без учета поправки на скошенность. (рис 32).


 с учетом поправки на скошенность и градиентом, рассчитанным
без итерационного способа (рис 33).
 с учетом поправки на скошенность и градиентом, рассчитанным
по методу Грина-Гаусса с итерациями (рис 34).

Наилучший результат дает метод с учетом поправки и градиентом


рассчитанным итерационным методом.

Рис 32. Поле погрешности лапласиана от полинома второй степени без учета
поправки с градиентом, посчитанным по методу Грина-Гаусса без итераций

Рис 33. Поле погрешности лапласиана от полинома второй степени с учетом


поправки и градиентом, посчитанным по методу Грина-Гаусса без итераций

32
Рис 34. Поле погрешности лапласиана от полинома второй степени с учетом
поправки и градиентом, посчитанным по методу Грина-Гаусса с итерациями

5.4 Расчет пространственных операторов на основе сетки и полей


вектора скорости и давления, полученных при помощи пакета Flos

В программе Flos был построен канал, сетка которого была построена


со сгущением к стенкам канала.

Рис 35. Канал в пакете Flos

Течение было рассчитано со значением числа Рейнольдса Re=200,


несжимаемой, ламинарной жидкости со схемой QUICK.

33
Рис 35. Сходимость решения

Рис 36. Поле давления (Flos)

34
Рис 37. Поле компоненты скорости Vx (Flos)

Рис 38. Поле компоненты скорости Vy (Flos)

Считаем эти поля в программе и изображаем в Paraview.

35
36
Рис 39. Поля скорости и давления считаные в программе.

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


дивергенции и ротора скорости.

37
Рис 40. Поле градиента давления по X и по Y

38
Рис 41. Поле дивергенция скорости

Заметим, что дивергенция скорости в случае несжимаемой жидкости


почти везде равна нулю.

Рис 42. Поле ротора скорости

39
Рис 43. Поле лапласиана давления

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

В ходе работы были произведены расчеты пространственных


операторов методом конечных объемов. Выучил основные алгоритмы на
языке Фортран в области вычислительной гидродинамики. Исследовал
изменения рас полей с разными сетками (измельченной и скошенной).
Для расчета градиента машинная точность по всей области
достигается только для полинома первой степени. Для нелинейной функции
возникает ошибка на границах. Аналогичные ситуации можно наблюдать для
остальных пространственных операторов. Порядок точности методов,
рассчитанных в ходе работы, совпал с ожидаемым. Поправки на скошенность
и не ортогональность ячеек дают заменное снижение порядка ошибки, но
машинная точность все же не достигается. Также был выполнен расчет
гидродинамической задачи течение жидкости в канале, сетка которого
сгущением к стенкам. Для полученного поля давления и скорости с помощью
программы были получены поля пространственных операторов данной
задачи.

40
7. Код в Fortran

MAIN
Program Main
character(*), parameter:: InputFile='input.txt',OutputFile='data1.dat' ! names of input and
output files
character MeshFile*30 ! name of file with computational mesh
integer, parameter:: IO = 12 ! input-output unit
real,allocatable,dimension(:,:):: X,Y,P,CellVolume,DivV,DivVError,rotV,LapP,&
DivVExact,rotVExact,rotVError,LapPError,LapPExact !scalar arrays
real,allocatable,dimension(:,:,:):: CellCenter, IFaceCenter, IFaceVector, JFaceCenter,
JFaceVector, GradP, GradPError, V ! vector arrays
real,allocatable,dimension(:,:,:):: GradPExact

!=== READ INPUT FILE ===


WRITE(*,*) 'Read input file: ', InputFile
OPEN(IO,FILE=InputFile)
READ(IO,*) MeshFile ! read name of file with computational mesh
CLOSE(IO)

!=== READ NODES NUMBER (NI,NJ) FROM FILE WITH MESH ===
WRITE(*,*) 'Read nodes number from file: ', MeshFile
OPEN(IO,FILE = MeshFile)
READ(IO,*) NI,NJ
WRITE(*,*) 'NI, NJ = ',NI,NJ

!=== ALLOCATE ALL ARRAYS ===


WRITE(*,*) 'Allocate arrays'
allocate(X(NI,NJ)) ! mesh nodes X-coordinates
allocate(Y(NI,NJ)) ! mesh nodes Y-coordinates
allocate(P(0:NI,0:NJ)) ! Pressure
allocate(CellVolume(NI-1,NJ-1)) ! Cell Volumes
allocate(CellCenter(0:NI,0:NJ,2)) ! Cell Centers
allocate(IFaceCenter( NI,NJ-1,2)) ! Face Centers for I-faces
allocate(IFaceVector( NI,NJ-1,2)) ! Face Vectors for I-faces
allocate(JFaceCenter( NI-1,NJ,2)) ! Face Centers for J-faces
allocate(JFaceVector( NI-1,NJ,2)) ! Face Vectors for I-faces
allocate(GradP(0:NI,0:NJ,2)) ! Vector Gradient P
allocate(GradPError(0:NI,0:NJ,2))
allocate(GradPExact(0:NI,0:NJ,2))
allocate(V(0:NI,0:NJ,2))
allocate(DivV(0:NI,0:NJ))
allocate(DivVError(0:NI,0:NJ))
41
allocate(DivVExact(0:NI,0:NJ))
allocate(rotV(0:NI,0:NJ))
allocate(rotVExact(0:NI,0:NJ))
allocate(rotVError(0:NI,0:NJ))
allocate(LapP(0:NI,0:NJ))
allocate(LapPError(0:NI,0:NJ))
allocate(LapPExact(0:NI,0:NJ))
!=== READ GRID ===
WRITE(*,*) 'Read mesh from file: ', MeshFile
READ(IO,*) ((X(I,J),Y(I,J),I=1,NI),J=1,NJ)
CLOSE(IO)

!=== CALCULATE METRIC ===


WRITE(*,*) 'Calculate metric'
Call
B_CalcMetric(NI,NJ,X,Y,CellCenter,CellVolume,IFaceCenter,IFaceVector,JFaceCenter,JFaceV
ector)
!=== INITIATE FIELDS ===
WRITE(*,*) 'Initiate fields'
DO J = 0,NJ
DO I = 0,NI
P(I,J) = Pressure(CellCenter(I,J,1),CellCenter(I,J,2))
V(I,J,1)=VelocityX(CellCenter(I,J,1))
V(I,J,2)=VelocityY(CellCenter(I,J,2))
GradPExact(I,J,1)=3*CellCenter(I,J,1)**2
GradPExact(I,J,2)=3*CellCenter(I,J,2)**2
DivVExact(I,J)=Diverror4(CellCenter(I,J,1),CellCenter(I,J,2))
rotVExact(I,J)=Roterror2(CellCenter(I,J,1),CellCenter(I,J,2))
!LapPExact(I,J)=6*(CellCenter(I,J,1)+CellCenter(I,J,2))
LapPExact(I,J)=12*(CellCenter(I,J,1)**2+CellCenter(I,J,2)**2)
ENDDO
ENDDO

!=== CALCULATE GRADIENT ===


WRITE(*,*) 'Calculate derivatives'
Call
B_CalcGradient(NI,NJ,P,GradP,Cellvolume,Cellcenter,IFaceCenter,JFaceCenter,IFaceVector,JF
aceVector)
!=== CALCULATE DIVERGENCE ===
WRITE(*,*) 'Calculate Divergence'
Call
B_CalcDiv(NI,NJ,V,DivV,GradP,Cellvolume,Cellcenter,IFaceCenter,JFaceCenter,IFaceVector,J
FaceVector,P)
!=== CALCULATE ROTOR ===
42
WRITE(*,*) 'Calculate Rotor'
Call
B_CalcRotor(NI,NJ,V,RotV,Cellvolume,Cellcenter,IFaceCenter,JFaceCenter,IFaceVector,JFace
Vector)
!=== CALCULATE LAPLACIAN ===
WRITE(*,*) 'Calculate Laplacian'
Call
B_CalcLap(NI,NJ,LapP,GradP,P,Cellvolume,Cellcenter,IFaceCenter,JFaceCenter,IFaceVector,J
FaceVector)
!=== CACULATE THE RELATIVE DEVIATION
WRITE(*,*) 'Caculate vector Gradient Error'
GradPError=ABS(GradP-GradPExact)/GradPExact
Write(*,*)'Maximum Gradx-error: ',maxval(GradPError(2:NI-2,2:NJ-2,1))
Write(*,*)'Maximum Gradx-error: ',maxval(GradPError(2:NI-2,2:NJ-2,2))
WRITE(*,*) 'Caculate Divergence Error'
DivVError=ABS(DivV-DivVExact)/DivVExact
Write(*,*)'Maximum DivV-error: ',maxval(DivVError(1:NI-1,1:NJ-1))
rotVError=ABS(rotV-rotVExact)/rotVExact
Write(*,*)'Maximum rotV-error: ',maxval(rotVError(1:NI-1,1:NJ-1))
LapPError=ABS(LapP-LapPExact)/LapPExact
Write(*,*)'Maximum LapP-error: ',maxval(LapPError(4:NI-1,4:NJ-1))
!=== OUTPUT FIELDS ===
WRITE(*,*) 'Output fields to file: ', OutputFile
Open(IO,FILE=OutputFile)
Call
B_OutputFields(IO,NI,NJ,X,Y,P,GradP,GradPError,V,DivV,DivVError,rotV,LapP,rotVError,La
pPError)
Close(IO)
END PROGRAM Main

CalcMetric

SUBROUTINE
B_CalcMetric(NI,NJ,X,Y,CellCenter,CellVolume,IFaceCenter,IFaceVector,JFaceCenter,JFaceV
ector)
REAL X(NI,NJ),Y(NI,NJ),& ! input: nodes coordinates
CellCenter(0:NI,0:NJ,2),CellVolume(NI-1,NJ-1),& ! output: cell centers and volumes
IFaceCenter( NI,NJ-1,2),IFaceVector(NI,NJ-1,2),& ! ace centers and vectors for I-faces
JFaceCenter( NI-1,NJ,2),JFaceVector(NI-1,NJ,2) ! face centers and vectors for J-faces
REAL r(2)
!=== FACE CENTERS AND FACE VECTORS ===
! I-DIRECTION
DO J = 1,NJ-1
DO I = 1,NI
r(1) = X(I,J+1) - X(I,J) ! r = vector from one node to another
43
r(2) = Y(I,J+1) - Y(I,J)
IFaceVector(I,J,1) = r(2) ! IFaceVector = r rotated on 90 degree
IFaceVector(I,J,2) =-r(1) ! IFaceVector directed to increasing I-index
IFaceCenter(I,J,1) = 0.5*(X(i,j)+x(i,j+1))
IFaceCenter(I,J,2) = 0.5*(Y(i,j)+Y(i,j+1))
ENDDO
ENDDO

! J-DIRECTION
DO J = 1,NJ
DO I = 1,NI-1
r(1) = X(I+1,J) - X(I,J) ! r = vector from one node to another
r(2) = Y(I+1,J) - Y(I,J)
JFaceVector(I,J,1) =-r(2) ! JFaceVector = r rotated on -90 degree
JFaceVector(I,J,2) = r(1) ! JFaceVector directed to increasing J-index
JFaceCenter(I,J,1) = 0.5*(X(i,j)+x(i+1,j))
JFaceCenter(I,J,2) = 0.5*(Y(i,j)+Y(i+1,j))
ENDDO
ENDDO

!=== CELL VOLUMES ===


DO J = 1,NJ-1
DO I = 1,NI-1
r(1)=X(I+1,J+1) - X(I,J)
r(2)=Y(I+1,J+1) - Y(I,J)
!norm2(cross_product())
CellVolume(I,J) = 0.5*DOT_PRODUCT(IFaceVector(I,J,:),r)& ! sum surfaces of two
triangles
+ 0.5*DOT_PRODUCT(JFaceVector(I,J,:),r)
ENDDO
ENDDO

!=== CELL CENTERS ===


! FOR INNER CELLS: CENTER OF CONTOUR (sum of FaceCenter*FaceLength/Perimeter)
DO J = 1,NJ-1
DO I = 1,NI-1
CellCenter(I,J,:) = ( IFaceCenter(I ,J,:)*Norm2(IFaceVector(I ,J,:))+&
IFaceCenter(I+1,J,:)*Norm2(IFaceVector(I+1,J,:))+&
JFaceCenter(I,J ,:)*Norm2(JFaceVector(I,J ,:))+&
JFaceCenter(I,J+1,:)*Norm2(JFaceVector(I,J+1,:)) )&
/( Norm2(IFaceVector(I,J,:))+Norm2(IFaceVector(I+1,J,:))+&
Norm2(JFaceVector(I,J,:))+Norm2(JFaceVector(I,J+1,:)) )
ENDDO
ENDDO
44
! FOR DUMMY CELLS ON BOUNDARIES: CELL CENTER = FACE CENTER! I-
BOUNDARIES -----------------------------------------------------
DO NBOUND = 1,2
IF (NBOUND.EQ.1) THEN
IBOUND = 1; IOUT = 0
ELSE
IBOUND = NI; IOUT = NI
ENDIF
DO J = 1,NJ-1
CellCenter(IOUT,J,:) = IFaceCenter(IBOUND,J,:)
ENDDO
ENDDO

! J-BOUNDARIES -----------------------------------------------------
DO NBOUND = 1,2
IF (NBOUND.EQ.1) THEN
JBOUND = 1; JOUT = 0
ELSE
JBOUND = NJ; JOUT = NJ
ENDIF
DO I = 1,NI-1
CellCenter(I,JOUT,:) = JFaceCenter(I,JBOUND,:)
ENDDO
ENDDO

END SUBROUTINE

CalcGradient без итерации

Subroutine
B_CalcGradient(NI,NJ,P,GradP,Cellvolume,Cellcenter,IFaceCenter,JFaceCenter,IFaceVector,JF
aceVector)
INTEGER NI,NJ
REAL P(0:NI,0:NJ), GradP(0:NI,0:NJ,2)
REAL CellCenter(0:NI,0:NJ,2),CellVolume(NI-1,NJ-1),&
IFaceCenter(NI,NJ-1,2),IFaceVector(NI,NJ-1,2),&
JFaceCenter(NI-1,NJ,2),JFaceVector(NI-1,NJ,2)
! local
INTEGER I,J
REAL VOL,RC(2),RF(4,2),SF(4,2),NCELL(4,2),PFace(4)
! Cell Centers
Do I=1,NI-1
Do J=1,NJ-1
!Coordinates of the cell Centers, which surround the Cell Cennter under consideration
45
NCEll(1,:)=CellCenter(I-1,J,:)
NCELL(2,:)=CellCenter(I,J-1,:)
NCELL(3,:)=CellCenter(I+1,J,:)
NCELL(4,:)=CellCenter(I,J+1,:)
! Coordinates of the centers of the surroungding facecs
RF(1,:)=IFaceCenter(I,J,:)
RF(2,:)=JFaceCenter(I,J,:)
RF(3,:)=IFaceCenter(I+1,J,:)
RF(4,:)=JFaceCenter(I,J+1,:)
! Vectors at Face Centers
SF(1,:)=-IFaceVector(I,J,:)
SF(2,:)=-JFaceVector(I,J,:)
SF(3,:)=IFaceVector(I+1,J,:)
SF(4,:)=JFaceVector(I,J+1,:)
! Vollume & Coordinate of Centers
VOL=CellVolume(I,J)
RC(:)=CellCenter(I,J,:)
! Pressure at Face Centers
PFace(1)=RLinearInterp(norm2(RC(:)-RF(1,:)),norm2(NCELL(1,:)-RF(1,:)),P(I,J),P(I-
1,J))
PFace(2)=RLinearInterp(norm2(RC(:)-RF(2,:)),norm2(NCELL(2,:)-RF(2,:)),P(I,J),P(I,J-
1))
PFace(3)=RLinearInterp(norm2(RC(:)-RF(3,:)),norm2(NCELL(3,:)-
RF(3,:)),P(I,J),P(I+1,J))
PFace(4)=RLinearInterp(norm2(RC(:)-RF(4,:)),norm2(NCELL(4,:)-
RF(4,:)),P(I,J),P(I,J+1))
! Count Gradient at Cell Centers

GradP(I,J,:)=(PFace(1)*SF(1,:)+PFace(2)*SF(2,:)+PFace(3)*SF(3,:)+PFace(4)*SF(4,:))/VOL
ENDDO
ENDDO
End Subroutine

CalcGradient с итерациями

Subroutine
B_CalcGradient(NI,NJ,P,GradP,Cellvolume,Cellcenter,IFaceCenter,JFaceCenter,IFaceVector,JF
aceVector)
INTEGER NI,NJ
REAL P(0:NI,0:NJ), GradP(0:NI,0:NJ,2)

REAL CellCenter(0:NI,0:NJ,2),CellVolume(NI-1,NJ-1),&
IFaceCenter(NI,NJ-1,2),IFaceVector(NI,NJ-1,2),&
JFaceCenter(NI-1,NJ,2),JFaceVector(NI-1,NJ,2)
! local
46
INTEGER I,J,I1,J1
REAL VOL,RC(2),RF(4,2),SF(4,2),NCELL(4,2),PFace, GP(2), RN(2),PE,GPE(2),RE(2)
! Cell Centers
Do I=1,NI-1
Do J=1,NJ-1
!Coordinates of the cell Centers, which surround the Cell Cennter under consideration
NCEll(1,:)=[I-1,J]
NCELL(2,:)=[I,J-1]
NCELL(3,:)=[I+1,J]
NCELL(4,:)=[I,J+1]
! Coordinates of the centers of the surroungding facecs
RF(1,:)=IFaceCenter(I,J,:)
RF(2,:)=JFaceCenter(I,J,:)
RF(3,:)=IFaceCenter(I+1,J,:)
RF(4,:)=JFaceCenter(I,J+1,:)
! Vectors at Face Centers
SF(1,:)=-IFaceVector(I,J,:)
SF(2,:)=-JFaceVector(I,J,:)
SF(3,:)=IFaceVector(I+1,J,:)
SF(4,:)=JFaceVector(I,J+1,:)
! Vollume & Coordinate of Centers
VOL=CellVolume(I,J)
RC(:)=CellCenter(I,J,:)
! Pressure at Face Centers
GP(:)=0
Do IFace=1,4
I1=NCELL(IFace,1)
J1=NCELL(IFace,2)
RN(:)=Cellcenter(I1,J1,:)
PE=RLinearInterp(norm2(RC(:)-RF(IFace,:)),norm2(RN(:)-RF(IFace,:)),P(I,J),P(I1,J1))
RE(1)=RLinearInterp(norm2(RC(:)-RF(IFace,:)),norm2(RN(:)-
RF(IFace,:)),RC(1),RN(1))
RE(2)=RLinearInterp(norm2(RC(:)-RF(IFace,:)),norm2(RN(:)-
RF(IFace,:)),RC(2),RN(2))
GPE(1)=RLinearInterp(norm2(RC(:)-RF(IFace,:)),norm2(RN(:)-
RF(IFace,:)),GRadP(I,J,1),GradP(I1,J1,1))
GPE(2)=RLinearInterp(norm2(RC(:)-RF(IFace,:)),norm2(RN(:)-
RF(IFace,:)),GRadP(I,J,2),GradP(I1,J1,2))
PFace=PE+Dot_product(RF(IFace,:)-RE(:),GPE(:))
GP(:)=GP(:)+PFace*SF(IFace,:)
ENDDO
! Count Gradient at Cell Centers
GradP(I,J,:)=GP(:)/VOL
ENDDO
ENDDO
End Subroutine

CalcDivergence

47
Subroutine
B_CalcDiv(NI,NJ,V,DivV,GradP,Cellvolume,Cellcenter,IFaceCenter,JFaceCenter,IFaceVector,J
FaceVector,P)
INTEGER NI,NJ
REAL DivV(0:NI,0:NJ), V(0:NI,0:NJ,2),P(0:NI,0:NJ), GradP(0:NI,0:NJ,2)
REAL CellCenter(0:NI,0:NJ,2),CellVolume(NI-1,NJ-1),&
IFaceCenter(NI,NJ-1,2),IFaceVector(NI,NJ-1,2),&
JFaceCenter(NI-1,NJ,2),JFaceVector(NI-1,NJ,2)
! local
INTEGER I,J,IFACE,mode,I1,J1
REAL VOL,RC(2),RF(4,2),SF(4,2),NCELL(4,2),VFace(2),PFace,P1,P2,P3
! Cell Centers
Write(*,*)'Enter mode:'
Read(*,*) mode
Do I=1,NI-1
Do J=1,NJ-1
!Coordinates of the cell Centers, which surround the Cell Cennter under consideration
NCEll(1,:)=[I-1,J]
NCELL(2,:)=[I,J-1]
NCELL(3,:)=[I+1,J]
NCELL(4,:)=[I,J+1]
! Coordinates of the centers of the surroungding facecs
RF(1,:)=IFaceCenter(I,J,:)
RF(2,:)=JFaceCenter(I,J,:)
RF(3,:)=IFaceCenter(I+1,J,:)
RF(4,:)=JFaceCenter(I,J+1,:)
! Vectors at Face Centers
SF(1,:)=-IFaceVector(I,J,:)
SF(2,:)=-JFaceVector(I,J,:)
SF(3,:)=IFaceVector(I+1,J,:)
SF(4,:)=JFaceVector(I,J+1,:)
! Vollume & Coordinate of Centers
VOL=CellVolume(I,J)
RC(:)=CellCenter(I,J,:)
DivV(I,J)=0
Do IFACE=1,4
I1=NCELL(IFACE,1)
J1=NCELL(IFACE,2)
! Velocity at Face Centers
VFace(1)=RLinearInterp(norm2(RC(:)-RF(IFACE,:)),norm2(CellCenter(I1,J1,:)-
RF(IFACE,:)),V(I,J,1),V(I1,J1,1))
VFace(2)=RLinearInterp(norm2(RC(:)-RF(IFACE,:)),norm2(CellCenter(I1,J1,:)-
RF(IFACE,:)),V(I,J,2),V(I1,J1,2))
! Count Divergence at Cell Centers
Select Case(mode)
48
case(0)
DivV(I,J)=DivV(I,J)+Dot_product(VFace(:),SF(IFACE,:))
case(1)
PFace=RLinearInterp(norm2(RC(:)-RF(IFACE,:)),norm2(CellCenter(I1,J1,:)-
RF(IFACE,:)),P(I,J),P(I1,J1))
DivV(I,J)=DivV(I,J)+Dot_product(PFace*VFace(:),SF(IFACE,:))
case(2)
IF(Dot_product(SF(IFACE,:),VFace(:)).GE.0.0) then
PFace=P(I,J)
Else
PFace=P(I1,J1)
IF (norm2(CellCenter(I1,J1,:)-RF(IFACE,:)).lt.1e-6) PFace=2*P(I1,J1)-P(I,J)
ENDIF
DivV(I,J)=DivV(I,J)+Dot_product(PFace*VFace(:),SF(IFACE,:))
case(3)
IF(Dot_product(SF(IFACE,:),VFace(:)).GE.0.0) then
PFace=P(I,J)+DOT_PRODUCT(RF(IFACE,:)-CellCenter(I,J,:),GradP(I,J,:))
ELSE
PFace=P(I1,J1)+DOT_PRODUCT(RF(IFACE,:)-CellCenter(I1,J1,:),GradP(I1,J1,:))
IF (norm2(CellCenter(I1,J1,:)-RF(IFACE,:)).lt.1e-6) then
P1=2*P(I1,J1)-P(I,J)
P2=4*(P(I,J)-P(I1,J1))
P3=3*DOT_PRODUCT(GradP(I,J,:),CellCenter(I,J,:)-RF(IFACE,:))
PFace=P1+P2-P3
END IF
END IF
DivV(I,J)=DivV(I,J)+Dot_product(PFace*VFace(:),SF(IFACE,:))
END SELECT
ENDDO
DivV(I,J)=DivV(I,J)/VOL
ENDDO
ENDDO
End Subroutine

CalcRotor
Subroutine
B_CalcRotor(NI,NJ,V,rotV,Cellvolume,Cellcenter,IFaceCenter,JFaceCenter,IFaceVector,JFace
Vector)
INTEGER NI,NJ
REAL RotV(0:NI,0:NJ), V(0:NI,0:NJ,2)
REAL CellCenter(0:NI,0:NJ,2),CellVolume(NI-1,NJ-1),&
IFaceCenter(NI,NJ-1,2),IFaceVector(NI,NJ-1,2),&
JFaceCenter(NI-1,NJ,2),JFaceVector(NI-1,NJ,2)
! local
INTEGER I,J
REAL VOL,RC(2),RF(4,2),SF(4,2),NCELL(4,2),VFace(4,2)
49
! Cell Centers
Do I=1,NI-1
Do J=1,NJ-1
!Coordinates of the cell Centers, which surround the Cell Cennter under consideration
NCEll(1,:)=CellCenter(I-1,J,:)
NCELL(2,:)=CellCenter(I,J-1,:)
NCELL(3,:)=CellCenter(I+1,J,:)
NCELL(4,:)=CellCenter(I,J+1,:)
! Coordinates of the centers of the surroungding facecs
RF(1,:)=IFaceCenter(I,J,:)
RF(2,:)=JFaceCenter(I,J,:)
RF(3,:)=IFaceCenter(I+1,J,:)
RF(4,:)=JFaceCenter(I,J+1,:)
! Vectors at Face Centers
SF(1,:)=-IFaceVector(I,J,:)
SF(2,:)=-JFaceVector(I,J,:)
SF(3,:)=IFaceVector(I+1,J,:)
SF(4,:)=JFaceVector(I,J+1,:)
! Vollume & Coordinate of Centers
VOL=CellVolume(I,J)
RC(:)=CellCenter(I,J,:)
! Velocity at Face Centers
VFace(1,1)=RLinearInterp(norm2(RC(:)-RF(1,:)),norm2(NCELL(1,:)-
RF(1,:)),V(I,J,1),V(I-1,J,1))
VFace(1,2)=RLinearInterp(norm2(RC(:)-RF(1,:)),norm2(NCELL(1,:)-
RF(1,:)),V(I,J,2),V(I-1,J,2))
VFace(2,1)=RLinearInterp(norm2(RC(:)-RF(2,:)),norm2(NCELL(2,:)-
RF(2,:)),V(I,J,1),V(I,J-1,1))
VFace(2,2)=RLinearInterp(norm2(RC(:)-RF(2,:)),norm2(NCELL(2,:)-
RF(2,:)),V(I,J,2),V(I,J-1,2))
VFace(3,1)=RLinearInterp(norm2(RC(:)-RF(3,:)),norm2(NCELL(3,:)-
RF(3,:)),V(I,J,1),V(I+1,J,1))
VFace(3,2)=RLinearInterp(norm2(RC(:)-RF(3,:)),norm2(NCELL(3,:)-
RF(3,:)),V(I,J,2),V(I+1,J,2))
VFace(4,1)=RLinearInterp(norm2(RC(:)-RF(4,:)),norm2(NCELL(4,:)-
RF(4,:)),V(I,J,1),V(I,J+1,1))
VFace(4,2)=RLinearInterp(norm2(RC(:)-RF(4,:)),norm2(NCELL(4,:)-
RF(4,:)),V(I,J,2),V(I,J+1,2))
! Count Rotor at Cell Centers
RotV(I,J)=0
Do IFace=1,4
RotV(I,J)=RotV(I,J)+(VFace(IFace,2)*SF(IFace,1)-VFace(IFace,1)*SF(IFace,2))/VOL
ENDDO
ENDDO
ENDDO
End Subroutine

CalcLaplacian

50
Subroutine
B_CalcLap(NI,NJ,LapP,GradP,P,Cellvolume,Cellcenter,IFaceCenter,JFaceCenter,IFaceVector,J
FaceVector)
INTEGER NI,NJ
REAL LapP(0:NI,0:NJ), GradP(0:NI,0:NJ,2), P(0:NI,0:NJ)
REAL CellCenter(0:NI,0:NJ,2),CellVolume(NI-1,NJ-1),&
IFaceCenter(NI,NJ-1,2),IFaceVector(NI,NJ-1,2),&
JFaceCenter(NI-1,NJ,2),JFaceVector(NI-1,NJ,2)
! local
INTEGER I,J,IFACE,I1,J1
Real D
REAL VOL,RC(2),RF(4,2),SF(4,2),NCELL(4,2),PD, XN(2), XX(2), GPE(2)
! Cell Centers
Do I=1,NI-1
Do J=1,NJ-1
!Coordinates of the cell Centers, which surround the Cell Cennter under consideration
NCEll(1,:)=[I-1,J]
NCELL(2,:)=[I,J-1]
NCELL(3,:)=[I+1,J]
NCELL(4,:)=[I,J+1]
! Coordinates of the centers of the surroungding facecs
RF(1,:)=IFaceCenter(I,J,:)
RF(2,:)=JFaceCenter(I,J,:)
RF(3,:)=IFaceCenter(I+1,J,:)
RF(4,:)=JFaceCenter(I,J+1,:)
! Vectors at Face Centers
SF(1,:)=-IFaceVector(I,J,:)
SF(2,:)=-JFaceVector(I,J,:)
SF(3,:)=IFaceVector(I+1,J,:)
SF(4,:)=JFaceVector(I,J+1,:)
! Vollume & Coordinate of Centers
VOL=CellVolume(I,J)
RC(:)=CellCenter(I,J,:)
LapP(I,J)=0
Do IFACE=1,4
I1=NCELL(IFACE,1)
J1=NCELL(IFACE,2)
D=norm2(RC(:)-CellCenter(I1,J1,:))
PD=(P(I1,J1)-P(I,J))/D
XN(:)=SF(IFACE,:)/norm2(SF(IFACE,:))
!for skew
XX(:)=(CellCenter(I1,J1,:)-CellCenter(I,J,:))/D
GPE(1)=RLinearInterp(norm2(RC(:)-RF(IFace,:)),norm2(Cellcenter(I1,J1,:)-
RF(IFace,:)),GRadP(I,J,1),GradP(I1,J1,1))

51
GPE(2)=RLinearInterp(norm2(RC(:)-RF(IFace,:)),norm2(Cellcenter(I1,J1,:)-
RF(IFace,:)),GRadP(I,J,2),GradP(I1,J1,2))
IF (norm2(CellCenter(I1,J1,:)-RF(IFACE,:)).LT.1e-5) then
PD=5./3.*PD-2./3.*DOT_PRODUCT(GradP(I,J,:),XN(:))
ENDIF
!for skew
PD=PD+DOT_PRODUCT((XN(:)-XX(:)),GPE(:))
LapP(I,J)=LapP(I,J)+PD*norm2(SF(IFACE,:))
ENDDO
! Count Laplacian at Cell Centers
LapP(I,J)=LapP(I,J)/VOL
ENDDO
ENDDO
End Subroutine

Function

Function Pressure(X,Y)
Pressure = x**4+y**
End Function
Function RLinearInterp(d1,d2,x1,x2)
RLinearInterp =(x1*d2+x2*d1)/(d1+d2)
End Function
Function VelocityX(X)
VelocityX= 1+X**2
End Function
Function VelocityY(X)
VelocityY= 1+X**2
End Function
Function Graderror1(X)
Graderror1 = 2*X
End Function
Function Graderror2(X)
Graderror2= 3*(X**2)
End Function
Function Diverror1(X,Y)
Diverror1= 2*X+2*Y
End Function
Function Diverror2(X,Y)
Diverror2= 3*(X**2)+3*(Y**2)
End Function
Function Diverror3(X,Y)
Diverror3= 3*(X+Y)+2
End Function
Function Diverror4(X,Y)
52
Diverror4= 3*(X**2+Y**2)+4*X*Y+2
End Function
Function Roterror1(X,Y)
Roterror1= 2*(X+Y)
End Function
Function Roterror2(X,Y)
Roterror2= 3*(X**2+Y**2)
End Function

OutputFields

Subroutine
B_OutputFields(IO,NI,NJ,X,Y,P,GradP,GradPError,V,DivV,DivVError,rotV,LapP,rotVError,La
pPError)
Real,Dimension(NI,NJ):: X,Y
Real,Dimension(0:NI,0:NJ)::P, DivV, DivVError, rotV, lapP, rotVError,LapPError
Real,Dimension(0:NI,0:NJ,2)::GradP, GradPError, V

Write(IO,*) 'VARIABLES
="X","Y","P","GradPx","GradPy","GradPErrorx","GradPErrorY","Vx","Vy","LapPError","Div
VError","rotVError"'
Write(IO,*) 'ZONE I=',NI,', J=',NJ,', DATAPACKING=BLOCK, VARLOCATION=([3-
12]=CELLCENTERED)'
Write(IO,'(100F14.7)') X(1:NI,1:NJ)
Write(IO,'(100F14.7)') Y(1:NI,1:NJ)
Write(IO,'(100F14.7)') P(1:NI-1,1:NJ-1)
Write(IO,'(100F14.7)') GradP(1:NI-1,1:NJ-1,1)
Write(IO,'(100F14.7)') GradP(1:NI-1,1:NJ-1,2)
Write(IO,'(100F14.7)') GradPError(1:NI-1,1:NJ-1,1)
Write(IO,'(100F14.7)') GradPError(1:NI-1,1:NJ-1,2)
! Write(IO,'(100F14.7)') LapP(1:NI-1,1:NJ-1)
Write(IO,'(100F14.7)') V(1:NI-1,1:NJ-1,1)
Write(IO,'(100F14.7)') V(1:NI-1,1:NJ-1,2)
Write(IO,'(100F14.7)') LapPError(1:NI-1,1:NJ-1)
Write(IO,'(100F14.7)') DivVError(1:NI-1,1:NJ-1)
! Write(IO,'(100F14.7)') RotV(1:NI-1,1:NJ-1)
Write(IO,'(100F14.7)') rotVError(1:NI-1,1:NJ-1)
! Write(IO,'(100F14.7)') DivV(1:NI-1,1:NJ-1)
End Subroutine

Список литературы

53
1. Е. М. Смирнов, Д.К. Зайцев. Метод конечных объемов в
приложении к задачам гидрогазодинамики и теплообмена в областях
сложной геометрии. Научнотехнические ведомости 2’ 2004 Проблемы
турбулентности и вычислительная гидродинамика (к 70-летию кафедры
«Гидроаэродинамика»)

54

Вам также может понравиться