G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsApproxC1GluingData.h
1
14#pragma once
15
17
18namespace gismo
19{
20
21template<short_t d, class T>
22class gsApproxC1GluingData
23{
24private:
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
33public:
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
86protected:
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
101template<short_t d, class T>
102void 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
memory::unique_ptr< gsGeometry > uPtr
Unique pointer for gsGeometry.
Definition gsGeometry.h:100
Provides declaration of Basis abstract interface.
#define index_t
Definition gsConfig.h:32
The G+Smo namespace, containing all definitions for the library.