bulk commit
[LbmBenchmarkKernelsPublic.git] / src / Geometry.c
CommitLineData
10988083
MW
1// --------------------------------------------------------------------------
2//
3// Copyright
4// Markus Wittmann, 2016-2017
5// RRZE, University of Erlangen-Nuremberg, Germany
6// markus.wittmann -at- fau.de or hpc -at- rrze.fau.de
7//
8// Viktor Haag, 2016
9// LSS, University of Erlangen-Nuremberg, Germany
10//
11// This file is part of the Lattice Boltzmann Benchmark Kernels (LbmBenchKernels).
12//
13// LbmBenchKernels is free software: you can redistribute it and/or modify
14// it under the terms of the GNU General Public License as published by
15// the Free Software Foundation, either version 3 of the License, or
16// (at your option) any later version.
17//
18// LbmBenchKernels is distributed in the hope that it will be useful,
19// but WITHOUT ANY WARRANTY; without even the implied warranty of
20// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21// GNU General Public License for more details.
22//
23// You should have received a copy of the GNU General Public License
24// along with LbmBenchKernels. If not, see <http://www.gnu.org/licenses/>.
25//
26// --------------------------------------------------------------------------
27#include "Geometry.h"
28#include "Memory.h"
29
30#include <strings.h>
31#include <math.h>
32
33#include <errno.h>
34
35void GeoCreateByStr(const char * geometryType, int dims[3], int periodic[3], LatticeDesc * ld)
36{
37 int type = -1;
38 void * typeDetails = NULL;
39 int tmp;
40
41 if (strncasecmp("channel", geometryType, 7) == 0) {
42 type = GEO_TYPE_CHANNEL;
43 }
44 else if (strncasecmp("box", geometryType, 3) == 0) {
45 type = GEO_TYPE_BOX;
46 }
47 else if (strncasecmp("pipe", geometryType, 4) == 0) {
48 type = GEO_TYPE_PIPE;
49 }
50 else if (strncasecmp("blocks", geometryType, 6) == 0) {
51 type = GEO_TYPE_BLOCKS;
52
53 // Default block size
54 tmp = 8;
55
56 if (strlen(geometryType) > 7) {
57 int blockSize = atoi(&geometryType[7]);
58
59 int dimMin = dims[0];
60
61 if (dims[1] < dimMin) dimMin = dims[1];
62 if (dims[2] < dimMin) dimMin = dims[2];
63
64 if (blockSize < 0 || blockSize > dimMin / 2) {
65 printf("ERROR: block size for geometry must be > 0 and smaller than half of the smalest dimension.\n");
66 // TODO: find a better solution for handling errors in here.
67 Verify(0);
68 }
69
70 tmp = blockSize;
71 }
72
73 typeDetails = &tmp;
74 }
e3f82424
MW
75 else if (strncasecmp("fluid", geometryType, 5) == 0) {
76 type = GEO_TYPE_FLUID;
77 }
10988083
MW
78 else {
79 printf("ERROR: unknown geometry specified.\n");
80 Verify(0);
81 }
82
83 GeoCreateByType(type, typeDetails, dims, periodic, ld);
84
85 return;
86}
87
88void GeoCreateByType(GEO_TYPES type, void * typeDetails, int dims[3], int periodic[3], LatticeDesc * ld)
89{
90 Assert(dims != NULL);
91 Assert(dims[0] > 0);
92 Assert(dims[1] > 0);
93 Assert(dims[2] > 0);
94
95 Assert(periodic != NULL);
96 Assert(periodic[0] >= 0);
97 Assert(periodic[1] >= 0);
98 Assert(periodic[2] >= 0);
99
100 Assert(ld != NULL);
101
102 Assert(type >= GEO_TYPE_MIN);
103 Assert(type <= GEO_TYPE_MAX);
104
e3f82424 105 const char * geoTypeStr[] = { "box", "channel", "pipe", "blocks", "fluid" };
10988083
MW
106
107 printf("# geometry: %d x %d x %d nodes, type %d %s\n", dims[0], dims[1], dims[2], type, geoTypeStr[type]);
108
109 ld->Dims[0] = dims[0];
110 ld->Dims[1] = dims[1];
111 ld->Dims[2] = dims[2];
112 ld->nCells = dims[0] * dims[1] * dims[2];
113 ld->PeriodicX = periodic[0];
114 ld->PeriodicY = periodic[1];
115 ld->PeriodicZ = periodic[2];
116
117 LatticeT * lattice;
118 MemAlloc((void **)&lattice, sizeof(LatticeT) * dims[0] * dims[1] * dims[2]);
119
120 ld->Lattice = lattice;
121
122 for (int z = 0; z < dims[2]; ++z) {
123 for (int y = 0; y < dims[1]; ++y) {
124 for (int x = 0; x < dims[0]; ++x) {
125 lattice[L_INDEX_4(dims, x, y, z)] = LAT_CELL_FLUID;
126 }
127 }
128 }
129
130 if (type == GEO_TYPE_CHANNEL || type == GEO_TYPE_BLOCKS || type == GEO_TYPE_PIPE) {
131 periodic[0] = 1;
132 }
e3f82424
MW
133 else if (type == GEO_TYPE_FLUID) {
134 // Actually this geometry is non-periodic, but we need fluid at the boundary.
135 periodic[0] = 1; periodic[1] = 1; periodic[2] = 1;
136 }
10988083
MW
137
138 // Walls or periodic on first and last x plane.
139 for (int z = 0; z < dims[2]; ++z) {
140 for (int y = 0; y < dims[1]; ++y) {
141 if(periodic[0]){
142 lattice[L_INDEX_4(dims, 0, y, z)] = LAT_CELL_FLUID;
143 lattice[L_INDEX_4(dims, dims[0] - 1, y, z)] = LAT_CELL_FLUID;
144 } else {
145 lattice[L_INDEX_4(dims, 0, y, z)] = LAT_CELL_OBSTACLE;
146 lattice[L_INDEX_4(dims, dims[0] - 1, y, z)] = LAT_CELL_OBSTACLE;
147 }
148 }
149 }
150
151 // Walls or periodic on first and last y plane.
152 for (int z = 0; z < dims[2]; ++z) {
153 for (int x = 0; x < dims[0]; ++x) {
154 if(periodic[1]){
155 lattice[L_INDEX_4(dims, x, 0, z)] = LAT_CELL_FLUID;
156 lattice[L_INDEX_4(dims, x, dims[1] - 1, z)] = LAT_CELL_FLUID;
157 } else {
158 lattice[L_INDEX_4(dims, x, 0, z)] = LAT_CELL_OBSTACLE;
159 lattice[L_INDEX_4(dims, x, dims[1] - 1, z)] = LAT_CELL_OBSTACLE;
160 }
161 }
162 }
163
164 // Walls or periodic on first and last z plane.
165 for (int y = 0; y < dims[1]; ++y) {
166 for (int x = 0; x < dims[0]; ++x) {
167 if(periodic[2]){
168 lattice[L_INDEX_4(dims, x, y, 0)] = LAT_CELL_FLUID;
169 lattice[L_INDEX_4(dims, x, y, dims[2] - 1)] = LAT_CELL_FLUID;
170 } else {
171 lattice[L_INDEX_4(dims, x, y, 0)] = LAT_CELL_OBSTACLE;
172 lattice[L_INDEX_4(dims, x, y, dims[2] - 1)] = LAT_CELL_OBSTACLE;
173 }
174 }
175 }
176
177 if (type == GEO_TYPE_CHANNEL) {
e3f82424 178 // Nothing todo here.
10988083
MW
179 }
180 else if (type == GEO_TYPE_PIPE) {
181 #define SQR(a) ((a)*(a))
182 double centerZ = dims[2] / 2.0 - 0.5;
183 double centerY = dims[1] / 2.0 - 0.5;
184 double minDiameter = MIN(dims[1], dims[2]);
185 double minRadiusSquared = SQR(minDiameter / 2 - 1);
186
187 for (int z = 0; z < dims[2]; ++z) {
188 for (int y = 0; y < dims[1]; ++y) {
189 if((SQR(z - centerZ) + SQR(y - centerY)) >= minRadiusSquared) {
190 for (int x = 0; x < dims[0]; ++x) {
191 lattice[L_INDEX_4(dims, x, y, z)] = LAT_CELL_OBSTACLE;
192 }
193 }
194 }
195 }
196 #undef SQR
197 }
198 else if (type == GEO_TYPE_BLOCKS) {
199
200 int blockSize = *((int *)typeDetails);
201
e3f82424 202#if 0
10988083
MW
203 if (blockSize == 0) {
204 blockSize = 8;
205 }
e3f82424
MW
206#endif
207 if (blockSize > 0) {
10988083 208
e3f82424 209 int dimMin = dims[0];
10988083 210
e3f82424
MW
211 if (dims[1] < dimMin) dimMin = dims[1];
212 if (dims[2] < dimMin) dimMin = dims[2];
10988083 213
e3f82424
MW
214 if (blockSize < 0 || blockSize > dimMin / 2) {
215 printf("ERROR: block size for geometry must be > 0 and smaller than half of the smalest dimension.\n");
216 // TODO: find a better solution for handling errors in here.
217 Verify(0);
218 }
10988083 219
e3f82424
MW
220 // Number of blocks in x, y, and z direction.
221 int nbx = blockSize, nby = blockSize, nbz = blockSize;
10988083 222
e3f82424
MW
223 for (int z = 0; z < dims[2]; ++z) {
224 if ((z % (2 * nbz)) < nbz) continue;
10988083 225
e3f82424
MW
226 for (int y = 0; y < dims[1]; ++y) {
227 if ((y % (2 * nby)) < nby) continue;
10988083 228
e3f82424 229 for (int x = 0; x < dims[0]; ++x) {
10988083 230
e3f82424
MW
231 if ((x % (2 * nbx)) >= nbx) {
232 lattice[L_INDEX_4(dims, x, y, z)] = LAT_CELL_OBSTACLE;
233 }
10988083
MW
234 }
235 }
236 }
237 }
238 }
239
240// if (latticeDumpAscii) {
241// const char strLatCellType[] = "X.IxO"; // X = Obstacle, . = Fluid, I = inlet, O = outlet
242// for (int z = dims[2] - 1; z >= 0; --z) {
243// printf("plane % 2d\n", z);
244//
245// for (int y = dims[1] - 1; y >= 0; --y) {
246// printf(" %2d ", y);
247// for (int x = 0; x < dims[0]; ++x) {
248// printf("%c", strLatCellType[lattice[L_INDEX_4(dims, x, y, z)]]);
249// }
250// printf("\n");
251// }
252// }
253// }
254
255// Lattice Helper Function
256
257 ld->nObst = 0;
258 ld->nFluid = 0;
259 ld->nInlet = 0;
260 ld->nOutlet = 0;
261
262 for (int z = 0; z < dims[2]; ++z) {
263 for (int y = 0; y < dims[1]; ++y) {
264 for (int x = 0; x < dims[0]; ++x) {
265 switch (lattice[L_INDEX_4(dims, x, y, z)]) {
266 case LAT_CELL_OBSTACLE: ld->nObst++; break;
267 case LAT_CELL_FLUID: ld->nFluid++; break;
268 case LAT_CELL_INLET: ld->nInlet++; ld->nFluid++; break;
269 case LAT_CELL_OUTLET: ld->nOutlet++; ld->nFluid++; break;
270 default:
271 Verify(0);
272 }
273 }
274 }
275 }
276
277 return;
278}
This page took 0.067255 seconds and 5 git commands to generate.