1 // --------------------------------------------------------------------------
4 // Markus Wittmann, 2016-2017
5 // RRZE, University of Erlangen-Nuremberg, Germany
6 // markus.wittmann -at- fau.de or hpc -at- rrze.fau.de
9 // LSS, University of Erlangen-Nuremberg, Germany
11 // This file is part of the Lattice Boltzmann Benchmark Kernels (LbmBenchKernels).
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.
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.
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/>.
26 // --------------------------------------------------------------------------
35 void GeoCreateByStr(const char * geometryType, int dims[3], int periodic[3], LatticeDesc * ld)
38 void * typeDetails = NULL;
41 if (strncasecmp("channel", geometryType, 7) == 0) {
42 type = GEO_TYPE_CHANNEL;
44 else if (strncasecmp("box", geometryType, 3) == 0) {
47 else if (strncasecmp("pipe", geometryType, 4) == 0) {
50 else if (strncasecmp("blocks", geometryType, 6) == 0) {
51 type = GEO_TYPE_BLOCKS;
56 if (strlen(geometryType) > 7) {
57 int blockSize = atoi(&geometryType[7]);
61 if (dims[1] < dimMin) dimMin = dims[1];
62 if (dims[2] < dimMin) dimMin = dims[2];
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.
75 else if (strncasecmp("fluid", geometryType, 5) == 0) {
76 type = GEO_TYPE_FLUID;
79 printf("ERROR: unknown geometry specified.\n");
83 GeoCreateByType(type, typeDetails, dims, periodic, ld);
88 void GeoCreateByType(GEO_TYPES type, void * typeDetails, int dims[3], int periodic[3], LatticeDesc * ld)
95 Assert(periodic != NULL);
96 Assert(periodic[0] >= 0);
97 Assert(periodic[1] >= 0);
98 Assert(periodic[2] >= 0);
102 Assert(type >= GEO_TYPE_MIN);
103 Assert(type <= GEO_TYPE_MAX);
105 const char * geoTypeStr[] = { "box", "channel", "pipe", "blocks", "fluid" };
107 printf("# geometry: %d x %d x %d nodes, type %d %s\n", dims[0], dims[1], dims[2], type, geoTypeStr[type]);
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];
118 MemAlloc((void **)&lattice, sizeof(LatticeT) * dims[0] * dims[1] * dims[2]);
120 ld->Lattice = lattice;
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;
130 if (type == GEO_TYPE_CHANNEL || type == GEO_TYPE_BLOCKS || type == GEO_TYPE_PIPE) {
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;
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) {
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;
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;
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) {
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;
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;
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) {
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;
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;
177 if (type == GEO_TYPE_CHANNEL) {
178 // Nothing todo here.
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);
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;
198 else if (type == GEO_TYPE_BLOCKS) {
200 int blockSize = *((int *)typeDetails);
203 if (blockSize == 0) {
209 int dimMin = dims[0];
211 if (dims[1] < dimMin) dimMin = dims[1];
212 if (dims[2] < dimMin) dimMin = dims[2];
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.
220 // Number of blocks in x, y, and z direction.
221 int nbx = blockSize, nby = blockSize, nbz = blockSize;
223 for (int z = 0; z < dims[2]; ++z) {
224 if ((z % (2 * nbz)) < nbz) continue;
226 for (int y = 0; y < dims[1]; ++y) {
227 if ((y % (2 * nby)) < nby) continue;
229 for (int x = 0; x < dims[0]; ++x) {
231 if ((x % (2 * nbx)) >= nbx) {
232 lattice[L_INDEX_4(dims, x, y, z)] = LAT_CELL_OBSTACLE;
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);
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)]]);
255 // Lattice Helper Function
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;