https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Functions
FillBetweenPointVectorsTools Namespace Reference

Functions

void fillBetweenPointVectorsGenerator (MeshBase &mesh, const std::vector< Point > &boundary_points_vec_1, const std::vector< Point > &boundary_points_vec_2, const unsigned int num_layers, const subdomain_id_type transition_layer_id, const boundary_id_type input_boundary_1_id, const boundary_id_type input_boundary_2_id, const boundary_id_type begin_side_boundary_id, const boundary_id_type end_side_boundary_id, const std::string type, const std::string name, const bool quad_elem=false, const Real bias_parameter=1.0, const Real sigma=3.0)
 Generates a 2D mesh with triangular elements for a region defined by two curves (sets of Points)
 
void fillBetweenPointVectorsGenerator (MeshBase &mesh, const std::vector< Point > &boundary_points_vec_1, const std::vector< Point > &boundary_points_vec_2, const unsigned int num_layers, const subdomain_id_type transition_layer_id, const boundary_id_type external_boundary_id, const std::string type, const std::string name, const bool quad_elem=false)
 Generates a 2D mesh with triangular elements for a region defined by two curves (sets of Points)
 
void elementsCreationFromNodesVectorsQuad (MeshBase &mesh, const std::vector< std::vector< Node * > > &nodes, const unsigned int num_layers, const std::vector< unsigned int > &node_number_vec, const subdomain_id_type transition_layer_id, const boundary_id_type input_boundary_1_id, const boundary_id_type input_boundary_2_id, const boundary_id_type begin_side_boundary_id, const boundary_id_type end_side_boundary_id)
 Generates a 2D mesh based on a 2D vector of Nodes using QUAD4 elements in the xy-plane.
 
void elementsCreationFromNodesVectors (MeshBase &mesh, const std::vector< std::vector< Node * > > &nodes, const unsigned int num_layers, const std::vector< unsigned int > &node_number_vec, const subdomain_id_type transition_layer_id, const boundary_id_type input_boundary_1_id, const boundary_id_type input_boundary_2_id, const boundary_id_type begin_side_boundary_id, const boundary_id_type end_side_boundary_id)
 Generates a 2D mesh based on a 2D vector of Nodes using TRI3 elements in the xy-plane.
 
void weightedInterpolator (const unsigned int vec_node_num, const std::vector< Point > &boundary_points_vec, std::vector< Real > &vec_index, std::vector< Real > &wt, std::vector< Real > &index, const Real sigma, std::unique_ptr< LinearInterpolation > &linear_vec_x, std::unique_ptr< LinearInterpolation > &linear_vec_y, std::unique_ptr< SplineInterpolation > &spline_vec_l)
 Generates weights, weighted indices and corresponding interpolation.
 
void surrogateGenerator (std::vector< Real > &weighted_surrogate_index, std::vector< Real > &unweighted_surrogate_index, const std::vector< unsigned int > &node_number_vec, const std::vector< Real > &index, const std::vector< Real > &wt, const unsigned int boundary_node_num, const unsigned int i)
 Generates weighted surrogate index vectors on one side for points of a sublayer curve.
 
bool needFlip (const std::vector< Point > &vec_pts_1, const std::vector< Point > &vec_pts_2)
 Decide whether one of the input vector of Points needs to be flipped to ensure correct transition layer shape.
 
bool isBoundarySimpleClosedLoop (MeshBase &mesh, Real &max_node_radius, std::vector< dof_id_type > &boundary_ordered_node_list, const Point origin_pt, const boundary_id_type bid)
 Decides whether a boundary of a given mesh is a closed loop with consecutive nodes's azimuthal angles change monotonically.
 
bool isBoundarySimpleClosedLoop (MeshBase &mesh, Real &max_node_radius, const Point origin_pt, const boundary_id_type bid)
 Decides whether a boundary of a given mesh is a closed loop with consecutive nodes's azimuthal angles change monotonically.
 
bool isBoundarySimpleClosedLoop (MeshBase &mesh, const Point origin_pt, const boundary_id_type bid)
 Decides whether a boundary of a given mesh is a closed loop with consecutive nodes's azimuthal angles change monotonically.
 
bool isBoundaryOpenSingleSegment (MeshBase &mesh, Real &max_node_radius, std::vector< dof_id_type > &boundary_ordered_node_list, const Point origin_pt, const boundary_id_type bid)
 Decides whether a boundary of a given mesh is an open single-segment boundary.
 
bool isCurveSimpleClosedLoop (MeshBase &mesh, Real &max_node_radius, std::vector< dof_id_type > &ordered_node_list, const Point origin_pt)
 Decides whether a curve contained in a given mesh is a closed loop with consecutive nodes's azimuthal angles change monotonically.
 
bool isCurveSimpleClosedLoop (MeshBase &mesh, Real &max_node_radius, const Point origin_pt)
 Decides whether a curve contained in a given mesh is a closed loop with consecutive nodes's azimuthal angles change monotonically.
 
bool isCurveSimpleClosedLoop (MeshBase &mesh, const Point origin_pt)
 Decides whether a curve contained in a given mesh is a closed loop with consecutive nodes's azimuthal angles change monotonically.
 
bool isCurveOpenSingleSegment (MeshBase &mesh, Real &max_node_radius, std::vector< dof_id_type > &ordered_node_list, const Point origin_pt)
 Decides whether a curve contained in a given mesh is an open single-segment curve.
 
void isClosedLoop (MeshBase &mesh, Real &max_node_radius, std::vector< dof_id_type > &ordered_node_list, std::vector< std::pair< dof_id_type, dof_id_type > > &node_assm, std::vector< dof_id_type > &midpoint_node_list, const Point origin_pt, const std::string input_type, bool &is_closed_loop, const bool suppress_exception=false)
 Decides whether a series of nodes contained in a given mesh forms a closed loop with consecutive nodes's azimuthal angles change monotonically.
 
void isClosedLoop (MeshBase &mesh, Real &max_node_radius, std::vector< dof_id_type > &ordered_node_list, std::vector< std::pair< dof_id_type, dof_id_type > > &node_assm, const Point origin_pt, const std::string input_type, bool &is_closed_loop, const bool suppress_exception=false)
 Decides whether a series of nodes contained in a given mesh forms a closed loop with consecutive nodes's azimuthal angles change monotonically.
 
bool isExternalBoundary (MeshBase &mesh, const boundary_id_type bid)
 Decides whether a boundary of a given mesh is an external boundary.
 
bool buildQuadElement (Elem *elem, Node *nd_0, Node *nd_1, Node *nd_2, Node *nd_3, const subdomain_id_type transition_layer_id)
 Creates an QUAD4 element that can be extruded in (0 0 1) direction.
 
bool buildTriElement (Elem *elem, Node *nd_0, Node *nd_1, Node *nd_2, const subdomain_id_type transition_layer_id)
 Creates an TRI3 element that can be extruded in (0 0 1) direction.
 
void fillBetweenPointVectorsGenerator (MeshBase &mesh, const std::vector< Point > &boundary_points_vec_1, const std::vector< Point > &boundary_points_vec_2, const unsigned int num_layers, const subdomain_id_type transition_layer_id, const boundary_id_type input_boundary_1_id, const boundary_id_type input_boundary_2_id, const boundary_id_type begin_side_boundary_id, const boundary_id_type end_side_boundary_id, const std::string type, const std::string name, const bool quad_elem, const Real bias_parameter, const Real sigma)
 
void fillBetweenPointVectorsGenerator (MeshBase &mesh, const std::vector< Point > &boundary_points_vec_1, const std::vector< Point > &boundary_points_vec_2, const unsigned int num_layers, const subdomain_id_type transition_layer_id, const boundary_id_type external_boundary_id, const std::string type, const std::string name, const bool quad_elem)
 
void elementsCreationFromNodesVectorsQuad (MeshBase &mesh, const std::vector< std::vector< Node * > > &nodes, const unsigned int num_layers, const std::vector< unsigned int > &node_number_vec, const subdomain_id_type transition_layer_id, const boundary_id_type input_boundary_1_id, const boundary_id_type input_boundary_2_id, const boundary_id_type begin_side_boundary_id, const boundary_id_type end_side_boundary_id)
 
void elementsCreationFromNodesVectors (MeshBase &mesh, const std::vector< std::vector< Node * > > &nodes, const unsigned int num_layers, const std::vector< unsigned int > &node_number_vec, const subdomain_id_type transition_layer_id, const boundary_id_type input_boundary_1_id, const boundary_id_type input_boundary_2_id, const boundary_id_type begin_side_boundary_id, const boundary_id_type end_side_boundary_id)
 
