Loading [MathJax]/extensions/tex2jax.js
https://mooseframework.inl.gov
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends
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) More...
 
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) More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
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. More...
 
bool isExternalBoundary (MeshBase &mesh, const boundary_id_type bid)
 Decides whether a boundary of a given mesh is an external boundary. More...
 
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. More...
 
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. More...
 
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

◆ 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.

Referenced by elementsCreationFromNodesVectorsQuad().

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

◆ 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.

Referenced by elementsCreationFromNodesVectors().

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 }
virtual Node *& set_node(const unsigned int i)
subdomain_id_type subdomain_id() const

◆ 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

◆ 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.

Referenced by fillBetweenPointVectorsGenerator().

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 }
MeshBase & mesh
const BoundaryInfo & get_boundary_info() const
virtual Elem * add_elem(Elem *e)=0
auto norm(const T &a) -> decltype(std::abs(a))
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
IntRange< T > make_range(T beg, T end)
bool buildTriElement(Elem *elem, Node *nd_0, Node *nd_1, Node *nd_2, const subdomain_id_type transition_layer_id)
bool absoluteFuzzyGreaterThan(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether a variable is greater than another variable within an absolute tolerance...
Definition: MooseUtils.h:420

◆ 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

◆ 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.

Referenced by fillBetweenPointVectorsGenerator().

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 }
MeshBase & mesh
const BoundaryInfo & get_boundary_info() const
virtual Elem * add_elem(Elem *e)=0
bool buildQuadElement(Elem *elem, Node *nd_0, Node *nd_1, Node *nd_2, Node *nd_3, const subdomain_id_type transition_layer_id)
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
IntRange< T > make_range(T beg, T end)

◆ 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  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 }
constexpr auto increment(std::index_sequence< first, tail... >)
Increment the first number in an index sequence, but roll over into the next number if it reaches Nma...
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
Definition: MooseUtils.h:372
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:302
MeshBase & mesh
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
bool needFlip(const std::vector< Point > &vec_pts_1, const std::vector< Point > &vec_pts_2)
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 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 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...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
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)
IntRange< T > make_range(T beg, T end)
MooseUnits pow(const MooseUnits &, int)
Definition: Units.C:537
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)

◆ 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  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 FillBetweenCurvesGenerator::generate(), FillBetweenSidesetsGenerator::generate(), and FillBetweenPointVectorsGenerator::generate().

◆ 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  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() [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  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 external_boundary_id, const std::string type, const std::string name, const bool quad_elem)

◆ 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 }
virtual const char * what() const
Get out the error message.
Provides a way for users to bail out of the current solve.
bool isBoundarySimpleClosedLoop(MeshBase &mesh, const Point origin_pt, const boundary_id_type bid)

◆ isBoundarySimpleClosedLoop() [1/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

◆ isBoundarySimpleClosedLoop() [2/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() [3/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() [4/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 }
MeshBase & mesh
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)
const BoundaryInfo & get_boundary_info() const
void build_side_list(std::vector< dof_id_type > &element_id_list, std::vector< unsigned short int > &side_list, std::vector< boundary_id_type > &bc_id_list) const
virtual const Elem * elem_ptr(const dof_id_type i) const=0
virtual std::unique_ptr< Elem > side_ptr(unsigned int i)=0
auto index_range(const T &sizable)

◆ isBoundarySimpleClosedLoop() [5/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 }
bool isBoundarySimpleClosedLoop(MeshBase &mesh, const Point origin_pt, const boundary_id_type bid)

◆ isBoundarySimpleClosedLoop() [6/6]

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

Definition at line 557 of file FillBetweenPointVectorsTools.C.

Referenced by isBoundaryOpenSingleSegment(), and isBoundarySimpleClosedLoop().

558 {
559  Real dummy_max_node_radius;
560  return isBoundarySimpleClosedLoop(mesh, dummy_max_node_radius, origin_pt, bid);
561 }
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool isBoundarySimpleClosedLoop(MeshBase &mesh, const Point origin_pt, const boundary_id_type bid)

◆ 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,
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().

◆ 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 }
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...
MeshBase & mesh
auto max(const L &left, const R &right)
auto norm(const T &a) -> decltype(std::abs(a))
Provides a way for users to bail out of the current solve.
IntRange< T > make_range(T beg, T end)
virtual const Node * node_ptr(const dof_id_type i) const=0

◆ 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,
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.

Referenced by isBoundarySimpleClosedLoop(), and isCurveSimpleClosedLoop().

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 }
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)

◆ 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 }
virtual const char * what() const
Get out the error message.
Provides a way for users to bail out of the current solve.
bool isCurveSimpleClosedLoop(MeshBase &mesh, const Point origin_pt)

◆ isCurveSimpleClosedLoop() [1/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

◆ isCurveSimpleClosedLoop() [2/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() [3/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() [4/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;
623  isClosedLoop(
624  mesh, max_node_radius, ordered_node_list, node_assm, origin_pt, "curve", is_closed_loop);
625  return is_closed_loop;
626 }
MeshBase & mesh
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)

◆ isCurveSimpleClosedLoop() [5/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 }
bool isCurveSimpleClosedLoop(MeshBase &mesh, const Point origin_pt)

◆ isCurveSimpleClosedLoop() [6/6]

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

Definition at line 636 of file FillBetweenPointVectorsTools.C.

Referenced by isCurveOpenSingleSegment(), and isCurveSimpleClosedLoop().

637 {
638  Real dummy_max_node_radius;
639  return isCurveSimpleClosedLoop(mesh, dummy_max_node_radius, origin_pt);
640 }
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
bool isCurveSimpleClosedLoop(MeshBase &mesh, const Point origin_pt)

◆ 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 }
bool is_prepared() const
MeshBase & mesh
const BoundaryInfo & get_boundary_info() const
void build_side_list(std::vector< dof_id_type > &element_id_list, std::vector< unsigned short int > &side_list, std::vector< boundary_id_type > &bc_id_list) const
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true)=0
virtual const Elem * elem_ptr(const dof_id_type i) const=0
const Elem * neighbor_ptr(unsigned int i) const
auto index_range(const T &sizable)

◆ 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

◆ 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.

Referenced by fillBetweenPointVectorsGenerator().

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 }
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
Definition: MooseUtils.h:372
auto norm(const T &a) -> decltype(std::abs(a))
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

◆ 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.

Referenced by fillBetweenPointVectorsGenerator().

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 }

◆ 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

◆ 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.

Referenced by fillBetweenPointVectorsGenerator().

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 &)
auto norm(const T &a) -> decltype(std::abs(a))
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)