21 template<
short_t d,
class T>
22 void gsApproxC1Vertex<d, T>::reparametrizeVertexPatches()
24 for(
size_t i = 0; i < m_auxPatches.size(); i++)
28 index_t vertex_1 = m_vertexIndices[i];
29 if(m_auxPatches[i].getOrient() == 0)
36 m_auxPatches[i].rotateParamAntiClockTwice();
40 m_auxPatches[i].rotateParamAntiClock();
44 m_auxPatches[i].rotateParamClock();
48 else if (m_auxPatches[i].getOrient() == 1)
55 m_auxPatches[i].rotateParamAntiClockTwice();
59 m_auxPatches[i].rotateParamAntiClock();
63 m_auxPatches[i].rotateParamClock();
70 template<
short_t d,
class T>
71 T gsApproxC1Vertex<d, T>::computeSigma(
const std::vector<size_t> &vertexIndices)
77 for(
size_t i = 0; i < m_auxPatches.size(); i++)
81 T p_temp = math::max(bsp_temp.
degree(0), bsp_temp.
degree(1));
83 p = (p < p_temp ? p_temp : p);
85 for(
index_t j = 0; j < m_auxPatches[i].getPatchRotated().parDim(); j++)
87 T h_geo_temp = bsp_temp.knot(j,p + 1);
88 h_geo = (h_geo > h_geo_temp ? h_geo_temp : h_geo);
95 for (
size_t i = 0; i < m_auxPatches.size(); i++)
97 deriv = m_auxPatches[i].getPatchRotated().deriv(zero);
98 sigma += deriv.template lpNorm<gsEigen::Infinity>();
100 sigma *= h_geo/(m_auxPatches.size()*p);
102 return (1.0 / sigma);
105 template<
short_t d,
class T>
106 void gsApproxC1Vertex<d, T>::checkOrientation(
size_t i) {
107 if (m_auxPatches[i].getPatchRotated().orientation() == -1)
109 m_auxPatches[i].swapAxis();
114 template<
short_t d,
class T>
115 void gsApproxC1Vertex<d, T>::computeKernel()
119 for(
size_t i = 0; i < m_patchesAroundVertex.size(); i++)
120 mp_vertex.
addPatch(m_auxPatches[i].getPatchRotated());
125 std::vector<index_t> dim_u, dim_v, side, patchID;
126 std::vector<index_t> dim_u_iFace, patchID_iFace;
127 gsMatrix<T> matrix_det(m_mp.targetDim(), m_mp.targetDim()), points(m_mp.parDim(),1);
129 for(
size_t np = 0; np < mp_vertex.
nPatches(); np++)
134 patchID.push_back(np);
135 dim_u.push_back(basisVertexResult[np].basis(0).component(0).size());
136 dim_v.push_back(basisVertexResult[np].basis(0).component(1).size());
137 dim_mat += basisVertexResult[np].basis(0).component(0).size();
138 if (!m_optionList.getSwitch(
"second"))
139 dim_mat += basisVertexResult[np].basis(0).component(0).size();
141 if(m_mp.parDim() == m_mp.targetDim())
142 matrix_det.col(0) = m_auxPatches[np].getPatchRotated().jacobian(points).col(0);
143 else if(m_mp.parDim() + 1 == m_mp.targetDim())
146 m_auxPatches[np].getPatchRotated().jacobian_into(points, ev);
148 N(0,0) = ev(1,0)*ev(2,1)-ev(2,0)*ev(1,1);
149 N(1,0) = ev(2,0)*ev(0,1)-ev(0,0)*ev(2,1);
150 N(2,0) = ev(0,0)*ev(1,1)-ev(1,0)*ev(0,1);
151 matrix_det.col(0) = ev.col(0);
152 matrix_det.col(2) = N;
158 patchID.push_back(np);
159 dim_u.push_back(basisVertexResult[np].basis(0).component(0).size());
160 dim_v.push_back(basisVertexResult[np].basis(0).component(1).size());
161 dim_mat += basisVertexResult[np].basis(0).component(1).size();
162 if (!m_optionList.getSwitch(
"second"))
163 dim_mat += basisVertexResult[np].basis(0).component(1).size();
165 if(m_mp.parDim() == m_mp.targetDim())
166 matrix_det.col(1) = m_auxPatches[np].getPatchRotated().jacobian(points).col(1);
167 else if(m_mp.parDim() + 1 == m_mp.targetDim())
170 m_auxPatches[np].getPatchRotated().jacobian_into(points, ev);
172 N(0,0) = ev(1,0)*ev(2,1)-ev(2,0)*ev(1,1);
173 N(1,0) = ev(2,0)*ev(0,1)-ev(0,0)*ev(2,1);
174 N(2,0) = ev(0,0)*ev(1,1)-ev(1,0)*ev(0,1);
175 matrix_det.col(1) = ev.col(1);
180 if (!m_optionList.getSwitch(
"second"))
184 patchID_iFace.push_back(np);
185 dim_u_iFace.push_back(basisVertexResult[np].basis(0).component(0).size());
189 if (patchID.size() != 2)
190 gsInfo <<
"Something went wrong \n";
193 if (m_optionList.getSwitch(
"second"))
196 if (matrix_det.determinant()*matrix_det.determinant() > 1e-15)
198 if (!m_optionList.getSwitch(
"second"))
205 if (m_optionList.getSwitch(
"info"))
206 gsInfo <<
"Det: " << matrix_det.determinant() <<
"\n";
209 coefs_corner.setZero();
212 for (
size_t bdy_index = 0; bdy_index < patchID.size(); ++bdy_index)
214 if (side[bdy_index] < 3)
216 index_t shift_row_neumann = dim_v[bdy_index];
217 for (
index_t i = 0; i < dim_v[bdy_index]; ++i)
219 for (
index_t j = 0; j < 6; ++j)
221 T coef_temp = basisVertexResult[patchID[bdy_index]].patch(j).coef(i*dim_u[bdy_index], 0);
222 if (coef_temp * coef_temp > 1e-25)
223 coefs_corner(shift_row+i, j) = coef_temp;
224 if (!m_optionList.getSwitch(
"second"))
226 T coef_temp = basisVertexResult[patchID[bdy_index]].patch(j).coef(i*dim_u[bdy_index] +1, 0);
227 if (coef_temp * coef_temp > 1e-25)
228 coefs_corner(shift_row_neumann + shift_row+i, j) = coef_temp;
232 shift_row += dim_v[bdy_index];
233 if (!m_optionList.getSwitch(
"second"))
234 shift_row += dim_v[bdy_index];
238 index_t shift_row_neumann = dim_u[bdy_index];
239 for (
index_t i = 0; i < dim_u[bdy_index]; ++i)
241 for (
index_t j = 0; j < 6; ++j)
243 T coef_temp = basisVertexResult[patchID[bdy_index]].patch(j).coef(i, 0);
244 if (coef_temp * coef_temp > 1e-25)
245 coefs_corner(shift_row+i, j) = coef_temp;
246 if (!m_optionList.getSwitch(
"second"))
248 T coef_temp = basisVertexResult[patchID[bdy_index]].patch(j).coef(i+dim_u[bdy_index], 0);
249 if (coef_temp * coef_temp > 1e-25)
250 coefs_corner(shift_row_neumann + shift_row+i, j) = coef_temp;
254 shift_row += dim_u[bdy_index];
255 if (!m_optionList.getSwitch(
"second"))
256 shift_row += dim_u[bdy_index];
259 for (
size_t iFace_index = 0; iFace_index < patchID_iFace.size(); ++iFace_index)
261 if (!m_optionList.getSwitch(
"second")) {
262 for (
index_t i = 0; i < 2; ++i)
264 for (
index_t j = 0; j < 6; ++j) {
265 T coef_temp = basisVertexResult[patchID_iFace[iFace_index]].patch(j).coef(i, 0);
266 if (coef_temp * coef_temp > 1e-25)
267 coefs_corner(shift_row + i, j) = coef_temp;
268 coef_temp = basisVertexResult[patchID_iFace[iFace_index]].patch(j).coef(i + dim_u_iFace[iFace_index],
270 if (coef_temp * coef_temp > 1e-25)
271 coefs_corner(shift_row + 2 + i, j) = coef_temp;
278 for (
index_t j = 0; j < 6; ++j)
280 T coef_temp = basisVertexResult[patchID[iFace_index]].patch(j).coef(0, 0);
281 if (coef_temp * coef_temp > 1e-25)
282 coefs_corner(shift_row, j) = coef_temp;
292 gsEigen::FullPivLU<gsMatrix<T>> KernelCorner(coefs_corner);
293 KernelCorner.setThreshold(threshold);
295 while (KernelCorner.dimensionOfKernel() < dofsCorner) {
297 KernelCorner.setThreshold(threshold);
299 if (m_optionList.getSwitch(
"info"))
300 gsInfo <<
"Dimension of Kernel: " << KernelCorner.dimensionOfKernel() <<
" With " << threshold <<
"\n";
303 vertBas.setIdentity(6, 6);
305 kernel = KernelCorner.kernel();
308 while (kernel.cols() < 6) {
309 kernel.conservativeResize(kernel.rows(), kernel.cols() + 1);
310 kernel.col(kernel.cols() - 1) = vertBas.col(count);
312 gsEigen::FullPivLU<gsMatrix<T>> ker_temp(kernel);
313 ker_temp.setThreshold(1e-6);
314 if (ker_temp.dimensionOfKernel() != 0) {
315 kernel = kernel.block(0, 0, kernel.rows(), kernel.cols() - 1);
321 kernel.setIdentity(6, 6);
323 if (m_optionList.getSwitch(
"info"))
324 gsInfo <<
"NumDofs: " << dofsCorner <<
" with Kernel: \n" << kernel <<
"\n";
326 for(
size_t np = 0; np < m_patchesAroundVertex.size(); np++)
330 for (
size_t j = 0; j < 6; ++j)
334 coef_bf.setZero(dim_uv, 1);
335 for (
index_t i = 0; i < 6; ++i)
336 if (kernel(i, j) * kernel(i, j) > 1e-25)
337 coef_bf += temp_result_0.
patch(i).coefs() * kernel(i, j);
339 basisVertexResult[np].patch(j).setCoefs(coef_bf);
index_t addPatch(typename gsGeometry< T >::uPtr g)
Add a patch from a gsGeometry<T>::uPtr.
Definition: gsMultiPatch.hpp:210
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
gsBasis< T > & basis(const size_t i) const
Return the basis of the i-th patch.
Definition: gsMultiPatch.hpp:171
bool isBoundary(const patchSide &ps) const
Is the given patch side ps set to a boundary?
Definition: gsBoxTopology.h:223
#define index_t
Definition: gsConfig.h:32
A tensor product B-spline basis.
Definition: gsTensorBSplineBasis.h:36
gsGeometry< T > & patch(size_t i) const
Return the i-th patch.
Definition: gsMultiPatch.h:226
size_t nPatches() const
Number of patches.
Definition: gsMultiPatch.h:208
#define gsInfo
Definition: gsDebug.h:43
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition: gsMultiPatch.h:33
bool isInterface(const patchSide &ps) const
Is the given patch side ps set to an interface?
Definition: gsBoxTopology.cpp:103
bool computeTopology(T tol=1e-4, bool cornersOnly=false, bool tjunctions=false)
Attempt to compute interfaces and boundaries automatically.
Definition: gsMultiPatch.hpp:366