G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsBoehm.h
Go to the documentation of this file.
1
14#pragma once
15
16#include <gsCore/gsLinearAlgebra.h> // just for index_t
17
18namespace gismo
19{
20
21
22// =============================================================================
23
24// Inserting knots in B-splines.
25
26// =============================================================================
27
28
30template<class T, class KnotVectorType, class Mat>
31void gsBoehm(
32 KnotVectorType & knots,
33 Mat & coefs,
34 T val,
35 int r = 1,
36 bool update_knots = true
37 );
38
39
41template<class T, class KnotVectorType, class Mat>
42void gsBoehmSingle(
43 KnotVectorType & knots,
44 Mat & coefs,
45 T val,
46 bool update_knots = true
47 );
48
49
50
53template<class T, class iter, class Mat>
54void gsBoehmSingle( iter knot, // Knot iterator
55 Mat & coefs, // Coefficients (p+1)
56 int p, // degree
57 T val // knot value to insert
58 );
59
60
64template<class KnotVectorType, class Mat, class ValIt>
65void gsBoehmRefine( KnotVectorType & knots,
66 Mat & coefs, //all Coefficients
67 int p, // degree
68 ValIt valBegin, ValIt valEnd, // knot values to insert
69 bool update_knots = true);
70
71
72
73// =============================================================================
74
75// Inserting knots in tensor-product B-splines.
76
77// =============================================================================
78
79
80
92// Algorithm is based on gsBoehm and THE NURBS BOOK.
93//
94// Some tests (for 2D and 3D) are written in gsTensorBoehm_test.
95//
96// Possible improvement: function builds new matrix for coefficient (11), so it
97// uses at least [2 * memory(coefs) + epsilon] memory.
98template<typename T, typename KnotVectorType, typename Mat>
99void gsTensorBoehm(
100 KnotVectorType& knots,
101 Mat& coefs,
102 T val,
103 int direction,
104 gsVector<unsigned> str,
105 int r = 1,
106 bool update_knots = true);
107
108
109
123//
124// Algorithm is based on gsBoehmRefine and THE NURBS BOOK
125//
126// Some tests (for 2D and 3D) are written in gsTensorBoehm_test
127//
128// Possible improvement: function builds new matrix for coefficients (!!), so it
129// uses at least [2 * memory(coefs) + epsilon] memory.
130template <typename KnotVectorType, typename Mat, typename ValIt>
132 KnotVectorType& knots,
133 Mat& coefs,
134 int direction,
135 gsVector<unsigned> str,
136 ValIt valBegin,
137 ValIt valEnd,
138 bool update_knots = true);
139
140
158template <short_t d, typename KnotVectorType, typename Mat, typename ValIt>
160 KnotVectorType& knots,
161 const unsigned index,
162 Mat& coefs,
163 gsVector<index_t, d>& nmb_of_coefs,
164 const gsVector<index_t, d>& act_size_of_coefs,
165 const gsVector<index_t, d>& size_of_coefs,
166 const unsigned direction,
167 ValIt valBegin,
168 ValIt valEnd,
169 const bool update_knots);
170
171
187template <short_t d, typename T, typename KnotVectorType, typename Mat>
189 const KnotVectorType& knots,
190 Mat& coefs,
191 const gsVector<index_t, d>& size_of_coefs,
192 T val,
193 const unsigned direction,
194 gsVector<index_t, d>& start,
195 gsVector<index_t, d>& end);
196
197
198
199// -----------------------------------------------------------------------------
200//
201// Helper functions
202//
203// -----------------------------------------------------------------------------
204
205
206
207namespace bspline
208{
209
217inline
218int getIndex(const gsVector<unsigned>& stride,
219 const gsVector<int>& position)
220{
221
222 GISMO_ASSERT(stride.size() == position.size(),
223 "stide size is not equal to dimension of coefficients size");
224
225 int ind = 0;
226 unsigned n = stride.size();
227
228 for (unsigned i = 0; i < n; ++i)
229 ind += static_cast<int>(stride[i]) * position[i];
230
231 return ind;
232}
233
234
235template<short_t d>
236index_t getIndex(const gsVector<index_t, d>& stride,
237 const gsVector<index_t, d>& position)
238{
239
240 index_t ind = 0;
241
242 for (short_t i = 0; i < d; ++i)
243 ind += stride[i] * position[i];
244
245 return ind;
246}
247
248
260template <typename T, typename KnotVectorType>
261void computeAlpha(std::vector< std::vector<T> >& alpha,
262 const KnotVectorType& knots,
263 T value,
264 int r,
265 int k,
266 int p,
267 int s)
268{
269
270 for (int j = 1; j <= r; ++j)
271 {
272 int L = k - p + j;
273 for (int i = 0; i <= p - j - s; ++i)
274 {
275 T knot_i = knots[L + i];
276 alpha[j - 1][i] = (value - knot_i) / (knots[i + k + 1] - knot_i);
277 }
278 }
279
280}
281
282
293inline
295 const unsigned number_of_points,
296 gsVector<int>& last_point
297 )
298{
299 index_t stride_length = stride.size();
300 for (index_t i = 0; i < stride_length; ++i)
301 {
302 if (i != stride_length - 1)
303 // we need to subtrack 1, because we need actual last index
304 last_point[i] = static_cast<int>(stride[i + 1] / stride[i]) - 1;
305 else
306 last_point[i] = static_cast<int>(number_of_points / stride[i]) - 1;
307 }
308
309}
310
311
324template <typename T, typename KnotVectorType, typename ValIt,
325 typename newKnotsType>
326void computeTensorAlpha(std::vector< std::vector<T> >& alpha,
327 newKnotsType& nknots,
328 const KnotVectorType& knots,
329 ValIt valBegin,
330 ValIt valEnd,
331 bool sparse = false)
332{
333 const int a = knots.iFind(*valBegin) - knots.begin();
334 const int b = (knots.iFind(*(valEnd - 1)) - knots.begin()) + 1;
335 const int p = knots.degree(); // degree
336 const int nik = std::distance(valBegin, valEnd); // number of inserted knots
337 const int nk = knots.size();
338
339 int i = b + p - 1;
340 int k = b + p + nik - 1; // nik - 1 == r
341
342 if (!sparse)
343 {
344 for (int j = 0; j <= a; j++)
345 nknots[j] = knots[j];
346
347 for (int j = b + p; j < nk; j++)
348 nknots[j + nik] = knots[j];
349 }
350
351
352 for (int j = nik - 1; 0 <= j; --j)
353 {
354 const T newKnot = *(--valEnd); // X[j]
355
356 // possible improvement: binary search instead of sequential
357 while ((newKnot <= knots[i]) && (a < i))
358 {
359 nknots[k] = knots[i];
360 k--;
361 i--;
362 }
363
364 for (int ell = 1; ell <= p; ell++)
365 {
366 T alfa = nknots[k + ell] - newKnot;
367 if (math::abs(alfa) != T(0.0))
368 alfa /= nknots[k + ell] - knots[i - p + ell];
369
370 alpha[j][ell - 1] = alfa;
371 }
372
373 nknots[k] = newKnot;
374 k--;
375 }
376}
377
378
388inline
390 const gsVector<unsigned>& str,
391 const int direction,
392 const int r)
393{
394 if (direction + 1 != str.size() )
395 {
396 new_str[direction + 1] += new_str[direction] * r;
397 }
398 for (index_t i = direction + 2; i < str.size(); ++i)
399 {
400 new_str[i] = new_str[i - 1] * (str[i] / str[i - 1]);
401 }
402}
403
404
410template<short_t d>
412 gsVector<index_t, d>& last_point)
413{
414 for (short_t i = 0; i < d; ++i)
415 {
416 last_point[i] = size_of_coef[i] - 1;
417 }
418}
419
420
427template <short_t d>
428void buildCoeffsStrides(const gsVector<index_t, d>& size_of_coefs,
429 gsVector<index_t, d>& strides)
430{
431 strides(0) = 1;
432 for (short_t dim = 1; dim < d; dim++)
433 strides(dim) = size_of_coefs(dim - 1) * strides(dim - 1);
434}
435
436
437
446inline
447unsigned numberOfIterations(const gsVector<index_t>& nmb_of_coefs,
448 const unsigned direction)
449{
450 unsigned nmb_of_iter = 1;
451 for (index_t i = 0; i < nmb_of_coefs.size(); ++i)
452 {
453 if (static_cast<unsigned>(i) != direction)
454 nmb_of_iter *= nmb_of_coefs[i];
455 }
456
457 return nmb_of_iter;
458}
459
460} //end namespace bspline
461
462} //end namespace gismo
463
464#ifndef GISMO_BUILD_LIB
465#include GISMO_HPP_HEADER(gsBoehm.hpp)
466#endif
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
void gsTensorBoehmRefine(KnotVectorType &knots, Mat &coefs, int direction, gsVector< unsigned > str, ValIt valBegin, ValIt valEnd, bool update_knots=true)
Definition gsBoehm.hpp:372
void gsTensorInsertKnotDegreeTimes(const KnotVectorType &knots, Mat &coefs, const gsVector< index_t, d > &size_of_coefs, T val, const unsigned direction, gsVector< index_t, d > &start, gsVector< index_t, d > &end)
Inserts knot val such that multiplicity of a val in knot vector is equal degree.
Definition gsBoehm.hpp:757
void gsTensorBoehmRefineLocal(KnotVectorType &knots, const unsigned index, Mat &coefs, gsVector< index_t, d > &nmb_of_coefs, const gsVector< index_t, d > &act_size_of_coefs, const gsVector< index_t, d > &size_of_coefs, const unsigned direction, ValIt valBegin, ValIt valEnd, const bool update_knots)
Local refinement algorithm.
Definition gsBoehm.hpp:501
void gsTensorBoehm(KnotVectorType &knots, Mat &coefs, T val, int direction, gsVector< unsigned > str, int r=1, bool update_knots=true)
Definition gsBoehm.hpp:245
#define short_t
Definition gsConfig.h:35
#define index_t
Definition gsConfig.h:32
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
This is the main header file that collects wrappers of Eigen for linear algebra.
void computeAlpha(std::vector< std::vector< T > > &alpha, const KnotVectorType &knots, T value, int r, int k, int p, int s)
Definition gsBoehm.h:261
unsigned numberOfIterations(const gsVector< index_t > &nmb_of_coefs, const unsigned direction)
Definition gsBoehm.h:447
void buildCoeffsStrides(const gsVector< index_t, d > &size_of_coefs, gsVector< index_t, d > &strides)
Definition gsBoehm.h:428
void getLastIndexLocal(const gsVector< index_t, d > &size_of_coef, gsVector< index_t, d > &last_point)
Definition gsBoehm.h:411
int getIndex(const gsVector< unsigned > &stride, const gsVector< int > &position)
Definition gsBoehm.h:218
void computeTensorAlpha(std::vector< std::vector< T > > &alpha, newKnotsType &nknots, const KnotVectorType &knots, ValIt valBegin, ValIt valEnd, bool sparse=false)
Definition gsBoehm.h:326
void getLastIndex(const gsVector< unsigned > &stride, const unsigned number_of_points, gsVector< int > &last_point)
Definition gsBoehm.h:294
void correctNewStride(gsVector< unsigned > &new_str, const gsVector< unsigned > &str, const int direction, const int r)
Definition gsBoehm.h:389
The G+Smo namespace, containing all definitions for the library.
void gsBoehm(KnotVectorType &knots, Mat &coefs, T val, int r=1, bool update_knots=true)
Performs insertion of multiple knot on "knots" and coefficients "coefs".
Definition gsBoehm.hpp:29
void gsBoehmSingle(KnotVectorType &knots, Mat &coefs, T val, bool update_knots=true)
Performs knot insertion once on "knots" and coefficients "coefs".
Definition gsBoehm.hpp:95
GISMO_DEPRECATED index_t direction(index_t s)
Returns the parametric direction that corresponds to side s.
Definition gsBoundary.h:1048
void gsBoehmRefine(KnotVectorType &knots, Mat &coefs, int p, ValIt valBegin, ValIt valEnd, bool update_knots=true)
Definition gsBoehm.hpp:163