G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsBoehm.hpp
Go to the documentation of this file.
1
14#pragma once
15
17
18namespace gismo
19{
20
26
27
28template<class T, class KnotVectorType, class Mat>
30 KnotVectorType & knots,
31 Mat & coefs,
32 T val,
33 int r,
34 bool update_knots
35 )
36{
37
38 GISMO_ASSERT( r >= 1, "Must insert at least one knot." );
39 if (r==1)
40 return gsBoehmSingle(knots, coefs, val, update_knots);
41
42 GISMO_ASSERT( coefs.rows() == (index_t)(knots.size() - knots.degree()-1),
43 "Incompatible coefficients("<<coefs.rows()
44 <<")/knots("<<knots.size()<<")/degree("<<knots.degree()<<")" ) ;
45
46 const int p = knots.degree();
47 typename KnotVectorType::uiterator kit = knots.uFind(val);
48 const int k = kit.lastAppearance();
49 // current multiplicity of val
50 const int s = (*kit == val || *(++kit)==val ? kit.multiplicity() : 0 );
51 /*
52 typename KnotVectorType::uiterator kit = knots.uFind(val);
53 int k = knots.iFind(val) - knots.begin();
54 int s = knots.multiplicity(val); // current multiplicity of val
55 */
56
57 GISMO_ASSERT( s + r < p + 2 , "Multiplicity can be at most deg+1 ("<<p+1<<")" );
58 int np= coefs.rows()-1;
59
60 Mat tmp = coefs.middleRows(k-p, p+1);
61 // resize coefficient matrix
62 coefs.conservativeResize( coefs.rows()+r, coefs.cols() );
63
64 // shift control points that are not affected
65 for( index_t i = np; i>=k-s; --i )
66 coefs.row(i+r) = coefs.row(i);
67
68 // Compute new control points
69 T a;
70 int L = 0;
71 for( index_t j = 1; j<=r; ++j )
72 {
73 L = k - p + j;
74
75 for( index_t i = 0; i<=p-j-s; ++i )
76 {
77 a = (val - knots[L+i]) / (knots[i+k+1] - knots[L+i]);
78 tmp.row(i) = a * tmp.row(i+1) + (1.0-a) * tmp.row(i);
79 }
80 coefs.row(L)= tmp.row(0);
81 coefs.row(k+r-j-s)= tmp.row(math::max(p-j-s,(index_t)0));
82 }
83 for( index_t i = L+1; i<k-s; ++i )
84 coefs.row(i) = tmp.row(i-L);
85 //coefs.middleRows(L+1, k-s-L-1) = tmp.
86
87 // Update knot vector
88 if ( update_knots )
89 knots.insert(val,r);
90}
91
92
93
94template<class T, class KnotVectorType, class Mat>
96 KnotVectorType & knots,
97 Mat & coefs,
98 T val,
99 bool update_knots
100 )
101{
102
103 GISMO_ASSERT( coefs.rows() == (index_t)(knots.size() - knots.degree()-1),
104 "Incompatible coefficients/knots" ) ;
105
106 int k = knots.iFind(val)-knots.begin();
107 int p = knots.degree();
108
109 coefs.duplicateRow( k );
110 // // resize coefficient matrix
111 //coefs.conservativeResize(coefs.rows() + 1, coefs.cols());
112 //
113 //for (index_t i = coefs.rows() - 1; i >= k+1; --i)
114 // coefs.row(i) = coefs.row(i-1);
115
116 // Compute new control points
117 T a;
118 for( index_t i = k; i>=k-p+1; --i )
119 {
120 a = (val - knots[i]) / (knots[i+p] - knots[i]);
121 coefs.row(i) = (T(1)-a) * coefs.row(i-1) + a * coefs.row(i);
122 }
123
124 // Update knot vector
125 if ( update_knots )
126 knots.insert(val);
127}
128
129
130
131template<class T, class iter, class Mat>
132void gsBoehmSingle( iter knot, // Knot iterator
133 Mat & coefs, // Coefficients (p+1)
134 int p, // degree
135 T val) // knot value to insert
136{
137 GISMO_ASSERT( coefs.rows() == p+1,
138 "Incompatible coefficients/knots" ) ;
139
140 knot++;
141
142 // resize coefficient matrix by adding one coefficient
143 coefs.conservativeResize( p+2, coefs.cols() );
144
145 // Shift coefficients by one place
146 // for (index_t i = p+1; i >= 1; --i)
147 // coefs.row(i) = coefs.row(i-1);
148 coefs.row(p+1) = coefs.row(p);
149
150 // Compute new control points
151 T a;
152 for( index_t i = p ; i>=1; --i )
153 {
154 a = (val - *knot) / ( *(knot+p) - *knot );
155 coefs.row(i) = (T(1)-a) * coefs.row(i-1) + a * coefs.row(i);
156 knot++;
157 }
158}
159
160
161
162template<class KnotVectorType, class Mat, class ValIt>
163void gsBoehmRefine( KnotVectorType & knots,
164 Mat & coefs, //all Coefficients
165 int p, // degree --remove
166 ValIt valBegin, ValIt valEnd, // knot values to insert
167 bool update_knots)
168{
169 if ( valBegin == valEnd ) return;
170
171 typedef typename std::iterator_traits<ValIt>::value_type T;
172
173 GISMO_ASSERT( (*valBegin >= knots[p]), "Value is before first knot: "
174 << *valBegin <<" < " <<knots[p] );
175 // && (val[val.size()-1]<=knots[knots.size()-p-1]));
176 //assert( knots[knots.size()-p-1]<=val[val.size()-1] );
177 const int np= coefs.rows();
178 const int nk= std::distance( valBegin, valEnd );
179 coefs.conservativeResize(np+nk, coefs.cols());
180
181 const int a = knots.iFind( *valBegin ) - knots.begin();
182 const int b = (knots.iFind( *(valEnd-1) ) - knots.begin()) + 1;
183 //const int a = knots.uFind(*valBegin).lastAppearance();
184 //const int b = knots.uFind(*(valEnd-1)).lastAppearance() + 1;
185
186 //gsKnotVector<T> nknots(p, knots.size()+nk);
187 std::vector<T> nknots(knots.size()+nk);
188
189 // shift control points that are not affected
190 for(index_t j = np ; j > b-1; j--)
191 coefs.row( j+nk-1) = coefs.row(j-1);
192
193 //std::copy( knots.begin(), knots.begin()+a+1,nknots.begin());
194 for(int j = 0; j <= a; j++)
195 nknots[j] = knots[j];
196 //std::copy( knots.begin()+b+p, knots.bend(),nknots.begin()+nk+b+p);
197 for(size_t j = b+p; j < knots.size(); j++)
198 nknots[j + nk] = knots[j];
199
200 int i = b + p - 1;
201 int k = b + p + nk-1;
202
203 for (int j = nk-1; j>=0; j--)
204 {
205 const T newKnot = *(--valEnd);
206
207 while( (newKnot <= knots[i]) && (i>a) )
208 {
209 coefs.row(k-p-1) = coefs.row(i-p-1);
210
211 nknots[k] = knots[i];
212 k-- ;
213 i-- ;
214 }
215
216 coefs.row(k-p-1) = coefs.row(k-p);
217
218
219 for(int l = 1 ; l <=p; l++)
220 {
221 const int ind = k-p+l;
222
223 T alfa = nknots[k+l] - newKnot;
224
225 if( math::abs(alfa) == T(0.0) )
226 coefs.row(ind-1) = coefs.row(ind);
227 else
228 {
229 alfa /= nknots[k+l]-knots[i-p+l];
230 coefs.row(ind-1) = alfa * coefs.row(ind-1) +
231 (1.0-alfa)*coefs.row(ind);
232 }
233 }
234 nknots[k] = newKnot;
235 k--;
236 }
237
238 if ( update_knots )
239 knots = KnotVectorType(p, nknots.begin(), nknots.end());
240 //knots.insert(valBegin, valEnd); // bug ?
241}
242
243
244template<typename T, typename KnotVectorType, typename Mat>
246 KnotVectorType& knots,
247 Mat& coefs,
248 T val,
249 const int direction,
251 int r,
252 bool update_knots)
253{
254 GISMO_ASSERT(1 <= r, "Can not make insertion r < 1 times");
255 GISMO_ASSERT(direction < str.size(),
256 "We can not insert a knot in a given direction");
257 GISMO_ASSERT(knots.first() < val && val < knots.last(),
258 "We can not insert a knot outside of the knot vector interval");
259
260 int d = str.size(); // dimension
261 int k = knots.iFind(val) - knots.begin();
262 int s = knots.multiplicity(val);
263 int p = knots.degree();
264
265
266 GISMO_ASSERT(s + r <= p,
267 "Multiplicity of a knot must be lower (or equal) "
268 "than a degree. Otherwise, we get non-continuous function.");
269
270 // we will compute new coefficients and put them new_coef matrix
271 int num_of_points = knots.size() - knots.degree() - 1;
272 unsigned points_to_add = (coefs.rows() / num_of_points) * r;
273 Mat new_coef = Mat(coefs.rows() + points_to_add, coefs.cols());
274
275 // we precompute alpha (variable we use in knot insertion algorithm)
276 std::vector< std::vector<T> > alpha(r, std::vector<T> (p - s));
277 computeAlpha<T, KnotVectorType>(alpha, knots, val, r, k, p, s);
278
279 // temporary matrix, for computation
280 Mat tmp(p + 1, coefs.cols());
281
282 // compute stride for new coefficients
283 gsVector<unsigned> new_str(str);
284 correctNewStride(new_str, str, direction, r);
285
286 // this two vectors will hold indices of current points
287 gsVector<int> position(d);
288 position.fill(0);
289 gsVector<int> new_position(position);
290
291 // necessary for computation of the indices
292 gsVector<int> first_point(position);
293 gsVector<int> last_point(d);
294 gsVector<int> new_last_point(d);
295 getLastIndex(str, coefs.rows(), last_point);
296 getLastIndex(new_str, new_coef.rows(), new_last_point);
297 last_point[direction] = 0;
298 new_last_point[direction] = 0;
299
300 int ind, new_ind; // actual indices (row of a coefs, new_coef)
301 unsigned step = str[direction];
302 unsigned new_step = new_str[direction];
303 bool flag = true; // safety flag
304
305 do
306 {
307 if (!flag)
308 GISMO_ERROR("This should not happened!"
309 "We do not have an index for the new matrix.");
310
311 ind = getIndex(str, position);
312 new_ind = getIndex(new_str, new_position);
313
314 // copy untouched points from the begining
315 for (int i = 0; i < k - p + 1; ++i)
316 {
317 new_coef.row(new_ind + i * new_step) = coefs.row(ind + i * step);
318 }
319
320 // make a temporary array of points
321 int tmp_ind = ind + step * (k - p);
322 for (int i = 0; i < p + 1; ++i)
323 {
324 tmp.row(i) = coefs.row(tmp_ind + step * i);
325 }
326
327 // compute new control points
328 int L = 0;
329 for (int j = 1; j <= r; ++j)
330 {
331 L = k - p + j;
332 for (int i = 0; i <= p - j - s; ++i)
333 {
334 T a = alpha[j - 1][i];
335 tmp.row(i) = a * tmp.row(i + 1) + (1.0 - a) * tmp.row(i);
336 }
337
338 new_coef.row(new_ind + new_step * L) = tmp.row(0);
339 new_coef.row(new_ind + new_step * (k + r - j - s)) =
340 tmp.row(p - j - s);
341 }
342
343 // put new control point into proper position
344 for (int i = L + 1; i < k - s; ++i)
345 {
346 new_coef.row(new_ind + step * i) = tmp.row(i - L);
347 }
348
349 // copy untouched points from the end
350 for (int i = k - s; i < num_of_points; ++i)
351 {
352 new_coef.row(new_ind + (i + r) * step) = coefs.row(ind + i * step);
353 }
354
355 flag = nextCubePoint<gsVector<int> >(new_position, first_point,
356 new_last_point);
357
358 } while(nextCubePoint<gsVector<int> >(position, first_point, last_point));
359
360
361 coefs = give(new_coef);
362
363 if (update_knots)
364 {
365 knots.insert(val, r);
366 }
367}
368
369
370
371template <typename KnotVectorType, typename Mat, typename ValIt>
373 KnotVectorType& knots,
374 Mat& coefs,
375 int direction,
377 ValIt valBegin,
378 ValIt valEnd,
379 bool update_knots)
380{
381
382 typedef typename std::iterator_traits<ValIt>::value_type T;
383
384 const int npts = coefs.rows(); // number of points
385 const int nik = std::distance(valBegin, valEnd); // number of inserted knots
386 const int nk = knots.size(); // number of knots
387 const int p = knots.degree(); // degree
388 const int d = str.size(); // dimension
389
390 GISMO_ASSERT(knots[p] <= *valBegin && *(valEnd - 1) <= knots[nk - p - 1],
391 "Can not insert knots, they are out of the knot range");
393 "We can not insert a knot in a given direction");
394
395 const int a = knots.iFind(*valBegin) - knots.begin();
396 const int b = (knots.iFind(*(valEnd - 1)) - knots.begin()) + 1;
397
398 // we compute new coefficients and put them into new_coef
399 int npts_in_dir = nk - p - 1; // number of points in direction d
400 int pts_to_add = (npts / npts_in_dir) * nik; // number of point we must add
401 Mat new_coefs = Mat(npts + pts_to_add, coefs.cols());
402
403 // allocate a memory for new knots and new control points
404 std::vector<T> nknots(nk + nik);
405
406 // compute stride for new coefficients
407 gsVector<unsigned> new_str(str);
408 correctNewStride(new_str, str, direction, nik);
409
410 gsVector<int> position(d); // position old points
411 for (int i = 0; i < d; ++i)
412 position[i] = 0;
413
414 gsVector<int> new_position(position); // position new points
415 gsVector<int> first_point(position); // first point of a cube
416 gsVector<int> last_point(d); // last point of a cube (old points)
417 gsVector<int> new_last_point(d); // last point of a cube (new points)
418
419 getLastIndex(str, npts, last_point);
420 getLastIndex(new_str, npts + pts_to_add, new_last_point);
421
422 last_point[direction] = 0;
423 new_last_point[direction] = 0;
424
425 int ind, new_ind;
426 const int step = str[direction];
427 const int new_step = new_str[direction];
428 bool flag = true;
429
430 // precompute alpha
431 std::vector< std::vector<T> > alpha(nik, std::vector<T> (p));
432 computeTensorAlpha<T, KnotVectorType, ValIt, std::vector<T> >
433 (alpha, nknots, knots, valBegin, valEnd);
434
435 do
436 {
437 ValIt valEndCopy = valEnd;
438
439 if (!flag)
440 GISMO_ERROR("This should not happened! "
441 "We do not have an index for the new matrix.");
442
443 ind = getIndex(str, position);
444 new_ind = getIndex(new_str, new_position);
445
446 // copy control points that are not affected
447 for (int j = 0; j <= a - p; ++j)
448 new_coefs.row(new_ind + j * new_step) = coefs.row(ind + j * step);
449 for (int j = npts_in_dir; b - 1 < j; --j)
450 new_coefs.row(new_ind + (j + nik - 1) * new_step) =
451 coefs.row(ind + (j - 1) * step);
452
453 // algorithm
454 int i = b + p - 1;
455 int k = b + p + nik - 1; // nik - 1 == r
456
457 for (int j = nik - 1; 0 <= j; j--)
458 {
459 const T newKnot = *(--valEndCopy);
460 while ((newKnot <= knots[i]) && (a < i))
461 {
462 new_coefs.row(new_ind + (k - p - 1) * new_step) =
463 coefs.row(ind + (i - p - 1) * step);
464 k--;
465 i--;
466 }
467
468 new_coefs.row(new_ind + (k - p - 1) * new_step) =
469 new_coefs.row(new_ind + (k - p) * new_step);
470
471 for (int ell = 1; ell <= p; ell++)
472 {
473 const T alfa = alpha[j][ell - 1];
474 const int index = k - p + ell;
475
476 if (math::abs(alfa) == T(0.0))
477 new_coefs.row(new_ind + (index - 1) * new_step) =
478 new_coefs.row(new_ind + index * new_step);
479 else
480 new_coefs.row(new_ind + (index - 1) * new_step) =
481 alfa * new_coefs.row(new_ind + (index - 1) * new_step) +
482 (1.0 - alfa) * new_coefs.row(new_ind + index * new_step);
483 }
484 k--;
485 }
486
487 flag = nextCubePoint<gsVector<int> >(new_position, first_point,
488 last_point);
489
490 } while(nextCubePoint<gsVector<int> >(position, first_point,
491 last_point));
492
493 coefs = give(new_coefs);
494
495 if (update_knots)
496 knots = KnotVectorType(p, nknots.begin(), nknots.end());
497}
498
499
500template <short_t d, typename KnotVectorType, typename Mat, typename ValIt>
501void gsTensorBoehmRefineLocal(KnotVectorType& knots,
502 const unsigned index,
503 Mat& coefs,
504 gsVector<index_t, d> &nmb_of_coefs,
505 const gsVector<index_t, d> &act_size_of_coefs,
506 const gsVector<index_t, d> &size_of_coefs,
507 const unsigned direction,
508 ValIt valBegin,
509 ValIt valEnd,
510 const bool update_knots)
511{
512
513 if (valBegin==valEnd)
514 return;
515
516 typedef typename std::iterator_traits<ValIt>::value_type T;
517
518 const index_t nik = std::distance(valBegin, valEnd); // number of inserted knots
519 const index_t p = knots.degree(); // degree
520 // number of original (not local) points
521 const index_t nopts = knots.size() - p - 1;
522 //const int d = size_of_coefs.size(); // dimension
523
524
525 const index_t a = knots.iFind(*valBegin) - knots.begin();
526 const index_t b = (knots.iFind(*(valEnd - 1)) - knots.begin()) + 1;
527
528 // allocate a memory for new knots and new control points
529 gsSparseVector<T> nknots(b + p + nik);
530
531
532 gsVector<index_t, d> position(d); // position old points
533 position.fill(0);
534
535 gsVector<index_t, d> first_point(position); // first point of a cube
536 gsVector<index_t, d> last_point(d); // last point of a cube (old points)
537 bspline::getLastIndexLocal<d>(nmb_of_coefs, last_point);
538 last_point[direction] = 0;
539
540 // build strides
541 gsVector<index_t, d> act_str(d);
542 bspline::buildCoeffsStrides<d>(act_size_of_coefs, act_str);
543
544 const index_t step = act_str[direction];
545
546 gsMatrix<T> zero(1, coefs.cols());
547 zero.fill(0.0);
548
549
550 // precompute alpha
551 std::vector< std::vector<T> > alpha(nik, std::vector<T> (p));
552 computeTensorAlpha<T, KnotVectorType, ValIt, gsSparseVector<T> >
553 (alpha, nknots, knots, valBegin, valEnd, true);
554
555 unsigned iterations = 0;
556 unsigned number_of_iterations = bspline::numberOfIterations(nmb_of_coefs,
557 direction);
558
559 do
560 {
561 if (number_of_iterations <= iterations)
562 break;
563 ++iterations;
564
565 ValIt valEndCopy = valEnd;
566
567 index_t ind = bspline::getIndex<d>(act_str, position);
568
569 for (index_t j = b - 1; j < nopts; j++)
570 {
571 index_t indx1 = j + nik - index;
572 index_t indx2 = j - index;
573
574 if (0 <= indx1 &&
575 indx1 < act_size_of_coefs[direction])
576 {
577 if (indx2 < 0)
578 coefs.row(ind + indx1 * step) = zero.row(0);
579 else
580 coefs.row(ind + indx1 * step) =
581 coefs.row(ind + indx2 * step);
582 }
583 }
584
585
586 int i = b + p - 1;
587 int k = b + p + nik - 1;
588
589 for (int j = nik - 1; 0 <= j; j--)
590 {
591 const T newKnot = *(--valEndCopy);
592
593 while ((newKnot <= knots[i]) && (a < i))
594 {
595 index_t indx1 = k - p - 1 - index;
596 index_t indx2 = i - p - 1 - index;
597
598 if (indx1 < 0 || act_size_of_coefs[direction] <= indx1)
599 {
600 k--;
601 i--;
602 continue;
603 }
604
605 if (indx2 < 0)
606 {
607 coefs.row(ind + indx1 * step) = zero.row(0);
608 }
609 else
610 {
611 coefs.row(ind + indx1 * step) =
612 coefs.row(ind + indx2 * step);
613 }
614 k--;
615 i--;
616 }
617
618 index_t indx1 = k - p - 1 - index;
619
620 if (0 <= indx1 && (indx1 + 1) < act_size_of_coefs[direction])
621 coefs.row(ind + indx1 * step) =
622 coefs.row(ind + (indx1 + 1) * step);
623
624 if (indx1 == act_size_of_coefs[direction] - 1)
625 coefs.row(ind + indx1 * step) = zero.row(0);
626
627 for (int ell = 1; ell <= p; ell++)
628 {
629 const T alfa = alpha[j][ell - 1];
630 const index_t mindex = k - p + ell - index;
631
632 if (mindex <= 0)
633 continue;
634
635 if (act_size_of_coefs[direction] < mindex)
636 break;
637
638 if (math::abs(alfa) == T(0.0))
639 {
640 if (mindex == act_size_of_coefs[direction])
641 coefs.row(ind + (mindex - 1) * step) = zero.row(0);
642 else
643 coefs.row(ind + (mindex - 1) * step) =
644 coefs.row(ind + mindex * step);
645 }
646 else
647 {
648 if (mindex == act_size_of_coefs[direction])
649 coefs.row(ind + (mindex - 1) * step) =
650 alfa * coefs.row(ind + (mindex - 1) * step);
651 else
652 coefs.row(ind + (mindex - 1) * step) =
653 alfa * coefs.row(ind + (mindex - 1) * step) +
654 (1.0 - alfa) * coefs.row(ind + mindex * step);
655 }
656 }
657 k--;
658 }
659 } while(nextCubePoint<gsVector<index_t, d> >(position, first_point,
660 last_point));
661
662 nmb_of_coefs[direction] = size_of_coefs[direction];
663
664 if (update_knots)
665 {
666 for (ValIt knot_iter = valBegin; knot_iter != valEnd; ++knot_iter)
667 knots.insert(*knot_iter, 1);
668 }
669}
670
671/*
672This function performs local Tensor Boehm algorithm. It works.
673
674template <short_t d, typename T, typename KnotVectorType, typename Mat>
675void gsTensorBoehmLocal(
676 const KnotVectorType& knots,
677 unsigned index,
678 Mat& coefs,
679 const gsVector<unsigned, d>& size_of_coefs,
680 const gsVector<unsigned, d>& act_size_of_coefs,
681 T val,
682 unsigned direction,
683 unsigned multiplicity,
684 gsVector<unsigned, d>& start,
685 gsVector<unsigned, d>& end)
686{
687 int k = knots.findspan(val);
688 int s = knots.multiplicity(val);
689 int p = knots.degree();
690
691 const unsigned r = multiplicity;
692
693 std::vector<std::vector<T> > alpha(r, std::vector<T> (p - s));
694 computeAlpha<T, KnotVectorType>(alpha, knots, val, r, k, p, s);
695
696 // temporary matrix, for computation
697 gsVector<unsigned, d> act_coefs_str(d);
698 bspline::buildCoeffsStrides<d>(act_size_of_coefs, act_coefs_str);
699
700 start(direction) = 0;
701 end(direction) = 0;
702 gsVector<unsigned, d> position(start);
703
704
705 unsigned step = act_coefs_str[direction];
706
707 do
708 {
709 const unsigned flat_ind = bspline::getIndex<d>(act_coefs_str, position);
710
711
712 int low = k - s - index;
713 for (int j = size_of_coefs(direction) - 1; low <= j; --j)
714 coefs.row(flat_ind + (j + r) * step) =
715 coefs.row(flat_ind + j * step);
716
717 Mat tmp(p + 1, coefs.cols());
718 for (int j = 0; j < p + 1; j++)
719 {
720 tmp.row(j) = coefs.row(flat_ind + (k - p + j - index) * step);
721 }
722
723 int L = 0;
724 for (unsigned j = 1; j <= r; j++)
725 {
726 L = k - p + j;
727
728 for (unsigned i = 0; i <= p - j - s; i++)
729 {
730 T alfa = alpha[j - 1][i];
731 tmp.row(i) = alfa * tmp.row(i + 1) + (1.0 - alfa) * tmp.row(i);
732
733// if (ind < 0)
734// continue;
735// else if (ind == static_cast<int>(act_size_of_coefs(direction)) - 1)
736// coefs.row(flat_ind + (ind * step) =
737// (1 - alfa) * coefs.row(flat_ind + ind * step);
738// else
739// {
740// coefs.row(flat_ind + (ind + 1) * step) =
741// alfa * coefs.row(flat_ind + (ind + 1) * step) +
742// (1.0 - alfa) * coefs.row(flat_ind + ind * step);
743 // }
744 }
745
746 coefs.row(flat_ind + (L - index) * step) = tmp.row(0);
747 coefs.row(flat_ind + (k + r - j - s - index) * step) =
748 tmp.row(p - j - s);
749
750 }
751 } while(nextCubePoint<gsVector<unsigned, d> >(position, start, end));
752}
753*/
754
755
756template <short_t d, typename T, typename KnotVectorType, typename Mat>
758 const KnotVectorType& knots,
759 Mat& coefs,
760 const gsVector<index_t, d>& size_of_coefs,
761 T val,
762 unsigned direction,
765{
766 int k = knots.iFind(val) - knots.begin();
767 int s = knots.multiplicity(val);
768 int p = knots.degree();
769
770 // if multiplicity is greater than degree, we insert no knots
771 if (p <= s)
772 return;
773
774 const unsigned r = p - s; // how many times we will insert the knot val
775
776 std::vector<std::vector<T> > alpha(r, std::vector<T> (p - s));
777 computeAlpha<T, KnotVectorType>(alpha, knots, val, r, k, p, s);
778
779 gsVector<index_t, d> coefs_str(d);
780 bspline::buildCoeffsStrides<d>(size_of_coefs, coefs_str);
781
782 start(direction) = 0;
783 end(direction) = 0;
784 gsVector<index_t, d> position(start);
785
786 unsigned step = coefs_str[direction];
787
788 do
789 {
790 const unsigned flat_ind = bspline::getIndex<d>(coefs_str, position);
791 for (unsigned j = 1; j <= r; j++)
792 {
793 for (unsigned i = 0; i <= p - j - s; i++)
794 {
795 T alfa = alpha[j - 1][i];
796 coefs.row(flat_ind + i * step) =
797 alfa * coefs.row(flat_ind + (i + 1) * step) +
798 (1.0 - alfa) * coefs.row(flat_ind + i * step);
799 }
800 }
801 } while(nextCubePoint<gsVector<index_t, d> >(position, start, end));
802}
803
804} // namespace gismo
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
Sparse vector class, based on gsEigen::SparseVector.
Definition gsSparseVector.h:35
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
bool nextCubePoint(Vec &cur, const Vec &end)
Iterate in lexigographic order through the points of the integer lattice contained in the cube [0,...
Definition gsCombinatorics.h:327
Provides combinatorial unitilies.
#define index_t
Definition gsConfig.h:32
#define GISMO_ERROR(message)
Definition gsDebug.h:118
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
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
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
S give(S &x)
Definition gsMemory.h:266
void gsBoehmRefine(KnotVectorType &knots, Mat &coefs, int p, ValIt valBegin, ValIt valEnd, bool update_knots=true)
Definition gsBoehm.hpp:163