22 template<
short_t d,
class T>
27 for(
typename BasisContainer::const_iterator it = bases.begin();it!=bases.end();++it)
28 m_bases.push_back( (gsBasis<T>*)(*it)->clone().release());
29 if(increaseSmoothnessLevel==-1)
30 m_incrSmoothnessDegree=this->maxDegree()-1;
32 m_incrSmoothnessDegree=increaseSmoothnessLevel;
33 m_minDist=
static_cast<unsigned>(std::max<index_t>(std::min<index_t>(m_incrSmoothnessDegree+1,maxDegree()),minEVDistance));
35 _setDistanceOfAllVertices();
39 if(!_checkTopologyWithBases())
40 GISMO_ERROR(
"topology and bases not suitable for composite basis");
44 template<
short_t d,
class T>
49 for(
typename BasisContainer::const_iterator it = bases.begin();it!=bases.end();++it)
50 m_bases.push_back( (gsBasis<T>*)(*it)->clone().release());
51 if(increaseSmoothnessLevel==-1)
52 m_incrSmoothnessDegree=this->maxDegree()-1;
54 m_incrSmoothnessDegree=increaseSmoothnessLevel;
55 m_minDist=
static_cast<unsigned>(std::max<index_t>(std::min<index_t>(m_incrSmoothnessDegree+1,maxDegree()),minEVDistance));
57 _setDistanceOfAllVertices();
61 if(!_checkTopologyWithBases())
62 GISMO_ERROR(
"topology and bases not suitable for composite basis");
66 template<
short_t d,
class T>
71 for (
size_t i = 0; i < mp.nPatches(); i++)
73 GISMO_ASSERT(
dynamic_cast<gsTensorBSplineBasis<2> *
>(& mp.basis(i))!=NULL,
"Bases is not of type gsTensorBSplineBasis<2>");
76 m_bases = mp.basesCopy();
77 if(increaseSmoothnessLevel==-1)
78 m_incrSmoothnessDegree=this->maxDegree()-1;
80 m_incrSmoothnessDegree=increaseSmoothnessLevel;
81 m_minDist=
static_cast<unsigned>(std::max<index_t>(std::min<index_t>(m_incrSmoothnessDegree+1,maxDegree()),minEVDistance));
83 _setDistanceOfAllVertices();
87 if(!_checkTopologyWithBases())
88 GISMO_ERROR(
"topology and bases not suitable for composite basis");
92 template<
short_t d,
class T>
95 m_topol = other.m_topol;
96 m_vertices = other.m_vertices;
97 m_distances=other.m_distances;
98 m_minDist=other.m_minDist;
100 for(ConstBasisIter it = other.m_bases.begin();it!=other.m_bases.end();++it)
102 m_bases.push_back( (gsBasis<T>*)(*it)->clone().release() );
104 m_incrSmoothnessDegree=other.m_incrSmoothnessDegree;
105 if(!this->_checkTopologyWithBases())
106 GISMO_ERROR(
"topology and bases not suitable for composite basis");
108 m_mapper=
new gsWeightMapper<T>(*other.m_mapper);
112 template<
short_t d,
class T>
113 gsMPBESBSplineBasis<d,T> &gsMPBESBSplineBasis<d,T>::operator=(
const gsMPBESBSplineBasis& other )
115 m_topol=other.m_topol;
116 m_vertices=other.m_vertices;
117 m_distances=other.m_distances;
118 m_minDist=other.m_minDist;
121 for(ConstBasisIter it = other.m_bases.begin();it!=other.m_bases.end();++it)
122 m_bases.push_back((BasisType*)(*it)->clone().release());
126 m_incrSmoothnessDegree=other.m_incrSmoothnessDegree;
131 template<
short_t d,
class T>
138 m_mapper = maker.makeMapper();
141 template<
short_t d,
class T>
144 if(ps.side()==1||ps.side()==2)
145 return basis(ps.
patch).size(1);
147 return basis(ps.
patch).size(0);
150 template<
short_t d,
class T>
153 unsigned patch_i = _getPatch(i), patch_j = _getPatch(j);
154 if( patch_i != patch_j )
156 indexType loc_i = _getPatchIndex(i), loc_j = _getPatchIndex(j);
160 for(
unsigned i2=0; i2< d;++i2 )
162 unsigned dist =
std::abs(static_cast<index_t>(vec_i[i2])-static_cast<index_t>(vec_j[i2]));
169 template<
short_t d,
class T>
172 result.resize(u.cols());
173 for(
index_t i = 0; i<u.cols();++i)
175 result(i)=
static_cast<unsigned>((degree(patch,0)+1)*(degree(patch,1)+1));
179 template<
short_t d,
class T>
182 std::vector<std::vector<T> >refineKnots(2);
183 refineKnots[0]=knots_u;
184 refineKnots[1]=knots_v;
185 basis(patch).insertKnots(refineKnots);
193 template<
short_t d,
class T>
196 std::vector<std::vector<T> > refineKnots;
197 _boxToRefineKnots(patch,boxes,refineKnots);
198 refine(patch,refineKnots[0],refineKnots[1],updateBasis);
201 template<
short_t d,
class T>
205 _boxesVectorToMatrix(boxes,mat_boxes);
206 refine(patch,mat_boxes,updateBasis);
209 template<
short_t d,
class T>
213 std::vector<std::vector<T> >refineKnots(2);
214 refineKnots[0]=knots_u;
215 refineKnots[1]=knots_v;
216 std::vector<gsMatrix<T> *> coefs;
217 unsigned geoDim = localCoef.cols();
219 for (
size_t i = 0; i<nPatches(); ++i)
222 end+=basis(i).size();
224 *localMat << localCoef.block(start,0,end-start+1,geoDim);
225 coefs.push_back(localMat);
227 basis(patch).refine_withCoefs(*coefs[patch],refineKnots);
229 repairPatches(coefs,patch);
230 unsigned totalSize=0;
231 for (
size_t i = 0; i<nPatches(); ++i)
233 totalSize+=basis(i).size();
235 localCoef.resize(totalSize,geoDim);
237 for (
size_t i = 0;i<nPatches();i++)
240 end+=basis(i).size();
241 localCoef.block(start,0,end-start+1,geoDim) << *coefs[i];
248 template<
short_t d,
class T>
252 std::vector<std::vector<T> > refineKnots;
253 _boxToRefineKnots(patch,boxes,refineKnots);
254 refine_withCoefs(coefs,patch,refineKnots[0],refineKnots[1],updateBasis);
257 template<
short_t d,
class T>
262 _boxesVectorToMatrix(boxes,mat_boxes);
263 refine_withCoefs(coefs,patch,mat_boxes,updateBasis);
266 template<
short_t d,
class T>
269 GISMO_ASSERT( boxes.size() % (2 * d + 1 ) == 0,
"The points did not define boxes properly. The boxes were not added to the basis.");
270 mat_boxes.resize(2,2*(boxes.size()/(2*d + 1)));
271 for(
unsigned index_t i = 0; i < (boxes.size())/(2*d+1); i++)
273 mat_boxes(0,2*i)=boxes[(i*(2*d+1))+1];
274 mat_boxes(1,2*i)=boxes[(i*(2*d+1))+2];
275 mat_boxes(0,2*i+1)=boxes[(i*(2*d+1))+3];
276 mat_boxes(1,2*i+1)=boxes[(i*(2*d+1))+4];
280 template<
short_t d,
class T>
281 void gsMPBESBSplineBasis<d,T>::_boxToRefineKnots(
const index_t patch,gsMatrix<T>
const & boxes,std::vector<std::vector<T> > & refineKnots)
283 gsTensorBSplineBasis<d,T> & this_base=basis(patch);
284 GISMO_ASSERT( boxes.rows() == this_base.dim() ,
"Number of rows of refinement boxes must equal dimension of parameter space.");
285 GISMO_ASSERT( boxes.cols() % 2 == 0,
"Refinement boxes must have even number of columns.");
287 const T tol = 0.000000001;
288 gsKnotVector<T> knots_u = this_base.component(0).knots();
289 gsKnotVector<T> knots_v = this_base.component(1).knots();
290 std::vector<T> ins_knots_u;
291 std::vector<T> ins_knots_v;
292 for(
size_t i = 1;i < knots_u.size();i++)
293 if( knots_u[i]-knots_u[i-1] > tol)
295 T midpt = knots_u[i-1] + (knots_u[i]-knots_u[i-1])/2;
296 for(
index_t j=0; j < boxes.cols(); j+=2 )
298 if( boxes(0,j) < midpt && midpt < boxes(0,j+1) )
299 ins_knots_u.push_back(midpt);
302 for(
size_t i = 1;i < knots_v.size();i++)
303 if( knots_v[i]-knots_v[i-1] > tol)
305 T midpt = knots_v[i-1] + (knots_v[i]-knots_v[i-1])/2;
306 for(
index_t j=0; j < boxes.cols(); j+=2 )
308 if( boxes(1,j) < midpt && midpt < boxes(1,j+1) )
309 ins_knots_v.push_back(midpt);
312 refineKnots.resize(2);
313 refineKnots[0]=ins_knots_u;
314 refineKnots[1]=ins_knots_v;
317 template<
short_t d,
class T>
318 unsigned gsMPBESBSplineBasis<d,T>::getNrOfSpecialKnots(
const gsKnotVector<T> kv,
const std::vector<T>& new_knots,
bool par,
index_t distance)
320 index_t specialKnots=0, index = 0, kv_index, nk_index;
321 for(
index_t i=0;i<=distance+kv.degree();++i)
323 kv_index = par ? kv.size()-i-1 : i;
324 nk_index = par ? new_knots.size()-index-1 : index;
325 if(nk_index>=static_cast<index_t>(new_knots.size())||nk_index<0)
327 if((!par&&new_knots[nk_index]<=kv.at(kv_index))||
328 (par&&new_knots[nk_index]>=kv.at(kv_index)))
337 template<
short_t d,
class T>
341 std::set<index_t> toCheck;
342 if(startFromPatch==-1)
343 for(
unsigned i = 0;i<m_bases.size();++i)
346 toCheck.insert(startFromPatch);
350 curElement=*(toCheck.begin());
351 toCheck.erase(curElement);
352 std::vector<std::vector<T> >refineKnots;
353 std::vector<index_t> checkPatches;
354 bool matched = _knotsMatchNeighbours(curElement,refineKnots,checkPatches);
357 if(coefs[curElement]!=NULL)
358 basis(curElement).refine_withCoefs(*(coefs[curElement]),refineKnots);
360 basis(curElement).insertKnots(refineKnots);
362 for(
unsigned i = 0;i<checkPatches.size();++i)
364 toCheck.insert(checkPatches[i]);
366 }
while(!toCheck.empty());
369 template<
short_t d,
class T>
371 std::vector<index_t>& checkPatches,
378 knotsToInsert.resize(2);
379 checkPatches.clear();
380 checkPatches.reserve(nPatches());
381 std::vector<bool> sideToCheck(4,
false);
382 std::vector<index_t> neighbours(4,-1);
384 knotIter kv,kv_end,kvN,kvN_end;
388 if( !m_topol.getNeighbour(ps,ps_neigh) )
390 knots_neigh = basis(ps_neigh.
patch).knots(1-(ps_neigh.
direction()));
392 m_topol.getInterface(ps,bf);
393 if(!bf.dirOrientation(ps,1-ps.
direction()))
395 kv = base.knots(1-side.direction()).begin();
396 kv_end = base.knots(1-side.direction()).end();
397 kvN = knots_neigh.
begin();
398 kvN_end = knots_neigh.
end();
399 neighbours[side-1]=ps_neigh.
patch;
400 while(kv != kv_end || kvN != kvN_end)
410 sideToCheck[side-1]=
true;
414 knotsToInsert[1-side.direction()].push_back(*kvN);
417 sideToCheck[side.opposite()-1]=
true;
422 sort( knotsToInsert[0].begin(), knotsToInsert[0].end() );
423 knotsToInsert[0].erase( unique( knotsToInsert[0].begin(), knotsToInsert[0].end() ), knotsToInsert[0].end() );
424 sort( knotsToInsert[1].begin(), knotsToInsert[1].end() );
425 knotsToInsert[1].erase( unique( knotsToInsert[1].begin(), knotsToInsert[1].end() ), knotsToInsert[1].end() );
427 for(
unsigned i = 0;i<4;i++)
429 if(sideToCheck[i]&&neighbours[i]!=-1)
430 checkPatches.push_back(neighbours[i]);
435 template<
short_t d,
class T>
internal::gsUKnotIterator< T > uiterator
Definition: gsKnotVector.h:102
A univariate Lagrange basis.
Definition: gsMPBESBSplineBasis.h:32
Knot vector for B-splines.
Provides declaration of Basis abstract interface.
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
Provides declaration of Basis abstract interface.
Struct which represents a certain side of a patch.
Definition: gsBoundary.h:231
T distance(gsMatrix< T > const &A, gsMatrix< T > const &B, index_t i=0, index_t j=0, bool cols=false)
compute a distance between the point number in the set and the point number <j> in the set ; by def...
static boxSide getFirst(short_t)
helper for iterating on sides of an n-dimensional box
Definition: gsBoundary.h:160
void repairPatches(std::vector< gsMatrix< T > * > &coefs, index_t startFromPatch=-1)
Definition: gsMPBESBSplineBasis.hpp:338
void _setMapping()
create a new mapping of the local basisfunctions
Definition: gsMPBESBSplineBasis.hpp:132
#define index_t
Definition: gsConfig.h:32
std::vector< T >::const_iterator iterator
Definition: gsKnotVector.h:97
A tensor product B-spline basis.
Definition: gsTensorBSplineBasis.h:36
Struct which represents a certain corner of a patch.
Definition: gsBoundary.h:392
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
A univariate Lagrange basis.
Definition: gsMPBESMapB2D.h:39
void refineElements(const index_t patch, std::vector< index_t > const &boxes, bool updateBasis=true)
Definition: gsMPBESBSplineBasis.hpp:202
T findParameter(patchSide const &ps, patchCorner const &pc, unsigned nrBasisFuncs) const
Definition: gsMPBESBSplineBasis.hpp:436
static boxSide getEnd(short_t dim)
helper for iterating on sides of an n-dimensional box
Definition: gsBoundary.h:176
uiterator ubegin() const
Returns unique iterator pointing to the beginning of the unique knots.
Definition: gsKnotVector.hpp:235
void freeAll(It begin, It end)
Frees all pointers in the range [begin end)
Definition: gsMemory.h:312
Struct which represents a certain side of a box.
Definition: gsBoundary.h:84
void numActive_into(const index_t patch, const gsMatrix< T > &u, gsVector< index_t > &result) const
Returns the number of active (nonzero) basis functions at points u in result.
Definition: gsMPBESBSplineBasis.hpp:170
unsigned basisFunctionsOnSide(const patchSide &ps) const
Returns the amount of basis functions on a given side of a given patch.
Definition: gsMPBESBSplineBasis.hpp:142
gsMPBESBSplineBasis()
Default empty constructor.
Definition: gsMPBESBSplineBasis.h:78
iterator end() const
Returns iterator pointing past the end of the repeated knots.
Definition: gsKnotVector.hpp:124
void reverse()
Better directly use affineTransformTo.
Definition: gsKnotVector.hpp:468
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
Class for representing a knot vector.
Definition: gsKnotVector.h:79
void refineElements_withCoefs(gsMatrix< T > &coefs, const index_t patch, std::vector< index_t > const &boxes, bool updateBasis=true)
Definition: gsMPBESBSplineBasis.hpp:258
EIGEN_STRONG_INLINE abs_expr< E > abs(const E &u)
Absolute value.
Definition: gsExpressions.h:4486
Struct which represents an interface between two patches.
Definition: gsBoundary.h:649
iterator begin() const
Returns iterator pointing to the beginning of the repeated knots.
Definition: gsKnotVector.hpp:117
index_t patch
The index of the patch.
Definition: gsBoundary.h:234
short_t direction() const
Returns the parametric direction orthogonal to this side.
Definition: gsBoundary.h:113
Provides declaration of TensorBSplineBasis abstract interface.