https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SBMSurfaceDistanceTest.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#include "gtest/gtest.h"
11#include "SurfaceEdge2.h"
12#include "SurfaceTri3.h"
13#include "SBMSurfaceDistance.h"
14#include "MooseMesh.h"
15#include "libmesh/face_tri3.h"
16#include "libmesh/edge_edge2.h"
17
18// The surface-element geometry (normals, intersect, bounding ball, projected
19// bounding-box diagonal, unsupported-geometry dispatchers) is covered by the
20// framework SurfaceElementTest. These tests cover only the SBM-owned
21// SBMUtils::distanceFrom free function.
22
23TEST(SBMSurfaceDistanceTest, Edge2NormalProjection)
24{
25 std::unique_ptr<Edge2> edge(new Edge2());
26 std::unique_ptr<Node> n0(new Node(Point(0.0, 0.0, 0.0), 0));
27 std::unique_ptr<Node> n1(new Node(Point(1.0, 0.0, 0.0), 1));
28 edge->set_node(0, n0.get());
29 edge->set_node(1, n1.get());
30
31 SurfaceEdge2 surface_edge(edge.get());
32
33 // Point directly above the edge midpoint: distance vector is normal-based.
34 Point pt(0.5, 1.0, 0.0);
35 Point dist = SBMUtils::distanceFrom(surface_edge, pt);
36 EXPECT_NEAR(dist(1), -1.0, 1e-12);
37}
38
39TEST(SBMSurfaceDistanceTest, Edge2NodeFallback)
40{
41 // Edge from (0,0,0) to (1,0,0); query point lies far off the line axis so its
42 // projection onto the edge falls outside the segment, forcing the side loop in
43 // distanceFrom() to take the NODEELEM/vertex fallback.
44 std::unique_ptr<Edge2> edge(new Edge2());
45 std::unique_ptr<Node> n0(new Node(Point(0.0, 0.0, 0.0), 0));
46 std::unique_ptr<Node> n1(new Node(Point(1.0, 0.0, 0.0), 1));
47 edge->set_node(0, n0.get());
48 edge->set_node(1, n1.get());
49
50 SurfaceEdge2 surface_edge(edge.get());
51
52 // Projection of (2, 1, 0) onto the line is (2, 0, 0), outside [0,1]; the
53 // nearest entity is node (1, 0, 0).
54 Point pt(2.0, 1.0, 0.0);
55 Point dist = SBMUtils::distanceFrom(surface_edge, pt);
56 EXPECT_NEAR(dist(0), -1.0, 1e-12);
57 EXPECT_NEAR(dist(1), -1.0, 1e-12);
58 EXPECT_NEAR(dist(2), 0.0, 1e-12);
59}
60
61TEST(SBMSurfaceDistanceTest, Edge2TiltedDirection)
62{
63 std::unique_ptr<Edge2> edge(new Edge2());
64 std::unique_ptr<Node> n0(new Node(Point(0.0, 0.0, 0.0), 0));
65 std::unique_ptr<Node> n1(new Node(Point(1.0, 1.0, 0.0), 1));
66 edge->set_node(0, n0.get());
67 edge->set_node(1, n1.get());
68
69 SurfaceEdge2 surface_edge(edge.get());
70 const Point n = surface_edge.normal();
71
72 Point pt(0.5, 0.0, 0.0);
73 Point dist = SBMUtils::distanceFrom(surface_edge, pt);
74 // Distance vector should point along the normal direction.
75 const double dot = dist(0) * n(0) + dist(1) * n(1);
76 EXPECT_GT(dot, 0.0);
77 // The nearest point on the edge to (0.5, 0, 0) is its projection (0.25, 0.25, 0), so the
78 // distance vector has magnitude 0.25 * sqrt(2). Pinning the magnitude guards against a
79 // right-direction-but-wrong-length result.
80 EXPECT_NEAR(dist.norm(), 0.25 * std::sqrt(2.0), 1e-12);
81}
82
83TEST(SBMSurfaceDistanceTest, Tri3NormalProjection)
84{
85 std::unique_ptr<Tri3> tri(new Tri3());
86 std::unique_ptr<Node> n0(new Node(Point(0.0, 0.0, 0.0), 0));
87 std::unique_ptr<Node> n1(new Node(Point(1.0, 0.0, 0.0), 1));
88 std::unique_ptr<Node> n2(new Node(Point(0.0, 1.0, 0.0), 2));
89 tri->set_node(0, n0.get());
90 tri->set_node(1, n1.get());
91 tri->set_node(2, n2.get());
92
93 SurfaceTri3 surface_tri(tri.get());
94
95 // Point above the triangle interior: distance vector roughly in -Z.
96 Point pt(0.3, 0.3, 1.0);
97 Point dist = SBMUtils::distanceFrom(surface_tri, pt);
98 EXPECT_NEAR(dist(2), -1.0, 1e-12);
99}
100
101TEST(SBMSurfaceDistanceTest, Tri3Tilted)
102{
103 std::unique_ptr<Tri3> tri(new Tri3());
104 std::unique_ptr<Node> n0(new Node(Point(0.0, 0.0, 0.0), 0));
105 std::unique_ptr<Node> n1(new Node(Point(1.0, 0.0, 1.0), 1));
106 std::unique_ptr<Node> n2(new Node(Point(0.0, 1.0, 1.0), 2));
107 tri->set_node(0, n0.get());
108 tri->set_node(1, n1.get());
109 tri->set_node(2, n2.get());
110
111 SurfaceTri3 surface_tri(tri.get());
112
113 // Off-element query: nearest entity is a vertex/edge of the tilted triangle.
114 Point pt(2.0, 0.0, 2.0);
115 Point dist = SBMUtils::distanceFrom(surface_tri, pt);
116 EXPECT_NEAR(dist(0), -1.0, 1e-12);
117 EXPECT_NEAR(dist(1), 0.0, 1e-12);
118 EXPECT_NEAR(dist(2), -1.0, 1e-12);
119
120 // Query exactly on a vertex: zero distance vector.
121 Point pt2(0.0, 0.0, 0.0);
122 Point dist2 = SBMUtils::distanceFrom(surface_tri, pt2);
123 EXPECT_NEAR(dist2(0), 0.0, 1e-12);
124 EXPECT_NEAR(dist2(1), 0.0, 1e-12);
125 EXPECT_NEAR(dist2(2), 0.0, 1e-12);
126}
TEST(SBMSurfaceDistanceTest, Edge2NormalProjection)
const Point & normal() const
libMesh::Point distanceFrom(const SurfaceElement &surface_elem, const libMesh::Point &pt)
Returns the vector from pt to the nearest point on the surface element: the normal projection if it f...