void weightedInterpolator (const unsigned int vec_node_num, const std::vector< Point > &boundary_points_vec, std::vector< Real > &vec_index, std::vector< Real > &wt, std::vector< Real > &index, const Real sigma, std::unique_ptr< LinearInterpolation > &linear_vec_x, std::unique_ptr< LinearInterpolation > &linear_vec_y, std::unique_ptr< SplineInterpolation > &spline_vec_l)
 
bool needFlip (const std::vector< Point > &vec_pts_1, const std::vector< Point > &vec_pts_2)
 
bool isBoundarySimpleClosedLoop (MeshBase &mesh, Real &max_node_radius, std::vector< dof_id_type > &boundary_ordered_node_list, const Point origin_pt, const boundary_id_type bid)
 
bool isBoundarySimpleClosedLoop (MeshBase &mesh, Real &max_node_radius, const Point origin_pt, const boundary_id_type bid)
 
bool isBoundarySimpleClosedLoop (MeshBase &mesh, const Point origin_pt, const boundary_id_type bid)
 
bool isBoundaryOpenSingleSegment (MeshBase &mesh, Real &max_node_radius, std::vector< dof_id_type > &boundary_ordered_node_list, const Point origin_pt, const boundary_id_type bid)
 
bool isExternalBoundary (MeshBase &mesh, const boundary_id_type bid)
 
bool isCurveSimpleClosedLoop (MeshBase &mesh, Real &max_node_radius, std::vector< dof_id_type > &ordered_node_list, const Point origin_pt)
 
bool isCurveSimpleClosedLoop (MeshBase &mesh, Real &max_node_radius, const Point origin_pt)
 
bool isCurveSimpleClosedLoop (MeshBase &mesh, const Point origin_pt)
 
bool isCurveOpenSingleSegment (MeshBase &mesh, Real &max_node_radius, std::vector< dof_id_type > &ordered_node_list, const Point origin_pt)
 
void isClosedLoop (MeshBase &mesh, Real &max_node_radius, std::vector< dof_id_type > &ordered_node_list, std::vector< std::pair< dof_id_type, dof_id_type > > &node_assm, std::vector< dof_id_type > &midpoint_node_list, const Point origin_pt, const std::string input_type, bool &is_closed_loop, const bool suppress_exception)
 
void isClosedLoop (MeshBase &mesh, Real &max_node_radius, std::vector< dof_id_type > &ordered_node_list, std::vector< std::pair< dof_id_type, dof_id_type > > &node_assm, const Point origin_pt, const std::string input_type, bool &is_closed_loop, const bool suppress_exception)
 
bool buildQuadElement (Elem *elem, Node *nd_0, Node *nd_1, Node *nd_2, Node *nd_3, const subdomain_id_type transition_layer_id)
 
bool buildTriElement (Elem *elem, Node *nd_0, Node *nd_1, Node *nd_2, const subdomain_id_type transition_layer_id)
 

Function Documentation

◆ buildQuadElement() [1/2]

bool FillBetweenPointVectorsTools::buildQuadElement ( Elem *  elem,
Node *  nd_0,
Node *  nd_1,
Node *  nd_2,
Node *  nd_3,
const subdomain_id_type  transition_layer_id 
)

Creates an QUAD4 element that can be extruded in (0 0 1) direction.

Parameters
elempointer of the element to be created
nd_0pointer of element's first node
nd_1pointer of element's second node
nd_2pointer of element's third node
nd_3pointer of element's fourth node
transition_layer_idid of the subdomain that this element belongs to
Returns
whether the element is flipped to ensure (0 0 1) extrudability

Referenced by elementsCreationFromNodesVectorsQuad().

◆ buildQuadElement() [2/2]

bool FillBetweenPointVectorsTools::buildQuadElement ( Elem elem,
Node nd_0,
Node nd_1,
Node nd_2,
Node nd_3,
const subdomain_id_type  transition_layer_id 
)

Definition at line 750 of file FillBetweenPointVectorsTools.C.

756{
757 // Adjust the order of nodes in an element so that the mesh can be extruded in (0 0 1)
758 // direction.
759 elem->subdomain_id() = transition_layer_id;
760 if (((*nd_1 - *nd_0).cross((*nd_2 - *nd_0)).unit())(2) > 0)
761 {
762 elem->set_node(0, nd_0);
763 elem->set_node(1, nd_1);
764 elem->set_node(2, nd_2);
765 elem->set_node(3, nd_3);
766 return false;
767 }
768 else
769 {
770 elem->set_node(0, nd_0);
771 elem->set_node(3, nd_1);
772 elem->set_node(2, nd_2);
773 elem->set_node(1, nd_3);
774 return true;
775 }
776}
virtual Node *& set_node(const unsigned int i)
subdomain_id_type subdomain_id() const

◆ buildTriElement() [1/2]

bool FillBetweenPointVectorsTools::buildTriElement ( Elem *  elem,
Node *  nd_0,
Node *  nd_1,
Node *  nd_2,
const subdomain_id_type  transition_layer_id 
)

Creates an TRI3 element that can be extruded in (0 0 1) direction.

Parameters
elempointer of the element to be created
nd_0pointer of element's first node
nd_1pointer of element's second node
nd_2pointer of element's third node
transition_layer_idid of the subdomain that this element belongs to
Returns
whether the element is flipped to ensure (0 0 1) extrudability

Referenced by elementsCreationFromNodesVectors().

◆ buildTriElement() [2/2]

bool FillBetweenPointVectorsTools::buildTriElement ( Elem elem,
Node nd_0,
Node nd_1,
Node nd_2,
const subdomain_id_type  transition_layer_id 
)

Definition at line 779 of file FillBetweenPointVectorsTools.C.

781{
782 // Adjust the order of nodes in an element so that the mesh can be extruded in (0 0 1)
783 // direction.
784 elem->subdomain_id() = transition_layer_id;
785 if (((*nd_1 - *nd_0).cross((*nd_2 - *nd_0)).unit())(2) > 0)
786 {
787 elem->set_node(0, nd_0);
788 elem->set_node(1, nd_1);
789 elem->set_node(2, nd_2);
790 return false;
791 }
792 else
793 {
794 elem->set_node(0, nd_0);
795 elem->set_node(2, nd_1);
796 elem->set_node(1, nd_2);
797 return true;
798 }
799}

◆ elementsCreationFromNodesVectors() [1/2]

void FillBetweenPointVectorsTools::elementsCreationFromNodesVectors ( MeshBase &  mesh,
const std::vector< std::vector< Node * > > &  nodes,
const unsigned int  num_layers,
const std::vector< unsigned int > &  node_number_vec,
const subdomain_id_type  transition_layer_id,
const boundary_id_type  input_boundary_1_id,
const boundary_id_type  input_boundary_2_id,
const boundary_id_type  begin_side_boundary_id,
const boundary_id_type  end_side_boundary_id 
)

Generates a 2D mesh based on a 2D vector of Nodes using TRI3 elements in the xy-plane.

Parameters
mesha reference MeshBase to contain the generated mesh
nodesa 2D vector of nodes based on which the mesh is built
num_layersnumber of sublayers of elements
node_number_vecnumber of nodes on each sublayer
transition_layer_idsubdomain id of the generated mesh
input_boundary_1_idid of the generated mesh's external boundary that originates from boundary_points_vec_1
input_boundary_2_idid of the generated mesh's external boundary that originates from boundary_points_vec_2
begin_side_boundary_idid of the generated mesh's external boundary that connects the first Points of the two input Point vectors
end_side_boundary_idid of the generated mesh's external boundary that connects the last Points of the two input Point vectors

Referenced by fillBetweenPointVectorsGenerator().

◆ elementsCreationFromNodesVectors() [2/2]

void FillBetweenPointVectorsTools::elementsCreationFromNodesVectors ( MeshBase mesh,
const std::vector< std::vector< Node * > > &  nodes,
const unsigned int  num_layers,
const std::vector< unsigned int > &  node_number_vec,
const subdomain_id_type  transition_layer_id,
const boundary_id_type  input_boundary_1_id,
const boundary_id_type  input_boundary_2_id,
const boundary_id_type  begin_side_boundary_id,
const boundary_id_type  end_side_boundary_id 
)

Definition at line 287 of file FillBetweenPointVectorsTools.C.

