17#include "libmesh/fe.h"
18#include "libmesh/quadrature_gauss.h"
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);
38 Real active_measure = 0.0;
39 Real total_measure = 0.0;
40 for (
const auto i : index_range(q_points))
42 if (is_active(q_points[i]))
43 active_measure += JxW[i];
44 total_measure += JxW[i];
47 return active_measure / total_measure;
53 if (MooseUtils::absoluteFuzzyEqual(lambda, 0))
55 if (MooseUtils::absoluteFuzzyEqual(lambda, 1))
58 return MooseUtils::absoluteFuzzyGreaterThan(1.0 - active_fraction, lambda);
64 const bool mark_intercepted,
86 for (
const auto * el : bd_elements)
87 for (
unsigned int s = 0; s < el->n_sides(); ++s)
88 if (!el->neighbor_ptr(s))
94std::vector<const Function *>
98 std::vector<const Function *> funcs;
99 funcs.reserve(function_names.size());
101 for (
const auto &
name : function_names)
108 mooseError(
"SBM distance helpers only support ParsedFunction, "
109 "UnsignedDistanceToSurfaceMesh, or SignedDistanceToSurfaceMesh types. Offending "
113 funcs.emplace_back(func);
125 "Function was not a valid distance strategy, the only "
126 "supported types are ParsedFunction, UnsignedDistanceToSurfaceMesh, or "
127 "SignedDistanceToSurfaceMesh.");
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();
134 return RealVectorValue(0.0, 0.0, 0.0);
136 return -(phi / grad_norm) * grad_phi;
145 const RealVectorValue grad_phi = parsed->gradient(t, proj_pt);
146 const Real grad_norm = grad_phi.norm();
148 return RealVectorValue(0.0, 0.0, 0.0);
149 return grad_phi / grad_norm;
157 mooseAssert(mesh_func,
"Function was not a valid distance strategy");
158 return mesh_func->surfaceNormal(pt);
167 Real min_dist = std::numeric_limits<Real>::max();
168 RealVectorValue closest_dist_vec;
170 for (
const auto & func : funcs)
173 const auto dist = dist_vec.norm();
177 closest_dist_vec = dist_vec;
181 return closest_dist_vec;
189 Real min_dist = std::numeric_limits<Real>::max();
190 RealVectorValue closest_normal_vec;
192 for (
const auto & func : funcs)
195 const auto dist = dist_vec.norm();
203 return closest_normal_vec;
210 for (
const auto * func : funcs)
214 mooseError(
"Signed distance requested but function was not a valid signed distance strategy. "
215 "Valid types are MooseParsedFunction or SignedDistanceToSurfaceMesh. "
216 "Offending function: ",
220 mooseAssert(!funcs.empty(),
"unionSignedDistance requires at least one function.");
223 Real min_value = funcs[0]->value(t,
p);
224 for (
const auto i : make_range(std::size_t(1), funcs.size()))
226 const Real val = funcs[i]->value(t,
p);
subdomain_id_type SubdomainID
void mooseError(Args &&... args)
const Function & getFunctionByName(const FunctionName &name) const
virtual RealGradient gradient(Real t, const Point &p) const
virtual Real value(Real t, const Point &p) 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...
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.
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.
RealVectorValue closestTrueNormalVector(const std::vector< const Function * > &funcs, const libMesh::Point &pt, Real t)
Scan all distance functions and return the corresponding normal vector.
bool checkWatertightnessFromRawElems(const std::vector< const Elem * > &bd_elements)
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.
static constexpr Real TOLERANCE
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
The subdomain IDs a (possibly partial) element can be labeled with.
Measured activity state of a (possibly partial) element, used to classify it.
bool all_nodes_active
Whether all of the element's nodes are on the active (retained) side.
bool all_nodes_inactive
Whether all of the element's nodes are on the inactive (removed) side.
Real active_fraction
Fraction of the element's quadrature-weighted measure that is active, in [0, 1].