void Foam::CV2D::removeSurfacePointPairs() { for ( Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); vit != finite_vertices_end(); ++vit ) { if (vit->index() >= startOfSurfacePointPairs_) { remove(vit); } } }
void Foam::CV2D::writeTriangles(const fileName& fName, bool internalOnly) const { Info<< "Writing triangles to " << fName << nl << endl; OFstream str(fName); labelList vertexMap(number_of_vertices(), -2); label verti = 0; for ( Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); vit != finite_vertices_end(); ++vit ) { if (!internalOnly || !vit->farPoint()) { vertexMap[vit->index()] = verti++; meshTools::writeOBJ(str, toPoint3D(vit->point())); } } for ( Triangulation::Finite_faces_iterator fit = finite_faces_begin(); fit != finite_faces_end(); ++fit ) { if ( !internalOnly || ( fit->vertex(0)->internalOrBoundaryPoint() || fit->vertex(1)->internalOrBoundaryPoint() || fit->vertex(2)->internalOrBoundaryPoint() ) ) { str << "f"; for (label i = 0; i < 3; ++i) { str << " " << vertexMap[fit->vertex(i)->index()] + 1; } str << nl; } } }
void Foam::CV2D::writePoints(const fileName& fName, bool internalOnly) const { Info<< "Writing points to " << fName << nl << endl; OFstream str(fName); for ( Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); vit != finite_vertices_end(); ++vit ) { if (!internalOnly || vit->internalOrBoundaryPoint()) { meshTools::writeOBJ(str, toPoint3D(vit->point())); } } }
void Foam::conformalVoronoiMesh::cellSizeMeshOverlapsBackground() const { const cellShapeControlMesh& cellSizeMesh = cellShapeControl_.shapeControlMesh(); DynamicList<Foam::point> pts(number_of_vertices()); for ( Delaunay::Finite_vertices_iterator vit = finite_vertices_begin(); vit != finite_vertices_end(); ++vit ) { if (vit->internalOrBoundaryPoint() && !vit->referred()) { pts.append(topoint(vit->point())); } } boundBox bb(pts); boundBox cellSizeMeshBb = cellSizeMesh.bounds(); bool fullyContained = true; if (!cellSizeMeshBb.contains(bb)) { Pout<< "Triangulation not fully contained in cell size mesh." << endl; Pout<< "Cell Size Mesh Bounds = " << cellSizeMesh.bounds() << endl; Pout<< "foamyHexMesh Bounds = " << bb << endl; fullyContained = false; } reduce(fullyContained, andOp<unsigned int>()); Info<< "Triangulation is " << (fullyContained ? "fully" : "not fully") << " contained in the cell size mesh" << endl; }
Foam::label Foam::cellShapeControlMesh::removePoints() { label nRemoved = 0; for ( CellSizeDelaunay::Finite_vertices_iterator vit = finite_vertices_begin(); vit != finite_vertices_end(); ++vit ) { std::list<Vertex_handle> verts; adjacent_vertices(vit, std::back_inserter(verts)); bool removePt = true; for ( std::list<Vertex_handle>::iterator aVit = verts.begin(); aVit != verts.end(); ++aVit ) { Vertex_handle avh = *aVit; scalar diff = mag(avh->targetCellSize() - vit->targetCellSize()) /max(vit->targetCellSize(), 1e-6); if (diff > 0.05) { removePt = false; } } if (removePt) { remove(vit); nRemoved++; } } return nRemoved; }
void DualPolyhedron_3::initialize() { DEBUG_START; /* * FIXME: Remove these two loops when local initialization will be * implemented */ for (SupportItem &item : items) item.associations.clear(); for (auto I = cells_begin(), E = cells_end(); I != E; ++I) I->info().associations.clear(); for (auto I = finite_vertices_begin(), E = finite_vertices_end(); I != E; ++I) associateVertex(I); if (getenv("INTERNAL_CHECK")) verify(); DEBUG_END; }
Foam::boundBox Foam::cellShapeControlMesh::bounds() const { DynamicList<Foam::point> pts(number_of_vertices()); for ( Finite_vertices_iterator vit = finite_vertices_begin(); vit != finite_vertices_end(); ++vit ) { if (vit->real()) { pts.append(topoint(vit->point())); } } boundBox bb(pts); return bb; }
void Foam::CV2D::calcDual ( point2DField& dualPoints, faceList& dualFaces, wordList& patchNames, labelList& patchSizes, EdgeMap<label>& mapEdgesRegion, EdgeMap<label>& indirectPatchEdge ) const { // Dual points stored in triangle order. dualPoints.setSize(number_of_faces()); label dualVerti = 0; for ( Triangulation::Finite_faces_iterator fit = finite_faces_begin(); fit != finite_faces_end(); ++fit ) { if ( fit->vertex(0)->internalOrBoundaryPoint() || fit->vertex(1)->internalOrBoundaryPoint() || fit->vertex(2)->internalOrBoundaryPoint() ) { fit->faceIndex() = dualVerti; dualPoints[dualVerti++] = toPoint2D(circumcenter(fit)); } else { fit->faceIndex() = -1; } } dualPoints.setSize(dualVerti); extractPatches(patchNames, patchSizes, mapEdgesRegion, indirectPatchEdge); forAll(patchNames, patchi) { Info<< "Patch " << patchNames[patchi] << " has size " << patchSizes[patchi] << endl; } // Create dual faces // ~~~~~~~~~~~~~~~~~ dualFaces.setSize(number_of_vertices()); label dualFacei = 0; labelList faceVerts(maxNvert); for ( Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); vit != finite_vertices_end(); ++vit ) { if (vit->internalOrBoundaryPoint()) { Face_circulator fcStart = incident_faces(vit); Face_circulator fc = fcStart; label verti = 0; do { if (!is_infinite(fc)) { if (fc->faceIndex() < 0) { FatalErrorInFunction << "Dual face uses vertex defined by a triangle" " defined by an external point" << exit(FatalError); } // Look up the index of the triangle faceVerts[verti++] = fc->faceIndex(); } } while (++fc != fcStart); if (faceVerts.size() > 2) { dualFaces[dualFacei++] = face(labelList::subList(faceVerts, verti)); } else { Info<< "From triangle point:" << vit->index() << " coord:" << toPoint2D(vit->point()) << " generated illegal dualFace:" << faceVerts << endl; } } } dualFaces.setSize(dualFacei); }
void Foam::CV2D::writeFaces(const fileName& fName, bool internalOnly) const { Info<< "Writing dual faces to " << fName << nl << endl; OFstream str(fName); label dualVerti = 0; for ( Triangulation::Finite_faces_iterator fit = finite_faces_begin(); fit != finite_faces_end(); ++fit ) { if ( !internalOnly || ( fit->vertex(0)->internalOrBoundaryPoint() || fit->vertex(1)->internalOrBoundaryPoint() || fit->vertex(2)->internalOrBoundaryPoint() ) ) { fit->faceIndex() = dualVerti++; meshTools::writeOBJ(str, toPoint3D(circumcenter(fit))); } else { fit->faceIndex() = -1; } } for ( Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); vit != finite_vertices_end(); ++vit ) { if (!internalOnly || vit->internalOrBoundaryPoint()) { Face_circulator fcStart = incident_faces(vit); Face_circulator fc = fcStart; str<< 'f'; do { if (!is_infinite(fc)) { if (fc->faceIndex() < 0) { FatalErrorInFunction << "Dual face uses vertex defined by a triangle" " defined by an external point" << exit(FatalError); } str<< ' ' << fc->faceIndex() + 1; } } while (++fc != fcStart); str<< nl; } } }
void Foam::cellShapeControlMesh::distribute ( const backgroundMeshDecomposition& decomposition ) { DynamicList<Foam::point> points(number_of_vertices()); DynamicList<scalar> sizes(number_of_vertices()); DynamicList<tensor> alignments(number_of_vertices()); DynamicList<Vb> farPts(8); for ( Finite_vertices_iterator vit = finite_vertices_begin(); vit != finite_vertices_end(); ++vit ) { if (vit->real()) { points.append(topoint(vit->point())); sizes.append(vit->targetCellSize()); alignments.append(vit->alignment()); } else if (vit->farPoint()) { farPts.append ( Vb ( vit->point(), -1, Vb::vtFar, Pstream::myProcNo() ) ); farPts.last().targetCellSize() = vit->targetCellSize(); farPts.last().alignment() = vit->alignment(); } } autoPtr<mapDistribute> mapDist = DistributedDelaunayMesh<CellSizeDelaunay>::distribute ( decomposition, points ); mapDist().distribute(sizes); mapDist().distribute(alignments); // Reset the entire tessellation DelaunayMesh<CellSizeDelaunay>::reset(); // Internal points have to be inserted first DynamicList<Vb> verticesToInsert(points.size()); forAll(farPts, ptI) { verticesToInsert.append(farPts[ptI]); }
Foam::cellShapeControlMesh::cellShapeControlMesh(const Time& runTime) : DistributedDelaunayMesh<CellSizeDelaunay> ( runTime, meshSubDir ), runTime_(runTime), defaultCellSize_(0.0) { if (this->vertexCount()) { fvMesh mesh ( IOobject ( meshSubDir, runTime.timeName(), runTime, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE ) ); if (mesh.nPoints() == this->vertexCount()) { pointScalarField sizes ( IOobject ( "sizes", runTime.timeName(), meshSubDir, runTime, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false ), pointMesh::New(mesh) ); triadIOField alignments ( IOobject ( "alignments", mesh.time().timeName(), meshSubDir, mesh.time(), IOobject::READ_IF_PRESENT, IOobject::AUTO_WRITE, false ) ); if ( sizes.size() == this->vertexCount() && alignments.size() == this->vertexCount() ) { for ( Finite_vertices_iterator vit = finite_vertices_begin(); vit != finite_vertices_end(); ++vit ) { vit->targetCellSize() = sizes[vit->index()]; vit->alignment() = alignments[vit->index()]; } } else { FatalErrorInFunction << "Cell size point field is not the same size as the " << "mesh." << abort(FatalError); } } } }
void Foam::CV2D::newPoints() { const scalar relaxation = relaxationModel_->relaxation(); Info<< "Relaxation = " << relaxation << endl; Field<point2D> dualVertices(number_of_faces()); label dualVerti = 0; // Find the dual point of each tetrahedron and assign it an index. for ( Triangulation::Finite_faces_iterator fit = finite_faces_begin(); fit != finite_faces_end(); ++fit ) { fit->faceIndex() = -1; if ( fit->vertex(0)->internalOrBoundaryPoint() || fit->vertex(1)->internalOrBoundaryPoint() || fit->vertex(2)->internalOrBoundaryPoint() ) { fit->faceIndex() = dualVerti; dualVertices[dualVerti] = toPoint2D(circumcenter(fit)); dualVerti++; } } dualVertices.setSize(dualVerti); Field<vector2D> displacementAccumulator ( startOfSurfacePointPairs_, vector2D::zero ); // Calculate target size and alignment for vertices scalarField sizes ( number_of_vertices(), meshControls().minCellSize() ); Field<vector2D> alignments ( number_of_vertices(), vector2D(1, 0) ); for ( Triangulation::Finite_vertices_iterator vit = finite_vertices_begin(); vit != finite_vertices_end(); ++vit ) { if (vit->internalOrBoundaryPoint()) { point2D vert = toPoint2D(vit->point()); // alignment and size determination pointIndexHit pHit; label hitSurface = -1; qSurf_.findSurfaceNearest ( toPoint3D(vert), meshControls().span2(), pHit, hitSurface ); if (pHit.hit()) { vectorField norm(1); allGeometry_[hitSurface].getNormal ( List<pointIndexHit>(1, pHit), norm ); alignments[vit->index()] = toPoint2D(norm[0]); sizes[vit->index()] = cellSizeControl_.cellSize ( toPoint3D(vit->point()) ); } } } // Info<< "Calculated alignments" << endl; scalar cosAlignmentAcceptanceAngle = 0.68; // Upper and lower edge length ratios for weight scalar u = 1.0; scalar l = 0.7; PackedBoolList pointToBeRetained(startOfSurfacePointPairs_, true); std::list<Point> pointsToInsert; for ( Triangulation::Finite_edges_iterator eit = finite_edges_begin(); eit != finite_edges_end(); eit++ ) { Vertex_handle vA = eit->first->vertex(cw(eit->second)); Vertex_handle vB = eit->first->vertex(ccw(eit->second)); if (!vA->internalOrBoundaryPoint() || !vB->internalOrBoundaryPoint()) { continue; } const point2D& dualV1 = dualVertices[eit->first->faceIndex()]; const point2D& dualV2 = dualVertices[eit->first->neighbor(eit->second)->faceIndex()]; scalar dualEdgeLength = mag(dualV1 - dualV2); point2D dVA = toPoint2D(vA->point()); point2D dVB = toPoint2D(vB->point()); Field<vector2D> alignmentDirsA(2); alignmentDirsA[0] = alignments[vA->index()]; alignmentDirsA[1] = vector2D ( -alignmentDirsA[0].y(), alignmentDirsA[0].x() ); Field<vector2D> alignmentDirsB(2); alignmentDirsB[0] = alignments[vB->index()]; alignmentDirsB[1] = vector2D ( -alignmentDirsB[0].y(), alignmentDirsB[0].x() ); Field<vector2D> alignmentDirs(alignmentDirsA); forAll(alignmentDirsA, aA) { const vector2D& a(alignmentDirsA[aA]); scalar maxDotProduct = 0.0; forAll(alignmentDirsB, aB) { const vector2D& b(alignmentDirsB[aB]); scalar dotProduct = a & b; if (mag(dotProduct) > maxDotProduct) { maxDotProduct = mag(dotProduct); alignmentDirs[aA] = a + sign(dotProduct)*b; alignmentDirs[aA] /= mag(alignmentDirs[aA]); } } } vector2D rAB = dVA - dVB; scalar rABMag = mag(rAB); forAll(alignmentDirs, aD) { vector2D& alignmentDir = alignmentDirs[aD]; if ((rAB & alignmentDir) < 0) { // swap the direction of the alignment so that has the // same sense as rAB alignmentDir *= -1; } scalar alignmentDotProd = ((rAB/rABMag) & alignmentDir); if (alignmentDotProd > cosAlignmentAcceptanceAngle) { scalar targetFaceSize = 0.5*(sizes[vA->index()] + sizes[vB->index()]); // Test for changing aspect ratio on second alignment (first // alignment is neartest surface normal) // if (aD == 1) // { // targetFaceSize *= 2.0; // } alignmentDir *= 0.5*targetFaceSize; vector2D delta = alignmentDir - 0.5*rAB; if (dualEdgeLength < 0.7*targetFaceSize) { delta *= 0; } else if (dualEdgeLength < targetFaceSize) { delta *= ( dualEdgeLength /(targetFaceSize*(u - l)) - 1/((u/l) - 1) ); } if ( vA->internalPoint() && vB->internalPoint() && rABMag > 1.75*targetFaceSize && dualEdgeLength > 0.05*targetFaceSize && alignmentDotProd > 0.93 ) { // Point insertion pointsToInsert.push_back(toPoint(0.5*(dVA + dVB))); } else if ( (vA->internalPoint() || vB->internalPoint()) && rABMag < 0.65*targetFaceSize ) { // Point removal // Only insert a point at the midpoint of the short edge // if neither attached point has already been identified // to be removed. if ( pointToBeRetained[vA->index()] == true && pointToBeRetained[vB->index()] == true ) { pointsToInsert.push_back(toPoint(0.5*(dVA + dVB))); } if (vA->internalPoint()) { pointToBeRetained[vA->index()] = false; } if (vB->internalPoint()) { pointToBeRetained[vB->index()] = false; } } else { if (vA->internalPoint()) { displacementAccumulator[vA->index()] += delta; } if (vB->internalPoint()) { displacementAccumulator[vB->index()] += -delta; } } } } }