296{
297 BoundaryInfo & boundary_info = mesh.get_boundary_info();
298
299 for (const auto i : make_range(num_layers))
300 {
301 unsigned int nodes_up_it = 0;
302 unsigned int nodes_down_it = 0;
303 const unsigned int node_number_up = node_number_vec[i + 1];
304 const unsigned int node_number_down = node_number_vec[i];
305
306 while (nodes_up_it < node_number_up - 1 && nodes_down_it < node_number_down - 1 &&
307 nodes_up_it + nodes_down_it < node_number_up + node_number_down - 3)
308 {
309 // Define the two possible options and chose the one with shorter distance
310 Real dis1 = (*nodes[i + 1][nodes_up_it] - *nodes[i][nodes_down_it + 1]).norm();
311 Real dis2 = (*nodes[i + 1][nodes_up_it + 1] - *nodes[i][nodes_down_it]).norm();
312 if (MooseUtils::absoluteFuzzyGreaterThan(dis1, dis2))
313 {
314 Elem * elem = mesh.add_elem(new Tri3);
315 bool is_elem_flip = buildTriElement(elem,
316 nodes[i + 1][nodes_up_it],
317 nodes[i][nodes_down_it],
318 nodes[i + 1][nodes_up_it + 1],
319 transition_layer_id);
320 if (i == num_layers - 1)
321 boundary_info.add_side(elem, is_elem_flip ? 0 : 2, input_boundary_2_id);
322 if (nodes_up_it == 0 && nodes_down_it == 0)
323 boundary_info.add_side(elem, is_elem_flip ? 2 : 0, begin_side_boundary_id);
324 nodes_up_it++;
325 }
326 else
327 {
328 Elem * elem = mesh.add_elem(new Tri3);
329 bool is_elem_flip = buildTriElement(elem,
330 nodes[i + 1][nodes_up_it],
331 nodes[i][nodes_down_it],
332 nodes[i][nodes_down_it + 1],
333 transition_layer_id);
334 if (i == 0)
335 boundary_info.add_side(elem, 1, input_boundary_1_id);
336 if (nodes_up_it == 0 && nodes_down_it == 0)
337 boundary_info.add_side(elem, is_elem_flip ? 2 : 0, begin_side_boundary_id);
338 nodes_down_it++;
339 }
340 }
341 // Handle the end
342 while (nodes_up_it < node_number_up - 1)
343 {
344 Elem * elem = mesh.add_elem(new Tri3);
345 bool is_elem_flip = buildTriElement(elem,
346 nodes[i + 1][nodes_up_it],
347 nodes[i][nodes_down_it],
348 nodes[i + 1][nodes_up_it + 1],
349 transition_layer_id);
350 nodes_up_it++;
351 if (i == num_layers - 1)
352 boundary_info.add_side(elem, is_elem_flip ? 0 : 2, input_boundary_2_id);
353 if (nodes_up_it == node_number_up - 1 && nodes_down_it == node_number_down - 1)
354 boundary_info.add_side(elem, 1, end_side_boundary_id);
355 }
356 while (nodes_down_it < node_number_down - 1)
357 {
358 Elem * elem = mesh.add_elem(new Tri3);
359 bool is_elem_flip = buildTriElement(elem,
360 nodes[i + 1][nodes_up_it],
361 nodes[i][nodes_down_it],
362 nodes[i][nodes_down_it + 1],
363 transition_layer_id);
364 nodes_down_it++;
365 if (i == 0)
366 boundary_info.add_side(elem, 1, input_boundary_1_id);
367 if (nodes_up_it == node_number_up - 1 && nodes_down_it == node_number_down - 1)
368 boundary_info.add_side(elem, is_elem_flip ? 0 : 2, end_side_boundary_id);
369 }
370 }
371}
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
const BoundaryInfo & get_boundary_info() const
virtual Elem * add_elem(Elem *e)=0
MeshBase & mesh
bool buildTriElement(Elem *elem, Node *nd_0, Node *nd_1, Node *nd_2, const subdomain_id_type transition_layer_id)
Creates an TRI3 element that can be extruded in (0 0 1) direction.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)

◆ elementsCreationFromNodesVectorsQuad() [1/2]

void FillBetweenPointVectorsTools::elementsCreationFromNodesVectorsQuad ( MeshBase &  mesh,
const std::vector< std::vector< Node * > > &  nodes,
const unsigned int  num_layers,
const std::vector< unsigned int > &  node_number_vec,
const subdomain_id_type  transition_layer_id,
const boundary_id_type  input_boundary_1_id,
const boundary_id_type  input_boundary_2_id,
const boundary_id_type  begin_side_boundary_id,
const boundary_id_type  end_side_boundary_id 
)

Generates a 2D mesh based on a 2D vector of Nodes using QUAD4 elements in the xy-plane.

Parameters
mesha reference MeshBase to contain the generated mesh
nodesa 2D vector of nodes based on which the mesh is built
num_layersnumber of sublayers of elements
node_number_vecnumber of nodes on each sublayer
transition_layer_idsubdomain id of the generated mesh
input_boundary_1_idid of the generated mesh's external boundary that originates from boundary_points_vec_1
input_boundary_2_idid of the generated mesh's external boundary that originates from boundary_points_vec_2
begin_side_boundary_idid of the generated mesh's external boundary that connects the first Points of the two input Point vectors
end_side_boundary_idid of the generated mesh's external boundary that connects the last Points of the two input Point vectors

Referenced by fillBetweenPointVectorsGenerator().

◆ elementsCreationFromNodesVectorsQuad() [2/2]

void FillBetweenPointVectorsTools::elementsCreationFromNodesVectorsQuad ( MeshBase mesh,
const std::vector< std::vector< Node * > > &  nodes,
const unsigned int  num_layers,
const std::vector< unsigned int > &  node_number_vec,
const subdomain_id_type  transition_layer_id,
const boundary_id_type  input_boundary_1_id,
const boundary_id_type  input_boundary_2_id,
const boundary_id_type  begin_side_boundary_id,
const boundary_id_type  end_side_boundary_id 
)

Definition at line 252 of file FillBetweenPointVectorsTools.C.

261{
262 const unsigned int node_number = node_number_vec.front();
263 BoundaryInfo & boundary_info = mesh.get_boundary_info();
264
265 for (const auto i : make_range(num_layers))
266 for (unsigned int j = 1; j < node_number; j++)
267 {
268 Elem * elem = mesh.add_elem(new Quad4);
269 bool is_elem_flip = buildQuadElement(elem,
270 nodes[i][j - 1],
271 nodes[i + 1][j - 1],
272 nodes[i + 1][j],
273 nodes[i][j],
274 transition_layer_id);
275 if (i == 0)
276 boundary_info.add_side(elem, is_elem_flip ? 0 : 3, input_boundary_1_id);
277 if (i == num_layers - 1)
278 boundary_info.add_side(elem, is_elem_flip ? 2 : 1, input_boundary_2_id);
279 if (j == 1)
280 boundary_info.add_side(elem, is_elem_flip ? 3 : 0, begin_side_boundary_id);
281 if (j == node_number - 1)
282 boundary_info.add_side(elem, is_elem_flip ? 1 : 2, end_side_boundary_id);
283 }
284}
for(PetscInt i=0;i< nvars;++i)
void ErrorVector unsigned int
bool buildQuadElement(Elem *elem, Node *nd_0, Node *nd_1, Node *nd_2, Node *nd_3, const subdomain_id_type transition_layer_id)
Creates an QUAD4 element that can be extruded in (0 0 1) direction.

◆ fillBetweenPointVectorsGenerator() [1/4]

void FillBetweenPointVectorsTools::fillBetweenPointVectorsGenerator ( MeshBase mesh,
const std::vector< Point > &  boundary_points_vec_1,
const std::vector< Point > &  boundary_points_vec_2,
const unsigned int  num_layers,
const subdomain_id_type  transition_layer_id,
const boundary_id_type  external_boundary_id,
const std::string  type,
const std::string  name,
const bool  quad_elem 
)

Definition at line 227 of file FillBetweenPointVectorsTools.C.

236{
238 boundary_points_vec_1,
239 boundary_points_vec_2,
240 num_layers,
241 transition_layer_id,
242 external_boundary_id,
243 external_boundary_id,
244 external_boundary_id,
245 external_boundary_id,
246 type,
247 name,
248 quad_elem);
249}
void fillBetweenPointVectorsGenerator(MeshBase &mesh, const std::vector< Point > &boundary_points_vec_1, const std::vector< Point > &boundary_points_vec_2, const unsigned int num_layers, const subdomain_id_type transition_layer_id, const boundary_id_type input_boundary_1_id, const boundary_id_type input_boundary_2_id, const boundary_id_type begin_side_boundary_id, const boundary_id_type end_side_boundary_id, const std::string type, const std::string name, const bool quad_elem=false, const Real bias_parameter=1.0, const Real sigma=3.0)
Generates a 2D mesh with triangular elements for a region defined by two curves (sets of Points)

◆ fillBetweenPointVectorsGenerator() [2/4]

