G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsBoehm.h
Go to the documentation of this file.
1 
14 #pragma once
15 
16 #include <gsCore/gsLinearAlgebra.h> // just for index_t
17 
18 namespace gismo
19 {
20 
21 
22 // =============================================================================
23 
24 // Inserting knots in B-splines.
25 
26 // =============================================================================
27 
28 
30 template<class T, class KnotVectorType, class Mat>
31 void gsBoehm(
32  KnotVectorType & knots,
33  Mat & coefs,
34  T val,
35  int r = 1,
36  bool update_knots = true
37  );
38 
39 
41 template<class T, class KnotVectorType, class Mat>
42 void gsBoehmSingle(
43  KnotVectorType & knots,
44  Mat & coefs,
45  T val,
46  bool update_knots = true
47  );
48 
49 
50 
53 template<class T, class iter, class Mat>
54 void 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 
64 template<class KnotVectorType, class Mat, class ValIt>
65 void 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.
98 template<typename T, typename KnotVectorType, typename Mat>
99 void 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.
130 template <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 
158 template <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 
187 template <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 
207 namespace bspline
208 {
209 
217 inline
218 int 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 
235 template<short_t d>
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 
260 template <typename T, typename KnotVectorType>
261 void 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 
293 inline
294 void getLastIndex(const gsVector<unsigned>& stride,
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 
324 template <typename T, typename KnotVectorType, typename ValIt,
325  typename newKnotsType>
326 void 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 
388 inline
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 
410 template<short_t d>
411 void getLastIndexLocal(const gsVector<index_t, d>& size_of_coef,
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 
427 template <short_t d>
428 void 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 
446 inline
447 unsigned 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
void gsBoehm(KnotVectorType &knots, Mat &coefs, T val, int r=1, bool update_knots=true)
Performs insertion of multiple knot on &quot;knots&quot; and coefficients &quot;coefs&quot;.
Definition: gsBoehm.hpp:29
void buildCoeffsStrides(const gsVector< index_t, d > &size_of_coefs, gsVector< index_t, d > &strides)
Definition: gsBoehm.h:428
T distance(gsMatrix< T > const &A, gsMatrix< T > const &B, index_t i=0, index_t j=0, bool cols=false)
compute a distance between the point number in the set and the point number &lt;j&gt; in the set ; by def...
#define short_t
Definition: gsConfig.h:35
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 gsBoehmRefine(KnotVectorType &knots, Mat &coefs, int p, ValIt valBegin, ValIt valEnd, bool update_knots=true)
Definition: gsBoehm.hpp:163
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 correctNewStride(gsVector< unsigned > &new_str, const gsVector< unsigned > &str, const int direction, const int r)
Definition: gsBoehm.h:389
#define index_t
Definition: gsConfig.h:32
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 getLastIndexLocal(const gsVector< index_t, d > &size_of_coef, gsVector< index_t, d > &last_point)
Definition: gsBoehm.h:411
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
void gsBoehmSingle(KnotVectorType &knots, Mat &coefs, T val, bool update_knots=true)
Performs knot insertion once on &quot;knots&quot; and coefficients &quot;coefs&quot;.
Definition: gsBoehm.hpp:95
void getLastIndex(const gsVector< unsigned > &stride, const unsigned number_of_points, gsVector< int > &last_point)
Definition: gsBoehm.h:294
GISMO_DEPRECATED index_t direction(index_t s)
Returns the parametric direction that corresponds to side s.
Definition: gsBoundary.h:1048
unsigned numberOfIterations(const gsVector< index_t > &nmb_of_coefs, const unsigned direction)
Definition: gsBoehm.h:447
This is the main header file that collects wrappers of Eigen for linear algebra.
EIGEN_STRONG_INLINE abs_expr< E > abs(const E &u)
Absolute value.
Definition: gsExpressions.h:4486
void gsTensorBoehm(KnotVectorType &knots, Mat &coefs, T val, int direction, gsVector< unsigned > str, int r=1, bool update_knots=true)
Definition: gsBoehm.hpp:245
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
int getIndex(const gsVector< unsigned > &stride, const gsVector< int > &position)
Definition: gsBoehm.h:218