26 #if defined __INTEL_COMPILER
27 #pragma warning (disable : 175 )
33 template<
short_t d,
class T>
36 GISMO_ASSERT( d==2,
"gsTensorBasis error: wrong dimension." );
38 if ( x->dim() == 1 && y->dim() == 1 )
43 GISMO_ERROR(
"gsTensorBasis error: Spaces must be of topological dimension 1.");
47 template<
short_t d,
class T>
50 GISMO_ASSERT( d==3,
"gsTensorBasis error: wrong dimension." );
52 GISMO_ASSERT( x->dim() == 1 && y->dim() == 1 && z->dim() == 1,
53 "Spaces must be of topological dimension 1." );
62 GISMO_ERROR(
"gsTensorBasis incorrect constructor for "<<d<<
"D basis");
65 template<
short_t d,
class T>
68 GISMO_ASSERT( d==4,
"gsTensorBasis error: wrong dimension." );
70 GISMO_ASSERT( x->dim() == 1 && y->dim() == 1 && z->dim() == 1 && w->dim() == 1,
71 "Spaces must be of topological dimension 1." );
81 GISMO_ERROR(
"gsTensorBasis incorrect constructor for "<<d<<
"D basis");
98 template<
short_t d,
class T>
102 for (
short_t i = 0; i < d; ++i)
103 m_bases[i] = o.m_bases[i]->
clone().release();
107 template<
short_t d,
class T>
114 for (
short_t i = 0; i < d; ++i)
117 m_bases[i] = o.m_bases[i]->
clone().release();
123 template<
short_t d,
class T>
128 result.resize( d, this->size() );
130 for (
short_t i = 0; i < d; ++i)
132 gr[i] = m_bases[i]->anchors();
133 size[i] = this->size(i);
141 for (
unsigned i=0; i<d; ++i )
142 result(i,r)= (gr[i])( 0, v(i) );
147 template<
short_t d,
class T>
155 for (
short_t l = 0; l < d; ++l)
157 m_bases[l]->anchor_into(ti[l], gr);
158 result(l,0) = gr.value();
162 template<
short_t d,
class T>
170 for(
index_t i = 0; i< sz; ++i )
171 mesh.addVertex( nodes.row(i).transpose() );
178 for (
short_t i = 0; i < d; ++i)
179 end(i) = this->size(i) - 1;
183 for (
short_t i = 0; i < d; ++i)
193 for (
index_t j = 0; j != end[i]; ++j)
195 mesh.addEdge(k, k + s );
203 template<
short_t d,
class T>
213 for (
short_t i = 0; i < d; ++i)
215 m_bases[i]->active_into(u.row(i), act[i]);
216 size[i] = act[i].rows();
220 result.resize( nb, u.cols() );
227 for (
index_t j=0; j<u.cols(); ++j)
229 nb = act[d-1]( v(d-1) ,j) ;
230 for (
short_t i=d-2; i>=0; --i )
231 nb = nb * m_bases[i]->size() + act[i](v(i), j) ;
238 template<
short_t d,
class T>
243 for (
short_t k = 0; k < d; ++k)
244 if ( ! m_bases[k]->isActive(ti[k], u.row(k)) )
249 template<
short_t d,
class T>
252 GISMO_ASSERT( dir>=0 && dir < this->dim(),
"Invalid slice direction requested" );
253 GISMO_ASSERT( k >=0 && k < this->size(dir),
"Invalid slice position requested" );
259 for (
short_t i = 0; i < d; ++i)
261 sliceSize *= this->size(i);
263 upp(r++) = this->size(i);
265 sliceSize /= upp(dir);
275 res(r++,0) = this->index(v);
282 template<
short_t d,
class T>
286 std::set<index_t> bdofs;
288 for (
short_t k = 0; k != d; ++k)
290 bd = this->coefSlice(k, 0);
291 for (
index_t i = 0; i < bd.size(); ++i)
292 bdofs.insert( bd(i) );
294 bd = this->coefSlice(k, size(k) - 1);
295 for (
index_t i = 0; i < bd.size(); ++i)
296 bdofs.insert( bd(i) );
299 return makeMatrix<index_t>(bdofs.begin(),
static_cast<index_t>(bdofs.size()), 1 );
303 template<
short_t d,
class T>
309 GISMO_ASSERT(offset < size(k),
"Offset cannot be bigger than the amount of basis functions orthogonal to Boxside s!");
310 return (this->coefSlice(k, (r ? size(k) - 1 -offset : offset) ));
313 template<
short_t d,
class T>
326 index+= str * ( sz_i - 1 );
375 template<
short_t d,
class T>
383 for (
short_t i=0; i < d; ++i )
385 rr.push_back(m_bases[i]->clone().
release());
389 template<
short_t d,
class T>
393 for (
short_t i = 0; i < d; ++i)
394 res.row(i) = m_bases[i]->support();
398 template<
short_t d,
class T>
404 for (
short_t j = 0; j < d; ++j)
405 res.row(j) = m_bases[j]->support( ti[j] );
409 template<
short_t d,
class T>
414 result.resize(1,u.cols() );
420 this->m_bases[0]->evalSingle_into(ti[0], u.row(0), result);
421 for (
short_t k = 1; k < d; ++k)
423 this->m_bases[k]->evalSingle_into( ti[k], u.row(k), ev);
424 result = result.cwiseProduct(ev);
428 template<
short_t d,
class T>
434 ti.noalias() = tensorIndex(i);
436 result.setOnes(d, u.cols() );
438 for (
short_t k = 0; k != d; ++k)
440 m_bases[k]->evalSingle_into ( ti[k], u.row(k), ev );
441 m_bases[k]->derivSingle_into( ti[k], u.row(k), dev );
443 result.row(k) = result.row(k).cwiseProduct(dev);
444 result.topRows(k) = result.topRows(k) * ev.asDiagonal();
447 result.bottomRows(d-k-1) = result.bottomRows(d-k-1) * ev.asDiagonal();
453 template<
short_t d,
class T>
459 ti.noalias() = tensorIndex(i);
461 result.setOnes( d*(d + 1)/2, u.cols() );
464 for (
short_t k = 0; k != d; ++k)
466 m_bases[k]->evalSingle_into ( ti[k], u.row(k), ev[k] );
467 m_bases[k]->derivSingle_into( ti[k], u.row(k), dev[k] );
471 for (
short_t k = 0; k != d; ++k)
474 m_bases[k]->deriv2Single_into( ti[k], u.row(k), ddev );
475 result.row(k) = result.row(k).cwiseProduct(ddev);
478 result.topRows(k) = result.topRows(k) * ev[k].asDiagonal();
479 result.middleRows(k+1,d-k-1) = result.middleRows(k+1, d-k-1) * ev[k].asDiagonal();
482 for (
short_t l = k+1; l != d; ++l)
485 result.row(c) = result.row(c).cwiseProduct(dev[k]);
487 result.row(c) = result.row(c).cwiseProduct(dev[l]);
490 for (
short_t r = 0; r != k; ++r)
491 result.row(c) = result.row(c).cwiseProduct(ev[r]);
492 for (
short_t r = k+1; r != l; ++r)
493 result.row(c) = result.row(c).cwiseProduct(ev[r]);
494 for (
short_t r = l+1; r < d; ++r)
495 result.row(c) = result.row(c).cwiseProduct(ev[r]);
501 template<
short_t d,
class T>
506 "Attempted to evaluate the tensor-basis on points with the wrong dimension" );
515 for (
short_t i = 0; i < d; ++i)
517 m_bases[i]->eval_into( u.row(i), ev[i] );
519 size[i] = ev[i].rows();
523 result.resize( nb, u.cols() );
530 result.row( r )= ev[0].row( v(0) );
532 result.row( r )= result.row( r ).cwiseProduct( ev[i].row( v(i) ) ) ;
538 template<
short_t d,
class T>
546 result.resize( coefs.cols(), u.cols() ) ;
548 unsigned sz = this->size()/m_bases[0]->size();
549 unsigned n = coefs.cols();
553 for (
index_t j=0; j< u.cols() ; j++ )
559 m_bases[0]->eval_into(uu.row(0), cc, e0);
561 for (
short_t i=1; i< d ; ++i )
563 sz /= m_bases[i]->size();
564 e0.resize( m_bases[i]->size(), n * sz );
566 m_bases[i]->eval(uu.row(i), e0, e1);
577 result.resize( coefs.cols(), u.cols() ) ;
581 this->eval_into(u, B);
582 this->active_into(u,ind);
584 for (
index_t j=0; j< u.cols() ; j++ )
586 result.col(j) = coefs.row( ind(0,j) ) * B(0,j);
587 for (
index_t i = 1; i < ind.rows(); ++i )
588 result.col(j) += coefs.row( ind(i,j) ) * B(i,j);
593 template<
short_t d,
class T>
597 std::vector<gsMatrix<T> > values[d];
602 for (
short_t i = 0; i < d; ++i)
605 m_bases[i]->evalAllDers_into( u.row(i), 1, values[i]);
608 const index_t num_i = values[i].front().rows();
613 result.resize( d*nb, u.cols() );
621 const index_t rownum = r*d + k;
622 result.row(rownum) = values[k][1].row( v(k) );
624 result.row(rownum).array() *= values[i][0].row( v(i) ).array();
626 result.row(rownum).array() *= values[i][0].row( v(i) ).array();
633 template<
short_t d,
class T>
636 bool sameElement)
const
638 GISMO_ASSERT(n>-2,
"gsTensorBasis::evalAllDers() is implemented only for -2<n<=2: -1 means no value, 0 values only, ... " );
645 std::vector< gsMatrix<T> >values[d];
650 for (
short_t i = 0; i < d; ++i)
653 m_bases[i]->evalAllDers_into( u.row(i), n, values[i], sameElement);
656 const index_t num_i = values[i].front().rows();
664 vals.resize(nb, u.cols());
669 vals.row( r )= values[0].front().row( v[0] );
671 vals.row(r).array() *= values[i].front().row( v[i] ).array();
680 der.resize(d*nb, u.cols());;
688 der.row(r) = values[k][1].row( v(k) );
690 der.row(r).array() *= values[i][0].row( v(i) ).array();
692 der.row(r).array() *= values[i][0].row( v(i) ).array();
701 deriv2_tp( values, nb_cwise, result[2] );
704 for (
int i = 3; i <=n; ++i)
717 der.row(r) = values[0][cc[0]].row(v[0]);
719 der.row(r).array() *= values[k][cc[k]].row(v[k]).array();
730 template<
short_t d,
class T>
734 std::vector< gsMatrix<T> >values[d];
737 for (
short_t i = 0; i < d; ++i)
739 m_bases[i]->evalAllDers_into( u.row(i), 2, values[i]);
740 const int num_i = values[i].front().rows();
744 deriv2_tp(values, nb_cwise, result);
749 template<
short_t d,
class T>
754 const unsigned nb = nb_cwise.prod();
755 const unsigned stride = d + d*(d-1)/2;
757 result.resize( stride*nb, values[0][0].cols() );
768 result.row(cur) = values[k][2].row( v.
at(k) ) ;
770 result.row(cur).array() *= values[i][0].row( v.
at(i) ).array();
772 result.row(cur).array() *= values[i][0].row( v.
at(i) ).array();
777 result.row(cur).noalias() =
778 values[k][1].row( v.
at(k) ).cwiseProduct( values[l][1].row( v.
at(l) ) );
780 result.row(cur).array() *= values[i][0].row( v.
at(i) ).array() ;
782 result.row(cur).array() *= values[i][0].row( v.
at(i) ).array();
784 result.row(cur).array() *= values[i][0].row( v.
at(i) ).array() ;
794 template<
short_t d,
class T>
801 for (
typename std::vector<index_t>::const_iterator
802 it = elements.begin(); it != elements.end(); ++it )
807 const index_t nEl_i = m_bases[i]->numElements();
809 mm = (mm - tmp) / nEl_i;
810 elIndices[i].push_sorted_unique(tmp);
818 m_bases[i]->refineElements(elIndices[i]);
823 template<
short_t d,
class T>
831 this->uniformRefine_withTransfer( transfer, numKnots, mul );
832 coefs = transfer * coefs;
836 GISMO_ASSERT( dir >= 0 && static_cast<unsigned>(dir) < d,
837 "Invalid basis component "<< dir <<
" requested for uniform refinement." );
840 this->size_cwise(sz);
843 this->m_bases[dir]->uniformRefine_withTransfer( transfer, numKnots, mul );
845 const index_t n = coefs.cols();
848 coefs.resize( sz[0], n * sz.template tail<static_cast<short_t>(d-1)>().prod() );
850 coefs = transfer * coefs;
852 sz[0] = coefs.rows();
854 coefs.resize( sz.prod(), n );
860 template<
short_t d,
class T>
866 for (
short_t i = 0; i < d; ++i)
868 m_bases[i]->uniformRefine_withTransfer( B[i], numKnots, mul );
871 tensorCombineTransferMatrices<d, T>( B, transfer );
875 template<
short_t d,
class T>
881 for (
short_t i = 0; i < d; ++i)
883 m_bases[i]->uniformCoarsen_withTransfer( B[i], numKnots );
886 tensorCombineTransferMatrices<d, T>( B, transfer );
889 template<
short_t d,
class T>
890 typename gsTensorBasis<d,T>::domainIter
896 template<
short_t d,
class T>
897 typename gsTensorBasis<d,T>::domainIter
900 return ( s == boundary::none ?
906 template<
short_t d,
class T>
910 std::vector<gsMatrix<T> > grid(d);
912 for (
short_t i = 0; i < d; ++i)
913 m_bases[i]->anchors_into(grid[i]);
915 return interpolateGrid(vals,grid);
919 template<
short_t d,
class T>
925 "Expecting as many values as the number of basis functions." );
928 const int sz = this->size();
934 typename gsSparseSolver<T>::LU solver;
938 q0 = vals.transpose();
940 for (
short_t i = 0; i < d; ++i)
943 const index_t sz_i = m_bases[i]->size();
945 q0.resize(sz_i, n * r_i);
948 Cmat = m_bases[i]->collocationMatrix(grid[i]);
949 solver.compute(Cmat);
953 gsWarn<<
"Failed LU decomposition for:\n";
954 gsWarn<<
"Points:\n"<< grid[i] <<
"\n";
955 gsWarn<<
"Knots:\n"<< m_bases[i]->detail() <<
"\n";
960 q1.resize(r_i, n * sz_i);
961 for (
index_t k = 0; k!=n; ++k)
962 q1.middleCols(k*sz_i, sz_i) = solver.solve(q0.middleCols(k*r_i,r_i)).transpose();
968 return this->makeGeometry(
give(q0) );
972 template<
short_t d,
class T>
979 if (
const Self_t * _other = dynamic_cast<const Self_t*>(&other) )
982 bndThis = this->boundaryOffset( bi.
first() .side(), offset );
983 bndOther= _other->boundaryOffset( bi.
second().side(), offset );
985 "Input error, sizes do not match: "
986 <<bndThis.rows()<<
"!="<<bndOther.rows() );
987 if (bndThis.size() == 1)
return;
1002 bSize[c] = this->component(k).size();
1010 for (
short_t k = 0; k<d; ++k )
1018 bPerm[c] = ( bMap[k] < s2 ? bMap[k] : bMap[k]-1 );
1029 gsWarn<<
"Cannot match with "<< other <<
"\n";
1032 template<
short_t d,
class T>
1038 this->matchWith(bi,other,bndThis,bndOther,0);
1041 template<
short_t d,
class T>
1045 for (
short_t i = 0; i < d; ++i)
1047 const T sz = m_bases[i]->getMinCellLength();
1048 if ( sz < h || h == 0 ) h = sz;
1053 template<
short_t d,
class T>
1057 for (
short_t i = 0; i < d; ++i)
1059 const T sz = m_bases[i]->getMaxCellLength();
1060 if ( sz > h ) h = sz;
1065 template<
short_t d,
class T>
1070 for (
short_t i = 0; i < d; ++i)
1072 el = m_bases[i]->elementInSupportOf(ti[i]);
Re-implements gsDomainIterator for iteration over all elements of a tensor product parameter domain...
Definition: gsTensorDomainIterator.h:35
Iterator over the elements of a tensor-structured grid.
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: gsTensorBasis.hpp:410
void parameters_into(index_t dim, gsVector< bool > ¶m) const
returns a vector of parameters describing the position of the corner
Definition: gsBoundary.h:322
std::vector< T * > release(std::vector< unique_ptr< T > > &cont)
Takes a vector of smart pointers, releases them and returns the corresponding raw pointers...
Definition: gsMemory.h:228
Creates a mapped object or data pointer to a matrix without copying data.
Definition: gsLinearAlgebra.h:126
bool nextCubePoint(Vec &cur, const Vec &end)
Iterate in lexigographic order through the points of the integer lattice contained in the cube [0...
Definition: gsCombinatorics.h:327
virtual 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: gsTensorBasis.hpp:454
void uniformCoarsen_withTransfer(gsSparseMatrix< T, RowMajor > &transfer, int numKnots=1)
Coarsen the basis uniformly and produce a sparse matrix which maps coarse coefficient vectors to refi...
Definition: gsTensorBasis.hpp:876
void firstComposition(typename Vec::Scalar sum, index_t dim, Vec &res)
Construct first composition of sum into dim integers.
Definition: gsCombinatorics.h:657
#define short_t
Definition: gsConfig.h:35
Provides structs and classes related to interfaces and boundaries.
void anchor_into(index_t i, gsMatrix< T > &result) const
Returns the anchors (graville absissae) that represent the members of the basis.
Definition: gsTensorBasis.hpp:148
bool parameter() const
Returns the parameter value (false=0=start, true=1=end) that corresponds to this side.
Definition: gsBoundary.h:128
virtual void connectivity(const gsMatrix< T > &nodes, gsMesh< T > &mesh) const
Definition: gsTensorBasis.hpp:163
void swapTensorDirection(int k1, int k2, gsVector< index_t, d > &sz, gsMatrix< T > &coefs)
Definition: gsTensorTools.h:129
S give(S &x)
Definition: gsMemory.h:266
Provides declaration of Geometry abstract interface.
void flipTensorVector(const int dir, const gsVector< index_t, d > &sz, gsMatrix< T > &coefs)
Flips tensor directions in place.
Definition: gsTensorTools.h:201
#define index_t
Definition: gsConfig.h:32
This class is derived from std::vector, and adds sort tracking.
Definition: gsSortedVector.h:109
void refineElements(std::vector< index_t > const &elements)
Refine elements defined by their tensor-index.
Definition: gsTensorBasis.hpp:795
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
bool nextComposition(Vec &v)
Returns (inplace) the next composition in lexicographic order.
Definition: gsCombinatorics.h:667
gsMatrix< T > elementInSupportOf(index_t j) const
Returns (the coordinates of) an element in the support of basis function j.
Definition: gsTensorBasis.hpp:1066
virtual void eval_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluates nonzero basis functions at point u into result.
Definition: gsTensorBasis.hpp:502
Class Representing a triangle mesh with 3D vertices.
Definition: gsMesh.h:31
virtual void evalAllDers_into(const gsMatrix< T > &u, int n, std::vector< gsMatrix< T > > &result, bool sameElement=false) const
Evaluate the nonzero functions and their derivatives up to order n at points u into result...
Definition: gsTensorBasis.hpp:634
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition: gsVector.h:35
#define gsWarn
Definition: gsDebug.h:50
virtual T getMinCellLength() const
Get the minimum mesh size, as expected for inverse inequalities.
Definition: gsTensorBasis.hpp:1042
Re-implements gsDomainIterator for iteration over all elements of the boundary of a tensor product pa...
Definition: gsTensorDomainBoundaryIterator.h:37
virtual 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: gsTensorBasis.hpp:429
T at(index_t i) const
Returns the i-th element of the vector.
Definition: gsVector.h:177
bool isActive(const index_t i, const gsVector< T > &u) const
Returns true if there the point u with non-zero value or derivatives when evaluated at the basis func...
Definition: gsTensorBasis.hpp:239
Abstract base class for tensor product bases.
Definition: gsTensorBasis.h:33
Struct which represents a certain side of a box.
Definition: gsBoundary.h:84
gsMatrix< T > support() const
Returns (a bounding box for) the domain of the whole basis.
Definition: gsTensorBasis.hpp:390
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
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: gsTensorBasis.hpp:204
void anchors_into(gsMatrix< T > &result) const
Returns the anchors (graville absissae) that represent the members of the basis.
Definition: gsTensorBasis.hpp:124
Provides declaration of the Mesh class.
uPtr clone()
Clone methode. Produceds a deep copy inside a uPtr.
memory::unique_ptr< gsGeometry > uPtr
Unique pointer for gsGeometry.
Definition: gsGeometry.h:100
gsGeometry< T >::uPtr interpolateGrid(gsMatrix< T > const &vals, std::vector< gsMatrix< T > >const &grid) const
Definition: gsTensorBasis.hpp:921
virtual void deriv_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluates the first partial derivatives of the nonzero basis function.
Definition: gsTensorBasis.hpp:594
gsMatrix< index_t > coefSlice(short_t dir, index_t k) const
Returns all the basis functions with tensor-numbering.
Definition: gsTensorBasis.hpp:250
gsMatrix< index_t > boundaryOffset(boxSide const &s, index_t offset) const
Definition: gsTensorBasis.hpp:304
bool nextLexicographic(Vec &cur, const Vec &size)
Iterates through a tensor lattice with the given size. Updates cur and returns true if another entry ...
Definition: gsCombinatorics.h:196
virtual void deriv2_into(const gsMatrix< T > &u, gsMatrix< T > &result) const
Evaluate the second derivatives of all active basis function at points u.
Definition: gsTensorBasis.hpp:731
gsMatrix< index_t > allBoundary() const
Definition: gsTensorBasis.hpp:283
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
void permuteTensorVector(const gsVector< index_t, d > &perm, gsVector< index_t, d > &sz, gsMatrix< T > &coefs)
Definition: gsTensorTools.h:169
Iterator over the boundary elements of a tensor-structured grid.
patchSide & second()
second, returns the second patchSide of this interface
Definition: gsBoundary.h:782
gsBasis< T >::domainIter makeDomainIterator() const
Create a domain iterator for the computational mesh of this basis, that points to the first element o...
Definition: gsTensorBasis.hpp:891
void uniformRefine_withCoefs(gsMatrix< T > &coefs, int numKnots=1, int mul=1, int dir=-1)
Definition: gsTensorBasis.hpp:824
Struct which represents an interface between two patches.
Definition: gsBoundary.h:649
void uniformRefine_withTransfer(gsSparseMatrix< T, RowMajor > &transfer, int numKnots=1, int mul=1)
Definition: gsTensorBasis.hpp:861
unsigned numCompositions(int sum, short_t dim)
Number of compositions of sum into dim integers.
Definition: gsCombinatorics.h:691
virtual T getMaxCellLength() const
Get the maximum mesh size, as expected for approximation error estimates.
Definition: gsTensorBasis.hpp:1054
Struct which represents a certain corner of a hyper-cube.
Definition: gsBoundary.h:291
virtual gsGeometry< T >::uPtr interpolateAtAnchors(gsMatrix< T > const &vals) const
Applies interpolation of values pts using the anchors as parameter points. May be reimplemented in de...
Definition: gsTensorBasis.hpp:908
short_t direction() const
Returns the parametric direction orthogonal to this side.
Definition: gsBoundary.h:113
A basis represents a family of scalar basis functions defined over a common parameter domain...
Definition: gsBasis.h:78
patchSide & first()
first, returns the first patchSide of this interface
Definition: gsBoundary.h:776