G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsC1SurfGluingDataAssembler.h
1 
15 #pragma once
16 
18 
19 namespace gismo
20 {
21 
22 template <class T, class bhVisitor = gsC1SurfGluingDataVisitor<T> >
23 class gsC1SurfGluingDataAssembler : public gsAssembler<T>
24 {
25 public:
26  typedef gsAssembler<T> Base;
27 
28 public:
29  gsC1SurfGluingDataAssembler(gsBasis<T> const & basis,
30  index_t const & uv,
31  gsMultiPatch<T> const & mp,
32  index_t const & gamma,
33  bool & isBoundary)
34  : m_uv(uv), m_mp(mp), m_gamma(gamma), m_isBoundary(isBoundary)
35  {
36 
37  m_basis.push_back(basis); // Basis for alpha and beta
38 
39  refresh();
40  }
41 
42  void refresh();
43  void refreshBeta();
44 
45  void assemble();
46  void assembleBeta();
47 
48 
49  inline void apply(bhVisitor & visitor,
50  index_t patchIndex = 0,
51  boxSide side = boundary::none);
52 
53  inline void applyBeta(bhVisitor & visitor,
54  index_t patchIndex = 0,
55  boxSide side = boundary::none);
56 
58  const gsSparseMatrix<T> & matrix_alpha() const { return m_system_alpha.matrix(); }
59  const gsMatrix<T> & rhs_alpha() const { return m_system_alpha.rhs(); }
60 
61  const gsSparseMatrix<T> & matrix_beta() const { return m_system_beta_S.matrix(); }
62  const gsMatrix<T> & rhs_beta() const { return m_system_beta_S.rhs(); }
63 
64 protected:
65  index_t m_uv;
66 
67  // interface + geometry for computing alpha and beta
68  gsMultiPatch<T> m_mp;
69 
70  index_t m_gamma;
71  bool m_isBoundary;
72 
73  // Space for phi_0,i, phi_1,j
74  std::vector< gsMultiBasis<T> > m_basis;
75 
76  //using Base::m_system;
77  using Base::m_ddof;
78 
79  gsSparseSystem<T> m_system_alpha;
80  gsSparseSystem<T> m_system_beta_S;
81 
82 }; // class gsG1BasisAssembler
83 
84 
85  template <class T, class bhVisitor>
86  void gsC1SurfGluingDataAssembler<T, bhVisitor>::refresh()
87  {
88  // 1. Obtain a map from basis functions to matrix columns and rows
89  gsDofMapper map_alpha(m_basis[0]);
90 
91  gsDofMapper map_beta_S(m_basis[0]);
92 
93  map_alpha.finalize();
94  map_beta_S.finalize();
95 
96  // 2. Create the sparse system
97  m_system_alpha = gsSparseSystem<T>(map_alpha);
98  m_system_beta_S = gsSparseSystem<T>(map_beta_S);
99  } // refresh()
100 
101 
102 
103  template <class T, class bhVisitor>
104  void gsC1SurfGluingDataAssembler<T, bhVisitor>::assemble()
105  {
106  //GISMO_ASSERT(m_system.initialized(), "Sparse system is not initialized, call refresh()");
107 
108  // Reserve sparse system
109  const index_t nz = gsAssemblerOptions::numColNz(m_basis[0][0],2,1,0.333333);
110  m_system_alpha.reserve(nz, 1);
111  m_system_beta_S.reserve(nz, 1);
112 
113  if(m_ddof.size()==0)
114  m_ddof.resize(2); // One for L, one for R, x2 for beta, alpha
115 
116  const gsDofMapper & mapper_alpha = m_system_alpha.colMapper(0);
117  const gsDofMapper & mapper_beta = m_system_beta_S.colMapper(0);
118 
119  m_ddof[0].setZero(mapper_alpha.boundarySize(), 1 ); // tilde
120  m_ddof[1].setZero(mapper_beta.boundarySize(), 1 ); // bar
121 
122  // Assemble volume integrals
123  bhVisitor visitor;
124  apply(visitor);
125 
126  m_system_alpha.matrix().makeCompressed();
127  m_system_beta_S.matrix().makeCompressed();
128 
129  }
130 
131  template <class T, class bhVisitor>
132  inline void gsC1SurfGluingDataAssembler<T, bhVisitor>::apply(bhVisitor & visitor,
133  index_t patchIndex,
134  boxSide side)
135  {
136  #pragma omp parallel
137  {
138  bhVisitor
139  #ifdef _OPENMP
140  // Create thread-private visitor
141  visitor_(visitor);
142  const int tid = omp_get_thread_num();
143  const int nt = omp_get_num_threads();
144  #else
145  &visitor_ = visitor;
146  #endif
147  gsQuadRule<T> quRule ; // Quadrature rule
148  gsMatrix<T> quNodes ; // Temp variable for mapped nodes
149  gsVector<T> quWeights; // Temp variable for mapped weights
150 
151  gsBasis<T> & basis = m_basis[0].basis(patchIndex); // = 0
152 
153  // Initialize reference quadrature rule and visitor data
154  visitor_.initialize(basis,quRule);
155 
156  //const gsGeometry<T> & patch = m_geo.patch(patchIndex); // 0 = patchindex
157 
158  // Initialize domain element iterator -- using unknown 0
159  typename gsBasis<T>::domainIter domIt = basis.makeDomainIterator(boundary::none);
160 
161  #ifdef _OPENMP
162  for ( domIt->next(tid); domIt->good(); domIt->next(nt) )
163  #else
164  for (; domIt->good(); domIt->next() )
165  #endif
166  {
167  // Map the Quadrature rule to the element
168  quRule.mapTo( domIt->lowerCorner(), domIt->upperCorner(), quNodes, quWeights );
169 
170  // Perform required evaluations on the quadrature nodes
171  visitor_.evaluate(basis, quNodes, m_uv, m_mp, m_gamma, m_isBoundary);
172 
173  // Assemble on element
174  visitor_.assemble(*domIt, quWeights);
175 
176  // Push to global matrix and right-hand side vector
177  #pragma omp critical(localToGlobal)
178  visitor_.localToGlobal(patchIndex, m_ddof, m_system_alpha, m_system_beta_S); // omp_locks inside
179  }
180  }//omp parallel
181  }
182 
183 } // namespace gismo
Visitor for the Gluing Data.
#define index_t
Definition: gsConfig.h:32
virtual void assemble(const gsMultiPatch< T > &curSolution)
Main non-linear assemble routine with input from current solution.
Definition: gsAssembler.hpp:55
std::vector< gsMatrix< T > > m_ddof
Definition: gsAssembler.h:295
void apply(ElementVisitor &visitor, size_t patchIndex=0, boxSide side=boundary::none)
Generic assembly routine for volume or boundary integrals.
Definition: gsAssembler.h:668