initial commit for version 1.5.x patch release
[OpenFOAM-1.5.x.git] / applications / utilities / mesh / conversion / kivaToFoam / readKivaGrid.H
blobb264214b8c58163de58457d2fd8b02d99ef5586c
1 ifstream kivaFile(kivaFileName.c_str());
3 if (!kivaFile.good())
5     FatalErrorIn(args.executable())
6         << "Cannot open file " << kivaFileName
7         << exit(FatalError);
10 Info << "Reading kiva grid from file " << kivaFileName << endl;
13 char title[120];
14 kivaFile.getline(title, 120, '\n');
16 label nPoints, nCells, nRegs;
17 kivaFile >> nCells >> nPoints >> nRegs;
19 pointField points(nPoints);
20 label i4;
21 labelList idface(nPoints), fv(nPoints);
23 for(label i=0; i<nPoints; i++)
25     scalar ffv;
26     kivaFile
27         >> i4
28         >> points[i].x() >> points[i].y() >> points[i].z()
29         >> ffv;
31     if (kivaVersion == kiva3v)
32     {
33         kivaFile >> idface[i];
34     }
36     // Convert from KIVA cgs units to SI
37     points[i] *= 0.01;
39     fv[i] = label(ffv);
42 labelList i1tab(nPoints), i3tab(nPoints), i8tab(nPoints), idreg(nPoints),
43       f(nPoints), bcl(nPoints), bcf(nPoints), bcb(nPoints);
45 label nBfaces = 0;
47 for(label i=0; i<nPoints; i++)
49     label i1, i3, i8;
50     scalar ff, fbcl, fbcf, fbcb;
52     kivaFile
53         >> i1 >> i3 >> i4 >> i8
54         >> ff >> fbcl >> fbcf >> fbcb
55         >> idreg[i];
57     // Correct indices to start from 0
58     i1tab[i] = i1 - 1;
59     i3tab[i] = i3 - 1;
60     i8tab[i] = i8 - 1;
62     // Convert scalar indices into hexLabels
63     f[i] = label(ff);
64     bcl[i] = label(fbcl);
65     bcf[i] = label(fbcf);
66     bcb[i] = label(fbcb);
68     if (bcl[i] > 0 && bcl[i] != 4) nBfaces++;
69     if (bcf[i] > 0 && bcf[i] != 4) nBfaces++;
70     if (bcb[i] > 0 && bcb[i] != 4) nBfaces++;
74 label mTable;
75 kivaFile >> mTable;
77 if (mTable == 0)
79     FatalErrorIn(args.executable())
80         << "mTable == 0. This is not supported."
81            " kivaToFoam needs complete neighbour information"
82         << exit(FatalError);
86 labelList imtab(nPoints), jmtab(nPoints), kmtab(nPoints);
88 for(label i=0; i<nPoints; i++)
90     label im, jm, km;
91     kivaFile >> i4 >> im >> jm >> km;
93     // Correct indices to start from 0
94     imtab[i] = im - 1;
95     jmtab[i] = jm - 1;
96     kmtab[i] = km - 1;
99 Info << "Finished reading KIVA file" << endl;
101 cellShapeList cellShapes(nPoints);
103 labelList cellZoning(nPoints, -1);
105 const cellModel& hex = *(cellModeller::lookup("hex"));
106 labelList hexLabels(8);
107 label activeCells = 0;
109 // Create and set the collocated point collapse map
110 labelList pointMap(nPoints);
112 forAll (pointMap, i)
114     pointMap[i] = i;
117 // Initialise all cells to hex and search and set map for collocated points
118 for(label i=0; i<nPoints; i++)
120     if (f[i] > 0.0)
121     {
122         hexLabels[0] = i;
123         hexLabels[1] = i1tab[i];
124         hexLabels[2] = i3tab[i1tab[i]];
125         hexLabels[3] = i3tab[i];
126         hexLabels[4] = i8tab[i];
127         hexLabels[5] = i1tab[i8tab[i]];
128         hexLabels[6] = i3tab[i1tab[i8tab[i]]];
129         hexLabels[7] = i3tab[i8tab[i]];
131         cellShapes[activeCells] = cellShape(hex, hexLabels);
133         edgeList edges = cellShapes[activeCells].edges();
135         forAll (edges, ei)
136         {
137             if (edges[ei].mag(points) < SMALL)
138             {
139                 label start = pointMap[edges[ei].start()];
140                 while (start != pointMap[start])
141                 {
142                     start = pointMap[start];
143                 }
145                 label end = pointMap[edges[ei].end()];
146                 while (end != pointMap[end])
147                 {
148                     end = pointMap[end];
149                 }
151                 label minLabel = min(start, end);
153                 pointMap[start] = pointMap[end] = minLabel;
154             }
155         }
157         // Grab the cell zoning info
158         cellZoning[activeCells] = idreg[i];
160         activeCells++;
161     }
164 // Contract list of cells to the active ones
165 cellShapes.setSize(activeCells);
166 cellZoning.setSize(activeCells);
168 // Map collocated points to refer to the same point and collapse cell shape
169 // to the corresponding hex-degenerate.
170 forAll (cellShapes, celli)
172     cellShape& cs = cellShapes[celli];
174     forAll (cs, i)
175     {
176         cs[i] = pointMap[cs[i]];
177     }
179     cs.collapse();
182 label bcIDs[11] = {-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};
184 const label nBCs = 12;
186 const word* kivaPatchTypes[nBCs] =
188     &wallPolyPatch::typeName,
189     &wallPolyPatch::typeName,
190     &wallPolyPatch::typeName,
191     &wallPolyPatch::typeName,
192     &symmetryPolyPatch::typeName,
193     &wedgePolyPatch::typeName,
194     &polyPatch::typeName,
195     &polyPatch::typeName,
196     &polyPatch::typeName,
197     &polyPatch::typeName,
198     &symmetryPolyPatch::typeName,
199     &cyclicPolyPatch::typeName
202 enum patchTypeNames
204     PISTON,
205     VALVE,
206     LINER,
207     CYLINDERHEAD,
208     AXIS,
209     WEDGE,
210     INFLOW,
211     OUTFLOW,
212     PRESIN,
213     PRESOUT,
214     SYMMETRYPLANE,
215     CYCLIC
218 const char* kivaPatchNames[nBCs] =
220     "piston",
221     "valve",
222     "liner",
223     "cylinderHead",
224     "axis",
225     "wedge",
226     "inflow", 
227     "outflow",
228     "presin",
229     "presout",
230     "symmetryPlane",
231     "cyclic"
235 List<SLList<face> > pFaces[nBCs];
237 face quadFace(4);
238 face triFace(3);
240 for(label i=0; i<nPoints; i++)
242     if (f[i] > 0)
243     {
244         // left
245         label bci = bcl[i];
246         if (bci != 4)
247         {
248             quadFace[0] = i3tab[i];
249             quadFace[1] = i;
250             quadFace[2] = i8tab[i];
251             quadFace[3] = i3tab[i8tab[i]];
253 #           include "checkPatch.H"
254         }
256         // right
257         bci = bcl[i1tab[i]];
258         if (bci != 4)
259         {
260             quadFace[0] = i1tab[i];
261             quadFace[1] = i3tab[i1tab[i]];
262             quadFace[2] = i8tab[i3tab[i1tab[i]]];
263             quadFace[3] = i8tab[i1tab[i]];
265 #           include "checkPatch.H"
266         }
268         // front
269         bci = bcf[i];
270         if (bci != 4)
271         {
272             quadFace[0] = i;
273             quadFace[1] = i1tab[i];
274             quadFace[2] = i8tab[i1tab[i]];
275             quadFace[3] = i8tab[i];
277 #           include "checkPatch.H"
278         }
280         // derriere (back)
281         bci = bcf[i3tab[i]];
282         if (bci != 4)
283         {
284             quadFace[0] = i3tab[i];
285             quadFace[1] = i8tab[i3tab[i]];
286             quadFace[2] = i8tab[i1tab[i3tab[i]]];
287             quadFace[3] = i1tab[i3tab[i]];
289 #           include "checkPatch.H"
290         }
292         // bottom
293         bci = bcb[i];
294         if (bci != 4)
295         {
296             quadFace[0] = i;
297             quadFace[1] = i3tab[i];
298             quadFace[2] = i1tab[i3tab[i]];
299             quadFace[3] = i1tab[i];
301 #           include "checkPatch.H"
302         }
304         // top
305         bci = bcb[i8tab[i]];
306         if (bci != 4)
307         {
308             quadFace[0] = i8tab[i];
309             quadFace[1] = i1tab[i8tab[i]];
310             quadFace[2] = i3tab[i1tab[i8tab[i]]];
311             quadFace[3] = i3tab[i8tab[i]];
313 #           include "checkPatch.H"
314         }
315     }
318 // Tranfer liner faces that are above the minimum cylinder-head z height
319 // into the cylinder-head region
322     pFaces[LINER].size()
323  && pFaces[LINER][0].size()
324  && pFaces[CYLINDERHEAD].size()
325  && pFaces[CYLINDERHEAD][0].size()
328     scalar minz = GREAT;
330     for
331     (
332         SLList<face>::iterator iter = pFaces[CYLINDERHEAD][0].begin();
333         iter != pFaces[CYLINDERHEAD][0].end();
334         ++iter
335     )
336     {
337         const face& pf = iter();
339         forAll (pf, pfi)
340         {
341             minz = min(minz, points[pf[pfi]].z());
342         }
343     }
345     minz += SMALL;
347     SLList<face> newLinerFaces;
349     for
350     (
351         SLList<face>::iterator iter = pFaces[LINER][0].begin();
352         iter != pFaces[LINER][0].end();
353         ++iter
354     )
355     {
356         const face& pf = iter();
358         scalar minfz = GREAT;
359         forAll (pf, pfi)
360         {
361             minfz = min(minfz, points[pf[pfi]].z());
362         }
364         if (minfz > minz)
365         {
366             pFaces[CYLINDERHEAD][0].append(pf);
367         }
368         else
369         {
370             newLinerFaces.append(pf);
371         }
372     }
374     if (pFaces[LINER][0].size() != newLinerFaces.size())
375     {
376         Info<< "Transfered " << pFaces[LINER][0].size() - newLinerFaces.size()
377             << " faces from liner region to cylinder head" << endl;
378         pFaces[LINER][0] = newLinerFaces;
379     }
381     SLList<face> newCylinderHeadFaces;
383     for
384     (
385         SLList<face>::iterator iter = pFaces[CYLINDERHEAD][0].begin();
386         iter != pFaces[CYLINDERHEAD][0].end();
387         ++iter
388     )
389     {
390         const face& pf = iter();
392         scalar minfz = GREAT;
393         forAll (pf, pfi)
394         {
395             minfz = min(minfz, points[pf[pfi]].z());
396         }
398         if (minfz < zHeadMin)
399         {
400             pFaces[LINER][0].append(pf);
401         }
402         else
403         {
404             newCylinderHeadFaces.append(pf);
405         }
406     }
408     if (pFaces[CYLINDERHEAD][0].size() != newCylinderHeadFaces.size())
409     {
410         Info<< "Transfered faces from cylinder-head region to linder" << endl;
411         pFaces[CYLINDERHEAD][0] = newCylinderHeadFaces;
412     }
416 // Count the number of non-zero sized patches
417 label nPatches = 0;
418 for (int bci=0; bci<nBCs; bci++)
420     forAll (pFaces[bci], rgi)
421     {
422         if (pFaces[bci][rgi].size())
423         {
424             nPatches++;
425         }
426     }
430 // Sort-out the 2D/3D wedge geometry
431 if (pFaces[WEDGE].size() && pFaces[WEDGE][0].size())
433     if (pFaces[WEDGE][0].size() == cellShapes.size())
434     {
435         // Distribute the points to be +/- 2.5deg from the x-z plane
437         scalar tanTheta = Foam::tan(2.5*mathematicalConstant::pi/180.0);
439         SLList<face>::iterator iterf = pFaces[WEDGE][0].begin();
440         SLList<face>::iterator iterb = pFaces[WEDGE][1].begin();
441         for
442         (
443             ;
444             iterf != pFaces[WEDGE][0].end(), iterb != pFaces[WEDGE][1].end();
445             ++iterf, ++iterb
446         )
447         {
448             for (direction d=0; d<4; d++)
449             {
450                 points[iterf()[d]].y() = -tanTheta*points[iterf()[d]].x();
451                 points[iterb()[d]].y() =  tanTheta*points[iterb()[d]].x();
452             }
453         }
454     }
455     else
456     {
457         pFaces[CYCLIC].setSize(1);
458         pFaces[CYCLIC][0] = pFaces[WEDGE][0];
459         for
460         (
461             SLList<face>::iterator iterb = pFaces[WEDGE][1].begin();
462             iterb != pFaces[WEDGE][1].end();
463             ++iterb
464         )
465         {
466             pFaces[CYCLIC][0].append(iterb());
467         }
469         pFaces[WEDGE].clear();
470         nPatches--;
471     }
475 // Build the patches
477 faceListList boundary(nPatches);
478 wordList patchNames(nPatches);
479 wordList patchTypes(nPatches);
480 word defaultFacesName = "defaultFaces";
481 word defaultFacesType = emptyPolyPatch::typeName;
482 wordList patchPhysicalTypes(nPatches);
484 label nAddedPatches = 0;
486 for (int bci=0; bci<nBCs; bci++)
488     forAll (pFaces[bci], rgi)
489     {
490         if (pFaces[bci][rgi].size())
491         {
492             patchTypes[nAddedPatches] = *kivaPatchTypes[bci];
494             patchNames[nAddedPatches] = kivaPatchNames[bci];
496             if (pFaces[bci].size() > 1)
497             {
498                 patchNames[nAddedPatches] += name(rgi+1);
499             }
501             boundary[nAddedPatches] = pFaces[bci][rgi];
502             nAddedPatches++;
503         }
504     }
508 // Remove unused points and update cell and face labels accordingly
510 labelList pointLabels(nPoints, -1);
512 // Scan cells for used points
513 forAll (cellShapes, celli)
515     forAll (cellShapes[celli], i)
516     {
517         pointLabels[cellShapes[celli][i]] = 1;
518     }
521 // Create addressing for used points and pack points array
522 label newPointi = 0;
523 forAll (pointLabels, pointi)
525     if (pointLabels[pointi] != -1)
526     {
527         pointLabels[pointi] = newPointi;
528         points[newPointi++] = points[pointi];
529     }
531 points.setSize(newPointi);
533 // Reset cell point labels
534 forAll (cellShapes, celli)
536     cellShape& cs = cellShapes[celli];
538     forAll (cs, i)
539     {
540         cs[i] = pointLabels[cs[i]];
541     }
544 // Reset boundary-face point labels
545 forAll (boundary, patchi)
547     forAll (boundary[patchi], facei)
548     {
549         face& f = boundary[patchi][facei];
551         forAll (f, i)
552         {
553             f[i] = pointLabels[f[i]];
554         }
555     }
558 preservePatchTypes
560     runTime,
561     runTime.constant(),
562     polyMesh::defaultRegion,
563     patchNames,
564     patchTypes,
565     defaultFacesName,
566     defaultFacesType,
567     patchPhysicalTypes
570 // Build the mesh and write it out
571 polyMesh pShapeMesh
573     IOobject
574     (
575         polyMesh::defaultRegion,
576         runTime.constant(),
577         runTime
578     ),
579     points,
580     cellShapes,
581     boundary,
582     patchNames,
583     patchTypes,
584     defaultFacesName,
585     defaultFacesType,
586     patchPhysicalTypes
589 Info << "Writing polyMesh" << endl;
590 pShapeMesh.write();
592 fileName czPath
594     runTime.path()/runTime.constant()/polyMesh::defaultRegion/"cellZoning"
596 Info << "Writing cell zoning info to file: " << czPath << endl;
597 OFstream cz(czPath);
599 cz << cellZoning << endl;