39 void Foam::CV2D::insertBoundingBox()
41 Info<<
"insertBoundingBox: creating bounding mesh" <<
endl;
42 scalar bigSpan = 10*meshControls().span();
50 void Foam::CV2D::fast_restore_Delaunay(Vertex_handle vh)
53 Face_handle f = vh->face(), next, start(f);
60 if (!internal_flip(f, cw(i))) external_flip(f, i);
61 if (f->neighbor(i) == start) start = f;
63 f = f->neighbor(cw(i));
68 void Foam::CV2D::external_flip(Face_handle& f,
int i)
70 Face_handle n = f->neighbor(i);
74 CGAL::ON_POSITIVE_SIDE
75 != side_of_oriented_circle(n, f->vertex(i)->point())
79 i = n->index(f->vertex(i));
84 bool Foam::CV2D::internal_flip(Face_handle& f,
int i)
86 Face_handle n = f->neighbor(i);
90 CGAL::ON_POSITIVE_SIDE
91 != side_of_oriented_circle(n, f->vertex(i)->point())
108 const dictionary& cvMeshDict
113 rndGen_(64293*Pstream::myProcNo()),
118 "cvSearchableSurfaces",
120 searchableSurface::geometryDir(runTime),
125 cvMeshDict.subDict(
"geometry"),
126 cvMeshDict.lookupOrDefault(
"singleRegionName", true)
133 cvMeshDict.subDict(
"surfaceConformation")
135 controls_(cvMeshDict, qSurf_.globalBounds()),
139 cvMeshDict.subDict(
"motionControl").subDict(
"shapeControlFunctions"),
141 controls_.minCellSize()
147 cvMeshDict.subDict(
"motionControl"),
155 cvMeshDict.subDict(
"surfaceConformation").
lookup(
"insidePoint")
158 startOfInternalPoints_(0),
159 startOfSurfacePointPairs_(0),
160 startOfBoundaryConformPointPairs_(0),
166 insertFeaturePoints();
181 const scalar nearness
184 Info<<
"insertInitialPoints(const point2DField& points): ";
186 startOfInternalPoints_ = number_of_vertices();
187 label nVert = startOfInternalPoints_;
201 <<
"Rejecting point " << p <<
" outside surface" <<
endl;
205 Info<< nVert <<
" vertices inserted" <<
endl;
220 IFstream pointsFile(pointFileName);
222 if (pointsFile.good())
233 <<
"Could not open pointsFile " << pointFileName
241 Info<<
"insertInitialGrid: ";
243 startOfInternalPoints_ = number_of_vertices();
244 label nVert = startOfInternalPoints_;
249 scalar deltax = xR/ni;
254 scalar deltay = yR/nj;
259 for (
int i=0; i<ni; i++)
261 for (
int j=0; j<nj; j++)
263 point
p(x0 + i*deltax, y0 + j*deltay, 0);
267 p.x() += pert*(
rndGen.scalar01() - 0.5);
268 p.y() += pert*(
rndGen.scalar01() - 0.5);
273 insert(Point(p.x(), p.y()))->index() = nVert++;
278 Info<< nVert <<
" vertices inserted" <<
endl;
293 startOfSurfacePointPairs_ = number_of_vertices();
297 insertSurfaceNearestPointPairs();
306 insertSurfaceNearPointPairs();
309 startOfBoundaryConformPointPairs_ = number_of_vertices();
317 markNearBoundaryPoints();
323 Triangulation::Finite_faces_iterator fit = finite_faces_begin();
324 fit != finite_faces_end();
333 label nIntersections = insertBoundaryConformPointPairs
335 "surfaceIntersections_" +
Foam::name(iter) +
".obj" 338 if (nIntersections == 0)
344 Info<<
"BC iteration " << iter <<
": " 345 << nIntersections <<
" point-pairs inserted" <<
endl;
353 Triangulation::Finite_faces_iterator fit = finite_faces_begin();
354 fit != finite_faces_end();
379 Triangulation::Finite_vertices_iterator vit = finite_vertices_begin();
380 vit != finite_vertices_end();
384 if (vit->index() >= startOfSurfacePointPairs_)
394 const scalar relaxation = relaxationModel_->relaxation();
396 Info<<
"Relaxation = " << relaxation <<
endl;
398 Field<point2D> dualVertices(number_of_faces());
405 Triangulation::Finite_faces_iterator fit = finite_faces_begin();
406 fit != finite_faces_end();
410 fit->faceIndex() = -1;
414 fit->vertex(0)->internalOrBoundaryPoint()
415 || fit->vertex(1)->internalOrBoundaryPoint()
416 || fit->vertex(2)->internalOrBoundaryPoint()
419 fit->faceIndex() = dualVerti;
421 dualVertices[dualVerti] =
toPoint2D(circumcenter(fit));
427 dualVertices.setSize(dualVerti);
429 Field<vector2D> displacementAccumulator
431 startOfSurfacePointPairs_,
438 number_of_vertices(),
442 Field<vector2D> alignments
444 number_of_vertices(),
450 Triangulation::Finite_vertices_iterator vit = finite_vertices_begin();
451 vit != finite_vertices_end();
455 if (vit->internalOrBoundaryPoint())
461 label hitSurface = -1;
474 allGeometry_[hitSurface].getNormal
476 List<pointIndexHit>(1, pHit),
480 alignments[vit->index()] =
toPoint2D(norm[0]);
482 sizes[vit->index()] =
493 scalar cosAlignmentAcceptanceAngle = 0.68;
499 PackedBoolList pointToBeRetained(startOfSurfacePointPairs_,
true);
501 std::list<Point> pointsToInsert;
505 Triangulation::Finite_edges_iterator eit = finite_edges_begin();
506 eit != finite_edges_end();
510 Vertex_handle vA = eit->first->vertex(cw(eit->second));
511 Vertex_handle vB = eit->first->vertex(ccw(eit->second));
513 if (!vA->internalOrBoundaryPoint() || !vB->internalOrBoundaryPoint())
518 const point2D& dualV1 = dualVertices[eit->first->faceIndex()];
520 dualVertices[eit->first->neighbor(eit->second)->faceIndex()];
522 scalar dualEdgeLength =
mag(dualV1 - dualV2);
527 Field<vector2D> alignmentDirsA(2);
529 alignmentDirsA[0] = alignments[vA->index()];
532 -alignmentDirsA[0].
y(),
533 alignmentDirsA[0].
x()
536 Field<vector2D> alignmentDirsB(2);
538 alignmentDirsB[0] = alignments[vB->index()];
541 -alignmentDirsB[0].
y(),
542 alignmentDirsB[0].
x()
545 Field<vector2D> alignmentDirs(alignmentDirsA);
547 forAll(alignmentDirsA, aA)
549 const vector2D& a(alignmentDirsA[aA]);
551 scalar maxDotProduct = 0.0;
553 forAll(alignmentDirsB, aB)
557 scalar dotProduct = a &
b;
559 if (
mag(dotProduct) > maxDotProduct)
561 maxDotProduct =
mag(dotProduct);
563 alignmentDirs[aA] = a +
sign(dotProduct)*
b;
565 alignmentDirs[aA] /=
mag(alignmentDirs[aA]);
572 scalar rABMag =
mag(rAB);
576 vector2D& alignmentDir = alignmentDirs[aD];
578 if ((rAB & alignmentDir) < 0)
585 scalar alignmentDotProd = ((rAB/rABMag) & alignmentDir);
587 if (alignmentDotProd > cosAlignmentAcceptanceAngle)
589 scalar targetFaceSize =
590 0.5*(sizes[vA->index()] + sizes[vB->index()]);
599 alignmentDir *= 0.5*targetFaceSize;
601 vector2D delta = alignmentDir - 0.5*rAB;
603 if (dualEdgeLength < 0.7*targetFaceSize)
607 else if (dualEdgeLength < targetFaceSize)
612 /(targetFaceSize*(u - l))
620 && vB->internalPoint()
621 && rABMag > 1.75*targetFaceSize
622 && dualEdgeLength > 0.05*targetFaceSize
623 && alignmentDotProd > 0.93
627 pointsToInsert.push_back(
toPoint(0.5*(dVA + dVB)));
631 (vA->internalPoint() || vB->internalPoint())
632 && rABMag < 0.65*targetFaceSize
642 pointToBeRetained[vA->index()] ==
true 643 && pointToBeRetained[vB->index()] == true
646 pointsToInsert.push_back(
toPoint(0.5*(dVA + dVB)));
649 if (vA->internalPoint())
651 pointToBeRetained[vA->index()] =
false;
654 if (vB->internalPoint())
656 pointToBeRetained[vB->index()] =
false;
661 if (vA->internalPoint())
663 displacementAccumulator[vA->index()] +=
delta;
666 if (vB->internalPoint())
668 displacementAccumulator[vB->index()] += -
delta;
676 scalar totalDist =
sum(
mag(displacementAccumulator));
679 displacementAccumulator *= relaxation;
681 label numberOfNewPoints = pointsToInsert.size();
685 Triangulation::Finite_vertices_iterator vit = finite_vertices_begin();
686 vit != finite_vertices_end();
690 if (vit->internalPoint())
692 if (pointToBeRetained[vit->index()])
694 pointsToInsert.push_front
699 + displacementAccumulator[vit->index()]
712 reinsertFeaturePoints();
714 startOfInternalPoints_ = number_of_vertices();
716 label nVert = startOfInternalPoints_;
718 Info<<
"Inserting " << numberOfNewPoints <<
" new points" <<
endl;
721 insert(pointsToInsert.begin(), pointsToInsert.end());
725 Delaunay::Finite_vertices_iterator vit = finite_vertices_begin();
726 vit != finite_vertices_end();
736 vit->index() = nVert++;
740 Info<<
" Total displacement = " << totalDisp <<
nl 741 <<
" Total distance = " << totalDist <<
nl 742 <<
" Points added = " << pointsToInsert.size()
990 +
"Triangles/allTriangles_"
dimensionedScalar sign(const dimensionedScalar &ds)
CGAL::Delaunay_triangulation_3< K, Tds, CompactLocator > Delaunay
scalar cellSize(const point &pt) const
#define forAll(list, i)
Loop across all elements in list.
FvWallInfoData< WallInfo, label > label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
vector2D point2D
Point2D is a vector.
void writePatch(const fileName &fName) const
Write patch.
errorManipArg< error, int > exit(error &err, const int errNo=1)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
void insertSurfacePointPairs()
Insert all surface point-pairs from.
Vector2D< scalar > vector2D
vector2D obtained from generic Vector2D
const dimensionedScalar b
Wien displacement law constant: default SI units: [m K].
Ostream & endl(Ostream &os)
Add newline and flush stream.
point toPoint3D(const point2D &) const
const cv2DControls & meshControls() const
void newPoints()
Move the internal points to the given new locations and update.
dimensionedScalar y0(const dimensionedScalar &ds)
PointIndexHit< point > pointIndexHit
void insert(const scalar, DynamicList< floatScalar > &)
Append scalar to given DynamicList.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
const point2D & toPoint2D(const point &) const
void insertGrid()
Create the initial mesh as a regular grid of points.
void writeFaces(const fileName &fName, bool internalOnly) const
Write dual faces as .obj file.
stressControl lookup("compactNormalStress") >> compactNormalStress
PointFromPoint2D toPoint(const point2D &) const
static word timeName(const scalar, const int precision=curPrecision_)
Return time name of given scalar time.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
void insertPoints(const point2DField &points, const scalar nearness)
Create the initial mesh from the given internal points.
label maxBoundaryConformingIter() const
Return the maximum number of boundary conformation iterations.
defineTypeNameAndDebug(combustionModel, 0)
bool mkDir(const fileName &, mode_t=0777)
Make a directory and return an error if it could not be created.
word name(const complex &)
Return a string representation of a complex.
vector2DField point2DField
point2DField is a vector2DField.
const point & max() const
Maximum point defining the bounding box.
void writeTriangles(const fileName &fName, bool internalOnly) const
Write triangles as .obj file.
vector point
Point is a vector.
dimensioned< scalar > mag(const dimensioned< Type > &)
Field< vector > vectorField
Specialisation of Field<T> for vector.
const point & min() const
Minimum point defining the bounding box.
CV2D(const Time &runTime, const dictionary &controlDict)
Construct for given surface.
scalar randomPerturbation() const
Return the random perturbation factor.
void removeSurfacePointPairs()
Remove the point-pairs introduced by insertSurfacePointPairs.
static const Vector2D< scalar > zero
void boundaryConform()
Insert point-pairs where there are protrusions into.