20#include <gsUnstructuredSplines/src/gsApproxC1GluingData.h>
24template<
short_t d,
class T>
29 typedef gsContainerBasis<d, T> Basis;
30 typedef typename std::vector<Basis> BasisContainer;
31 typedef typename std::vector<gsPatchReparameterized<d,T>> C1AuxPatchContainer;
34 typedef memory::shared_ptr<gsApproxC1Vertex> Ptr;
37 typedef memory::unique_ptr<gsApproxC1Vertex> uPtr;
42 ~gsApproxC1Vertex() { }
46 BasisContainer & bases,
47 const std::vector<size_t> & patchesAroundVertex,
48 const std::vector<size_t> & vertexIndices,
49 const index_t & numVer,
51 : m_mp(mp), m_bases(bases), m_patchesAroundVertex(patchesAroundVertex),
52 m_vertexIndices(vertexIndices), m_optionList(optionList)
57 basisVertexResult.clear();
59 for(
size_t i = 0; i < m_patchesAroundVertex.size(); i++)
61 index_t patch_1 = m_patchesAroundVertex[i];
63 m_auxPatches.push_back(gsPatchReparameterized<d,T>(m_mp.patch(patch_1), m_bases[patch_1]));
66 reparametrizeVertexPatches();
69 T sigma = computeSigma(m_vertexIndices);
75 Phi.col(3) *= sigma * sigma;
76 Phi.col(4) *= sigma * sigma;
77 Phi.col(5) *= sigma * sigma;
80 if (m_auxPatches[0].getPatchRotated().parDim() + 1 == m_auxPatches[0].getPatchRotated().targetDim())
84 gsMatrix<T> Jk = m_auxPatches[0].getPatchRotated().jacobian(zero);
88 gsMatrix<T> geoMapDeriv1 = m_auxPatches[0].getPatchRotated()
90 gsMatrix<T> geoMapDeriv2 = m_auxPatches[0].getPatchRotated()
96 n(0) = Jk(1,0)*Jk(2,1)-Jk(2,0)*Jk(1,1);
97 n(1) = Jk(2,0)*Jk(0,1)-Jk(0,0)*Jk(2,1);
98 n(2) = Jk(0,0)*Jk(1,1)-Jk(1,0)*Jk(0,1);
106 rotVec(0) = n(1,0)*z(2,0)-n(2,0)*z(1,0);
107 rotVec(1) = n(2,0)*z(0,0)-n(0,0)*z(2,0);
108 rotVec(2) = n(0,0)*z(1,0)-n(1,0)*z(0,0);
110 T cos_t = (n.dot(z))/ (n.norm() * z.norm());
111 T sin_t = rotVec.norm() / (n.norm() * z.norm());
117 R(0, 0) = cos_t + rotVec.x() * rotVec.x() * (1 - cos_t);
118 R(0, 1) = rotVec.x() * rotVec.y() * (1 - cos_t) - rotVec.z() * sin_t;
119 R(0, 2) = rotVec.x() * rotVec.z() * (1 - cos_t) + rotVec.y() * sin_t;
121 R(1, 0) = rotVec.x() * rotVec.y() * (1 - cos_t) + rotVec.z() * sin_t;
122 R(1, 1) = cos_t + rotVec.y() * rotVec.y() * (1 - cos_t);
123 R(1, 2) = rotVec.y() * rotVec.z() * (1 - cos_t) - rotVec.x() * sin_t;
125 R(2, 0) = rotVec.x() * rotVec.z() * (1 - cos_t) - rotVec.y() * sin_t;
126 R(2, 1) = rotVec.y() * rotVec.z() * (1 - cos_t) + rotVec.x() * sin_t;
127 R(2, 2) = cos_t + rotVec.z() * rotVec.z() * (1 - cos_t);
129 for (
size_t np = 0; np < m_auxPatches.size(); np++)
131 gsMatrix<T> coeffPatch = m_auxPatches[np].getPatchRotated().coefs();
133 for (index_t i = 0; i < coeffPatch.rows(); i++)
136 (coeffPatch.row(i) - coeffPatch.row(0)) * R.transpose() + coeffPatch.row(0);
139 rotPatch.
addPatch(m_auxPatches[np].getPatchRotated());
140 rotPatch.
patch(np).setCoefs(coeffPatch);
148 Phi(4, 3) = sigma * sigma;
149 Phi(5, 4) = sigma * sigma;
150 Phi(7, 4) = sigma * sigma;
151 Phi(8, 5) = sigma * sigma;
155 for (
size_t np = 0; np < m_auxPatches.size(); np++)
156 rotPatch.
addPatch(m_auxPatches[np].getPatchRotated());
160 for(
size_t i = 0; i < m_patchesAroundVertex.size(); i++)
162 C1AuxPatchContainer auxPatchSingle;
163 auxPatchSingle.push_back(m_auxPatches[i]);
165 std::vector<patchSide> containingSides;
166 patchCorner pC(m_patchesAroundVertex[i], m_vertexIndices[i]);
167 pC.getContainingSides(d, containingSides);
173 if (containingSides.at(0).side() < 3)
175 patchSide side_temp = containingSides[0];
176 containingSides[0] = containingSides[1];
177 containingSides[1] = side_temp;
184 std::vector<bool> isInterface(2);
185 isInterface[0] = m_mp.isInterface(
patchSide(m_patchesAroundVertex[i], containingSides.at(0).side()));
186 isInterface[1] = m_mp.isInterface(
patchSide(m_patchesAroundVertex[i], containingSides.at(1).side()));
189 std::vector<gsBSpline<T>> alpha, beta;
190 std::vector<gsBSplineBasis<T>> basis_plus, basis_minus;
192 std::vector<bool> kindOfEdge;
194 alpha.resize(2); beta.resize(2); basis_plus.resize(2); basis_minus.resize(2);
195 kindOfEdge.resize(2);
199 for (
size_t dir = 0; dir < containingSides.size(); ++dir)
202 if (isInterface[dir])
205 m_mp.getNeighbour(containingSides[dir], result);
208 for (
size_t i_tmp = 0; i_tmp < m_patchesAroundVertex.size(); i_tmp++)
209 if (m_patchesAroundVertex[i_tmp] ==
size_t(result.
patch))
216 index_t dir_1 = auxPatchSingle[0].getMapIndex(containingSides[dir].side()) < 3 ? 1 : 0;
217 index_t dir_2 = m_auxPatches[patch2].getMapIndex(result.side().
index()) < 3 ? 1 : 0;
218 if (basis.component(dir_1).numElements() > basis2.
component(dir_2).numElements())
226 gsApproxC1GluingData<d, T> approxGluingData(auxPatchSingle, m_optionList, containingSides, isInterface, basis_pm);
230 gsMultiBasis<T> initSpace(auxPatchSingle[0].getBasisRotated().piece(0));
231 for (
size_t dir = 0; dir < containingSides.size(); ++dir)
233 index_t localdir = auxPatchSingle[0].getMapIndex(containingSides[dir].index()) < 3 ? 1 : 0;
235 if (isInterface[dir])
237 alpha[localdir] = approxGluingData.alphaS(localdir);
238 beta[localdir] = approxGluingData.betaS(localdir);
241 kindOfEdge[localdir] = isInterface[dir];
244 if (isInterface[dir])
247 createPlusSpace(geo, basis_pm, localdir, b_plus);
248 createMinusSpace(geo, basis_pm, localdir, b_minus);
254 createPlusSpace(geo, initSpace.basis(0), localdir, b_plus);
255 createMinusSpace(geo, initSpace.basis(0), localdir, b_minus);
262 basis_plus[localdir] = b_plus;
263 basis_minus[localdir] = b_minus;
266 typename gsSparseSolver<T>::SimplicialLDLT solver;
270 gsMultiBasis<T> vertexSpace(auxPatchSingle[0].getBasisRotated().piece(m_vertexIndices[i] + 4));
271 A.setIntegrationElements(vertexSpace);
275 auto u = A.getSpace(vertexSpace);
279 if (!m_optionList.getSwitch(
"interpolation"))
282 for (index_t dir = 0; dir < vertexSpace.basis(0).domainDim(); dir++)
283 for (index_t i = 3 * vertexSpace.basis(0).degree(dir) + 1; i < vertexSpace.basis(0).component(
284 1 - dir).size(); i++)
286 act = vertexSpace.basis(0).boundaryOffset(dir == 0 ? 3 : 1, i);
294 fixedDofs.setZero(u.mapper().boundarySize(), 1);
297 A.assemble(u * u.tr());
298 solver.compute(A.matrix());
303 for (index_t bfID = 0; bfID < 6; bfID++)
305 gsVertexBasis<T> vertexBasis(geo, basis_pm, alpha, beta, basis_plus, basis_minus, Phi,
307 if (m_optionList.getSwitch(
"interpolation"))
311 gsMatrix<T> anchors = vertexSpace.basis(0).anchors();
313 result_1.
addPatch(vertexSpace.basis(0).interpolateAtAnchors(
give(values)));
319 auto aa = A.getCoeff(vertexBasis);
324 auto u_sol = A.getSolution(u, solVector);
328 result_1.
addPatch(vertexSpace.basis(0).makeGeometry(
give(sol)));
334 basisVertexResult.push_back(result_1);
338 for (
size_t j = 0; j < m_patchesAroundVertex.size(); j++)
339 temp_mp.
addPatch(m_mp.patch(m_patchesAroundVertex[j]));
342 if (m_patchesAroundVertex.size() != temp_mp.
interfaces().size())
346 for(
size_t i = 0; i < m_patchesAroundVertex.size(); i++)
347 m_auxPatches[i].parametrizeBasisBack(basisVertexResult[i]);
351 for(
size_t i = 0; i < m_patchesAroundVertex.size(); i++)
352 m_auxPatches[i].parametrizeBasisBack(basisVertexResult[i]);
380 void reparametrizeVertexPatches();
382 void checkOrientation(
size_t i);
384 T computeSigma(
const std::vector<size_t> & vertexIndices);
386 void computeKernel();
388 std::vector<gsMultiPatch<T>> getVertexBasis() {
return basisVertexResult; }
395 BasisContainer & m_bases;
397 const std::vector<size_t> & m_patchesAroundVertex;
398 const std::vector<size_t> & m_vertexIndices;
403 C1AuxPatchContainer m_auxPatches;
406 std::vector<gsMultiPatch<T>> basisVertexResult;
412#ifndef GISMO_BUILD_LIB
413#include GISMO_HPP_HEADER(gsApproxC1Vertex.hpp)
short_t index() const
Returns the index (as specified in boundary::side) of the box side.
Definition gsBoundary.h:140
Definition gsExpressions.h:973
A univariate B-spline basis.
Definition gsBSplineBasis.h:700
const ifContainer & interfaces() const
Return the vector of interfaces.
Definition gsBoxTopology.h:252
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
bool computeTopology(T tol=1e-4, bool cornersOnly=false, bool tjunctions=false)
Attempt to compute interfaces and boundaries automatically.
Definition gsMultiPatch.hpp:377
gsGeometry< T > & patch(size_t i) const
Return the i-th patch.
Definition gsMultiPatch.h:292
index_t addPatch(typename gsGeometry< T >::uPtr g)
Add a patch from a gsGeometry<T>::uPtr.
Definition gsMultiPatch.hpp:211
Class which holds a list of parameters/options, and provides easy access to them.
Definition gsOptionList.h:33
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
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
Provides declaration of Basis abstract interface.
#define index_t
Definition gsConfig.h:32
Provides declaration of Basis abstract interface. Similar to gsMultiBasis, but without topology.
#define GISMO_UNUSED(x)
Definition gsDebug.h:112
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
The G+Smo namespace, containing all definitions for the library.
S give(S &x)
Definition gsMemory.h:266
Struct which represents a certain corner of a patch.
Definition gsBoundary.h:393
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