G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsTensorBSplineBasis.h
Go to the documentation of this file.
1
15#pragma once
16
20
21namespace gismo
22{
23
35template<short_t d, class T>
37{
38public:
39 typedef gsKnotVector<T> KnotVectorType;
40
43
46
48
51 typedef CoordinateBasis Basis_t;
52
54 typedef T Scalar_t;
55
58
61
62 typedef typename Base::iterator iterator;
63 typedef typename Base::const_iterator const_iterator;
64
66 typedef memory::shared_ptr< Self_t > Ptr;
67
69 typedef memory::unique_ptr< Self_t > uPtr;
70
71public:
72
75 {
76 for(short_t i = 0; i!=d; ++i)
77 this->m_bases[i] = new Basis_t();
78 }
79
80 void swap(gsTensorBSplineBasis & other)
81 {
82 this->Base::swap(static_cast<Base&>(other));
83 std::swap(m_isPeriodic, other.m_isPeriodic);
84 }
85
86#if !EIGEN_HAS_RVALUE_REFERENCES
88 { gsTensorBSplineBasis::swap(other); return *this;}
89// #else // defined implicitly
90// gsTensorBSplineBasis(gsTensorBSplineBasis && other) : Base(give(other)) { }
91// gsTensorBSplineBasis(const gsTensorBSplineBasis & other) : Base(other) { }
92// gsTensorBSplineBasis & operator=(gsTensorBSplineBasis&& other)
93// { return (gsTensorBSplineBasis &)Base::operator=(give(other)); }
94// gsTensorBSplineBasis & operator=(const gsTensorBSplineBasis& other)
95// { return (gsTensorBSplineBasis &)Base::operator=(other); }
96#endif
97
105 template<typename U>
106 gsTensorBSplineBasis( KnotVectorType KV1, gsKnotVector<U> KV2,
107 typename util::enable_if<d==2,U>::type * = NULL )
108 : Base( new Basis_t(give(KV1)), new Basis_t(give(KV2)) )
109 { m_isPeriodic = -1; }
110
119 gsTensorBSplineBasis( KnotVectorType KV1,
120 KnotVectorType KV2,
121 KnotVectorType KV3 )
122 : Base( new Basis_t(give(KV1)), new Basis_t(give(KV2)), new Basis_t(give(KV3)) )
123 { m_isPeriodic = -1; }
124
125 gsTensorBSplineBasis( KnotVectorType KV1,
126 KnotVectorType KV2,
127 KnotVectorType KV3,
128 KnotVectorType KV4)
129 : Base( new Basis_t(give(KV1)), new Basis_t(give(KV2)),
130 new Basis_t(give(KV3)), new Basis_t(give(KV4)) )
131 { m_isPeriodic = -1; }
132
133 explicit gsTensorBSplineBasis(std::vector<KnotVectorType> KV)
134 {
135 GISMO_ENSURE(d == KV.size(), "Invalid number of knot-vectors given." );
136 for(short_t i = 0; i!=d; ++i)
137 this->m_bases[i] = new Basis_t( give(KV[i]) );
138 m_isPeriodic = -1;
139 }
140
141 gsTensorBSplineBasis( Basis_t* x, Basis_t* y) : Base(x,y)
142 {
143 GISMO_ENSURE(d==2,"Invalid constructor." );
145 }
146
147 gsTensorBSplineBasis( Basis_t* x, Basis_t* y, Basis_t* z ) : Base(x,y,z)
148 {
149 GISMO_ENSURE(d==3,"Invalid constructor." );
151
152 }
153
154 gsTensorBSplineBasis( Basis_t* x, Basis_t* y, Basis_t* z, Basis_t* w ) : Base(x,y,z,w)
155 {
156 GISMO_ENSURE(d==4,"Invalid constructor." );
158 }
159
160 explicit gsTensorBSplineBasis(std::vector< gsBasis<T>*> & bb );
161
162 explicit gsTensorBSplineBasis(std::vector< Basis_t*> & bb );
163
164#ifdef __DOXYGEN__
166 typename gsBSplineTraits<static_cast<short_t>(d-1),T>::Basis::uPtr boundaryBasis(boxSide const & s);
167#endif
168 GISMO_UPTR_FUNCTION_DEF(BoundaryBasisType, boundaryBasis, boxSide const &)
169 {
170 std::vector<gsBasis<T>*> rr;
171 this->getComponentsForSide(n1,rr);
172 return BoundaryBasisType::New(rr);
173 }
174
175 GISMO_CLONE_FUNCTION(gsTensorBSplineBasis)
176
177 static Self_t * New(std::vector<gsBasis<T>*> & bb )
178 { return new Self_t(bb); }
179
180 static Self_t * New(std::vector<Basis_t*> & bb )
181 { return new Self_t(bb); }
182
183 static uPtr make(std::vector<gsBasis<T>*> & bb )
184 { return uPtr( new Self_t(bb) ); }
185
186 static uPtr make(std::vector<Basis_t*> & bb )
187 { return uPtr( new Self_t(bb) ); }
188
189public:
190
191 KnotVectorType & knots (int i)
192 { return Self_t::component(i).knots(); }
193
194 const KnotVectorType & knots (int i) const
195 { return Self_t::component(i).knots(); }
196
197 // knot \a k of direction \a i
198 T knot(int i, int k) const
199 { return Self_t::component(i).knots()[k]; }
200
201
202 const Basis_t & component(short_t dir) const
203 {
204 return static_cast<const Basis_t &>(Base::component(dir));
205 }
206
207 Basis_t & component(short_t dir)
208 {
209 return static_cast<Basis_t &>(Base::component(dir));
210 }
211
212 // Look at gsBasis class for a description
213 void active_into(const gsMatrix<T> & u, gsMatrix<index_t>& result) const;
214
219 void active_cwise(const gsMatrix<T> & u, gsVector<index_t,d>& low,
220 gsVector<index_t,d>& upp ) const;
221
223 std::ostream &print(std::ostream &os) const
224 {
225 os << "TensorBSplineBasis: dim=" << this->dim()<< ", size="<< this->size() <<".";
226 if( m_isPeriodic != -1 )
227 os << "Periodic in " << m_isPeriodic << "-th direction.\n";
228 for ( short_t i = 0; i!=d; ++i )
229 os << "\n Direction "<< i <<": "<< Self_t::component(i).knots() <<" ";
230 os << "\n";
231 return os;
232 }
233
234 //
235 // param other parent/reference mesh determining the smoothness at the inner knots.
236 // param i number of k-refinement steps to perform
237
241 void k_refine(Self_t & other, int const & i = 1)
242 {
243 for (short_t j = 0; j < d; ++j)
244 Self_t::component(j).refine_k(other.component(j), i);
245 }
246
249 void refine_p(int const & i = 1)
250 {
251 for (short_t j = 0; j < d; ++j)
252 Self_t::component(j).refine_p(i);
253 }
254
257 void refine_h(int const & i = 1)
258 {
259 for (short_t j = 0; j < d; ++j)
260 Self_t::component(j).refine_h(i);
261 }
262
274 void refine_withTransfer(gsSparseMatrix<T,RowMajor> & transfer, const std::vector< std::vector<T> >& refineKnots);
275 void refine_withTransfer(gsSparseMatrix<T,RowMajor> & transfer, gsMatrix<T> const & boxes)
276 {
277 this->refine_withTransfer(transfer,this->_boxToKnots(boxes));
278 }
279
291 void refine_withCoefs(gsMatrix<T> & coefs,const std::vector< std::vector<T> >& refineKnots);
292 void refine_withCoefs(gsMatrix<T> & coefs, gsMatrix<T> const & boxes)
293 {
294 this->refine_withCoefs(coefs,this->_boxToKnots(boxes));
295 }
296
299 void insertKnot(T knot, index_t dir, int mult=1)
300 { this->knots(dir).insert( knot, mult); }
301
304 void removeKnot(T knot, index_t dir, int mult=1)
305 { this->knots(dir).remove( knot, mult); }
306
313 void insertKnots(const std::vector< std::vector<T> >& refineKnots)
314 {
315 GISMO_ASSERT( refineKnots.size() == d, "refineKnots vector has wrong size" );
316 for (short_t j = 0; j < d; ++j) // refine basis in each direction
317 this->knots(j).insert(refineKnots[j]);
318 }
319
358 void refine( gsMatrix<T> const & boxes, int refExt = 0);
359
360 GISMO_MAKE_GEOMETRY_NEW
361
364 void reduceContinuity(int const & i = 1)
365 {
366 for (short_t j = 0; j < d; ++j)
367 Self_t::component(j).reduceContinuity(i);
368 }
369
372 template <int _Rows>
374 {
375 //result.resize(d,2);
376 gsMatrix<index_t> tmp_vec;
377 const gsVector<index_t, d> ti = this->tensorIndex(i);
378
379 for (short_t dim = 0; dim < d; ++dim)
380 {
381 const gsKnotVector<T> & kv = Self_t::component(dim).knots();
382 kv.supportIndex_into(ti[dim], tmp_vec);
383 result.row(dim).noalias() =
384 tmp_vec.cwiseMax(0).cwiseMin(kv.numElements());
385 }
386 }
387
391 {
392 gsMatrix<index_t, d, 2> result(d, 2);
393 elementSupport_into(i, result);
394 return result;
395 }
396
399 template <int _Rows>
401 gsMatrix<index_t> & result) const
402 {
403 GISMO_ASSERT( box.rows() == static_cast<index_t>(d), "Invalid input box");
405
407 this->stride_cwise(str);
408
409 for (short_t dm = 0; dm != d; ++dm)
410 {
411 tmp(dm,0) = Self_t::component(dm).knots().lastKnotIndex (box(dm,0)) - this->degree(dm);
412 tmp(dm,1) = Self_t::component(dm).knots().firstKnotIndex(box(dm,1)) - 1;
413 }
414
415 const gsVector<index_t,d> sz = tmp.col(1)- tmp.col(0) + gsVector<index_t,d>::Ones();
416
417 result = gsVector<index_t>::LinSpaced(sz[0], tmp(0,0), tmp(0,1));
418 for (short_t dm = 1; dm != d; ++dm)
419 result = result.replicate(1,sz[dm]) +
420 gsVector<index_t>::Constant(result.rows(), str[dm] )
421 * gsVector<index_t>::LinSpaced(sz[dm], tmp(dm,0), tmp(dm,1))
422 .transpose();
423 }
424
425 template <int _Rows>
426 gsMatrix<T> elementDom(const gsMatrix<index_t,_Rows,2> & box) const
427 {
428 GISMO_ASSERT( box.rows() == static_cast<index_t>(d), "Invalid input box");
429 gsMatrix<T> rvo;
430 rvo.resize(d,2);
431 for (short_t dm = 0; dm != d; ++dm)
432 {
433 rvo(dm,0) = Self_t::component(dm).knots().uValue(box(dm,0));
434 rvo(dm,1) = Self_t::component(dm).knots().uValue(box(dm,1));
435 }
436 return rvo;
437 }
438
440 inline bool isPeriodic() const { return m_isPeriodic != -1; }
441
443 inline int periodicDirection() const { return m_isPeriodic; }
444
446 inline void setPeriodic( const int dir )
447 {
448 Self_t::component(dir).setPeriodic();
449 if( Self_t::component(dir).isPeriodic() ) // Only when succeeded when converting to periodic.
450 m_isPeriodic = dir;
451 }
452
454 gsMatrix<T> perCoefs( const gsMatrix<T>& originalCoefs, short_t dir ) const
455 {
456 // Identify which coefficients to copy and where to copy them.
457 std::vector<index_t> sourceSliceIndices;
458 std::vector<index_t> targetSliceIndices;
459 index_t numPeriodic = Self_t::component(dir).numCrossingFunctions();
460
461 const index_t sz = this->size(dir) - numPeriodic;
462 for( index_t i = 0; i < numPeriodic; i++ )
463 {
464 gsMatrix<index_t> currentSourceSlice = this->coefSlice(dir,i);
465 gsMatrix<index_t> currentTargetSlice = this->coefSlice(dir, sz + i );
466
467 for( index_t j = 0; j != currentSourceSlice.size(); j++ )
468 {
469 sourceSliceIndices.push_back( static_cast<index_t>( currentSourceSlice(j) ) );
470 targetSliceIndices.push_back( static_cast<index_t>( currentTargetSlice(j) ) );
471 }
472 }
473
474 // Copy the chosen coefficients.
475 gsMatrix<T> result = originalCoefs;
476 for( size_t i = 0; i != sourceSliceIndices.size(); i++ )
477 {
478 //gsDebug << "source: " << sourceSliceIndices[i] << "\n";
479 //gsDebug << "target: " << targetSliceIndices[i] << "\n";
480 result.row( targetSliceIndices[ i ] ) = originalCoefs.row( sourceSliceIndices[ i ] );
481 }
482
483 return result;
484 }
485
486private:
487
491 std::vector<std::vector<T>> _boxToKnots(gsMatrix<T> const & boxes);
492
496 {
497 m_isPeriodic = -1;
498 for( short_t i = 0; i < this->dim(); i++ )
499 {
500 if( Self_t::component(i).isPeriodic() )
501 {
502 if( m_isPeriodic == -1 )
503 m_isPeriodic = i;
504 else
505 gsWarn << "Cannot handle a basis that is periodic in more than one direction.\n";
506 }
507 }
508 }
509
510protected:
511
515
516};
517
518#ifdef GISMO_WITH_PYBIND11
519
523 void pybind11_init_gsTensorBSplineBasis2(pybind11::module &m);
524 void pybind11_init_gsTensorBSplineBasis3(pybind11::module &m);
525 void pybind11_init_gsTensorBSplineBasis4(pybind11::module &m);
526
527#endif // GISMO_WITH_PYBIND11
528
529} // namespace gismo
530
531
532// *****************************************************************
533#ifndef GISMO_BUILD_LIB
534#include GISMO_HPP_HEADER(gsTensorBSplineBasis.hpp)
535/*
536#else
537#ifdef gsTensorBSplineBasis_EXPORT
538#include GISMO_HPP_HEADER(gsTensorBSplineBasis.hpp)
539#undef EXTERN_CLASS_TEMPLATE
540#define EXTERN_CLASS_TEMPLATE CLASS_TEMPLATE_INST
541#endif
542namespace gismo
543{
544EXTERN_CLASS_TEMPLATE gsTensorBSplineBasis<2,real_t>;
545EXTERN_CLASS_TEMPLATE gsTensorBSplineBasis<3,real_t>;
546EXTERN_CLASS_TEMPLATE gsTensorBSplineBasis<4,real_t>;
547}
548*/
549#endif
550// *****************************************************************
Struct which represents a certain side of a box.
Definition gsBoundary.h:85
A univariate B-spline basis.
Definition gsBSplineBasis.h:700
A basis represents a family of scalar basis functions defined over a common parameter domain.
Definition gsBasis.h:79
Class for representing a knot vector.
Definition gsKnotVector.h:80
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
Sparse matrix class, based on gsEigen::SparseMatrix.
Definition gsSparseMatrix.h:139
A tensor product B-spline basis.
Definition gsTensorBSplineBasis.h:37
void k_refine(Self_t &other, int const &i=1)
Perform k-refinement coordinate-wise, in all directions.
Definition gsTensorBSplineBasis.h:241
gsTensorBSplineBasis(KnotVectorType KV1, gsKnotVector< U > KV2, typename util::enable_if< d==2, U >::type *=NULL)
Constructs a 2D tensor product B-spline basis. Assumes that the tamplate parameter d is equal to 2.
Definition gsTensorBSplineBasis.h:106
gsBSplineTraits< static_cast< short_t >(d-1), T >::Basis::uPtr boundaryBasis(boxSide const &s)
Returns the boundary basis for side s.
GISMO_MAKE_GEOMETRY_NEW void reduceContinuity(int const &i=1)
Reduces spline continuity (in all directions) at interior knots by i.
Definition gsTensorBSplineBasis.h:364
gsBSplineTraits< d, T >::Geometry GeometryType
Associated Boundary basis type.
Definition gsTensorBSplineBasis.h:57
void setPeriodic(const int dir)
Converts.
Definition gsTensorBSplineBasis.h:446
std::vector< std::vector< T > > _boxToKnots(gsMatrix< T > const &boxes)
Definition gsTensorBSplineBasis.hpp:106
void setIsPeriodic()
Definition gsTensorBSplineBasis.h:495
gsTensorBSplineBasis()
Default constructor.
Definition gsTensorBSplineBasis.h:74
void insertKnots(const std::vector< std::vector< T > > &refineKnots)
Takes a vector of coordinate wise knot values and inserts these values to the basis.
Definition gsTensorBSplineBasis.h:313
void refine_withCoefs(gsMatrix< T > &coefs, 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:83
void refine_p(int const &i=1)
p-refinement (essentially degree elevation in all directions)
Definition gsTensorBSplineBasis.h:249
gsBSplineTraits< static_cast< short_t >(d-1), T >::Basis BoundaryBasisType
Associated Boundary basis type.
Definition gsTensorBSplineBasis.h:60
gsMatrix< T > perCoefs(const gsMatrix< T > &originalCoefs, short_t dir) const
Sets the coefficients so that the resulting TensorBSpline is periodic in direction dir.
Definition gsTensorBSplineBasis.h:454
gsBSplineBasis< T > CoordinateBasis
Coordinate basis type.
Definition gsTensorBSplineBasis.h:50
gsTensorBSplineBasis(KnotVectorType KV1, KnotVectorType KV2, KnotVectorType KV3)
Constructs a 3D tensor product B-spline basis. Assumes that the tamplate parameter d is equal to 3.
Definition gsTensorBSplineBasis.h:119
memory::unique_ptr< Self_t > uPtr
Smart pointer for gsTensorBSplineBasis.
Definition gsTensorBSplineBasis.h:69
void elementSupport_into(const index_t i, gsMatrix< index_t, _Rows, 2 > &result) const
Returns span (element) indices of the beginning and end of the support of the i-th basis function.
Definition gsTensorBSplineBasis.h:373
T Scalar_t
Coefficient type.
Definition gsTensorBSplineBasis.h:54
void insertKnot(T knot, index_t dir, int mult=1)
Definition gsTensorBSplineBasis.h:299
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 gsTensorBSplineBasis.hpp:176
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
Basis_t & component(short_t dir)
For a tensor product basis, return the 1-d basis for the i-th parameter component.
Definition gsTensorBSplineBasis.h:207
void removeKnot(T knot, index_t dir, int mult=1)
Definition gsTensorBSplineBasis.h:304
void refine_h(int const &i=1)
Uniform h-refinement (placing i new knots inside each knot-span, for all directions.
Definition gsTensorBSplineBasis.h:257
gsMatrix< index_t, d, 2 > elementSupport(const index_t &i) const
Returns span (element) indices of the beginning and end of the support of the i-th basis function.
Definition gsTensorBSplineBasis.h:390
memory::shared_ptr< Self_t > Ptr
Smart pointer for gsTensorBSplineBasis.
Definition gsTensorBSplineBasis.h:66
void elementActive_into(const gsMatrix< index_t, _Rows, 2 > &box, gsMatrix< index_t > &result) const
Returns the indices of active basis functions in the given input element box.
Definition gsTensorBSplineBasis.h:400
gsBSplineBasis< T > Family_t
Family type.
Definition gsTensorBSplineBasis.h:45
gsTensorBasis< d, T > Base
Base type.
Definition gsTensorBSplineBasis.h:42
std::ostream & print(std::ostream &os) const
Prints the object as a string.
Definition gsTensorBSplineBasis.h:223
const Basis_t & component(short_t dir) const
For a tensor product basis, return the (const) 1-d basis for the i-th parameter component.
Definition gsTensorBSplineBasis.h:202
bool isPeriodic() const
Tells, whether there is a coordinate direction in which the basis is periodic.
Definition gsTensorBSplineBasis.h:440
int periodicDirection() const
Gives the value of m_isPeriodic.
Definition gsTensorBSplineBasis.h:443
void active_cwise(const gsMatrix< T > &u, gsVector< index_t, d > &low, gsVector< index_t, d > &upp) const
Definition gsTensorBSplineBasis.hpp:50
short_t m_isPeriodic
Definition gsTensorBSplineBasis.h:514
A tensor product of d B-spline functions, with arbitrary target dimension.
Definition gsTensorBSpline.h:45
Abstract base class for tensor product bases.
Definition gsTensorBasis.h:34
gsMatrix< index_t > coefSlice(short_t dir, index_t k) const
Returns all the basis functions with tensor-numbering.
Definition gsTensorBasis.hpp:250
void stride_cwise(gsVector< index_t, d > &result) const
Returns the strides for all dimensions.
Definition gsTensorBasis.h:512
short_t degree(short_t i) const
Returns the degree of the basis wrt variable i.
Definition gsTensorBasis.h:465
index_t size() const
Returns the number of elements in the basis.
Definition gsTensorBasis.h:108
Basis_t & component(short_t dir)
For a tensor product basis, return the 1-d basis for the i-th parameter component.
Definition gsTensorBasis.h:596
gsVector< index_t, d > tensorIndex(const index_t &m) const
Returns the tensor index of the basis function with global index m.
Definition gsTensorBasis.h:527
void getComponentsForSide(boxSide const &s, std::vector< Basis_t * > &rr) const
Returns the components for a basis on the face s.
Definition gsTensorBasis.hpp:377
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
void refine(gsMatrix< T > const &boxes, int refExt=0)
Refinement of the tensor basis on the area defined by boxes.
Definition gsTensorBSplineBasis.hpp:156
Provides declaration of BSplineBasis class.
#define short_t
Definition gsConfig.h:35
#define index_t
Definition gsConfig.h:32
#define gsWarn
Definition gsDebug.h:50
#define GISMO_ENSURE(cond, message)
Definition gsDebug.h:102
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Represents a tensor-product B-spline patch.
Provides declaration of TensorBasis class.
The G+Smo namespace, containing all definitions for the library.
S give(S &x)
Definition gsMemory.h:266
Traits for BSplineBasis in more dimensions.
Definition gsBSplineBasis.h:32