1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend 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 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. 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 allFaces_.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 // Get 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;
246 // if (found) break; HJ, not needed. Never true
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 allFaces_[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 allFaces_[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 allFaces_[nFaces] = cellsFaceShapes[cellI][faceI];
413 // Reset the size of the face list
414 allFaces_.setSize(nFaces);
415 faces_.reset(allFaces_, nFaces);
421 Foam::polyMesh::polyMesh
424 const Xfer<pointField>& points,
425 const cellShapeList& cellsAsShapes,
426 const faceListList& boundaryFaces,
427 const wordList& boundaryPatchNames,
428 const wordList& boundaryPatchTypes,
429 const word& defaultBoundaryPatchName,
430 const word& defaultBoundaryPatchType,
431 const wordList& boundaryPatchPhysicalTypes,
450 // To be re-sliced later. HJ, 19/oct/2008
451 points_(allPoints_, allPoints_.size()),
465 faces_(allFaces_, allFaces_.size()),
492 clearedPrimitives_(false),
505 boundaryFaces.size() + 1 // add room for a default patch
507 bounds_(allPoints_, syncPar),
508 geometricD_(Vector<label>::zero),
509 solutionD_(Vector<label>::zero),
552 globalMeshDataPtr_(NULL),
555 curMotionTimeIndex_(time().timeIndex()),
556 oldAllPointsPtr_(NULL),
561 Info<<"Constructing polyMesh from cell and boundary shapes." << endl;
564 // Remove all of the old mesh files if they exist
565 removeFiles(instance());
567 // Calculate faces and cells
568 labelList patchSizes;
569 labelList patchStarts;
570 label defaultPatchStart;
585 // Warning: Patches can only be added once the face list is
586 // completed, as they hold a subList of the face list
587 forAll (boundaryFaces, patchI)
589 // add the patch to the list
595 boundaryPatchTypes[patchI],
596 boundaryPatchNames[patchI],
606 boundaryPatchPhysicalTypes.size()
607 && boundaryPatchPhysicalTypes[patchI].size()
610 boundary_[patchI].physicalType() =
611 boundaryPatchPhysicalTypes[patchI];
615 label nAllPatches = boundaryFaces.size();
618 label nDefaultFaces = nFaces - defaultPatchStart;
621 reduce(nDefaultFaces, sumOp<label>());
624 if (nDefaultFaces > 0)
626 WarningIn("polyMesh::polyMesh(... construct from shapes...)")
627 << "Found " << nDefaultFaces
628 << " undefined faces in mesh; adding to default patch." << endl;
630 // Check if there already exists a defaultFaces patch as last patch
632 label patchI = findIndex(boundaryPatchNames, defaultBoundaryPatchName);
636 if (patchI != boundaryFaces.size()-1 || boundary_[patchI].size())
638 FatalErrorIn("polyMesh::polyMesh(... construct from shapes...)")
639 << "Default patch " << boundary_[patchI].name()
640 << " already has faces in it or is not"
641 << " last in list of patches." << exit(FatalError);
644 WarningIn("polyMesh::polyMesh(... construct from shapes...)")
645 << "Reusing existing patch " << patchI
646 << " for undefined faces." << endl;
653 boundary_[patchI].type(),
654 boundary_[patchI].name(),
655 nFaces - defaultPatchStart,
669 defaultBoundaryPatchType,
670 defaultBoundaryPatchName,
671 nFaces - defaultPatchStart,
673 boundary_.size() - 1,
682 // Reset the size of the boundary
683 boundary_.setSize(nAllPatches);
685 // Set the primitive mesh
690 // Calculate topology for the patches (processor-processor comms etc.)
691 boundary_.updateMesh();
693 // Calculate the geometry for the patches (transformation tensors etc.)
694 boundary_.calcGeometry();
701 Info << "Mesh OK" << endl;
707 Foam::polyMesh::polyMesh
710 const Xfer<pointField>& points,
711 const cellShapeList& cellsAsShapes,
712 const faceListList& boundaryFaces,
713 const wordList& boundaryPatchNames,
714 const PtrList<dictionary>& boundaryDicts,
715 const word& defaultBoundaryPatchName,
716 const word& defaultBoundaryPatchType,
735 // To be re-sliced later. HJ, 19/oct/2008
736 points_(allPoints_, allPoints_.size()),
750 faces_(allFaces_, allFaces_.size()),
777 clearedPrimitives_(false),
790 boundaryFaces.size() + 1 // add room for a default patch
792 bounds_(allPoints_, syncPar),
793 geometricD_(Vector<label>::zero),
794 solutionD_(Vector<label>::zero),
837 globalMeshDataPtr_(NULL),
840 curMotionTimeIndex_(time().timeIndex()),
841 oldAllPointsPtr_(NULL),
846 Info<<"Constructing polyMesh from cell and boundary shapes." << endl;
849 // Remove all of the old mesh files if they exist
850 removeFiles(instance());
852 // Calculate faces and cells
853 labelList patchSizes;
854 labelList patchStarts;
855 label defaultPatchStart;
870 // Warning: Patches can only be added once the face list is
871 // completed, as they hold a subList of the face list
872 forAll (boundaryDicts, patchI)
874 dictionary patchDict(boundaryDicts[patchI]);
876 patchDict.set("nFaces", patchSizes[patchI]);
877 patchDict.set("startFace", patchStarts[patchI]);
879 // add the patch to the list
885 boundaryPatchNames[patchI],
893 label nAllPatches = boundaryFaces.size();
895 label nDefaultFaces = nFaces - defaultPatchStart;
898 reduce(nDefaultFaces, sumOp<label>());
901 if (nDefaultFaces > 0)
903 WarningIn("polyMesh::polyMesh(... construct from shapes...)")
904 << "Found " << nDefaultFaces
905 << " undefined faces in mesh; adding to default patch." << endl;
907 // Check if there already exists a defaultFaces patch as last patch
909 label patchI = findIndex(boundaryPatchNames, defaultBoundaryPatchName);
913 if (patchI != boundaryFaces.size()-1 || boundary_[patchI].size())
915 FatalErrorIn("polyMesh::polyMesh(... construct from shapes...)")
916 << "Default patch " << boundary_[patchI].name()
917 << " already has faces in it or is not"
918 << " last in list of patches." << exit(FatalError);
921 WarningIn("polyMesh::polyMesh(... construct from shapes...)")
922 << "Reusing existing patch " << patchI
923 << " for undefined faces." << endl;
930 boundary_[patchI].type(),
931 boundary_[patchI].name(),
932 nFaces - defaultPatchStart,
946 defaultBoundaryPatchType,
947 defaultBoundaryPatchName,
948 nFaces - defaultPatchStart,
950 boundary_.size() - 1,
959 // Reset the size of the boundary
960 boundary_.setSize(nAllPatches);
962 // Set the primitive mesh
967 // Calculate topology for the patches (processor-processor comms etc.)
968 boundary_.updateMesh();
970 // Calculate the geometry for the patches (transformation tensors etc.)
971 boundary_.calcGeometry();
978 Info << "Mesh OK" << endl;
984 // ************************************************************************* //