17#include "libmesh/edge_edge2.h"
18#include "libmesh/edge_edge3.h"
19#include "libmesh/edge_edge4.h"
27 MooseEnum edge_elem_type(
"EDGE2 EDGE3 EDGE4",
"EDGE2");
31 "new_subdomain_id", 1,
"Subdomain ID to assign to the curve elements");
32 params.
addParam<SubdomainName>(
"new_subdomain_name",
33 "Subdomain name to assign to the curve elements");
36 params.
addParam<Point>(
"start_point",
"Starting (x,y,z) point for curve.");
37 params.
addParam<Point>(
"end_point",
"Ending (x,y,z) point for curve.");
38 params.
addParam<RealVectorValue>(
"start_direction",
"Direction vector of curve at start point.");
39 params.
addParam<RealVectorValue>(
"end_direction",
"Direction vector of curve at end point.");
41 "Curve extremities input");
44 params.
addParam<MeshGeneratorName>(
"start_mesh",
45 "Meshgenerator providing the mesh to start spline from.");
47 "boundary_providing_start_point",
48 "Boundary at whose centroid the spline should start. If the start_direction is not set, the "
49 "starting direction is computed from a side-volume average of the side-vertex-average "
50 "normals of the boundary sides");
51 params.
addParam<MeshGeneratorName>(
"end_mesh",
52 "Meshgenerator providing the mesh to end splne on.");
54 "boundary_providing_end_point",
55 "Boundary at whose centroid the spline should end. If the end_direction is not set, the "
56 "ending direction is computed from a side-volume average of the side-vertex-average normals "
57 "of the boundary sides");
59 "start_mesh end_mesh boundary_providing_start_point boundary_providing_end_point",
60 "Curve extremities input");
63 params.
addParam<
unsigned int>(
"degree", 3,
"Degree of interpolating polynomial.");
65 "sharpness", 0.6,
"sharpness>0 & sharpness<=1",
"Sharpness of curve bend.");
69 "Number of control points used to draw the curve. Minimum of degree+1 points are required.");
74 "edge_element_type", edge_elem_type,
"Type of the EDGE elements to be generated.");
76 "num_elements",
"num_elements>=1",
"Numer of elements to be drawn. Must be at least 1.");
80 "This BSplineMeshGenerator object is designed to generate a mesh of a curve that consists of "
81 "EDGE2, EDGE3, or EDGE4 elements drawn using an open uniform B-Spline.");
82 params.
addParam<std::vector<BoundaryName>>(
"edge_nodesets",
83 std::vector<BoundaryName>(),
84 "Nodeset name to give each edge of the spline curve");
91 _new_subdomain_id(getParam<
SubdomainID>(
"new_subdomain_id")),
92 _degree(getParam<unsigned
int>(
"degree")),
93 _sharpness(getParam<
libMesh::Real>(
"sharpness")),
94 _num_cps(getParam<unsigned
int>(
"num_cps")),
95 _order((unsigned
int)(getParam<
MooseEnum>(
"edge_element_type")) + 1),
96 _num_elements(getParam<unsigned
int>(
"num_elements")),
97 _node_set_boundaries(getParam<
std::vector<BoundaryName>>(
"edge_nodesets")),
98 _start_mesh_input(getMesh(
"start_mesh", true)),
99 _end_mesh_input(getMesh(
"end_mesh", true))
102 paramError(
"num_cps",
"Number of control points must be at least degree+1.");
109 "boundary_providing_start_point must be specified if start_point is not");
111 paramError(
"start_mesh",
"start_mesh must be specified if start_point is not.");
117 "start_point and boundary_providing_start_point or start_mesh cannot be "
118 "simultaneously specified!");
121 "Starting direction must be specified if the 'start_point' is specified");
127 "boundary_providing_end_point must be specified if start_point is not");
129 paramError(
"end_mesh",
"end_mesh must be specified if start_point is not.");
135 "end_point and boundary_providing_end_point or end_mesh cannot be "
136 "simultaneously specified!");
139 "Ending direction must be specified if the 'end_point' is specified");
142 paramError(
"edge_nodesets",
"If specified, edge_nodesets must have exactly 2 entries.");
145std::unique_ptr<MeshBase>
148 std::unique_ptr<MeshBase> start_mesh;
149 std::unique_ptr<MeshBase> end_mesh;
155 const auto start_point =
157 const auto end_point =
160 ? getParam<RealVectorValue>(
"start_direction")
162 const auto end_dir =
isParamValid(
"end_direction") ? getParam<RealVectorValue>(
"end_direction")
168 unsigned int half_cps;
174 mooseWarning(
"Need an even number of control points. `num_cps` has been decreased by 1.");
179 start_point, end_point, start_dir, end_dir, half_cps,
_sharpness);
187 std::vector<Node *> nodes(n_ts);
188 std::vector<Point> eval_points;
189 for (
const auto i : make_range(n_ts))
192 const auto t_current = ((Real)i / (Real)(n_ts - 1));
193 eval_points.push_back(b_spline.
getPoint(t_current));
194 nodes[i] =
mesh->add_point(eval_points.back(), i);
200 std::unique_ptr<Elem> new_elem;
204 new_elem = std::make_unique<Edge2>();
207 new_elem = std::make_unique<Edge3>();
208 new_elem->set_node(2, nodes[i *
_order + 1]);
212 new_elem = std::make_unique<Edge4>();
213 new_elem->set_node(2, nodes[i *
_order + 1]);
214 new_elem->set_node(3, nodes[i *
_order + 2]);
218 new_elem->set_node(0, nodes[i *
_order]);
219 mooseAssert((i + 1) *
_order < nodes.size(),
"Out of bounds in nodes array");
220 new_elem->set_node(1, nodes[((i + 1) *
_order)]);
223 mesh->add_elem(std::move(new_elem));
228 mesh->set_subdomain_name(
234 BoundaryInfo & boundary_info =
mesh->get_boundary_info();
237 boundary_info.nodeset_name(i++) = side_name;
240 boundary_info.add_node(*(nodes.end() - 1),
243 return dynamic_pointer_cast<MeshBase>(
mesh);
250 getParam<BoundaryName>(
"boundary_providing_start_point"), start_mesh);
257 getParam<BoundaryName>(
"boundary_providing_end_point"), end_mesh);
264 getParam<BoundaryName>(
"boundary_providing_start_point"), start_mesh);
271 getParam<BoundaryName>(
"boundary_providing_end_point"), end_mesh);
subdomain_id_type SubdomainID
registerMooseObject("MooseApp", BSplineCurveGenerator)
void ErrorVector unsigned int
Mesh generator to create a 1D B-spline curve mesh in 3D space.
Point startPoint(MeshBase &start_mesh) const
Return the starting point of the spline.
const unsigned int _degree
degree of interpolating spline
Point endPoint(MeshBase &end_mesh) const
Return the ending point of the spline.
static InputParameters validParams()
BSplineCurveGenerator(const InputParameters ¶meters)
const unsigned int _num_elements
number of edge elements on the curve
const unsigned int _num_cps
number of control points to be generated
std::vector< BoundaryName > _node_set_boundaries
vector of the names of the boundaries at the ends of the spline curve
const unsigned int _order
order of the EDGE elements to be generated
const Real _sharpness
sharpness of curve (measure of how close it is to the curve with three orthogonal segments)
RealVectorValue startDirection(MeshBase &start_mesh) const
Return the starting direction of the spline.
RealVectorValue endDirection(MeshBase &end_mesh) const
Return the ending direction of the spline.
std::unique_ptr< MeshBase > & _end_mesh_input
If 'end_mesh' parameter is set, reference to input mesh providing the ending boundary.
std::unique_ptr< MeshBase > & _start_mesh_input
If 'start_mesh' parameter is set, reference to input mesh providing the starting boundary.
const SubdomainID _new_subdomain_id
Subdomain ID for the elements created.
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
MeshGenerators are objects that can modify or add to an existing mesh.
std::unique_ptr< ReplicatedMesh > buildReplicatedMesh(unsigned int dim=libMesh::invalid_uint)
Build a replicated mesh.
static InputParameters validParams()
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Class implementing a uniform clamped B-Spline curve.
libMesh::Point getPoint(const libMesh::Real t) const
Evaluate the BSpline interpolation at given value of t.
void mooseWarning(Args &&... args) const
Point boundaryCentroidCalculator(const BoundaryName &boundary, MeshBase &mesh)
Calculates the centroid of a boundary on a mesh.
RealVectorValue boundaryWeightedNormal(const BoundaryName &boundary, MeshBase &mesh)
Calculates the side-volume weighted (side-vertex) average normal of a boundary on a mesh.
std::vector< Point > bSplineControlPoints(const libMesh::Point &start_point, const libMesh::Point &end_point, const libMesh::RealVectorValue &start_direction, const libMesh::RealVectorValue &end_direction, const unsigned int cps_per_half, const libMesh::Real sharpness)
Creates control points for an open uniform BSpline.
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real