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 &oldCyclicPolyPatch::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 // Transfer 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()
330 forAllConstIter(SLList<face>, pFaces[CYLINDERHEAD][0], iter)
332 const face& pf = iter();
336 minz = min(minz, points[pf[pfi]].z());
342 SLList<face> newLinerFaces;
344 forAllConstIter(SLList<face>, pFaces[LINER][0], iter)
346 const face& pf = iter();
348 scalar minfz = GREAT;
351 minfz = min(minfz, points[pf[pfi]].z());
356 pFaces[CYLINDERHEAD][0].append(pf);
360 newLinerFaces.append(pf);
364 if (pFaces[LINER][0].size() != newLinerFaces.size())
366 Info<< "Transfered " << pFaces[LINER][0].size() - newLinerFaces.size()
367 << " faces from liner region to cylinder head" << endl;
368 pFaces[LINER][0] = newLinerFaces;
371 SLList<face> newCylinderHeadFaces;
373 forAllConstIter(SLList<face>, pFaces[CYLINDERHEAD][0], iter)
375 const face& pf = iter();
377 scalar minfz = GREAT;
380 minfz = min(minfz, points[pf[pfi]].z());
383 if (minfz < zHeadMin)
385 pFaces[LINER][0].append(pf);
389 newCylinderHeadFaces.append(pf);
393 if (pFaces[CYLINDERHEAD][0].size() != newCylinderHeadFaces.size())
395 Info<< "Transfered faces from cylinder-head region to linder" << endl;
396 pFaces[CYLINDERHEAD][0] = newCylinderHeadFaces;
401 // Count the number of non-zero sized patches
403 for (int bci=0; bci<nBCs; bci++)
405 forAll(pFaces[bci], rgi)
407 if (pFaces[bci][rgi].size())
415 // Sort-out the 2D/3D wedge geometry
416 if (pFaces[WEDGE].size() && pFaces[WEDGE][0].size())
418 if (pFaces[WEDGE][0].size() == cellShapes.size())
420 // Distribute the points to be +/- 2.5deg from the x-z plane
422 scalar tanTheta = Foam::tan(degToRad(2.5));
424 SLList<face>::iterator iterf = pFaces[WEDGE][0].begin();
425 SLList<face>::iterator iterb = pFaces[WEDGE][1].begin();
429 iterf != pFaces[WEDGE][0].end(), iterb != pFaces[WEDGE][1].end();
433 for (direction d=0; d<4; d++)
435 points[iterf()[d]].y() = -tanTheta*points[iterf()[d]].x();
436 points[iterb()[d]].y() = tanTheta*points[iterb()[d]].x();
442 pFaces[CYCLIC].setSize(1);
443 pFaces[CYCLIC][0] = pFaces[WEDGE][0];
444 forAllIter(SLList<face>, pFaces[WEDGE][1], iterb)
446 pFaces[CYCLIC][0].append(iterb());
449 pFaces[WEDGE].clear();
457 faceListList boundary(nPatches);
458 wordList patchNames(nPatches);
459 wordList patchTypes(nPatches);
460 word defaultFacesName = "defaultFaces";
461 word defaultFacesType = emptyPolyPatch::typeName;
463 label nAddedPatches = 0;
465 for (int bci=0; bci<nBCs; bci++)
467 forAll(pFaces[bci], rgi)
469 if (pFaces[bci][rgi].size())
471 patchTypes[nAddedPatches] = *kivaPatchTypes[bci];
473 patchNames[nAddedPatches] = kivaPatchNames[bci];
475 if (pFaces[bci].size() > 1)
477 patchNames[nAddedPatches] += name(rgi+1);
480 boundary[nAddedPatches] = pFaces[bci][rgi];
487 // Remove unused points and update cell and face labels accordingly
489 labelList pointLabels(nPoints, -1);
491 // Scan cells for used points
492 forAll(cellShapes, celli)
494 forAll(cellShapes[celli], i)
496 pointLabels[cellShapes[celli][i]] = 1;
500 // Create addressing for used points and pack points array
502 forAll(pointLabels, pointi)
504 if (pointLabels[pointi] != -1)
506 pointLabels[pointi] = newPointi;
507 points[newPointi++] = points[pointi];
510 points.setSize(newPointi);
512 // Reset cell point labels
513 forAll(cellShapes, celli)
515 cellShape& cs = cellShapes[celli];
519 cs[i] = pointLabels[cs[i]];
523 // Reset boundary-face point labels
524 forAll(boundary, patchi)
526 forAll(boundary[patchi], facei)
528 face& f = boundary[patchi][facei];
532 f[i] = pointLabels[f[i]];
537 PtrList<dictionary> patchDicts;
542 polyMesh::meshSubDir,
548 // Add information to dictionary
549 forAll(patchNames, patchI)
551 if (!patchDicts.set(patchI))
553 patchDicts.set(patchI, new dictionary());
555 // Add but not overwrite
556 patchDicts[patchI].add("type", patchTypes[patchI], false);
559 // Build the mesh and write it out
564 polyMesh::defaultRegion,
577 Info << "Writing polyMesh" << endl;
582 runTime.path()/runTime.constant()/polyMesh::defaultRegion/"cellZoning"
584 Info << "Writing cell zoning info to file: " << czPath << endl;
587 cz << cellZoning << endl;