G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsMPBESBasis.hpp
Go to the documentation of this file.
1 
15 
16 namespace gismo
17 {
18 
19 // template<short_t d, class T>
20 // void gsMPBESBasis<d,T>::_setMapping()
21 // {
22 // // * Initializer mapper
23 // gsMapFactory * maker = _getMapFactory();
24 // if(m_mapper)
25 // delete m_mapper;
26 // m_mapper = maker->makeMapper();
27 // delete maker;
28 // }
29 
30 template<short_t d, class T>
32 {
33  bool consistent = true;
34  consistent = consistent && _checkTopologyWithBases();
35  return consistent;
36 }
37 
38 template<short_t d, class T>
39 void gsMPBESBasis<d,T>::connectivity(const gsMatrix<T> & nodes,gsMesh<T> & mesh) const
40 {
41  const indexType sz = size();
42  GISMO_ASSERT( nodes.rows() == sz, "Invalid input.");
43 
44  // Add vertices
45  for( indexType i = 0; i< sz; ++i )
46  mesh.addVertex( nodes.row(i).transpose() );
47 
48  for( indexType i = 0; i< sz; ++i )
49  for( indexType j = i+1; j< sz; ++j )
50  if(isConnected(i,j))
51  mesh.addEdge(i,j);
52 }
53 
54 template<short_t d, class T>
55 bool gsMPBESBasis<d,T>::isConnected(indexType i,indexType j) const
56 {
57  std::vector<indexType> locals_i,locals_j;
58  m_mapper->targetToSource(i,locals_i);
59  m_mapper->targetToSource(j,locals_j);
60  indexType sz_i = locals_i.size(), sz_j = locals_j.size();
61 
62  if( sz_i==1 && sz_j==1 )
63  return isLocallyConnected(locals_i[0],locals_j[0]);
64 
65  if( sz_i==1 || sz_j==1 )
66  {
67  std::vector<indexType> & lookthrough=locals_j;
68  indexType element = sz_i==1 ? locals_i[0] : locals_j[0];
69  if( sz_i==1 )
70  lookthrough=locals_j;
71  else
72  lookthrough=locals_i;
73 
74  bool connected = false;
75  for( unsigned i2 = 0; i2<lookthrough.size(); ++i2 )
76  if( isLocallyConnected(element,lookthrough[i2]) )
77  {
78  connected = true;
79  break;
80  }
81  return connected;
82  }
83 
84  std::vector<indexType> setIntersection(sz_i+sz_j);
85  std::vector<indexType>::iterator it;
86  it=std::set_intersection (locals_i.begin(), locals_i.end(), locals_j.begin(), locals_j.end(), setIntersection.begin());
87  indexType sz_intersect = it-setIntersection.begin();
88  setIntersection.resize(sz_intersect);
89 
90  if( sz_intersect == sz_i-1 || sz_intersect == sz_j-1 )
91  return true;
92 
93  if( sz_intersect == 0 )
94  {
95  bool connected,allConnected=true;
96  for( indexType i3 = 0; i3< sz_i; ++i3 )
97  {
98  connected = false;
99  for( indexType j3 = 0; j3< sz_j; ++j3 )
100  if( isLocallyConnected(locals_i[i3],locals_j[j3]) )
101  {
102  connected = true;
103  break;
104  }
105  if( !connected )
106  {
107  allConnected=false;
108  break;
109  }
110  }
111  if ( allConnected )
112  return true;
113  allConnected=true;
114  for( indexType j4 = 0; j4< sz_j; ++j4 )
115  {
116  connected = false;
117  for( indexType i5 = 0; i5< sz_i; ++i5 )
118  if( isLocallyConnected(locals_i[i5],locals_j[j4]) )
119  {
120  connected = true;
121  break;
122  }
123  if( !connected )
124  {
125  allConnected=false;
126  break;
127  }
128  }
129  if ( allConnected )
130  return true;
131  }
132 
133  return false;
134 }
135 
136 template<short_t d, class T>
137 void gsMPBESBasis<d,T>::uniformRefine(index_t numKnots, index_t mul,bool updateBasis)
138 {
139  index_t start, end = -1;
140  for (BasisIter it=m_bases.begin();it!=m_bases.end();++it)
141  {
142  start=end+1;
143  end=start+(*it)->size()-1;
144  (*it)->uniformRefine(numKnots,mul);
145  }
146  if(updateBasis)
147  updateTopol();
148 }
149 
150 template<short_t d, class T>
151 void gsMPBESBasis<d,T>::uniformRefine_withCoefs(gsMatrix<T>& coefs, index_t numKnots, index_t mul, bool updateBasis)
152 {
153  index_t start, end = -1, geoDim=coefs.cols(), totalLength = 0;
154  std::vector<gsMatrix<T> *> newCoefs;
155  for (BasisIter it=m_bases.begin();it!=m_bases.end();++it)
156  {
157  start=end+1;
158  end=start+(*it)->size()-1;
159  gsMatrix<T> * it_coef = new gsMatrix<T>(end-start+1,geoDim);
160  it_coef->setZero();
161  *it_coef << coefs.block(start,0,end-start+1,geoDim);
162  (*it)->uniformRefine_withCoefs(*it_coef, numKnots,mul);
163  newCoefs.push_back(it_coef);
164  totalLength+=it_coef->rows();
165  }
166  coefs.resize(totalLength,geoDim);
167  end = -1;
168  for(ConstMatrixPtrIter it=newCoefs.begin();it!=newCoefs.end();++it)
169  {
170  start=end+1;
171  end=start+(*it)->rows()-1;
172  coefs.block(start,0,end-start+1,geoDim)<<**it;
173  }
174  freeAll(newCoefs);
175  if(updateBasis)
176  updateTopol();
177 }
178 
179 template<short_t d, class T>
180 void gsMPBESBasis<d,T>::degreeElevate( index_t amount , bool updateBasis )
181 {
182  for (size_t i = 0; i < nPatches(); ++i)
183  m_bases[i]->degreeElevate(amount); // TODO: must be something else then gsBasis::degreeElevate
184  if(updateBasis)
185  updateTopol();
186 }
187 
188 template<short_t d, class T>
189 void gsMPBESBasis<d,T>::degreeIncrease( index_t amount , index_t dir, bool updateBasis )
190 {
191  for (size_t i = 0; i < nPatches(); ++i)
192  m_bases[i]->degreeElevate(amount, dir);
193  if(updateBasis)
194  updateTopol();
195 }
196 
197 template<short_t d, class T>
199 {
200  std::vector<gsMatrix<T> *> coefs;
201  for (size_t i = 0; i < nPatches(); ++i)
202  coefs.push_back(NULL);
203  repairPatches(coefs,startFromPatch);
204 }
205 
206 template<short_t d, class T>
207 void gsMPBESBasis<d,T>::smoothCornerEdge(const patchCorner&pc,const patchSide& ps,bool updateBasis)
208 {
209  boundaryInterface interface;
210  bool special = isSpecialVertex(pc);
211  if( special && m_topol.getInterface(ps,interface) )
212  {
213  for(unsigned i=0;i<m_distances.size();++i)
214  if(m_distances[i].isDistancesOfInterface(interface))
215  m_distances[i].setParamDist(m_minDist,pc,*this);
216  }
217  if(updateBasis)
218  updateTopol();
219 }
220 
221 template<short_t d, class T>
223 {
224  std::vector<std::vector<patchCorner> >cornerLists;
225  std::vector<patchSide> psides;
226  m_topol.getEVs(cornerLists);
227  for(unsigned i=0;i<cornerLists.size();++i)
228  for(unsigned j=0;j<cornerLists[i].size();++j)
229  {
230  patchCorner& pc=cornerLists[i][j];
231  pc.getContainingSides(d,psides);
232  for(unsigned k=0;k<psides.size();++k)
233  smoothCornerEdge(pc,psides[k],false);
234  }
235  updateTopol();
236 }
237 
238 template<short_t d, class T>
239 void gsMPBESBasis<d,T>::repairPatches(gsMatrix<T> & localCoef, index_t startFromPatch)
240 {
241  std::vector<gsMatrix<T> *> patchCoefs;
242  unsigned geoDim = localCoef.cols();
243  index_t start, end = -1;
244  for (size_t i = 0; i < nPatches(); ++i)
245  {
246  start=end+1;
247  end+=m_bases[i]->size();
248  gsMatrix<T>* localMat = new gsMatrix<T>(end-start+1,geoDim);
249  *localMat << localCoef.block(start,0,end-start+1,geoDim);
250  patchCoefs.push_back(localMat);
251  }
252  repairPatches(patchCoefs,startFromPatch);
253  unsigned totalSize=0;
254  for (size_t i = 0; i < nPatches(); ++i)
255  {
256  totalSize+=m_bases[i]->size();
257  }
258  localCoef.resize(totalSize,geoDim);
259  end = -1;
260  for (size_t i = 0; i < nPatches(); i++)
261  {
262  start=end+1;
263  end+=m_bases[i]->size();
264  localCoef.block(start,0,end-start+1,geoDim) << *patchCoefs[i];
265  }
266 }
267 
268 template<short_t d, class T>
270 {
271  typedef typename std::vector<std::pair<patchSide,T> >::const_iterator cWeightPairIter;
272  for(cWeightPairIter it=m_patchSideWeights.begin();it!=m_patchSideWeights.end();++it)
273  if(it->first == ps)
274  return it->second;
275  return 1.0;
276 }
277 
278 template<short_t d, class T>
279 bool gsMPBESBasis<d,T>::setWeight(const patchSide & ps, const T weight)
280 {
281  typedef typename std::vector<std::pair<patchSide,T> >::iterator weightPairIter;
282  bool found = false;
283  for(weightPairIter it=m_patchSideWeights.begin();it!=m_patchSideWeights.end();++it)
284  if(it->first == ps)
285  {
286  it->second = weight;
287  found = true;
288  }
289  if(!found && m_topol.isInterface(ps))
290  {
291  m_patchSideWeights.push_back(std::make_pair(ps,weight));
292  found = true;
293  }
294  return found;
295 }
296 
297 template<short_t d, class T>
299 {
300  m_vertices.clear();
301  std::vector<std::vector<patchCorner> > vertexLists;
302  m_topol.getEVs(vertexLists);
303  for(unsigned i = 0;i<vertexLists.size();++i)
304  for(unsigned j=0;j<vertexLists[i].size();++j)
305  m_vertices.push_back(std::make_pair(vertexLists[i][j],true));
306  m_topol.getOVs(vertexLists);
307  for(unsigned i = 0;i<vertexLists.size();++i)
308  for(unsigned j=0;j<vertexLists[i].size();++j)
309  m_vertices.push_back(std::make_pair(vertexLists[i][j],false));
310 }
311 
312 template<short_t d, class T>
314 {
315  m_distances.clear();
316  for(std::vector<boundaryInterface>::const_iterator iter = m_topol.iBegin();
317  iter!=m_topol.iEnd();++iter)
318  {
319  const patchSide & ps = (*iter).first();
320  gsVector<bool>pars(2);
321  index_t dir = ps.direction();
322  pars(dir ) = ps.parameter();
323  pars(1-dir)=0;
324  patchCorner pc1 = patchCorner(ps.patch,pars);
325  pars(1-dir)=1;
326  patchCorner pc2 = patchCorner(ps.patch,pars);
327  distances dist(*iter,pc1,pc2,*this);
328  m_distances.push_back(dist);
329  }
330 }
331 
332 template<short_t d, class T>
334 {
335  std::vector<patchCorner> vertexList;
336  m_topol.getCornerList(pc,vertexList);
337  for(unsigned i = 0;i<vertexList.size();++i)
338  {
339  bool found = false;
340  for(unsigned j = 0;j<m_vertices.size();++j)
341  if(m_vertices[j].first==vertexList[i])
342  {
343  m_vertices[j].second=true;
344  found=true;
345  }
346  if(!found)
347  m_vertices.push_back(std::make_pair(vertexList[i],true));
348  }
349  std::vector<patchSide> sides;
350  pc.getContainingSides(dim(),sides);
351  for(unsigned i = 0;i<sides.size();++i)
352  {
353  boundaryInterface interface;
354  if(m_topol.getInterface(sides[i],interface))
355  for(unsigned j=0;j<m_distances.size();++j)
356  if(m_distances[j].isDistancesOfInterface(interface))
357  m_distances[j].setParamDist(m_minDist,pc,*this);
358  }
359 }
360 
361 template<short_t d, class T>
363 {
364  typedef std::vector<std::pair<patchCorner,bool> >::const_iterator cvertices_iter;
365  for(cvertices_iter iter=m_vertices.begin(); iter!=m_vertices.end();++iter)
366  if(pc==(*iter).first)
367  return (*iter).second;
368  return false;
369 }
370 
371 template<short_t d, class T>
373 {
374  boundaryInterface interface;
375  T param = 0.0;
376  bool special = isSpecialVertex(pc);
377  if( special && m_topol.getInterface(ps,interface) )
378  {
379  for(unsigned i=0;i<m_distances.size();++i)
380  if(m_distances[i].isDistancesOfInterface(interface))
381  param = m_distances[i].getParamDist(pc,*this);
382  }
383  else if( special )
384  param = findParameter(ps,pc,m_minDist);
385  else
386  {
387  const index_t deg=degree(pc.patch,1-ps.side().direction());
388  const unsigned degree = std::min<index_t>(deg,m_incrSmoothnessDegree+1);
389  for(unsigned i=0;i<m_vertices.size();++i)
390  if(pc==m_vertices[i].first)
391  param = findParameter(ps,pc,degree);
392  }
393  return param;
394 }
395 
396 template<short_t d, class T>
398  const patchCorner& pc2,const gsMPBESBasis<d,T>& basis) :
399  interface(iface),corner1(pc1),corner2(pc2)
400 {
401  const patchSide& ps = interface.first();
402  const unsigned patch = ps.patch;
403  const boxSide& side = ps.side();
404  const index_t deg=basis.degree(patch,1-side.direction());
405  const index_t max=basis.basisFunctionsOnSide(ps);
406 
407  GISMO_ASSERT(d==2,"only works for dimension 2");
408  std::vector<patchSide> psides;
409  pc1.getContainingSides(2,psides);
410  psides.erase(std::remove(psides.begin(), psides.end(), ps), psides.end());
411  const patchSide ps1 = psides[0];
412  pc2.getContainingSides(2,psides);
413  psides.erase(std::remove(psides.begin(), psides.end(), ps), psides.end());
414  const patchSide ps2 = psides[0];
415 
416  const unsigned degree = std::min<index_t>(deg,basis.getIncrSmoothnessDegree()+1);
417  const index_t dist=std::max<index_t>(degree,basis.getMinDist());
418  unsigned val1,val2;
419 
420  _determineValues(ps,ps1,ps2,dist,degree,max,val1,val2,basis);
421  parametricDistance1=basis.findParameter(interface.first(),pc1,val1);
422  parametricDistance2=basis.findParameter(interface.first(),pc1,val2);
423 }
424 
425 template<short_t d, class T>
427 {
428  std::vector<patchCorner> cornerList;
429  basis.getTopol().getCornerList(corner1,cornerList);
430  if( std::find(cornerList.begin(), cornerList.end(), pc)!=cornerList.end() )
431  {
432  if(basis.isSpecialVertex(pc))
433  {
434  if(corner1.patch==interface.first().patch)
435  parametricDistance1=basis.findParameter(interface.first(),corner1,absoluteVal);
436  else
437  parametricDistance1=basis.findParameter(interface.second(),corner1,absoluteVal);
438  }
439  }
440  else
441  {
442  basis.getTopol().getCornerList(corner2,cornerList);
443  if( std::find(cornerList.begin(), cornerList.end(), pc)!=cornerList.end() )
444  if(basis.isSpecialVertex(pc))
445  {
446  if(corner2.patch==interface.first().patch)
447  parametricDistance2=basis.findParameter(interface.first(),corner2,absoluteVal);
448  else
449  parametricDistance2=basis.findParameter(interface.second(),corner2,absoluteVal);
450  }
451  }
452 }
453 
454 template<short_t d, class T>
456 {
457  T param = -1.0;
458  std::vector<patchCorner> cornerList;
459  basis.getTopol().getCornerList(corner1,cornerList);
460  if( std::find(cornerList.begin(), cornerList.end(), pc)!=cornerList.end() )
461  param = parametricDistance1;
462  else
463  {
464  basis.getTopol().getCornerList(corner2,cornerList);
465  if( std::find(cornerList.begin(), cornerList.end(), pc)!=cornerList.end() )
466  param = parametricDistance2;
467  }
468  return param;
469 }
470 
471 template<short_t d, class T>
472 void gsMPBESBasis<d,T>::distances::_determineValues(patchSide side,patchSide ls,patchSide rs,index_t dist,unsigned degree,unsigned max,
473  unsigned& left,unsigned& right,const gsMPBESBasis<d,T>& basis) const
474 {
475  gsVector<bool>pars(2);
476  index_t dir = side.direction();
477  index_t par = side.parameter();
478  pars(dir) = par==0 ? false : true;
479  pars(1-dir)=ls.parameter();
480  patchCorner pc1 = patchCorner(side.patch,pars);
481  pars(1-dir)=rs.parameter();
482  patchCorner pc2 = patchCorner(side.patch,pars);
483  bool leftSpecialVert = basis.isSpecialVertex(pc1);
484  bool rightSpecialVert = basis.isSpecialVertex(pc2);
485  bool leftInter = basis.getTopol().isInterface(ls);
486  bool rightInter = basis.getTopol().isInterface(rs);
487  unsigned leftDist = dist;
488  unsigned rightDist = dist;
489  if(leftSpecialVert&&rightSpecialVert)
490  {
491  if(leftDist+rightDist<=max)
492  {
493  left=leftDist;
494  right=rightDist;
495  }
496  else
497  {
498  left=max/2;
499  right=max-left;
500  }
501  }
502  else if(leftSpecialVert&&rightInter)
503  {
504  right=degree;
505  left=max-degree<leftDist?max-degree:leftDist;
506  }
507  else if(rightSpecialVert&&leftInter)
508  {
509  left=degree;
510  right=max-degree<rightDist?max-degree:rightDist;
511  }
512  else if(rightSpecialVert)
513  {
514  right=max<rightDist?max:rightDist;
515  left=0;
516  }
517  else if(leftSpecialVert)
518  {
519  left=max<leftDist?max:leftDist;
520  right=0;
521  }
522  else
523  {
524  left=0;
525  right=0;
526  if(leftInter)
527  left=degree;
528  if(rightInter)
529  right=degree;
530  }
531 }
532 
533 } // namespace gismo
bool isSpecialVertex(const patchCorner &pc) const
gives back true, if the given patchCorner is a special vertex
Definition: gsMPBESBasis.hpp:362
Provides declaration of Basis abstract interface.
Struct which represents a certain side of a patch.
Definition: gsBoundary.h:231
void setC0(patchCorner pc)
Definition: gsMPBESBasis.hpp:333
T getWeight(const patchSide &ps) const
Definition: gsMPBESBasis.hpp:269
T getParamDist(const patchCorner &pc, const gsMPBESBasis< d, T > &basis) const
gets the parametric distance from the corner pc
Definition: gsMPBESBasis.hpp:455
bool parameter() const
Returns the parameter value (false=0=start, true=1=end) that corresponds to this side.
Definition: gsBoundary.h:128
virtual T findParameter(patchSide const &ps, patchCorner const &pc, unsigned nrBasisFuncs) const =0
#define index_t
Definition: gsConfig.h:32
void getContainingSides(short_t dim, std::vector< patchSide > &sides) const
returns a vector of patchSides that contain this corner
Definition: gsBoundary.h:416
bool _check() const
Checks the gsMappedBasis for consistency.
Definition: gsMPBESBasis.hpp:31
Struct which represents a certain corner of a patch.
Definition: gsBoundary.h:392
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
void uniformRefine_withCoefs(gsMatrix< T > &localCoefs, index_t numKnots=1, index_t mul=1, bool updateBasis=true)
Definition: gsMPBESBasis.hpp:151
Class Representing a triangle mesh with 3D vertices.
Definition: gsMesh.h:31
virtual void repairPatches(std::vector< gsMatrix< T > * > &coefs, index_t startFromPatch=-1)=0
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
Purely abstract class gsMappedBasis, which gives means of combining basis functions to new...
Definition: gsMPBESBasis.h:46
void smoothCornerEdge(const patchCorner &pc, const patchSide &ps, bool updateBasis=true)
Definition: gsMPBESBasis.hpp:207
void freeAll(It begin, It end)
Frees all pointers in the range [begin end)
Definition: gsMemory.h:312
Private stract that has the purpose of storing distance information of c^0 parts around special verti...
Definition: gsMPBESBasis.h:341
Struct which represents a certain side of a box.
Definition: gsBoundary.h:84
T getParametricDistanceOfVertex(const patchCorner &pc, const patchSide &ps) const
gives back the parametric c^0 distance of the edge ps starting from corner pc
Definition: gsMPBESBasis.hpp:372
void degreeIncrease(index_t amount=1, index_t dir=-1, bool updateBasis=true)
Definition: gsMPBESBasis.hpp:189
void smoothEverything()
Definition: gsMPBESBasis.hpp:222
void setParamDist(unsigned absoluteVal, const patchCorner &pc, const gsMPBESBasis< d, T > &basis)
Definition: gsMPBESBasis.hpp:426
distances(const boundaryInterface &iface, const patchCorner &pc1, const patchCorner &pc2, const gsMPBESBasis< d, T > &basis)
Definition: gsMPBESBasis.hpp:397
void _determineValues(patchSide side, patchSide ls, patchSide rs, index_t dist, unsigned degree, unsigned max, unsigned &left, unsigned &right, const gsMPBESBasis< d, T > &basis) const
determines the right values for the two distances, only used in the constructer
Definition: gsMPBESBasis.hpp:472
void uniformRefine(index_t numKnots=1, index_t mul=1, bool updateBasis=true)
Definition: gsMPBESBasis.hpp:137
virtual unsigned basisFunctionsOnSide(const patchSide &ps) const =0
Returns the amount of basis functions on a given side of a given patch.
bool setWeight(const patchSide &ps, const T weight)
Definition: gsMPBESBasis.hpp:279
Struct which represents an interface between two patches.
Definition: gsBoundary.h:649
void _initVertices()
initializes the m_vertices field
Definition: gsMPBESBasis.hpp:298
index_t getIncrSmoothnessDegree() const
getter for m_incrSmoothnessDegree
Definition: gsMPBESBasis.h:168
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 degreeElevate(index_t amount=1, bool updateBasis=true)
Definition: gsMPBESBasis.hpp:180
void _setDistanceOfAllVertices()
initializes the m_distances field
Definition: gsMPBESBasis.hpp:313
patchSide & first()
first, returns the first patchSide of this interface
Definition: gsBoundary.h:776