G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsApproxC1Edge.hpp
Go to the documentation of this file.
1
14#pragma once
15
17
19
20#include <gsUnstructuredSplines/src/gsApproxC1GluingData.h>
21
22namespace 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);
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
Definition gsExpressions.h:973
A univariate B-spline basis.
Definition gsBSplineBasis.h:700
A B-spline function of one argument, with arbitrary target dimension.
Definition gsBSpline.h:51
Maintains a mapping from patch-local dofs to global dof indices and allows the elimination of individ...
Definition gsDofMapper.h:69
Definition gsExprAssembler.h:33
Generic evaluator of isogeometric expressions.
Definition gsExprEvaluator.h:39
Abstract base class representing a geometry map.
Definition gsGeometry.h:93
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
Holds a set of patch-wise bases and their topology information.
Definition gsMultiBasis.h:37
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition gsMultiPatch.h:100
index_t addPatch(typename gsGeometry< T >::uPtr g)
Add a patch from a gsGeometry<T>::uPtr.
Definition gsMultiPatch.hpp:211
index_t size() const
Returns the number of elements in the basis.
Definition gsBSplineBasis.h:165
A tensor product B-spline basis.
Definition gsTensorBSplineBasis.h:37
Creates the (approx) C1 Edge space.
#define index_t
Definition gsConfig.h:32
Reparametrize one Patch.
The G+Smo namespace, containing all definitions for the library.
S give(S &x)
Definition gsMemory.h:266