1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, see <http://www.gnu.org/licenses/>.
25 Create polyMesh from cell and patch shapes
27 \*---------------------------------------------------------------------------*/
31 #include "primitiveMesh.H"
32 #include "DynamicList.H"
34 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
36 Foam::labelListList Foam::polyMesh::cellShapePointCells
38 const cellShapeList& c
41 List<DynamicList<label, primitiveMesh::cellsPerPoint_> >
48 const labelList& labels = c[i];
52 // Set working point label
53 label curPoint = labels[j];
54 DynamicList<label, primitiveMesh::cellsPerPoint_>& curPointCells =
57 // Enter the cell label in the point's cell list
58 curPointCells.append(i);
62 labelListList pointCellAddr(pc.size());
66 pointCellAddr[pointI].transfer(pc[pointI]);
73 Foam::labelList Foam::polyMesh::facePatchFaceCells
75 const faceList& patchFaces,
76 const labelListList& pointCells,
77 const faceListList& cellsFaceShapes,
83 labelList FaceCells(patchFaces.size());
85 forAll(patchFaces, fI)
89 const face& curFace = patchFaces[fI];
90 const labelList& facePoints = patchFaces[fI];
92 forAll(facePoints, pointI)
94 const labelList& facePointCells = pointCells[facePoints[pointI]];
96 forAll(facePointCells, cellI)
98 faceList cellFaces = cellsFaceShapes[facePointCells[cellI]];
100 forAll(cellFaces, cellFace)
102 if (cellFaces[cellFace] == curFace)
104 // Found the cell corresponding to this face
105 FaceCells[fI] = facePointCells[cellI];
120 "polyMesh::facePatchFaceCells(const faceList& patchFaces,"
121 "const labelListList& pointCells,"
122 "const faceListList& cellsFaceShapes,"
123 "const label patchID)"
124 ) << "face " << fI << " in patch " << patchID
125 << " does not have neighbour cell"
126 << " face: " << patchFaces[fI]
127 << abort(FatalError);
135 //- Set faces_, calculate cells and patchStarts.
136 void Foam::polyMesh::setTopology
138 const cellShapeList& cellsAsShapes,
139 const faceListList& boundaryFaces,
140 const wordList& boundaryPatchNames,
141 labelList& patchSizes,
142 labelList& patchStarts,
143 label& defaultPatchStart,
148 // Calculate the faces of all cells
149 // Initialise maximum possible numer of mesh faces to 0
152 // Set up a list of face shapes for each cell
153 faceListList cellsFaceShapes(cellsAsShapes.size());
154 cells.setSize(cellsAsShapes.size());
156 forAll(cellsFaceShapes, cellI)
158 cellsFaceShapes[cellI] = cellsAsShapes[cellI].faces();
160 cells[cellI].setSize(cellsFaceShapes[cellI].size());
162 // Initialise cells to -1 to flag undefined faces
163 static_cast<labelList&>(cells[cellI]) = -1;
165 // Count maximum possible numer of mesh faces
166 maxFaces += cellsFaceShapes[cellI].size();
169 // Set size of faces array to maximum possible number of mesh faces
170 faces_.setSize(maxFaces);
172 // Initialise number of faces to 0
175 // set reference to point-cell addressing
176 labelListList PointCells = cellShapePointCells(cellsAsShapes);
183 // Insertion cannot be done in one go as the faces need to be
184 // added into the list in the increasing order of neighbour
185 // cells. Therefore, all neighbours will be detected first
186 // and then added in the correct order.
188 const faceList& curFaces = cellsFaceShapes[cellI];
190 // Record the neighbour cell
191 labelList neiCells(curFaces.size(), -1);
193 // Record the face of neighbour cell
194 labelList faceOfNeiCell(curFaces.size(), -1);
196 label nNeighbours = 0;
199 forAll(curFaces, faceI)
201 // Skip faces that have already been matched
202 if (cells[cellI][faceI] >= 0) continue;
206 const face& curFace = curFaces[faceI];
208 // Get the list of labels
209 const labelList& curPoints = curFace;
212 forAll(curPoints, pointI)
214 // dGget the list of cells sharing this point
215 const labelList& curNeighbours =
216 PointCells[curPoints[pointI]];
218 // For all neighbours
219 forAll(curNeighbours, neiI)
221 label curNei = curNeighbours[neiI];
223 // Reject neighbours with the lower label
226 // Get the list of search faces
227 const faceList& searchFaces = cellsFaceShapes[curNei];
229 forAll(searchFaces, neiFaceI)
231 if (searchFaces[neiFaceI] == curFace)
236 // Record the neighbour cell and face
237 neiCells[faceI] = curNei;
238 faceOfNeiCell[faceI] = neiFaceI;
249 } // End of current points
250 } // End of current faces
252 // Add the faces in the increasing order of neighbours
253 for (label neiSearch = 0; neiSearch < nNeighbours; neiSearch++)
255 // Find the lowest neighbour which is still valid
257 label minNei = cells.size();
259 forAll(neiCells, ncI)
261 if (neiCells[ncI] > -1 && neiCells[ncI] < minNei)
264 minNei = neiCells[ncI];
270 // Add the face to the list of faces
271 faces_[nFaces] = curFaces[nextNei];
273 // Set cell-face and cell-neighbour-face to current face label
274 cells[cellI][nextNei] = nFaces;
275 cells[neiCells[nextNei]][faceOfNeiCell[nextNei]] = nFaces;
277 // Stop the neighbour from being used again
278 neiCells[nextNei] = -1;
280 // Increment number of faces counter
287 "polyMesh::setTopology\n"
289 " const cellShapeList& cellsAsShapes,\n"
290 " const faceListList& boundaryFaces,\n"
291 " const wordList& boundaryPatchNames,\n"
292 " labelList& patchSizes,\n"
293 " labelList& patchStarts,\n"
294 " label& defaultPatchStart,\n"
298 ) << "Error in internal face insertion"
299 << abort(FatalError);
306 patchSizes.setSize(boundaryFaces.size(), -1);
307 patchStarts.setSize(boundaryFaces.size(), -1);
309 forAll(boundaryFaces, patchI)
311 const faceList& patchFaces = boundaryFaces[patchI];
313 labelList curPatchFaceCells =
322 // Grab the start label
323 label curPatchStart = nFaces;
325 forAll(patchFaces, faceI)
327 const face& curFace = patchFaces[faceI];
329 const label cellInside = curPatchFaceCells[faceI];
331 faces_[nFaces] = curFace;
333 // get faces of the cell inside
334 const faceList& facesOfCellInside = cellsFaceShapes[cellInside];
338 forAll(facesOfCellInside, cellFaceI)
340 if (facesOfCellInside[cellFaceI] == curFace)
342 if (cells[cellInside][cellFaceI] >= 0)
346 "polyMesh::setTopology\n"
348 " const cellShapeList& cellsAsShapes,\n"
349 " const faceListList& boundaryFaces,\n"
350 " const wordList& boundaryPatchNames,\n"
351 " labelList& patchSizes,\n"
352 " labelList& patchStarts,\n"
353 " label& defaultPatchStart,\n"
357 ) << "Trying to specify a boundary face " << curFace
358 << " on the face on cell " << cellInside
359 << " which is either an internal face or already "
360 << "belongs to some other patch. This is face "
361 << faceI << " of patch "
362 << patchI << " named "
363 << boundaryPatchNames[patchI] << "."
364 << abort(FatalError);
369 cells[cellInside][cellFaceI] = nFaces;
377 FatalErrorIn("polyMesh::polyMesh(... construct from shapes...)")
378 << "face " << faceI << " of patch " << patchI
379 << " does not seem to belong to cell " << cellInside
380 << " which, according to the addressing, "
381 << "should be next to it."
382 << abort(FatalError);
385 // increment the counter of faces
389 patchSizes[patchI] = nFaces - curPatchStart;
390 patchStarts[patchI] = curPatchStart;
393 // Grab "non-existing" faces and put them into a default patch
395 defaultPatchStart = nFaces;
399 labelList& curCellFaces = cells[cellI];
401 forAll(curCellFaces, faceI)
403 if (curCellFaces[faceI] == -1) // "non-existent" face
405 curCellFaces[faceI] = nFaces;
406 faces_[nFaces] = cellsFaceShapes[cellI][faceI];
413 // Reset the size of the face list
414 faces_.setSize(nFaces);
420 Foam::polyMesh::polyMesh
423 const Xfer<pointField>& points,
424 const cellShapeList& cellsAsShapes,
425 const faceListList& boundaryFaces,
426 const wordList& boundaryPatchNames,
427 const wordList& boundaryPatchTypes,
428 const word& defaultBoundaryPatchName,
429 const word& defaultBoundaryPatchType,
430 const wordList& boundaryPatchPhysicalTypes,
488 clearedPrimitives_(false),
501 boundaryFaces.size() + 1 // add room for a default patch
503 bounds_(points_, syncPar),
504 geometricD_(Vector<label>::zero),
505 solutionD_(Vector<label>::zero),
506 tetBasePtIsPtr_(NULL),
549 globalMeshDataPtr_(NULL),
551 curMotionTimeIndex_(time().timeIndex()),
556 Info<<"Constructing polyMesh from cell and boundary shapes." << endl;
559 // Remove all of the old mesh files if they exist
560 removeFiles(instance());
562 // Calculate faces and cells
563 labelList patchSizes;
564 labelList patchStarts;
565 label defaultPatchStart;
580 // Warning: Patches can only be added once the face list is
581 // completed, as they hold a subList of the face list
582 forAll(boundaryFaces, patchI)
584 // add the patch to the list
590 boundaryPatchTypes[patchI],
591 boundaryPatchNames[patchI],
601 boundaryPatchPhysicalTypes.size()
602 && boundaryPatchPhysicalTypes[patchI].size()
605 boundary_[patchI].physicalType() =
606 boundaryPatchPhysicalTypes[patchI];
610 label nAllPatches = boundaryFaces.size();
612 if (nFaces > defaultPatchStart)
614 WarningIn("polyMesh::polyMesh(... construct from shapes...)")
615 << "Found " << nFaces - defaultPatchStart
616 << " undefined faces in mesh; adding to default patch." << endl;
618 // Check if there already exists a defaultFaces patch as last patch
620 label patchI = findIndex(boundaryPatchNames, defaultBoundaryPatchName);
624 if (patchI != boundaryFaces.size()-1 || boundary_[patchI].size())
626 FatalErrorIn("polyMesh::polyMesh(... construct from shapes...)")
627 << "Default patch " << boundary_[patchI].name()
628 << " already has faces in it or is not"
629 << " last in list of patches." << exit(FatalError);
632 WarningIn("polyMesh::polyMesh(... construct from shapes...)")
633 << "Reusing existing patch " << patchI
634 << " for undefined faces." << endl;
641 boundaryPatchTypes[patchI],
642 boundaryPatchNames[patchI],
643 nFaces - defaultPatchStart,
657 defaultBoundaryPatchType,
658 defaultBoundaryPatchName,
659 nFaces - defaultPatchStart,
661 boundary_.size() - 1,
670 // Reset the size of the boundary
671 boundary_.setSize(nAllPatches);
673 // Set the primitive mesh
678 // Calculate topology for the patches (processor-processor comms etc.)
679 boundary_.updateMesh();
681 // Calculate the geometry for the patches (transformation tensors etc.)
682 boundary_.calcGeometry();
689 Info<< "Mesh OK" << endl;
695 Foam::polyMesh::polyMesh
698 const Xfer<pointField>& points,
699 const cellShapeList& cellsAsShapes,
700 const faceListList& boundaryFaces,
701 const wordList& boundaryPatchNames,
702 const PtrList<dictionary>& boundaryDicts,
703 const word& defaultBoundaryPatchName,
704 const word& defaultBoundaryPatchType,
762 clearedPrimitives_(false),
775 boundaryFaces.size() + 1 // add room for a default patch
777 bounds_(points_, syncPar),
778 geometricD_(Vector<label>::zero),
779 solutionD_(Vector<label>::zero),
780 tetBasePtIsPtr_(NULL),
823 globalMeshDataPtr_(NULL),
825 curMotionTimeIndex_(time().timeIndex()),
830 Info<<"Constructing polyMesh from cell and boundary shapes." << endl;
833 // Remove all of the old mesh files if they exist
834 removeFiles(instance());
836 // Calculate faces and cells
837 labelList patchSizes;
838 labelList patchStarts;
839 label defaultPatchStart;
854 // Warning: Patches can only be added once the face list is
855 // completed, as they hold a subList of the face list
856 forAll(boundaryDicts, patchI)
858 dictionary patchDict(boundaryDicts[patchI]);
860 patchDict.set("nFaces", patchSizes[patchI]);
861 patchDict.set("startFace", patchStarts[patchI]);
863 // add the patch to the list
869 boundaryPatchNames[patchI],
877 label nAllPatches = boundaryFaces.size();
879 if (nFaces > defaultPatchStart)
881 WarningIn("polyMesh::polyMesh(... construct from shapes...)")
882 << "Found " << nFaces - defaultPatchStart
883 << " undefined faces in mesh; adding to default patch." << endl;
885 // Check if there already exists a defaultFaces patch as last patch
887 label patchI = findIndex(boundaryPatchNames, defaultBoundaryPatchName);
891 if (patchI != boundaryFaces.size()-1 || boundary_[patchI].size())
893 FatalErrorIn("polyMesh::polyMesh(... construct from shapes...)")
894 << "Default patch " << boundary_[patchI].name()
895 << " already has faces in it or is not"
896 << " last in list of patches." << exit(FatalError);
899 WarningIn("polyMesh::polyMesh(... construct from shapes...)")
900 << "Reusing existing patch " << patchI
901 << " for undefined faces." << endl;
908 boundary_[patchI].type(),
909 boundary_[patchI].name(),
910 nFaces - defaultPatchStart,
924 defaultBoundaryPatchType,
925 defaultBoundaryPatchName,
926 nFaces - defaultPatchStart,
928 boundary_.size() - 1,
937 // Reset the size of the boundary
938 boundary_.setSize(nAllPatches);
940 // Set the primitive mesh
945 // Calculate topology for the patches (processor-processor comms etc.)
946 boundary_.updateMesh();
948 // Calculate the geometry for the patches (transformation tensors etc.)
949 boundary_.calcGeometry();
956 Info << "Mesh OK" << endl;
962 // ************************************************************************* //