Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / applications / utilities / mesh / conversion / plot3dToFoam / hexBlock.C
blob9cb858028954e3949cb6089aed9306b18206daa6
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | foam-extend: Open Source CFD
4    \\    /   O peration     | Version:     3.2
5     \\  /    A nd           | Web:         http://www.foam-extend.org
6      \\/     M anipulation  | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
8 License
9     This file is part of foam-extend.
11     foam-extend is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by the
13     Free Software Foundation, either version 3 of the License, or (at your
14     option) any later version.
16     foam-extend is distributed in the hope that it will be useful, but
17     WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     General Public License for more details.
21     You should have received a copy of the GNU General Public License
22     along with foam-extend.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "hexBlock.H"
28 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
30 namespace Foam
33 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
35 label hexBlock::vtxLabel(label a, label b, label c) const
37     return (a + b*(xDim_ + 1) + c*(xDim_ + 1)*(yDim_ + 1));
41 // Calculate the handedness of the block by looking at the orientation
42 // of the spanning edges of a hex. Loops until valid cell found (since might
43 // be prism)
44 void hexBlock::setHandedness()
46     const pointField& p = points_;
48     for (label k = 0; k <= zDim_ - 1; k++)
49     {
50         for (label j = 0; j <= yDim_ - 1; j++)
51         {
52             for (label i = 0; i <= xDim_ - 1; i++)
53             {
54                 vector x = p[vtxLabel(i+1, j, k)] - p[vtxLabel(i, j, k)];
55                 vector y = p[vtxLabel(i, j+1, k)] - p[vtxLabel(i, j, k)];
56                 vector z = p[vtxLabel(i, j, k+1)] - p[vtxLabel(i, j, k)];
58                 if (mag(x) > SMALL && mag(y) > SMALL && mag(z) > SMALL)
59                 {
60                     Info<< "Looking at cell "
61                         << i << ' ' << j << ' ' << k
62                         << " to determine orientation."
63                         << endl;
65                     if (((x ^ y) & z) > 0)
66                     {
67                         Info<< "Right-handed block." << endl;
68                         blockHandedness_ = right;
69                     }
70                     else
71                     {
72                         Info << "Left-handed block." << endl;
73                         blockHandedness_ = left;
74                     }
75                     return;
76                 }
77                 else
78                 {
79                     Info<< "Cannot determine orientation of cell "
80                         << i << ' ' << j << ' ' << k
81                         << " since has base vectors " << x << y << z << endl;
82                 }
83             }
84         }
85     }
87     if (blockHandedness_ == noPoints)
88     {
89         WarningIn("hexBlock::hexBlock::setHandedness()")
90             << "Cannot determine orientation of block."
91             << " Continuing as if right handed." << endl;
92         blockHandedness_ = right;
93     }
97 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
99 // Construct from components
100 hexBlock::hexBlock(const label nx, const label ny, const label nz)
102     xDim_(nx - 1),
103     yDim_(ny - 1),
104     zDim_(nz - 1),
105     blockHandedness_(noPoints),
106     points_((xDim_ + 1)*(yDim_ + 1)*(zDim_ + 1))
110 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
112 void hexBlock::readPoints
114     const bool readBlank,
115     const scalar twoDThicknes,
116     Istream& is
119     scalar iBlank;
121     label nPoints = points_.size();
123     if (twoDThicknes > 0)
124     {
125         nPoints /= 2;
126     }
128     Info<< "Reading " << nPoints << " x coordinates..." << endl;
129     for (label i=0; i < nPoints; i++)
130     {
131         is >> points_[i].x();
132     }
134     Info<< "Reading " << nPoints << " y coordinates..." << endl;
135     for (label i=0; i < nPoints; i++)
136     {
137         is >> points_[i].y();
138     }
140     if (twoDThicknes > 0)
141     {
142         Info<< "Extruding " << nPoints << " points in z direction..." << endl;
143         // Duplicate points
144         for (label i=0; i < nPoints; i++)
145         {
146             points_[i+nPoints] = points_[i];
147         }
148         for (label i=0; i < nPoints; i++)
149         {
150             points_[i].z() = 0;
151             points_[i+nPoints].z() = twoDThicknes;
152         }
153     }
154     else
155     {
156         Info<< "Reading " << nPoints << " z coordinates..." << endl;
157         for (label i=0; i < nPoints; i++)
158         {
159             is >> points_[i].z();
160         }
161     }
164     if (readBlank)
165     {
166         Info<< "Reading " << nPoints << " blanks..." << endl;
167         for (label i=0; i < nPoints; i++)
168         {
169             is >> iBlank;
170         }
171     }
173     // Set left- or righthandedness of block by looking at a cell.
174     setHandedness();
178 labelListList hexBlock::blockCells() const
180     labelListList result(xDim_*yDim_*zDim_);
182     label cellNo = 0;
184     if (blockHandedness_ == right)
185     {
186         for (label k = 0; k <= zDim_ - 1; k++)
187         {
188             for (label j = 0; j <= yDim_ - 1; j++)
189             {
190                 for (label i = 0; i <= xDim_ - 1; i++)
191                 {
192                     labelList& hexLabels = result[cellNo];
193                     hexLabels.setSize(8);
195                     hexLabels[0] = vtxLabel(i, j, k);
196                     hexLabels[1] = vtxLabel(i+1, j, k);
197                     hexLabels[2] = vtxLabel(i+1, j+1, k);
198                     hexLabels[3] = vtxLabel(i, j+1, k);
199                     hexLabels[4] = vtxLabel(i, j, k+1);
200                     hexLabels[5] = vtxLabel(i+1, j, k+1);
201                     hexLabels[6] = vtxLabel(i+1, j+1, k+1);
202                     hexLabels[7] = vtxLabel(i, j+1, k+1);
204                     cellNo++;
205                 }
206             }
207         }
208     }
209     else if (blockHandedness_ == left)
210     {
211         for (label k = 0; k <= zDim_ - 1; k++)
212         {
213             for (label j = 0; j <= yDim_ - 1; j++)
214             {
215                 for (label i = 0; i <= xDim_ - 1; i++)
216                 {
217                     labelList& hexLabels = result[cellNo];
218                     hexLabels.setSize(8);
220                     hexLabels[0] = vtxLabel(i, j, k+1);
221                     hexLabels[1] = vtxLabel(i+1, j, k+1);
222                     hexLabels[2] = vtxLabel(i+1, j+1, k+1);
223                     hexLabels[3] = vtxLabel(i, j+1, k+1);
224                     hexLabels[4] = vtxLabel(i, j, k);
225                     hexLabels[5] = vtxLabel(i+1, j, k);
226                     hexLabels[6] = vtxLabel(i+1, j+1, k);
227                     hexLabels[7] = vtxLabel(i, j+1, k);
229                     cellNo++;
230                 }
231             }
232         }
233     }
234     else
235     {
236         FatalErrorIn("hexBlock::cellShapes()")
237             << "Unable to determine block handedness as points "
238             << "have not been read in yet"
239             << abort(FatalError);
240     }
242     return result;
246 // Return block patch faces given direction and range limits
247 // From the cfx manual: direction
248 // 0 = solid (3-D patch),
249 // 1 = high i, 2 = high j, 3 = high k
250 // 4 = low i, 5 = low j, 6 = low k
251 faceList hexBlock::patchFaces(const label direc, const labelList& range) const
253     if (range.size() != 6)
254     {
255         FatalErrorIn
256         (
257             "patchFaces(const label direc, const labelList& range) const"
258         )   << "Invalid size of the range array: " << range.size()
259             << ". Should be 6 (xMin, xMax, yMin, yMax, zMin, zMax"
260             << abort(FatalError);
261     }
263     label xMinRange = range[0];
264     label xMaxRange = range[1];
265     label yMinRange = range[2];
266     label yMaxRange = range[3];
267     label zMinRange = range[4];
268     label zMaxRange = range[5];
270     faceList result(0);
272     switch (direc)
273     {
274         case 1:
275         {
276             // high i = xmax
278             result.setSize
279             (
280                 (yMaxRange - yMinRange + 1)*(zMaxRange - zMinRange + 1)
281             );
283             label p = 0;
284             for (label k = zMinRange - 1; k <= zMaxRange - 1; k++)
285             {
286                 for (label j = yMinRange - 1; j <= yMaxRange - 1; j++)
287                 {
288                     result[p].setSize(4);
290                     // set the points
291                     result[p][0] = vtxLabel(xDim_, j, k);
292                     result[p][1] = vtxLabel(xDim_, j+1, k);
293                     result[p][2] = vtxLabel(xDim_, j+1, k+1);
294                     result[p][3] = vtxLabel(xDim_, j, k+1);
296                     p++;
297                 }
298             }
300             result.setSize(p);
301             break;
302         }
304         case 2:
305         {
306             // high j = ymax
307             result.setSize
308             (
309                 (xMaxRange - xMinRange + 1)*(zMaxRange - zMinRange + 1)
310             );
312             label p = 0;
313             for (label i = xMinRange - 1; i <= xMaxRange - 1; i++)
314             {
315                 for (label k = zMinRange - 1; k <= zMaxRange - 1; k++)
316                 {
317                     result[p].setSize(4);
319                     // set the points
320                     result[p][0] = vtxLabel(i, yDim_, k);
321                     result[p][1] = vtxLabel(i, yDim_, k + 1);
322                     result[p][2] = vtxLabel(i + 1, yDim_, k + 1);
323                     result[p][3] = vtxLabel(i + 1, yDim_, k);
325                     p++;
326                 }
327             }
329             result.setSize(p);
330             break;
331         }
333         case 3:
334         {
335             // high k = zmax
336             result.setSize
337             (
338                 (xMaxRange - xMinRange + 1)*(yMaxRange - yMinRange + 1)
339             );
341             label p = 0;
342             for (label i = xMinRange - 1; i <= xMaxRange - 1; i++)
343             {
344                 for (label j = yMinRange - 1; j <= yMaxRange - 1; j++)
345                 {
346                     result[p].setSize(4);
348                     // set the points
349                     result[p][0] = vtxLabel(i, j, zDim_);
350                     result[p][1] = vtxLabel(i + 1, j, zDim_);
351                     result[p][2] = vtxLabel(i + 1, j + 1, zDim_);
352                     result[p][3] = vtxLabel(i, j + 1, zDim_);
354                     p++;
355                 }
356             }
358             result.setSize(p);
359             break;
360         }
362         case 4:
363         {
364             // low i = xmin
365             result.setSize
366             (
367                 (yMaxRange - yMinRange + 1)*(zMaxRange - zMinRange + 1)
368             );
370             label p = 0;
371             for (label k = zMinRange - 1; k <= zMaxRange - 1; k++)
372             {
373                 for (label j = yMinRange - 1; j <= yMaxRange - 1; j++)
374                 {
375                     result[p].setSize(4);
377                     // set the points
378                     result[p][0] = vtxLabel(0, j, k);
379                     result[p][1] = vtxLabel(0, j, k + 1);
380                     result[p][2] = vtxLabel(0, j + 1, k + 1);
381                     result[p][3] = vtxLabel(0, j + 1, k);
383                     p++;
384                 }
385             }
387             result.setSize(p);
388             break;
389         }
391         case 5:
392         {
393             // low j = ymin
394             result.setSize
395             (
396                 (xMaxRange - xMinRange + 1)*(zMaxRange - zMinRange + 1)
397             );
399             label p = 0;
400             for (label i = xMinRange - 1; i <= xMaxRange - 1; i++)
401             {
402                 for (label k = zMinRange - 1; k <= zMaxRange - 1; k++)
403                 {
404                     result[p].setSize(4);
406                     // set the points
407                     result[p][0] = vtxLabel(i, 0, k);
408                     result[p][1] = vtxLabel(i + 1, 0, k);
409                     result[p][2] = vtxLabel(i + 1, 0, k + 1);
410                     result[p][3] = vtxLabel(i, 0, k + 1);
412                     p++;
413                 }
414             }
416             result.setSize(p);
417             break;
418         }
420         case 6:
421         {
422             // low k = zmin
423             result.setSize
424             (
425                 (xMaxRange - xMinRange + 1)*(yMaxRange - yMinRange + 1)
426             );
428             label p = 0;
429             for (label i = xMinRange - 1; i <= xMaxRange - 1; i++)
430             {
431                 for (label j = yMinRange - 1; j <= yMaxRange - 1; j++)
432                 {
433                     result[p].setSize(4);
435                     // set the points
436                     result[p][0] = vtxLabel(i, j, 0);
437                     result[p][1] = vtxLabel(i, j + 1, 0);
438                     result[p][2] = vtxLabel(i + 1, j + 1, 0);
439                     result[p][3] = vtxLabel(i + 1, j, 0);
441                     p++;
442                 }
443             }
445             result.setSize(p);
446             break;
447         }
449         default:
450         {
451             FatalErrorIn
452             (
453                 "patchFaces(const label direc, const labelList& range) const"
454             )   << "direction out of range (1 to 6): " << direc
455                 << abort(FatalError);
456         }
457     }
459     // Correct the face orientation based on the handedness of the block.
460     // Do nothing for the right-handed block
461     if (blockHandedness_ == noPoints)
462     {
463         FatalErrorIn
464         (
465             "patchFaces(const label direc, const labelList& range) const"
466         )   << "Unable to determine block handedness as points "
467             << "have not been read in yet"
468             << abort(FatalError);
469     }
470     else if (blockHandedness_ == left)
471     {
472         // turn all faces inside out
473         forAll (result, faceI)
474         {
475             result[faceI] = result[faceI].reverseFace();
476         }
477     }
479     return result;
483 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
485 } // End namespace Foam
487 // ************************************************************************* //