https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Classes | Functions
SBMUtils Namespace Reference

Classes

struct  ClassificationSubdomains
 The subdomain IDs a (possibly partial) element can be labeled with. More...
 
struct  ElementActivity
 Measured activity state of a (possibly partial) element, used to classify it. More...
 

Functions

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 falls inside the element, otherwise the nearest edge or vertex.
 
bool checkWatertightnessFromRawElems (const std::vector< const Elem * > &bd_elements)
 
Real activeElementFraction (const Elem &elem, Order qrule_order, const std::function< bool(const libMesh::Point &)> &is_active)
 Compute the fraction of an element's quadrature-weighted measure satisfying a predicate.
 
bool isInactive (Real active_fraction, Real lambda)
 Return whether a partial element is inactive, i.e.
 
SubdomainID classifyPartialElement (const ElementActivity &activity, const ClassificationSubdomains &subdomains, bool mark_intercepted, Real lambda)
 Classify a (possibly partial) element into an inside/outside/intercepted subdomain.
 
std::vector< const Function * > buildDistanceFunctions (const std::vector< FunctionName > &function_names, const FunctionInterface &function_provider)
 Build a list of distance functions based on names specified in input.
 
RealVectorValue distanceVectorFromFunction (const Function *func, const libMesh::Point &pt, Real t)
 Compute the distance vector induced by a distance function.
 
RealVectorValue trueNormalFromFunction (const Function *func, const libMesh::Point &pt, Real t)
 Compute the true boundary surface normal at the point on the boundary closest to pt.
 
RealVectorValue closestDistanceVector (const std::vector< const Function * > &funcs, const libMesh::Point &pt, Real t)
 Scan all distance functions and return the closest distance vector.
 
RealVectorValue closestTrueNormalVector (const std::vector< const Function * > &funcs, const libMesh::Point &pt, Real t)
 Scan all distance functions and return the corresponding normal vector.
 
Real unionSignedDistance (const std::vector< const Function * > &funcs, Real t, const Point &p)
 Computes the union signed distance by taking the minimum of all signed distance functions.
 
Point distanceFrom (const SurfaceElement &surface_elem, const Point &pt)
 

Function Documentation

◆ activeElementFraction()

Real SBMUtils::activeElementFraction ( const Elem &  elem,
Order  qrule_order,
const std::function< bool(const libMesh::Point &)> &  is_active 
)

Compute the fraction of an element's quadrature-weighted measure satisfying a predicate.

Definition at line 26 of file SBMUtils.C.

29{
30 const FEType fe_type(elem.default_order(), LAGRANGE);
31 auto fe = FEBase::build(elem.dim(), fe_type);
32 QGauss qrule(elem.dim(), qrule_order);
33 const auto & q_points = fe->get_xyz();
34 const auto & JxW = fe->get_JxW();
35 fe->attach_quadrature_rule(&qrule);
36 fe->reinit(&elem);
37
38 Real active_measure = 0.0;
39 Real total_measure = 0.0;
40 for (const auto i : index_range(q_points))
41 {
42 if (is_active(q_points[i]))
43 active_measure += JxW[i];
44 total_measure += JxW[i];
45 }
46
47 return active_measure / total_measure;
48}

Referenced by InterceptedElementModifier::computeSubdomainID(), SubdomainElementModifier::computeSubdomainID(), and TEST().

◆ buildDistanceFunctions()

std::vector< const Function * > SBMUtils::buildDistanceFunctions ( const std::vector< FunctionName > &  function_names,
const FunctionInterface function_provider 
)

Build a list of distance functions based on names specified in input.

Definition at line 95 of file SBMUtils.C.

97{
98 std::vector<const Function *> funcs;
99 funcs.reserve(function_names.size());
100
101 for (const auto & name : function_names)
102 {
103 const Function * func = &function_provider.getFunctionByName(name);
104 if (!dynamic_cast<const MooseParsedFunction *>(func) &&
105 !dynamic_cast<const UnsignedDistanceToSurfaceMesh *>(func) &&
106 !dynamic_cast<const SignedDistanceToSurfaceMesh *>(func))
107 {
108 mooseError("SBM distance helpers only support ParsedFunction, "
109 "UnsignedDistanceToSurfaceMesh, or SignedDistanceToSurfaceMesh types. Offending "
110 "function: ",
111 name);
112 }
113 funcs.emplace_back(func);
114 }
115
116 return funcs;
117}
void mooseError(Args &&... args)
const std::string name
Definition Setup.h:21
const Function & getFunctionByName(const FunctionName &name) const
Computes the signed distance to a surface mesh using KDTree nearest neighbor lookup from SBMSurfaceMe...
Computes the unsigned distance to a surface mesh using KDTree nearest neighbor lookup from SBMSurface...

