G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsTensorNurbsBasis.h
Go to the documentation of this file.
1 
14 #pragma once
15 
16 #include <gsNurbs/gsNurbs.h>
17 #include <gsNurbs/gsNurbsBasis.h>
18 #include <gsCore/gsRationalBasis.h>
20 #include <gsTensor/gsTensorTools.h>
21 
22 namespace gismo
23 {
24 
37 template<short_t d, class T>
38 class gsTensorNurbsBasis : public gsRationalBasis<typename gsBSplineTraits<d,T>::Basis>
39 {
40 
41 public:
42  typedef gsKnotVector<T> KnotVectorType;
43 
46 
49 
52 
54  typedef typename Src_t::Basis_t Basis_t;
55 
57  typedef T Scalar_t;
58 
61 
63  typedef typename gsBSplineTraits<static_cast<short_t>(d-1),T>::RatBasis BoundaryBasisType;
64 
66  typedef memory::shared_ptr< gsTensorNurbsBasis > Ptr;
67 
69  typedef memory::unique_ptr< gsTensorNurbsBasis > uPtr;
70 
71  //typedef typename Base::iterator iterator;
72  //typedef typename Base::const_iterator const_iterator;
73 
74 public:
75 
77  gsTensorNurbsBasis( const KnotVectorType& KV1, const KnotVectorType& KV2 )
78  : Base( new gsBSplineBasis<T>(KV1, KV1.degree()), new gsBSplineBasis<T>(KV2, KV2.degree()) )
79  { }
80 
81  gsTensorNurbsBasis( const KnotVectorType& KV1, const KnotVectorType& KV2, const KnotVectorType& KV3 )
82  : Base( new gsBSplineBasis<T>(KV1, KV1.degree()),
83  new gsBSplineBasis<T>(KV2, KV2.degree()),
84  new gsBSplineBasis<T>(KV3, KV3.degree()) )
85  { }
86 
87  // TO DO: more constructors
88  //gsTensorNurbsBasis( gsBSplineBasis * x, gsBSplineBasis* y, Basis_t* z ) : Base(x,y,z) { };
89  //gsTensorNurbsBasis( std::vector<Basis_t* > const & bb ) : Base(bb) { };
90 
91 
92  // Constructors forwarded from the base class
93  gsTensorNurbsBasis() : Base() { };
94 
95  gsTensorNurbsBasis( Src_t* basis ) : Base(basis) { }
96 
97  gsTensorNurbsBasis( const Src_t & basis ) : Base(basis) { }
98 
99  gsTensorNurbsBasis( std::vector<gsBasis<T>* > const & bb, gsMatrix<T> w ) : Base(Src_t(bb), give(w)) { }
100 
101  gsTensorNurbsBasis( Src_t* basis, gsMatrix<T> w ) : Base(basis, give(w)) { }
102 
103  gsTensorNurbsBasis(const gsTensorNurbsBasis & o) : Base(o) { }
104 
105  GISMO_CLONE_FUNCTION(gsTensorNurbsBasis)
106 
107  //static uPtr make(std::vector<gsBasis<T>* > const & bb, gsMatrix<T> w)
108  //{ return uPtr( new gsTensorNurbsBasis(bb, w) ); }
109 
110  GISMO_MAKE_GEOMETRY_NEW
111 
112 public:
113 
115  std::ostream &print(std::ostream &os) const
116  {
117  os << "TensorNurbsBasis: dim=" << this->dim()<< ", size="<< this->size() << ".";
118  for ( unsigned i = 0; i!=d; ++i )
119  os << "\n Direction "<< i <<": "<< this->m_src->component(i).knots() <<" ";
120  os << "\n";
121  return os;
122  }
123 
124  gsKnotVector<T> & knots (int i)
125  { return m_src->knots(i); }
126 
127  const gsKnotVector<T> & knots (int i) const
128  { return m_src->knots(i); }
129 
130  // knot \a k of direction \a i
131  T knot(int i, int k) const
132  { return m_src->knot(i, k); }
133 
135  void size_cwise(gsVector<index_t,d> & result) const
136  {
137  // call the function of the underlying basis
138  m_src->size_cwise(result);
139  }
140 
142  void stride_cwise(gsVector<index_t,d> & result) const
143  {
144  // call the function of the underlying basis
145  m_src->stride_cwise(result);
146  }
147 
148  void swapDirections(const unsigned i, const unsigned j)
149  {
151  size_cwise(sz);
152 
153  // First swap the weights
154  swapTensorDirection(i, j, sz, m_weights);
155 
156  // Then swap the basis components
157  m_src->swapDirections(i, j);
158  }
159 
160  void uniformRefine_withCoefs(gsMatrix<T>& coefs, int numKnots=1, int mul=1, int dir=-1)
161  {
162  GISMO_ASSERT( coefs.rows() == this->size() && m_weights.rows() == this->size(),
163  "Invalid dimensions" );
164 
165  gsSparseMatrix<T, RowMajor> transfer;
166  if (dir==-1)
167  {
168  m_src->uniformRefine_withTransfer(transfer, numKnots, mul);
169 
170  coefs = transfer * ( m_weights.asDiagonal() * coefs);
171  m_weights = transfer * m_weights;
172  // Alternative way
173  // gsBasis<T> * tmp = m_src->clone();
174  // tmp->uniformRefine_withCoefs(coefs, numKnots);
175  // delete tmp;
176  // m_src->uniformRefine_withCoefs(m_weights, numKnots);
177 
178  // back to affine coefs
179  coefs.array().colwise() /= m_weights.col(0).array();
180  // equiv:
181  // for (int i = 0; i < coefs.rows(); ++i)
182  // coefs.row(i) /= m_weights.at(i);
183  }
184  else
185  {
186  GISMO_ASSERT( dir >= 0 && static_cast<unsigned>(dir) < d,
187  "Invalid basis component "<< dir <<" requested for degree elevation" );
188 
189  gsVector<index_t,d> sz;
190  m_src->size_cwise(sz);
191  m_src->component(dir).uniformRefine_withTransfer( transfer, numKnots, mul );
192 
193  const index_t coefs_cols = coefs.cols();
194  const index_t weights_cols = m_weights.cols();
195 
196  coefs = m_weights.asDiagonal() * coefs; //<<<<-----this goes wrong!!
197  swapTensorDirection(0, dir, sz, coefs);
198  coefs.resize( sz[0], coefs_cols * sz.template tail<static_cast<short_t>(d-1)>().prod() );
199  coefs = transfer * coefs;
200 
201  swapTensorDirection(0, dir, sz, m_weights);
202  m_weights.resize( sz[0], weights_cols * sz.template tail<static_cast<short_t>(d-1)>().prod() );
203  m_weights = transfer * m_weights;
204 
205  sz[0] = coefs.rows();
206 
207  coefs.resize( sz.prod(), coefs_cols );
208  m_weights.resize( sz.prod(), weights_cols );
209  swapTensorDirection(0, dir, sz, coefs);
210  swapTensorDirection(0, dir, sz, m_weights);
211 
212  coefs.array().colwise() /= m_weights.col(0).array();
213  }
214  }
215 
216 #ifdef __DOXYGEN__
217  typename BoundaryBasisType::uPtr boundaryBasis(boxSide const & s);
219 #endif
220 
221  GISMO_UPTR_FUNCTION_DEF(BoundaryBasisType, boundaryBasis, boxSide const &)
222  {
223  typename Src_t::BoundaryBasisType::uPtr bb = m_src->boundaryBasis(n1);
224  gsMatrix<index_t> ind = m_src->boundary(n1);
225 
226  gsMatrix<T> ww( ind.size(),1);
227  for ( index_t i=0; i<ind.size(); ++i)
228  ww(i,0) = m_weights( (ind)(i,0), 0);
229 
230  return new BoundaryBasisType(bb.release(), give(ww));// note: constructor consumes the pointer
231  }
232 
233  void matchWith(const boundaryInterface & bi, const gsBasis<T> & other,
234  gsMatrix<index_t> & bndThis, gsMatrix<index_t> & bndOther) const
235  {
236  this->matchWith(bi,other,bndThis,bndOther,0);
237  }
238 
239  // see gsBasis for documentation
240  void matchWith(const boundaryInterface & bi, const gsBasis<T> & other,
241  gsMatrix<index_t> & bndThis, gsMatrix<index_t> & bndOther, index_t offset) const
242  {
243  if ( const gsTensorNurbsBasis<d,T> * _other = dynamic_cast<const gsTensorNurbsBasis<d,T> *>(&other) )
244  m_src->matchWith(bi,_other->source(),bndThis,bndOther,offset);
245  else if ( const gsTensorBasis<d,T> * __other = dynamic_cast<const gsTensorBasis<d,T> *>(&other) )
246  m_src->matchWith(bi,*__other,bndThis,bndOther,offset);
247  else
248  gsWarn<<"Cannot match with "<<other<<"\n";
249  }
250 
251 
252 protected:
253  using Base::m_src;
254  using Base::m_weights;
255 
256 };
257 
258 
259 } // namespace gismo
memory::unique_ptr< gsTensorNurbsBasis > uPtr
Unique pointer for gsTensorNurbsBasis.
Definition: gsTensorNurbsBasis.h:69
gsBSplineBasis< T > Family_t
Family type.
Definition: gsTensorNurbsBasis.h:48
memory::shared_ptr< gsTensorNurbsBasis > Ptr
Shared pointer for gsTensorNurbsBasis.
Definition: gsTensorNurbsBasis.h:66
Represents a NURBS basis with one parameter.
gsBSplineTraits< d, T >::Basis Src_t
Source basis type.
Definition: gsTensorNurbsBasis.h:51
Represents a NURBS curve/function with one parameter.
index_t size() const
size
Definition: gsRationalBasis.h:137
Traits for BSplineBasis in more dimensions.
Definition: gsBSplineBasis.h:31
Class that creates a rational counterpart for a given basis.
Definition: gsRationalBasis.h:47
T Scalar_t
Coefficient type.
Definition: gsTensorNurbsBasis.h:57
A tensor product Non-Uniform Rational B-spline function (NURBS) of parametric dimension d...
Definition: gsTensorNurbs.h:40
void swapTensorDirection(int k1, int k2, gsVector< index_t, d > &sz, gsMatrix< T > &coefs)
Definition: gsTensorTools.h:129
void stride_cwise(gsVector< index_t, d > &result) const
Returns the strides for all dimensions.
Definition: gsTensorNurbsBasis.h:142
Utility functions related to tensor-structured objects.
S give(S &x)
Definition: gsMemory.h:266
#define index_t
Definition: gsConfig.h:32
Src_t::Basis_t Basis_t
Coordinate basis type.
Definition: gsTensorNurbsBasis.h:54
gsRationalBasis< typename gsBSplineTraits< d, T >::Basis > Base
Base type.
Definition: gsTensorNurbsBasis.h:45
A tensor product B-spline basis.
Definition: gsTensorBSplineBasis.h:36
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
short_t degree(short_t i=0) const
Degree with respect to the i-th variable. If the basis is a tensor product of (piecewise) polynomial ...
Definition: gsRationalBasis.h:162
std::ostream & print(std::ostream &os) const
Prints the object as a string.
Definition: gsTensorNurbsBasis.h:115
BoundaryBasisType::uPtr boundaryBasis(boxSide const &s)
Gives back the boundary basis at boxSide s.
A univariate B-spline basis.
Definition: gsBSplineBasis.h:694
gsBSplineTraits< d, T >::RatGeometry GeometryType
Associated geometry type.
Definition: gsTensorNurbsBasis.h:60
#define gsWarn
Definition: gsDebug.h:50
const gsBasis< T > & basis(const index_t k) const
Helper which casts and returns the k-th piece of this function set as a gsBasis.
Definition: gsFunctionSet.hpp:33
gsTensorNurbsBasis(const KnotVectorType &KV1, const KnotVectorType &KV2)
Constructors for gsTensorNurbsBasis.
Definition: gsTensorNurbsBasis.h:77
A tensor product Non-Uniform Rational B-spline (NURBS) basis.
Definition: gsTensorNurbsBasis.h:38
gsBSplineTraits< static_cast< short_t >d-1), T >::RatBasis BoundaryBasisType
Associated Boundary basis type.
Definition: gsTensorNurbsBasis.h:63
Provides declaration of RationalBasis class.
void size_cwise(gsVector< index_t, d > &result) const
The number of basis functions in the direction of the k-th parameter component.
Definition: gsTensorNurbsBasis.h:135
memory::unique_ptr< Self_t > uPtr
Smart pointer for gsTensorBSplineBasis.
Definition: gsTensorBSplineBasis.h:69
Class for representing a knot vector.
Definition: gsKnotVector.h:79
Provides declaration of TensorBSplineBasis abstract interface.