20 #include <gsUnstructuredSplines/src/gsApproxC1GluingData.h>
24 template<
short_t d,
class T>
25 class gsApproxC1Vertex
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,
51 : m_mp(mp), m_bases(bases), m_patchesAroundVertex(patchesAroundVertex),
52 m_vertexIndices(vertexIndices), m_optionList(optionList)
55 basisVertexResult.clear();
57 for(
size_t i = 0; i < m_patchesAroundVertex.size(); i++)
59 index_t patch_1 = m_patchesAroundVertex[i];
61 m_auxPatches.push_back(gsPatchReparameterized<d,T>(m_mp.patch(patch_1), m_bases[patch_1]));
64 reparametrizeVertexPatches();
67 T sigma = computeSigma(m_vertexIndices);
73 Phi.col(3) *= sigma * sigma;
74 Phi.col(4) *= sigma * sigma;
75 Phi.col(5) *= sigma * sigma;
78 if (m_auxPatches[0].getPatchRotated().parDim() + 1 == m_auxPatches[0].getPatchRotated().targetDim())
82 gsMatrix<T> Jk = m_auxPatches[0].getPatchRotated().jacobian(zero);
86 gsMatrix<T> geoMapDeriv1 = m_auxPatches[0].getPatchRotated()
88 gsMatrix<T> geoMapDeriv2 = m_auxPatches[0].getPatchRotated()
94 n(0) = Jk(1,0)*Jk(2,1)-Jk(2,0)*Jk(1,1);
95 n(1) = Jk(2,0)*Jk(0,1)-Jk(0,0)*Jk(2,1);
96 n(2) = Jk(0,0)*Jk(1,1)-Jk(1,0)*Jk(0,1);
104 rotVec(0) = n(1,0)*z(2,0)-n(2,0)*z(1,0);
105 rotVec(1) = n(2,0)*z(0,0)-n(0,0)*z(2,0);
106 rotVec(2) = n(0,0)*z(1,0)-n(1,0)*z(0,0);
108 T cos_t = (n.dot(z))/ (n.norm() * z.norm());
109 T sin_t = rotVec.norm() / (n.norm() * z.norm());
115 R(0, 0) = cos_t + rotVec.x() * rotVec.x() * (1 - cos_t);
116 R(0, 1) = rotVec.x() * rotVec.y() * (1 - cos_t) - rotVec.z() * sin_t;
117 R(0, 2) = rotVec.x() * rotVec.z() * (1 - cos_t) + rotVec.y() * sin_t;
119 R(1, 0) = rotVec.x() * rotVec.y() * (1 - cos_t) + rotVec.z() * sin_t;
120 R(1, 1) = cos_t + rotVec.y() * rotVec.y() * (1 - cos_t);
121 R(1, 2) = rotVec.y() * rotVec.z() * (1 - cos_t) - rotVec.x() * sin_t;
123 R(2, 0) = rotVec.x() * rotVec.z() * (1 - cos_t) - rotVec.y() * sin_t;
124 R(2, 1) = rotVec.y() * rotVec.z() * (1 - cos_t) + rotVec.x() * sin_t;
125 R(2, 2) = cos_t + rotVec.z() * rotVec.z() * (1 - cos_t);
127 for (
size_t np = 0; np < m_auxPatches.size(); np++)
129 gsMatrix<T> coeffPatch = m_auxPatches[np].getPatchRotated().coefs();
131 for (
index_t i = 0; i < coeffPatch.rows(); i++)
134 (coeffPatch.row(i) - coeffPatch.row(0)) * R.transpose() + coeffPatch.row(0);
137 rotPatch.
addPatch(m_auxPatches[np].getPatchRotated());
138 rotPatch.
patch(np).setCoefs(coeffPatch);
146 Phi(4, 3) = sigma * sigma;
147 Phi(5, 4) = sigma * sigma;
148 Phi(7, 4) = sigma * sigma;
149 Phi(8, 5) = sigma * sigma;
153 for (
size_t np = 0; np < m_auxPatches.size(); np++)
154 rotPatch.
addPatch(m_auxPatches[np].getPatchRotated());
158 for(
size_t i = 0; i < m_patchesAroundVertex.size(); i++)
160 C1AuxPatchContainer auxPatchSingle;
161 auxPatchSingle.push_back(m_auxPatches[i]);
163 std::vector<patchSide> containingSides;
164 patchCorner pC(m_patchesAroundVertex[i], m_vertexIndices[i]);
165 pC.getContainingSides(d, containingSides);
171 if (containingSides.at(0).side() < 3)
173 patchSide side_temp = containingSides[0];
174 containingSides[0] = containingSides[1];
175 containingSides[1] = side_temp;
182 std::vector<bool> isInterface(2);
183 isInterface[0] = m_mp.isInterface(
patchSide(m_patchesAroundVertex[i], containingSides.at(0).side()));
184 isInterface[1] = m_mp.isInterface(
patchSide(m_patchesAroundVertex[i], containingSides.at(1).side()));
187 std::vector<gsBSpline<T>> alpha, beta;
188 std::vector<gsBSplineBasis<T>> basis_plus, basis_minus;
190 std::vector<bool> kindOfEdge;
192 alpha.resize(2); beta.resize(2); basis_plus.resize(2); basis_minus.resize(2);
193 kindOfEdge.resize(2);
197 for (
size_t dir = 0; dir < containingSides.size(); ++dir)
200 if (isInterface[dir])
203 m_mp.getNeighbour(containingSides[dir], result);
206 for (
size_t i_tmp = 0; i_tmp < m_patchesAroundVertex.size(); i_tmp++)
207 if (m_patchesAroundVertex[i_tmp] ==
size_t(result.
patch))
214 index_t dir_1 = auxPatchSingle[0].getMapIndex(containingSides[dir].side()) < 3 ? 1 : 0;
215 index_t dir_2 = m_auxPatches[patch2].getMapIndex(result.side().
index()) < 3 ? 1 : 0;
224 gsApproxC1GluingData<d, T> approxGluingData(auxPatchSingle, m_optionList, containingSides, isInterface, basis_pm);
228 gsMultiBasis<T> initSpace(auxPatchSingle[0].getBasisRotated().piece(0));
229 for (
size_t dir = 0; dir < containingSides.size(); ++dir)
231 index_t localdir = auxPatchSingle[0].getMapIndex(containingSides[dir].index()) < 3 ? 1 : 0;
233 if (isInterface[dir])
235 alpha[localdir] = approxGluingData.alphaS(localdir);
236 beta[localdir] = approxGluingData.betaS(localdir);
239 kindOfEdge[localdir] = isInterface[dir];
242 if (isInterface[dir])
245 createPlusSpace(geo, basis_pm, localdir, b_plus);
246 createMinusSpace(geo, basis_pm, localdir, b_minus);
252 createPlusSpace(geo, initSpace.
basis(0), localdir, b_plus);
253 createMinusSpace(geo, initSpace.
basis(0), localdir, b_minus);
260 basis_plus[localdir] = b_plus;
261 basis_minus[localdir] = b_minus;
264 typename gsSparseSolver<T>::SimplicialLDLT solver;
268 gsMultiBasis<T> vertexSpace(auxPatchSingle[0].getBasisRotated().piece(m_vertexIndices[i] + 4));
269 A.setIntegrationElements(vertexSpace);
273 auto u = A.getSpace(vertexSpace);
277 if (!m_optionList.getSwitch(
"interpolation"))
280 for (
index_t dir = 0; dir < vertexSpace.basis(0).domainDim(); dir++)
281 for (
index_t i = 3 * vertexSpace.basis(0).degree(dir) + 1; i < vertexSpace.basis(0).component(
282 1 - dir).size(); i++)
284 act = vertexSpace.basis(0).boundaryOffset(dir == 0 ? 3 : 1, i);
292 fixedDofs.setZero(u.mapper().boundarySize(), 1);
295 A.assemble(u * u.tr());
296 solver.compute(A.matrix());
301 for (
index_t bfID = 0; bfID < 6; bfID++)
303 gsVertexBasis<T> vertexBasis(geo, basis_pm, alpha, beta, basis_plus, basis_minus, Phi,
305 if (m_optionList.getSwitch(
"interpolation"))
309 gsMatrix<T> anchors = vertexSpace.basis(0).anchors();
311 result_1.
addPatch(vertexSpace.basis(0).interpolateAtAnchors(
give(values)));
317 auto aa = A.getCoeff(vertexBasis);
322 auto u_sol = A.getSolution(u, solVector);
326 result_1.
addPatch(vertexSpace.basis(0).makeGeometry(
give(sol)));
332 basisVertexResult.push_back(result_1);
336 for (
size_t j = 0; j < m_patchesAroundVertex.size(); j++)
337 temp_mp.
addPatch(m_mp.patch(m_patchesAroundVertex[j]));
340 if (m_patchesAroundVertex.size() != temp_mp.
interfaces().size())
344 for(
size_t i = 0; i < m_patchesAroundVertex.size(); i++)
345 m_auxPatches[i].parametrizeBasisBack(basisVertexResult[i]);
349 for(
size_t i = 0; i < m_patchesAroundVertex.size(); i++)
350 m_auxPatches[i].parametrizeBasisBack(basisVertexResult[i]);
378 void reparametrizeVertexPatches();
380 void checkOrientation(
size_t i);
382 T computeSigma(
const std::vector<size_t> & vertexIndices);
384 void computeKernel();
386 std::vector<gsMultiPatch<T>> getVertexBasis() {
return basisVertexResult; }
393 BasisContainer & m_bases;
395 const std::vector<size_t> & m_patchesAroundVertex;
396 const std::vector<size_t> & m_vertexIndices;
401 C1AuxPatchContainer m_auxPatches;
404 std::vector<gsMultiPatch<T>> basisVertexResult;
410 #ifndef GISMO_BUILD_LIB
411 #include GISMO_HPP_HEADER(gsApproxC1Vertex.hpp)
index_t addPatch(typename gsGeometry< T >::uPtr g)
Add a patch from a gsGeometry<T>::uPtr.
Definition: gsMultiPatch.hpp:210
Abstract base class representing a geometry map.
Definition: gsGeometry.h:92
Definition: gsExprAssembler.h:30
Struct which represents a certain side of a patch.
Definition: gsBoundary.h:231
Provides declaration of Basis abstract interface.
S give(S &x)
Definition: gsMemory.h:266
#define index_t
Definition: gsConfig.h:32
A tensor product B-spline basis.
Definition: gsTensorBSplineBasis.h:36
Struct which represents a certain corner of a patch.
Definition: gsBoundary.h:392
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
Maintains a mapping from patch-local dofs to global dof indices and allows the elimination of individ...
Definition: gsDofMapper.h:68
A univariate B-spline basis.
Definition: gsBSplineBasis.h:694
Holds a set of patch-wise bases and their topology information.
Definition: gsMultiBasis.h:36
gsGeometry< T > & patch(size_t i) const
Return the i-th patch.
Definition: gsMultiPatch.h:226
Provides declaration of Basis abstract interface. Similar to gsMultiBasis, but without topology...
Definition: gsDirichletValues.h:23
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition: gsMultiPatch.h:33
Generic evaluator of isogeometric expressions.
Definition: gsExprEvaluator.h:38
short_t index() const
Returns the index (as specified in boundary::side) of the box side.
Definition: gsBoundary.h:140
Class which holds a list of parameters/options, and provides easy access to them. ...
Definition: gsOptionList.h:32
const ifContainer & interfaces() const
Return the vector of interfaces.
Definition: gsBoxTopology.h:252
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
virtual const gsBasis< T > & basis() const =0
Returns a const reference to the basis of the geometry.
index_t patch
The index of the patch.
Definition: gsBoundary.h:234
bool computeTopology(T tol=1e-4, bool cornersOnly=false, bool tjunctions=false)
Attempt to compute interfaces and boundaries automatically.
Definition: gsMultiPatch.hpp:366