G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsApproxC1GluingData.h
1 
14 #pragma once
15 
17 
18 namespace gismo
19 {
20 
21 template<short_t d, class T>
22 class gsApproxC1GluingData
23 {
24 private:
25  typedef typename std::vector<gsPatchReparameterized<d,T>> C1AuxPatchContainer;
26 
28  typedef memory::shared_ptr<gsApproxC1GluingData> Ptr;
29 
31  typedef memory::unique_ptr<gsApproxC1GluingData> uPtr;
32 
33 public:
34  gsApproxC1GluingData()
35  { }
36 
37 
38  gsApproxC1GluingData(C1AuxPatchContainer const & auxPatchContainer,
39  gsOptionList const & optionList,
40  std::vector<patchSide> sidesContainer,
41  std::vector<bool> isInterface = std::vector<bool>{},
42  gsTensorBSplineBasis<d, T> basis = gsTensorBSplineBasis<d, T>())
43  : m_auxPatches(auxPatchContainer), m_optionList(optionList)
44  {
45  alphaSContainer.resize(2);
46  betaSContainer.resize(2);
47  if (m_auxPatches.size() == 2) // Interface
48  {
49  setGlobalGluingData(1,0); // u
50  setGlobalGluingData(0,1); // v
51  }
52  else if (m_auxPatches.size() == 1 && sidesContainer.size() == 2) // Vertex
53  {
54  for (size_t dir = 0; dir < sidesContainer.size(); dir++)
55  {
56  // Map global side to local side
57  index_t localSide = auxPatchContainer[0].getMapIndex(sidesContainer[dir].index());
58  //gsInfo << "Global: " << sidesContainer[dir] << " : " << localSide << "\n";
59  index_t localDir = localSide < 3 ? 1 : 0;
60 
61  createGluingDataSpace(m_auxPatches[0].getPatchRotated(), basis,
62  localDir, bsp_gD, m_optionList.getInt("gluingDataDegree"), m_optionList.getInt("gluingDataSmoothness"));
63 
64  if(isInterface[dir]) // West
65  {
66  setGlobalGluingData(0, localDir);
67  }
68 
69  else
70  {
71  // empty
72  }
73  }
74  }
75  //else
76  // gsInfo << "I am here \n";
77 
78  }
79 
80  // Computed the gluing data globally
81  void setGlobalGluingData(index_t patchID = 0, index_t dir = 1);
82 
83  gsBSpline<T> & alphaS(index_t patchID) { return alphaSContainer[patchID]; }
84  gsBSpline<T> & betaS(index_t patchID) { return betaSContainer[patchID]; }
85 
86 protected:
87 
88  // Spline space for the gluing data + multiPatch
89  C1AuxPatchContainer m_auxPatches;
90 
91  gsBSplineBasis<T> bsp_gD;
92 
93  const gsOptionList m_optionList;
94 
95  // Result
96  std::vector<gsBSpline<T>> alphaSContainer, betaSContainer;
97 
98 }; // class gsGluingData
99 
100 
101 template<short_t d, class T>
102 void gsApproxC1GluingData<d, T>::setGlobalGluingData(index_t patchID, index_t dir)
103 {
104  // Interpolate boundary yes or no //
105  bool interpolate_boundary = false;
106  // Interpolate boundary yes or no //
107 
108  gsTensorBSplineBasis<d, T> basis = dynamic_cast<const gsTensorBSplineBasis<d, T> &>(m_auxPatches[patchID].getBasisRotated().piece(0));;
109  if (m_auxPatches.size() == 2) // Interface
110  {
111  gsTensorBSplineBasis<d, T> basis2 = dynamic_cast<const gsTensorBSplineBasis<d, T> &>(m_auxPatches[1-patchID].getBasisRotated().piece(0));
112  if (basis.component(dir).numElements() > basis2.component(1-dir).numElements())
113  basis.component(dir) = basis2.component(1-dir);
114 
115  // ======== Space for gluing data : S^(p_tilde, r_tilde) _k ========
116  createGluingDataSpace(m_auxPatches[patchID].getPatchRotated(), basis,
117  dir, bsp_gD, m_optionList.getInt("gluingDataDegree"), m_optionList.getInt("gluingDataSmoothness"));
118  }
119 
120 
121 
123  typename gsSparseSolver<T>::SimplicialLDLT solver;
124  gsExprAssembler<T> A(1,1);
125 
126  // Elements used for numerical integration
127  gsMultiBasis<T> BsplineSpace(bsp_gD);
128  A.setIntegrationElements(BsplineSpace);
129  gsExprEvaluator<T> ev(A);
130 
131  gsAlpha<T> alpha(m_auxPatches[patchID].getPatchRotated(), dir);
132  auto aa = A.getCoeff(alpha);
133 
134  // Set the discretization space
135  auto u = A.getSpace(BsplineSpace);
136 
137  // Create Mapper
138  gsDofMapper map(BsplineSpace);
139  gsMatrix<index_t> act(2,1);
140  act(0,0) = 0;
141  act(1,0) = BsplineSpace[0].size()-1; // First and last
142  if (interpolate_boundary)
143  map.markBoundary(0, act); // Patch 0
144  map.finalize();
145 
146  u.setupMapper(map);
147 
148  gsMatrix<T> & fixedDofs = const_cast<expr::gsFeSpace<T>&>(u).fixedPart();
149  fixedDofs.setZero( u.mapper().boundarySize(), 1 );
150 
151  // For the boundary
152  gsMatrix<T> points_bdy(1,2);
153  points_bdy << 0.0, 1.0;
154  if (interpolate_boundary)
155  fixedDofs = alpha.eval(points_bdy).transpose();
156 
157  A.initSystem();
158  A.assemble(u * u.tr(), u * aa);
159 
160  solver.compute( A.matrix() );
161  gsMatrix<T> solVector = solver.solve(A.rhs());
162 
163  auto u_sol = A.getSolution(u, solVector);
164  gsMatrix<T> sol;
165  u_sol.extract(sol);
166 
167  typename gsGeometry<T>::uPtr tilde_temp;
168  tilde_temp = bsp_gD.makeGeometry(sol);
169  alphaSContainer[dir] = dynamic_cast<gsBSpline<T> &> (*tilde_temp);
170 
171  gsBeta<T> beta(m_auxPatches[patchID].getPatchRotated(), dir);
172  auto bb = A.getCoeff(beta);
173 
174  // For the boundary
175  if (interpolate_boundary)
176  fixedDofs = beta.eval(points_bdy).transpose();
177 
178  A.initSystem();
179  A.assemble(u * u.tr(), u * bb);
180 
181  solver.compute( A.matrix() );
182  solVector = solver.solve(A.rhs());
183 
184  auto u_sol2 = A.getSolution(u, solVector);
185  u_sol2.extract(sol);
186 
187  tilde_temp = bsp_gD.makeGeometry(sol);
188  betaSContainer[dir] = dynamic_cast<gsBSpline<T> &> (*tilde_temp);
189 
190 } // setGlobalGluingData
191 
192 
193 } // namespace gismo
Provides declaration of Basis abstract interface.
#define index_t
Definition: gsConfig.h:32