void Foam::PrimitivePatch<Face, FaceList, PointField, PointType>:: calcPointFaces() const { if (debug) { Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::" << "calcPointFaces() : calculating pointFaces" << endl; } if (pointFacesPtr_) { // it is considered an error to attempt to recalculate // if already allocated FatalErrorIn ( "PrimitivePatch<Face, FaceList, PointField, PointType>::" "calcPointFaces()" ) << "pointFaces already calculated" << abort(FatalError); } const List<Face>& f = localFaces(); // set up storage for pointFaces List<SLList<label> > pointFcs(meshPoints().size()); forAll(f, faceI) { const Face& curPoints = f[faceI]; forAll(curPoints, pointI) { pointFcs[curPoints[pointI]].append(faceI); } }
void Foam::PrimitivePatch<Face, FaceList, PointField, PointType>:: calcLocalPointOrder() const { // Note: Cannot use bandCompressing as point-point addressing does // not exist and is not considered generally useful. // if (debug) { Pout<< "PrimitivePatch<Face, FaceList, PointField, PointType>::" << "calcLocalPointOrder() : " << "calculating local point order" << endl; } if (localPointOrderPtr_) { // it is considered an error to attempt to recalculate // if already allocated FatalErrorIn ( "PrimitivePatch<Face, FaceList, PointField, PointType>::" "calcLocalPointOrder()" ) << "local point order already calculated" << abort(FatalError); } const List<Face>& lf = localFaces(); const labelListList& ff = faceFaces(); boolList visitedFace(lf.size(), false); localPointOrderPtr_ = new labelList(meshPoints().size(), -1); labelList& pointOrder = *localPointOrderPtr_; boolList visitedPoint(pointOrder.size(), false); label nPoints = 0; forAll (lf, faceI) { if (!visitedFace[faceI]) { SLList<label> faceOrder(faceI); do { const label curFace = faceOrder.first(); faceOrder.removeHead(); if (!visitedFace[curFace]) { visitedFace[curFace] = true; const labelList& curPoints = lf[curFace]; // mark points forAll (curPoints, pointI) { if (!visitedPoint[curPoints[pointI]]) { visitedPoint[curPoints[pointI]] = true; pointOrder[nPoints] = curPoints[pointI]; nPoints++; } } // add face neighbours to the list const labelList& nbrs = ff[curFace]; forAll (nbrs, nbrI) { if (!visitedFace[nbrs[nbrI]]) { faceOrder.append(nbrs[nbrI]); } } } } while (faceOrder.size()); } }
void Foam::enrichedPatch::calcPointPoints() const { // Calculate point-point addressing if (pointPointsPtr_) { FatalErrorIn("void enrichedPatch::calcPointPoints() const") << "Point-point addressing already calculated." << abort(FatalError); } // Algorithm: // Go through all faces and add the previous and next point as the // neighbour for each point. While inserting points, reject the // duplicates (as every internal edge will be visited twice). List<DynamicList<label, primitiveMesh::edgesPerPoint_> > pp(meshPoints().size()); const faceList& lf = localFaces(); register bool found = false; forAll (lf, faceI) { const face& curFace = lf[faceI]; forAll (curFace, pointI) { DynamicList<label, primitiveMesh::edgesPerPoint_>& curPp = pp[curFace[pointI]]; // Do next label label next = curFace.nextLabel(pointI); found = false; forAll (curPp, i) { if (curPp[i] == next) { found = true; break; } } if (!found) { curPp.append(next); } // Do previous label label prev = curFace.prevLabel(pointI); found = false; forAll (curPp, i) { if (curPp[i] == prev) { found = true; break; } } if (!found) { curPp.append(prev); } } }
void Foam::PrimitivePatch<Face, FaceList, PointField, PointType>:: calcAddressing() const { if (debug) { Info<< "PrimitivePatch<Face, FaceList, PointField, PointType>::" << "calcAddressing() : calculating patch addressing" << endl; } if (edgesPtr_ || faceFacesPtr_ || edgeFacesPtr_ || faceEdgesPtr_) { // it is considered an error to attempt to recalculate // if already allocated FatalErrorIn ( "PrimitivePatch<Face, FaceList, PointField, PointType>::" "calcAddressing()" ) << "addressing already calculated" << abort(FatalError); } // get reference to localFaces const List<Face>& locFcs = localFaces(); // get reference to pointFaces const labelListList& pf = pointFaces(); // Guess the max number of edges and neighbours for a face label maxEdges = 0; forAll(locFcs, faceI) { maxEdges += locFcs[faceI].size(); } // create the lists for the various results. (resized on completion) edgesPtr_ = new edgeList(maxEdges); edgeList& edges = *edgesPtr_; edgeFacesPtr_ = new labelListList(maxEdges); labelListList& edgeFaces = *edgeFacesPtr_; // faceFaces created using a dynamic list. Cannot guess size because // of multiple connections List<DynamicList<label> > ff(locFcs.size()); faceEdgesPtr_ = new labelListList(locFcs.size()); labelListList& faceEdges = *faceEdgesPtr_; // count the number of face neighbours labelList noFaceFaces(locFcs.size()); // initialise the lists of subshapes for each face to avoid duplication edgeListList faceIntoEdges(locFcs.size()); forAll(locFcs, faceI) { faceIntoEdges[faceI] = locFcs[faceI].edges(); labelList& curFaceEdges = faceEdges[faceI]; curFaceEdges.setSize(faceIntoEdges[faceI].size()); forAll(curFaceEdges, faceEdgeI) { curFaceEdges[faceEdgeI] = -1; } }
patchFaceI < myPatches[patchI].size(); patchFaceI++ ) { const label faceI = faceMap[faceIndex++]; const labelledTri& f = localFaces()[faceI]; os << f[0] << ' ' << f[1] << ' ' << f[2] << endl; } } } else { forAll(*this, faceI) { const labelledTri& f = localFaces()[faceI]; os << f[0] << ' ' << f[1] << ' ' << f[2] << endl; } } os << "attribute \"element type\" string \"triangles\"" << endl << "attribute \"ref\" string \"positions\"" << endl << endl; } // Standard trailer void triSurface::writeDXTrailer(Ostream& os) const { os << "# the field, with three components: \"positions\", \"connections\"" << ", and \"data\"" << endl << "object \"irregular positions irregular connections\" class field"
markPointNbrs(surf, faceI, false, okToCollapse); break; } } } } Pout<< "collapseEdge : collapsing " << nCollapsed << " triangles" << endl; nTotalCollapsed += nCollapsed; if (nCollapsed == 0) { break; } // Pack the triangles surf = pack(surf, newPoints, pointMap); } // Remove any unused vertices surf = triSurface(surf.localFaces(), surf.patches(), surf.localPoints()); return nTotalCollapsed; } // ************************************************************************* //
void Foam::cyclicGgiPolyPatch::calcTransforms() const { if (active() && debug) { // Check definition of the cyclic pair checkDefinition(); } // For computing the rotation tensors forwardT and reverseT, we // can see from Robert Magnan's post on the Forum dated // 27/May/2008 that we cannot use the actual implementation of // calcTransformTensors and rotationTensor. // // It is also not possible to use Robert solution because for // non-conformal cyclic meshes, we cannot usualy find a pair of // matching faces for computing the tensors. So we are using // user-supplied values instead. // // Since these tensors are defined as private in the // coupledPolyPatch class definition, we will override these // values here and compute the tensors ourselves using the // Rodrigues Rotation formula. // We compute the rotationTensor from rotationAxis_ and // rotationAngle_ We compute the separation vector from // separationOffset_ // All transforms are constant: size = 1. HJ, 18/Feb/2009 if (mag(rotationAngle_) > SMALL) { // Rotation tensor computed from rotationAxis_ and rotationAngle_ // Note: cyclics already have opposing signs for the rotation // so there is no need for a special practice. HJ, 30/Jun/2009 forwardT_ = tensorField ( 1, RodriguesRotation(rotationAxis_, -rotationAngle_) ); reverseT_ = tensorField ( 1, RodriguesRotation(rotationAxis_, rotationAngle_) ); } else { forwardT_.setSize(0); reverseT_.setSize(0); } // Handling the separation offset separatly if (mag(separationOffset_) > SMALL) { separation_ = vectorField(1, separationOffset_); } else { separation_.setSize(0); } if (debug > 1 && master()) { if (patchToPatch().uncoveredMasterFaces().size() > 0) { // Write uncovered master faces Info<< "Writing uncovered master faces for patch " << name() << " as VTK." << endl; const polyMesh& mesh = boundaryMesh().mesh(); fileName fvPath(mesh.time().path()/"VTK"); mkDir(fvPath); indirectPrimitivePatch::writeVTK ( fvPath/fileName("uncoveredCyclicGgiFaces" + name()), IndirectList<face> ( localFaces(), patchToPatch().uncoveredMasterFaces() ), localPoints() ); } if (patchToPatch().uncoveredSlaveFaces().size() > 0) { // Write uncovered master faces Info<< "Writing uncovered shadow faces for patch " << shadowName() << " as VTK." << endl; const polyMesh& mesh = boundaryMesh().mesh(); fileName fvPath(mesh.time().path()/"VTK"); mkDir(fvPath); indirectPrimitivePatch::writeVTK ( fvPath/fileName("uncoveredCyclicGgiFaces" + shadowName()), IndirectList<face> ( shadow().localFaces(), patchToPatch().uncoveredSlaveFaces() ), shadow().localPoints() ); } // Check for bridge overlap if (!bridgeOverlap()) { if ( patchToPatch().uncoveredMasterFaces().size() > 0 || patchToPatch().uncoveredSlaveFaces().size() > 0 ) { FatalErrorIn("label cyclicGgiPolyPatch::shadowIndex() const") << "cyclic ggi patch " << name() << " with shadow " << shadowName() << " has " << patchToPatch().uncoveredMasterFaces().size() << " uncovered master faces and " << patchToPatch().uncoveredSlaveFaces().size() << " uncovered slave faces. Bridging is switched off. " << abort(FatalError); } } } }