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.
 

Function Documentation

◆ buildQuadElement()

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

Definition at line 748 of file FillBetweenPointVectorsTools.C.

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

Referenced by elementsCreationFromNodesVectorsQuad().

◆ buildTriElement()

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

Definition at line 777 of file FillBetweenPointVectorsTools.C.

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

Referenced by elementsCreationFromNodesVectors().

◆ elementsCreationFromNodesVectors()

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

Definition at line 285 of file FillBetweenPointVectorsTools.C.

294{
295 BoundaryInfo & boundary_info = mesh.get_boundary_info();
296
297 for (const auto i : make_range(num_layers))
298 {
299 unsigned int nodes_up_it = 0;
300 unsigned int nodes_down_it = 0;
301 const unsigned int node_number_up = node_number_vec[i + 1];
302 const unsigned int node_number_down = node_number_vec[i];
303
304 while (nodes_up_it < node_number_up - 1 && nodes_down_it < node_number_down - 1 &&
305 nodes_up_it + nodes_down_it < node_number_up + node_number_down - 3)
306 {
307 // Define the two possible options and chose the one with shorter distance
308 Real dis1 = (*nodes[i + 1][nodes_up_it] - *nodes[i][nodes_down_it + 1]).norm();
309 Real dis2 = (*nodes[i + 1][nodes_up_it + 1] - *nodes[i][nodes_down_it]).norm();
310 if (MooseUtils::absoluteFuzzyGreaterThan(dis1, dis2))
311 {
312 Elem * elem = mesh.add_elem(new Tri3);
313 bool is_elem_flip = buildTriElement(elem,
314 nodes[i + 1][nodes_up_it],
315 nodes[i][nodes_down_it],
316 nodes[i + 1][nodes_up_it + 1],
317 transition_layer_id);
318 if (i == num_layers - 1)
319 boundary_info.add_side(elem, is_elem_flip ? 0 : 2, input_boundary_2_id);
320 if (nodes_up_it == 0 && nodes_down_it == 0)
321 boundary_info.add_side(elem, is_elem_flip ? 2 : 0, begin_side_boundary_id);
322 nodes_up_it++;
323 }
324 else
325 {
326 Elem * elem = mesh.add_elem(new Tri3);
327 bool is_elem_flip = buildTriElement(elem,
328 nodes[i + 1][nodes_up_it],
329 nodes[i][nodes_down_it],
330 nodes[i][nodes_down_it + 1],
331 transition_layer_id);
332 if (i == 0)
333 boundary_info.add_side(elem, 1, input_boundary_1_id);
334 if (nodes_up_it == 0 && nodes_down_it == 0)
335 boundary_info.add_side(elem, is_elem_flip ? 2 : 0, begin_side_boundary_id);
336 nodes_down_it++;
337 }
338 }
339 // Handle the end
340 while (nodes_up_it < node_number_up - 1)
341 {
342 Elem * elem = mesh.add_elem(new Tri3);
343 bool is_elem_flip = buildTriElement(elem,
344 nodes[i + 1][nodes_up_it],
345 nodes[i][nodes_down_it],
346 nodes[i + 1][nodes_up_it + 1],
347 transition_layer_id);
348 nodes_up_it++;
349 if (i == num_layers - 1)
350 boundary_info.add_side(elem, is_elem_flip ? 0 : 2, input_boundary_2_id);
351 if (nodes_up_it == node_number_up - 1 && nodes_down_it == node_number_down - 1)
352 boundary_info.add_side(elem, 1, end_side_boundary_id);
353 }
354 while (nodes_down_it < node_number_down - 1)
355 {
356 Elem * elem = mesh.add_elem(new Tri3);
357 bool is_elem_flip = buildTriElement(elem,
358 nodes[i + 1][nodes_up_it],
359 nodes[i][nodes_down_it],
360 nodes[i][nodes_down_it + 1],
361 transition_layer_id);
362 nodes_down_it++;
363 if (i == 0)
364 boundary_info.add_side(elem, 1, input_boundary_1_id);
365 if (nodes_up_it == node_number_up - 1 && nodes_down_it == node_number_down - 1)
366 boundary_info.add_side(elem, is_elem_flip ? 0 : 2, end_side_boundary_id);
367 }
368 }
369}
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.

Referenced by fillBetweenPointVectorsGenerator().

◆ elementsCreationFromNodesVectorsQuad()

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

Definition at line 250 of file FillBetweenPointVectorsTools.C.

259{
260 const unsigned int node_number = node_number_vec.front();
261 BoundaryInfo & boundary_info = mesh.get_boundary_info();
262
263 for (const auto i : make_range(num_layers))
264 for (unsigned int j = 1; j < node_number; j++)
265 {
266 Elem * elem = mesh.add_elem(new Quad4);
267 bool is_elem_flip = buildQuadElement(elem,
268 nodes[i][j - 1],
269 nodes[i + 1][j - 1],
270 nodes[i + 1][j],
271 nodes[i][j],
272 transition_layer_id);
273 if (i == 0)
274 boundary_info.add_side(elem, is_elem_flip ? 0 : 3, input_boundary_1_id);
275 if (i == num_layers - 1)
276 boundary_info.add_side(elem, is_elem_flip ? 2 : 1, input_boundary_2_id);
277 if (j == 1)
278 boundary_info.add_side(elem, is_elem_flip ? 3 : 0, begin_side_boundary_id);
279 if (j == node_number - 1)
280 boundary_info.add_side(elem, is_elem_flip ? 1 : 2, end_side_boundary_id);
281 }
282}
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.

Referenced by fillBetweenPointVectorsGenerator().

◆ fillBetweenPointVectorsGenerator() [1/2]

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

Definition at line 225 of file FillBetweenPointVectorsTools.C.

