https://mooseframework.inl.gov
Loading...
Searching...
No Matches
BSpline.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#include "BSpline.h"
12#include "MooseError.h"
13#include "SplineUtils.h"
14#include "Conversion.h"
15
16namespace Moose
17{
18BSpline::BSpline(const unsigned int degree,
19 const libMesh::Point & start_point,
20 const libMesh::Point & end_point,
21 const libMesh::RealVectorValue & start_direction,
22 const libMesh::RealVectorValue & end_direction,
23 const unsigned int cps_per_half,
24 const libMesh::Real sharpness,
25 const std::string & caller_name)
26 : _degree(degree),
27 _start_point(start_point),
28 _end_point(end_point),
29 _start_dir(start_direction),
30 _end_dir(end_direction),
31 _cps_per_half(cps_per_half),
32 _sharpness(sharpness),
33 _caller_name(caller_name),
34 _control_points(createControlPoints()),
35 _knot_vector(buildKnotVector())
36{
37}
38
41{
42 mooseAssert((t >= 0) && (t <= 1), "t should be in [0, 1]. t=" + std::to_string(t));
43 libMesh::Point returnPoint(0, 0, 0);
44 if (t == 1.0)
45 return _control_points.back();
46 for (const auto i : index_range(_control_points))
47 returnPoint += BSpline::CdBBasis(t, i, _degree) * _control_points[i];
48
49 return returnPoint;
50}
51
52std::vector<libMesh::Point>
54{
55 std::vector<libMesh::Point> cps;
59 return cps;
60}
61
62std::vector<libMesh::Real>
64{
65 std::vector<libMesh::Real> knot_vector(_degree, 0); // initialize bottom to zeros
66
67 const unsigned int num_points_left = _control_points.size() + 1 - _degree;
68 if (_control_points.size() < _degree + 1)
70 ": Number of control points must be greater than or equal to degree + 1!");
71
72 for (const auto i : make_range(num_points_left))
73 {
74 knot_vector.push_back(i); // count up
75 mooseAssert(i < _control_points.size(),
76 "i must be less than the number of control points because of 0 indexing.");
77 }
78
79 // Filling with int(degree + 1) 0s at the beginning and 1s at the end makes the B-spline go
80 // through the start and end point Note: the "+1" comes from the loop above which starts at 0 and
81 // ends at num_points_left - 1
82 for (const auto i : make_range(_degree))
83 {
84 libmesh_ignore(i);
85 knot_vector.push_back(num_points_left - 1);
86 }
87
88 // Normalize values s.t. the the max value is 1.
89 // This must be done to have a constant domain of t to be between 0 and 1 (inclusive).
90 // NOTE: the spacing is uniform, making this a uniform BSpline
91 for (auto & value : knot_vector)
92 {
93 value /= (num_points_left - 1);
94 mooseAssert(value <= 1.0 && value >= 0.0,
95 "knot_vector must be normalized to 1 with minimum value 0.");
96 }
97
98 return knot_vector;
99}
100
102BSpline::CdBBasis(const libMesh::Real t, const unsigned int i, const unsigned int j) const
103{
104 mooseAssert(i + 1 < _knot_vector.size(), "Out of bounds access in knot vector");
105 mooseAssert(_knot_vector[i] <= _knot_vector[i + 1],
106 "Knot vector is ill-formatted. Ensure values are increasing." +
108 if (j == 0)
109 return ((t < _knot_vector[i + 1]) && (_knot_vector[i] <= t)) ? 1 : 0;
110 else
111 return BSpline::firstCoeff(t, i, j) * BSpline::CdBBasis(t, i, j - 1) +
112 BSpline::secondCoeff(t, i, j) * BSpline::CdBBasis(t, i + 1, j - 1);
113}
114
116BSpline::firstCoeff(const libMesh::Real t, const unsigned int i, const unsigned int j) const
117{
118 mooseAssert(i + j < _knot_vector.size(), "Out of bounds access in knot vector");
119 const auto ti = _knot_vector[i];
120 const auto tij = _knot_vector[i + j];
121 if (ti != tij)
122 return (t - ti) / (tij - ti);
123 else
124 return 0;
125}
126
128BSpline::secondCoeff(const libMesh::Real t, const unsigned int i, const unsigned int j) const
129{
130 mooseAssert(i + j + 1 < _knot_vector.size(), "Out of bounds access in knot vector");
131 libMesh::Real ti1 = _knot_vector[i + 1];
132 libMesh::Real tij1 = _knot_vector[i + j + 1];
133 if (ti1 != tij1)
134 return (tij1 - t) / (tij1 - ti1);
135 else
136 return 0;
137}
138}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
const unsigned int _degree
The polynomial degree of the B-Spline.
Definition BSpline.h:85
libMesh::Real CdBBasis(const libMesh::Real t, const unsigned int i, const unsigned int j) const
Evaluates the the basis function for a B-Spline according to the Cox-de-Boor recursive formula.
Definition BSpline.C:102
libMesh::Point getPoint(const libMesh::Real t) const
Evaluate the BSpline interpolation at given value of t.
Definition BSpline.C:40
const std::vector< libMesh::Real > _knot_vector
The knot vector.
Definition BSpline.h:106
const libMesh::Real _sharpness
sharpness of the curve
Definition BSpline.h:97
libMesh::Real secondCoeff(const libMesh::Real t, const unsigned int i, const unsigned int j) const
Submethod used in CdBBasis routine.
Definition BSpline.C:128
const std::vector< libMesh::Point > _control_points
The control points.
Definition BSpline.h:102
const libMesh::Point _start_point
starting point of spline
Definition BSpline.h:87
BSpline(const unsigned int degree, 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, const std::string &caller_name)
Definition BSpline.C:18
const std::string _caller_name
Name of the object working with this class, used for error reporting.
Definition BSpline.h:100
const libMesh::Point _end_point
ending point of spline
Definition BSpline.h:89
libMesh::Real firstCoeff(const libMesh::Real t, const unsigned int i, const unsigned int j) const
Submethod used in CdBBasis routine.
Definition BSpline.C:116
const libMesh::RealVectorValue _end_dir
ending direction of spline
Definition BSpline.h:93
std::vector< libMesh::Real > buildKnotVector() const
Internal method for building the knot vector given the degree and control points.
Definition BSpline.C:63
const unsigned int _cps_per_half
number of control points per half of the spline (vertex is auto-included)
Definition BSpline.h:95
const libMesh::RealVectorValue _start_dir
starting direction of spline
Definition BSpline.h:91
std::vector< libMesh::Point > createControlPoints() const
Creates a vector control points from the SplineUtils set of functions.
Definition BSpline.C:53
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
std::string stringify(const T &t)
conversion to string
Definition Conversion.h:65
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, const std::string &caller_name)
Creates control points for an open uniform BSpline.
Definition SplineUtils.C:67
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real