31 template<
short_t d,
class T>
38 typedef std::vector<std::pair<index_t,index_t> >::iterator step_iter;
40 typedef typename std::vector<BasisType *>::const_iterator ConstBasisIter;
41 typedef typename std::vector<BasisType *>::iterator BasisIter;
42 typedef typename std::vector<gsMatrix<T> *>::const_iterator ConstMatrixPtrIter;
44 typedef std::vector<indexType> IndexContainer;
45 typedef std::vector<indexType>::const_iterator ConstIndexIter;
50 m_incrSmoothnessDegree(incrSmoothnessDegree), m_topol(topol), m_basis(basis), m_global(0)
61 gsWeightMapper<T> * makeMapper()
const
63 index_t locals = _getNrOfLocalBasisFunktions();
64 index_t size = m_basis->nPatches();
65 std::vector<index_t> offsets;
67 offsets.push_back(_getFirstLocalIndex(i));
68 m_mapper =
new gsWeightMapper<T>(locals,locals);
70 _setMappingOfPatch(i);
72 gsWeightMapper<T> * mapper = m_mapper;
82 virtual bool _checkMapping()
const = 0;
84 virtual void _finalize()
const = 0;
86 virtual void _setMappingOfPatch(
index_t const patch)
const = 0;
88 index_t _getNrOfLocalBasisFunktions()
const
91 for (
size_t i = 0; i < m_basis->nPatches(); ++i)
92 size += m_basis->getBase(i).size();
103 void _setTensorMappingOfPatch(
index_t const patch)
const
105 const gsBasis<T> & base = m_basis->getBase(patch);
108 index_t u_amount =_getParMax(patch,0)+1, v_amount=_getParMax(patch,1)+1;
109 patchSide ps_north(patch,boundary::north);
110 patchSide ps_south(patch,boundary::south);
117 patchCorner pc_northeast(patch,boundary::northeast);
118 patchCorner pc_northwest(patch,boundary::northwest);
119 patchCorner pc_southeast(patch,boundary::southeast);
120 patchCorner pc_southwest(patch,boundary::southwest);
121 bool northeast = m_basis->isSpecialVertex(pc_northeast);
122 bool northwest = m_basis->isSpecialVertex(pc_northwest);
123 bool southeast = m_basis->isSpecialVertex(pc_southeast);
124 bool southwest = m_basis->isSpecialVertex(pc_southwest);
126 index_t ne_l_u = getDistanceOfVertex(pc_northeast,ps_north);
127 index_t nw_l_u = getDistanceOfVertex(pc_northwest,ps_north);
128 index_t se_l_u = getDistanceOfVertex(pc_southeast,ps_south);
129 index_t sw_l_u = getDistanceOfVertex(pc_southwest,ps_south);
130 index_t se_l_v = getDistanceOfVertex(pc_southeast,ps_east);
131 index_t ne_l_v = getDistanceOfVertex(pc_northeast,ps_east);
132 index_t sw_l_v = getDistanceOfVertex(pc_southwest,ps_west);
133 index_t nw_l_v = getDistanceOfVertex(pc_northwest,ps_west);
135 if(ne_l_u+nw_l_u>u_amount)
138 nw_l_u=u_amount-ne_l_u;
140 if(se_l_u+sw_l_u>u_amount)
143 sw_l_u=u_amount-se_l_u;
145 if(se_l_v+ne_l_v>v_amount)
148 ne_l_v=v_amount-se_l_v;
150 if(sw_l_v+nw_l_v>v_amount)
153 nw_l_v=v_amount-sw_l_v;
156 index_t n_l_v = north ? degree_v : 0;
157 index_t s_l_v = south ? degree_v : 0;
158 index_t e_l_u = east ? degree_u : 0;
159 index_t w_l_u = west ? degree_u : 0;
161 bool north_same=
false;
162 bool east_same=
false;
163 if(1==m_basis->nPatches())
171 for(
index_t j = 0;j<sw_l_v ;j++)
172 for(
index_t i = 0;i<sw_l_u ;i++)
174 if(!_getLocalIndex_into(patch,i,j,localIndex))
176 if(i>=degree_u&&j>=degree_v)
178 else if((southwest||degree_u==1||degree_v==1) && i == 0 && j==0)
179 _addSingularCornerToMap(localIndex);
180 else if(southwest && west && i==0)
181 _addCombinedLineToMap(ps_west,localIndex,1,0);
182 else if(southwest && south && j==0)
183 _addCombinedLineToMap(ps_south,localIndex,1,0);
184 else if(!southwest && south && west)
185 _addCombinedBlockToMap(ps_south,ps_west,localIndex,degree_u,degree_v,j,i);
186 else if(!southwest && south && !west)
187 _addCombinedLineToMap(ps_south,localIndex,degree_v,j);
188 else if(!southwest && !south && west)
189 _addCombinedLineToMap(ps_west,localIndex,degree_u,i);
191 _addFreeToMap(localIndex);
195 for(
index_t i=sw_l_u;i<u_amount-se_l_u;i++)
197 if(!_getLocalIndex_into(patch,i,j,localIndex))
200 _addCombinedLineToMap(ps_south,localIndex,degree_v,j);
202 _addFreeToMap(localIndex);
205 for(
index_t j = 0;j<se_l_v ;j++)
206 for(
index_t i = u_amount-se_l_u; i<u_amount ;i++)
208 if(!_getLocalIndex_into(patch,i,j,localIndex))
210 if(i<u_amount-degree_u&&j>=degree_v)
212 else if(!southeast&&east_same)
214 else if((southeast||degree_u==1||degree_v==1) && i == u_amount-1 && j==0)
215 _addSingularCornerToMap(localIndex);
216 else if(southeast && east && i==u_amount-1)
217 _addCombinedLineToMap(ps_east,localIndex,1,0);
218 else if(southeast && south && j==0)
219 _addCombinedLineToMap(ps_south,localIndex,1,0);
220 else if(!southeast && south && east)
221 _addCombinedBlockToMap(ps_south,ps_east,localIndex,degree_u,degree_v,j,u_amount-1-i);
222 else if(!southeast && south && !east)
223 _addCombinedLineToMap(ps_south,localIndex,degree_v,j);
224 else if(!southeast && !south && east)
225 _addCombinedLineToMap(ps_east,localIndex,degree_u,u_amount-1-i);
227 _addFreeToMap(localIndex);
230 for(
index_t j=sw_l_v;j<v_amount-nw_l_v;j++)
233 if(!_getLocalIndex_into(patch,i,j,localIndex))
236 _addCombinedLineToMap(ps_west,localIndex,degree_u,i);
238 _addFreeToMap(localIndex);
241 for(
index_t j=s_l_v;j<v_amount-n_l_v;j++)
242 for(
index_t i=w_l_u;i<u_amount-e_l_u;i++)
244 if(j<sw_l_v&&j<degree_v&&i<sw_l_u&&i<degree_u)
246 if(j<se_l_v&&j<degree_v&&i>=u_amount-se_l_u&&i>=u_amount-degree_u)
248 if(j>=v_amount-ne_l_v&&j>=v_amount-degree_v&&i>=u_amount-ne_l_u&&i>=u_amount-degree_u)
250 if(j>=v_amount-nw_l_v&&j>=v_amount-degree_v&&i<nw_l_u&&i<degree_u)
252 if(!_getLocalIndex_into(patch,i,j,localIndex))
254 _addFreeToMap(localIndex);
257 for(
index_t j=se_l_v;j<v_amount-ne_l_v;j++)
258 for(
index_t i=u_amount-e_l_u;i<u_amount;i++)
260 if(!_getLocalIndex_into(patch,i,j,localIndex))
265 _addCombinedLineToMap(ps_east,localIndex,degree_u,u_amount-1-i);
267 _addFreeToMap(localIndex);
270 for(
index_t j = v_amount-nw_l_v;j<v_amount ;j++)
271 for(
index_t i = 0; i<nw_l_u ;i++)
273 if(!_getLocalIndex_into(patch,i,j,localIndex))
275 if(i>=degree_u&&j<v_amount-degree_v)
277 else if(!northwest&&north_same)
279 else if((northwest||degree_u==1||degree_v==1) && i == 0 && j==v_amount-1)
280 _addSingularCornerToMap(localIndex);
281 else if(northwest && west && i==0)
282 _addCombinedLineToMap(ps_west,localIndex,1,0);
283 else if(northwest && north && j==v_amount-1)
284 _addCombinedLineToMap(ps_north,localIndex,1,0);
285 else if(!northwest && north && west)
286 _addCombinedBlockToMap(ps_north,ps_west,localIndex,degree_u,degree_v,v_amount-1-j,i);
287 else if(!northwest && north && !west)
288 _addCombinedLineToMap(ps_north,localIndex,degree_v,v_amount-1-j);
289 else if(!northwest && !north && west)
290 _addCombinedLineToMap(ps_west,localIndex,degree_u,i);
292 _addFreeToMap(localIndex);
295 for(
index_t j=v_amount-n_l_v;j<v_amount;j++)
296 for(
index_t i=nw_l_u;i<u_amount-ne_l_u;i++)
298 if(!_getLocalIndex_into(patch,i,j,localIndex))
300 if(north&&north_same)
303 _addCombinedLineToMap(ps_north,localIndex,degree_v,v_amount-1-j);
305 _addFreeToMap(localIndex);
308 for(
index_t j = v_amount-ne_l_v;j<v_amount ;j++)
309 for(
index_t i = u_amount-ne_l_u; i<u_amount ;i++)
311 if(!_getLocalIndex_into(patch,i,j,localIndex))
313 if(i<u_amount-degree_u&&j<v_amount-degree_v)
315 else if(!northeast&&(north_same||east_same))
317 else if((northeast||degree_u==1||degree_v==1) && i == u_amount-1 && j==v_amount-1)
318 _addSingularCornerToMap(localIndex);
319 else if(northeast && east && i==u_amount-1)
320 _addCombinedLineToMap(ps_east,localIndex,1,0);
321 else if(northeast && north && j==v_amount-1)
322 _addCombinedLineToMap(ps_north,localIndex,1,0);
323 else if(!northeast && north && east)
324 _addCombinedBlockToMap(ps_north,ps_east,localIndex,degree_u,degree_v,v_amount-1-j,u_amount-1-i);
325 else if(!northeast && north && !east)
326 _addCombinedLineToMap(ps_north,localIndex,degree_v,v_amount-1-j);
327 else if(!northeast && !north && east)
328 _addCombinedLineToMap(ps_east,localIndex,degree_u,u_amount-1-i);
330 _addFreeToMap(localIndex);
395 result.push_back(1.0);
396 result.push_back(1.0);
399 typedef typename std::vector<T>::iterator tIter;
400 std::vector<T> temp0 = kv0i.
get();
401 std::vector<T> temp1 = kv1i.
get();
402 for(tIter it = temp0.begin();it!=temp0.end();++it)
404 for(tIter it = temp1.begin();it!=temp1.end();++it)
414 kv1.addConstant(kv0.last());
415 T inserted = kv0.last();
416 kv0.remove(kv0.last(),degree);
417 kv1.remove(kv1.first(),kv1.degree()+1);
418 kv0.append(kv1.begin(),kv1.end());
420 boem_mat.setZero(kv0.size()-kv0.degree()-1,1);
421 boem_mat.coeffRef(l0-(kv1.degree()+2)-knot_index)=1;
422 gsBoehm<T,gsKnotVector<T>,
gsMatrix<T> >(kv0,boem_mat,inserted,degree-1,
false);
423 for(
index_t i = 0;i<degree;i++)
426 result.push_back(boem_mat.coeff(i+l0-(kv0.degree()+2)-knot_index,0));
428 result.push_back(boem_mat.coeff(i+l0-(kv0.degree()+2)-knot_index,0));
442 bool _alreadyHandled(
patchSide const & ps,
bool flag)
const
444 std::vector<indexType> vertices = _findVertexInPatches(ps,flag);
445 for(
size_t i = 0;i<vertices.size();i++)
446 if(_getPatch(vertices[i]) < ps.
patch )
451 bool _alreadyHandled(std::vector<index_t> local_BFs,
index_t startPatch)
const
453 for(
size_t i = 0;i<local_BFs.size();i++)
454 if((
index_t)startPatch>_getPatch(local_BFs[i]))
459 std::vector<indexType> _findVertexInPatches(
patchSide ps,
bool flag)
const
465 std::vector<patchCorner> cornerList;
467 std::vector<indexType> vertices;
468 for(
size_t i = 0;i<cornerList.size();++i)
469 vertices.push_back(_getLocalIndex(cornerList[i]));
473 void _flipOverCorner(
patchSide & ps,
bool & flag)
const
478 case boundary::north : ps =
patchSide(patch,flag ? boundary::east : boundary::west);
481 case boundary::south : ps =
patchSide(patch,flag ? boundary::east : boundary::west);
484 case boundary::west : ps =
patchSide(patch,flag ? boundary::north : boundary::south);
487 case boundary::east : ps =
patchSide(patch,flag ? boundary::north : boundary::south);
501 void _addToMap(std::vector<indexType> indices,std::vector<weightType> weights)
const
503 for(
size_t i = 0;i<indices.size();++i)
504 m_mapper->setEntry(indices[i],m_global,weights[i]);
508 void _addFreeToMap(
index_t localIndex)
const
510 std::vector<indexType> indices;
511 indices.push_back(localIndex);
512 std::vector<weightType> weights;
513 weights.push_back(1);
514 _addToMap(indices,weights);
517 void _addSingularCornerToMap(
index_t localIndex)
const
519 index_t u=_getPar(localIndex,0), v=_getPar(localIndex,1), patch=_getPatch(localIndex);
533 if(_alreadyHandled(ps,flag))
535 std::vector<indexType> vertices = _findVertexInPatches(ps,flag);
536 std::vector<indexType> locals;
537 std::vector<weightType> weights;
538 for(
size_t i = 0;i<vertices.size();i++)
540 locals.push_back(vertices[i]);
541 weights.push_back(static_cast<weightType>(1));
543 _addToMap(locals,weights);
548 std::vector<patchSide> sides;
549 std::vector<index_t> lengths;
550 std::vector<index_t> dists;
552 lengths.push_back(length);
553 dists.push_back(distToPs);
554 _addBlockToMap(localStartIndex,sides,lengths,dists);
559 std::vector<patchSide> sides;
560 std::vector<index_t> lengths;
561 std::vector<index_t> dists;
562 sides.push_back(ps_u);
563 sides.push_back(ps_v);
564 lengths.push_back(length_u);
565 lengths.push_back(length_v);
566 dists.push_back(distToPs_u);
567 dists.push_back(distToPs_v);
568 _addBlockToMap(localStartIndex,sides,lengths,dists);
571 void _addBlockToMap(
index_t localStartIndex, std::vector<patchSide>
const & sides, std::vector<index_t>
const & lengths, std::vector<index_t>
const & dists)
const
577 std::vector<std::vector<T> > weights1D;
578 std::vector<bool> minus_dir;
579 std::vector<index_t> dirs;
580 std::vector<weightType> weight;
582 for(
size_t i = 0; i<sides.size();++i)
589 minus_dir.push_back(!par);
591 kv_this=_getKnotVector(ps.
patch,dir);
594 kv_neigh=_getKnotVector(ps_neighbour.
patch,dir_neigh);
595 w0 = m_basis->getWeight(ps);
596 w1 = m_basis->getWeight(ps_neighbour);
598 _getBoehmCoefs(kv_this,par,w0,kv_neigh,par_neigh,w1,lengths[i],dists[i],weight);
599 weights1D.push_back(weight);
601 std::vector<indexType> locals;
602 std::vector<weightType> weights;
603 std::vector<std::pair<index_t,index_t> >steps;
609 weightType weight2 = 1.0;
610 for(
size_t i=0;i<sides.size();++i)
612 steps.push_back(std::make_pair(minus_dir[i] ? -distances(i) : distances(i),dirs[i]));
613 weight2 *= weights1D[i][distances(i)];
615 index_t localIndexTravelled = _travelUVSteps(localStartIndex,steps);
616 locals.push_back(localIndexTravelled);
617 weights.push_back(weight2);
618 }
while(_nextPoint(lengths,distances));
619 if(_alreadyHandled(locals,_getPatch(localStartIndex)))
621 _addToMap(locals,weights);
624 bool _nextPoint(std::vector<index_t>
const & lengths,
gsVector<index_t> & point)
const
626 for(
size_t i = 0; i<lengths.size(); ++i)
628 if(++point(i)<=lengths[i])
643 index_t _transformToNeighbour(
index_t localIndex,step_iter current,step_iter end)
const
645 index_t patch = _getPatch(localIndex);
646 index_t u = _getPar(localIndex,0);
647 index_t v = _getPar(localIndex,1);
649 if(current->second==0)
650 ps =
patchSide(patch,current->first>0 ? 2 : 1);
652 ps =
patchSide(patch,current->first>0 ? 4 : 3);
656 GISMO_ASSERT((ps.side()==1&&u==0)||(ps.side()==2&&u==_getParMax(patch,0))||
657 (ps.side()==3&&v==0)||(ps.side()==4&&v==_getParMax(patch,1)),
658 "steps does not fit to point");
659 GISMO_ASSERT(current->first!=0,
"stepsize is zero, which is not allowed in this position.");
660 bool orient = bf.dirOrientation(ps,1-ps.
direction());
661 index_t non_fixed = current->second==1 ? u : v;
662 current->first>0 ? current->first-- : current->first++;
663 _transformStepsToNeighbour(current,end,ps,ps_neighbour,orient);
664 localIndex=_transformIndexToNeighbour(localIndex,ps_neighbour,orient,non_fixed);
671 index_t u_max = _getParMax(patch,0);
672 index_t v_max = _getParMax(patch,1);
674 localIndex = _getLocalIndex(patch,orient ? non_fixed : u_max-non_fixed,ps_neighbour.
parameter() ? v_max : 0);
676 localIndex = _getLocalIndex(patch,(ps_neighbour.
parameter()) ? u_max : 0,orient ? non_fixed : v_max-non_fixed);
679 void _transformStepsToNeighbour(step_iter current,step_iter end,
patchSide const & ps,
patchSide const & ps_neighbour,
bool orient)
const
681 boxSide s1=ps.side(),s2=ps_neighbour.side();
683 for(step_iter it = current;it!=end;++it)
691 else if((s1==1&&s2==3)||(s1==2&&s2==4)||(s1==3&&s2==1)||(s1==4&&s2==2))
692 for(step_iter it = current;it!=end;++it)
699 it->second=(1-it->second);
701 else if((s1==1&&s2==4)||(s1==2&&s2==3)||(s1==3&&s2==2)||(s1==4&&s2==1))
702 for(step_iter it = current;it!=end;++it)
707 it->second=(1-it->second);
711 index_t _travelInsidePatch(
index_t localIndex,
bool dir,step_iter current)
const
713 index_t patch = _getPatch(localIndex);
714 index_t par = _getPar(localIndex,dir);
715 index_t par_max = _getParMax(patch,dir);
716 index_t fixed_par = _getPar(localIndex,!dir);
717 if(0<=par+current->first&&par+current->first<=par_max)
722 else if(current->first>0)
724 current->first-=par_max-par;
732 localIndex = _getLocalIndex(patch,dir ? fixed_par : par,dir ? par : fixed_par);
736 index_t _travelUVSteps(
index_t localIndex,std::vector<std::pair<index_t, index_t> > steps)
const
738 step_iter current = steps.begin();
739 step_iter end = steps.end();
742 GISMO_ASSERT(current->second==0||current->second==1,
"only 0 and 1 direction possible");
743 localIndex=_travelInsidePatch(localIndex, current->second != 0, current);
744 if(current->first==0)
747 localIndex=_transformToNeighbour(localIndex,current,end);
762 return _getFirstLocalIndex(patch)+patchIndex;
769 return _getLocalIndex(ps,param(0));
774 return _getLocalIndex(ps.
patch,ps.side(),flag);
779 return _getLocalIndex(patch,_getPatchIndex(patch,side,flag));
789 index+=m_basis->localSize(i);
796 return _getFirstLocalIndex(patch)+m_basis->localSize(patch)-1;
805 for(
index_t i = 0;i<_getPatch(localIndex);i++)
807 patchIndex-=m_basis->localSize(i);
815 for (patch = 0; patch < m_basis->nPatches(); patch++)
817 if (localIndex >= m_basis->localSize(patch))
818 localIndex -= m_basis->localSize(patch);
829 short_t const m_incrSmoothnessDegree;
832 mutable gsWeightMapper<T> *m_mapper;
Struct which represents a certain side of a patch.
Definition: gsBoundary.h:231
Provides declaration of the BoxTopology class.
#define short_t
Definition: gsConfig.h:35
virtual short_t degree(short_t i) const
Degree with respect to the i-th variable. If the basis is a tensor product of (piecewise) polynomial ...
Definition: gsBasis.hpp:650
bool parameter() const
Returns the parameter value (false=0=start, true=1=end) that corresponds to this side.
Definition: gsBoundary.h:128
Boehm's algorithm for knot insertion.
bool getCornerList(const patchCorner &start, std::vector< patchCorner > &cornerList) const
Definition: gsBoxTopology.cpp:187
A univariate Lagrange basis.
Definition: gsMPBESMapTensor.h:32
S give(S &x)
Definition: gsMemory.h:266
#define index_t
Definition: gsConfig.h:32
Struct which represents a certain corner of a patch.
Definition: gsBoundary.h:392
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
Sparse matrix class, based on gsEigen::SparseMatrix.
Definition: gsSparseMatrix.h:140
bool getInterface(const patchSide &ps, boundaryInterface &result) const
Definition: gsBoxTopology.h:290
const knotContainer & get() const
Get a reference to the underlying std::vector of knots.
Definition: gsKnotVector.h:810
bool getNeighbour(const patchSide &ps, patchSide &result, int &ii) const
Definition: gsBoxTopology.cpp:137
Purely abstract class gsMappedBasis, which gives means of combining basis functions to new...
Definition: gsMPBESBasis.h:46
Struct which represents a certain side of a box.
Definition: gsBoundary.h:84
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
Class for representing a knot vector.
Definition: gsKnotVector.h:79
Struct which represents an interface between two patches.
Definition: gsBoundary.h:649
Defines a topological arrangement of a collection of "boxes" (e.g., parameter domains that map to phy...
Definition: gsBoxTopology.h:38
int degree() const
Returns the degree of the knot vector.
Definition: gsKnotVector.hpp:700
index_t patch
The index of the patch.
Definition: gsBoundary.h:234
Struct which represents a certain corner of a hyper-cube.
Definition: gsBoundary.h:291
short_t direction() const
Returns the parametric direction orthogonal to this side.
Definition: gsBoundary.h:113
bool isInterface(const patchSide &ps) const
Is the given patch side ps set to an interface?
Definition: gsBoxTopology.cpp:103
A basis represents a family of scalar basis functions defined over a common parameter domain...
Definition: gsBasis.h:78