void FillBetweenPointVectorsTools::fillBetweenPointVectorsGenerator ( MeshBase &  mesh,
const std::vector< Point > &  boundary_points_vec_1,
const std::vector< Point > &  boundary_points_vec_2,
const unsigned int  num_layers,
const subdomain_id_type  transition_layer_id,
const boundary_id_type  external_boundary_id,
const std::string  type,
const std::string  name,
const bool  quad_elem = false 
)

Generates a 2D mesh with triangular elements for a region defined by two curves (sets of Points)

Parameters
mesha reference MeshBase to contain the generated mesh
boundary_points_vec_1vector of Points of Side #1
boundary_points_vec_2vector of Points of Side #2
num_layersnumber of sublayers of elements
transition_layer_idsubdomain id of the generated mesh
external_boundary_idid of the generated mesh's external boundary
typetype of the MOOSE object that calls this method
namename of the MOOSE object that calls this method
quad_elemwhether the QUAD4 elements are used to construct the mesh

◆ fillBetweenPointVectorsGenerator() [3/4]

void FillBetweenPointVectorsTools::fillBetweenPointVectorsGenerator ( MeshBase mesh,
const std::vector< Point > &  boundary_points_vec_1,
const std::vector< Point > &  boundary_points_vec_2,
const unsigned int  num_layers,
const subdomain_id_type  transition_layer_id,
const boundary_id_type  input_boundary_1_id,
const boundary_id_type  input_boundary_2_id,
const boundary_id_type  begin_side_boundary_id,
const boundary_id_type  end_side_boundary_id,
const std::string  type,
const std::string  name,
const bool  quad_elem,
const Real  bias_parameter,
const Real  sigma 
)

Definition at line 32 of file FillBetweenPointVectorsTools.C.

46{
48 boundary_points_vec_1, Point(0.0, 0.0, 1.0), Point(0.0, 0.0, 0.0)) ||
50 boundary_points_vec_2, Point(0.0, 0.0, 1.0), Point(0.0, 0.0, 0.0)))
51 mooseError("In ",
52 type,
53 " ",
54 name,
55 ", the input vectors of points for "
56 "FillBetweenPointVectorsTools::fillBetweenPointVectorsGenerator "
57 "must be in XY plane.");
58
59 const unsigned int vec_1_node_num = boundary_points_vec_1.size();
60 const unsigned int vec_2_node_num = boundary_points_vec_2.size();
61
62 if (vec_1_node_num < 2 || vec_2_node_num < 2)
63 mooseError("In ",
64 type,
65 " ",
66 name,
67 ", the two input vectors of points for "
68 "FillBetweenPointVectorsTools::fillBetweenPointVectorsGenerator "
69 "must respectively contain at least two elements.");
70
71 if (quad_elem && boundary_points_vec_1.size() != boundary_points_vec_2.size())
72 mooseError("In ",
73 type,
74 " ",
75 name,
76 ", QUAD4 elements option can only be selected when the two input vectors of Points "
77 "have the same length. In the current instance, the first vector has ",
78 boundary_points_vec_1.size(),
79 " points and the second ",
80 boundary_points_vec_2.size(),
81 " points");
82
83 std::vector<Point> possibly_reoriented_boundary_points_vec_2;
84 const std::vector<Point> * oriented_boundary_points_vec_2 = &boundary_points_vec_2;
85
86 if (needFlip(boundary_points_vec_1, boundary_points_vec_2))
87 {
88 possibly_reoriented_boundary_points_vec_2.assign(boundary_points_vec_2.rbegin(),
89 boundary_points_vec_2.rend());
90 oriented_boundary_points_vec_2 = &possibly_reoriented_boundary_points_vec_2;
91
92 // This isn't worth warning about. The way
93 // MooseMeshUtils::makeOrderedNodeList works, we can end up
94 // finding a flip necessary on one element numbering and
95 // unnecessary on another.
96 //
97 // mooseWarning(
98 // "In FillBetweenPointVectorsTools, one of the vector of Points must be flipped to ensure "
99 // "correct transition layer shape.");
100 }
101
102 std::vector<Real> vec_1_index; // Unweighted index
103 std::vector<Real> vec_2_index; // Unweighted index
104
105 std::vector<Real> wt_1;
106 std::vector<Real> index_1; // Weighted index
107 std::vector<Real> wt_2;
108 std::vector<Real> index_2; // Weighted index
109
110 // create interpolations
111 std::unique_ptr<LinearInterpolation> linear_vec_1_x;
112 std::unique_ptr<LinearInterpolation> linear_vec_1_y;
113 std::unique_ptr<SplineInterpolation> spline_vec_1_l;
114 std::unique_ptr<LinearInterpolation> linear_vec_2_x;
115 std::unique_ptr<LinearInterpolation> linear_vec_2_y;
116 std::unique_ptr<SplineInterpolation> spline_vec_2_l;
117
118 weightedInterpolator(vec_1_node_num,
119 boundary_points_vec_1,
120 vec_1_index,
121 wt_1,
122 index_1,
123 sigma,
124 linear_vec_1_x,
125 linear_vec_1_y,
126 spline_vec_1_l);
127 weightedInterpolator(vec_2_node_num,
128 *oriented_boundary_points_vec_2,
129 vec_2_index,
130 wt_2,
131 index_2,
132 sigma,
133 linear_vec_2_x,
134 linear_vec_2_y,
135 spline_vec_2_l);
136
137 // If the two input vectors have different sizes
138 // The node numbers of the intermediate layers change linearly
139 const Real increment = ((Real)vec_2_node_num - (Real)vec_1_node_num) / (Real)(num_layers);
140 // Number of nodes in each sublayer
141 std::vector<unsigned int> node_number_vec;
142 // 2D vector of nodes
143 std::vector<std::vector<Node *>> nodes(num_layers + 1);
144 // Node counter
145 unsigned int node_counter = 0;
146
147 for (const auto i : make_range(num_layers + 1))
148 {
149 // calculate number of nodes in each sublayer
150 node_number_vec.push_back(
151 (unsigned int)(vec_1_node_num + (long)(increment * i + 0.5 - (increment < 0))));
152 // Reserve memory for new nodes
153 nodes[i] = std::vector<Node *>(node_number_vec[i]);
154
155 // Calculate vectors of weighted surrogated index for side #1
156 std::vector<Real> weighted_surrogate_index_1;
157 std::vector<Real> unweighted_surrogate_index_1;
158
159 surrogateGenerator(weighted_surrogate_index_1,
160 unweighted_surrogate_index_1,
161 node_number_vec,
162 wt_1,
163 vec_1_index,
164 vec_1_node_num,
165 i);
166
167 // Calculate vectors of weighted surrogated index for side #2
168 std::vector<Real> weighted_surrogate_index_2;
169 std::vector<Real> unweighted_surrogate_index_2;
170
171 surrogateGenerator(weighted_surrogate_index_2,
172 unweighted_surrogate_index_2,
173 node_number_vec,
174 wt_2,
175 vec_2_index,
176 vec_2_node_num,
177 i);
178
179 for (const auto j : make_range(node_number_vec[i]))
180 {
181 // Create surrogate Points on side #1 for Point #j on the sublayer
182 Point surrogate_pos_1 = Point(linear_vec_1_x->sample(weighted_surrogate_index_1[j]),
183 linear_vec_1_y->sample(weighted_surrogate_index_1[j]),
184 0.0);
185 // Create surrogate Points on side #2 for Point #j on the sublayer
186 Point surrogate_pos_2 = Point(linear_vec_2_x->sample(weighted_surrogate_index_2[j]),
187 linear_vec_2_y->sample(weighted_surrogate_index_2[j]),
188 0.0);
189 const Real l_ratio = bias_parameter <= 0.0
190 ? std::pow(spline_vec_2_l->sample(weighted_surrogate_index_2[j]) /
191 spline_vec_1_l->sample(weighted_surrogate_index_1[j]),
192 1.0 / ((Real)num_layers - 1.0))
193 : bias_parameter;
194 const Real index_factor =
195 MooseUtils::absoluteFuzzyEqual(l_ratio, 1.0)
196 ? (Real)i / (Real)num_layers
197 : (1.0 - std::pow(l_ratio, (Real)i)) / (1.0 - std::pow(l_ratio, (Real)num_layers));
198 Point tmp_point = surrogate_pos_2 * index_factor + surrogate_pos_1 * (1.0 - index_factor);
199 nodes[i][j] = mesh.add_point(tmp_point, j + node_counter);
200 }
201 node_counter += node_number_vec[i];
202 }
203 // Create triangular elements based on the 2D Node vector
204 if (quad_elem)
206 nodes,
207 num_layers,
208 node_number_vec,
209 transition_layer_id,
210 input_boundary_1_id,
211 input_boundary_2_id,
212 begin_side_boundary_id,
213 end_side_boundary_id);
214 else
216 nodes,
217 num_layers,
218 node_number_vec,
219 transition_layer_id,
220 input_boundary_1_id,
221 input_boundary_2_id,
222 begin_side_boundary_id,
223 end_side_boundary_id);
224}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
void elementsCreationFromNodesVectorsQuad(MeshBase &mesh, const std::vector< std::vector< Node * > > &nodes, const unsigned int num_layers, const std::vector< unsigned int > &node_number_vec, const subdomain_id_type transition_layer_id, const boundary_id_type input_boundary_1_id, const boundary_id_type input_boundary_2_id, const boundary_id_type begin_side_boundary_id, const boundary_id_type end_side_boundary_id)
Generates a 2D mesh based on a 2D vector of Nodes using QUAD4 elements in the xy-plane.
void elementsCreationFromNodesVectors(MeshBase &mesh, const std::vector< std::vector< Node * > > &nodes, const unsigned int num_layers, const std::vector< unsigned int > &node_number_vec, const subdomain_id_type transition_layer_id, const boundary_id_type input_boundary_1_id, const boundary_id_type input_boundary_2_id, const boundary_id_type begin_side_boundary_id, const boundary_id_type end_side_boundary_id)
Generates a 2D mesh based on a 2D vector of Nodes using TRI3 elements in the xy-plane.
bool needFlip(const std::vector< Point > &vec_pts_1, const std::vector< Point > &vec_pts_2)
Decide whether one of the input vector of Points needs to be flipped to ensure correct transition lay...
bool isCoPlanar(const std::vector< Point > &vec_pts, const Point plane_nvec, const Point fixed_pt)
Decides whether all the Points of a vector of Points are in a plane that is defined by a normal vecto...
MooseUnits pow(const MooseUnits &, int)
Definition Units.C:537

