G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsC1SurfBasisVertex.h
1 
14 #pragma once
15 
16 
17 #include <gsUnstructuredSplines/src/gsC1SurfGluingData.h>
18 #include <gsUnstructuredSplines/src/gsC1SurfVisitorBasisVertex.h>
19 
20 
21 
22 namespace gismo
23 {
24  template<class T, class bhVisitor = gsG1ASVisitorBasisVertex<T>>
25  class gsC1SurfBasisVertex : public gsAssembler<T>
26  {
27  public:
28  typedef gsAssembler<T> Base;
29 
30  public:
31  gsC1SurfBasisVertex(gsMultiPatch<T> mp, // Single Patch
32  gsMultiBasis<T> basis, // Single Basis
33  std::vector<bool> isBoundary,
34  gsMatrix<T> &Phi,
35  gsMatrix<T> gluingD)
36  : m_mp(mp), m_basis(basis), m_isBoundary(isBoundary), m_Phi(Phi), m_gD(gluingD)
37  {
38 
39  for (index_t dir = 0; dir < m_mp.parDim(); dir++) // For the TWO directions
40  {
41  // Computing the G1 - basis function at the edge
42  // Spaces for computing the g1 basis
43  gsBSplineBasis<T> basis_edge = dynamic_cast<gsBSplineBasis<T> &>(m_basis.basis(0).component(dir)); // 0 -> u, 1 -> v
44 
45  gsBSplineBasis<T> basis_plus(basis_edge);
46  basis_plus.elevateContinuity(1);
47  m_basis_plus.push_back(basis_plus);
48 
49  gsBSplineBasis<T> basis_minus(basis_edge);
50  basis_minus.degreeReduce(1);
51  m_basis_minus.push_back(basis_minus);
52  }
53 
54  // Basis for the G1 basis
55  m_basis_g1 = m_basis.basis(0);
56 
57 
58  }
59 
60 
61  void refresh();
62  void assemble();
63  inline void apply(bhVisitor & visitor, index_t patchIndex);
64  void solve();
65 
66  void constructSolution(gsMultiPatch<T> & result);
67 
68  void setG1BasisVertex(gsMultiPatch<T> & result)
69  {
70  m_geo = m_basis_g1;
71  refresh();
72  assemble();
73  solve();
74 
75  constructSolution(result);
76  }
77 
78 
79  private:
80  // Avoid hidden overloads w.r.t. gsAssembler
81  void constructSolution(const gsMatrix<T>& solVector,
82  gsMultiPatch<T>& result, short_t unk) const
84 
85  void constructSolution(const gsMatrix<T>& solVector,
86  gsMultiPatch<T>& result,
87  const gsVector<index_t> & unknowns) const
89 
90  protected:
91 
92  // Input
93  gsMultiPatch<T> m_mp;
94  gsMultiBasis<T> m_basis;
95  std::vector<bool> m_isBoundary;
96  gsMatrix<T> m_Phi;
97 
98  // Gluing data
99  gsMatrix<T> m_gD;
100 
101  // Basis for getting the G1 Basis
102  std::vector<gsBSplineBasis<T>> m_basis_plus;
103  std::vector<gsBSplineBasis<T>> m_basis_minus;
104 
105  // Basis for the G1 Basis
106  gsMultiBasis<T> m_basis_g1;
107 
108  // Basis for Integration
109  gsMultiBasis<T> m_geo;
110 
111  // System
112  std::vector<gsSparseSystem<T> > m_f;
113 
114  // For Dirichlet boundary
115  using Base::m_ddof;
116 
117  std::vector<gsMatrix<T>> solVec;
118 
119  }; // class gsG1BasisEdge
120 
121 
122  template <class T, class bhVisitor>
123  void gsC1SurfBasisVertex<T,bhVisitor>::constructSolution(gsMultiPatch<T> & result)
124  {
125 
126  result.clear();
127 
128  // Dim is the same for all basis functions
129  const index_t dim = ( 0!=solVec.at(0).cols() ? solVec.at(0).cols() : m_ddof[0].cols() );
130 
131  gsMatrix<T> coeffs;
132  for (index_t p = 0; p < 6; ++p)
133  {
134  const gsDofMapper & mapper = m_f.at(p).colMapper(0); // unknown = 0
135 
136  // Reconstruct solution coefficients on patch p
137  index_t sz;
138  sz = m_basis.basis(0).size();
139 
140  coeffs.resize(sz, dim);
141 
142  for (index_t i = 0; i < sz; ++i)
143  {
144  if (mapper.is_free(i, 0)) // DoF value is in the solVector // 0 = unitPatch
145  {
146  coeffs.row(i) = solVec.at(p).row(mapper.index(i, 0));
147  }
148  else // eliminated DoF: fill with Dirichlet data
149  {
150  //gsInfo << "mapper index dirichlet: " << m_ddof[unk].row( mapper.bindex(i, p) ).head(dim) << "\n";
151  coeffs.row(i) = m_ddof[0].row( mapper.bindex(i, 0) ).head(dim); // = 0
152  }
153  }
154  result.addPatch(m_basis_g1.basis(0).makeGeometry(give(coeffs)));
155  }
156  }
157 
158  template <class T, class bhVisitor>
159  void gsC1SurfBasisVertex<T,bhVisitor>::refresh()
160  {
161  // 1. Obtain a map from basis functions to matrix columns and rows
162  gsDofMapper map(m_basis.basis(0));
163 
164  // SET THE DOFS
165 
166  map.finalize();
167 
168 
169  // 2. Create the sparse system
170  gsSparseSystem<T> m_system = gsSparseSystem<T>(map);
171  for (index_t i = 0; i < 6; i++)
172  m_f.push_back(m_system);
173 
174  } // refresh()
175 
176  template <class T, class bhVisitor>
177  void gsC1SurfBasisVertex<T,bhVisitor>::assemble()
178  {
179  // Reserve sparse system
180  const index_t nz = gsAssemblerOptions::numColNz(m_basis[0],2,1,0.333333);
181  for (size_t i = 0; i < m_f.size(); i++)
182  m_f.at(i).reserve(nz, 1);
183 
184 
185  if(m_ddof.size()==0)
186  m_ddof.resize(1); // 0,1
187 
188  const gsDofMapper & map = m_f.at(0).colMapper(0); // Map same for every
189 
190  m_ddof[0].setZero(map.boundarySize(), 1 ); // plus
191 
192  // Assemble volume integrals
193  bhVisitor visitor;
194  apply(visitor,0); // patch 0
195 
196  for (size_t i = 0; i < m_f.size(); i++)
197  m_f.at(i).matrix().makeCompressed();
198 
199  } // assemble()
200 
201  template <class T, class bhVisitor>
202  void gsC1SurfBasisVertex<T,bhVisitor>::apply(bhVisitor & visitor, index_t patchIndex)
203  {
204 #pragma omp parallel
205  {
206 
207  gsQuadRule<T> quRule ; // Quadrature rule
208  gsMatrix<T> quNodes ; // Temp variable for mapped nodes
209  gsVector<T> quWeights; // Temp variable for mapped weights
210 
211  bhVisitor
212 #ifdef _OPENMP
213  // Create thread-private visitor
214  visitor_(visitor);
215  const int tid = omp_get_thread_num();
216  const int nt = omp_get_num_threads();
217 #else
218  &visitor_ = visitor;
219 #endif
220 
221  gsBasis<T> & basis_g1 = m_basis_g1.basis(0); // basis for construction
222 
223  // Same for all patches
224  gsBasis<T> & basis_geo = m_basis.basis(0); // 2D
225 
226  // Initialize reference quadrature rule and visitor data
227  visitor_.initialize(basis_g1, quRule);
228 
229  const gsGeometry<T> & patch = m_mp.patch(0);
230 
231  // Initialize domain element iterator
232  typename gsBasis<T>::domainIter domIt = m_geo.basis(0).makeDomainIterator(boundary::none);
233 
234 #ifdef _OPENMP
235  for ( domIt->next(tid); domIt->good(); domIt->next(nt) )
236 #else
237  for (; domIt->good(); domIt->next() )
238 #endif
239  {
240  // Map the Quadrature rule to the element
241  quRule.mapTo( domIt->lowerCorner(), domIt->upperCorner(), quNodes, quWeights );
242 #pragma omp critical(evaluate)
243  // Perform required evaluations on the quadrature nodes
244  visitor_.evaluate(basis_g1, basis_geo, m_basis_plus, m_basis_minus, patch, quNodes, m_gD, m_isBoundary, m_Phi);
245 
246  // Assemble on element
247  visitor_.assemble(*domIt, quWeights);
248 
249  // Push to global matrix and right-hand side vector
250 #pragma omp critical(localToGlobal)
251  visitor_.localToGlobal(patchIndex, m_ddof, m_f); // omp_locks inside // patchIndex == 0
252  }
253  }//omp parallel
254  } // apply
255 
256  template <class T, class bhVisitor>
257  void gsC1SurfBasisVertex<T,bhVisitor>::solve()
258  {
259  typename gsSparseSolver<T>::SimplicialLDLT solver;
260 // typename gsSparseSolver<T>::LU solver;
261 
262 
263 // gsInfo << "rhs: " << m_f.at(4).rhs() << "\n";
264 
265  for (index_t i = 0; i < 6; i++) // Tilde
266  {
267  solver.compute(m_f.at(i).matrix());
268  solVec.push_back(solver.solve(m_f.at(i).rhs()));
269  }
270  } // solve
271 
272 } // namespace gismo
index_t addPatch(typename gsGeometry< T >::uPtr g)
Add a patch from a gsGeometry&lt;T&gt;::uPtr.
Definition: gsMultiPatch.hpp:210
Abstract base class representing a geometry map.
Definition: gsGeometry.h:92
Class representing a reference quadrature rule.
Definition: gsQuadRule.h:28
void clear()
Clear (delete) all patches.
Definition: gsMultiPatch.h:319
index_t boundarySize() const
Returns the number of eliminated dofs.
Definition: gsDofMapper.h:457
#define GISMO_NO_IMPLEMENTATION
Definition: gsDebug.h:129
#define short_t
Definition: gsConfig.h:35
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
S give(S &x)
Definition: gsMemory.h:266
#define index_t
Definition: gsConfig.h:32
Maintains a mapping from patch-local dofs to global dof indices and allows the elimination of individ...
Definition: gsDofMapper.h:68
A univariate B-spline basis.
Definition: gsBSplineBasis.h:694
void finalize()
Must be called after all boundaries and interfaces have been marked to set up the dof numbering...
Definition: gsDofMapper.cpp:240
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
T at(index_t i) const
Returns the i-th element of the vectorization of the matrix.
Definition: gsMatrix.h:211
Holds a set of patch-wise bases and their topology information.
Definition: gsMultiBasis.h:36
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
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition: gsMultiPatch.h:33
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
virtual void mapTo(const gsVector< T > &lower, const gsVector< T > &upper, gsMatrix< T > &nodes, gsVector< T > &weights) const
Maps quadrature rule (i.e., points and weights) from the reference domain to an element.
Definition: gsQuadRule.h:177
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
The assembler class provides generic routines for volume and boundary integrals that are used for for...
Definition: gsAssembler.h:265
A basis represents a family of scalar basis functions defined over a common parameter domain...
Definition: gsBasis.h:78
void apply(ElementVisitor &visitor, size_t patchIndex=0, boxSide side=boundary::none)
Generic assembly routine for volume or boundary integrals.
Definition: gsAssembler.h:668