G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsHBSplineBasis.hpp
1 
14 #pragma once
15 
17 
18 #include <gsIO/gsXml.h>
20 
21 namespace gismo
22 {
23 
24 /*
25 template<short_t d, class T>
26 gsHBSplineBasis<d,T>::gsHBSplineBasis(gsBSplineBasis<T> & bsbasis)
27  : gsHTensorBasis<d,T>( gsTensorBSplineBasis<d,T>(&bsbasis) )
28 {
29  // Note: The compiler adds automatically a return statement
30  // at the end of each constructor. Throwing an exception
31  // causes this return statement to be unreachable, and
32  // warning 4702 is emitted. To stop this warning we add
33  // "bsbasis.dim()==1", which is not known at compile time
34  GISMO_ASSERT(d==1, "Wrong dimension");
35 }
36 */
37 
38 template<short_t d, class T>
39 typename gsHBSplineBasis<d,T>::BoundaryBasisType * gsHBSplineBasis<d,T>::basisSlice(index_t dir_fixed,T par ) const
40 {
41  GISMO_ASSERT(d-1>=0,"d must be greater or equal than 1");
42  GISMO_ASSERT(dir_fixed>=0 && static_cast<index_t>(dir_fixed)<d,"cannot fix a dir greater than dim or smaller than 0");
43  const boxSide side(dir_fixed,0);
44  const typename gsTensorBSplineBasis<d,T>::BoundaryBasisType::uPtr bBSplineBasis =
45  this->m_bases[0]->boundaryBasis(side);
46  typename gsHBSplineBasis<d,T>::BoundaryBasisType* bBasis =
47  new typename gsHBSplineBasis<d,T>::BoundaryBasisType(*bBSplineBasis);
48 
49  if(d!=1)
50  {
51  std::vector<index_t> boxes;
52  this->getBoxesAlongSlice(dir_fixed,par,boxes);
53  bBasis->refineElements(boxes);
54  }
55 
56  return bBasis;
57 }
58 
59 template<short_t d, class T>
60 std::ostream & gsHBSplineBasis<d,T>::print(std::ostream &os) const
61 {
62  os << "Hierarchical B-spline ";
64  //this->printCharMatrix(os);
65  return os;
66 }
67 
68 
69 template<short_t d, class T>
71 {
72  // Sets everything related to gsHTensorBasis
73  // this->update_structure(); // base class update
74 }
75 
76 template<short_t d, class T>
78 {
79  int lvl = this->levelOf(i);
80  this->m_bases[lvl]->evalSingle_into(
81  this->m_xmatrix[lvl][ i - this->m_xmatrix_offset[lvl] ], u, result);
82 }
83 
84 template<short_t d, class T>
86 {
87  int lvl = this->levelOf(i);
88  this->m_bases[lvl]->derivSingle_into(
89  this->m_xmatrix[lvl][ i - this->m_xmatrix_offset[lvl] ], u, result);
90 }
91 
92 template<short_t d, class T>
94 {
95  int lvl = this->levelOf(i);
96  this->m_bases[lvl]->deriv2Single_into(
97  this->m_xmatrix[lvl][ i - this->m_xmatrix_offset[lvl] ], u, result);
98 }
99 
100 template<short_t d, class T>
102 {
103  gsVector<index_t> nact;
104  gsMatrix<index_t> act;
105  // Get the number of active functions
106  this->numActive_into(u, nact);
107  // Set everything to zero
108  result.setZero(nact.maxCoeff(), u.cols());
109 
110  gsMatrix<T> curr_res;
111  for(index_t j = 0; j < u.cols(); j++) // for all points
112  {
113  const gsMatrix<T> & curr_u = u.col(j);
114 
115  // Compute the indices of active functions on curr_u
117 
118  // for all actives on the point
119  for(index_t i = 0; i != act.rows(); i++)
120  {
121  gsHBSplineBasis<d,T>::evalSingle_into( act(i,0), curr_u, curr_res );
122  result(i,j) = curr_res(0,0);
123  }
124  }
125 }
126 
127 template<short_t d, class T>
129 {
130  gsVector<index_t> nact;
131  gsMatrix<index_t> act;
132  // Get the number of active functions
133  this->numActive_into(u, nact);
134  // Set everything to zero
135  result.setZero( d*nact.maxCoeff(), u.cols() );
136 
137  gsMatrix<T> curr_res;
138  for(index_t j = 0; j < u.cols(); j++) // for all points
139  {
140  const gsMatrix<T> & curr_u = u.col(j);
141 
142  // Compute the indices of active functions on curr_u
144 
145  // for all actives on the point
146  for(index_t i = 0; i < act.rows(); i++)
147  {
148  gsHBSplineBasis<d,T>::derivSingle_into( act(i,0), curr_u, curr_res );
149  result.block(i*d,j,d,1).noalias() = curr_res;
150  }
151  }
152 }
153 
154 template<short_t d, class T>
156 {
157  gsVector<index_t> nact;
158  gsMatrix<index_t> act;
159 
160  const int blocksize = d*(d + 1)/2;
161 
162  // Get the number of active functions
163  this->numActive_into(u, nact);
164  result.resize( blocksize * nact.maxCoeff(), u.cols() );
165  // Set everything to zero
166  result.setZero();
167 
168  // Current result for u.col(j)
169  gsMatrix<T> curr_res;
170 
171  for(index_t j = 0; j < u.cols(); j++) // for all points
172  {
173  const gsMatrix<T> & curr_u = u.col(j);
174 
175  // Compute the indices of active functions on curr_u
177 
178  // for all actives at the point
179  for(index_t i = 0; i < act.rows(); i++)
180  {
181  gsHBSplineBasis<d,T>::deriv2Single_into( act(i,0), curr_u, curr_res );
182  result.block(i*blocksize,j,blocksize,1) = curr_res;
183  }
184  }
185 }
186 
187 template<short_t d, class T>
189 {
190  result.clear();
191  //gsVector<index_t> level;
192  //gsMatrix<index_t> b1, b2; //boxes in highest level numbering
193  //this->m_tree.getBoxesInLevelIndex(b1, b2, level);//return boxes in level indices
194  tensorBasis curTensorlvl = this->tensorLevel(0);
195  //std::vector< gsSparseMatrix<T,RowMajor> > transfer(this->maxLevel());
197  std::vector<std::vector<T> > knots(d);
198 
199  std::vector<CMatrix> xmatLvl_i, xmatLvl_i1;
200 
201  this->setActiveToLvl(0, xmatLvl_i );
202 
203  for(unsigned i = 1; i <= this->maxLevel(); ++i)
204  {
205  for(unsigned dim = 0; dim != d; ++dim)
206  {
207  const gsKnotVector<T> & ckv = m_bases[i-1]->knots(dim);
208  const gsKnotVector<T> & fkv = m_bases[i ]->knots(dim);
209  ckv.symDifference(fkv, knots[dim]);
210 
211  // equivalent (dyadic ref.):
212  // ckv.getUniformRefinementKnots(1, knots[dim]);
213  }
214 
215  curTensorlvl.refine_withTransfer(transfer, knots);
216 
217  this->setActiveToLvl(i, xmatLvl_i1);
218 
219  const gsSparseMatrix<T> crs = this->coarsening(xmatLvl_i, xmatLvl_i1, transfer);
220  result.push_back(crs);
221 
222  xmatLvl_i.swap(xmatLvl_i1);
223  }
224 }
225 
226 
227 template<short_t d, class T>
229 {
230  int size1= 0;int size2 = 0;
231  int glob_numb = 0;//continous numbering of hierarchical basis
232  for(unsigned int i =0; i< old.size();i++){//count the number of basis functions in old basis
233  size1 += old[i].size();
234  }
235  for(unsigned int i =0; i< n.size();i++){//count the number of basis functions in new basis
236  size2 += n[i].size();
237  }
238  gsSparseMatrix<T> result(size2,size1);
239 
240  //gsMatrix<T> transferDense = transfer;
241  gsSparseMatrix<T,ColMajor> temptransfer = transfer;
242 // gsDebug<<"size1 "<<size1<<" size2 "<<size2<<std::endl;
243 // gsDebug<<"temptransfer.rows"<< temptransfer.rows()<<" cols "<<temptransfer.cols();
244  for (unsigned int i = 0; i < old.size(); i++)//iteration through the levels of the old basis
245  {
246  // find starting index of level i in new basis
247  int start_lv_i = 0;
248  for(unsigned int l =0; l < i; l++)
249  {
250  start_lv_i += n[l].size();
251  }
252 
253  for (unsigned int j = 0; j < old[i].size();j++)//iteration through the basis functions in the given level
254  {
255 // gsDebug<<"function "<<j<<std::endl;
256  const unsigned old_ij = old[i][j]; // tensor product index
257 
258  if( n[i].bContains(old_ij) )//it he basis function was not refined
259  {
260  result(start_lv_i + std::distance(n[i].begin(), n[i].find_it_or_fail(old_ij) ),glob_numb ) = 1;//settign the coefficient of the not refined basis function to 1
261  }
262  else
263  {
264 // TODO delete if the spafce matrix version is tested
265 // for(int k = 0; k < transferDense.rows(); k++)//basis function was refined->looking for the coeficinets from the global transfer matrix
266 // {
267 // if(transferDense(k, old_ij) != 0)//if the coefficient is non zero we find the coresponding function in n
268 // {
269 // const int pos = start_lv_i + n[i].size() + std::distance(n[i+1].begin(), n[i+1].find_it_or_fail(k));
270 // result(pos,glob_numb) = transferDense(k, old_ij);
271 // }
272 // }
273  for(typename gsSparseMatrix<T,ColMajor>::InnerIterator k(temptransfer,old_ij); k; ++k)//basis function was refined->looking for the coeficinets from the global transfer matrix
274  {
275 
276  //if(transferDense(k, old_ij) != 0)//if the coefficient is non zero we find the coresponding function in n
277  //{
278  const int pos = start_lv_i + n[i].size() + std::distance(n[i+1].begin(), n[i+1].find_it_or_fail(k.row()));
279  result(pos,glob_numb) = k.value();//transferDense(k, old_ij);
280  //}
281  }
282  }
283  glob_numb++;
284  }
285  }
286  return result;
287 }
288 
289 template<short_t d, class T>
290 gsSparseMatrix<T> gsHBSplineBasis<d,T>::coarsening_direct( const std::vector<gsSortedVector<index_t> >& old, const std::vector<gsSortedVector<index_t> >& n, const std::vector<gsSparseMatrix<T,RowMajor> >& transfer) const
291 {
292  int size1= 0;int size2 = 0;
293  int glob_numb = 0;//continous numbering of hierarchical basis
294  for(unsigned int i =0; i< old.size();i++){//count the number of basis functions in old basis
295  size1 += old[i].size();
296  }
297  for(unsigned int i =0; i< n.size();i++){//count the number of basis functions in new basis
298  size2 += n[i].size();
299  }
300  gsSparseMatrix<T> result(size2,size1);
301 
302 
303 // std::vector<gsMatrix<T> > transferDense;// = transfer;
304 // transferDense.resize(transfer.size());
305 // for (unsigned int i = 0; i < transfer.size();i++){
306 // transferDense[i] = transfer[i];
307 // }
308  std::vector<gsSparseMatrix<T,ColMajor> > temptransfer;// = transfer;
309  temptransfer.resize(transfer.size());
310  for (unsigned int i = 0; i < transfer.size();i++){
311  temptransfer[i] = transfer[i];
312  }
313 
314  for (unsigned int i = 0; i < old.size(); i++)//iteration through the levels of the old basis
315  {
316  // find starting index of level i in new basis
317  int start_lv_i = 0;
318  for(unsigned int l =0; l < i; l++)
319  {
320  start_lv_i += n[l].size();
321  }
322 
323 
324  for (unsigned int j = 0; j < old[i].size();j++)//iteration through the basis functions in the given level
325  {
326 
327  start_lv_i = 0;
328  for(unsigned int l =0; l < i; l++)
329  {
330  start_lv_i += n[l].size();
331  }
332  const unsigned old_ij = old[i][j]; // tensor product index
333 
334  if( n[i].bContains(old_ij) )//it he basis function was not refined
335  {
336  result(start_lv_i + std::distance(n[i].begin(), n[i].find_it_or_fail(old_ij) ),glob_numb ) = 1;//settign the coefficient of the not refined basis function to 1
337  }
338  else
339  {
340  std::vector<lvl_coef> coeffs;
341  lvl_coef temp;
342  temp.pos = old_ij;
343  temp.coef = 1;
344  temp.lvl = i;
345  coeffs.push_back(temp);
346  for (size_t coeff_index = 0; coeff_index < coeffs.size(); ++coeff_index)
347  {
348  const lvl_coef coeff = coeffs[coeff_index];
349 
350  start_lv_i = 0;
351  for(unsigned int l =0; l < coeff.lvl; l++)
352  {
353  start_lv_i += n[l].size();
354  }
355 
356  for(typename gsSparseMatrix<T,ColMajor>::InnerIterator k(temptransfer[coeff.lvl],coeff.pos); k; ++k)//basis function was refined->looking for the coeficinets from the global transfer matrix
357  {
358  if(n[coeff.lvl+1].bContains(k.row()))
359  {
360  //gsDebug<<"j: "<<j<<" "<<"oldij"<<old_ij<<"k.row() "<<k.row()<<" ";
361  //gsDebug<<"j: "<<j<<" "<<"globnumb "<<glob_numb<<" "<<" coef "<< coeff.coef * temptransfer[coeff.lvl](k.row(), coeff.pos)<<" ";
362  const int pos = start_lv_i + n[coeff.lvl].size() + std::distance(n[coeff.lvl+1].begin(), n[coeff.lvl+1].find_it_or_fail(k.row()));
363  //gsDebug<<"pos:"<<pos<<std::endl;
364  //double ppp = transferDense[coeff.lvl](k, coeff.pos);
365  result(pos,glob_numb) += coeff.coef * temptransfer[coeff.lvl](k.row(), coeff.pos);//transferDense[coeff.lvl](k, coeff.pos);
366  }else
367  {
368  temp.pos = k.row();
369  temp.coef = temptransfer[coeff.lvl](k.row(), coeff.pos) * coeff.coef;
370  temp.lvl = coeff.lvl+1;
371  coeffs.push_back(temp);
372  }
373  }
374 
375 // for(unsigned int ii = 0; ii < coeffs.size();ii++){
376 // gsDebug<<"( "<< coeffs[ii].pos<<" , "<<coeffs[ii].coef<<" , "<<coeffs[ii].lvl<<" )"<<std::endl;
377 // }
378  }
379  }
380  glob_numb++;
381  }
382  }
383  return result;
384 }
385 
386 template<short_t d, class T>
387 gsSparseMatrix<T> gsHBSplineBasis<d,T>::coarsening_direct2( const std::vector<gsSortedVector<index_t> >& old,
388  const std::vector<gsSortedVector<index_t> >& n,
389  const std::vector<gsSparseMatrix<T,RowMajor> >& transfer) const
390 {
391  int size1 = 0, size2 = 0;
392  int glob_numb = 0;//continous numbering of hierarchical basis
393  for(unsigned int i =0; i< old.size();i++){//count the number of basis functions in old basis
394  size1 += old[i].size();
395  }
396  for(unsigned int i =0; i< n.size();i++){//count the number of basis functions in new basis
397  size2 += n[i].size();
398  }
399  gsSparseMatrix<T> result(size2,size1);
400 
401 
402 // std::vector<gsMatrix<T> > transferDense;// = transfer;
403 // transferDense.resize(transfer.size());
404 // for (unsigned int i = 0; i < transfer.size();i++){
405 // transferDense[i] = transfer[i];
406 // }
407  std::vector<gsSparseMatrix<T,ColMajor> > temptransfer;// = transfer;
408  temptransfer.resize(transfer.size());
409  for (unsigned int i = 0; i < transfer.size();i++){
410  temptransfer[i] = transfer[i];
411  //gsDebug<<"transfer"<<i<<"\n"<<transfer[i]<<std::endl;
412  }
413 
414  for (unsigned int i = 0; i < old.size(); i++)//iteration through the levels of the old basis
415  {
416  // find starting index of level i in new basis
417  int start_lv_i = 0;
418  for(unsigned int l =0; l < i; l++)
419  {
420  start_lv_i += n[l].size();
421  }
422 
423 
424  for (unsigned int j = 0; j < old[i].size();j++)//iteration through the basis functions in the given level
425  {
426  //gsDebug<<"j = "<<j<<std::endl;
427  start_lv_i = 0;
428  for(unsigned int l =0; l < i; l++)
429  {
430  start_lv_i += n[l].size();
431  }
432  const unsigned old_ij = old[i][j]; // tensor product index
433 
434  if( n[i].bContains(old_ij) )//it he basis function was not refined
435  {
436  result(start_lv_i + std::distance(n[i].begin(), n[i].find_it_or_fail(old_ij) ),glob_numb ) = 1;//settign the coefficient of the not refined basis function to 1
437  }
438  else
439  {
440 
441  gsMatrix<index_t, d, 2> supp(d, 2);
442  this->m_bases[i]->elementSupport_into(old_ij, supp);//this->support(start_lv_i+old_ij);
443  //gsDebug<<"supp "<< supp<<std::endl;
444  //unsigned max_lvl = math::min<index_t>( this->m_tree.query4(supp.col(0),supp.col(1), i), transfer.size() ) ;
445  gsSparseVector<T,RowMajor> t(this->m_bases[i]->size());
446  t.setZero();
447  t[old_ij] = 1;
448  //gsDebug<<"j = "<<j<<std::endl;
449  //gsDebug<<"nsize"<<n.size()<<std::endl;
450  for(unsigned int k = i+1; k < n.size();k++){
451  start_lv_i = 0;
452  for(unsigned int l =0; l < k-1; l++)
453  {
454  start_lv_i += n[l].size();
455  }
456 // gsDebug<<"k "<<k<<std::endl;
457 // gsDebug<<"nk"<<std::endl;
458 // for(int a = 0; a < n[k].size();a++){
459 // gsDebug<<n[k][a]<<" ";
460 // }
461  //gsDebug<<std::endl;
462  gsSparseVector<T,RowMajor> M;
463  M.setZero();
464  M = temptransfer[k-1] * t.transpose();
465 
466  //gsDebug<<"M\n"<<M<<std::endl;
467  for(int l = 0 ; l < M.size();l++)
468  //for(typename gsSparseVector<T,RowMajor>::InnerIterator l(M); l; ++l)//basis function was refined->looking for the coeficinets from the global transfer matrix
469  {
470  if(M[l]!=0)
471  if(n[k].bContains(l))
472  {
473  //gsDebug<<"j: "<<j<<" "<<"oldij"<<old_ij<<" "<<"l:"<<l<<" ";
474  //gsDebug<<"k "<<k<<" j: "<<j<<" "<<"globnumb "<<glob_numb<<" "<<"l:"<<l<<" "<<M[l]<<" ";
475  const int pos = start_lv_i + n[k-1].size() + std::distance(n[k].begin(), n[k].find_it_or_fail(l));
476  //gsDebug<<"pos:"<<pos<<std::endl;
477  //double ppp = transferDense[coeffs[0].lvl](k, coeffs[0].pos);
478  result(pos,glob_numb) = M[l];//transferDense[coeffs[0].lvl](k, coeffs[0].pos);
479  M[l] = 0;
480  //const int pos = start_lv_i + n[coeffs[0].lvl].size() + std::distance(n[coeffs[0].lvl+1].begin(), n[coeffs[0].lvl+1].find_it_or_fail(k.row()));
481  //double ppp = transferDense[coeffs[0].lvl](k, coeffs[0].pos);
482  //result(pos,glob_numb) += coeffs[0].coef * temptransfer[coeffs[0].lvl](k.row(), coeffs[0].pos);//transferDense[coeffs[0].lvl](k, coeffs[0].pos);
483  }
484  }
485  t = M;
486  //gsDebug<<"M after \n"<<M<<std::endl;
487  }
488  }
489  glob_numb++;
490  }
491 
492  }
493 
494  return result;
495 }
496 namespace internal
497 {
498 
500 template<short_t d, class T>
501 class gsXml< gsHBSplineBasis<d,T> >
502 {
503 private:
504  gsXml() { }
505 public:
506  GSXML_COMMON_FUNCTIONS(gsHBSplineBasis<TMPLA2(d,T)>);
507  static std::string tag () { return "Basis"; }
508  static std::string type () { return "HBSplineBasis"+ (d>1 ? to_string(d):""); }
509 
510  static gsHBSplineBasis<d,T> * get (gsXmlNode * node)
511  {
512  return getHTensorBasisFromXml< gsHBSplineBasis<d,T> > (node);
513  }
514 
515  static gsXmlNode * put (const gsHBSplineBasis<d,T> & obj,
516  gsXmlTree & data )
517  {
518  return putHTensorBasisToXml< gsHBSplineBasis<d,T> > (obj, data);
519  }
520 };
521 
522 }
523 
524 
525 }// namespace gismo
Provides definition of HTensorBasis abstract interface.
void deriv2Single_into(index_t i, const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluate the (partial) derivatives of the i-th basis function at points u into result.
Definition: gsHBSplineBasis.hpp:93
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...
void deriv2_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluate the second derivatives of all active basis function at points u.
Definition: gsHBSplineBasis.hpp:155
A hierarchical B-spline basis of parametric dimension d.
Definition: gsHBSplineBasis.h:35
gsSparseMatrix< T > coarsening(const std::vector< gsSortedVector< index_t > > &old, const std::vector< gsSortedVector< index_t > > &n, const gsSparseMatrix< T, RowMajor > &transfer) const
returns a transfer matrix using the characteristic matrix of the old and new basis ...
Definition: gsHBSplineBasis.hpp:228
#define index_t
Definition: gsConfig.h:32
void printBasic(std::ostream &os=gsInfo) const
Prints the spline-space hierarchy.
Definition: gsHTensorBasis.h:560
This class is derived from std::vector, and adds sort tracking.
Definition: gsSortedVector.h:109
void derivSingle_into(index_t i, const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluates the (partial) derivatives of the i-th basis function at points u into result.
Definition: gsHBSplineBasis.hpp:85
void deriv_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluates the first partial derivatives of the nonzero basis function.
Definition: gsHBSplineBasis.hpp:128
A tensor product B-spline basis.
Definition: gsTensorBSplineBasis.h:36
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
BoundaryBasisType * basisSlice(index_t dir_fixed, T par) const
Gives back the basis at a slice in dir_fixed at par.
Definition: gsHBSplineBasis.hpp:39
Provides implementation of generic XML functions.
std::ostream & print(std::ostream &os) const
Prints the object as a string.
Definition: gsHBSplineBasis.hpp:60
std::string to_string(const unsigned &i)
Helper to convert small unsigned to string.
Definition: gsXml.cpp:74
void transferbyLvl(std::vector< gsSparseMatrix< T > > &result)
returns transfer matrices betweend the levels of the given hierarchical spline
Definition: gsHBSplineBasis.hpp:188
index_t size() const
The number of basis functions in this basis.
Definition: gsHTensorBasis.hpp:298
virtual void refineElements(std::vector< index_t > const &boxes)
Insert the given boxes into the quadtree.
Definition: gsHTensorBasis.hpp:843
void initialize()
Initialize the characteristic and coefficient matrices and the internal bspline representations.
Definition: gsHBSplineBasis.hpp:70
virtual void active_into(const gsMatrix< T > &u, gsMatrix< index_t > &result) const
Returns the indices of active basis functions at points u, as a list of indices, in result...
Definition: gsHTensorBasis.hpp:1383
void symDifference(const gsKnotVector< T > &other, std::vector< T > &result) const
Computes the symmetric difference between this knot-vector and other.
Definition: gsKnotVector.hpp:172
Struct which represents a certain side of a box.
Definition: gsBoundary.h:84
void refine_withTransfer(gsSparseMatrix< T, RowMajor > &transfer, const std::vector< std::vector< T > > &refineKnots)
Takes a vector of coordinate wise knot values and inserts these values to the basis.
Definition: gsTensorBSplineBasis.hpp:66
void eval_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluates nonzero basis functions at point u into result.
Definition: gsHBSplineBasis.hpp:101
memory::unique_ptr< Self_t > uPtr
Smart pointer for gsTensorBSplineBasis.
Definition: gsTensorBSplineBasis.h:69
void evalSingle_into(index_t i, const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluate the i-th basis function at points u into result.
Definition: gsHBSplineBasis.hpp:77
Class for representing a knot vector.
Definition: gsKnotVector.h:79
Provides declaration of input/output XML utilities struct.