Loading...
Searching...
No Matches
readKivaGrid.H
Go to the documentation of this file.
1std::ifstream kivaFile(kivaFileName);
2
3if (!kivaFile.good())
4{
6 << "Cannot open file " << kivaFileName
7 << exit(FatalError);
8}
9
10Info << "Reading kiva grid from file " << kivaFileName << endl;
11
12
13char title[120];
14kivaFile.getline(title, 120, '\n');
15
16label nPoints, nCells, nRegs;
17kivaFile >> nCells >> nPoints >> nRegs;
18
19pointField points(nPoints);
20label i4;
21labelList idface(nPoints), fv(nPoints);
22
23for (label i=0; i<nPoints; i++)
24{
25 scalar ffv;
27 >> i4
28 >> points[i].x() >> points[i].y() >> points[i].z()
29 >> ffv;
30
31 if (kivaVersion == kiva3v)
32 {
33 kivaFile >> idface[i];
34 }
35
36 // Convert from KIVA cgs units to SI
37 points[i] *= 0.01;
38
39 fv[i] = label(ffv);
40}
41
44
45// label nBfaces = 0;
46
47for (label i=0; i<nPoints; i++)
48{
49 label i1, i3, i8;
50 scalar ff, fbcl, fbcf, fbcb;
51
53 >> i1 >> i3 >> i4 >> i8
54 >> ff >> fbcl >> fbcf >> fbcb
55 >> idreg[i];
56
57 // Correct indices to start from 0
58 i1tab[i] = i1 - 1;
59 i3tab[i] = i3 - 1;
60 i8tab[i] = i8 - 1;
61
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);
67
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;
71}
72
73
74label mTable;
76
77if (mTable == 0)
78{
80 << "mTable == 0. This is not supported."
81 " kivaToFoam needs complete neighbour information"
82 << exit(FatalError);
83}
84
85
87
88for (label i=0; i<nPoints; i++)
89{
90 label im, jm, km;
91 kivaFile >> i4 >> im >> jm >> km;
92
93 // Correct indices to start from 0
94 imtab[i] = im - 1;
95 jmtab[i] = jm - 1;
96 kmtab[i] = km - 1;
97}
98
99Info << "Finished reading KIVA file" << endl;
100
102
103labelList cellZoning(nPoints, -1);
104
105const cellModel& hex = cellModel::ref(cellModel::HEX);
106labelList hexLabels(8);
107label activeCells = 0;
108
109// Create and set the collocated point collapse map
110labelList pointMap(nPoints);
111
112forAll(pointMap, i)
113{
114 pointMap[i] = i;
115}
116
117// Initialise all cells to hex and search and set map for collocated points
118for (label i=0; i<nPoints; i++)
119{
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]];
130
131 cellShapes[activeCells].reset(hex, hexLabels);
132
133 edgeList edges = cellShapes[activeCells].edges();
134
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 }
144
145 label end = pointMap[edges[ei].end()];
146 while (end != pointMap[end])
147 {
148 end = pointMap[end];
149 }
150
151 pointMap[start] = pointMap[end] = Foam::min(start, end);
152 }
153 }
154
155 // Grab the cell zoning info
156 cellZoning[activeCells] = idreg[i];
157
158 activeCells++;
159 }
160}
161
162// Contract list of cells to the active ones
163cellShapes.setSize(activeCells);
164cellZoning.setSize(activeCells);
165
166// Map collocated points to refer to the same point and collapse cell shape
167// to the corresponding hex-degenerate.
168forAll(cellShapes, celli)
169{
170 cellShape& cs = cellShapes[celli];
171
172 forAll(cs, i)
173 {
174 cs[i] = pointMap[cs[i]];
175 }
176
177 cs.collapse();
178}
179
180label bcIDs[11] = {-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};
181
182constexpr label nBCs = 12;
183
184const word* kivaPatchTypes[nBCs] =
185{
186 &wallPolyPatch::typeName,
187 &wallPolyPatch::typeName,
188 &wallPolyPatch::typeName,
189 &wallPolyPatch::typeName,
190 &symmetryPolyPatch::typeName,
191 &wedgePolyPatch::typeName,
192 &polyPatch::typeName,
193 &polyPatch::typeName,
194 &polyPatch::typeName,
195 &polyPatch::typeName,
196 &symmetryPolyPatch::typeName,
197 &oldCyclicPolyPatch::typeName
198};
199
200enum patchTypeNames
201{
202 PISTON,
203 VALVE,
204 LINER,
205 CYLINDERHEAD,
206 AXIS,
207 WEDGE,
208 INFLOW,
209 OUTFLOW,
210 PRESIN,
211 PRESOUT,
212 SYMMETRYPLANE,
213 CYCLIC
214};
215
216const char* kivaPatchNames[nBCs] =
217{
218 "piston",
219 "valve",
220 "liner",
221 "cylinderHead",
222 "axis",
223 "wedge",
224 "inflow",
225 "outflow",
226 "presin",
227 "presout",
228 "symmetryPlane",
229 "cyclic"
230};
231
232
233List<DynamicList<face>> pFaces[nBCs];
234
235face quadFace(4);
236face triFace(3);
237
238for (label i=0; i<nPoints; i++)
239{
240 if (f[i] > 0)
241 {
242 // left
243 label bci = bcl[i];
244 if (bci != 4)
245 {
246 quadFace[0] = i3tab[i];
247 quadFace[1] = i;
248 quadFace[2] = i8tab[i];
249 quadFace[3] = i3tab[i8tab[i]];
250
251 #include "checkPatch.H"
252 }
253
254 // right
255 bci = bcl[i1tab[i]];
256 if (bci != 4)
257 {
258 quadFace[0] = i1tab[i];
259 quadFace[1] = i3tab[i1tab[i]];
260 quadFace[2] = i8tab[i3tab[i1tab[i]]];
261 quadFace[3] = i8tab[i1tab[i]];
262
263 #include "checkPatch.H"
264 }
265
266 // front
267 bci = bcf[i];
268 if (bci != 4)
269 {
270 quadFace[0] = i;
271 quadFace[1] = i1tab[i];
272 quadFace[2] = i8tab[i1tab[i]];
273 quadFace[3] = i8tab[i];
274
275 #include "checkPatch.H"
276 }
277
278 // derriere (back)
279 bci = bcf[i3tab[i]];
280 if (bci != 4)
281 {
282 quadFace[0] = i3tab[i];
283 quadFace[1] = i8tab[i3tab[i]];
284 quadFace[2] = i8tab[i1tab[i3tab[i]]];
285 quadFace[3] = i1tab[i3tab[i]];
286
287 #include "checkPatch.H"
288 }
289
290 // bottom
291 bci = bcb[i];
292 if (bci != 4)
293 {
294 quadFace[0] = i;
295 quadFace[1] = i3tab[i];
296 quadFace[2] = i1tab[i3tab[i]];
297 quadFace[3] = i1tab[i];
298
299 #include "checkPatch.H"
300 }
301
302 // top
303 bci = bcb[i8tab[i]];
304 if (bci != 4)
305 {
306 quadFace[0] = i8tab[i];
307 quadFace[1] = i1tab[i8tab[i]];
308 quadFace[2] = i3tab[i1tab[i8tab[i]]];
309 quadFace[3] = i3tab[i8tab[i]];
310
311 #include "checkPatch.H"
312 }
313 }
314}
315
316// Transfer liner faces that are above the minimum cylinder-head z height
317// into the cylinder-head region
319(
320 pFaces[LINER].size()
321 && pFaces[LINER][0].size()
322 && pFaces[CYLINDERHEAD].size()
323 && pFaces[CYLINDERHEAD][0].size()
324)
325{
326 scalar minz = GREAT;
327
328 for (const face& pf : pFaces[CYLINDERHEAD][0])
329 {
330 forAll(pf, pfi)
331 {
332 minz = Foam::min(minz, points[pf[pfi]].z());
333 }
334 }
335
336 minz += SMALL;
337
338 DynamicList<face> newLinerFaces;
339
340 for (const face& pf : pFaces[LINER][0])
341 {
342 scalar minfz = GREAT;
343 for (const label pointi : pf)
344 {
345 minfz = Foam::min(minfz, points[pointi].z());
346 }
347
348 if (minfz > minz)
349 {
350 pFaces[CYLINDERHEAD][0].push_back(pf);
351 }
352 else
353 {
354 newLinerFaces.push_back(pf);
355 }
356 }
357
358 if (pFaces[LINER][0].size() != newLinerFaces.size())
359 {
360 Info<< "Transferred " << pFaces[LINER][0].size() - newLinerFaces.size()
361 << " faces from liner region to cylinder head" << endl;
362 pFaces[LINER][0] = std::move(newLinerFaces);
363 }
364
365 DynamicList<face> newCylinderHeadFaces;
366
367 for (const face& pf : pFaces[CYLINDERHEAD][0])
368 {
369 scalar minfz = GREAT;
370 for (const label pointi : pf)
371 {
372 minfz = Foam::min(minfz, points[pointi].z());
373 }
374
375 if (minfz < zHeadMin)
376 {
377 pFaces[LINER][0].push_back(pf);
378 }
379 else
380 {
381 newCylinderHeadFaces.push_back(pf);
382 }
383 }
384
385 if (pFaces[CYLINDERHEAD][0].size() != newCylinderHeadFaces.size())
386 {
387 Info<< "Transferred faces from cylinder-head region to linder" << endl;
388 pFaces[CYLINDERHEAD][0] = std::move(newCylinderHeadFaces);
389 }
390}
391
392
393// Count the number of non-zero sized patches
394label nPatches = 0;
395for (int bci=0; bci<nBCs; bci++)
396{
397 for (const auto& faces : pFaces[bci])
398 {
399 if (faces.size())
400 {
401 nPatches++;
402 }
403 }
404}
405
406
407// Sort-out the 2D/3D wedge geometry
408if (pFaces[WEDGE].size() && pFaces[WEDGE][0].size())
409{
410 if (pFaces[WEDGE][0].size() == cellShapes.size())
411 {
412 // Distribute the points to be +/- 2.5deg from the x-z plane
413
414 const scalar tanTheta = Foam::tan(degToRad(2.5));
415
416 auto iterf = pFaces[WEDGE][0].cbegin();
417 auto iterb = pFaces[WEDGE][1].cbegin();
418
419 const auto end_iterf = pFaces[WEDGE][0].cend();
420 const auto end_iterb = pFaces[WEDGE][1].cend();
421
422 for
423 (
424 ;
425 (iterf != end_iterf) && (iterb != end_iterb);
426 ++iterf, ++iterb
427 )
428 {
429 const auto& facef = *iterf;
430 const auto& faceb = *iterb;
431
432 for (direction d=0; d<4; d++)
433 {
434 points[facef[d]].y() = -tanTheta*points[facef[d]].x();
435 points[faceb[d]].y() = tanTheta*points[faceb[d]].x();
436 }
437 }
438 }
439 else
440 {
441 pFaces[CYCLIC].resize(1);
442 pFaces[CYCLIC][0] = pFaces[WEDGE][0];
443 pFaces[CYCLIC][0].push_back(pFaces[WEDGE][1]);
444
445 pFaces[WEDGE].clear();
446 nPatches--;
447 }
448}
449
450
451// Build the patches
452
453faceListList boundary(nPatches);
456word defaultFacesName = "defaultFaces";
457word defaultFacesType = emptyPolyPatch::typeName;
458
460
461for (int bci=0; bci<nBCs; bci++)
462{
463 forAll(pFaces[bci], rgi)
464 {
465 if (pFaces[bci][rgi].size())
466 {
467 patchTypes[nAddedPatches] = *kivaPatchTypes[bci];
468
469 patchNames[nAddedPatches] = kivaPatchNames[bci];
470
471 if (pFaces[bci].size() > 1)
472 {
473 patchNames[nAddedPatches] += name(rgi+1);
474 }
475
476 boundary[nAddedPatches] = pFaces[bci][rgi];
478 }
479 }
480}
481
482
483// Remove unused points and update cell and face labels accordingly
484
485labelList pointLabels(nPoints, -1);
486
487// Scan cells for used points
489{
490 forAll(cellShapes[celli], i)
491 {
492 pointLabels[cellShapes[celli][i]] = 1;
493 }
494}
495
496// Create addressing for used points and pack points array
497label newPointi = 0;
499{
500 if (pointLabels[pointi] != -1)
501 {
502 pointLabels[pointi] = newPointi;
503 points[newPointi++] = points[pointi];
504 }
505}
507
508// Reset cell point labels
509forAll(cellShapes, celli)
510{
511 cellShape& cs = cellShapes[celli];
512
513 forAll(cs, i)
514 {
515 cs[i] = pointLabels[cs[i]];
516 }
517}
518
519// Reset boundary-face point labels
521{
522 forAll(boundary[patchi], facei)
523 {
524 face& f = boundary[patchi][facei];
525
526 forAll(f, i)
527 {
528 f[i] = pointLabels[f[i]];
529 }
530 }
531}
532
533PtrList<dictionary> patchDicts;
535(
536 runTime,
537 runTime.constant(),
538 polyMesh::meshSubDir,
543);
544// Add information to dictionary
546{
547 if (!patchDicts.set(patchi))
548 {
549 patchDicts.set(patchi, new dictionary());
550 }
551 // Add but not overwrite
552 patchDicts[patchi].add("type", patchTypes[patchi], false);
553}
554
555// Build the mesh and write it out
557(
558 IOobject
559 (
560 polyMesh::defaultRegion,
561 runTime.constant(),
562 runTime
563 ),
564 std::move(points),
566 boundary,
571);
572
573// More precision (for points data)
574IOstream::minPrecision(10);
575
576Info << "Writing polyMesh" << endl;
577pShapeMesh.removeFiles();
578pShapeMesh.write();
579
580fileName czPath
581(
582 runTime.path()/runTime.constant()/polyMesh::defaultRegion/"cellZoning"
583);
584Info << "Writing cell zoning info to file: " << czPath << endl;
585OFstream cz(czPath);
586
587cz << cellZoning << endl;
cellShapeList cellShapes
faceListList boundary
engineTime & runTime
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
auto & name
const pointField & points
label nPoints
const char * end
Definition SVGTools.H:223
List< edge > edgeList
List of edge.
Definition edgeList.H:32
dimensionedScalar tan(const dimensionedScalar &ds)
List< label > labelList
A List of labels.
Definition List.H:62
messageStream Info
Information stream (stdout output on master, null elsewhere).
IOstream & hex(IOstream &io)
Definition IOstream.H:579
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:26
List< cellShape > cellShapeList
List of cellShape.
wordList patchTypes(nPatches)
labelList i3tab(nPoints)
labelList kmtab(nPoints)
labelList idreg(nPoints)
wordList patchNames(nPatches)
labelList bcl(nPoints)
label i4
labelList i1tab(nPoints)
PtrList< dictionary > patchDicts
label newPointi
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=cellModel::ref(cellModel::HEX);labelList hexLabels(8);label activeCells=0;labelList pointMap(nPoints);forAll(pointMap, i){ pointMap[i]=i;}for(label i=0;i< nPoints;i++){ if(f[i] > 0.0) { hexLabels[0]=i;hexLabels[1]=i1tab[i];hexLabels[2]=i3tab[i1tab[i]];hexLabels[3]=i3tab[i];hexLabels[4]=i8tab[i];hexLabels[5]=i1tab[i8tab[i]];hexLabels[6]=i3tab[i1tab[i8tab[i]]];hexLabels[7]=i3tab[i8tab[i]];cellShapes[activeCells].reset(hex, hexLabels);edgeList edges=cellShapes[activeCells].edges();forAll(edges, ei) { if(edges[ei].mag(points)< SMALL) { label start=pointMap[edges[ei].start()];while(start !=pointMap[start]) { start=pointMap[start];} label end=pointMap[edges[ei].end()];while(end !=pointMap[end]) { end=pointMap[end];} pointMap[start]=pointMap[end]=Foam::min(start, end);} } cellZoning[activeCells]=idreg[i];activeCells++;}}cellShapes.setSize(activeCells);cellZoning.setSize(activeCells);forAll(cellShapes, celli){ cellShape &cs=cellShapes[celli];forAll(cs, i) { cs[i]=pointMap[cs[i]];} cs.collapse();}label bcIDs[11]={-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};constexpr label nBCs=12;const word *kivaPatchTypes[nBCs]={ &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &symmetryPolyPatch::typeName, &wedgePolyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &symmetryPolyPatch::typeName, &oldCyclicPolyPatch::typeName};enum patchTypeNames{ PISTON, VALVE, LINER, CYLINDERHEAD, AXIS, WEDGE, INFLOW, OUTFLOW, PRESIN, PRESOUT, SYMMETRYPLANE, CYCLIC};const char *kivaPatchNames[nBCs]={ "piston", "valve", "liner", "cylinderHead", "axis", "wedge", "inflow", "outflow", "presin", "presout", "symmetryPlane", "cyclic"};List< DynamicList< face > > pFaces[nBCs]
face quadFace(4)
labelList imtab(nPoints)
labelList jmtab(nPoints)
polyMesh pShapeMesh(IOobject(polyMesh::defaultRegion, runTime.constant(), runTime), std::move(points), cellShapes, boundary, patchNames, patchDicts, defaultFacesName, defaultFacesType)
face triFace(3)
labelList f(nPoints)
labelList idface(nPoints)
labelList pointLabels(nPoints, -1)
Info<< "Reading kiva grid from file "<< kivaFileName<< endl;char title[120];kivaFile.getline(title, 120, '\n');label nPoints, nCells, nRegs;kivaFile > nCells nPoints nRegs
label nAddedPatches
word defaultFacesName
labelList i8tab(nPoints)
labelList bcf(nPoints)
word defaultFacesType
preservePatchTypes(runTime, runTime.constant(), polyMesh::meshSubDir, patchNames, patchDicts, defaultFacesName, defaultFacesType)
labelList bcb(nPoints)
labelList fv(nPoints)
label mTable
std::ifstream kivaFile(kivaFileName)
label nPatches
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299