◆ fillBetweenPointVectorsGenerator() [4/4]

void FillBetweenPointVectorsTools::fillBetweenPointVectorsGenerator ( MeshBase &  mesh,
const std::vector< Point > &  boundary_points_vec_1,
const std::vector< Point > &  boundary_points_vec_2,
const unsigned int  num_layers,
const subdomain_id_type  transition_layer_id,
const boundary_id_type  input_boundary_1_id,
const boundary_id_type  input_boundary_2_id,
const boundary_id_type  begin_side_boundary_id,
const boundary_id_type  end_side_boundary_id,
const std::string  type,
const std::string  name,
const bool  quad_elem = false,
const Real  bias_parameter = 1.0,
const Real  sigma = 3.0 
)

Generates a 2D mesh with triangular elements for a region defined by two curves (sets of Points)

Parameters
mesha reference MeshBase to contain the generated mesh
boundary_points_vec_1vector of Points of Side #1
boundary_points_vec_2vector of Points of Side #2
num_layersnumber of sublayers of elements
transition_layer_idsubdomain id of the generated mesh
input_boundary_1_idid of the generated mesh's external boundary that originates from boundary_points_vec_1
input_boundary_2_idid of the generated mesh's external boundary that originates from boundary_points_vec_2
begin_side_boundary_idid of the generated mesh's external boundary that connects the first Points of the two input Point vectors
end_side_boundary_idid of the generated mesh's external boundary that connects the last Points of the two input Point vectors
typetype of the MOOSE object that calls this method for error messages
namename of the MOOSE object that calls this method for error messages
quad_elemwhether the QUAD4 elements are used to construct the mesh
bias_parametera parameter to control bias options (1) >0, biasing factor (2) <=0 automatic biasing
sigmaGaussian parameter used for Gaussian blurring of local node density; only used if bias_parameter <= 0

Referenced by fillBetweenPointVectorsGenerator(), FillBetweenCurvesGenerator::generate(), FillBetweenPointVectorsGenerator::generate(), and FillBetweenSidesetsGenerator::generate().

◆ isBoundaryOpenSingleSegment() [1/2]

bool FillBetweenPointVectorsTools::isBoundaryOpenSingleSegment ( MeshBase &  mesh,
Real &  max_node_radius,
std::vector< dof_id_type > &  boundary_ordered_node_list,
const Point  origin_pt,
const boundary_id_type  bid 
)

Decides whether a boundary of a given mesh is an open single-segment boundary.

Parameters
meshinput mesh that contains the boundary to be examined
max_node_radiusthe maximum radius of the nodes on the boundary
boundary_ordered_node_listthe ordered node ids on the given boundary
origin_ptorigin position of the given mesh (used for azimuthal angle calculation)
bidID of the boundary to be examined
Returns
whether the boundary is an open single-segment boundary

Referenced by FillBetweenSidesetsGenerator::generate().

◆ isBoundaryOpenSingleSegment() [2/2]

bool FillBetweenPointVectorsTools::isBoundaryOpenSingleSegment ( MeshBase mesh,
Real &  max_node_radius,
std::vector< dof_id_type > &  boundary_ordered_node_list,
const Point  origin_pt,
const boundary_id_type  bid 
)

Definition at line 564 of file FillBetweenPointVectorsTools.C.

569{
570 try
571 {
572 isBoundarySimpleClosedLoop(mesh, max_node_radius, boundary_ordered_node_list, origin_pt, bid);
573 }
574 catch (MooseException & e)
575 {
576 if (((std::string)e.what())
577 .compare("This mesh generator does not work for the provided external boundary as it "
578 "is not a closed loop.") != 0)
579 throw MooseException("The provided boundary is not an open single-segment boundary.");
580 else
581 return true;
582 }
583
584 throw MooseException("The provided boundary is closed loop, which is not supported.");
585}
Provides a way for users to bail out of the current solve.
virtual const char * what() const
Get out the error message.
bool isBoundarySimpleClosedLoop(MeshBase &mesh, Real &max_node_radius, std::vector< dof_id_type > &boundary_ordered_node_list, const Point origin_pt, const boundary_id_type bid)
Decides whether a boundary of a given mesh is a closed loop with consecutive nodes's azimuthal angles...

◆ isBoundarySimpleClosedLoop() [1/6]

bool FillBetweenPointVectorsTools::isBoundarySimpleClosedLoop ( MeshBase &  mesh,
const Point  origin_pt,
const boundary_id_type  bid 
)

Decides whether a boundary of a given mesh is a closed loop with consecutive nodes's azimuthal angles change monotonically.

Parameters
meshinput mesh that contains the boundary to be examined
origin_ptorigin position of the given mesh (used for azimuthal angle calculation)
bidID of the boundary to be examined
Returns
whether the boundary is a closed loop with consecutive nodes's azimuthal angles change monotonically

◆ isBoundarySimpleClosedLoop() [2/6]

bool FillBetweenPointVectorsTools::isBoundarySimpleClosedLoop ( MeshBase mesh,
const Point  origin_pt,
const boundary_id_type  bid 
)

Definition at line 557 of file FillBetweenPointVectorsTools.C.

558{
559 Real dummy_max_node_radius;
560 return isBoundarySimpleClosedLoop(mesh, dummy_max_node_radius, origin_pt, bid);
561}

◆ isBoundarySimpleClosedLoop() [3/6]

bool FillBetweenPointVectorsTools::isBoundarySimpleClosedLoop ( MeshBase &  mesh,
Real &  max_node_radius,
const Point  origin_pt,
const boundary_id_type  bid 
)

Decides whether a boundary of a given mesh is a closed loop with consecutive nodes's azimuthal angles change monotonically.

Parameters
meshinput mesh that contains the boundary to be examined
max_node_radiusthe maximum radius of the nodes on the boundary
origin_ptorigin position of the given mesh (used for azimuthal angle calculation)
bidID of the boundary to be examined
Returns
whether the boundary is a closed loop with consecutive nodes's azimuthal angles change monotonically

◆ isBoundarySimpleClosedLoop() [4/6]

bool FillBetweenPointVectorsTools::isBoundarySimpleClosedLoop ( MeshBase mesh,
Real &  max_node_radius,
const Point  origin_pt,
const boundary_id_type  bid 
)

Definition at line 546 of file FillBetweenPointVectorsTools.C.

550{
551 std::vector<dof_id_type> dummy_boundary_ordered_node_list;
553 mesh, max_node_radius, dummy_boundary_ordered_node_list, origin_pt, bid);
554}

◆ isBoundarySimpleClosedLoop() [5/6]

bool FillBetweenPointVectorsTools::isBoundarySimpleClosedLoop ( MeshBase &  mesh,
Real &  max_node_radius,
std::vector< dof_id_type > &  boundary_ordered_node_list,
const Point  origin_pt,
const boundary_id_type  bid 
)

Decides whether a boundary of a given mesh is a closed loop with consecutive nodes's azimuthal angles change monotonically.

