https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SBMBndElementBase.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 "SBMBndElementBase.h"
11#include "Ball.h"
12#include "GeometryBase.h"
13#include "LineSegment.h"
14#include "libmesh/string_to_enum.h"
15
16SBMBndElementBase::SBMBndElementBase(const Elem * elem, const Point & normal)
17 : _elem(elem), _normal(normal)
18{
19 mooseAssert(elem, "Element must not be null");
20 mooseAssert(MooseUtils::absoluteFuzzyEqual(_normal.norm(), 1),
21 "normal vector must be unit length, length = " << _normal.norm());
22
23 // Validate side type once, here, so distanceFrom() can trust the invariant
24 // without paying a per-call check. libMesh standard elements have uniform
25 // side types, so probing side(0) is sufficient.
26 if (elem && elem->n_sides() > 0)
27 {
28 const auto t = elem->build_side_ptr(0)->type();
29 if (t != EDGE2 && t != NODEELEM)
30 mooseError("SBMBndElementBase: unsupported side type ",
32 " (from element type ",
34 "). distanceFrom() only handles EDGE2 and NODEELEM sides.");
35 }
36}
37
38Point
39SBMBndElementBase::distanceFrom(const Point & pt) const
40{
41 // Side-type precondition is validated once in the base ctor; no per-call
42 // check needed here.
43
44 // (a) Project pt onto the normal direction
45 const auto vec_to_first = _elem->point(0) - pt;
46 const auto scale = vec_to_first * _normal;
47 const auto projection = _normal * scale;
48
49 // Check if projection point lands inside the geometry
50 if (_elem->contains_point(pt + projection))
51 return projection;
52
53 // (d) Point to closest edge or node
54 Real min_dist = std::numeric_limits<Real>::max();
55 Point closest_vec;
56
57 const unsigned int n_edges = _elem->n_sides();
58 for (unsigned int j = 0; j < n_edges; ++j)
59 {
60 std::unique_ptr<const Elem> curr_edge = _elem->build_side_ptr(j);
61
62 switch (curr_edge->type())
63 {
64 case EDGE2:
65 {
66 const Point & p1 = *curr_edge->node_ptr(0);
67 const Point & p2 = *curr_edge->node_ptr(1);
68
69 const Point edge = p2 - p1;
70 Real t = ((pt - p1) * edge) / (edge * edge);
71 t = std::clamp(t, 0.0, 1.0);
72 const Point proj = p1 + t * edge;
73 const Real dist = (pt - proj).norm();
74
75 if (dist < min_dist)
76 {
77 min_dist = dist;
78 closest_vec = proj - pt;
79 }
80 break;
81 }
82
83 case NODEELEM:
84 {
85 const Point & p = *curr_edge->node_ptr(0);
86 const Real dist = (pt - p).norm();
87 if (dist < min_dist)
88 {
89 min_dist = dist;
90 closest_vec = p - pt;
91 }
92 break;
93 }
94
95 default:
96 mooseAssert(false, "unreachable: side type validated in SBMBndElementBase ctor");
97 }
98 }
99
100 return closest_vec;
101}
102
103Real
105{
106 BoundingBox bbox = _elem->loose_bounding_box();
107
108 const Point & min_pt = bbox.first;
109 const Point & max_pt = bbox.second;
110
111 // Step (a): Calculate box_vec
112 Point box_vec = max_pt - min_pt;
113
114 // Step (b): Project box_vec onto normal_dir
115 Real normal_scale = box_vec * normal_dir;
116 Point normal_box_vec = normal_dir * normal_scale;
117
118 // Step (c): Calculate tangent_vec and its norm
119 Point tangent_vec = box_vec - normal_box_vec;
120
121 return tangent_vec.norm();
122}
123
124bool
125SBMBndElementBase::intersect(const LineSegment & line_segment) const
126{
127 if (const auto * geom = dynamic_cast<const GeometryBase *>(this))
128 return geom->intersect(line_segment);
129
130 mooseError("SBMBndElementBase::intersect: unsupported geometry type");
131}
132
133Ball
135{
136 if (const auto * geom = dynamic_cast<const GeometryBase *>(this))
137 return geom->computeBoundingBall();
138
139 mooseError("SBMBndElementBase::computeBoundingBall: unsupported geometry type");
140}
const Real p
void mooseError(Args &&... args)
Real scale
Ball computeBoundingBall() const override
Ball computeBoundingBall() const
Compute a bounding ball for this boundary element.
Real getProjectedBoundingBoxDiagonal(const Point &normal_dir) const
Compute the length of the element bounding-box diagonal projected onto a plane orthogonal to a given ...
virtual Point distanceFrom(const Point &pt) const
Compute the distance vector from an arbitrary point to this boundary element.
const Elem * _elem
< Pointer to the libMesh element representing this boundary face.
SBMBndElementBase(const Elem *elem, const Point &normal)
Constructor takes a pointer to a boundary element and its precomputed unit normal.
const Elem & elem() const
Getter for the underlying element.
bool intersect(const LineSegment &line_segment) const
Check if the given line segment intersects this boundary element.
std::string enum_to_string(const T e)