G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
20 namespace gismo
21 {
22 
23 #define MAPPER_PATCH_DOF(a,b,c) m_dofs[c][m_offset[b]+a]
24 
68 class GISMO_EXPORT gsDofMapper
69 {
70 public:
71 
73  gsDofMapper();
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 
172 private:
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 
182 public:
183 
185  gsVector<index_t> asVector(index_t comp = 0) const;
186 
191  gsVector<index_t> inverseAsVector(index_t comp = 0) const;
192 
195  void setMatchingInterfaces(const gsBoxTopology & mp);
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 
539 private:
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
554 private:
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 
596 inline 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
index_t boundarySize() const
Returns the number of eliminated dofs.
Definition: gsDofMapper.h:457
index_t size(index_t comp) const
Returns the total number of dofs (free and eliminated).
Definition: gsDofMapper.h:428
size_t mapSize() const
Returns the total number of patch-local degrees of freedom that are being mapped. ...
Definition: gsDofMapper.h:473
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 &lt;j&gt; in the set ; by def...
size_t offset(int k) const
Returns the offset corresponding to patch k.
Definition: gsDofMapper.h:466
std::vector< size_t > m_offset
Offsets.
Definition: gsDofMapper.h:571
std::vector< index_t > m_numCpldDofs
Offsets of coupled dofs, nComp+1.
Definition: gsDofMapper.h:584
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
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
Provides structs and classes related to interfaces and boundaries.
std::vector< index_t > m_tagged
Stores the tagged indices.
Definition: gsDofMapper.h:591
bool is_tagged_index(index_t gl) const
Returns true if gl is a tagged dof.
Definition: gsDofMapper.h:411
bool is_coupled_index(index_t gl) const
Returns true if gl is a coupled dof.
Definition: gsDofMapper.h:398
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
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 lastIndex() const
Returns one past the biggest value of the free indices.
Definition: gsDofMapper.h:265
index_t m_shift
Shifting of the global index (zero by default)
Definition: gsDofMapper.h:574
#define index_t
Definition: gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
Maintains a mapping from patch-local dofs to global dof indices and allows the elimination of individ...
Definition: gsDofMapper.h:68
Handles shared library creation and other class attributes.
index_t cindex(index_t i, index_t k=0, index_t c=0) const
Returns the coupled dof index.
Definition: gsDofMapper.h:347
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
index_t global_to_bindex(index_t gl) const
Returns the boundary index of global dof gl.
Definition: gsDofMapper.h:364
bool is_free_index(index_t gl) const
Returns true if global dof gl is not eliminated.
Definition: gsDofMapper.h:376
const std::vector< index_t > & getTagged() const
Returns the vector of tagged (not eliminated) dofs.
Definition: gsDofMapper.h:448
bool is_boundary_index(index_t gl) const
Returns true if global dof gl is eliminated.
Definition: gsDofMapper.h:386
Holds a set of patch-wise bases and their topology information.
Definition: gsMultiBasis.h:36
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
index_t tindex(index_t i, index_t k=0, index_t c=0) const
Returns the tagged dof index.
Definition: gsDofMapper.h:355
bool allFree() const
Returns true iff all DoFs are considered as free.
Definition: gsDofMapper.h:343
#define gsInfo
Definition: gsDebug.h:43
Provides forward declarations of types and structs.
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
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 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
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
size_t numPatches() const
Returns the number of patches present underneath the mapper.
Definition: gsDofMapper.h:469
index_t m_bshift
Shifting of the boundary index (zero by default)
Definition: gsDofMapper.h:577
Class containing a set of boundary conditions.
Definition: gsBoundaryConditions.h:341
index_t size() const
Returns the total number of dofs (free and eliminated).
Definition: gsDofMapper.h:421
std::vector< index_t > m_numFreeDofs
Offsets of free dofs, nComp+1.
Definition: gsDofMapper.h:580
std::vector< index_t > m_numElimDofs
Offsets of eliminated dofs, nComp+1.
Definition: gsDofMapper.h:582
index_t numComponents() const
Returns the number of components present in the mapper.
Definition: gsDofMapper.h:417
bool isFinalized() const
Checks whether finalize() has been called.
Definition: gsDofMapper.h:236
index_t freeSize() const
Returns the number of free (not eliminated) dofs.
Definition: gsDofMapper.h:436
std::ostream & print(std::ostream &os=gsInfo) const
Print summary.
Definition: gsDofMapper.cpp:346
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
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 isPermutation() const
Returns true iff the mapper is a permuatation.
Definition: gsDofMapper.h:239
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 firstIndex(index_t comp=0) const
Returns the smallest value of the indices for comp.
Definition: gsDofMapper.h:261
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
A basis represents a family of scalar basis functions defined over a common parameter domain...
Definition: gsBasis.h:78