Referenced by ShortestDistanceToSurface::ShortestDistanceToSurface().

◆ checkWatertightnessFromRawElems()

bool SBMUtils::checkWatertightnessFromRawElems ( const std::vector< const Elem * > &  bd_elements)

Definition at line 84 of file SBMUtils.C.

85{
86 for (const auto * el : bd_elements)
87 for (unsigned int s = 0; s < el->n_sides(); ++s)
88 if (!el->neighbor_ptr(s))
89 return false;
90
91 return true;
92}
for(PetscInt i=0;i< nvars;++i)
void ErrorVector unsigned int

◆ classifyPartialElement()

SubdomainID SBMUtils::classifyPartialElement ( const ElementActivity activity,
const ClassificationSubdomains subdomains,
bool  mark_intercepted,
Real  lambda 
)

Classify a (possibly partial) element into an inside/outside/intercepted subdomain.

An element with all nodes active and a fully active measure is inside; one with all nodes inactive and a fully inactive measure is outside. A remaining (partial) element is assigned the intercepted subdomain when mark_intercepted is true, and otherwise is resolved by the lambda threshold (see isInactive).

Definition at line 62 of file SBMUtils.C.

66{
67 // Same-side nodes do not rule out a surface crossing the element or enclosing a region
68 // within it. Quadrature sampling detects most such cases, but may miss very small regions.
69 // Exact endpoint comparisons are intentional: activeElementFraction returns exactly zero
70 // or one when no or all quadrature points are active, respectively.
71 if (activity.all_nodes_active && activity.active_fraction == 1.0)
72 return subdomains.inside;
73
74 if (activity.all_nodes_inactive && activity.active_fraction == 0.0)
75 return subdomains.outside;
76
77 if (mark_intercepted)
78 return subdomains.intercepted;
79
80 return isInactive(activity.active_fraction, lambda) ? subdomains.outside : subdomains.inside;
81}
bool isInactive(Real active_fraction, Real lambda)
Return whether a partial element is inactive, i.e.
Definition SBMUtils.C:51
bool all_nodes_active
Whether all of the element's nodes are on the active (retained) side.
Definition SBMUtils.h:49
bool all_nodes_inactive
Whether all of the element's nodes are on the inactive (removed) side.
Definition SBMUtils.h:51
Real active_fraction
Fraction of the element's quadrature-weighted measure that is active, in [0, 1].
Definition SBMUtils.h:53

Referenced by InterceptedElementModifier::computeSubdomainID().

◆ closestDistanceVector()

RealVectorValue SBMUtils::closestDistanceVector ( const std::vector< const Function * > &  funcs,
const libMesh::Point pt,
Real  t 
)

Scan all distance functions and return the closest distance vector.

Definition at line 163 of file SBMUtils.C.

166{
167 Real min_dist = std::numeric_limits<Real>::max();
168 RealVectorValue closest_dist_vec;
169
170 for (const auto & func : funcs)
171 {
172 const auto dist_vec = distanceVectorFromFunction(func, pt, t);
173 const auto dist = dist_vec.norm();
174 if (dist < min_dist)
175 {
176 min_dist = dist;
177 closest_dist_vec = dist_vec;
178 }
179 }
180
181 return closest_dist_vec;
182}
RealVectorValue distanceVectorFromFunction(const Function *func, const libMesh::Point &pt, Real t)
Compute the distance vector induced by a distance function.
Definition SBMUtils.C:120

Referenced by ShortestDistanceToSurface::distanceVector(), and TEST_F().

◆ closestTrueNormalVector()

RealVectorValue SBMUtils::closestTrueNormalVector ( const std::vector< const Function * > &  funcs,
const libMesh::Point pt,
Real  t 
)

Scan all distance functions and return the corresponding normal vector.

Definition at line 185 of file SBMUtils.C.

