G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsC1SurfSpline.hpp
Go to the documentation of this file.
1
14#pragma once
17
18
19namespace gismo
20{
21 template<short_t d,class T>
22 void gsC1SurfSpline<d,T>::defaultOptions()
23 {
24 /*
25 to do: general
26 m_options.addInt("gluingDataDegree","Polynomial degree of the gluing data space", p-1 );
27 m_options.addInt("gluingDataSmoothness","Regularity of the gluing data space", p-2 );
28 m_options.addSwitch("info","Print debug information", false );
29 m_options.addSwitch("plot","Print debug information", false );
30 */
31 }
32
33 template<short_t d,class T>
34 void gsC1SurfSpline<d,T>::init()
35 {
36 // Check requirements
37 for (size_t p=0; p!=m_multiBasis.nBases(); p++)
38 {
39 gsTensorBSplineBasis<d, T> * basis_patch = dynamic_cast<gsTensorBSplineBasis<d, T> *>(&m_patches.basis(p));
40 index_t degree;
41 for (short_t dd = 0; dd!=d; dd++)
42 {
43 degree = basis_patch->component(dd).knots().degree();
44 GISMO_ENSURE((index_t)(basis_patch->component(dd).knots().size()-2*(degree+1))>=(index_t)(5-degree),"For a degree="<<degree<<" basis, the knot vector should at least have "<<5-degree<<" inner knots, but now it has "<<basis_patch->component(dd).knots().size()-2*(degree+1)<<" inner knots.");
45 }
46
47 // regularity check (r=p-2)
48 // check for AS??
49 }
50
51 // Fix orientation of each patch
52 m_patches.fixOrientation();
53
54 m_bases.clear();
55 m_bases.reserve(m_patches.nPatches()); // For each Patch
56 for (size_t np = 0; np < m_patches.nPatches(); np++)
57 {
58 // gsContainerBasisBase
59 gsContainerBasis<d,T> containerBasis(1); // for 9 subspaces and 4 helper Basis
60 m_bases.push_back(containerBasis);
61 }
62
63
64 // Create interior spline space
65 for (size_t np = 0; np < m_patches.nPatches(); np++)
66 {
67 gsTensorBSplineBasis<d, T> basis_patch = dynamic_cast<gsTensorBSplineBasis<d, T> &>(m_multiBasis.basis(np));
68 //gsInfo << "Basis Patch: " << basis_patch.component(0).knots().asMatrix() << "\n";
69 m_bases[np].setBasis(0, basis_patch); // Inner
70 }
71
72 index_t row_dofs = 0;
73 // Inner basis
74 for (size_t np = 0; np < m_patches.nPatches(); np++)
75 {
76 index_t dim_u = m_bases[np].piece(0).component(0).size();
77 index_t dim_v = m_bases[np].piece(0).component(1).size();
78 row_dofs += (dim_u - 4) * (dim_v - 4);
79 }
80
81 // Interfaces
82 for (size_t numInt = 0; numInt < m_patches.interfaces().size(); numInt++)
83 {
84 index_t dir = m_patches.interfaces()[numInt].first().m_index < 3 ? 1 : 0;
85 gsBSplineBasis<T> basis_edge = dynamic_cast<gsBSplineBasis<T> &>(m_multiBasis.basis(m_patches.interfaces()[numInt].first().patch).component(dir)); // If the interface matches!!!
86
87 gsBSplineBasis<T> basis_plus(basis_edge);
88 basis_plus.elevateContinuity(1);
89
90 gsBSplineBasis<T> basis_minus(basis_edge);
91 basis_minus.degreeReduce(1);
92
93 index_t numDofs = basis_plus.size() + basis_minus.size() - 10;
94 row_dofs += numDofs;
95 }
96
97 // Boundary Edges
98 for (size_t numBdy = 0; numBdy < m_patches.boundaries().size(); numBdy++)
99 {
100 const patchSide &bit = m_patches.boundaries()[numBdy];
101
102 index_t patch_1 = bit.patch;
103 index_t side_1 = bit.side().index();
104
105 index_t dir = side_1 < 3 ? 1 : 0;
106 gsBSplineBasis<T> basis_edge = dynamic_cast<gsBSplineBasis<T> &>(m_multiBasis.basis(patch_1).component(dir)); // If the interface matches!!!
107
108 gsBSplineBasis<T> basis_plus(basis_edge);
109 basis_plus.elevateContinuity(1);
110
111 gsBSplineBasis<T> basis_minus(basis_edge);
112 basis_minus.degreeReduce(1);
113
114 index_t numDofs = basis_plus.size() + basis_minus.size() - 10;
115 row_dofs += numDofs;
116 }
117
118 // Vertices
119 for (size_t numVer = 0; numVer < m_patches.vertices().size(); numVer++)
120 {
121 row_dofs += 6;
122 }
123
124
125 m_matrix.clear();
126 index_t dim_col = 0;
127 for (size_t i = 0; i < m_bases.size(); i++)
128 {
129 dim_col += m_bases[i].size();
130 }
131
132 m_matrix.resize(row_dofs, dim_col);
133 const index_t nz = 7*row_dofs; // TODO
134 m_matrix.reserve(nz);
135
136// gsInfo << m_multiBasis << "\n";
137// for (index_t np = 0; np < m_patches.nPatches(); np++)
138// gsInfo << "Basis " << np << " Size: " << m_multiBasis.basis(np).size() << "\n";
139// gsInfo << "Mat dim: (" << row_dofs << " : " << dim_col << ")\n";
140 }
141
142
143 template<short_t d,class T>
144 void gsC1SurfSpline<d,T>::compute()
145 {
146 std::vector<gsEigen::Triplet<T,index_t>> tripletList;
147 // Compute Inner Basis functions
148 index_t shift_row = 0, shift_col = 0;
149 for(size_t np = 0; np < m_patches.nPatches(); ++np)
150 {
151 index_t dim_u = m_bases[np].piece(0).component(0).size();
152 index_t dim_v = m_bases[np].piece(0).component(1).size();
153
154 index_t row_i = 0;
155 for (index_t j = 2; j < dim_v-2; ++j)
156 for (index_t i = 2; i < dim_u-2; ++i)
157 {
158 tripletList.push_back(gsEigen::Triplet<T,index_t>(shift_row + row_i, shift_col + j*dim_u+i,1));
159 ++row_i;
160 }
161 shift_row += row_i;
162 shift_col += m_bases[np].size();
163 }
164
165 // Interfaces
166 for (size_t numInt = 0; numInt < m_patches.interfaces().size(); numInt++)
167 {
168 gsC1SurfEdge<d,T> smoothC1Edge(m_patches,m_patches.interfaces()[numInt]);
169 smoothC1Edge.computeG1InterfaceBasis();
170 std::vector<gsMultiPatch<T>> basisEdge = smoothC1Edge.getBasis();
171
172 //gsWriteParaview(basisEdge[0].patch(0),"test_1",2000);
173
174 const boundaryInterface & item = m_patches.interfaces()[numInt];
175
176 index_t patch_1 = item.first().patch;
177 index_t patch_2 = item.second().patch;
178
179 index_t begin_col = 0, end_col = 0, shift_col = 0;
180 for (index_t np = 0; np < patch_1; ++np)
181 shift_col += m_bases[np].size();
182
183 end_col += m_bases[patch_1].piece(0).size();
184 for (size_t ii = 0; ii < basisEdge[0].nPatches(); ++ii)
185 {
186 index_t jj = 0;
187 for (index_t j = begin_col; j < end_col; ++j, ++jj)
188 if (basisEdge[0].patch(ii).coef(jj, 0) * basisEdge[0].patch(ii).coef(jj, 0) > 1e-25)
189 tripletList.push_back(gsEigen::Triplet<T,index_t>(shift_row + ii, shift_col + j,basisEdge[0].patch(ii).coef(jj, 0)));
190 }
191
192 begin_col = 0, end_col = 0, shift_col = 0;
193 for (index_t np = 0; np < patch_2; ++np)
194 shift_col += m_bases[np].size();
195
196 end_col += m_bases[patch_2].piece(0).size();
197
198 for (size_t ii = 0; ii < basisEdge[1].nPatches(); ++ii)
199 {
200 index_t jj = 0;
201 for (index_t j = begin_col; j < end_col; ++j, ++jj)
202 if (basisEdge[1].patch(ii).coef(jj, 0) * basisEdge[1].patch(ii).coef(jj, 0) > 1e-25)
203 tripletList.push_back(gsEigen::Triplet<T,index_t>(shift_row + ii, shift_col + j,basisEdge[1].patch(ii).coef(jj, 0)));
204 }
205
206 shift_row += basisEdge[0].nPatches();
207
208 }
209 // Compute Edge Basis functions
210 for (size_t numBdy = 0; numBdy < m_patches.boundaries().size(); numBdy++)
211 {
212
213 const patchSide & bit = m_patches.boundaries()[numBdy];
214
215 index_t patch_1 = bit.patch;
216 index_t side_1 = bit.side().index();
217
218 gsC1SurfEdge<d,T> smoothC1Edge(m_patches,bit);
219 smoothC1Edge.computeG1BoundaryBasis(side_1);
220 std::vector<gsMultiPatch<T>> basisEdge = smoothC1Edge.getBasis();
221
222 index_t begin_col = 0, end_col = 0, shift_col = 0;
223 for (index_t np = 0; np < patch_1; ++np)
224 shift_col += m_bases[np].size();
225
226 end_col += m_bases[patch_1].piece(0).size();
227 for (size_t ii = 0; ii < basisEdge[0].nPatches(); ++ii)
228 {
229 index_t jj = 0;
230 for (index_t j = begin_col; j < end_col; ++j, ++jj)
231 if (basisEdge[0].patch(ii).coef(jj, 0) * basisEdge[0].patch(ii).coef(jj, 0) > 1e-25)
232 tripletList.push_back(gsEigen::Triplet<T,index_t>(shift_row + ii, shift_col + j,basisEdge[0].patch(ii).coef(jj, 0)));
233 }
234
235 shift_row += basisEdge[0].nPatches();
236 }
237 // Compute Vertex Basis functions
238 for (size_t numVer = 0; numVer < m_patches.vertices().size(); numVer++)
239 {
240 std::vector<patchCorner> allcornerLists = m_patches.vertices()[numVer];
241 std::vector<index_t> patchIndex;
242 std::vector<index_t> vertIndex;
243 for (size_t j = 0; j < allcornerLists.size(); j++)
244 {
245 patchIndex.push_back(allcornerLists[j].patch);
246 vertIndex.push_back(allcornerLists[j].m_index);
247 }
248
249 gsC1SurfVertex<d,T> smoothC1Vertex(m_patches, patchIndex, vertIndex);
250 smoothC1Vertex.computeG1InternalVertexBasis();
251 std::vector<gsMultiPatch<T>> basisVertex = smoothC1Vertex.getBasis();
252
253 for(size_t pInd=0; pInd < patchIndex.size(); pInd++)
254 {
255 index_t begin_col = 0, end_col = 0, shift_col = 0;
256 for (index_t np = 0; np < patchIndex[pInd]; ++np)
257 shift_col += m_bases[np].size();
258
259 end_col += m_bases[patchIndex[pInd]].piece(0).size();
260 for (size_t ii = 0; ii < basisVertex[pInd].nPatches(); ++ii)
261 {
262 index_t jj = 0;
263 for (index_t j = begin_col; j < end_col; ++j, ++jj)
264 if (basisVertex[pInd].patch(ii).coef(jj, 0) * basisVertex[pInd].patch(ii).coef(jj, 0) > 1e-25)
265 tripletList.push_back(gsEigen::Triplet<T,index_t>(shift_row + ii, shift_col + j,basisVertex[pInd].patch(ii).coef(jj, 0)));
266 }
267 }
268 shift_row += 6;
269 }
270 m_matrix.setFromTriplets(tripletList.begin(),tripletList.end());
271 m_matrix.makeCompressed();
272 }
273
274
275} // namespace gismo
short_t index() const
Returns the index (as specified in boundary::side) of the box side.
Definition gsBoundary.h:140
A univariate B-spline basis.
Definition gsBSplineBasis.h:700
A tensor product B-spline basis.
Definition gsTensorBSplineBasis.h:37
const Basis_t & component(short_t dir) const
For a tensor product basis, return the (const) 1-d basis for the i-th parameter component.
Definition gsTensorBSplineBasis.h:202
Creates the (approx) C1 Edge space.
Creates the (approx.) C1 Vertex space.
#define index_t
Definition gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition gsDebug.h:102
The G+Smo namespace, containing all definitions for the library.
Struct which represents an interface between two patches.
Definition gsBoundary.h:650
patchSide & first()
first, returns the first patchSide of this interface
Definition gsBoundary.h:776
patchSide & second()
second, returns the second patchSide of this interface
Definition gsBoundary.h:782
Struct which represents a certain side of a patch.
Definition gsBoundary.h:232
index_t patch
The index of the patch.
Definition gsBoundary.h:234