Line data Source code
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 "SBMUtils.h" 11 : #include "Function.h" 12 : #include "FunctionInterface.h" 13 : #include "MooseParsedFunction.h" 14 : #include "UnsignedDistanceToSurfaceMesh.h" 15 : 16 : #include <limits> 17 : 18 : namespace SBMUtils 19 : { 20 : 21 : bool 22 13 : checkWatertightnessFromRawElems(const std::vector<const Elem *> & bd_elements) 23 : { 24 41 : for (const auto * el : bd_elements) 25 96 : for (unsigned int s = 0; s < el->n_sides(); ++s) 26 68 : if (!el->neighbor_ptr(s)) 27 : return false; 28 : 29 : return true; 30 : } 31 : 32 : std::vector<const Function *> 33 53 : buildDistanceFunctions(const std::vector<FunctionName> & function_names, 34 : const FunctionInterface & function_provider) 35 : { 36 : std::vector<const Function *> funcs; 37 53 : funcs.reserve(function_names.size()); 38 : 39 134 : for (const auto & name : function_names) 40 : { 41 83 : const Function * func = &function_provider.getFunctionByName(name); 42 83 : if (!dynamic_cast<const MooseParsedFunction *>(func) && 43 53 : !dynamic_cast<const UnsignedDistanceToSurfaceMesh *>(func)) 44 : { 45 2 : mooseError("SBM distance helpers only support ParsedFunction or " 46 : "UnsignedDistanceToSurfaceMesh types. Offending function: ", 47 : name); 48 : } 49 81 : funcs.emplace_back(func); 50 : } 51 : 52 51 : return funcs; 53 0 : } 54 : 55 : RealVectorValue 56 3323436 : distanceVectorFromFunction(const Function * func, const libMesh::Point & pt, Real t) 57 : { 58 : mooseAssert(dynamic_cast<const MooseParsedFunction *>(func) || 59 : dynamic_cast<const UnsignedDistanceToSurfaceMesh *>(func), 60 : "Function was not a valid distance strategy, the only " 61 : "supported types are ParsedFunction and " 62 : "UnsignedDistanceToSurfaceMesh."); 63 : 64 3323436 : const Real phi = func->value(t, pt); 65 3323436 : const RealVectorValue grad_phi = func->gradient(t, pt); 66 3323436 : const Real grad_norm = grad_phi.norm(); 67 : 68 3323436 : if (grad_norm <= libMesh::TOLERANCE) 69 : return RealVectorValue(0.0, 0.0, 0.0); 70 : 71 3318220 : return -(phi / grad_norm) * grad_phi; 72 : } 73 : 74 : RealVectorValue 75 5484 : trueNormalFromFunction(const Function * func, const libMesh::Point & pt, Real t) 76 : { 77 5484 : if (const auto * parsed = dynamic_cast<const MooseParsedFunction *>(func)) 78 : { 79 3436 : const auto proj_pt = pt + distanceVectorFromFunction(func, pt, t); 80 3436 : const RealVectorValue grad_phi = parsed->gradient(t, proj_pt); 81 3436 : const Real grad_norm = grad_phi.norm(); 82 3436 : if (grad_norm <= libMesh::TOLERANCE) 83 : return RealVectorValue(0.0, 0.0, 0.0); 84 : return grad_phi / grad_norm; 85 : } 86 : else 87 : { 88 2048 : const auto * mesh_func = dynamic_cast<const UnsignedDistanceToSurfaceMesh *>(func); 89 : mooseAssert(mesh_func, "Function was not a valid distance strategy"); 90 2048 : return mesh_func->surfaceNormal(pt); 91 : } 92 : } 93 : 94 : RealVectorValue 95 1840448 : closestDistanceVector(const std::vector<const Function *> & funcs, 96 : const libMesh::Point & pt, 97 : Real t) 98 : { 99 : Real min_dist = std::numeric_limits<Real>::max(); 100 : RealVectorValue closest_dist_vec; 101 : 102 5154208 : for (const auto & func : funcs) 103 : { 104 3313760 : const auto dist_vec = distanceVectorFromFunction(func, pt, t); 105 3313760 : const auto dist = dist_vec.norm(); 106 3313760 : if (dist < min_dist) 107 : { 108 : min_dist = dist; 109 2317788 : closest_dist_vec = dist_vec; 110 : } 111 : } 112 : 113 1840448 : return closest_dist_vec; 114 : } 115 : 116 : RealVectorValue 117 1024 : closestTrueNormalVector(const std::vector<const Function *> & funcs, 118 : const libMesh::Point & pt, 119 : Real t) 120 : { 121 : Real min_dist = std::numeric_limits<Real>::max(); 122 : RealVectorValue closest_normal_vec; 123 : 124 4096 : for (const auto & func : funcs) 125 : { 126 3072 : const auto dist_vec = distanceVectorFromFunction(func, pt, t); 127 3072 : const auto dist = dist_vec.norm(); 128 3072 : if (dist < min_dist) 129 : { 130 : min_dist = dist; 131 2412 : closest_normal_vec = trueNormalFromFunction(func, pt, t); 132 : } 133 : } 134 : 135 1024 : return closest_normal_vec; 136 : } 137 : 138 : } // namespace SBMUtils