188{
189 Real min_dist = std::numeric_limits<Real>::max();
190 RealVectorValue closest_normal_vec;
191
192 for (const auto & func : funcs)
193 {
194 const auto dist_vec = distanceVectorFromFunction(func, pt, t);
195 const auto dist = dist_vec.norm();
196 if (dist < min_dist)
197 {
198 min_dist = dist;
199 closest_normal_vec = trueNormalFromFunction(func, pt, t);
200 }
201 }
202
203 return closest_normal_vec;
204}
RealVectorValue trueNormalFromFunction(const Function *func, const libMesh::Point &pt, Real t)
Compute the true boundary surface normal at the point on the boundary closest to pt.
Definition SBMUtils.C:140

Referenced by TEST_F(), and ShortestDistanceToSurface::trueNormal().

◆ distanceFrom() [1/2]

libMesh::Point SBMUtils::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 falls inside the element, otherwise the nearest edge or vertex.

Precondition (mooseAssert in debug builds): the element's sides are EDGE2 or NODEELEM (the only side types this routine handles).

Referenced by UnsignedDistanceToSurfaceMesh::distanceVectorToSurface(), TEST(), TEST(), TEST(), TEST(), and TEST().

◆ distanceFrom() [2/2]

Point SBMUtils::distanceFrom ( const SurfaceElement surface_elem,
const Point &  pt 
)

Definition at line 23 of file SBMSurfaceDistance.C.

24{
25 const Elem & element = surface_elem.elem();
26 const Point & normal = surface_elem.normal();
27
28 // Precondition: this routine only handles EDGE2 and NODEELEM element sides.
29 // libMesh standard elements have uniform side types, so probing side(0) is
30 // sufficient. Validated once here as a debug assert; callers build these from
31 // supported surface meshes.
32 mooseAssert(
33 [&element]()
34 {
35 if (element.n_sides() == 0)
36 return true;
37 const auto t = element.build_side_ptr(0)->type();
38 return t == EDGE2 || t == NODEELEM;
39 }(),
40 "SBMUtils::distanceFrom only handles EDGE2 and NODEELEM element sides.");
41
42 // (a) Project pt onto the normal direction
43 const auto vec_to_first = element.point(0) - pt;
44 const auto scale = vec_to_first * normal;
45 const auto projection = normal * scale;
46
47 // Check if projection point lands inside the geometry
48 if (element.contains_point(pt + projection))
49 return projection;
50
51 // (b) Point to closest edge or node
52 Real min_dist = std::numeric_limits<Real>::max();
53 Point closest_vec;
54
55 const unsigned int n_edges = element.n_sides();
56 for (unsigned int j = 0; j < n_edges; ++j)
57 {
58 std::unique_ptr<const Elem> curr_edge = element.build_side_ptr(j);
59
60 switch (curr_edge->type())
61 {
62 case EDGE2:
63 {
64 const Point & p1 = *curr_edge->node_ptr(0);
65 const Point & p2 = *curr_edge->node_ptr(1);
66
67 const Point edge = p2 - p1;
68 Real t = ((pt - p1) * edge) / (edge * edge);
69 t = std::clamp(t, 0.0, 1.0);
70 const Point proj = p1 + t * edge;
71 const Real dist = (pt - proj).norm();
72
73 if (dist < min_dist)
74 {
75 min_dist = dist;
76 closest_vec = proj - pt;
77 }
78 break;
79 }
80
81 case NODEELEM:
82 {
83 const Point & p = *curr_edge->node_ptr(0);
84 const Real dist = (pt - p).norm();
85 if (dist < min_dist)
86 {
87 min_dist = dist;
88 closest_vec = p - pt;
89 }
90 break;
91 }
92
93 default:
94 mooseAssert(false, "unreachable: side type validated by the precondition above");
95 }
96 }
97
98 return closest_vec;
99}
const Real p
Real scale
const Point & normal() const
const Elem & elem() const
auto norm(const T &a)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

◆ distanceVectorFromFunction()

RealVectorValue SBMUtils::distanceVectorFromFunction ( const Function func,
const libMesh::Point pt,
Real  t 
)

Compute the distance vector induced by a distance function.

The provided function must represent a distance to the true boundary: either a signed distance function (ParsedFunction) or an unsigned distance function provided by UnsignedDistanceToSurfaceMesh.

Definition at line 120 of file SBMUtils.C.

