1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM 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 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 Create polyMesh from cell and patch shapes
28 \*---------------------------------------------------------------------------*/
31 #include <OpenFOAM/Time.H>
32 #include <OpenFOAM/primitiveMesh.H>
33 #include <OpenFOAM/DynamicList.H>
35 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
37 Foam::labelListList Foam::polyMesh::cellShapePointCells
39 const cellShapeList& c
42 List<DynamicList<label, primitiveMesh::cellsPerPoint_> >
49 const labelList& labels = c[i];
53 // Set working point label
54 label curPoint = labels[j];
55 DynamicList<label, primitiveMesh::cellsPerPoint_>& curPointCells =
58 // Enter the cell label in the point's cell list
59 curPointCells.append(i);
63 labelListList pointCellAddr(pc.size());
67 pointCellAddr[pointI].transfer(pc[pointI]);
74 Foam::labelList Foam::polyMesh::facePatchFaceCells
76 const faceList& patchFaces,
77 const labelListList& pointCells,
78 const faceListList& cellsFaceShapes,
84 labelList FaceCells(patchFaces.size());
86 forAll(patchFaces, fI)
90 const face& curFace = patchFaces[fI];
91 const labelList& facePoints = patchFaces[fI];
93 forAll(facePoints, pointI)
95 const labelList& facePointCells = pointCells[facePoints[pointI]];
97 forAll(facePointCells, cellI)
99 faceList cellFaces = cellsFaceShapes[facePointCells[cellI]];
101 forAll(cellFaces, cellFace)
103 if (cellFaces[cellFace] == curFace)
105 // Found the cell corresponding to this face
106 FaceCells[fI] = facePointCells[cellI];
121 "polyMesh::facePatchFaceCells(const faceList& patchFaces,"
122 "const labelListList& pointCells,"
123 "const faceListList& cellsFaceShapes,"
124 "const label patchID)"
125 ) << "face " << fI << " in patch " << patchID
126 << " does not have neighbour cell"
127 << " face: " << patchFaces[fI]
128 << abort(FatalError);
136 Foam::polyMesh::polyMesh
139 const Xfer<pointField>& points,
140 const cellShapeList& cellsAsShapes,
141 const faceListList& boundaryFaces,
142 const wordList& boundaryPatchNames,
143 const wordList& boundaryPatchTypes,
144 const word& defaultBoundaryPatchName,
145 const word& defaultBoundaryPatchType,
146 const wordList& boundaryPatchPhysicalTypes,
204 clearedPrimitives_(false),
217 boundaryFaces.size() + 1 // add room for a default patch
219 bounds_(points_, syncPar),
220 geometricD_(Vector<label>::zero),
221 solutionD_(Vector<label>::zero),
264 globalMeshDataPtr_(NULL),
266 curMotionTimeIndex_(time().timeIndex()),
271 Info<<"Constructing polyMesh from cell and boundary shapes." << endl;
274 // Remove all of the old mesh files if they exist
275 removeFiles(instance());
277 // Calculate the faces of all cells
278 // Initialise maximum possible numer of mesh faces to 0
281 // Set up a list of face shapes for each cell
282 faceListList cellsFaceShapes(cellsAsShapes.size());
283 cellList cells(cellsAsShapes.size());
285 forAll(cellsFaceShapes, cellI)
287 cellsFaceShapes[cellI] = cellsAsShapes[cellI].faces();
289 cells[cellI].setSize(cellsFaceShapes[cellI].size());
291 // Initialise cells to -1 to flag undefined faces
292 static_cast<labelList&>(cells[cellI]) = -1;
294 // Count maximum possible numer of mesh faces
295 maxFaces += cellsFaceShapes[cellI].size();
298 // Set size of faces array to maximum possible number of mesh faces
299 faces_.setSize(maxFaces);
301 // Initialise number of faces to 0
304 // set reference to point-cell addressing
305 labelListList PointCells = cellShapePointCells(cellsAsShapes);
312 // Insertion cannot be done in one go as the faces need to be
313 // added into the list in the increasing order of neighbour
314 // cells. Therefore, all neighbours will be detected first
315 // and then added in the correct order.
317 const faceList& curFaces = cellsFaceShapes[cellI];
319 // Record the neighbour cell
320 labelList neiCells(curFaces.size(), -1);
322 // Record the face of neighbour cell
323 labelList faceOfNeiCell(curFaces.size(), -1);
325 label nNeighbours = 0;
328 forAll(curFaces, faceI)
330 // Skip faces that have already been matched
331 if (cells[cellI][faceI] >= 0) continue;
335 const face& curFace = curFaces[faceI];
337 // Get the list of labels
338 const labelList& curPoints = curFace;
341 forAll(curPoints, pointI)
343 // dGget the list of cells sharing this point
344 const labelList& curNeighbours =
345 PointCells[curPoints[pointI]];
347 // For all neighbours
348 forAll(curNeighbours, neiI)
350 label curNei = curNeighbours[neiI];
352 // Reject neighbours with the lower label
355 // Get the list of search faces
356 const faceList& searchFaces = cellsFaceShapes[curNei];
358 forAll(searchFaces, neiFaceI)
360 if (searchFaces[neiFaceI] == curFace)
365 // Record the neighbour cell and face
366 neiCells[faceI] = curNei;
367 faceOfNeiCell[faceI] = neiFaceI;
378 } // End of current points
379 } // End of current faces
381 // Add the faces in the increasing order of neighbours
382 for (label neiSearch = 0; neiSearch < nNeighbours; neiSearch++)
384 // Find the lowest neighbour which is still valid
386 label minNei = cells.size();
388 forAll (neiCells, ncI)
390 if (neiCells[ncI] > -1 && neiCells[ncI] < minNei)
393 minNei = neiCells[ncI];
399 // Add the face to the list of faces
400 faces_[nFaces] = curFaces[nextNei];
402 // Set cell-face and cell-neighbour-face to current face label
403 cells[cellI][nextNei] = nFaces;
404 cells[neiCells[nextNei]][faceOfNeiCell[nextNei]] = nFaces;
406 // Stop the neighbour from being used again
407 neiCells[nextNei] = -1;
409 // Increment number of faces counter
416 "polyMesh::polyMesh\n"
418 " const IOobject&,\n"
419 " const Xfer<pointField>&,\n"
420 " const cellShapeList& cellsAsShapes,\n"
421 " const faceListList& boundaryFaces,\n"
422 " const wordList& boundaryPatchTypes,\n"
423 " const wordList& boundaryPatchNames,\n"
424 " const word& defaultBoundaryPatchType\n"
426 ) << "Error in internal face insertion"
427 << abort(FatalError);
434 labelList patchSizes(boundaryFaces.size(), -1);
435 labelList patchStarts(boundaryFaces.size(), -1);
437 forAll (boundaryFaces, patchI)
439 const faceList& patchFaces = boundaryFaces[patchI];
441 labelList curPatchFaceCells =
450 // Grab the start label
451 label curPatchStart = nFaces;
453 forAll (patchFaces, faceI)
455 const face& curFace = patchFaces[faceI];
457 const label cellInside = curPatchFaceCells[faceI];
459 faces_[nFaces] = curFace;
461 // get faces of the cell inside
462 const faceList& facesOfCellInside = cellsFaceShapes[cellInside];
466 forAll (facesOfCellInside, cellFaceI)
468 if (facesOfCellInside[cellFaceI] == curFace)
470 if (cells[cellInside][cellFaceI] >= 0)
474 "polyMesh::polyMesh\n"
476 " const IOobject&,\n"
477 " const Xfer<pointField>&,\n"
478 " const cellShapeList& cellsAsShapes,\n"
479 " const faceListList& boundaryFaces,\n"
480 " const wordList& boundaryPatchTypes,\n"
481 " const wordList& boundaryPatchNames,\n"
482 " const word& defaultBoundaryPatchType\n"
484 ) << "Trying to specify a boundary face " << curFace
485 << " on the face on cell " << cellInside
486 << " which is either an internal face or already "
487 << "belongs to some other patch. This is face "
488 << faceI << " of patch "
489 << patchI << " named "
490 << boundaryPatchNames[patchI] << "."
491 << abort(FatalError);
496 cells[cellInside][cellFaceI] = nFaces;
504 FatalErrorIn("polyMesh::polyMesh(... construct from shapes...)")
505 << "face " << faceI << " of patch " << patchI
506 << " does not seem to belong to cell " << cellInside
507 << " which, according to the addressing, "
508 << "should be next to it."
509 << abort(FatalError);
512 // increment the counter of faces
516 patchSizes[patchI] = nFaces - curPatchStart;
517 patchStarts[patchI] = curPatchStart;
520 // Grab "non-existing" faces and put them into a default patch
522 label defaultPatchStart = nFaces;
526 labelList& curCellFaces = cells[cellI];
528 forAll(curCellFaces, faceI)
530 if (curCellFaces[faceI] == -1) // "non-existent" face
532 curCellFaces[faceI] = nFaces;
533 faces_[nFaces] = cellsFaceShapes[cellI][faceI];
540 // Reset the size of the face list
541 faces_.setSize(nFaces);
543 // Warning: Patches can only be added once the face list is
544 // completed, as they hold a subList of the face list
545 forAll (boundaryFaces, patchI)
547 // add the patch to the list
553 boundaryPatchTypes[patchI],
554 boundaryPatchNames[patchI],
564 boundaryPatchPhysicalTypes.size()
565 && boundaryPatchPhysicalTypes[patchI].size()
568 boundary_[patchI].physicalType() =
569 boundaryPatchPhysicalTypes[patchI];
573 label nAllPatches = boundaryFaces.size();
575 if (nFaces > defaultPatchStart)
577 WarningIn("polyMesh::polyMesh(... construct from shapes...)")
578 << "Found " << nFaces - defaultPatchStart
579 << " undefined faces in mesh; adding to default patch." << endl;
586 defaultBoundaryPatchType,
587 defaultBoundaryPatchName,
588 nFaces - defaultPatchStart,
590 boundary_.size() - 1,
598 // Reset the size of the boundary
599 boundary_.setSize(nAllPatches);
601 // Set the primitive mesh
606 // Calculate topology for the patches (processor-processor comms etc.)
607 boundary_.updateMesh();
609 // Calculate the geometry for the patches (transformation tensors etc.)
610 boundary_.calcGeometry();
617 Info << "Mesh OK" << endl;
623 // ************************ vim: set sw=4 sts=4 et: ************************ //