G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsMPBESBasis.hpp
Go to the documentation of this file.
1
15
16namespace 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
30template<short_t d, class T>
32{
33 bool consistent = true;
34 consistent = consistent && _checkTopologyWithBases();
35 return consistent;
36}
37
38template<short_t d, class T>
39void 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
54template<short_t d, class T>
55bool 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
136template<short_t d, class T>
137void 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
150template<short_t d, class T>
151void 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
179template<short_t d, class T>
180void 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
188template<short_t d, class T>
189void 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
197template<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
206template<short_t d, class T>
207void 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
221template<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
238template<short_t d, class T>
239void 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
268template<short_t d, class T>
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
278template<short_t d, class T>
279bool 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
297template<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
312template<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();
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
332template<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
361template<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
371template<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
396template<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
425template<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
454template<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
471template<short_t d, class T>
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
Struct which represents a certain side of a box.
Definition gsBoundary.h:85
bool parameter() const
Returns the parameter value (false=0=start, true=1=end) that corresponds to this side.
Definition gsBoundary.h:128
short_t direction() const
Returns the parametric direction orthogonal to this side.
Definition gsBoundary.h:113
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:47
bool setWeight(const patchSide &ps, const T weight)
Definition gsMPBESBasis.hpp:279
void degreeIncrease(index_t amount=1, index_t dir=-1, bool updateBasis=true)
Definition gsMPBESBasis.hpp:189
void setC0(patchCorner pc)
Definition gsMPBESBasis.hpp:333
T getWeight(const patchSide &ps) const
Definition gsMPBESBasis.hpp:269
void uniformRefine_withCoefs(gsMatrix< T > &localCoefs, index_t numKnots=1, index_t mul=1, bool updateBasis=true)
Definition gsMPBESBasis.hpp:151
virtual void repairPatches(std::vector< gsMatrix< T > * > &coefs, index_t startFromPatch=-1)=0
void _setDistanceOfAllVertices()
initializes the m_distances field
Definition gsMPBESBasis.hpp:313
void _initVertices()
initializes the m_vertices field
Definition gsMPBESBasis.hpp:298
void uniformRefine(index_t numKnots=1, index_t mul=1, bool updateBasis=true)
Definition gsMPBESBasis.hpp:137
void smoothEverything()
Definition gsMPBESBasis.hpp:222
bool isSpecialVertex(const patchCorner &pc) const
gives back true, if the given patchCorner is a special vertex
Definition gsMPBESBasis.hpp:362
void smoothCornerEdge(const patchCorner &pc, const patchSide &ps, bool updateBasis=true)
Definition gsMPBESBasis.hpp:207
bool _check() const
Checks the gsMappedBasis for consistency.
Definition gsMPBESBasis.hpp:31
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 degreeElevate(index_t amount=1, bool updateBasis=true)
Definition gsMPBESBasis.hpp:180
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
Class Representing a triangle mesh with 3D vertices.
Definition gsMesh.h:32
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
#define index_t
Definition gsConfig.h:32
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Provides declaration of Basis abstract interface.
The G+Smo namespace, containing all definitions for the library.
void freeAll(It begin, It end)
Frees all pointers in the range [begin end)
Definition gsMemory.h:312
Struct which represents an interface between two patches.
Definition gsBoundary.h:650
patchSide & first()
first, returns the first patchSide of this interface
Definition gsBoundary.h:776
patchSide & second()
second, returns the second patchSide of this interface
Definition gsBoundary.h:782
Private stract that has the purpose of storing distance information of c^0 parts around special verti...
Definition gsMPBESBasis.h:342
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
T getParamDist(const patchCorner &pc, const gsMPBESBasis< d, T > &basis) const
gets the parametric distance from the corner pc
Definition gsMPBESBasis.hpp:455
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
Struct which represents a certain corner of a patch.
Definition gsBoundary.h:393
void getContainingSides(short_t dim, std::vector< patchSide > &sides) const
returns a vector of patchSides that contain this corner
Definition gsBoundary.h:416
Struct which represents a certain side of a patch.
Definition gsBoundary.h:232
index_t patch
The index of the patch.
Definition gsBoundary.h:234