24 template<
short_t d,
class T>
34 for (
size_t np = 0; np < m_patches.nPatches(); np++) {
36 if (p != basis_np.
degree(0))
37 gsWarn <<
"Not suitable for different degrees! \n";
41 for (
size_t np = 0; np < m_patches.nPatches(); np++)
42 for (
index_t dir = 0; dir < 2; dir++) {
46 std::vector<real_t> unique_geo = kv_geo.unique();
48 if (2 != unique_geo.
size())
49 gsWarn <<
"Not suitable for geometries with inner knots! \n";
52 m_options.addSwitch(
"info",
"Print debug information",
false );
53 m_options.addSwitch(
"plot",
"Print debug information",
false );
54 m_options.addSwitch(
"interpolation",
"Compute the basis with interpolation",
false );
55 m_options.addSwitch(
"second",
"Compute the second biharmonic problem",
false );
57 m_options.addInt(
"gluingDataDegree",
"Print debug information", -1 );
58 m_options.addInt(
"gluingDataSmoothness",
"Print debug information", -1 );
61 template<
short_t d,
class T>
67 m_patches.fixOrientation();
70 m_bases.reserve(m_patches.nPatches());
71 for (
size_t np = 0; np < m_patches.nPatches(); np++)
79 gsContainerBasis<d,T> containerBasis(9);
80 m_bases.push_back(containerBasis);
84 for (
size_t np = 0; np < m_patches.nPatches(); np++)
91 row_dofs += (dim_u - 4) * (dim_v - 4);
93 m_bases[np].setBasis(0, basis_inner);
97 for (
size_t numInt = 0; numInt < m_patches.interfaces().size(); numInt++)
110 if (basis_11.
component(dir_1).numElements() > basis_22.
component(dir_2).numElements())
129 createPlusSpace(m_patches.patch(patch), basis, dir, basis_plus);
130 createMinusSpace(m_patches.patch(patch), basis, dir, basis_minus);
135 createGluingDataSpace(m_patches.patch(patch), basis, dir, basis_gluingData,
136 m_options.getInt(
"gluingDataDegree"), m_options.getInt(
"gluingDataSmoothness"));
141 createEdgeSpace(m_patches.patch(item.
first().
patch), basis_11, dir_1,
142 basis_plus, basis_minus, basis_gluingData, basis_edge_11);
143 createEdgeSpace(m_patches.patch(item.
second().
patch), basis_22, dir_2,
144 basis_plus, basis_minus, basis_gluingData, basis_edge_22);
155 for (
size_t numBdy = 0; numBdy < m_patches.boundaries().size(); numBdy++)
157 const patchSide & bit = m_patches.boundaries()[numBdy];
159 index_t dir_1 = m_patches.boundaries()[numBdy].m_index < 3 ? 1 : 0;
166 createPlusSpace(m_patches.patch(bit.
patch), basis, dir_1, basis_plus);
167 createMinusSpace(m_patches.patch(bit.
patch), basis, dir_1, basis_minus);
171 createEdgeSpace(m_patches.patch(bit.
patch), basis, dir_1, basis_plus, basis_minus, basis_edge_11);
173 m_bases[bit.
patch].setBasis(bit.side().
index(), basis_edge_11);
175 index_t numDofs = std::max(basis_plus.size() + basis_minus.size() - 10, (
index_t)0);
180 for (
size_t numVer = 0; numVer < m_patches.vertices().size(); numVer++)
182 std::vector<patchCorner> allcornerLists = m_patches.vertices()[numVer];
183 for (
size_t j = 0; j < allcornerLists.size(); j++)
185 std::vector<patchSide> containingSides;
186 allcornerLists[j].getContainingSides(d, containingSides);
187 bool isInterface_1 = m_patches.isInterface(
patchSide(allcornerLists[j].patch,
188 containingSides.at(0).side()));
189 bool isInterface_2 = m_patches.isInterface(
patchSide(allcornerLists[j].patch,
190 containingSides.at(1).side()));
197 m_patches.getNeighbour(containingSides.at(0), result);
201 index_t dir_1 = containingSides.at(0).side() < 3 ? 1 : 0;
209 m_patches.getNeighbour(containingSides.at(1), result);
213 index_t dir_1 = containingSides.at(1).side() < 3 ? 1 : 0;
219 if (containingSides.at(0).side() < 3)
221 bool isInterface_temp = isInterface_1;
222 isInterface_1 = isInterface_2;
223 isInterface_2 = isInterface_temp;
227 createVertexSpace(m_patches.patch(allcornerLists[j].patch), basis,
228 isInterface_1, isInterface_2, basis_vertex_11, m_options.getInt(
"gluingDataDegree"),
229 m_options.getInt(
"gluingDataSmoothness"));
231 m_bases[allcornerLists[j].patch].setBasis(allcornerLists[j].m_index + 4, basis_vertex_11);
239 for (
size_t i = 0; i < m_bases.size(); i++)
241 dim_col += m_bases[i].size();
244 m_matrix.resize(row_dofs, dim_col);
245 const index_t nz = (m_multiBasis.basis(0).degree(0)*2 + 1)*row_dofs;
246 m_matrix.reserve(nz);
249 if (m_options.getSwitch(
"info"))
251 for (
size_t i = 0; i < m_bases.size(); i++)
253 gsInfo <<
"Patch " << i <<
": \n";
254 for (
index_t j = 0; j < m_bases[i].nPieces(); j++)
256 gsInfo << (j == 0 ?
"Interior Space: " : ( j < 5 ?
"Edge Space: " :
"Vertex Space: ") ) <<
"\n";
259 std::vector<index_t> vec_1 = basis.knots(0).multiplicities();
260 std::vector<index_t> vec_2 = basis.knots(1).multiplicities();
263 gsInfo << mult_1.transpose() <<
"\n";
264 gsInfo << mult_2.transpose() <<
"\n";
265 gsInfo <<
"----------------------------------\n";
272 template<
short_t d,
class T>
276 index_t shift_row = 0, shift_col = 0;
277 for(
size_t np = 0; np < m_patches.nPatches(); ++np)
279 index_t dim_u = m_bases[np].piece(0).component(0).size();
280 index_t dim_v = m_bases[np].piece(0).component(1).size();
283 for (
index_t j = 2; j < dim_v-2; ++j)
284 for (
index_t i = 2; i < dim_u-2; ++i)
286 m_matrix.insert(shift_row + row_i, shift_col + j*dim_u+i) = 1.0;
291 shift_col += m_bases[np].size();
295 for (
size_t numInt = 0; numInt < m_patches.interfaces().size(); numInt++)
304 gsApproxC1Edge<d, T> approxC1Edge(m_patches, m_bases, item, numInt, m_options);
305 std::vector<gsMultiPatch<T>> basisEdge = approxC1Edge.getEdgeBasis();
307 index_t begin_col = 0, end_col = 0, shift_col = 0;
308 for (
index_t np = 0; np < patch_1; ++np)
309 shift_col += m_bases[np].size();
311 for (
index_t ns = 0; ns < side_1; ++ns)
312 begin_col += m_bases[patch_1].piece(ns).size();
313 for (
index_t ns = 0; ns < side_1+1; ++ns)
314 end_col += m_bases[patch_1].piece(ns).size();
316 for (
size_t ii = 0; ii < basisEdge[0].nPatches(); ++ii)
319 for (
index_t j = begin_col; j < end_col; ++j, ++jj) {
320 if (basisEdge[0].patch(ii).coef(jj, 0) * basisEdge[0].patch(ii).coef(jj, 0) > 1e-25)
321 m_matrix.insert(shift_row + ii, shift_col + j) = basisEdge[0].patch(ii).coef(jj, 0);
325 begin_col = 0, end_col = 0, shift_col = 0;
326 for (
index_t np = 0; np < patch_2; ++np)
327 shift_col += m_bases[np].size();
329 for (
index_t ns = 0; ns < side_2; ++ns)
330 begin_col += m_bases[patch_2].piece(ns).size();
331 for (
index_t ns = 0; ns < side_2+1; ++ns)
332 end_col += m_bases[patch_2].piece(ns).size();
334 for (
size_t ii = 0; ii < basisEdge[1].nPatches(); ++ii)
337 for (
index_t j = begin_col; j < end_col; ++j, ++jj) {
338 if (basisEdge[1].patch(ii).coef(jj, 0) * basisEdge[1].patch(ii).coef(jj, 0) > 1e-25)
339 m_matrix.insert(shift_row + ii, shift_col + j) = basisEdge[1].patch(ii).coef(jj, 0);
343 shift_row += basisEdge[0].nPatches();
347 for (
size_t numBdy = 0; numBdy < m_patches.boundaries().size(); numBdy++)
349 const patchSide & bit = m_patches.boundaries()[numBdy];
353 gsApproxC1Edge<d, T> approxC1Edge(m_patches, m_bases, bit, numBdy, m_options);
354 std::vector<gsMultiPatch<T>> basisEdge = approxC1Edge.getEdgeBasis();
356 index_t begin_col = 0, end_col = 0, shift_col = 0;
357 for (
index_t np = 0; np < patch_1; ++np)
358 shift_col += m_bases[np].size();
360 for (
index_t ns = 0; ns < side_1; ++ns)
361 begin_col += m_bases[patch_1].piece(ns).size();
362 for (
index_t ns = 0; ns < side_1+1; ++ns)
363 end_col += m_bases[patch_1].piece(ns).size();
365 for (
size_t ii = 0; ii < basisEdge[0].nPatches(); ++ii)
368 for (
index_t j = begin_col; j < end_col; ++j, ++jj) {
369 if (basisEdge[0].patch(ii).coef(jj, 0) * basisEdge[0].patch(ii).coef(jj, 0) > 1e-20)
370 m_matrix.insert(shift_row + ii, shift_col + j) = basisEdge[0].patch(ii).coef(jj, 0);
373 shift_row += basisEdge[0].nPatches();
377 for (
size_t numVer = 0; numVer < m_patches.vertices().size(); numVer++)
379 std::vector<patchCorner> allcornerLists = m_patches.vertices()[numVer];
380 std::vector<size_t> patchIndex;
381 std::vector<size_t> vertIndex;
382 for (
size_t j = 0; j < allcornerLists.size(); j++)
384 patchIndex.push_back(allcornerLists[j].patch);
385 vertIndex.push_back(allcornerLists[j].m_index);
388 gsApproxC1Vertex<d, T> approxC1Vertex(m_patches, m_bases, patchIndex, vertIndex, numVer, m_options);
389 std::vector<gsMultiPatch<T>> basisVertex = approxC1Vertex.getVertexBasis();
391 for (
size_t np = 0; np < patchIndex.size(); ++np)
393 index_t patch_1 = patchIndex[np];
394 index_t corner = vertIndex[np];
396 index_t begin_col = 0, end_col = 0, shift_col = 0;
397 for (
index_t np = 0; np < patch_1; ++np)
398 shift_col += m_bases[np].size();
400 for (
index_t ns = 0; ns < corner+4; ++ns)
401 begin_col += m_bases[patch_1].piece(ns).size();
402 for (
index_t ns = 0; ns < corner+4+1; ++ns)
403 end_col += m_bases[patch_1].piece(ns).size();
405 for (
size_t ii = 0; ii < basisVertex[np].nPatches(); ++ii)
408 for (
index_t j = begin_col; j < end_col; ++j, ++jj) {
409 if (basisVertex[np].patch(ii).coef(jj, 0) * basisVertex[np].patch(ii).coef(jj, 0) > 1e-20)
411 m_matrix.insert(shift_row + ii, shift_col + j) = basisVertex[np].patch(ii).coef(jj, 0);
416 shift_row += basisVertex[0].nPatches();
418 m_matrix.makeCompressed();
index_t size() const
size
Definition: gsBSplineBasis.h:165
short_t degree(short_t i) const
Returns the degree of the basis wrt variable i.
Definition: gsTensorBasis.h:465
Creates the (approx.) C1 Vertex space.
Struct which represents a certain side of a patch.
Definition: gsBoundary.h:231
void init()
Initializes the method.
Definition: gsApproxC1Spline.hpp:62
Provides declaration of Basis abstract interface.
void compute()
Computes the basis.
Definition: gsApproxC1Spline.hpp:273
void defaultOptions()
Sets the default options.
Definition: gsApproxC1Spline.hpp:25
size_t size() const
Number of knots (including repetitions).
Definition: gsKnotVector.h:242
#define index_t
Definition: gsConfig.h:32
A tensor product B-spline basis.
Definition: gsTensorBSplineBasis.h:36
A univariate B-spline basis.
Definition: gsBSplineBasis.h:694
Creates a mapped object or data pointer to a vector without copying data.
Definition: gsLinearAlgebra.h:129
#define gsWarn
Definition: gsDebug.h:50
const KnotVectorType & knots(int i=0) const
Returns the knot vector of the basis.
Definition: gsBSplineBasis.h:369
Creates the (approx) C1 Edge space.
#define gsInfo
Definition: gsDebug.h:43
Class for representing a knot vector.
Definition: gsKnotVector.h:79
patchSide & second()
second, returns the second patchSide of this interface
Definition: gsBoundary.h:782
Struct which represents an interface between two patches.
Definition: gsBoundary.h:649
short_t index() const
Returns the index (as specified in boundary::side) of the box side.
Definition: gsBoundary.h:140
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
index_t patch
The index of the patch.
Definition: gsBoundary.h:234
patchSide & first()
first, returns the first patchSide of this interface
Definition: gsBoundary.h:776