1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2008 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
25 \*---------------------------------------------------------------------------*/
27 #include "addPatchCellLayer.H"
29 #include "polyTopoChange.H"
30 #include "meshTools.H"
31 #include "mapPolyMesh.H"
32 #include "syncTools.H"
33 #include "polyAddPoint.H"
34 #include "polyAddFace.H"
35 #include "polyModifyFace.H"
36 #include "polyAddCell.H"
37 #include "wallPoint.H"
38 #include "globalIndex.H"
40 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
42 defineTypeNameAndDebug(Foam::addPatchCellLayer, 0);
45 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
47 // Calculate global faces per pp edge.
48 Foam::labelListList Foam::addPatchCellLayer::calcGlobalEdgeFaces
51 const globalIndex& globalFaces,
52 const indirectPrimitivePatch& pp,
53 const labelList& meshEdges
56 //// Determine coupled edges just so we don't have to have storage
57 //// for all non-coupled edges.
59 //PackedList<1> isCoupledEdge(mesh.nEdges(), 0);
61 //const polyBoundaryMesh& patches = mesh.boundaryMesh();
63 //forAll(patches, patchI)
65 // const polyPatch& pp = patches[patchI];
69 // const labelList& meshEdges = pp.meshEdges();
71 // forAll(meshEdges, i)
73 // isCoupledEdge.set(meshEdges[i], 1);
78 // From mesh edge to global face labels. Sized only for pp edges.
79 labelListList globalEdgeFaces(mesh.nEdges());
81 const labelListList& edgeFaces = pp.edgeFaces();
83 forAll(edgeFaces, edgeI)
85 label meshEdgeI = meshEdges[edgeI];
87 //if (isCoupledEdge.get(meshEdgeI) == 1)
89 const labelList& eFaces = edgeFaces[edgeI];
91 // Store face and processor as unique tag.
92 labelList& globalEFaces = globalEdgeFaces[meshEdgeI];
93 globalEFaces.setSize(eFaces.size());
97 globalFaces.toGlobal(pp.addressing()[eFaces[i]]);
102 // Synchronise across coupled edges.
103 syncTools::syncEdgeList
108 labelList(), // null value
109 false // no separation
113 return IndirectList<labelList>(globalEdgeFaces, meshEdges)();
117 Foam::label Foam::addPatchCellLayer::nbrFace
119 const labelListList& edgeFaces,
124 const labelList& eFaces = edgeFaces[edgeI];
126 if (eFaces.size() == 2)
128 return (eFaces[0] != faceI ? eFaces[0] : eFaces[1]);
137 void Foam::addPatchCellLayer::addVertex
150 if (f[fp-1] != pointI && f[0] != pointI)
156 // Check for duplicates.
160 for (label i = 0; i < fp; i++)
171 "addPatchCellLayer::addVertex(const label, face&"
173 ) << "Point " << pointI << " already present in face "
174 << f << abort(FatalError);
182 // Is edge to the same neighbour? (and needs extrusion and has not been
183 // dealt with already)
184 bool Foam::addPatchCellLayer::sameEdgeNeighbour
186 const indirectPrimitivePatch& pp,
187 const labelListList& globalEdgeFaces,
188 const boolList& doneEdge,
189 const label thisGlobalFaceI,
190 const label nbrGlobalFaceI,
194 const edge& e = pp.edges()[edgeI];
197 !doneEdge[edgeI] // not yet handled
199 addedPoints_[e[0]].size() != 0 // is extruded
200 || addedPoints_[e[1]].size() != 0
203 nbrFace(globalEdgeFaces, edgeI, thisGlobalFaceI)
204 == nbrGlobalFaceI // is to same neighbour
209 // Collect consecutive string of edges that connects the same two
210 // (possibly coupled) faces. Returns -1 if no unvisited edge can be found.
211 // Otherwise returns start and end index in face.
212 Foam::labelPair Foam::addPatchCellLayer::getEdgeString
214 const indirectPrimitivePatch& pp,
215 const labelListList& globalEdgeFaces,
216 const boolList& doneEdge,
217 const label patchFaceI,
218 const label globalFaceI
221 const labelList& fEdges = pp.faceEdges()[patchFaceI];
226 // Get edge that hasn't been done yet but needs extrusion
229 label edgeI = fEdges[fp];
230 const edge& e = pp.edges()[edgeI];
236 addedPoints_[e[0]].size() != 0
237 || addedPoints_[e[1]].size() != 0
248 // We found an edge that needs extruding but hasn't been done yet.
249 // Now find the face on the other side
250 label nbrGlobalFaceI = nbrFace
257 if (nbrGlobalFaceI == -1)
259 // Proper boundary edge. Only extrude single edge.
264 // Search back for edge
265 // - which hasn't been handled yet
266 // - with same neighbour
267 // - that needs extrusion
270 label prevFp = fEdges.rcIndex(startFp);
290 // Search forward for end of string
294 label nextFp = fEdges.fcIndex(endFp);
316 return labelPair(startFp, endFp);
320 // Adds a side face i.e. extrudes a patch edge.
321 Foam::label Foam::addPatchCellLayer::addSideFace
323 const indirectPrimitivePatch& pp,
324 const labelList& patchID, // prestored patch per pp face
325 const labelListList& addedCells, // per pp face the new extruded cell
327 const label ownFaceI, // pp face that provides owner
328 const label nbrFaceI,
329 const label patchEdgeI, // edge to add to
330 const label meshEdgeI, // corresponding mesh edge
331 const label layerI, // layer
332 const label numEdgeFaces, // number of layers for edge
333 polyTopoChange& meshMod
336 // Edge to 'inflate' from
337 label inflateEdgeI = -1;
339 // Mesh faces using edge
340 const labelList& meshFaces = mesh_.edgeFaces()[meshEdgeI];
344 if (mesh_.isInternalFace(meshFaces[i]))
346 // meshEdge uses internal faces so ok to inflate from it
347 inflateEdgeI = meshEdgeI;
353 // Get my mesh face and its zone.
354 label meshFaceI = pp.addressing()[ownFaceI];
355 label zoneI = mesh_.faceZones().whichZone(meshFaceI);
357 label addedFaceI = -1;
359 // Is patch edge external edge of indirectPrimitivePatch?
362 // External edge so external face. Patch id is obtained from
363 // any other patch connected to edge.
365 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
367 // Loop over all faces connected to edge to inflate and
368 // see if any boundary face (but not meshFaceI)
369 label otherPatchID = patchID[ownFaceI];
373 label faceI = meshFaces[k];
378 && !mesh_.isInternalFace(faceI)
381 otherPatchID = patches.whichPatch(faceI);
386 // Determine if different number of layer on owner and neighbour side
387 // (relevant only for coupled faces). See section for internal edge
392 if (addedCells[ownFaceI].size() < numEdgeFaces)
394 label offset = numEdgeFaces - addedCells[ownFaceI].size();
395 if (layerI <= offset)
401 layerOwn = layerI - offset;
410 //Pout<< "Added boundary face:" << newFace
411 // << " own:" << addedCells[ownFaceI][layerOwn]
412 // << " patch:" << otherPatchID
415 addedFaceI = meshMod.setAction
420 addedCells[ownFaceI][layerOwn], // owner
423 inflateEdgeI, // master edge
426 otherPatchID, // patch for face
427 zoneI, // zone for face
428 false // face zone flip
434 // When adding side faces we need to modify neighbour and owners
435 // in region where layer mesh is stopped. Determine which side
436 // has max number of faces and make sure layers match closest to
437 // original pp if there are different number of layers.
442 if (addedCells[ownFaceI].size() > addedCells[nbrFaceI].size())
445 addedCells[ownFaceI].size() - addedCells[nbrFaceI].size();
449 if (layerI <= offset)
455 layerNbr = layerI - offset;
458 else if (addedCells[nbrFaceI].size() > addedCells[ownFaceI].size())
461 addedCells[nbrFaceI].size() - addedCells[ownFaceI].size();
465 if (layerI <= offset)
471 layerOwn = layerI - offset;
476 // Same number of layers on both sides.
481 addedFaceI = meshMod.setAction
486 addedCells[ownFaceI][layerOwn], // owner
487 addedCells[nbrFaceI][layerNbr], // neighbour
489 inflateEdgeI, // master edge
492 -1, // patch for face
493 zoneI, // zone for face
494 false // face zone flip
498 //Pout<< "Added internal face:" << newFace
499 // << " own:" << addedCells[ownFaceI][layerOwn]
500 // << " nei:" << addedCells[nbrFaceI][layerNbr]
508 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
510 // Construct from mesh
511 Foam::addPatchCellLayer::addPatchCellLayer(const polyMesh& mesh)
519 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
521 Foam::labelListList Foam::addPatchCellLayer::addedCells
523 const polyMesh& mesh,
524 const labelListList& layerFaces
527 labelListList layerCells(layerFaces.size());
529 forAll(layerFaces, patchFaceI)
531 const labelList& faceLabels = layerFaces[patchFaceI];
533 if (faceLabels.size() > 0)
535 labelList& added = layerCells[patchFaceI];
536 added.setSize(faceLabels.size()-1);
538 for (label i = 0; i < faceLabels.size()-1; i++)
540 added[i] = mesh.faceNeighbour()[faceLabels[i]];
548 Foam::labelListList Foam::addPatchCellLayer::addedCells() const
550 return addedCells(mesh_, layerFaces_);
554 void Foam::addPatchCellLayer::setRefinement
556 const scalarField& expansionRatio,
557 const indirectPrimitivePatch& pp,
558 const labelList& nFaceLayers,
559 const labelList& nPointLayers,
560 const vectorField& firstLayerDisp,
561 polyTopoChange& meshMod
566 Pout<< "addPatchCellLayer::setRefinement : Adding up to "
568 << " layers of cells to indirectPrimitivePatch with "
569 << pp.nPoints() << " points" << endl;
574 pp.nPoints() != firstLayerDisp.size()
575 || pp.nPoints() != nPointLayers.size()
576 || pp.size() != nFaceLayers.size()
581 "addPatchCellLayer::setRefinement"
582 "(const scalar, const indirectPrimitivePatch&"
583 ", const labelList&, const vectorField&, polyTopoChange&)"
584 ) << "Size of new points is not same as number of points used by"
585 << " the face subset" << endl
586 << " patch.nPoints:" << pp.nPoints()
587 << " displacement:" << firstLayerDisp.size()
588 << " nPointLayers:" << nPointLayers.size() << nl
589 << " patch.nFaces:" << pp.size()
590 << " nFaceLayers:" << nFaceLayers.size()
591 << abort(FatalError);
594 forAll(nPointLayers, i)
596 if (nPointLayers[i] < 0)
600 "addPatchCellLayer::setRefinement"
601 "(const scalar, const indirectPrimitivePatch&"
602 ", const labelList&, const vectorField&, polyTopoChange&)"
603 ) << "Illegal number of layers " << nPointLayers[i]
604 << " at patch point " << i << abort(FatalError);
607 forAll(nFaceLayers, i)
609 if (nFaceLayers[i] < 0)
613 "addPatchCellLayer::setRefinement"
614 "(const scalar, const indirectPrimitivePatch&"
615 ", const labelList&, const vectorField&, polyTopoChange&)"
616 ) << "Illegal number of layers " << nFaceLayers[i]
617 << " at patch face " << i << abort(FatalError);
621 const labelList& meshPoints = pp.meshPoints();
623 // Precalculate mesh edges for pp.edges.
624 labelList meshEdges(calcMeshEdges(mesh_, pp));
628 // Check synchronisation
629 // ~~~~~~~~~~~~~~~~~~~~~
632 labelList n(mesh_.nPoints(), 0);
633 IndirectList<label>(n, meshPoints) = nPointLayers;
634 syncTools::syncPointList(mesh_, n, maxEqOp<label>(), 0, false);
637 forAll(meshPoints, i)
639 label meshPointI = meshPoints[i];
641 if (n[meshPointI] != nPointLayers[i])
645 "addPatchCellLayer::setRefinement"
646 "(const scalar, const indirectPrimitivePatch&"
647 ", const labelList&, const vectorField&"
649 ) << "At mesh point:" << meshPointI
650 << " coordinate:" << mesh_.points()[meshPointI]
651 << " specified nLayers:" << nPointLayers[i] << endl
652 << "On coupled point a different nLayers:"
653 << n[meshPointI] << " was specified."
654 << abort(FatalError);
659 // Check that nPointLayers equals the max layers of connected faces
660 // (or 0). Anything else makes no sense.
661 labelList nFromFace(mesh_.nPoints(), 0);
662 forAll(nFaceLayers, i)
664 const face& f = pp[i];
668 label pointI = f[fp];
670 nFromFace[pointI] = max(nFromFace[pointI], nFaceLayers[i]);
673 syncTools::syncPointList
682 forAll(nPointLayers, i)
684 label meshPointI = meshPoints[i];
689 && nPointLayers[i] != nFromFace[meshPointI]
694 "addPatchCellLayer::setRefinement"
695 "(const scalar, const indirectPrimitivePatch&"
696 ", const labelList&, const vectorField&"
698 ) << "At mesh point:" << meshPointI
699 << " coordinate:" << mesh_.points()[meshPointI]
700 << " specified nLayers:" << nPointLayers[i] << endl
701 << "but the max nLayers of surrounding faces is:"
702 << nFromFace[meshPointI]
703 << abort(FatalError);
709 pointField d(mesh_.nPoints(), wallPoint::greatPoint);
710 IndirectList<point>(d, meshPoints) = firstLayerDisp;
711 syncTools::syncPointList
716 wallPoint::greatPoint,
720 forAll(meshPoints, i)
722 label meshPointI = meshPoints[i];
724 if (mag(d[meshPointI] - firstLayerDisp[i]) > SMALL)
728 "addPatchCellLayer::setRefinement"
729 "(const scalar, const indirectPrimitivePatch&"
730 ", const labelList&, const vectorField&"
732 ) << "At mesh point:" << meshPointI
733 << " coordinate:" << mesh_.points()[meshPointI]
734 << " specified displacement:" << firstLayerDisp[i]
736 << "On coupled point a different displacement:"
737 << d[meshPointI] << " was specified."
738 << abort(FatalError);
743 // Check that edges of pp (so ones that become boundary faces)
744 // connect to only one boundary face. Guarantees uniqueness of
745 // patch that they go into so if this is a coupled patch both
746 // sides decide the same.
747 // ~~~~~~~~~~~~~~~~~~~~~~
749 for (label edgeI = pp.nInternalEdges(); edgeI < pp.nEdges(); edgeI++)
751 const edge& e = pp.edges()[edgeI];
753 if (nPointLayers[e[0]] > 0 || nPointLayers[e[1]] > 0)
755 // Edge is to become a face
757 const labelList& eFaces = pp.edgeFaces()[edgeI];
759 // First check: pp should be single connected.
760 if (eFaces.size() != 1)
764 "addPatchCellLayer::setRefinement"
765 "(const scalar, const indirectPrimitivePatch&"
766 ", const labelList&, const vectorField&"
768 ) << "boundary-edge-to-be-extruded:"
769 << pp.points()[meshPoints[e[0]]]
770 << pp.points()[meshPoints[e[0]]]
771 << " has more than two faces using it:" << eFaces
772 << abort(FatalError);
775 label myFaceI = pp.addressing()[eFaces[0]];
777 label meshEdgeI = meshEdges[edgeI];
779 // Mesh faces using edge
780 const labelList& meshFaces = mesh_.edgeFaces()[meshEdgeI];
782 // Check that there is only one patchface using edge.
783 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
789 label faceI = meshFaces[i];
791 if (faceI != myFaceI)
793 if (!mesh_.isInternalFace(faceI))
803 "addPatchCellLayer::setRefinement"
805 ", const indirectPrimitivePatch&"
806 ", const labelList&, const vectorField&"
808 ) << "boundary-edge-to-be-extruded:"
809 << pp.points()[meshPoints[e[0]]]
810 << pp.points()[meshPoints[e[0]]]
811 << " has more than two boundary faces"
814 << mesh_.faceCentres()[bFaceI]
815 << " patch:" << patches.whichPatch(bFaceI)
816 << " and " << faceI << " fc:"
817 << mesh_.faceCentres()[faceI]
818 << " patch:" << patches.whichPatch(faceI)
819 << abort(FatalError);
829 // From master point (in patch point label) to added points (in mesh point
831 addedPoints_.setSize(pp.nPoints());
833 // Mark points that do not get extruded by setting size of addedPoints_ to 0
834 label nTruncated = 0;
836 forAll(nPointLayers, patchPointI)
838 if (nPointLayers[patchPointI] > 0)
840 addedPoints_[patchPointI].setSize(nPointLayers[patchPointI]);
850 Pout<< "Not adding points at " << nTruncated << " out of "
851 << pp.nPoints() << " points" << endl;
859 forAll(firstLayerDisp, patchPointI)
861 if (addedPoints_[patchPointI].size() > 0)
863 label meshPointI = meshPoints[patchPointI];
865 label zoneI = mesh_.pointZones().whichZone(meshPointI);
867 point pt = mesh_.points()[meshPointI];
869 vector disp = firstLayerDisp[patchPointI];
871 for (label i = 0; i < addedPoints_[patchPointI].size(); i++)
875 label addedVertI = meshMod.setAction
880 meshPointI, // master point
881 zoneI, // zone for point
882 true // supports a cell
886 addedPoints_[patchPointI][i] = addedVertI;
888 disp *= expansionRatio[patchPointI];
895 // Add cells to all boundaryFaces
898 labelListList addedCells(pp.size());
900 forAll(pp, patchFaceI)
902 if (nFaceLayers[patchFaceI] > 0)
904 addedCells[patchFaceI].setSize(nFaceLayers[patchFaceI]);
906 label meshFaceI = pp.addressing()[patchFaceI];
908 label ownZoneI = mesh_.cellZones().whichZone
910 mesh_.faceOwner()[meshFaceI]
913 for (label i = 0; i < nFaceLayers[patchFaceI]; i++)
915 // Note: add from cell (owner of patch face) or from face?
916 // for now add from cell so we can map easily.
917 addedCells[patchFaceI][i] = meshMod.setAction
924 mesh_.faceOwner()[meshFaceI], // master cell id
925 ownZoneI // zone for cell
929 //Pout<< "For patchFace:" << patchFaceI
930 // << " meshFace:" << pp.addressing()[patchFaceI]
931 // << " layer:" << i << " added cell:"
932 // << addedCells[patchFaceI][i]
939 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
941 // Precalculated patchID for each patch face
942 labelList patchID(pp.size());
944 forAll(pp, patchFaceI)
946 label meshFaceI = pp.addressing()[patchFaceI];
948 patchID[patchFaceI] = patches.whichPatch(meshFaceI);
953 // Create faces on top of the original patch faces.
954 // These faces are created from original patch faces outwards so in order
955 // of increasing cell number. So orientation should be same as original
956 // patch face for them to have owner<neighbour.
958 layerFaces_.setSize(pp.size());
960 forAll(pp.localFaces(), patchFaceI)
962 label meshFaceI = pp.addressing()[patchFaceI];
964 if (addedCells[patchFaceI].size() > 0)
966 layerFaces_[patchFaceI].setSize(addedCells[patchFaceI].size() + 1);
967 layerFaces_[patchFaceI][0] = meshFaceI;
969 label zoneI = mesh_.faceZones().whichZone(meshFaceI);
971 // Get duplicated vertices on the patch face.
972 const face& f = pp.localFaces()[patchFaceI];
974 face newFace(f.size());
976 for (label i = 0; i < addedCells[patchFaceI].size(); i++)
980 if (addedPoints_[f[fp]].size() == 0)
982 // Keep original point
983 newFace[fp] = meshPoints[f[fp]];
987 // Get new outside point
989 addedPoints_[f[fp]].size()
990 - addedCells[patchFaceI].size();
991 newFace[fp] = addedPoints_[f[fp]][i+offset];
1000 if (i == addedCells[patchFaceI].size()-1)
1002 // Top layer so is patch face.
1004 patchI = patchID[patchFaceI];
1008 // Internal face between layer i and i+1
1009 nei = addedCells[patchFaceI][i+1];
1014 layerFaces_[patchFaceI][i+1] = meshMod.setAction
1019 addedCells[patchFaceI][i], // owner
1023 meshFaceI, // master face for addition
1025 patchI, // patch for face
1026 zoneI, // zone for face
1027 false // face zone flip
1030 //Pout<< "Added inbetween face " << newFace
1031 // << " own:" << addedCells[patchFaceI][i]
1032 // << " nei:" << nei
1033 // << " patch:" << patchI
1040 // Modify old patch faces to be on the inside
1042 forAll(pp, patchFaceI)
1044 if (addedCells[patchFaceI].size() > 0)
1046 label meshFaceI = pp.addressing()[patchFaceI];
1048 label zoneI = mesh_.faceZones().whichZone(meshFaceI);
1054 pp[patchFaceI], // modified face
1055 meshFaceI, // label of face
1056 mesh_.faceOwner()[meshFaceI], // owner
1057 addedCells[patchFaceI][0], // neighbour
1059 -1, // patch for face
1060 false, // remove from zone
1061 zoneI, // zone for face
1062 false // face flip in zone
1065 //Pout<< "Modified old patch face " << meshFaceI
1066 // << " own:" << mesh_.faceOwner()[meshFaceI]
1067 // << " nei:" << addedCells[patchFaceI][0]
1074 // Create 'side' faces, one per edge that is being extended.
1077 const labelListList& faceEdges = pp.faceEdges();
1078 const faceList& localFaces = pp.localFaces();
1079 const edgeList& edges = pp.edges();
1081 // Get number of layers per edge. This is 0 if edge is not extruded;
1082 // max of connected faces otherwise.
1083 labelList edgeLayers(pp.nEdges());
1086 // Use list over mesh.nEdges() since syncTools does not yet support
1087 // partial list synchronisation.
1088 labelList meshEdgeLayers(mesh_.nEdges(), -1);
1090 forAll(meshEdges, edgeI)
1092 const edge& e = edges[edgeI];
1094 label meshEdgeI = meshEdges[edgeI];
1096 if ((nPointLayers[e[0]] == 0) && (nPointLayers[e[1]] == 0))
1098 meshEdgeLayers[meshEdgeI] = 0;
1102 const labelList& eFaces = pp.edgeFaces()[edgeI];
1106 meshEdgeLayers[meshEdgeI] = max
1108 nFaceLayers[eFaces[i]],
1109 meshEdgeLayers[meshEdgeI]
1115 syncTools::syncEdgeList
1121 false // no separation
1124 forAll(meshEdges, edgeI)
1126 edgeLayers[edgeI] = meshEdgeLayers[meshEdges[edgeI]];
1131 // Global indices engine
1132 const globalIndex globalFaces(mesh_.nFaces());
1134 // Get for all pp edgeFaces a unique faceID
1135 labelListList globalEdgeFaces
1147 // Mark off which edges have been extruded
1148 boolList doneEdge(pp.nEdges(), false);
1151 // Create faces. Per face walk connected edges and find string of edges
1152 // between the same two faces and extrude string into a single face.
1153 forAll(pp, patchFaceI)
1155 const labelList& fEdges = faceEdges[patchFaceI];
1159 // Get string of edges that needs to be extruded as a single face.
1160 // Returned as indices in fEdges.
1169 globalFaces.toGlobal(pp.addressing()[patchFaceI])
1173 //Pout<< "Found unextruded edges in edges:" << fEdges
1174 // << " start:" << indexPair[0]
1175 // << " end:" << indexPair[1]
1178 const label startFp = indexPair[0];
1179 const label endFp = indexPair[1];
1183 // Extrude edges from indexPair[0] up to indexPair[1]
1184 // (note indexPair = indices of edges. There is one more vertex
1186 const face& f = localFaces[patchFaceI];
1188 labelList stringedVerts;
1189 if (endFp >= startFp)
1191 stringedVerts.setSize(endFp-startFp+2);
1195 stringedVerts.setSize(endFp+f.size()-startFp+2);
1200 for (label i = 0; i < stringedVerts.size()-1; i++)
1202 stringedVerts[i] = f[fp];
1203 doneEdge[fEdges[fp]] = true;
1206 stringedVerts[stringedVerts.size()-1] = f[fp];
1209 // Now stringedVerts contains the vertices in order of face f.
1210 // This is consistent with the order if f becomes the owner cell
1211 // and nbrFaceI the neighbour cell. Note that the cells get
1212 // added in order of pp so we can just use face ordering and
1213 // because we loop in incrementing order as well we will
1214 // always have nbrFaceI > patchFaceI.
1216 label startEdgeI = fEdges[startFp];
1218 label meshEdgeI = meshEdges[startEdgeI];
1220 label numEdgeSideFaces = edgeLayers[startEdgeI];
1222 for (label i = 0; i < numEdgeSideFaces; i++)
1224 label vEnd = stringedVerts[stringedVerts.size()-1];
1225 label vStart = stringedVerts[0];
1227 // calculate number of points making up a face
1228 label newFp = 2*stringedVerts.size();
1232 // layer 0 gets all the truncation of neighbouring
1233 // faces with more layers.
1234 if (addedPoints_[vEnd].size() != 0)
1237 addedPoints_[vEnd].size() - numEdgeSideFaces;
1239 if (addedPoints_[vStart].size() != 0)
1242 addedPoints_[vStart].size() - numEdgeSideFaces;
1246 face newFace(newFp);
1250 // For layer 0 get pp points, for all other layers get
1251 // points of layer-1.
1254 forAll(stringedVerts, stringedI)
1256 label v = stringedVerts[stringedI];
1257 addVertex(meshPoints[v], newFace, newFp);
1262 forAll(stringedVerts, stringedI)
1264 label v = stringedVerts[stringedI];
1265 if (addedPoints_[v].size() > 0)
1268 addedPoints_[v].size() - numEdgeSideFaces;
1271 addedPoints_[v][i+offset-1],
1278 addVertex(meshPoints[v], newFace, newFp);
1283 // add points between stringed vertices (end)
1284 if (numEdgeSideFaces < addedPoints_[vEnd].size())
1286 if (i == 0 && addedPoints_[vEnd].size() != 0)
1289 addedPoints_[vEnd].size() - numEdgeSideFaces;
1290 for (label ioff = 0; ioff < offset; ioff++)
1294 addedPoints_[vEnd][ioff],
1302 forAllReverse(stringedVerts, stringedI)
1304 label v = stringedVerts[stringedI];
1305 if (addedPoints_[v].size() > 0)
1308 addedPoints_[v].size() - numEdgeSideFaces;
1311 addedPoints_[v][i+offset],
1318 addVertex(meshPoints[v], newFace, newFp);
1323 // add points between stringed vertices (start)
1324 if (numEdgeSideFaces < addedPoints_[vStart].size())
1326 if (i == 0 && addedPoints_[vStart].size() != 0)
1329 addedPoints_[vStart].size() - numEdgeSideFaces;
1330 for (label ioff = offset; ioff > 0; ioff--)
1334 addedPoints_[vStart][ioff-1],
1344 // Add face inbetween faces patchFaceI and nbrFaceI
1345 // (possibly -1 for external edges)
1347 newFace.setSize(newFp);
1349 label nbrFaceI = nbrFace
1364 startEdgeI, // edge to inflate from
1365 meshEdgeI, // corresponding mesh edge
1378 void Foam::addPatchCellLayer::updateMesh
1380 const mapPolyMesh& morphMap,
1381 const labelList& faceMap, // new to old patch faces
1382 const labelList& pointMap // new to old patch points
1386 labelListList newAddedPoints(pointMap.size());
1388 forAll(newAddedPoints, newPointI)
1390 label oldPointI = pointMap[newPointI];
1392 const labelList& added = addedPoints_[oldPointI];
1394 labelList& newAdded = newAddedPoints[newPointI];
1395 newAdded.setSize(added.size());
1400 label newPointI = morphMap.reversePointMap()[added[i]];
1404 newAdded[newI++] = newPointI;
1407 newAdded.setSize(newI);
1409 addedPoints_.transfer(newAddedPoints);
1413 labelListList newLayerFaces(faceMap.size());
1415 forAll(newLayerFaces, newFaceI)
1417 label oldFaceI = faceMap[newFaceI];
1419 const labelList& added = layerFaces_[oldFaceI];
1421 labelList& newAdded = newLayerFaces[newFaceI];
1422 newAdded.setSize(added.size());
1427 label newFaceI = morphMap.reverseFaceMap()[added[i]];
1431 newAdded[newI++] = newFaceI;
1434 newAdded.setSize(newI);
1436 layerFaces_.transfer(newLayerFaces);
1441 Foam::labelList Foam::addPatchCellLayer::calcMeshEdges
1443 const primitiveMesh& mesh,
1444 const indirectPrimitivePatch& pp
1447 labelList meshEdges(pp.nEdges());
1449 forAll(meshEdges, patchEdgeI)
1451 const edge& e = pp.edges()[patchEdgeI];
1453 label v0 = pp.meshPoints()[e[0]];
1454 label v1 = pp.meshPoints()[e[1]];
1455 meshEdges[patchEdgeI] = meshTools::findEdge
1458 mesh.pointEdges()[v0],
1467 // ************************************************************************* //