Parameters
meshinput mesh that contains the boundary to be examined
max_node_radiusthe maximum radius of the nodes on the boundary
boundary_ordered_node_listthe ordered node ids on the given boundary
origin_ptorigin position of the given mesh (used for azimuthal angle calculation)
bidID of the boundary to be examined
Returns
whether the boundary is a closed loop with consecutive nodes's azimuthal angles change monotonically

Referenced by isBoundaryOpenSingleSegment(), isBoundarySimpleClosedLoop(), and isBoundarySimpleClosedLoop().

◆ isBoundarySimpleClosedLoop() [6/6]

bool FillBetweenPointVectorsTools::isBoundarySimpleClosedLoop ( MeshBase mesh,
Real &  max_node_radius,
std::vector< dof_id_type > &  boundary_ordered_node_list,
const Point  origin_pt,
const boundary_id_type  bid 
)

Definition at line 501 of file FillBetweenPointVectorsTools.C.

506{
507 // This has no communication and expects elem_ptr to find any
508 // element, so it only works on serialized meshes
509 libMesh::MeshSerializer serial(mesh);
510
511 max_node_radius = 0.0;
512 BoundaryInfo & boundary_info = mesh.get_boundary_info();
513 auto side_list_tmp = boundary_info.build_side_list();
514 std::vector<std::pair<dof_id_type, dof_id_type>> boundary_node_assm;
515 std::vector<dof_id_type> boundary_midpoint_node_list;
516 for (const auto i : index_range(side_list_tmp))
517 {
518 if (std::get<2>(side_list_tmp[i]) == bid)
519 {
520 // store two nodes of each side
521 const auto elem = mesh.elem_ptr(std::get<0>(side_list_tmp[i]));
522 const auto side = elem->side_ptr(std::get<1>(side_list_tmp[i]));
523 boundary_node_assm.push_back(std::make_pair(side->node_id(0), side->node_id(1)));
524 // see if there is a midpoint
525 const auto & side_type = elem->side_type(std::get<1>(side_list_tmp[i]));
526 if (side_type == EDGE3)
527 boundary_midpoint_node_list.push_back(
528 elem->node_id(elem->n_vertices() + std::get<1>(side_list_tmp[i])));
529 else
530 boundary_midpoint_node_list.push_back(DofObject::invalid_id);
531 }
532 }
533 bool is_closed_loop;
534 isClosedLoop(mesh,
535 max_node_radius,
536 boundary_ordered_node_list,
537 boundary_node_assm,
538 boundary_midpoint_node_list,
539 origin_pt,
540 "external boundary",
541 is_closed_loop);
542 return is_closed_loop;
543}
std::vector< BCTuple > build_side_list(BCTupleSortBy sort_by=BCTupleSortBy::ELEM_ID) const
static constexpr dof_id_type invalid_id
virtual std::unique_ptr< Elem > side_ptr(unsigned int i)=0
virtual const Elem * elem_ptr(const dof_id_type i) const=0
void isClosedLoop(MeshBase &mesh, Real &max_node_radius, std::vector< dof_id_type > &ordered_node_list, std::vector< std::pair< dof_id_type, dof_id_type > > &node_assm, std::vector< dof_id_type > &midpoint_node_list, const Point origin_pt, const std::string input_type, bool &is_closed_loop, const bool suppress_exception=false)
Decides whether a series of nodes contained in a given mesh forms a closed loop with consecutive node...
auto index_range(const T &sizable)

◆ isClosedLoop() [1/4]

void FillBetweenPointVectorsTools::isClosedLoop ( MeshBase mesh,
Real &  max_node_radius,
std::vector< dof_id_type > &  ordered_node_list,
std::vector< std::pair< dof_id_type, dof_id_type > > &  node_assm,
const Point  origin_pt,
const std::string  input_type,
bool &  is_closed_loop,
const bool  suppress_exception 
)

Definition at line 728 of file FillBetweenPointVectorsTools.C.

736{
737 std::vector<dof_id_type> dummy_midpoint_node_list(node_assm.size(), DofObject::invalid_id);
738 isClosedLoop(mesh,
739 max_node_radius,
740 ordered_node_list,
741 node_assm,
742 dummy_midpoint_node_list,
743 origin_pt,
744 input_type,
745 is_closed_loop,
746 suppress_exception);
747}

◆ isClosedLoop() [2/4]

void FillBetweenPointVectorsTools::isClosedLoop ( MeshBase &  mesh,
Real &  max_node_radius,
std::vector< dof_id_type > &  ordered_node_list,
std::vector< std::pair< dof_id_type, dof_id_type > > &  node_assm,
const Point  origin_pt,
const std::string  input_type,
bool &  is_closed_loop,
const bool  suppress_exception = false 
)

Decides whether a series of nodes contained in a given mesh forms a closed loop with consecutive nodes's azimuthal angles change monotonically.

Parameters
meshinput mesh that contains the node series to be examined
max_node_radiusthe maximum radius of the nodes in the series
ordered_node_listthe ordered node ids on the given curve
node_assmthe assembly of the node id pairs that correspond vertices of a series of sides
origin_ptorigin position of the given mesh (used for azimuthal angle calculation)
is_closed_loopwhether the series of nodes form a closed loop with consecutive nodes's azimuthal angles change monotonically
suppress_exceptionwhether to suppress the exceptions thrown by this function if the boundary is not closed

◆ isClosedLoop() [3/4]

void FillBetweenPointVectorsTools::isClosedLoop ( MeshBase mesh,
Real &  max_node_radius,
std::vector< dof_id_type > &  ordered_node_list,
std::vector< std::pair< dof_id_type, dof_id_type > > &  node_assm,
std::vector< dof_id_type > &  midpoint_node_list,
const Point  origin_pt,
const std::string  input_type,
bool &  is_closed_loop,
const bool  suppress_exception 
)

Definition at line 666 of file FillBetweenPointVectorsTools.C.

675{
676 // This has no communication and expects node_ptr to find any
677 // node, so it only works on serialized meshes
678 libMesh::MeshSerializer serial(mesh);
679
680 std::vector<dof_id_type> dummy_elem_list = std::vector<dof_id_type>(node_assm.size(), 0);
681 std::vector<dof_id_type> ordered_dummy_elem_list;
682 is_closed_loop = false;
684 node_assm, dummy_elem_list, midpoint_node_list, ordered_node_list, ordered_dummy_elem_list);
685 // If the code ever gets here, node_assm is empty.
686 // If the ordered_node_list front and back are not the same, the boundary is not a loop.
687 // This is not done inside the loop just for some potential applications in the future.
688 if (ordered_node_list.front() != ordered_node_list.back())
689 {
690 // This is invalid type #2
691 if (!suppress_exception)
692 throw MooseException("This mesh generator does not work for the provided ",
693 input_type,
694 " as it is not a closed loop.");
695 }
696 // It the curve is a loop, check if azimuthal angles change monotonically
697 else
698 {
699 // Utilize cross product here.
700 // If azimuthal angles change monotonically,
701 // the z components of the cross products are always negative or positive.
702 std::vector<Real> ordered_node_azi_list;
703 for (const auto i : make_range(ordered_node_list.size() - 1))
704 {
705 ordered_node_azi_list.push_back(
706 (*mesh.node_ptr(ordered_node_list[i]) - origin_pt)
707 .cross(*mesh.node_ptr(ordered_node_list[i + 1]) - origin_pt)(2));
708 // Use this opportunity to calculate maximum radius
709 max_node_radius =
710 std::max((*mesh.node_ptr(ordered_node_list[i]) - origin_pt).norm(), max_node_radius);
711 }
712 std::sort(ordered_node_azi_list.begin(), ordered_node_azi_list.end());
713 if (ordered_node_azi_list.front() * ordered_node_azi_list.back() < 0.0)
714 {
715 // This is invalid type #3
716 if (!suppress_exception)
717 throw MooseException(
718 "This mesh generator does not work for the provided ",
719 input_type,
720 " as azimuthal angles of consecutive nodes do not change monotonically.");
721 }
722 else
723 is_closed_loop = true;
724 }
725}
virtual const Node * node_ptr(const dof_id_type i) const=0
void makeOrderedNodeList(std::vector< std::pair< dof_id_type, dof_id_type > > &node_assm, std::vector< dof_id_type > &elem_id_list, std::vector< dof_id_type > &midpoint_node_list, std::vector< dof_id_type > &ordered_node_list, std::vector< dof_id_type > &ordered_elem_id_list)
Convert a list of sides in the form of a vector of pairs of node ids into a list of ordered nodes bas...

◆ isClosedLoop() [4/4]

