17 #include "libmesh/edge_edge2.h" 18 #include "libmesh/edge_edge3.h" 19 #include "libmesh/edge_edge4.h" 29 MooseEnum edge_elem_type(
"EDGE2 EDGE3 EDGE4",
"EDGE2");
33 "new_subdomain_id", 1,
"Subdomain ID to assign to the curve elements");
34 params.
addParam<SubdomainName>(
"new_subdomain_name",
35 "Subdomain name to assign to the curve elements");
38 params.
addParam<
Point>(
"start_point",
"Starting (x,y,z) point for curve.");
39 params.
addParam<
Point>(
"end_point",
"Ending (x,y,z) point for curve.");
43 "Curve extremities input");
46 params.
addParam<MeshGeneratorName>(
"start_mesh",
47 "Meshgenerator providing the mesh to start spline from.");
49 "boundary_providing_start_point",
50 "Boundary at whose centroid the spline should start. If the start_direction is not set, the " 51 "starting direction is computed from a side-volume average of the side-vertex-average " 52 "normals of the boundary sides");
53 params.
addParam<MeshGeneratorName>(
"end_mesh",
54 "Meshgenerator providing the mesh to end splne on.");
56 "boundary_providing_end_point",
57 "Boundary at whose centroid the spline should end. If the end_direction is not set, the " 58 "ending direction is computed from a side-volume average of the side-vertex-average normals " 59 "of the boundary sides");
61 "start_mesh end_mesh boundary_providing_start_point boundary_providing_end_point",
62 "Curve extremities input");
65 params.
addParam<
unsigned int>(
"degree", 3,
"Degree of interpolating polynomial.");
67 "sharpness", 0.6,
"sharpness>0 & sharpness<=1",
"Sharpness of curve bend.");
71 "Number of control points used to draw the curve. Minimum of degree+1 points are required.");
76 "edge_element_type", edge_elem_type,
"Type of the EDGE elements to be generated.");
78 "num_elements",
"num_elements>=1",
"Numer of elements to be drawn. Must be at least 1.");
82 "This BSplineMeshGenerator object is designed to generate a mesh of a curve that consists of " 83 "EDGE2, EDGE3, or EDGE4 elements drawn using an open uniform B-Spline.");
84 params.
addParam<std::vector<BoundaryName>>(
"edge_nodesets",
85 std::vector<BoundaryName>(),
86 "Nodeset name to give each edge of the spline curve");
93 _new_subdomain_id(getParam<
SubdomainID>(
"new_subdomain_id")),
94 _degree(getParam<unsigned
int>(
"degree")),
96 _num_cps(getParam<unsigned
int>(
"num_cps")),
97 _order((unsigned
int)(getParam<
MooseEnum>(
"edge_element_type")) + 1),
98 _num_elements(getParam<unsigned
int>(
"num_elements")),
99 _node_set_boundaries(getParam<
std::vector<BoundaryName>>(
"edge_nodesets")),
100 _start_mesh_input(getMesh(
"start_mesh", true)),
101 _end_mesh_input(getMesh(
"end_mesh", true))
104 paramError(
"num_cps",
"Number of control points must be at least degree+1.");
111 "boundary_providing_start_point must be specified if start_point is not");
113 paramError(
"start_mesh",
"start_mesh must be specified if start_point is not.");
119 "start_point and boundary_providing_start_point or start_mesh cannot be " 120 "simultaneously specified!");
123 "Starting direction must be specified if the 'start_point' is specified");
129 "boundary_providing_end_point must be specified if start_point is not");
131 paramError(
"end_mesh",
"end_mesh must be specified if start_point is not.");
137 "end_point and boundary_providing_end_point or end_mesh cannot be " 138 "simultaneously specified!");
141 "Ending direction must be specified if the 'end_point' is specified");
144 paramError(
"edge_nodesets",
"If specified, edge_nodesets must have exactly 2 entries.");
147 std::unique_ptr<MeshBase>
163 unsigned int half_cps;
169 mooseWarning(
"Need an even number of control points. `num_cps` has been decreased by 1.");
174 start_point, end_point, start_dir, end_dir, half_cps,
_sharpness);
182 std::vector<Node *> nodes(n_ts);
183 std::vector<Point> eval_points;
187 const auto t_current = ((
Real)i / (
Real)(n_ts - 1));
188 eval_points.push_back(b_spline.
getPoint(t_current));
195 std::unique_ptr<Elem> new_elem;
199 new_elem = std::make_unique<Edge2>();
202 new_elem = std::make_unique<Edge3>();
203 new_elem->set_node(2, nodes[i *
_order + 1]);
207 new_elem = std::make_unique<Edge4>();
208 new_elem->set_node(2, nodes[i *
_order + 1]);
209 new_elem->set_node(3, nodes[i *
_order + 2]);
213 new_elem->set_node(0, nodes[i *
_order]);
214 mooseAssert((i + 1) *
_order < nodes.size(),
"Out of bounds in nodes array");
215 new_elem->set_node(1, nodes[((i + 1) *
_order)]);
234 boundary_info.
add_node(*(nodes.end() - 1),
244 return getParam<Point>(
"start_point");
247 getParam<BoundaryName>(
"boundary_providing_start_point"), *
_start_mesh);
254 return getParam<Point>(
"end_point");
257 getParam<BoundaryName>(
"boundary_providing_end_point"), *
_end_mesh);
264 return getParam<RealVectorValue>(
"start_direction");
267 getParam<BoundaryName>(
"boundary_providing_start_point"), *
_start_mesh);
274 return getParam<RealVectorValue>(
"end_direction");
277 getParam<BoundaryName>(
"boundary_providing_end_point"), *
_end_mesh);
std::vector< BoundaryName > _node_set_boundaries
vector of the names of the boundaries at the ends of the spline curve
std::string & nodeset_name(boundary_id_type id)
RealVectorValue endDirection() const
Return the ending direction of the spline.
RealVectorValue boundaryWeightedNormal(const BoundaryName &boundary, MeshBase &mesh)
Calculates the side-volume weighted (side-vertex) average normal of a boundary on a mesh...
std::unique_ptr< ReplicatedMesh > buildReplicatedMesh(unsigned int dim=libMesh::invalid_uint)
Build a replicated mesh.
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 ...
const unsigned int _num_elements
number of edge elements on the curve
std::unique_ptr< MeshBase > _end_mesh
If 'end_mesh' parameter is set, mesh providing the ending boundary.
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
const unsigned int _order
order of the EDGE elements to be generated
const unsigned int _num_cps
number of control points to be generated
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
The following methods are specializations for using the libMesh::Parallel::packed_range_* routines fo...
const BoundaryInfo & get_boundary_info() const
RealVectorValue startDirection() const
Return the starting direction of the spline.
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
registerMooseObject("MooseApp", BSplineCurveGenerator)
std::unique_ptr< MeshBase > & _end_mesh_input
If 'end_mesh' parameter is set, reference to input mesh providing the ending boundary.
boundary_id_type get_id_by_name(std::string_view name) const
void mooseWarning(Args &&... args) const
void add_node(const Node *node, const boundary_id_type id)
static InputParameters validParams()
const Real _sharpness
sharpness of curve (measure of how close it is to the curve with three orthogonal segments) ...
virtual Elem * add_elem(Elem *e)=0
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Point endPoint() const
Return the ending point of the spline.
std::string & subdomain_name(subdomain_id_type id)
static InputParameters validParams()
BSplineCurveGenerator(const InputParameters ¶meters)
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.
libMesh::Point getPoint(const libMesh::Real t) const
Evaluate the BSpline interpolation at given value of t.
const unsigned int _degree
degree of interpolating spline
const SubdomainID _new_subdomain_id
Subdomain ID for the elements created.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Class implementing a uniform clamped B-Spline curve.
Point boundaryCentroidCalculator(const BoundaryName &boundary, MeshBase &mesh)
Calculates the centroid of a boundary on a mesh.
std::unique_ptr< MeshBase > _start_mesh
If 'start_mesh' parameter is set, mesh providing the starting boundary.
Point startPoint() const
Return the starting point of the spline.
IntRange< T > make_range(T beg, T end)
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Mesh generator to create a 1D B-spline curve mesh in 3D space.
MeshGenerators are objects that can modify or add to an existing mesh.
void ErrorVector unsigned int
std::unique_ptr< MeshBase > & _start_mesh_input
If 'start_mesh' parameter is set, reference to input mesh providing the starting boundary.