234{
236 boundary_points_vec_1,
237 boundary_points_vec_2,
238 num_layers,
239 transition_layer_id,
240 external_boundary_id,
241 external_boundary_id,
242 external_boundary_id,
243 external_boundary_id,
244 type,
245 name,
246 quad_elem);
247}
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/2]

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

Definition at line 30 of file FillBetweenPointVectorsTools.C.

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

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

◆ isBoundaryOpenSingleSegment()

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

Definition at line 562 of file FillBetweenPointVectorsTools.C.

567{
568 try
569 {
570 isBoundarySimpleClosedLoop(mesh, max_node_radius, boundary_ordered_node_list, origin_pt, bid);
571 }
572 catch (MooseException & e)
573 {
574 if (((std::string)e.what())
575 .compare("This mesh generator does not work for the provided external boundary as it "
576 "is not a closed loop.") != 0)
577 throw MooseException("The provided boundary is not an open single-segment boundary.");
578 else
579 return true;
580 }
581
582 throw MooseException("The provided boundary is closed loop, which is not supported.");
583}
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...

Referenced by FillBetweenSidesetsGenerator::generate().

◆ isBoundarySimpleClosedLoop() [1/3]

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

Definition at line 555 of file FillBetweenPointVectorsTools.C.

556{
557 Real dummy_max_node_radius;
558 return isBoundarySimpleClosedLoop(mesh, dummy_max_node_radius, origin_pt, bid);
559}

◆ isBoundarySimpleClosedLoop() [2/3]

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

Definition at line 544 of file FillBetweenPointVectorsTools.C.

548{
549 std::vector<dof_id_type> dummy_boundary_ordered_node_list;
551 mesh, max_node_radius, dummy_boundary_ordered_node_list, origin_pt, bid);
552}

◆ isBoundarySimpleClosedLoop() [3/3]

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

Definition at line 499 of file FillBetweenPointVectorsTools.C.

504{
505 // This has no communication and expects elem_ptr to find any
506 // element, so it only works on serialized meshes
507 libMesh::MeshSerializer serial(mesh);
508
509 max_node_radius = 0.0;
510 BoundaryInfo & boundary_info = mesh.get_boundary_info();
511 auto side_list_tmp = boundary_info.build_side_list();
512 std::vector<std::pair<dof_id_type, dof_id_type>> boundary_node_assm;
513 std::vector<dof_id_type> boundary_midpoint_node_list;
514 for (const auto i : index_range(side_list_tmp))
515 {
516 if (std::get<2>(side_list_tmp[i]) == bid)
517 {
518 // store two nodes of each side
519 const auto elem = mesh.elem_ptr(std::get<0>(side_list_tmp[i]));
520 const auto side = elem->side_ptr(std::get<1>(side_list_tmp[i]));
521 boundary_node_assm.push_back(std::make_pair(side->node_id(0), side->node_id(1)));
522 // see if there is a midpoint
523 const auto & side_type = elem->side_type(std::get<1>(side_list_tmp[i]));
524 if (side_type == EDGE3)
525 boundary_midpoint_node_list.push_back(
526 elem->node_id(elem->n_vertices() + std::get<1>(side_list_tmp[i])));
527 else
528 boundary_midpoint_node_list.push_back(DofObject::invalid_id);
529 }
530 }
531 bool is_closed_loop;
532 isClosedLoop(mesh,
533 max_node_radius,
534 boundary_ordered_node_list,
535 boundary_node_assm,
536 boundary_midpoint_node_list,
537 origin_pt,
538 "external boundary",
539 is_closed_loop);
540 return is_closed_loop;
541}
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...

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

◆ isClosedLoop() [1/2]

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

Definition at line 726 of file FillBetweenPointVectorsTools.C.

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

◆ isClosedLoop() [2/2]

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

Definition at line 664 of file FillBetweenPointVectorsTools.C.

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

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

◆ isCurveOpenSingleSegment()

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

Definition at line 641 of file FillBetweenPointVectorsTools.C.

645{
646 try
647 {
648 isCurveSimpleClosedLoop(mesh, max_node_radius, ordered_node_list, origin_pt);
649 }
650 catch (MooseException & e)
651 {
652 if (((std::string)e.what())
653 .compare("This mesh generator does not work for the provided curve as it is not a "
654 "closed loop.") != 0)
655 throw MooseException("The provided curve is not an open single-segment boundary.");
656 else
657 return true;
658 }
659 throw MooseException("The provided curve is closed loop, which is not supported.");
660 return false;
661}
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...

Referenced by FillBetweenCurvesGenerator::generate().

◆ isCurveSimpleClosedLoop() [1/3]

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

Definition at line 634 of file FillBetweenPointVectorsTools.C.

635{
636 Real dummy_max_node_radius;
637 return isCurveSimpleClosedLoop(mesh, dummy_max_node_radius, origin_pt);
638}

◆ isCurveSimpleClosedLoop() [2/3]

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

Definition at line 627 of file FillBetweenPointVectorsTools.C.

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

◆ isCurveSimpleClosedLoop() [3/3]

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

Definition at line 607 of file FillBetweenPointVectorsTools.C.

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

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

◆ isExternalBoundary()

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

Definition at line 586 of file FillBetweenPointVectorsTools.C.

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

Referenced by FillBetweenSidesetsGenerator::generate().

◆ needFlip()

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

Definition at line 477 of file FillBetweenPointVectorsTools.C.

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

Referenced by fillBetweenPointVectorsGenerator().

◆ 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 436 of file FillBetweenPointVectorsTools.C.

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

Referenced by fillBetweenPointVectorsGenerator().

◆ weightedInterpolator()

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

Definition at line 372 of file FillBetweenPointVectorsTools.C.

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

Referenced by fillBetweenPointVectorsGenerator().