121{
122 mooseAssert(dynamic_cast<const MooseParsedFunction *>(func) ||
123 dynamic_cast<const UnsignedDistanceToSurfaceMesh *>(func) ||
124 dynamic_cast<const SignedDistanceToSurfaceMesh *>(func),
125 "Function was not a valid distance strategy, the only "
126 "supported types are ParsedFunction, UnsignedDistanceToSurfaceMesh, or "
127 "SignedDistanceToSurfaceMesh.");
128
129 const Real phi = func->value(t, pt);
130 const RealVectorValue grad_phi = func->gradient(t, pt);
131 const Real grad_norm = grad_phi.norm();
132
133 if (grad_norm <= libMesh::TOLERANCE)
134 return RealVectorValue(0.0, 0.0, 0.0);
135
136 return -(phi / grad_norm) * grad_phi;
137}
virtual RealGradient gradient(Real t, const Point &p) const
virtual Real value(Real t, const Point &p) const
static constexpr Real TOLERANCE

Referenced by closestDistanceVector(), closestTrueNormalVector(), ShortestDistanceToSurface::distanceVectorByFunc(), ShortestDistanceToSurface::distanceVectorByIndex(), TEST_F(), TEST_F(), and trueNormalFromFunction().

◆ isInactive()

bool SBMUtils::isInactive ( Real  active_fraction,
Real  lambda 
)

Return whether a partial element is inactive, i.e.

its inactive fraction exceeds lambda.

The endpoint handling preserves the convention that lambda zero rejects and lambda one accepts a partially active element.

Definition at line 51 of file SBMUtils.C.

52{
53 if (MooseUtils::absoluteFuzzyEqual(lambda, 0))
54 return true;
55 if (MooseUtils::absoluteFuzzyEqual(lambda, 1))
56 return false;
57
58 return MooseUtils::absoluteFuzzyGreaterThan(1.0 - active_fraction, lambda);
59}

Referenced by classifyPartialElement(), SubdomainElementModifier::computeSubdomainID(), and TEST().

◆ trueNormalFromFunction()

RealVectorValue SBMUtils::trueNormalFromFunction ( const Function func,
const libMesh::Point pt,
Real  t 
)

Compute the true boundary surface normal at the point on the boundary closest to pt.

Definition at line 140 of file SBMUtils.C.

141{
142 if (const auto * parsed = dynamic_cast<const MooseParsedFunction *>(func))
143 {
144 const auto proj_pt = pt + distanceVectorFromFunction(func, pt, t);
145 const RealVectorValue grad_phi = parsed->gradient(t, proj_pt);
146 const Real grad_norm = grad_phi.norm();
147 if (grad_norm <= libMesh::TOLERANCE)
148 return RealVectorValue(0.0, 0.0, 0.0);
149 return grad_phi / grad_norm;
150 }
151 else
152 {
153 const auto * mesh_func = dynamic_cast<const UnsignedDistanceToSurfaceMesh *>(func);
154 if (!mesh_func)
155 mesh_func = dynamic_cast<const SignedDistanceToSurfaceMesh *>(func);
156
157 mooseAssert(mesh_func, "Function was not a valid distance strategy");
158 return mesh_func->surfaceNormal(pt);
159 }
160}

Referenced by closestTrueNormalVector(), TEST_F(), ShortestDistanceToSurface::trueNormalByFunc(), and ShortestDistanceToSurface::trueNormalByIndex().

◆ unionSignedDistance()

Real SBMUtils::unionSignedDistance ( const std::vector< const Function * > &  funcs,
Real  t,
const Point &  p 
)

Computes the union signed distance by taking the minimum of all signed distance functions.

This definition is valid for overlapping geometries and preserves the correct union boundary.

Definition at line 207 of file SBMUtils.C.

208{
209 // Ensure all distance functions are valid signed distance strategies
210 for (const auto * func : funcs)
211 {
212 if (!dynamic_cast<const MooseParsedFunction *>(func) &&
213 !dynamic_cast<const SignedDistanceToSurfaceMesh *>(func))
214 mooseError("Signed distance requested but function was not a valid signed distance strategy. "
215 "Valid types are MooseParsedFunction or SignedDistanceToSurfaceMesh. "
216 "Offending function: ",
217 func->name());
218 }
219
220 mooseAssert(!funcs.empty(), "unionSignedDistance requires at least one function.");
221
222 // Union signed distance: min of all signed distances
223 Real min_value = funcs[0]->value(t, p);
224 for (const auto i : make_range(std::size_t(1), funcs.size()))
225 {
226 const Real val = funcs[i]->value(t, p);
227 if (val < min_value)
228 min_value = val;
229 }
230
231 return min_value;
232}

Referenced by TEST_F(), TEST_F(), and ShortestDistanceToSurface::value().