void FillBetweenPointVectorsTools::isClosedLoop ( MeshBase &  mesh,
Real &  max_node_radius,
std::vector< dof_id_type > &  ordered_node_list,
std::vector< std::pair< dof_id_type, dof_id_type > > &  node_assm,
std::vector< dof_id_type > &  midpoint_node_list,
const Point  origin_pt,
const std::string  input_type,
bool &  is_closed_loop,
const bool  suppress_exception = false 
)

Decides whether a series of nodes contained in a given mesh forms a closed loop with consecutive nodes's azimuthal angles change monotonically.

Parameters
meshinput mesh that contains the node series to be examined
max_node_radiusthe maximum radius of the nodes in the series
ordered_node_listthe ordered node ids on the given curve
node_assmthe assembly of the node id pairs that correspond to vertices of the sides on the closed loop
midpoint_node_listthe node ids of the midpoints of the sides for quadratic sides
origin_ptorigin position of the given mesh (used for azimuthal angle calculation)
is_closed_loopwhether the series of nodes form a closed loop with consecutive nodes's azimuthal angles changing monotonically
suppress_exceptionwhether to suppress the exceptions thrown by this function if the boundary is not closed

Referenced by CircularBoundaryCorrectionGenerator::generate(), isBoundarySimpleClosedLoop(), isClosedLoop(), and isCurveSimpleClosedLoop().

◆ isCurveOpenSingleSegment() [1/2]

bool FillBetweenPointVectorsTools::isCurveOpenSingleSegment ( MeshBase &  mesh,
Real &  max_node_radius,
std::vector< dof_id_type > &  ordered_node_list,
const Point  origin_pt 
)

Decides whether a curve contained in a given mesh is an open single-segment curve.

Parameters
meshinput mesh that contains the curve to be examined
max_node_radiusthe maximum radius of the nodes on the curve
ordered_node_listthe ordered node ids on the given curve
origin_ptorigin position of the given mesh (used for azimuthal angle calculation)
Returns
whether the boundary is an open single-segment boundary

Referenced by FillBetweenCurvesGenerator::generate().

◆ isCurveOpenSingleSegment() [2/2]

bool FillBetweenPointVectorsTools::isCurveOpenSingleSegment ( MeshBase mesh,
Real &  max_node_radius,
std::vector< dof_id_type > &  ordered_node_list,
const Point  origin_pt 
)

Definition at line 643 of file FillBetweenPointVectorsTools.C.

647{
648 try
649 {
650 isCurveSimpleClosedLoop(mesh, max_node_radius, ordered_node_list, origin_pt);
651 }
652 catch (MooseException & e)
653 {
654 if (((std::string)e.what())
655 .compare("This mesh generator does not work for the provided curve as it is not a "
656 "closed loop.") != 0)
657 throw MooseException("The provided curve is not an open single-segment boundary.");
658 else
659 return true;
660 }
661 throw MooseException("The provided curve is closed loop, which is not supported.");
662 return false;
663}
bool isCurveSimpleClosedLoop(MeshBase &mesh, Real &max_node_radius, std::vector< dof_id_type > &ordered_node_list, const Point origin_pt)
Decides whether a curve contained in a given mesh is a closed loop with consecutive nodes's azimuthal...

◆ isCurveSimpleClosedLoop() [1/6]

bool FillBetweenPointVectorsTools::isCurveSimpleClosedLoop ( MeshBase &  mesh,
const Point  origin_pt 
)

Decides whether a curve contained in a given mesh is a closed loop with consecutive nodes's azimuthal angles change monotonically.

Parameters
meshinput mesh that contains the curve to be examined
origin_ptorigin position of the given mesh (used for azimuthal angle calculation)
Returns
whether the curve is a closed loop with consecutive nodes's azimuthal angles change monotonically

◆ isCurveSimpleClosedLoop() [2/6]

bool FillBetweenPointVectorsTools::isCurveSimpleClosedLoop ( MeshBase mesh,
const Point  origin_pt 
)

Definition at line 636 of file FillBetweenPointVectorsTools.C.

637{
638 Real dummy_max_node_radius;
639 return isCurveSimpleClosedLoop(mesh, dummy_max_node_radius, origin_pt);
640}

◆ isCurveSimpleClosedLoop() [3/6]

bool FillBetweenPointVectorsTools::isCurveSimpleClosedLoop ( MeshBase &  mesh,
Real &  max_node_radius,
const Point  origin_pt 
)

Decides whether a curve contained in a given mesh is a closed loop with consecutive nodes's azimuthal angles change monotonically.

Parameters
meshinput mesh that contains the curve to be examined
max_node_radiusthe maximum radius of the nodes on the curve
origin_ptorigin position of the given mesh (used for azimuthal angle calculation)
Returns
whether the curve is a closed loop with consecutive nodes's azimuthal angles change monotonically

◆ isCurveSimpleClosedLoop() [4/6]

bool FillBetweenPointVectorsTools::isCurveSimpleClosedLoop ( MeshBase mesh,
Real &  max_node_radius,
const Point  origin_pt 
)

Definition at line 629 of file FillBetweenPointVectorsTools.C.

630{
631 std::vector<dof_id_type> dummy_ordered_node_list;
632 return isCurveSimpleClosedLoop(mesh, max_node_radius, dummy_ordered_node_list, origin_pt);
633}

◆ isCurveSimpleClosedLoop() [5/6]

bool FillBetweenPointVectorsTools::isCurveSimpleClosedLoop ( MeshBase &  mesh,
Real &  max_node_radius,
std::vector< dof_id_type > &  ordered_node_list,
const Point  origin_pt 
)

Decides whether a curve contained in a given mesh is a closed loop with consecutive nodes's azimuthal angles change monotonically.

Parameters
meshinput mesh that contains the curve to be examined
max_node_radiusthe maximum radius of the nodes on the curve
ordered_node_listthe ordered node ids on the given curve
origin_ptorigin position of the given mesh (used for azimuthal angle calculation)
Returns
whether the curve is a closed loop with consecutive nodes's azimuthal angles change monotonically

Referenced by isCurveOpenSingleSegment(), isCurveSimpleClosedLoop(), and isCurveSimpleClosedLoop().

◆ isCurveSimpleClosedLoop() [6/6]

bool FillBetweenPointVectorsTools::isCurveSimpleClosedLoop ( MeshBase mesh,
Real &  max_node_radius,
std::vector< dof_id_type > &  ordered_node_list,
const Point  origin_pt 
)

Definition at line 609 of file FillBetweenPointVectorsTools.C.

613{
614 // This has no communication and expects to loop over all elements
615 // on every processor, so it only works on serialized meshes
616 libMesh::MeshSerializer serial(mesh);
617
618 max_node_radius = 0.0;
619 std::vector<std::pair<dof_id_type, dof_id_type>> node_assm;
620 for (auto it = mesh.active_elements_begin(); it != mesh.active_elements_end(); it++)
621 node_assm.push_back(std::make_pair((*it)->node_id(0), (*it)->node_id(1)));
622 bool is_closed_loop;
624 mesh, max_node_radius, ordered_node_list, node_assm, origin_pt, "curve", is_closed_loop);
625 return is_closed_loop;
626}

◆ isExternalBoundary() [1/2]

bool FillBetweenPointVectorsTools::isExternalBoundary ( MeshBase &  mesh,
const boundary_id_type  bid 
)

Decides whether a boundary of a given mesh is an external boundary.

Parameters
meshinput mesh that contains the boundary to be examined
bidID of the boundary to be examined
Returns
whether the boundary is the external boundary of the given mesh

Referenced by FillBetweenSidesetsGenerator::generate().

◆ isExternalBoundary() [2/2]

bool FillBetweenPointVectorsTools::isExternalBoundary ( MeshBase mesh,
const boundary_id_type  bid 
)

Definition at line 588 of file FillBetweenPointVectorsTools.C.

589{
590 // This has no communication and expects elem_ptr to find any
591 // element, so it only works on serialized meshes
592 libMesh::MeshSerializer serial(mesh);
593
594 if (!mesh.is_prepared())
596 BoundaryInfo & boundary_info = mesh.get_boundary_info();
597 auto side_list = boundary_info.build_side_list();
598 for (const auto i : index_range(side_list))
599 {
600 if (std::get<2>(side_list[i]) == bid)
601 if (mesh.elem_ptr(std::get<0>(side_list[i]))->neighbor_ptr(std::get<1>(side_list[i])) !=
602 nullptr)
603 return false;
604 }
605 return true;
606}
const Elem * neighbor_ptr(unsigned int i) const
bool is_prepared() const
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true, const bool assert_valid=true)=0

◆ needFlip() [1/2]

bool FillBetweenPointVectorsTools::needFlip ( const std::vector< Point > &  vec_pts_1,
const std::vector< Point > &  vec_pts_2 
)

Decide whether one of the input vector of Points needs to be flipped to ensure correct transition layer shape.

