20 template<
short_t d,
class T>
24 typedef typename std::vector<BasisType *>::const_iterator tempBasisIter;
26 for(tempBasisIter it = bases.begin();it!=bases.end();++it)
27 m_bases.push_back((BasisType*)(*it)->clone().release());
28 if(increaseSmoothnessLevel==-1)
29 m_incrSmoothnessDegree=this->maxDegree()-1;
31 m_incrSmoothnessDegree=increaseSmoothnessLevel;
32 m_minDist=
static_cast<unsigned>(std::max<index_t>(std::min<index_t>(m_incrSmoothnessDegree+1,maxDegree()),minEVDistance));
34 _setDistanceOfAllVertices();
38 if(!_checkTopologyWithBases())
39 GISMO_ERROR(
"topology and bases not suitable for composite basis");
43 template<
short_t d,
class T>
45 std::vector<gsMatrix<T> * > & coefs,
index_t increaseSmoothnessLevel,
index_t minEVDistance)
48 for(
typename BasisContainer::const_iterator it = bases.begin();it!=bases.end();++it)
49 m_bases.push_back( (gsBasis<T>*)(*it)->clone().release());
50 if(increaseSmoothnessLevel==-1)
51 m_incrSmoothnessDegree=this->maxDegree()-1;
53 m_incrSmoothnessDegree=increaseSmoothnessLevel;
54 m_minDist=
static_cast<unsigned>(std::max<index_t>(std::min<index_t>(m_incrSmoothnessDegree+1,maxDegree()),minEVDistance));
56 _setDistanceOfAllVertices();
60 if(!_checkTopologyWithBases())
61 GISMO_ERROR(
"topology and bases not suitable for composite basis");
65 template<
short_t d,
class T>
69 m_bases.push_back((BasisType *)base.clone().release());
70 m_incrSmoothnessDegree=this->maxDegree()-1;
71 m_minDist=
static_cast<unsigned>(std::min<index_t>(m_incrSmoothnessDegree+1,maxDegree()));
73 _setDistanceOfAllVertices();
77 _checkTopologyWithBases();
81 template<
short_t d,
class T>
86 for (
size_t i = 0; i < mp.nPatches(); i++)
88 GISMO_ASSERT(
dynamic_cast<gsHTensorBasis<2> *
>(& mp.basis(i))!=NULL,
"Bases is not of type gsHTensorBasis<2>");
91 m_bases = mp.basesCopy();
92 if(increaseSmoothnessLevel==-1)
93 m_incrSmoothnessDegree=this->maxDegree()-1;
95 m_incrSmoothnessDegree=increaseSmoothnessLevel;
96 m_minDist=
static_cast<unsigned>(std::max<index_t>(std::min<index_t>(m_incrSmoothnessDegree+1,maxDegree()),minEVDistance));
98 _setDistanceOfAllVertices();
102 _checkTopologyWithBases();
106 template<
short_t d,
class T>
111 for (
size_t i = 0; i < mb.nBases(); i++)
113 GISMO_ASSERT(
dynamic_cast<const gsHTensorBasis<2> *
>(&mb.basis(i))!=NULL,
"Bases is not of type gsHTensorBasis<2>");
114 m_bases.push_back((BasisType *)mb.basis(i).clone().release());
117 if(increaseSmoothnessLevel==-1)
118 m_incrSmoothnessDegree=this->maxDegree()-1;
120 m_incrSmoothnessDegree=increaseSmoothnessLevel;
121 m_minDist=
static_cast<unsigned>(std::max<index_t>(std::min<index_t>(m_incrSmoothnessDegree+1,maxDegree()),minEVDistance));
123 _setDistanceOfAllVertices();
127 _checkTopologyWithBases();
131 template<
short_t d,
class T>
134 m_topol = other.m_topol;
135 m_vertices=other.m_vertices;
136 m_distances=other.m_distances;
137 m_minDist=other.m_minDist;
139 for(ConstBasisIter it = other.m_bases.begin();it!=other.m_bases.end();++it)
141 m_bases.push_back( (BasisType *)(*it)->clone().release() );
143 m_incrSmoothnessDegree=other.m_incrSmoothnessDegree;
144 this->_checkTopologyWithBases();
146 m_mapper=
new gsWeightMapper<T>(*other.m_mapper);
150 template<
short_t d,
class T>
151 gsMPBESHSplineBasis<d,T>& gsMPBESHSplineBasis<d,T>::operator=(
const gsMPBESHSplineBasis& other )
153 m_topol=other.m_topol;
154 m_vertices=other.m_vertices;
155 m_distances=other.m_distances;
156 m_minDist=other.m_minDist;
159 for(ConstBasisIter it = other.m_bases.begin();it!=other.m_bases.end();++it)
160 m_bases.push_back((BasisType*)(*it)->clone().release());
164 m_incrSmoothnessDegree=other.m_incrSmoothnessDegree;
169 template<
short_t d,
class T>
176 m_mapper = maker.makeMapper();
179 template<
short_t d,
class T>
183 std::vector<bool> actives;
184 for(
unsigned level = 0;level<=basis(ps.
patch).maxLevel();++level)
186 basis(ps.
patch).activeBoundaryFunctionsOfLevel(level,ps.side(),actives);
187 for(std::vector<bool>::const_iterator iter = actives.begin();iter!=actives.end();++iter)
194 template<
short_t d,
class T>
197 unsigned patch_i = _getPatch(i), patch_j = _getPatch(j);
198 if( patch_i != patch_j )
200 indexType loc_i = _getPatchIndex(i), loc_j = _getPatchIndex(j);
201 unsigned level_i = basis(patch_i).levelOf(loc_i);
202 unsigned level_j = basis(patch_j).levelOf(loc_j);
203 if( level_i != level_j )
205 unsigned tensorIndex_i = basis(patch_i).flatTensorIndexOf(loc_i);
206 unsigned tensorIndex_j = basis(patch_j).flatTensorIndexOf(loc_j);
207 gsVector<index_t,d> vec_i = basis(patch_i).getBases()[level_i]->tensorIndex(tensorIndex_i);
208 gsVector<index_t,d> vec_j = basis(patch_j).getBases()[level_j]->tensorIndex(tensorIndex_j);
210 for(
unsigned i2=0; i2< d;++i2 )
211 if( vec_i[j]-vec_j[i2] != 0 )
216 template<
short_t d,
class T>
219 basis(patch).refine(boxes);
220 std::vector<gsMatrix<T> *> coefs;
221 for (
size_t i = 0; i < nPatches(); ++i)
222 coefs.push_back(NULL);
225 repairPatches(coefs,patch);
230 template<
short_t d,
class T>
233 basis(patch).refineElements(boxes);
234 std::vector<gsMatrix<T> *> coefs;
235 for (
size_t i = 0; i < nPatches(); ++i)
236 coefs.push_back(NULL);
239 repairPatches(coefs,patch);
244 template<
short_t d,
class T>
248 std::vector<gsMatrix<T> *> coefs;
249 unsigned geoDim = localCoef.cols();
251 for (
size_t i = 0; i < nPatches(); ++i)
254 end+=basis(i).size();
256 *localMat << localCoef.block(start,0,end-start+1,geoDim);
257 coefs.push_back(localMat);
259 basis(patch).refine_withCoefs(*coefs[patch],boxes);
261 repairPatches(coefs,patch);
262 unsigned totalSize=0;
263 for (
size_t i = 0; i < nPatches(); ++i)
265 totalSize+=basis(i).size();
267 localCoef.resize(totalSize,geoDim);
269 for (
size_t i = 0; i < nPatches(); i++)
272 end+=basis(i).size();
273 localCoef.block(start,0,end-start+1,geoDim) << *coefs[i];
281 template<
short_t d,
class T>
284 std::vector<gsMatrix<T> *> coefs;
285 unsigned geoDim = localCoef.cols();
287 for (
size_t i = 0; i < nPatches(); ++i)
290 end+=basis(i).size();
292 *localMat << localCoef.block(start,0,end-start+1,geoDim);
293 coefs.push_back(localMat);
295 basis(patch).refineElements_withCoefs(*coefs[patch],boxes);
297 repairPatches(coefs,patch);
298 unsigned totalSize=0;
299 for (
size_t i = 0; i < nPatches(); ++i)
301 totalSize+=basis(i).size();
303 localCoef.resize(totalSize,geoDim);
305 for (
size_t i = 0; i < nPatches(); i++)
308 end+=basis(i).size();
309 localCoef.block(start,0,end-start+1,geoDim) << *coefs[i];
316 template<
short_t d,
class T>
319 m_bases[patch]->refine( boxes, refExt);
320 std::vector<gsMatrix<T> *> coefs;
321 for (
size_t i = 0; i < nPatches(); ++i)
322 coefs.push_back(NULL);
325 repairPatches(coefs,patch);
330 template<
short_t d,
class T>
333 std::vector<size_t> toCheck;
334 if(startFromPatch==-1)
335 for(
size_t i = 0; i < m_bases.size(); ++i)
336 toCheck.push_back(i);
338 toCheck.push_back(startFromPatch);
342 curElement=toCheck[0];
343 toCheck.erase(toCheck.begin());
344 std::vector<index_t> boxes;
345 std::vector<index_t> checkPatches(0);
347 matched = matched && _innerBoxesAreSuitable(curElement,boxes);
350 if(coefs[curElement]!=NULL)
351 basis(curElement).refineElements_withCoefs(*(coefs[curElement]),boxes);
353 basis(curElement).refineElements(boxes);
354 toCheck.push_back(curElement);
359 matched = matched && _boxesMatchNeighbours(curElement,boxes,checkPatches);
362 if(coefs[curElement]!=NULL)
363 basis(curElement).refineElements_withCoefs(*(coefs[curElement]),boxes);
365 basis(curElement).refineElements(boxes);
367 for(
size_t i = 0; i < checkPatches.size(); ++i)
368 if(std::find(toCheck.begin(), toCheck.end(), checkPatches[i])==toCheck.end())
369 toCheck.push_back(checkPatches[i]);
370 }
while(!toCheck.empty());
373 template<
short_t d,
class T>
375 std::vector<index_t>& boxes)
377 size_t sz = boxes.size();
378 short_t dist_u = 2*std::min(m_bases[patch]->degree(0),(
short_t)(m_incrSmoothnessDegree+1));
379 short_t dist_v = 2*std::min(m_bases[patch]->degree(1),(
short_t)(m_incrSmoothnessDegree+1));
380 patchSide ps_north(patch,boundary::north);
381 patchSide ps_south(patch,boundary::south);
384 bool north = m_topol.isInterface(ps_north);
385 bool south = m_topol.isInterface(ps_south);
386 bool east = m_topol.isInterface(ps_east);
387 bool west = m_topol.isInterface(ps_west);
391 basis(patch).tree().getBoxesInLevelIndex(b1,b2,level);
392 for(
index_t i = 0; i < level.rows(); i++)
397 index_t b_uMin = b1(i,0),b_vMin = b1(i,1);
398 index_t b_uMax = b2(i,0),b_vMax = b2(i,1);
399 index_t uMin = 0, uMax = basis(patch).getBases()[l]->knots(0).uSize() - 1;
400 index_t vMin = 0, vMax = basis(patch).getBases()[l]->knots(1).uSize() - 1;
402 if( uMin < b_uMin && b_uMax < uMax && vMin < b_vMin && b_vMax < vMax )
406 if( west && uMin == b_uMin && b_uMax < uMin+dist_u )
407 _addBox(patch,b_uMin,b_vMin,uMin+dist_u,b_vMax,l,boxes);
408 if( east && uMax == b_uMax && b_uMin > uMax-dist_u )
409 _addBox(patch,uMax-dist_u,b_vMin,b_uMax,b_vMax,l,boxes);
410 if( south && vMin == b_vMin && b_vMax < vMin+dist_v )
411 _addBox(patch,b_uMin,b_vMin,b_uMax,vMin+dist_v,l,boxes);
412 if( north && vMax == b_vMax && b_vMin > vMax-dist_v )
413 _addBox(patch,b_uMin,vMax-dist_v,b_uMax,b_vMax,l,boxes);
415 return boxes.size()==sz;
418 template<
short_t d,
class T>
419 bool gsMPBESHSplineBasis<d,T>::_boxesMatchNeighbours(
const index_t patch,
420 std::vector<index_t>& boxes, std::vector<index_t>& checkPatches)
422 unsigned sz = boxes.size();
424 patchSide ps, ps_neigh;
425 std::vector<bool> sideToCheck(4,
false);
426 std::vector<index_t> neighbours(4,-1);
427 gsVector<bool> orient;
428 index_t patch_max_level = basis(patch).maxLevel();
429 for(
unsigned side=1;side<=4;++side)
431 ps=patchSide(patch,side);
432 if( !m_topol.getNeighbour(ps,ps_neigh) )
434 neighbours[side-1]=ps_neigh.patch;
435 unsigned neighbour_max_level = basis(ps_neigh.patch).maxLevel();
436 unsigned max_level = std::max<unsigned>(patch_max_level,neighbour_max_level);
437 for(
unsigned l=1;l<=max_level;++l)
439 std::vector<bool> s_patch,s_neigh,s_res;
440 basis(patch).activeBoundaryFunctionsOfLevel(l,ps.side(),s_patch);
441 basis(ps_neigh.patch).activeBoundaryFunctionsOfLevel(l,ps_neigh.side(),s_neigh);
442 unsigned sz2 = s_patch.size();
443 boundaryInterface bf;
444 m_topol.getInterface(ps,bf);
445 if(!bf.dirOrientation(ps,1-ps.direction()))
446 std::reverse(s_neigh.begin(),s_neigh.end());
448 for(
unsigned i = 0;i<sz2;i++)
450 s_res[i]=s_neigh[i]&&!s_patch[i];
451 if(s_patch[i]&&!s_neigh[i])
452 sideToCheck[side-1]=
true;
454 unsigned start = 0, end=0;
462 else if(end<sz2&&s_res[end])
466 _addBoundaryBox(patch,ps.side(),start,end-1,l,boxes,sideToCheck);
473 for(
unsigned i = 0;i<4;i++)
475 if(sideToCheck[i]&&neighbours[i]!=-1)
476 checkPatches.push_back(neighbours[i]);
478 return boxes.size()==sz;
481 template<
short_t d,
class T>
482 void gsMPBESHSplineBasis<d,T>::_addBoundaryBox(
const index_t patch,
const boxSide s,
const index_t start,
const index_t end,
const unsigned level, std::vector<index_t> & boxes, std::vector<bool> & sideToCheck)
484 short_t u_max = basis(patch).getBases()[level]->size(0)-1;
485 short_t v_max = basis(patch).getBases()[level]->size(1)-1;
486 short_t dist_u = 2*std::min(m_bases[patch]->degree(0),(
short_t)(m_incrSmoothnessDegree+1));
487 short_t dist_v = 2*std::min(m_bases[patch]->degree(1),(
short_t)(m_incrSmoothnessDegree+1));
491 _addFunBox(patch,0,start,dist_u-1,end,level,boxes);
493 sideToCheck[2-1]=
true;
496 _addFunBox(patch,u_max-(dist_u-1),start,u_max,end,level,boxes);
498 sideToCheck[1-1]=
true;
501 _addFunBox(patch,start,0,end,dist_v-1,level,boxes);
503 sideToCheck[4-1]=
true;
506 _addFunBox(patch,start,v_max-(dist_v-1),end,v_max,level,boxes);
508 sideToCheck[3-1]=
true;
516 sideToCheck[3-1]=
true;
517 if(end>=static_cast<index_t>(v_max)-1)
518 sideToCheck[4-1]=
true;
523 sideToCheck[1-1]=
true;
524 if(end>=static_cast<index_t>(u_max)-1)
525 sideToCheck[2-1]=
true;
529 template<
short_t d,
class T>
530 void gsMPBESHSplineBasis<d,T>::_addFunBox(
const index_t patch,
const unsigned uMin,
const unsigned vMin,
const unsigned uMax,
const unsigned vMax,
const unsigned level, std::vector<index_t> & boxes)
532 boxes.push_back(level);
533 gsMatrix<index_t> supportIndex;
534 basis(patch).getBases()[level]->knots(0).supportIndex_into(uMin,supportIndex);
535 boxes.push_back(supportIndex(0,0));
536 basis(patch).getBases()[level]->knots(1).supportIndex_into(vMin,supportIndex);
537 boxes.push_back(supportIndex(0,0));
538 basis(patch).getBases()[level]->knots(0).supportIndex_into(uMax,supportIndex);
539 boxes.push_back(supportIndex(0,1));
540 basis(patch).getBases()[level]->knots(1).supportIndex_into(vMax,supportIndex);
541 boxes.push_back(supportIndex(0,1));
544 template<
short_t d,
class T>
545 void gsMPBESHSplineBasis<d,T>::_addBox(
const index_t patch,
const unsigned uMin,
const unsigned vMin,
const unsigned uMax,
const unsigned vMax,
const unsigned level, std::vector<index_t> & boxes)
547 gsVector<index_t,d> lowerLeft;
550 gsVector<index_t,d> upperRight;
553 if( uMin<uMax && vMin<vMax && static_cast<index_t>(level)>basis(patch).tree().query3(lowerLeft,upperRight,level))
555 boxes.push_back(level);
556 boxes.push_back(uMin);
557 boxes.push_back(vMin);
558 boxes.push_back(uMax);
559 boxes.push_back(vMax);
563 template<
short_t d,
class T>
564 void gsMPBESHSplineBasis<d,T>::_endpointsOfActiveBoundaryFunctions(patchSide
const & ps,
bool orient,std::vector<T>& endpoints)
const
567 unsigned deg = degree(patch,1-(ps.direction()));
568 std::vector<bool> actives;
569 for(
unsigned level = 0;level<=basis(patch).maxLevel();++level)
571 gsKnotVector<T> knots = basis(patch).getBases()[level]->knots(1-(ps.direction()));
572 basis(patch).activeBoundaryFunctionsOfLevel(level,ps.side(),actives);
576 std::reverse(actives.begin(), actives.end());
578 for(
unsigned i = 0; i<actives.size();++i)
580 endpoints.push_back(knots.at(i+deg+1));
582 std::sort(endpoints.begin(),endpoints.end());
585 template<
short_t d,
class T>
590 std::vector<T> endpoints;
593 _endpointsOfActiveBoundaryFunctions(ps,pars(1-ps.
direction()),endpoints);
594 return endpoints[nrBasisFuncs-1];
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.
void repairPatches(std::vector< gsMatrix< T > * > &coefs, index_t startFromPatch=-1)
Definition: gsMPBESHSplineBasis.hpp:331
Struct which represents a certain side of a patch.
Definition: gsBoundary.h:231
void _setMapping()
create a new mapping of the local basisfunctions
Definition: gsMPBESHSplineBasis.hpp:170
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...
#define short_t
Definition: gsConfig.h:35
A univariate Lagrange basis.
Definition: gsMPBESMapHB2D.h:40
Provides declaration of MultiBasis class.
virtual void refineWithExtension(const index_t patch, gsMatrix< T > const &boxes, index_t refExt=0, bool updateBasis=true)
Refine the are defined by boxes on patch k with extension refExt.
Definition: gsMPBESHSplineBasis.hpp:317
#define index_t
Definition: gsConfig.h:32
A univariate Lagrange basis.
Definition: gsMPBESHSplineBasis.h:32
gsMPBESHSplineBasis()
Default empty constructor.
Definition: gsMPBESHSplineBasis.h:77
Struct which represents a certain corner of a patch.
Definition: gsBoundary.h:392
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
void freeAll(It begin, It end)
Frees all pointers in the range [begin end)
Definition: gsMemory.h:312
T findParameter(patchSide const &ps, patchCorner const &pc, unsigned nrBasisFuncs) const
Definition: gsMPBESHSplineBasis.hpp:586
void refineElements(const index_t patch, std::vector< index_t > const &boxes, bool updateBasis=true)
Definition: gsMPBESHSplineBasis.hpp:231
unsigned basisFunctionsOnSide(const patchSide &ps) const
Returns the amount of basis functions on a given side of a given patch.
Definition: gsMPBESHSplineBasis.hpp:180
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
void refine_withCoefs(gsMatrix< T > &localCoef, const index_t patch, gsMatrix< T > const &boxes, bool updateBasis=true)
Definition: gsMPBESHSplineBasis.hpp:245
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
void refineElements_withCoefs(gsMatrix< T > &localCoef, const index_t patch, std::vector< index_t > const &boxes, bool updateBasis=true)
Definition: gsMPBESHSplineBasis.hpp:282
void refine(const index_t patch, gsMatrix< T > const &boxes, bool updateBasis=true)
Definition: gsMPBESHSplineBasis.hpp:217