G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsApproxC1Edge.hpp
Go to the documentation of this file.
1 
14 #pragma once
15 
17 
19 
20 #include <gsUnstructuredSplines/src/gsApproxC1GluingData.h>
21 
22 namespace gismo
23 {
24  template<short_t d,class T>
25  void gsApproxC1Edge<d,T>::compute(std::vector<patchSide> & sidesContainer) {
26 
27  // Compute GLuing data
28  gsApproxC1GluingData<d, T> approxGluingData(m_auxPatches, m_optionList, sidesContainer);
29 
31  index_t dir_pm, patch;
32  if (sidesContainer.size() == 2) {
33  if (m_auxPatches[0].getBasisRotated().piece(0).component(1).numElements() >
34  m_auxPatches[1].getBasisRotated().piece(0).component(0).numElements()) {
35  basis = dynamic_cast<const gsTensorBSplineBasis<d, T> &>(m_auxPatches[1].getBasisRotated().piece(0));
36  dir_pm = 0;
37  patch = 1;
38  } else {
39  basis = dynamic_cast<const gsTensorBSplineBasis<d, T> &>(m_auxPatches[0].getBasisRotated().piece(0));
40  dir_pm = 1;
41  patch = 0;
42  }
43  }
44  else
45  {
46  basis = dynamic_cast<const gsTensorBSplineBasis<d, T> &>(m_auxPatches[0].getBasisRotated().piece(0));
47  dir_pm = 1;
48  patch = 0;
49  }
50 
52  basisEdgeResult.clear();
53  for (size_t patchID = 0; patchID < sidesContainer.size(); patchID++)
54  {
55  gsMultiPatch<T> result;
56 
57  index_t dir = patchID == 0 ? 1 : 0;
58 
59  gsBSplineBasis<T> basis_plus, basis_minus;
60 
61  gsMultiBasis<T> initSpace(m_auxPatches[patchID].getBasisRotated().piece(0));
62  createPlusSpace(m_auxPatches[patch].getPatchRotated(), basis, dir_pm, basis_plus);
63  createMinusSpace(m_auxPatches[patch].getPatchRotated(), basis, dir_pm, basis_minus);
64 
65  gsGeometry<T> &geo = m_auxPatches[patchID].getPatchRotated();
66 
67  gsBSpline<T> beta, alpha;
68  bool bdy = true;
69  if (sidesContainer.size() == 2)
70  {
71  bdy = false;
72  beta = approxGluingData.betaS(dir);
73  alpha = approxGluingData.alphaS(dir);
74  }
75 
76  // [!The same setup for each bf!]
77  typename gsSparseSolver<T>::SimplicialLDLT solver;
78  gsExprAssembler<T> A(1, 1);
79 
80  // Elements used for numerical integration
81  gsMultiBasis<T> edgeSpace(
82  m_auxPatches[patchID].getBasisRotated().piece(sidesContainer[patchID]));
83 
84  A.setIntegrationElements(edgeSpace);
85  gsExprEvaluator<T> ev(A);
86 
87  // Set the discretization space
88  auto u = A.getSpace(edgeSpace);
89 
90  // Create Mapper
91  gsDofMapper map(edgeSpace);
92  if (!m_optionList.getSwitch("interpolation"))
93  {
95  for (index_t i = 2; i < edgeSpace[0].component(1 - dir).size();
96  i++) // only the first two u/v-columns are Dofs (0/1)
97  {
98  act = edgeSpace[0].boundaryOffset(dir == 0 ? 3 : 1, i); // WEST
99  map.markBoundary(0, act); // Patch 0
100  }
101  map.finalize();
102 
103  u.setupMapper(map);
104 
105  gsMatrix<T> &fixedDofs = const_cast<expr::gsFeSpace<T> &>(u).fixedPart();
106  fixedDofs.setZero(u.mapper().boundarySize(), 1);
107 
108  A.initSystem();
109  A.assemble(u * u.tr()); // The Matrix is the same for each bf
110  solver.compute(A.matrix());
111  // [!The same setup for each bf!]
112  }
113 
114  index_t n_plus = basis_plus.size();
115  index_t n_minus = basis_minus.size();
116 
117  index_t bfID_init = 3;
118  for (index_t bfID = bfID_init; bfID < n_plus - bfID_init; bfID++) // first 3 and last 3 bf are eliminated
119  {
120  gsTraceBasis<T> traceBasis(geo, beta, basis_plus, initSpace.basis(0), bdy, bfID, dir);
121 
122  if (m_optionList.getSwitch("interpolation"))
123  {
124  //gsQuasiInterpolate<T>::Schoenberg(edgeSpace.basis(0), traceBasis, sol);
125  //result.addPatch(edgeSpace.basis(0).interpolateAtAnchors(give(values)));
126  gsMatrix<T> anchors = edgeSpace.basis(0).anchors();
127  gsMatrix<T> values = traceBasis.eval(anchors);
128  result.addPatch(edgeSpace.basis(0).interpolateAtAnchors(give(values)));
129  }
130  else
131  {
132  A.initVector(); // Just the rhs
133 
134  auto aa = A.getCoeff(traceBasis);
135 
136  A.assemble(u * aa);
137 
138  gsMatrix<T> solVector = solver.solve(A.rhs());
139 
140  auto u_sol = A.getSolution(u, solVector);
141  gsMatrix<T> sol;
142  u_sol.extract(sol);
143 
144  result.addPatch(edgeSpace.basis(0).makeGeometry(give(sol)));
145  }
146  }
147 
148  bfID_init = 2;
149  for (index_t bfID = bfID_init; bfID < n_minus - bfID_init; bfID++) // first 2 and last 2 bf are eliminated
150  {
151  gsNormalDerivBasis<T> normalDerivBasis(geo, alpha, basis_minus, initSpace.basis(0), bdy, bfID,
152  dir);
153  if (m_optionList.getSwitch("interpolation"))
154  {
155  //gsQuasiInterpolate<T>::Schoenberg(edgeSpace.basis(0), traceBasis, sol);
156  //result.addPatch(edgeSpace.basis(0).interpolateAtAnchors(give(values)));
157  gsMatrix<T> anchors = edgeSpace.basis(0).anchors();
158  gsMatrix<T> values = normalDerivBasis.eval(anchors);
159  result.addPatch(edgeSpace.basis(0).interpolateAtAnchors(give(values)));
160  }
161  else
162  {
163  A.initVector(); // Just the rhs
164 
165  auto aa = A.getCoeff(normalDerivBasis);
166 
167  A.assemble(u * aa);
168 
169  gsMatrix<T> solVector = solver.solve(A.rhs());
170 
171  auto u_sol = A.getSolution(u, solVector);
172  gsMatrix<T> sol;
173  u_sol.extract(sol);
174 
175  result.addPatch(edgeSpace.basis(0).makeGeometry(give(sol)));
176  }
177  }
178 
179  // parametrizeBasisBack
180  m_auxPatches[patchID].parametrizeBasisBack(result);
181 
182  basisEdgeResult.push_back(result);
183  }
184  }
185 
186 
187  template<short_t d,class T>
188  void gsApproxC1Edge<d,T>::computeAuxTopology()
189  {
190  for(size_t i = 0; i < m_auxPatches.size(); i++)
191  {
192  if(m_auxPatches[i].getPatchRotated().orientation() == -1)
193  m_auxPatches[i].swapAxis();
194  }
195  }
196 
197 
198  template<short_t d,class T>
199  void gsApproxC1Edge<d,T>::reparametrizeInterfacePatches(std::vector<patchSide> & sidesContainer)
200  {
201  computeAuxTopology();
202 
203 // gsMultiPatch<T> temp_mp;
204 // for(index_t i = 0; i < m_auxPatches.size(); i++)
205 // temp_mp.addPatch(m_auxPatches[i].getPatchRotated());
206 //
207 // temp_mp.computeTopology();
208 
209  // Right patch along the interface. Patch 0 -> v coordinate. Edge west along interface
210  switch (sidesContainer[0].side().index())
211  {
212  case 1:
213  break;
214  case 4: m_auxPatches[0].rotateParamClock();
215  break;
216  case 3: m_auxPatches[0].rotateParamAntiClock();
217  break;
218  case 2: m_auxPatches[0].rotateParamAntiClockTwice();
219  break;
220  default:
221  break;
222  }
223 
224  // Left patch along the interface. Patch 1 -> u coordinate. Edge south along interface
225  switch (sidesContainer[1].side().index())
226  {
227  case 3:
228  break;
229  case 4: m_auxPatches[1].rotateParamAntiClockTwice();
230  break;
231  case 2: m_auxPatches[1].rotateParamAntiClock();
232  break;
233  case 1: m_auxPatches[1].rotateParamClock();
234  break;
235  default:
236  break;
237  }
238  } // reparametrizeInterfacePatches
239 
240 
241  template<short_t d,class T>
242  void gsApproxC1Edge<d,T>::reparametrizeSinglePatch(index_t side)
243  {
244  computeAuxTopology();
245 
246  if(m_auxPatches[0].getOrient())
247  {
248  switch (side)
249  {
250  case 3:
251  break;
252  case 2:
253  m_auxPatches[0].rotateParamClock();
254  break;
255  case 4:
256  m_auxPatches[0].rotateParamAntiClockTwice();
257  break;
258  case 1:
259  m_auxPatches[0].rotateParamAntiClock();
260  break;
261  }
262  }
263  else
264  {
265  switch (side)
266  {
267  case 1:
268  break;
269  case 4:
270  m_auxPatches[0].rotateParamClock();
271  break;
272  case 2:
273  m_auxPatches[0].rotateParamAntiClockTwice();
274  break;
275  case 3:
276  m_auxPatches[0].rotateParamAntiClock();
277  break;
278  }
279  }
280  } // reparametrizeSinglePatch
281 
282 } // namespace gismo
index_t size() const
size
Definition: gsBSplineBasis.h:165
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
Definition: gsExprAssembler.h:30
S give(S &x)
Definition: gsMemory.h:266
#define index_t
Definition: gsConfig.h:32
Reparametrize one Patch.
A tensor product B-spline basis.
Definition: gsTensorBSplineBasis.h:36
Maintains a mapping from patch-local dofs to global dof indices and allows the elimination of individ...
Definition: gsDofMapper.h:68
A B-spline function of one argument, with arbitrary target dimension.
Definition: gsBSpline.h:50
A univariate B-spline basis.
Definition: gsBSplineBasis.h:694
Holds a set of patch-wise bases and their topology information.
Definition: gsMultiBasis.h:36
Creates the (approx) C1 Edge space.
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
Definition: gsDirichletValues.h:23
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition: gsMultiPatch.h:33
Generic evaluator of isogeometric expressions.
Definition: gsExprEvaluator.h:38