Parameters
vec_pts_1first vector of points to be examined
vec_pts_2second vector of points to be examined
Returns
whether one of the vectors needs to be flipped to ensure correct transition layer shape

Referenced by fillBetweenPointVectorsGenerator().

◆ needFlip() [2/2]

bool FillBetweenPointVectorsTools::needFlip ( const std::vector< Point > &  vec_pts_1,
const std::vector< Point > &  vec_pts_2 
)

Definition at line 479 of file FillBetweenPointVectorsTools.C.

480{
481 const Real th1 =
482 acos((vec_pts_1.back() - vec_pts_1.front()) * (vec_pts_2.front() - vec_pts_1.front()) /
483 (vec_pts_1.back() - vec_pts_1.front()).norm() /
484 (vec_pts_2.front() - vec_pts_1.front()).norm());
485 const Real th2 = acos(
486 (vec_pts_2.back() - vec_pts_1.back()) * (vec_pts_1.front() - vec_pts_1.back()) /
487 (vec_pts_2.back() - vec_pts_1.back()).norm() / (vec_pts_1.front() - vec_pts_1.back()).norm());
488 const Real th3 = acos(
489 (vec_pts_2.front() - vec_pts_2.back()) * (vec_pts_1.back() - vec_pts_2.back()) /
490 (vec_pts_2.front() - vec_pts_2.back()).norm() / (vec_pts_1.back() - vec_pts_2.back()).norm());
491 const Real th4 =
492 acos((vec_pts_1.front() - vec_pts_2.front()) * (vec_pts_2.back() - vec_pts_2.front()) /
493 (vec_pts_1.front() - vec_pts_2.front()).norm() /
494 (vec_pts_2.back() - vec_pts_2.front()).norm());
495 if (MooseUtils::absoluteFuzzyEqual(th1 + th2 + th3 + th4, 2 * M_PI))
496 return false;
497 return true;
498}

◆ surrogateGenerator()

void FillBetweenPointVectorsTools::surrogateGenerator ( std::vector< Real > &  weighted_surrogate_index,
std::vector< Real > &  unweighted_surrogate_index,
const std::vector< unsigned int > &  node_number_vec,
const std::vector< Real > &  index,
const std::vector< Real > &  wt,
const unsigned int  boundary_node_num,
const unsigned int  i 
)

Generates weighted surrogate index vectors on one side for points of a sublayer curve.

Parameters
weighted_surrogate_indexweighted surrogate index vector
unweighted_surrogate_indexunweighted surrogate index vector
node_number_vecnumber of points/nodes on the sublayer curve
indexweighted index vector of the points on the side
wtweight vector of the points on the side
boundary_node_numnumber of points/nodes on the side
iindex of the sublayer

Definition at line 438 of file FillBetweenPointVectorsTools.C.

445{
446 // First element is trivial
447 weighted_surrogate_index.push_back(0.0);
448 unweighted_surrogate_index.push_back(0.0);
449 for (unsigned int j = 1; j < node_number_vec[i]; j++)
450 {
451 // uniform interval for unweighted index
452 unweighted_surrogate_index.push_back((Real)j / ((Real)node_number_vec[i] - 1.0));
453 // >
454 const auto it_0 =
455 std::upper_bound(index.begin(), index.end(), unweighted_surrogate_index[j - 1]);
456 // >=
457 const auto it_1 = std::lower_bound(index.begin(), index.end(), unweighted_surrogate_index[j]);
458 //
459 const auto it_dist = std::distance(it_0, it_1);
460 //
461 const auto it_start = std::distance(index.begin(), it_0);
462
463 if (it_0 == it_1)
464 weighted_surrogate_index.push_back(weighted_surrogate_index[j - 1] +
465 wt[it_start - 1] / ((Real)node_number_vec[i] - 1.0));
466 else
467 {
468 weighted_surrogate_index.push_back(weighted_surrogate_index[j - 1]);
469 weighted_surrogate_index[j] += (*it_0 - unweighted_surrogate_index[j - 1]) * wt[it_start - 1];
470 weighted_surrogate_index[j] +=
471 (unweighted_surrogate_index[j] - *(it_1 - 1)) * wt[it_start + it_dist - 1];
472 for (unsigned int k = 1; k < it_dist; k++)
473 weighted_surrogate_index[j] += wt[it_start + k - 1] / ((Real)boundary_node_num - 1.0);
474 }
475 }
476}

Referenced by fillBetweenPointVectorsGenerator().

◆ weightedInterpolator() [1/2]

void FillBetweenPointVectorsTools::weightedInterpolator ( const unsigned int  vec_node_num,
const std::vector< Point > &  boundary_points_vec,
std::vector< Real > &  vec_index,
std::vector< Real > &  wt,
std::vector< Real > &  index,
const Real  sigma,
std::unique_ptr< LinearInterpolation > &  linear_vec_x,
std::unique_ptr< LinearInterpolation > &  linear_vec_y,
std::unique_ptr< SplineInterpolation > &  spline_vec_l 
)

Generates weights, weighted indices and corresponding interpolation.

Parameters
vec_node_numnumber of points/nodes on the given curve
boundary_points_vecvector of points on the given curve
vec_indexunweighted index vector
wtweights based on point-to-point distances
indexweighted index vector
sigmaGaussian parameter used for Gaussian blurring of local node density
linear_vec_xlinear interpolation of x coordinates based on weighted index
linear_vec_ylinear interpolation of y coordinates based on weighted index
spline_vec_lspline interpolation of inter-node length based on weighted index

Referenced by fillBetweenPointVectorsGenerator().

◆ weightedInterpolator() [2/2]

void FillBetweenPointVectorsTools::weightedInterpolator ( const unsigned int  vec_node_num,
const std::vector< Point > &  boundary_points_vec,
std::vector< Real > &  vec_index,
std::vector< Real > &  wt,
std::vector< Real > &  index,
const Real  sigma,
std::unique_ptr< LinearInterpolation > &  linear_vec_x,
std::unique_ptr< LinearInterpolation > &  linear_vec_y,
std::unique_ptr< SplineInterpolation > &  spline_vec_l 
)

Definition at line 374 of file FillBetweenPointVectorsTools.C.

383{
384 std::vector<Real> pos_x;
385 std::vector<Real> pos_y;
386 std::vector<Real> dist_vec;
387 std::vector<Real> pos_l;
388
389 for (const auto i : make_range(vec_node_num))
390 {
391 // Unweighted, the index interval is just uniform
392 // Normalized range 0~1
393 vec_index.push_back((Real)i / ((Real)vec_node_num - 1.0));
394 // X and Y coordinates cooresponding to the index
395 pos_x.push_back(boundary_points_vec[i](0));
396 pos_y.push_back(boundary_points_vec[i](1));
397 // Use Point-to-Point distance as unnormalized weight
398 if (i > 0)
399 {
400 wt.push_back((boundary_points_vec[i] - boundary_points_vec[i - 1]).norm());
401 dist_vec.push_back(wt.back());
402 }
403 // Accumulated unnormalized weights to get unnormalized weighted index
404 index.push_back(std::accumulate(wt.begin(), wt.end(), 0.0));
405 }
406 const Real dist_vec_total = index.back(); // Total accumulated distances
407 const Real wt_norm_factor = dist_vec_total / ((Real)vec_node_num - 1.0); // Normalization factor
408 // Normalization for both weights and weighted indices
409 std::transform(
410 wt.begin(), wt.end(), wt.begin(), [wt_norm_factor](Real & c) { return c / wt_norm_factor; });
411 std::transform(index.begin(),
412 index.end(),
413 index.begin(),
414 [dist_vec_total](Real & c) { return c / dist_vec_total; });
415 // Use Gaussian blurring to smoothen local density
416 for (const auto i : make_range(vec_node_num))
417 {
418 Real gaussian_factor(0.0);
419 Real sum_tmp(0.0);
420 // Use interval as parameter now, consider distance in the future
421 for (const auto j : make_range(vec_node_num - 1))
422 {
423 // dis_vec and index are off by 0.5
424 const Real tmp_factor =
425 exp(-((Real)(i - j) - 0.5) * ((Real)(i - j) - 0.5) / 2.0 / sigma / sigma);
426 gaussian_factor += tmp_factor;
427 sum_tmp += tmp_factor * dist_vec[j];
428 }
429 pos_l.push_back(sum_tmp / gaussian_factor);
430 }
431 // Interpolate positions based on weighted indices
432 linear_vec_x = std::make_unique<LinearInterpolation>(index, pos_x);
433 linear_vec_y = std::make_unique<LinearInterpolation>(index, pos_y);
434 spline_vec_l = std::make_unique<SplineInterpolation>(index, pos_l);
435}
auto exp(const T &)