G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsHBSplineBasis.hpp
1
14#pragma once
15
17
18#include <gsIO/gsXml.h>
20
21namespace gismo
22{
23
24/*
25template<short_t d, class T>
26gsHBSplineBasis<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
38template<short_t d, class T>
39typename 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
59template<short_t d, class T>
60std::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
69template<short_t d, class T>
71{
72 // Sets everything related to gsHTensorBasis
73 // this->update_structure(); // base class update
74}
75
76template<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
84template<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
92template<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
100template<short_t d, class T>
102{
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
127template<short_t d, class T>
129{
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
154template<short_t d, class T>
156{
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
187template<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
227template<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
289template<short_t d, class T>
290gsSparseMatrix<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
386template<short_t d, class T>
387gsSparseMatrix<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}
496namespace internal
497{
498
500template<short_t d, class T>
501class gsXml< gsHBSplineBasis<d,T> >
502{
503private:
504 gsXml() { }
505public:
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
Struct which represents a certain side of a box.
Definition gsBoundary.h:85
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 gsBasis.hpp:316
A hierarchical B-spline basis of parametric dimension d.
Definition gsHBSplineBasis.h:36
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
void initialize()
Initialize the characteristic and coefficient matrices and the internal bspline representations.
Definition gsHBSplineBasis.hpp:70
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
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
void eval_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluates nonzero basis functions at point u into result.
Definition gsHBSplineBasis.hpp:101
void transferbyLvl(std::vector< gsSparseMatrix< T > > &result)
returns transfer matrices betweend the levels of the given hierarchical spline
Definition gsHBSplineBasis.hpp:188
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
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
std::ostream & print(std::ostream &os) const
Prints the object as a string.
Definition gsHBSplineBasis.hpp:60
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
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
index_t size() const
The number of basis functions in this basis.
Definition gsHTensorBasis.hpp:298
void printBasic(std::ostream &os=gsInfo) const
Prints the spline-space hierarchy.
Definition gsHTensorBasis.h:560
virtual void refineElements(std::vector< index_t > const &boxes)
Insert the given boxes into the quadtree.
Definition gsHTensorBasis.hpp:844
Class for representing a knot vector.
Definition gsKnotVector.h:80
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
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
This class is derived from std::vector, and adds sort tracking.
Definition gsSortedVector.h:110
Sparse matrix class, based on gsEigen::SparseMatrix.
Definition gsSparseMatrix.h:139
A tensor product B-spline basis.
Definition gsTensorBSplineBasis.h:37
memory::unique_ptr< Self_t > uPtr
Smart pointer for gsTensorBSplineBasis.
Definition gsTensorBSplineBasis.h:69
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
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
#define index_t
Definition gsConfig.h:32
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Provides definition of HTensorBasis abstract interface.
Provides implementation of generic XML functions.
Provides declaration of input/output XML utilities struct.
std::string to_string(const unsigned &i)
Helper to convert small unsigned to string.
Definition gsXml.cpp:74
The G+Smo namespace, containing all definitions for the library.