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
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 //PackedBoolList isCoupledEdge(mesh.nEdges());
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 UIndirectList<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() // is extruded
200 || addedPoints_[e[1]].size()
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];
235 && ( addedPoints_[e[0]].size() || addedPoints_[e[1]].size() )
245 // We found an edge that needs extruding but hasn't been done yet.
246 // Now find the face on the other side
247 label nbrGlobalFaceI = nbrFace
254 if (nbrGlobalFaceI == -1)
256 // Proper boundary edge. Only extrude single edge.
261 // Search back for edge
262 // - which hasn't been handled yet
263 // - with same neighbour
264 // - that needs extrusion
267 label prevFp = fEdges.rcIndex(startFp);
287 // Search forward for end of string
291 label nextFp = fEdges.fcIndex(endFp);
313 return labelPair(startFp, endFp);
317 // Adds a side face i.e. extrudes a patch edge.
318 Foam::label Foam::addPatchCellLayer::addSideFace
320 const indirectPrimitivePatch& pp,
321 const labelList& patchID, // prestored patch per pp face
322 const labelListList& addedCells, // per pp face the new extruded cell
324 const label ownFaceI, // pp face that provides owner
325 const label nbrFaceI,
326 const label patchEdgeI, // edge to add to
327 const label meshEdgeI, // corresponding mesh edge
328 const label layerI, // layer
329 const label numEdgeFaces, // number of layers for edge
330 const labelList& meshFaces, // precalculated edgeFaces
331 polyTopoChange& meshMod
334 // Edge to 'inflate' from
335 label inflateEdgeI = -1;
337 // Check mesh faces using edge
340 if (mesh_.isInternalFace(meshFaces[i]))
342 // meshEdge uses internal faces so ok to inflate from it
343 inflateEdgeI = meshEdgeI;
349 // Get my mesh face and its zone.
350 label meshFaceI = pp.addressing()[ownFaceI];
351 // Zone info comes from any side patch face. Otherwise -1 since we
352 // don't know what to put it in - inherit from the extruded faces?
353 label zoneI = -1; //mesh_.faceZones().whichZone(meshFaceI);
356 label addedFaceI = -1;
358 // Is patch edge external edge of indirectPrimitivePatch?
361 // External edge so external face. Patch id is obtained from
362 // any other patch connected to edge.
364 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
366 // Loop over all faces connected to edge to inflate and
367 // see if any boundary face (but not meshFaceI)
368 label otherPatchID = patchID[ownFaceI];
372 label faceI = meshFaces[k];
377 && !mesh_.isInternalFace(faceI)
380 otherPatchID = patches.whichPatch(faceI);
381 zoneI = mesh_.faceZones().whichZone(faceI);
384 label index = mesh_.faceZones()[zoneI].whichFace(faceI);
385 flip = mesh_.faceZones()[zoneI].flipMap()[index];
391 // Determine if different number of layer on owner and neighbour side
392 // (relevant only for coupled faces). See section for internal edge
397 if (addedCells[ownFaceI].size() < numEdgeFaces)
399 label offset = numEdgeFaces - addedCells[ownFaceI].size();
400 if (layerI <= offset)
406 layerOwn = layerI - offset;
415 //Pout<< "Added boundary face:" << newFace
416 // << " own:" << addedCells[ownFaceI][layerOwn]
417 // << " patch:" << otherPatchID
420 addedFaceI = meshMod.setAction
425 addedCells[ownFaceI][layerOwn], // owner
428 inflateEdgeI, // master edge
431 otherPatchID, // patch for face
432 zoneI, // zone for face
433 flip // face zone flip
439 // When adding side faces we need to modify neighbour and owners
440 // in region where layer mesh is stopped. Determine which side
441 // has max number of faces and make sure layers match closest to
442 // original pp if there are different number of layers.
447 if (addedCells[ownFaceI].size() > addedCells[nbrFaceI].size())
450 addedCells[ownFaceI].size() - addedCells[nbrFaceI].size();
454 if (layerI <= offset)
460 layerNbr = layerI - offset;
463 else if (addedCells[nbrFaceI].size() > addedCells[ownFaceI].size())
466 addedCells[nbrFaceI].size() - addedCells[ownFaceI].size();
470 if (layerI <= offset)
476 layerOwn = layerI - offset;
481 // Same number of layers on both sides.
486 addedFaceI = meshMod.setAction
491 addedCells[ownFaceI][layerOwn], // owner
492 addedCells[nbrFaceI][layerNbr], // neighbour
494 inflateEdgeI, // master edge
497 -1, // patch for face
498 zoneI, // zone for face
499 flip // face zone flip
503 //Pout<< "Added internal face:" << newFace
504 // << " own:" << addedCells[ownFaceI][layerOwn]
505 // << " nei:" << addedCells[nbrFaceI][layerNbr]
513 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
515 // Construct from mesh
516 Foam::addPatchCellLayer::addPatchCellLayer(const polyMesh& mesh)
524 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
526 Foam::labelListList Foam::addPatchCellLayer::addedCells
528 const polyMesh& mesh,
529 const labelListList& layerFaces
532 labelListList layerCells(layerFaces.size());
534 forAll(layerFaces, patchFaceI)
536 const labelList& faceLabels = layerFaces[patchFaceI];
538 if (faceLabels.size())
540 labelList& added = layerCells[patchFaceI];
541 added.setSize(faceLabels.size()-1);
543 for (label i = 0; i < faceLabels.size()-1; i++)
545 added[i] = mesh.faceNeighbour()[faceLabels[i]];
553 Foam::labelListList Foam::addPatchCellLayer::addedCells() const
555 return addedCells(mesh_, layerFaces_);
559 void Foam::addPatchCellLayer::setRefinement
561 const scalarField& expansionRatio,
562 const indirectPrimitivePatch& pp,
563 const labelList& nFaceLayers,
564 const labelList& nPointLayers,
565 const vectorField& firstLayerDisp,
566 polyTopoChange& meshMod
571 Pout<< "addPatchCellLayer::setRefinement : Adding up to "
573 << " layers of cells to indirectPrimitivePatch with "
574 << pp.nPoints() << " points" << endl;
579 pp.nPoints() != firstLayerDisp.size()
580 || pp.nPoints() != nPointLayers.size()
581 || pp.size() != nFaceLayers.size()
586 "addPatchCellLayer::setRefinement"
587 "(const scalar, const indirectPrimitivePatch&"
588 ", const labelList&, const vectorField&, polyTopoChange&)"
589 ) << "Size of new points is not same as number of points used by"
590 << " the face subset" << endl
591 << " patch.nPoints:" << pp.nPoints()
592 << " displacement:" << firstLayerDisp.size()
593 << " nPointLayers:" << nPointLayers.size() << nl
594 << " patch.nFaces:" << pp.size()
595 << " nFaceLayers:" << nFaceLayers.size()
596 << abort(FatalError);
599 forAll(nPointLayers, i)
601 if (nPointLayers[i] < 0)
605 "addPatchCellLayer::setRefinement"
606 "(const scalar, const indirectPrimitivePatch&"
607 ", const labelList&, const vectorField&, polyTopoChange&)"
608 ) << "Illegal number of layers " << nPointLayers[i]
609 << " at patch point " << i << abort(FatalError);
612 forAll(nFaceLayers, i)
614 if (nFaceLayers[i] < 0)
618 "addPatchCellLayer::setRefinement"
619 "(const scalar, const indirectPrimitivePatch&"
620 ", const labelList&, const vectorField&, polyTopoChange&)"
621 ) << "Illegal number of layers " << nFaceLayers[i]
622 << " at patch face " << i << abort(FatalError);
626 const labelList& meshPoints = pp.meshPoints();
628 // Some storage for edge-face-addressing.
629 DynamicList<label> ef;
631 // Precalculate mesh edges for pp.edges.
632 labelList meshEdges(calcMeshEdges(mesh_, pp));
636 // Check synchronisation
637 // ~~~~~~~~~~~~~~~~~~~~~
640 labelList n(mesh_.nPoints(), 0);
641 UIndirectList<label>(n, meshPoints) = nPointLayers;
642 syncTools::syncPointList(mesh_, n, maxEqOp<label>(), 0, false);
645 forAll(meshPoints, i)
647 label meshPointI = meshPoints[i];
649 if (n[meshPointI] != nPointLayers[i])
653 "addPatchCellLayer::setRefinement"
654 "(const scalar, const indirectPrimitivePatch&"
655 ", const labelList&, const vectorField&"
657 ) << "At mesh point:" << meshPointI
658 << " coordinate:" << mesh_.points()[meshPointI]
659 << " specified nLayers:" << nPointLayers[i] << endl
660 << "On coupled point a different nLayers:"
661 << n[meshPointI] << " was specified."
662 << abort(FatalError);
667 // Check that nPointLayers equals the max layers of connected faces
668 // (or 0). Anything else makes no sense.
669 labelList nFromFace(mesh_.nPoints(), 0);
670 forAll(nFaceLayers, i)
672 const face& f = pp[i];
676 label pointI = f[fp];
678 nFromFace[pointI] = max(nFromFace[pointI], nFaceLayers[i]);
681 syncTools::syncPointList
690 forAll(nPointLayers, i)
692 label meshPointI = meshPoints[i];
697 && nPointLayers[i] != nFromFace[meshPointI]
702 "addPatchCellLayer::setRefinement"
703 "(const scalar, const indirectPrimitivePatch&"
704 ", const labelList&, const vectorField&"
706 ) << "At mesh point:" << meshPointI
707 << " coordinate:" << mesh_.points()[meshPointI]
708 << " specified nLayers:" << nPointLayers[i] << endl
709 << "but the max nLayers of surrounding faces is:"
710 << nFromFace[meshPointI]
711 << abort(FatalError);
717 pointField d(mesh_.nPoints(), wallPoint::greatPoint);
718 UIndirectList<point>(d, meshPoints) = firstLayerDisp;
719 syncTools::syncPointList
724 wallPoint::greatPoint,
728 forAll(meshPoints, i)
730 label meshPointI = meshPoints[i];
732 if (mag(d[meshPointI] - firstLayerDisp[i]) > SMALL)
736 "addPatchCellLayer::setRefinement"
737 "(const scalar, const indirectPrimitivePatch&"
738 ", const labelList&, const vectorField&"
740 ) << "At mesh point:" << meshPointI
741 << " coordinate:" << mesh_.points()[meshPointI]
742 << " specified displacement:" << firstLayerDisp[i]
744 << "On coupled point a different displacement:"
745 << d[meshPointI] << " was specified."
746 << abort(FatalError);
751 // Check that edges of pp (so ones that become boundary faces)
752 // connect to only one boundary face. Guarantees uniqueness of
753 // patch that they go into so if this is a coupled patch both
754 // sides decide the same.
755 // ~~~~~~~~~~~~~~~~~~~~~~
757 for (label edgeI = pp.nInternalEdges(); edgeI < pp.nEdges(); edgeI++)
759 const edge& e = pp.edges()[edgeI];
761 if (nPointLayers[e[0]] > 0 || nPointLayers[e[1]] > 0)
763 // Edge is to become a face
765 const labelList& eFaces = pp.edgeFaces()[edgeI];
767 // First check: pp should be single connected.
768 if (eFaces.size() != 1)
772 "addPatchCellLayer::setRefinement"
773 "(const scalar, const indirectPrimitivePatch&"
774 ", const labelList&, const vectorField&"
776 ) << "boundary-edge-to-be-extruded:"
777 << pp.points()[meshPoints[e[0]]]
778 << pp.points()[meshPoints[e[1]]]
779 << " has more than two faces using it:" << eFaces
780 << abort(FatalError);
783 label myFaceI = pp.addressing()[eFaces[0]];
785 label meshEdgeI = meshEdges[edgeI];
787 // Mesh faces using edge
789 // Mesh faces using edge
790 const labelList& meshFaces = mesh_.edgeFaces(meshEdgeI, ef);
792 // Check that there is only one patchface using edge.
793 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
799 label faceI = meshFaces[i];
801 if (faceI != myFaceI)
803 if (!mesh_.isInternalFace(faceI))
813 "addPatchCellLayer::setRefinement"
815 ", const indirectPrimitivePatch&"
816 ", const labelList&, const vectorField&"
818 ) << "boundary-edge-to-be-extruded:"
819 << pp.points()[meshPoints[e[0]]]
820 << pp.points()[meshPoints[e[1]]]
821 << " has more than two boundary faces"
824 << mesh_.faceCentres()[bFaceI]
825 << " patch:" << patches.whichPatch(bFaceI)
826 << " and " << faceI << " fc:"
827 << mesh_.faceCentres()[faceI]
828 << " patch:" << patches.whichPatch(faceI)
829 << abort(FatalError);
839 // From master point (in patch point label) to added points (in mesh point
841 addedPoints_.setSize(pp.nPoints());
843 // Mark points that do not get extruded by setting size of addedPoints_ to 0
844 label nTruncated = 0;
846 forAll(nPointLayers, patchPointI)
848 if (nPointLayers[patchPointI] > 0)
850 addedPoints_[patchPointI].setSize(nPointLayers[patchPointI]);
860 Pout<< "Not adding points at " << nTruncated << " out of "
861 << pp.nPoints() << " points" << endl;
869 forAll(firstLayerDisp, patchPointI)
871 if (addedPoints_[patchPointI].size())
873 label meshPointI = meshPoints[patchPointI];
875 label zoneI = mesh_.pointZones().whichZone(meshPointI);
877 point pt = mesh_.points()[meshPointI];
879 vector disp = firstLayerDisp[patchPointI];
881 for (label i = 0; i < addedPoints_[patchPointI].size(); i++)
885 label addedVertI = meshMod.setAction
890 meshPointI, // master point
891 zoneI, // zone for point
892 true // supports a cell
896 addedPoints_[patchPointI][i] = addedVertI;
898 disp *= expansionRatio[patchPointI];
905 // Add cells to all boundaryFaces
908 labelListList addedCells(pp.size());
910 forAll(pp, patchFaceI)
912 if (nFaceLayers[patchFaceI] > 0)
914 addedCells[patchFaceI].setSize(nFaceLayers[patchFaceI]);
916 label meshFaceI = pp.addressing()[patchFaceI];
918 label ownZoneI = mesh_.cellZones().whichZone
920 mesh_.faceOwner()[meshFaceI]
923 for (label i = 0; i < nFaceLayers[patchFaceI]; i++)
925 // Note: add from cell (owner of patch face) or from face?
926 // for now add from cell so we can map easily.
927 addedCells[patchFaceI][i] = meshMod.setAction
934 mesh_.faceOwner()[meshFaceI], // master cell id
935 ownZoneI // zone for cell
939 //Pout<< "For patchFace:" << patchFaceI
940 // << " meshFace:" << pp.addressing()[patchFaceI]
941 // << " layer:" << i << " added cell:"
942 // << addedCells[patchFaceI][i]
949 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
951 // Precalculated patchID for each patch face
952 labelList patchID(pp.size());
954 forAll(pp, patchFaceI)
956 label meshFaceI = pp.addressing()[patchFaceI];
958 patchID[patchFaceI] = patches.whichPatch(meshFaceI);
963 // Create faces on top of the original patch faces.
964 // These faces are created from original patch faces outwards so in order
965 // of increasing cell number. So orientation should be same as original
966 // patch face for them to have owner<neighbour.
968 layerFaces_.setSize(pp.size());
970 forAll(pp.localFaces(), patchFaceI)
972 label meshFaceI = pp.addressing()[patchFaceI];
974 if (addedCells[patchFaceI].size())
976 layerFaces_[patchFaceI].setSize(addedCells[patchFaceI].size() + 1);
977 layerFaces_[patchFaceI][0] = meshFaceI;
979 // Get duplicated vertices on the patch face.
980 const face& f = pp.localFaces()[patchFaceI];
982 face newFace(f.size());
984 for (label i = 0; i < addedCells[patchFaceI].size(); i++)
988 if (addedPoints_[f[fp]].empty())
990 // Keep original point
991 newFace[fp] = meshPoints[f[fp]];
995 // Get new outside point
997 addedPoints_[f[fp]].size()
998 - addedCells[patchFaceI].size();
999 newFace[fp] = addedPoints_[f[fp]][i+offset];
1004 // Get new neighbour
1011 if (i == addedCells[patchFaceI].size()-1)
1013 // Top layer so is patch face.
1015 patchI = patchID[patchFaceI];
1016 zoneI = mesh_.faceZones().whichZone(meshFaceI);
1019 const faceZone& fz = mesh_.faceZones()[zoneI];
1020 flip = fz.flipMap()[fz.whichFace(meshFaceI)];
1025 // Internal face between layer i and i+1
1026 nei = addedCells[patchFaceI][i+1];
1031 layerFaces_[patchFaceI][i+1] = meshMod.setAction
1036 addedCells[patchFaceI][i], // owner
1040 meshFaceI, // master face for addition
1042 patchI, // patch for face
1043 zoneI, // zone for face
1044 flip // face zone flip
1047 //Pout<< "Added inbetween face " << newFace
1048 // << " own:" << addedCells[patchFaceI][i]
1049 // << " nei:" << nei
1050 // << " patch:" << patchI
1057 // Modify old patch faces to be on the inside
1059 forAll(pp, patchFaceI)
1061 if (addedCells[patchFaceI].size())
1063 label meshFaceI = pp.addressing()[patchFaceI];
1069 pp[patchFaceI], // modified face
1070 meshFaceI, // label of face
1071 mesh_.faceOwner()[meshFaceI], // owner
1072 addedCells[patchFaceI][0], // neighbour
1074 -1, // patch for face
1075 true, //false, // remove from zone
1076 -1, //zoneI, // zone for face
1077 false // face flip in zone
1080 //Pout<< "Modified old patch face " << meshFaceI
1081 // << " own:" << mesh_.faceOwner()[meshFaceI]
1082 // << " nei:" << addedCells[patchFaceI][0]
1089 // Create 'side' faces, one per edge that is being extended.
1092 const labelListList& faceEdges = pp.faceEdges();
1093 const faceList& localFaces = pp.localFaces();
1094 const edgeList& edges = pp.edges();
1096 // Get number of layers per edge. This is 0 if edge is not extruded;
1097 // max of connected faces otherwise.
1098 labelList edgeLayers(pp.nEdges());
1101 // Use list over mesh.nEdges() since syncTools does not yet support
1102 // partial list synchronisation.
1103 labelList meshEdgeLayers(mesh_.nEdges(), -1);
1105 forAll(meshEdges, edgeI)
1107 const edge& e = edges[edgeI];
1109 label meshEdgeI = meshEdges[edgeI];
1111 if ((nPointLayers[e[0]] == 0) && (nPointLayers[e[1]] == 0))
1113 meshEdgeLayers[meshEdgeI] = 0;
1117 const labelList& eFaces = pp.edgeFaces()[edgeI];
1121 meshEdgeLayers[meshEdgeI] = max
1123 nFaceLayers[eFaces[i]],
1124 meshEdgeLayers[meshEdgeI]
1130 syncTools::syncEdgeList
1136 false // no separation
1139 forAll(meshEdges, edgeI)
1141 edgeLayers[edgeI] = meshEdgeLayers[meshEdges[edgeI]];
1146 // Global indices engine
1147 const globalIndex globalFaces(mesh_.nFaces());
1149 // Get for all pp edgeFaces a unique faceID
1150 labelListList globalEdgeFaces
1162 // Mark off which edges have been extruded
1163 boolList doneEdge(pp.nEdges(), false);
1166 // Create faces. Per face walk connected edges and find string of edges
1167 // between the same two faces and extrude string into a single face.
1168 forAll(pp, patchFaceI)
1170 const labelList& fEdges = faceEdges[patchFaceI];
1174 // Get string of edges that needs to be extruded as a single face.
1175 // Returned as indices in fEdges.
1184 globalFaces.toGlobal(pp.addressing()[patchFaceI])
1188 //Pout<< "Found unextruded edges in edges:" << fEdges
1189 // << " start:" << indexPair[0]
1190 // << " end:" << indexPair[1]
1193 const label startFp = indexPair[0];
1194 const label endFp = indexPair[1];
1198 // Extrude edges from indexPair[0] up to indexPair[1]
1199 // (note indexPair = indices of edges. There is one more vertex
1201 const face& f = localFaces[patchFaceI];
1203 labelList stringedVerts;
1204 if (endFp >= startFp)
1206 stringedVerts.setSize(endFp-startFp+2);
1210 stringedVerts.setSize(endFp+f.size()-startFp+2);
1215 for (label i = 0; i < stringedVerts.size()-1; i++)
1217 stringedVerts[i] = f[fp];
1218 doneEdge[fEdges[fp]] = true;
1221 stringedVerts[stringedVerts.size()-1] = f[fp];
1224 // Now stringedVerts contains the vertices in order of face f.
1225 // This is consistent with the order if f becomes the owner cell
1226 // and nbrFaceI the neighbour cell. Note that the cells get
1227 // added in order of pp so we can just use face ordering and
1228 // because we loop in incrementing order as well we will
1229 // always have nbrFaceI > patchFaceI.
1231 label startEdgeI = fEdges[startFp];
1233 label meshEdgeI = meshEdges[startEdgeI];
1235 label numEdgeSideFaces = edgeLayers[startEdgeI];
1237 for (label i = 0; i < numEdgeSideFaces; i++)
1239 label vEnd = stringedVerts[stringedVerts.size()-1];
1240 label vStart = stringedVerts[0];
1242 // calculate number of points making up a face
1243 label newFp = 2*stringedVerts.size();
1247 // layer 0 gets all the truncation of neighbouring
1248 // faces with more layers.
1249 if (addedPoints_[vEnd].size())
1252 addedPoints_[vEnd].size() - numEdgeSideFaces;
1254 if (addedPoints_[vStart].size())
1257 addedPoints_[vStart].size() - numEdgeSideFaces;
1261 face newFace(newFp);
1265 // For layer 0 get pp points, for all other layers get
1266 // points of layer-1.
1269 forAll(stringedVerts, stringedI)
1271 label v = stringedVerts[stringedI];
1272 addVertex(meshPoints[v], newFace, newFp);
1277 forAll(stringedVerts, stringedI)
1279 label v = stringedVerts[stringedI];
1280 if (addedPoints_[v].size())
1283 addedPoints_[v].size() - numEdgeSideFaces;
1286 addedPoints_[v][i+offset-1],
1293 addVertex(meshPoints[v], newFace, newFp);
1298 // add points between stringed vertices (end)
1299 if (numEdgeSideFaces < addedPoints_[vEnd].size())
1301 if (i == 0 && addedPoints_[vEnd].size())
1304 addedPoints_[vEnd].size() - numEdgeSideFaces;
1305 for (label ioff = 0; ioff < offset; ioff++)
1309 addedPoints_[vEnd][ioff],
1317 forAllReverse(stringedVerts, stringedI)
1319 label v = stringedVerts[stringedI];
1320 if (addedPoints_[v].size())
1323 addedPoints_[v].size() - numEdgeSideFaces;
1326 addedPoints_[v][i+offset],
1333 addVertex(meshPoints[v], newFace, newFp);
1338 // add points between stringed vertices (start)
1339 if (numEdgeSideFaces < addedPoints_[vStart].size())
1341 if (i == 0 && addedPoints_[vStart].size())
1344 addedPoints_[vStart].size() - numEdgeSideFaces;
1345 for (label ioff = offset; ioff > 0; ioff--)
1349 addedPoints_[vStart][ioff-1],
1359 // Add face inbetween faces patchFaceI and nbrFaceI
1360 // (possibly -1 for external edges)
1362 newFace.setSize(newFp);
1364 label nbrFaceI = nbrFace
1371 const labelList& meshFaces = mesh_.edgeFaces
1385 startEdgeI, // edge to inflate from
1386 meshEdgeI, // corresponding mesh edge
1400 void Foam::addPatchCellLayer::updateMesh
1402 const mapPolyMesh& morphMap,
1403 const labelList& faceMap, // new to old patch faces
1404 const labelList& pointMap // new to old patch points
1408 labelListList newAddedPoints(pointMap.size());
1410 forAll(newAddedPoints, newPointI)
1412 label oldPointI = pointMap[newPointI];
1414 const labelList& added = addedPoints_[oldPointI];
1416 labelList& newAdded = newAddedPoints[newPointI];
1417 newAdded.setSize(added.size());
1422 label newPointI = morphMap.reversePointMap()[added[i]];
1426 newAdded[newI++] = newPointI;
1429 newAdded.setSize(newI);
1431 addedPoints_.transfer(newAddedPoints);
1435 labelListList newLayerFaces(faceMap.size());
1437 forAll(newLayerFaces, newFaceI)
1439 label oldFaceI = faceMap[newFaceI];
1441 const labelList& added = layerFaces_[oldFaceI];
1443 labelList& newAdded = newLayerFaces[newFaceI];
1444 newAdded.setSize(added.size());
1449 label newFaceI = morphMap.reverseFaceMap()[added[i]];
1453 newAdded[newI++] = newFaceI;
1456 newAdded.setSize(newI);
1458 layerFaces_.transfer(newLayerFaces);
1463 Foam::labelList Foam::addPatchCellLayer::calcMeshEdges
1465 const primitiveMesh& mesh,
1466 const indirectPrimitivePatch& pp
1469 labelList meshEdges(pp.nEdges());
1471 forAll(meshEdges, patchEdgeI)
1473 const edge& e = pp.edges()[patchEdgeI];
1475 label v0 = pp.meshPoints()[e[0]];
1476 label v1 = pp.meshPoints()[e[1]];
1477 meshEdges[patchEdgeI] = meshTools::findEdge
1480 mesh.pointEdges()[v0],
1489 // ************************************************************************* //