G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsTensorNurbsBasis.h
Go to the documentation of this file.
1
14#pragma once
15
20
21namespace gismo
22{
23
36template<short_t d, class T>
37class gsTensorNurbsBasis : public gsRationalBasis<typename gsBSplineTraits<d,T>::Basis>
38{
39
40public:
41 typedef gsKnotVector<T> KnotVectorType;
42
43 typedef memory::unique_ptr<gsGeometry<T> > gsGeoPtr;
44
47
50
53
55 typedef typename Src_t::Basis_t Basis_t;
56
58 typedef T Scalar_t;
59
62
64 typedef typename gsBSplineTraits<static_cast<short_t>(d-1),T>::RatBasis BoundaryBasisType;
65
67 typedef memory::shared_ptr< gsTensorNurbsBasis > Ptr;
68
70 typedef memory::unique_ptr< gsTensorNurbsBasis > uPtr;
71
72 //typedef typename Base::iterator iterator;
73 //typedef typename Base::const_iterator const_iterator;
74
75public:
76
77 explicit gsTensorNurbsBasis(std::vector<KnotVectorType> KV, gsMatrix<T> w)
78 : Base(new Src_t(give(KV)), give(w)) { }
79
80 // Constructors forwarded from the base class
81 gsTensorNurbsBasis() : Base() { };
82
83 gsTensorNurbsBasis( Src_t* basis ) : Base(basis) { }
84
85 gsTensorNurbsBasis( const Src_t & basis ) : Base(basis) { }
86
87 gsTensorNurbsBasis( Src_t* basis, gsMatrix<T> w ) : Base(basis, give(w)) { }
88
89 gsTensorNurbsBasis(const gsTensorNurbsBasis & o) : Base(o) { }
90
91 GISMO_CLONE_FUNCTION(gsTensorNurbsBasis)
92
93 gsGeoPtr makeGeometry( gsMatrix<T> coefs ) const;
94
95public:
96
98 std::ostream &print(std::ostream &os) const
99 {
100 os << "TensorNurbsBasis: dim=" << this->dim()<< ", size="<< this->size() << ".";
101 for ( unsigned i = 0; i!=d; ++i )
102 os << "\n Direction "<< i <<": "<< this->m_src->component(i).knots() <<" ";
103 os << "\n";
104 return os;
105 }
106
107 gsKnotVector<T> & knots (int i)
108 { return m_src->knots(i); }
109
110 const gsKnotVector<T> & knots (int i) const
111 { return m_src->knots(i); }
112
113 // knot \a k of direction \a i
114 T knot(int i, int k) const
115 { return m_src->knot(i, k); }
116
118 void size_cwise(gsVector<index_t,d> & result) const
119 {
120 // call the function of the underlying basis
121 m_src->size_cwise(result);
122 }
123
126 {
127 // call the function of the underlying basis
128 m_src->stride_cwise(result);
129 }
130
131 void swapDirections(const unsigned i, const unsigned j)
132 {
134 size_cwise(sz);
135
136 // First swap the weights
137 swapTensorDirection(i, j, sz, m_weights);
138
139 // Then swap the basis components
140 m_src->swapDirections(i, j);
141 }
142
143 void uniformRefine_withCoefs(gsMatrix<T>& coefs, int numKnots = 1, int mul = 1, short_t const dir = -1)
144 {
145 GISMO_ASSERT( coefs.rows() == this->size() && m_weights.rows() == this->size(),
146 "Invalid dimensions" );
147
148 gsSparseMatrix<T, RowMajor> transfer;
149 if (dir==-1)
150 {
151 m_src->uniformRefine_withTransfer(transfer, numKnots, mul);
152
153 coefs = transfer * ( m_weights.asDiagonal() * coefs);
154 m_weights = transfer * m_weights;
155 // Alternative way
156 // gsBasis<T> * tmp = m_src->clone();
157 // tmp->uniformRefine_withCoefs(coefs, numKnots);
158 // delete tmp;
159 // m_src->uniformRefine_withCoefs(m_weights, numKnots);
160
161 // back to affine coefs
162 coefs.array().colwise() /= m_weights.col(0).array();
163 // equiv:
164 // for (int i = 0; i < coefs.rows(); ++i)
165 // coefs.row(i) /= m_weights.at(i);
166 }
167 else
168 {
169 GISMO_ASSERT( dir >= 0 && static_cast<unsigned>(dir) < d,
170 "Invalid basis component "<< dir <<" requested for degree elevation" );
171
172 gsVector<index_t,d> sz;
173 m_src->size_cwise(sz);
174 m_src->component(dir).uniformRefine_withTransfer( transfer, numKnots, mul );
175
176 const index_t coefs_cols = coefs.cols();
177 const index_t weights_cols = m_weights.cols();
178
179 coefs = m_weights.asDiagonal() * coefs; //<<<<-----this goes wrong!!
180 swapTensorDirection(0, dir, sz, coefs);
181 coefs.resize( sz[0], coefs_cols * sz.template tail<static_cast<short_t>(d-1)>().prod() );
182 coefs = transfer * coefs;
183
184 swapTensorDirection(0, dir, sz, m_weights);
185 m_weights.resize( sz[0], weights_cols * sz.template tail<static_cast<short_t>(d-1)>().prod() );
186 m_weights = transfer * m_weights;
187
188 sz[0] = coefs.rows();
189
190 coefs.resize( sz.prod(), coefs_cols );
191 m_weights.resize( sz.prod(), weights_cols );
192 swapTensorDirection(0, dir, sz, coefs);
193 swapTensorDirection(0, dir, sz, m_weights);
194
195 coefs.array().colwise() /= m_weights.col(0).array();
196 }
197 }
198
199#ifdef __DOXYGEN__
202#endif
203
204 GISMO_UPTR_FUNCTION_DEF(BoundaryBasisType, boundaryBasis, boxSide const &)
205 {
206 typename Src_t::BoundaryBasisType::uPtr bb = m_src->boundaryBasis(n1);
207 gsMatrix<index_t> ind = m_src->boundary(n1);
208
209 gsMatrix<T> ww( ind.size(),1);
210 for ( index_t i=0; i<ind.size(); ++i)
211 ww(i,0) = m_weights( (ind)(i,0), 0);
212
213 return new BoundaryBasisType(bb.release(), give(ww));// note: constructor consumes the pointer
214 }
215
216 void matchWith(const boundaryInterface & bi, const gsBasis<T> & other,
217 gsMatrix<index_t> & bndThis, gsMatrix<index_t> & bndOther) const
218 {
219 this->matchWith(bi,other,bndThis,bndOther,0);
220 }
221
222 // see gsBasis for documentation
223 void matchWith(const boundaryInterface & bi, const gsBasis<T> & other,
224 gsMatrix<index_t> & bndThis, gsMatrix<index_t> & bndOther, index_t offset) const
225 {
226 if ( const gsTensorNurbsBasis<d,T> * _other = dynamic_cast<const gsTensorNurbsBasis<d,T> *>(&other) )
227 m_src->matchWith(bi,_other->source(),bndThis,bndOther,offset);
228 else if ( const gsTensorBasis<d,T> * __other = dynamic_cast<const gsTensorBasis<d,T> *>(&other) )
229 m_src->matchWith(bi,*__other,bndThis,bndOther,offset);
230 else
231 gsWarn<<"Cannot match with "<<other<<"\n";
232 }
233
234
235protected:
236 using Base::m_src;
237 using Base::m_weights;
238
239};
240
241
242} // namespace gismo
243
244// *****************************************************************
245#ifndef GISMO_BUILD_LIB
246#include GISMO_HPP_HEADER(gsTensorNurbsBasis.hpp)
247#else
248#ifdef gsTensorNurbsBasis_EXPORT
249#include GISMO_HPP_HEADER(gsTensorNurbsBasis.hpp)
250#undef EXTERN_CLASS_TEMPLATE
251#define EXTERN_CLASS_TEMPLATE CLASS_TEMPLATE_INST
252#endif
253namespace gismo
254{
255EXTERN_CLASS_TEMPLATE gsTensorNurbsBasis<2,real_t>;
256EXTERN_CLASS_TEMPLATE gsTensorNurbsBasis<3,real_t>;
257EXTERN_CLASS_TEMPLATE gsTensorNurbsBasis<4,real_t>;
258}
259#endif
260// *****************************************************************
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
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
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
Class that creates a rational counterpart for a given basis.
Definition gsRationalBasis.h:48
index_t size() const
Definition gsRationalBasis.h:137
A tensor product B-spline basis.
Definition gsTensorBSplineBasis.h:37
memory::unique_ptr< Self_t > uPtr
Smart pointer for gsTensorBSplineBasis.
Definition gsTensorBSplineBasis.h:69
A tensor product Non-Uniform Rational B-spline (NURBS) basis.
Definition gsTensorNurbsBasis.h:38
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:118
gsBSplineTraits< d, T >::Basis Src_t
Source basis type.
Definition gsTensorNurbsBasis.h:52
Src_t::Basis_t Basis_t
Coordinate basis type.
Definition gsTensorNurbsBasis.h:55
gsRationalBasis< typename gsBSplineTraits< d, T >::Basis > Base
Base type.
Definition gsTensorNurbsBasis.h:46
void stride_cwise(gsVector< index_t, d > &result) const
Returns the strides for all dimensions.
Definition gsTensorNurbsBasis.h:125
T Scalar_t
Coefficient type.
Definition gsTensorNurbsBasis.h:58
memory::shared_ptr< gsTensorNurbsBasis > Ptr
Shared pointer for gsTensorNurbsBasis.
Definition gsTensorNurbsBasis.h:67
BoundaryBasisType::uPtr boundaryBasis(boxSide const &s)
Gives back the boundary basis at boxSide s.
memory::unique_ptr< gsTensorNurbsBasis > uPtr
Unique pointer for gsTensorNurbsBasis.
Definition gsTensorNurbsBasis.h:70
gsBSplineTraits< static_cast< short_t >(d-1), T >::RatBasis BoundaryBasisType
Associated Boundary basis type.
Definition gsTensorNurbsBasis.h:64
gsBSplineTraits< d, T >::RatGeometry GeometryType
Associated geometry type.
Definition gsTensorNurbsBasis.h:61
gsBSplineBasis< T > Family_t
Family type.
Definition gsTensorNurbsBasis.h:49
std::ostream & print(std::ostream &os) const
Prints the object as a string.
Definition gsTensorNurbsBasis.h:98
A tensor product Non-Uniform Rational B-spline function (NURBS) of parametric dimension d,...
Definition gsTensorNurbs.h:41
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
void swapTensorDirection(int k1, int k2, gsVector< index_t, d > &sz, gsMatrix< T > &coefs)
Definition gsTensorTools.h:129
#define short_t
Definition gsConfig.h:35
#define index_t
Definition gsConfig.h:32
#define gsWarn
Definition gsDebug.h:50
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Represents a NURBS basis with one parameter.
Provides declaration of RationalBasis class.
Provides declaration of TensorBSplineBasis abstract interface.
Utility functions related to tensor-structured objects.
The G+Smo namespace, containing all definitions for the library.
S give(S &x)
Definition gsMemory.h:266
Struct which represents an interface between two patches.
Definition gsBoundary.h:650
Traits for BSplineBasis in more dimensions.
Definition gsBSplineBasis.h:32