1 ifstream kivaFile(kivaFileName.c_str());
5 FatalErrorIn(args.executable())
6 << "Cannot open file " << kivaFileName
10 Info << "Reading kiva grid from file " << kivaFileName << endl;
14 kivaFile.getline(title, 120, '\n');
16 label nPoints, nCells, nRegs;
17 kivaFile >> nCells >> nPoints >> nRegs;
19 pointField points(nPoints);
21 labelList idface(nPoints), fv(nPoints);
23 for(label i=0; i<nPoints; i++)
28 >> points[i].x() >> points[i].y() >> points[i].z()
31 if (kivaVersion == kiva3v)
33 kivaFile >> idface[i];
36 // Convert from KIVA cgs units to SI
42 labelList i1tab(nPoints), i3tab(nPoints), i8tab(nPoints), idreg(nPoints),
43 f(nPoints), bcl(nPoints), bcf(nPoints), bcb(nPoints);
47 for(label i=0; i<nPoints; i++)
50 scalar ff, fbcl, fbcf, fbcb;
53 >> i1 >> i3 >> i4 >> i8
54 >> ff >> fbcl >> fbcf >> fbcb
57 // Correct indices to start from 0
62 // Convert scalar indices into hexLabels
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++;
79 FatalErrorIn(args.executable())
80 << "mTable == 0. This is not supported."
81 " kivaToFoam needs complete neighbour information"
86 labelList imtab(nPoints), jmtab(nPoints), kmtab(nPoints);
88 for(label i=0; i<nPoints; i++)
91 kivaFile >> i4 >> im >> jm >> km;
93 // Correct indices to start from 0
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);
117 // Initialise all cells to hex and search and set map for collocated points
118 for(label i=0; i<nPoints; 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();
137 if (edges[ei].mag(points) < SMALL)
139 label start = pointMap[edges[ei].start()];
140 while (start != pointMap[start])
142 start = pointMap[start];
145 label end = pointMap[edges[ei].end()];
146 while (end != pointMap[end])
151 label minLabel = min(start, end);
153 pointMap[start] = pointMap[end] = minLabel;
157 // Grab the cell zoning info
158 cellZoning[activeCells] = idreg[i];
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];
176 cs[i] = pointMap[cs[i]];
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
218 const char* kivaPatchNames[nBCs] =
235 List<SLList<face> > pFaces[nBCs];
240 for(label i=0; i<nPoints; i++)
248 quadFace[0] = i3tab[i];
250 quadFace[2] = i8tab[i];
251 quadFace[3] = i3tab[i8tab[i]];
253 # include "checkPatch.H"
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"
273 quadFace[1] = i1tab[i];
274 quadFace[2] = i8tab[i1tab[i]];
275 quadFace[3] = i8tab[i];
277 # include "checkPatch.H"
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"
297 quadFace[1] = i3tab[i];
298 quadFace[2] = i1tab[i3tab[i]];
299 quadFace[3] = i1tab[i];
301 # include "checkPatch.H"
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"
318 // Tranfer liner faces that are above the minimum cylinder-head z height
319 // into the cylinder-head region
323 && pFaces[LINER][0].size()
324 && pFaces[CYLINDERHEAD].size()
325 && pFaces[CYLINDERHEAD][0].size()
332 SLList<face>::iterator iter = pFaces[CYLINDERHEAD][0].begin();
333 iter != pFaces[CYLINDERHEAD][0].end();
337 const face& pf = iter();
341 minz = min(minz, points[pf[pfi]].z());
347 SLList<face> newLinerFaces;
351 SLList<face>::iterator iter = pFaces[LINER][0].begin();
352 iter != pFaces[LINER][0].end();
356 const face& pf = iter();
358 scalar minfz = GREAT;
361 minfz = min(minfz, points[pf[pfi]].z());
366 pFaces[CYLINDERHEAD][0].append(pf);
370 newLinerFaces.append(pf);
374 if (pFaces[LINER][0].size() != newLinerFaces.size())
376 Info<< "Transfered " << pFaces[LINER][0].size() - newLinerFaces.size()
377 << " faces from liner region to cylinder head" << endl;
378 pFaces[LINER][0] = newLinerFaces;
381 SLList<face> newCylinderHeadFaces;
385 SLList<face>::iterator iter = pFaces[CYLINDERHEAD][0].begin();
386 iter != pFaces[CYLINDERHEAD][0].end();
390 const face& pf = iter();
392 scalar minfz = GREAT;
395 minfz = min(minfz, points[pf[pfi]].z());
398 if (minfz < zHeadMin)
400 pFaces[LINER][0].append(pf);
404 newCylinderHeadFaces.append(pf);
408 if (pFaces[CYLINDERHEAD][0].size() != newCylinderHeadFaces.size())
410 Info<< "Transfered faces from cylinder-head region to linder" << endl;
411 pFaces[CYLINDERHEAD][0] = newCylinderHeadFaces;
416 // Count the number of non-zero sized patches
418 for (int bci=0; bci<nBCs; bci++)
420 forAll (pFaces[bci], rgi)
422 if (pFaces[bci][rgi].size())
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())
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();
444 iterf != pFaces[WEDGE][0].end(), iterb != pFaces[WEDGE][1].end();
448 for (direction d=0; d<4; d++)
450 points[iterf()[d]].y() = -tanTheta*points[iterf()[d]].x();
451 points[iterb()[d]].y() = tanTheta*points[iterb()[d]].x();
457 pFaces[CYCLIC].setSize(1);
458 pFaces[CYCLIC][0] = pFaces[WEDGE][0];
461 SLList<face>::iterator iterb = pFaces[WEDGE][1].begin();
462 iterb != pFaces[WEDGE][1].end();
466 pFaces[CYCLIC][0].append(iterb());
469 pFaces[WEDGE].clear();
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)
490 if (pFaces[bci][rgi].size())
492 patchTypes[nAddedPatches] = *kivaPatchTypes[bci];
494 patchNames[nAddedPatches] = kivaPatchNames[bci];
496 if (pFaces[bci].size() > 1)
498 patchNames[nAddedPatches] += name(rgi+1);
501 boundary[nAddedPatches] = pFaces[bci][rgi];
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)
517 pointLabels[cellShapes[celli][i]] = 1;
521 // Create addressing for used points and pack points array
523 forAll (pointLabels, pointi)
525 if (pointLabels[pointi] != -1)
527 pointLabels[pointi] = newPointi;
528 points[newPointi++] = points[pointi];
531 points.setSize(newPointi);
533 // Reset cell point labels
534 forAll (cellShapes, celli)
536 cellShape& cs = cellShapes[celli];
540 cs[i] = pointLabels[cs[i]];
544 // Reset boundary-face point labels
545 forAll (boundary, patchi)
547 forAll (boundary[patchi], facei)
549 face& f = boundary[patchi][facei];
553 f[i] = pointLabels[f[i]];
562 polyMesh::defaultRegion,
570 // Build the mesh and write it out
575 polyMesh::defaultRegion,
589 Info << "Writing polyMesh" << endl;
594 runTime.path()/runTime.constant()/polyMesh::defaultRegion/"cellZoning"
596 Info << "Writing cell zoning info to file: " << czPath << endl;
599 cz << cellZoning << endl;