G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsDofMapper.h
Go to the documentation of this file.
1
14#pragma once
15
17#include <gsCore/gsBoundary.h>
18#include <gsCore/gsExport.h>
19
20namespace gismo
21{
22
23#define MAPPER_PATCH_DOF(a,b,c) m_dofs[c][m_offset[b]+a]
24
68class GISMO_EXPORT gsDofMapper
69{
70public:
71
74
84 template<class T>
86 const gsMultiBasis<T> &bases,
87 const gsBoundaryConditions<T> &dirichlet,
88 int unk = 0
89 ) : m_shift(0), m_bshift(0)
90 {
91 init(bases, dirichlet, unk); //obsolete, one component
92 }
93
100 template<class T>
101 gsDofMapper(const gsMultiBasis<T> & bases, index_t nComp = 1)
102 {
103 init(bases, nComp);
104 }
105
112 template<class T>
114 std::vector<const gsMultiBasis<T> *> const & bases
115 )
116 {
117 init(bases);
118 }
119
120
127 template<class T>
128 gsDofMapper(const gsBasis<T> & basis, index_t nComp = 1)
129 {
130 initSingle(basis, nComp);
131 }
132
139 gsDofMapper(const gsVector<index_t> &patchDofSizes, index_t nComp = 1)
140 {
141 initPatchDofs(patchDofSizes, nComp);
142 }
143
145 template <typename T>
146 void init(const gsMultiBasis<T> & bases, index_t nComp = 1);
147
149 template <typename T>
150 void init( std::vector<const gsMultiBasis<T> *> const & bases);
151
154 template<class T>
155 void init(const gsMultiBasis<T> &basis,
156 const gsBoundaryConditions<T> &dirichlet, int unk = 0);
157
158 void swap(gsDofMapper & other)
159 {
160 m_dofs .swap(other.m_dofs);
161 m_offset.swap(other.m_offset);
162
163 std::swap(m_shift , other.m_shift);
164 std::swap(m_bshift , other.m_bshift);
165 std::swap(m_numFreeDofs, other.m_numFreeDofs);
166 std::swap(m_numElimDofs, other.m_numElimDofs);
167 std::swap(m_numCpldDofs, other.m_numCpldDofs);
168 std::swap(m_curElimId , other.m_curElimId);
169 std::swap(m_tagged , other.m_tagged);
170 }
171
172private:
173
175 template <typename T>
176 void initSingle( const gsBasis<T> & basis, index_t nComp = 1);
177
179 void initPatchDofs(const gsVector<index_t> & patchDofSizes,
180 index_t nComp = 1);
181
182public:
183
185 gsVector<index_t> asVector(index_t comp = 0) const;
186
191 gsVector<index_t> inverseAsVector(index_t comp = 0) const;
192
196
202 void colapseDofs(index_t k, const gsMatrix<unsigned> & b, index_t comp = 0);
203
207 void matchDof( index_t u, index_t i, index_t v, index_t j, index_t comp = 0);
208
211 void matchDofs(index_t u, const gsMatrix<index_t> & b1,
212 index_t v, const gsMatrix<index_t> & b2,
213 index_t comp = 0);
214
216 void markCoupled(index_t i, index_t k, index_t comp = 0);
217
219 void markTagged(index_t i, index_t k, index_t comp = 0);
220
222 void markCoupledAsTagged();
223
225 // to do: put k at the end
226 void markBoundary(index_t k, const gsMatrix<index_t> & boundaryDofs, index_t comp = 0);
227
229 void eliminateDof(index_t i, index_t k, index_t comp = 0);
230
233 void finalize();
234
236 bool isFinalized() const { return m_curElimId>=0; }
237
239 bool isPermutation() const { return static_cast<size_t>(size())==mapSize(); }
240
242 std::ostream& print( std::ostream& os = gsInfo ) const;
243
245 void setIdentity(index_t nPatches, size_t nDofs, size_t nComp = 1);
246
248 void setShift(index_t shift);
249
251 void addShift(index_t shift);
252
258 void permuteFreeDofs(const gsVector<index_t>& permutation, index_t comp = 0);
259
261 index_t firstIndex(index_t comp = 0) const
262 { return m_numFreeDofs[comp] + m_numElimDofs[comp] + m_shift; }
263
265 index_t lastIndex() const { return m_shift + freeSize(); }
266
268 void setBoundaryShift(index_t shift);
269
276 void localToGlobal(const gsMatrix<index_t>& locals,
277 index_t patchIndex,
278 gsMatrix<index_t>& globals,
279 index_t comp = 0) const;
280
288 void localToGlobal2(const gsMatrix<index_t>& locals,
289 index_t patchIndex,
290 gsMatrix<index_t>& globals,
291 index_t & numFree,
292 index_t comp = 0) const;
293
300 inline index_t freeIndex(index_t i, index_t k = 0, index_t c = 0) const
301 {
302 GISMO_ASSERT(m_curElimId>=0, "finalize() was not called on gsDofMapper");
303 return MAPPER_PATCH_DOF(i,k,c);
304 }
305
306 index_t componentOf(index_t gl) const
307 {
308 GISMO_ASSERT(m_curElimId>=0,"finalize() was not called on gsDofMapper");
309 //index_t c = 1; // could do some binary search
310 //in place
311 //while (gl >= m_numFreeDofs[c]+m_numElimDofs[c]) { ++c; }
312 //elim
313 return (gl<m_numFreeDofs.back() ?
314 std::distance(m_numFreeDofs.begin(), std::upper_bound(m_numFreeDofs.begin(), m_numFreeDofs.end(), gl))
315 : std::distance(m_numElimDofs.begin(),std::upper_bound(m_numElimDofs.begin(), m_numElimDofs.end(), gl-m_numFreeDofs.back())) ) - 1;
316 //while (gl >= m_numFreeDofs[c] + m_shift) { ++c; } return c-1;
317 }
318
325 inline index_t index(index_t i, index_t k = 0, index_t c = 0) const
326 {
327 GISMO_ASSERT(m_curElimId>=0, "finalize() was not called on gsDofMapper");
328 return MAPPER_PATCH_DOF(i,k,c)+m_shift;
329 }
330
334 inline index_t bindex(index_t i, index_t k = 0, index_t c = 0) const
335 {
336 GISMO_ASSERT(m_curElimId>=0, "finalize() was not called on gsDofMapper");
337 return MAPPER_PATCH_DOF(i,k,c) - m_numFreeDofs.back()
338 //- m_numElimDofs[c]
339 + m_bshift;
340 }
341
343 bool allFree() const
344 { return m_numFreeDofs.back()+m_numElimDofs.back()==m_curElimId; }
345
347 inline index_t cindex(index_t i, index_t k = 0, index_t c = 0) const
348 {
349 GISMO_ASSERT(m_curElimId>=0, "finalize() was not called on gsDofMapper");
350 return MAPPER_PATCH_DOF(i,k,c) - m_numFreeDofs[c+1]
351 + m_numCpldDofs[c+1];
352 }
353
355 inline index_t tindex(index_t i, index_t k = 0, index_t c = 0) const
356 {
357 GISMO_ASSERT(m_curElimId>=0, "finalize() was not called on gsDofMapper");
358 return std::distance(m_tagged.begin(),std::lower_bound(m_tagged.begin(),m_tagged.end(),MAPPER_PATCH_DOF(i,k,c)));
359 }
360
365 {
366 GISMO_ASSERT( is_boundary_index( gl ),
367 "global_to_bindex(): dof "<<gl<<" is not on the boundary");
368 return gl - m_numFreeDofs.back() - m_shift + m_bshift;
369 //gl -= m_numFreeDofs.back() + m_shift;
370 //const index_t c = std::distance(m_numElimDofs.begin(),
371 // std::upper_bound(m_numElimDofs.begin(), m_numElimDofs.end(),gl)) -1;
372 //return gl + m_bshift; // - m_numElimDofs[c]
373 }
374
376 inline bool is_free_index(index_t gl) const
377 {
378 return gl < m_curElimId + m_shift;
379 }
380
382 inline bool is_free( index_t i, index_t k = 0, index_t c = 0) const
383 { return is_free_index( index(i, k, c) ); }
384
386 inline bool is_boundary_index( index_t gl ) const
387 { return gl >= m_numFreeDofs.back() + m_shift; }
388
390 inline bool is_boundary(index_t i, index_t k = 0, index_t c = 0) const
391 {return is_boundary_index( index(i, k, c) );}
392
394 inline bool is_coupled( index_t i, index_t k = 0, index_t c = 0) const
395 { return is_coupled_index( index(i, k, c) ); }
396
398 inline bool is_coupled_index(index_t gl) const
399 {
400 const index_t gc = componentOf(gl);
401 const index_t vv = m_numFreeDofs[gc+1] + m_shift;
402 return (gl < vv && // is a free dof and
403 (gl + m_numCpldDofs[gc+1] + 1 > vv) ); // is not standard dof
404 }
405
407 inline bool is_tagged(index_t i, index_t k = 0, index_t c = 0) const
408 { return is_tagged_index( index(i, k, c) ); }
409
411 inline bool is_tagged_index(index_t gl) const
412 {
413 return std::binary_search(m_tagged.begin(),m_tagged.end(),gl);
414 }
415
417 inline index_t numComponents() const
418 { return static_cast<index_t>(m_dofs.size()); }
419
421 inline index_t size() const
422 {
423 GISMO_ENSURE(m_curElimId>=0, "finalize() was not called on gsDofMapper");
424 return freeSize() + boundarySize();
425 }
426
428 inline index_t size(index_t comp) const
429 {
430 GISMO_ENSURE(m_curElimId>=0, "finalize() was not called on gsDofMapper");
431 return m_numFreeDofs[comp+1]-m_numFreeDofs[comp]
432 + m_numElimDofs[comp+1]-m_numElimDofs[comp];
433 }
434
436 inline index_t freeSize() const
437 {
438 return m_curElimId;
439 }
440
441 inline index_t freeSize(index_t comp) const
442 {
443 return m_numFreeDofs[comp+1]-m_numFreeDofs[comp] +
444 (allFree() ? m_numElimDofs[comp+1]-m_numElimDofs[comp] : 0 );
445 }
446
448 const std::vector<index_t> & getTagged() const { return m_tagged; }
449
451 index_t coupledSize() const;
452
454 index_t taggedSize() const;
455
457 inline index_t boundarySize() const
458 {
459 GISMO_ENSURE(m_curElimId>=0, "finalize() was not called on gsDofMapper");
460 return m_numElimDofs.back();
461 }
462
463 index_t boundarySizeWithDuplicates() const;
464
466 size_t offset(int k) const {return m_offset[k];}
467
469 size_t numPatches() const {return m_offset.size();}
470
473 size_t mapSize() const
474 { return (m_dofs.empty()?0:m_dofs.size() * m_dofs.front().size()); }
475
476 size_t componentsSize() const {return m_dofs.size();}
477
480 size_t patchSize(const index_t k, const index_t c = 0) const
481 {
482 const size_t k1(k+1);
483 GISMO_ASSERT(k1<=numPatches(), "Invalid patch index "<< k <<" >= "<< numPatches() );
484 if ( 1==m_offset.size() ) return m_dofs[c].size();
485 else if ( k1==m_offset.size() ) return (m_dofs[c].size() - m_offset.back());
486 else return (m_offset[k1]-m_offset[k]);
487 }
488
489 size_t totalSize(const index_t c = 0) const
490 {
491 return m_dofs[c].size();
492 }
493
497 void preImage(index_t gl, std::vector<std::pair<index_t,index_t> > & result) const;
498
501 std::pair<index_t,index_t> anyPreImage(index_t gl) const;
502
505 std::vector<std::pair<index_t,index_t> > anyPreImages(index_t comp = 0) const;
506
509 std::map<index_t,index_t> inverseOnPatch(const index_t k) const;
510
513 bool indexOnPatch(const index_t gl, const index_t k) const;
514
519 {
520 return m_dofs[n/m_dofs.front().size()]
521 [n%m_dofs.front().size()] + m_shift;
522 }
523
525 gsVector<index_t> findBoundary(const index_t k) const;
526
528 gsVector<index_t> findFree(const index_t k) const;
529
531 gsVector<index_t> findCoupled(const index_t k, const index_t j = -1) const;
532
534 gsVector<index_t> findFreeUncoupled(const index_t k) const;
535
537 gsVector<index_t> findTagged(const index_t k) const;
538
539private:
540
541 template<class Predicate, class Iterator>
542 static gsVector<index_t> find_impl(Iterator istart, Iterator iend, Predicate pred);
543
544 void finalizeComp(const index_t comp);
545
546 // replace all references to oldIdx by newIdx
547 inline void replaceDofGlobally(index_t oldIdx, index_t newIdx);
548 inline void replaceDofGlobally(index_t oldIdx, index_t newIdx, index_t comp);
549
550 void mergeDofsGlobally(index_t dof1, index_t dof2);
551 void mergeDofsGlobally(index_t dof1, index_t dof2, index_t comp);
552
553// Data members
554private:
555
556 // m_dofs/m_patchDofs stores for each patch the mapping from local to global dofs.
557 //
558 // During setup, the entries have a different meaning:
559 // 0 -- regular free dof
560 // negative -- an eliminated dof
561 // positive -- a coupling dof
562 // For nonzero entries, the value is an id which identifies the eliminated/coupling
563 // group of the dof. Dofs with the same id will get the same dof index in the
564 // final numbering stage in finalize().
565
566 // Representation of each component as a single vector plus
567 // offsets for patch-local indices
568 std::vector<std::vector<index_t> > m_dofs;
569
571 std::vector<size_t> m_offset;
572
575
578
580 std::vector<index_t> m_numFreeDofs;
582 std::vector<index_t> m_numElimDofs;
584 std::vector<index_t> m_numCpldDofs;
585
586 // used during setup: running id for current eliminated dof
587 // After finalize() is called m_curElimId takes positive value.
588 index_t m_curElimId;
589
591 std::vector<index_t> m_tagged;
592
593}; // class gsDofMapper
594
596inline std::ostream& operator<<( std::ostream& os, const gsDofMapper& b )
597{
598 return b.print( os );
599}
600
601#ifdef GISMO_WITH_PYBIND11
602
606 void pybind11_init_gsDofMapper(pybind11::module &m);
607
608#endif // GISMO_WITH_PYBIND11
609
610} // namespace gismo
611
612
613#ifndef GISMO_BUILD_LIB
614#include GISMO_HPP_HEADER(gsDofMapper.hpp)
615#endif
A basis represents a family of scalar basis functions defined over a common parameter domain.
Definition gsBasis.h:79
Class containing a set of boundary conditions.
Definition gsBoundaryConditions.h:342
Defines a topological arrangement of a collection of "boxes" (e.g., parameter domains that map to phy...
Definition gsBoxTopology.h:39
Maintains a mapping from patch-local dofs to global dof indices and allows the elimination of individ...
Definition gsDofMapper.h:69
bool allFree() const
Returns true iff all DoFs are considered as free.
Definition gsDofMapper.h:343
bool is_coupled(index_t i, index_t k=0, index_t c=0) const
Returns true if local dof i of patch k is coupled.
Definition gsDofMapper.h:394
bool is_coupled_index(index_t gl) const
Returns true if gl is a coupled dof.
Definition gsDofMapper.h:398
std::vector< size_t > m_offset
Offsets.
Definition gsDofMapper.h:571
bool is_tagged_index(index_t gl) const
Returns true if gl is a tagged dof.
Definition gsDofMapper.h:411
bool is_boundary(index_t i, index_t k=0, index_t c=0) const
Returns true if local dof i of patch k is eliminated.
Definition gsDofMapper.h:390
index_t cindex(index_t i, index_t k=0, index_t c=0) const
Returns the coupled dof index.
Definition gsDofMapper.h:347
gsDofMapper(const gsVector< index_t > &patchDofSizes, index_t nComp=1)
construct a dof mapper with a given number of dofs per patch
Definition gsDofMapper.h:139
std::ostream & print(std::ostream &os=gsInfo) const
Print summary.
Definition gsDofMapper.cpp:346
index_t bindex(index_t i, index_t k=0, index_t c=0) const
Returns the boundary index of local dof i of patch k.
Definition gsDofMapper.h:334
void setMatchingInterfaces(const gsBoxTopology &mp)
gsDofMapper(const gsMultiBasis< T > &bases, index_t nComp=1)
construct a dof mapper that identifies the degrees of freedom in the multibasis
Definition gsDofMapper.h:101
index_t freeIndex(index_t i, index_t k=0, index_t c=0) const
Returns the index associated to local dof i of patch k without shifts.
Definition gsDofMapper.h:300
bool isPermutation() const
Returns true iff the mapper is a permuatation.
Definition gsDofMapper.h:239
gsDofMapper(const gsBasis< T > &basis, index_t nComp=1)
construct a dof mapper that manages the degrees of freedom in a gsBasis
Definition gsDofMapper.h:128
index_t mapIndex(index_t n) const
For n being an index which is already offsetted, it returns the global index where it is mapped to by...
Definition gsDofMapper.h:518
index_t size(index_t comp) const
Returns the total number of dofs (free and eliminated).
Definition gsDofMapper.h:428
index_t tindex(index_t i, index_t k=0, index_t c=0) const
Returns the tagged dof index.
Definition gsDofMapper.h:355
index_t m_shift
Shifting of the global index (zero by default)
Definition gsDofMapper.h:574
std::vector< index_t > m_tagged
Stores the tagged indices.
Definition gsDofMapper.h:591
size_t patchSize(const index_t k, const index_t c=0) const
Returns the total number of patch-local DoFs that live on patch k for component c.
Definition gsDofMapper.h:480
index_t size() const
Returns the total number of dofs (free and eliminated).
Definition gsDofMapper.h:421
std::vector< index_t > m_numCpldDofs
Offsets of coupled dofs, nComp+1.
Definition gsDofMapper.h:584
size_t numPatches() const
Returns the number of patches present underneath the mapper.
Definition gsDofMapper.h:469
size_t offset(int k) const
Returns the offset corresponding to patch k.
Definition gsDofMapper.h:466
bool is_free_index(index_t gl) const
Returns true if global dof gl is not eliminated.
Definition gsDofMapper.h:376
size_t mapSize() const
Returns the total number of patch-local degrees of freedom that are being mapped.
Definition gsDofMapper.h:473
std::vector< index_t > m_numFreeDofs
Offsets of free dofs, nComp+1.
Definition gsDofMapper.h:580
index_t boundarySize() const
Returns the number of eliminated dofs.
Definition gsDofMapper.h:457
bool isFinalized() const
Checks whether finalize() has been called.
Definition gsDofMapper.h:236
index_t lastIndex() const
Returns one past the biggest value of the free indices.
Definition gsDofMapper.h:265
index_t freeSize() const
Returns the number of free (not eliminated) dofs.
Definition gsDofMapper.h:436
const std::vector< index_t > & getTagged() const
Returns the vector of tagged (not eliminated) dofs.
Definition gsDofMapper.h:448
index_t numComponents() const
Returns the number of components present in the mapper.
Definition gsDofMapper.h:417
bool is_tagged(index_t i, index_t k=0, index_t c=0) const
Returns true if local dof i of patch k is tagged.
Definition gsDofMapper.h:407
index_t firstIndex(index_t comp=0) const
Returns the smallest value of the indices for comp.
Definition gsDofMapper.h:261
index_t global_to_bindex(index_t gl) const
Returns the boundary index of global dof gl.
Definition gsDofMapper.h:364
index_t index(index_t i, index_t k=0, index_t c=0) const
Returns the global dof index associated to local dof i of patch k.
Definition gsDofMapper.h:325
std::vector< index_t > m_numElimDofs
Offsets of eliminated dofs, nComp+1.
Definition gsDofMapper.h:582
gsDofMapper(std::vector< const gsMultiBasis< T > * > const &bases)
construct a dof mapper that identifies the degrees of freedom for a vector of multibasis
Definition gsDofMapper.h:113
bool is_free(index_t i, index_t k=0, index_t c=0) const
Returns true if local dof i of patch k is not eliminated.
Definition gsDofMapper.h:382
index_t m_bshift
Shifting of the boundary index (zero by default)
Definition gsDofMapper.h:577
gsDofMapper(const gsMultiBasis< T > &bases, const gsBoundaryConditions< T > &dirichlet, int unk=0)
construct a dof mapper that identifies the degrees of freedom in the multibasis and eliminates the de...
Definition gsDofMapper.h:85
bool is_boundary_index(index_t gl) const
Returns true if global dof gl is eliminated.
Definition gsDofMapper.h:386
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
Holds a set of patch-wise bases and their topology information.
Definition gsMultiBasis.h:37
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
Provides structs and classes related to interfaces and boundaries.
#define index_t
Definition gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition gsDebug.h:102
#define gsInfo
Definition gsDebug.h:43
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Handles shared library creation and other class attributes.
Provides forward declarations of types and structs.
The G+Smo namespace, containing all definitions for the library.
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...