-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathdomain_partition.c
152 lines (151 loc) · 6.74 KB
/
domain_partition.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/****************************************************************************
* ArtraCFD *
* <By Huangrui Mo> *
* Copyright (C) Huangrui Mo <huangrui.mo@gmail.com> *
* This file is part of ArtraCFD. *
* ArtraCFD is free software: you can redistribute it and/or modify it *
* under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
****************************************************************************/
/****************************************************************************
* Required Header Files
****************************************************************************/
#include "domain_partition.h"
#include "commons.h"
/****************************************************************************
* Function definitions
****************************************************************************/
void PartitionDomain(Space *space)
{
Partition *const part = &(space->part);
/*
* Outward facing surface unit normal vector of domain boundary
* Surface normal vector can provide great advantage: every surface can
* be treated uniformly if operations are incorporated with surface
* normal vector. For example, (NX, NY, NZ) is the outward facing unit
* normal vector at surface point (i, j, k), then its neighbour node
* (ih, jh, kh) is more inner than current node if
* (ih - i) * NX + (jh - j) * NY + (kh - k) * NZ < 0.
*/
const int N[NBC][DIMS] = {{0, 0, 0}, {-1, 0, 0}, {1, 0, 0},
{0, -1, 0}, {0, 1, 0}, {0, 0, -1}, {0, 0, 1}};
for (int p = 0; p < NBC; ++p) {
for (int s = 0; s < DIMS; ++s) {
part->N[p][s] = N[p][s];
}
}
/*
* Define the index control array of each partition
* min and max are used to define domain index range and are widely
* used in for loop control. To reduce loop comparisons, use a
* reachable value for min, and unreachable value for max. To count
* the total valid objects, simply do (max - min).
*
* Index range
* Entire domain (includes exterior ghost): [0, n);
* Lower exterior ghost: [0, ng);
* Normal nodes: [ng, n-ng);
* Lower boundary: [ng, ng+1);
* Interior node layers: [ng+1, n-ng-1);
* Upper Boundary: [n-ng-1, n-ng);
* Upper exterior ghost: [n-ng, n);
*
* The computational domain are categorized into three main regions:
* interior region, boundary region, and ghost region. In general,
* the interior region is where normal computation is performed;
* the boundary region is where physical boundary condition is enforced;
* the ghost region is where numerical boundary treatment is performed.
*
* When the periodic boundary condition is applied to a direction, then
* the interior region in this direction should be extended to include
* the boundary region, which will then participate normal computation.
*/
for (int s = 0, q = PWB; s < DIMS; ++s, q = q + 2) {
/* interior region */
if (PERIODIC == part->typeBC[q]) { /* extended interior range */
part->ns[PIN][s][MIN] = part->ng[s];
part->ns[PIN][s][MAX] = part->n[s] - part->ng[s];
} else { /* normal interior range */
part->ns[PIN][s][MIN] = part->ng[s] + 1;
part->ns[PIN][s][MAX] = part->n[s] - part->ng[s] - 1;
}
/* boundary box */
for (int p = PWB; p <= PBB; ++p) {
part->ns[p][s][MIN] = part->ng[s];
part->ns[p][s][MAX] = part->n[s] - part->ng[s];
}
/* ghost box */
for (int p = PWG; p <= PBG; ++p) {
part->ns[p][s][MIN] = 0;
part->ns[p][s][MAX] = part->n[s];
}
/* physical region */
part->ns[PHY][s][MIN] = part->ng[s];
part->ns[PHY][s][MAX] = part->n[s] - part->ng[s];
/* all region */
part->ns[PAL][s][MIN] = 0;
part->ns[PAL][s][MAX] = part->n[s];
}
/* adjust boundary box to the boundary region of each direction */
for (int p = PWB, s = 0; p <= PBB; p = p + 2, ++s) {
part->ns[p][s][MAX] = part->ns[p][s][MIN] + 1;
}
for (int p = PEB, s = 0; p <= PBB; p = p + 2, ++s) {
part->ns[p][s][MIN] = part->ns[p][s][MAX] - 1;
}
/* adjust ghost box to the ghost region of each direction */
for (int p = PWG, s = 0; p <= PBG; p = p + 2, ++s) {
part->ns[p][s][MAX] = part->ng[s];
}
for (int p = PEG, s = 0; p <= PBG; p = p + 2, ++s) {
part->ns[p][s][MIN] = part->n[s] - part->ng[s];
}
/* computational node range with dimension priority */
const int np[DIMS][DIMS][LIMIT] = {
{
{part->ns[PIN][X][MIN], part->ns[PIN][X][MAX]},
{part->ns[PIN][Y][MIN], part->ns[PIN][Y][MAX]},
{part->ns[PIN][Z][MIN], part->ns[PIN][Z][MAX]}
},
{
{part->ns[PIN][Y][MIN], part->ns[PIN][Y][MAX]},
{part->ns[PIN][X][MIN], part->ns[PIN][X][MAX]},
{part->ns[PIN][Z][MIN], part->ns[PIN][Z][MAX]}
},
{
{part->ns[PIN][Z][MIN], part->ns[PIN][Z][MAX]},
{part->ns[PIN][X][MIN], part->ns[PIN][X][MAX]},
{part->ns[PIN][Y][MIN], part->ns[PIN][Y][MAX]}
}
};
for (int n = 0; n < DIMS; ++n) {
for (int s = 0; s < DIMS; ++s) {
for (int m = 0; m < LIMIT; ++m) {
part->np[n][s][m] = np[n][s][m];
}
}
}
/* search path for interfacial node */
const int path[PATHN][DIMS] = { /* searching path */
{-1, 0, 0}, {1, 0, 0}, {0, -1, 0}, {0, 1, 0}, {0, 0, -1}, {0, 0, 1},
{-1, -1, 0}, {1, -1, 0}, {-1, 1, 0}, {1, 1, 0},
{-1, 0, -1}, {1, 0, -1}, {-1, 0, 1}, {1, 0, 1},
{0, -1, -1}, {0, 1, -1}, {0, -1, 1}, {0, 1, 1},
{-2, 0, 0}, {2, 0, 0}, {0, -2, 0}, {0, 2, 0}, {0, 0, -2}, {0, 0, 2},
{-3, 0, 0}, {3, 0, 0}, {0, -3, 0}, {0, 3, 0}, {0, 0, -3}, {0, 0, 3}
};
for (int n = 0; n < PATHN; ++n) {
for (int s = 0; s < DIMS; ++s) {
part->path[n][s] = path[n][s];
}
}
const int base = 6; /* base directions in searching path */
part->pathSep[1] = base; /* end index for layer 1 */
part->pathSep[2] = part->pathSep[1] + 18; /* end index for layer 2 */
part->pathSep[3] = part->pathSep[2] + base; /* end index for layer 3 */
/* max search path for a spatial scheme */
part->pathSep[0] = part->pathSep[part->gl];
return;
}
/* a good practice: end file with a newline */