26 #ifdef gsSpectra_ENABLED
34 gsBiharmonicExprAssembler<T>::gsBiharmonicExprAssembler(
const gsMultiPatch<T> & mp,
35 const gsMultiBasis<T> & mb,
36 const gsFunctionSet<T> & force,
37 const gsBoundaryConditions<T> & bcs
46 this->_defaultOptions();
52 gsBiharmonicExprAssembler<T>& gsBiharmonicExprAssembler<T>::operator=(
const gsBiharmonicExprAssembler& other )
56 m_penalty=other.m_penalty;
57 m_lambda=other.m_lambda;
58 m_second=other.m_second;
59 m_continuity=other.m_continuity;
61 m_patches=other.m_patches;
62 m_basis=other.m_basis;
63 m_spaceBasis=other.m_spaceBasis;
65 m_force=other.m_force;
67 m_options=other.m_options;
70 m_assembler.setIntegrationElements(m_basis);
71 m_assembler.setOptions(m_options);
77 gsBiharmonicExprAssembler<T>& gsBiharmonicExprAssembler<T>::operator=( gsBiharmonicExprAssembler&& other )
79 m_penalty=
give(other.m_penalty);
80 m_lambda=
give(other.m_lambda);
81 m_second=
give(other.m_second);
82 m_continuity=
give(other.m_continuity);
84 m_patches=
give(other.m_patches);
85 m_basis=
give(other.m_basis);
86 m_spaceBasis=
give(other.m_spaceBasis);
87 m_bcs=
give(other.m_bcs);
88 m_force=
give(other.m_force);
90 m_options=
give(other.m_options);
93 m_assembler.setIntegrationElements(m_basis);
94 m_assembler.setOptions(m_options);
99 void gsBiharmonicExprAssembler<T>::_defaultOptions()
101 m_options.addReal(
"PenaltyIfc",
"Parameter Nitsche's method",-1);
102 m_options.addReal(
"Lambda",
"Parameter for BC projection",1e-5);
103 m_options.addSwitch(
"Second",
"Assemble the second biharmonic equation",
false);
104 m_options.addInt(
"Continuity",
"Set the continuity for the space",-1);
106 gsOptionList assemblerOptions = m_assembler.defaultOptions().wrapIntoGroup(
"ExprAssembler");
107 m_options.update(assemblerOptions,gsOptionList::addIfUnknown);
111 void gsBiharmonicExprAssembler<T>::_getOptions()
113 m_penalty = m_options.getReal(
"PenaltyIfc");
114 m_lambda = m_options.getReal(
"Lambda");
115 m_second = m_options.getSwitch(
"Second");
116 m_continuity = m_options.getInt(
"Continuity");
118 GISMO_ENSURE(m_options.hasGroup(
"ExprAssembler"),
"The option list does not contain options with the label 'ExprAssembler'!");
119 m_assembler.setOptions(m_options.getGroup(
"ExprAssembler"));
123 void gsBiharmonicExprAssembler<T>::setOptions(gsOptionList & options)
125 m_options.update(options,gsOptionList::ignoreIfUnknown);
131 void gsBiharmonicExprAssembler<T>::_initialize()
134 m_assembler.setIntegrationElements(m_basis);
135 m_assembler.setOptions(m_options.getGroup(
"ExprAssembler"));
137 GISMO_ASSERT(m_bcs.hasGeoMap(),
"No geometry map was assigned to the boundary conditions. Use bc.setGeoMap to assign one!");
139 m_assembler.getSpace(*m_spaceBasis, 1, 0);
143 void gsBiharmonicExprAssembler<T>::_setup(
const expr::gsFeSpace<T> & u)
147 _setMapperForBiharmonic(m_bcs, *m_spaceBasis, map);
151 _getDirichletNeumannValuesL2Projection(m_patches, m_basis, m_bcs, *m_spaceBasis, u);
155 void gsBiharmonicExprAssembler<T>::assembleMass()
157 m_assembler.cleanUp();
162 geometryMap G = m_assembler.getMap(m_patches);
165 auto u = m_assembler.trialSpace(0);
171 m_assembler.initSystem();
174 m_assembler.assemble(u * u.tr() *
meas(G));
178 void gsBiharmonicExprAssembler<T>::assemble()
180 m_assembler.cleanUp();
185 geometryMap G = m_assembler.getMap(m_patches);
188 auto ff = m_assembler.getCoeff(*m_force, G);
191 auto u = m_assembler.trialSpace(0);
197 m_assembler.initSystem();
200 m_assembler.assemble(ilapl(u, G) * ilapl(u, G).tr() *
meas(G),u * ff *
meas(G));
203 auto g_L = m_assembler.getBdrFunction(G);
205 m_assembler.assembleBdr(m_bcs.get(
"Laplace"), (igrad(u, G) *
nv(G)) * g_L.tr() );
210 gsMatrix<T> mu_interfaces;
212 _computeStabilityParameter(m_patches, m_basis, mu_interfaces);
215 for (
typename gsMultiPatch<T>::const_iiterator it = m_patches.iBegin(); it != m_patches.iEnd(); ++it, ++i)
217 T stab = 4 * ( m_basis.maxCwiseDegree() + m_basis.dim() ) * ( m_basis.maxCwiseDegree() + 1 );
218 T m_h = m_basis.basis(0).getMinCellLength();
219 T mu = 2 * stab / m_h;
224 mu = mu_interfaces(i,0) / m_h;
226 mu = m_penalty / m_h;
228 std::vector<boundaryInterface> iFace;
229 iFace.push_back(*it);
230 m_assembler.assembleIfc(iFace,
232 -alpha * 0.5 * igrad(u.left(), G) *
nv(G.left()).normalized() *
233 (ilapl(u.left(), G)).tr() *
nv(G.left()).norm(),
235 (igrad(u.left(), G) *
nv(G.left()).normalized() * (ilapl(u.left(), G)).tr()).tr() *
238 -alpha * 0.5 * igrad(u.left(), G.left()) *
nv(G.left()).normalized() *
239 (ilapl(u.right(), G.right())).tr() *
nv(G.left()).norm(),
240 -alpha * 0.5 * (igrad(u.left(), G.left()) *
nv(G.left()).normalized() *
241 (ilapl(u.right(), G.right())).tr()).tr() *
nv(G.left()).norm(),
243 alpha * 0.5 * igrad(u.right(), G.right()) *
nv(G.left()).normalized() *
244 (ilapl(u.left(), G.left())).tr() *
nv(G.left()).norm(),
245 alpha * 0.5 * (igrad(u.right(), G.right()) *
nv(G.left()).normalized() *
246 (ilapl(u.left(), G.left())).tr()).tr() *
nv(G.left()).norm(),
248 alpha * 0.5 * igrad(u.right(), G.right()) *
nv(G.left()).normalized() *
249 (ilapl(u.right(), G.right())).tr() *
nv(G.left()).norm(),
250 alpha * 0.5 * (igrad(u.right(), G.right()) *
nv(G.left()).normalized() *
251 (ilapl(u.right(), G.right())).tr()).tr() *
nv(G.left()).norm(),
254 mu * igrad(u.left(), G.left()) *
nv(G.left()).normalized() *
255 (igrad(u.left(), G.left()) *
nv(G.left()).normalized()).tr() *
nv(G.left()).norm(),
257 -mu * (igrad(u.left(), G.left()) *
nv(G.left()).normalized()) *
258 (igrad(u.right(), G.right()) *
nv(G.left()).normalized()).tr() *
nv(G.left()).norm(),
260 -mu * (igrad(u.right(), G.right()) *
nv(G.left()).normalized()) *
261 (igrad(u.left(), G.left()) *
nv(G.left()).normalized()).tr() *
nv(G.left()).norm(),
263 mu * igrad(u.right(), G.right()) *
nv(G.left()).normalized() *
264 (igrad(u.right(), G.right()) *
nv(G.left()).normalized()).tr() *
nv(G.left()).norm()
268 gsDebug<<
"Put here the terms for continuity 1\n";
275 void gsBiharmonicExprAssembler<T>::assembleRHS()
277 m_assembler.cleanUp();
282 geometryMap G = m_assembler.getMap(m_patches);
285 auto ff = m_assembler.getCoeff(*m_force, G);
288 auto u = m_assembler.trialSpace(0);
294 m_assembler.initVector(1);
297 m_assembler.assemble(u * ff *
meas(G));
300 auto g_L = m_assembler.getBdrFunction(G);
302 m_assembler.assembleBdr(m_bcs.get(
"Laplace"), (igrad(u, G) *
nv(G)) * g_L.tr() );
306 void gsBiharmonicExprAssembler<T>::assembleLHS()
308 m_assembler.cleanUp();
313 geometryMap G = m_assembler.getMap(m_patches);
316 auto u = m_assembler.trialSpace(0);
322 m_assembler.initMatrix();
325 m_assembler.assemble(ilapl(u, G) * ilapl(u, G).tr() *
meas(G));
330 gsMatrix<T> mu_interfaces;
332 _computeStabilityParameter(m_patches, m_basis, mu_interfaces);
335 for (
typename gsMultiPatch<T>::const_iiterator it = m_patches.iBegin(); it != m_patches.iEnd(); ++it, ++i)
337 T stab = 4 * ( m_basis.maxCwiseDegree() + m_basis.dim() ) * ( m_basis.maxCwiseDegree() + 1 );
338 T m_h = m_basis.basis(0).getMinCellLength();
339 T mu = 2 * stab / m_h;
344 mu = mu_interfaces(i,0) / m_h;
346 mu = m_penalty / m_h;
348 std::vector<boundaryInterface> iFace;
349 iFace.push_back(*it);
350 m_assembler.assembleIfc(iFace,
352 -alpha * 0.5 * igrad(u.left(), G) *
nv(G.left()).normalized() *
353 (ilapl(u.left(), G)).tr() *
nv(G.left()).norm(),
355 (igrad(u.left(), G) *
nv(G.left()).normalized() * (ilapl(u.left(), G)).tr()).tr() *
358 -alpha * 0.5 * igrad(u.left(), G.left()) *
nv(G.left()).normalized() *
359 (ilapl(u.right(), G.right())).tr() *
nv(G.left()).norm(),
360 -alpha * 0.5 * (igrad(u.left(), G.left()) *
nv(G.left()).normalized() *
361 (ilapl(u.right(), G.right())).tr()).tr() *
nv(G.left()).norm(),
363 alpha * 0.5 * igrad(u.right(), G.right()) *
nv(G.left()).normalized() *
364 (ilapl(u.left(), G.left())).tr() *
nv(G.left()).norm(),
365 alpha * 0.5 * (igrad(u.right(), G.right()) *
nv(G.left()).normalized() *
366 (ilapl(u.left(), G.left())).tr()).tr() *
nv(G.left()).norm(),
368 alpha * 0.5 * igrad(u.right(), G.right()) *
nv(G.left()).normalized() *
369 (ilapl(u.right(), G.right())).tr() *
nv(G.left()).norm(),
370 alpha * 0.5 * (igrad(u.right(), G.right()) *
nv(G.left()).normalized() *
371 (ilapl(u.right(), G.right())).tr()).tr() *
nv(G.left()).norm(),
374 mu * igrad(u.left(), G.left()) *
nv(G.left()).normalized() *
375 (igrad(u.left(), G.left()) *
nv(G.left()).normalized()).tr() *
nv(G.left()).norm(),
377 -mu * (igrad(u.left(), G.left()) *
nv(G.left()).normalized()) *
378 (igrad(u.right(), G.right()) *
nv(G.left()).normalized()).tr() *
nv(G.left()).norm(),
380 -mu * (igrad(u.right(), G.right()) *
nv(G.left()).normalized()) *
381 (igrad(u.left(), G.left()) *
nv(G.left()).normalized()).tr() *
nv(G.left()).norm(),
383 mu * igrad(u.right(), G.right()) *
nv(G.left()).normalized() *
384 (igrad(u.right(), G.right()) *
nv(G.left()).normalized()).tr() *
nv(G.left()).norm()
388 gsDebug<<
"Put here the terms for continuity 1\n";
394 void gsBiharmonicExprAssembler<T>::constructSolution(gsMatrix<T> & solVector)
396 auto u = m_assembler.trialSpace(0);
397 auto u_sol = m_assembler.getSolution(u, solVector);
399 if (
const gsMappedBasis<2,T> * bb2 =
dynamic_cast<const gsMappedBasis<2,T> *
>(m_spaceBasis))
401 u_sol.extract(m_mspline);
405 u_sol.extract(m_sol);
411 typename gsFunctionSet<T>::Ptr gsBiharmonicExprAssembler<T>::getSolution()
const
413 if (
const gsMappedBasis<2,T> * bb2 =
dynamic_cast<const gsMappedBasis<2,T> *
>(m_spaceBasis))
424 T gsBiharmonicExprAssembler<T>::l2error(gsMatrix<T> & solVector,
const gsFunctionSet<T> & exact)
426 auto u = m_assembler.trialSpace(0);
427 auto u_sol = m_assembler.getSolution(u, solVector);
428 geometryMap G = m_assembler.getMap(m_patches);
430 gsExprEvaluator<T> ev(m_assembler);
431 auto u_ex = ev.getVariable(exact, G);
433 T l2err= math::sqrt( ev.integral( (u_ex - u_sol).sqNorm() *
meas(G) ) );
438 T gsBiharmonicExprAssembler<T>::h1error(gsMatrix<T> & solVector,
const gsFunctionSet<T> & exact)
440 geometryMap G = m_assembler.getMap(m_patches);
441 auto u = m_assembler.trialSpace(0);
442 auto u_sol = m_assembler.getSolution(u, solVector);
444 gsExprEvaluator<T> ev(m_assembler);
445 auto u_ex = ev.getVariable(exact, G);
447 T l2err = math::sqrt( ev.integral( (u_ex - u_sol).sqNorm() *
meas(G) ) );
449 math::sqrt(ev.integral( ( igrad(u_ex) - igrad(u_sol,G) ).sqNorm() *
meas(G) ));
454 T gsBiharmonicExprAssembler<T>::h2error(gsMatrix<T> & solVector,
const gsFunctionSet<T> & exact)
456 geometryMap G = m_assembler.getMap(m_patches);
457 auto u = m_assembler.trialSpace(0);
458 auto u_sol = m_assembler.getSolution(u, solVector);
460 gsExprEvaluator<T> ev(m_assembler);
461 auto u_ex = ev.getVariable(exact, G);
463 T l2err = math::sqrt( ev.integral( (u_ex - u_sol).sqNorm() *
meas(G) ) );
465 math::sqrt(ev.integral( ( igrad(u_ex) - igrad(u_sol,G) ).sqNorm() *
meas(G) ));
467 math::sqrt(ev.integral( ( ihess(u_ex) - ihess(u_sol,G) ).sqNorm() *
meas(G) ));
473 std::tuple<T,T,T> gsBiharmonicExprAssembler<T>::errors(gsMatrix<T> & solVector,
const gsFunctionSet<T> & exact)
475 geometryMap G = m_assembler.getMap(m_patches);
476 auto u = m_assembler.trialSpace(0);
477 auto u_sol = m_assembler.getSolution(u, solVector);
479 gsExprEvaluator<T> ev(m_assembler);
480 auto u_ex = ev.getVariable(exact, G);
482 T l2err = math::sqrt( ev.integral( (u_ex - u_sol).sqNorm() *
meas(G) ) );
484 math::sqrt(ev.integral( ( igrad(u_ex) - igrad(u_sol,G) ).sqNorm() *
meas(G) ));
486 math::sqrt(ev.integral( ( ihess(u_ex) - ihess(u_sol,G) ).sqNorm() *
meas(G) ));
487 return std::make_tuple(l2err,h1err,h2err);
491 T gsBiharmonicExprAssembler<T>::interfaceError(gsMatrix<T> & solVector,
const gsFunctionSet<T> & exact)
494 if (
const gsMappedBasis<2,T> * bb2 =
dynamic_cast<const gsMappedBasis<2,T> *
>(m_spaceBasis))
496 geometryMap G = m_assembler.getMap(m_patches);
497 auto u = m_assembler.trialSpace(0);
498 auto u_sol = m_assembler.getSolution(u, solVector);
501 u_sol.extractFull(solFull);
502 gsMappedSpline<2, T> mappedSpline(*bb2, solFull);
504 auto ms_sol = m_assembler.getCoeff(mappedSpline);
506 gsExprEvaluator<T> ev(m_assembler);
507 T IFaceErr = math::sqrt(ev.integralInterface(((igrad(ms_sol.left(), G.left()) -
508 igrad(ms_sol.right(), G.right())) *
509 nv(G).normalized()).sqNorm() *
meas(G)));
515 geometryMap G = m_assembler.getMap(m_patches);
516 auto u = m_assembler.trialSpace(0);
517 auto u_sol = m_assembler.getSolution(u, solVector);
522 auto ms_sol = m_assembler.getCoeff(sol);
524 gsExprEvaluator<T> ev(m_assembler);
525 T IFaceErr = math::sqrt(ev.integralInterface(((igrad(ms_sol.left(), G.left()) -
526 igrad(ms_sol.right(), G.right())) *
527 nv(G).normalized()).sqNorm() *
meas(G)));
534 void gsBiharmonicExprAssembler<T>::setSpaceBasis(
const gsFunctionSet<T> & spaceBasis)
536 m_spaceBasis = &spaceBasis;
542 void gsBiharmonicExprAssembler<T>::_setMapperForBiharmonic(
const gsBoundaryConditions<T> & bc,
543 const gsFunctionSet<T> & spaceBasis,
544 gsDofMapper & mapper)
546 if (
const gsMappedBasis<2,T> * bb2 =
dynamic_cast<const gsMappedBasis<2,T> *
>(&spaceBasis))
548 mapper.setIdentity(bb2->nPatches(), bb2->size(), 1);
550 gsMatrix<index_t> bnd;
551 for (
typename gsBoundaryConditions<T>::const_iterator it = bc.begin(
"Dirichlet"); it != bc.end(
"Dirichlet"); ++it)
553 bnd = bb2->basis(it->ps.patch).boundary(it->ps.side());
554 mapper.markBoundary(it->ps.patch, bnd, 0);
557 for (
typename gsBoundaryConditions<T>::const_iterator it = bc.begin(
"Neumann"); it != bc.end(
"Neumann"); ++it)
559 bnd = bb2->basis(it->ps.patch).boundaryOffset(it->ps.side(),1);
560 mapper.markBoundary(it->ps.patch, bnd, 0);
564 else if (
const gsMultiBasis<T> * dbasis =
dynamic_cast<const gsMultiBasis<T> *
>(&spaceBasis))
566 mapper.init(*dbasis);
568 for (gsBoxTopology::const_iiterator it = dbasis->topology().iBegin();
569 it != dbasis->topology().iEnd(); ++it)
571 dbasis->matchInterface(*it, mapper);
574 gsMatrix<index_t> bnd;
575 for (
typename gsBoundaryConditions<T>::const_iterator
576 it = bc.begin(
"Dirichlet"); it != bc.end(
"Dirichlet"); ++it)
578 bnd = dbasis->basis(it->ps.patch).boundary(it->ps.side());
579 mapper.markBoundary(it->ps.patch, bnd, 0);
582 for (
typename gsBoundaryConditions<T>::const_iterator
583 it = bc.begin(
"Neumann"); it != bc.end(
"Neumann"); ++it)
585 bnd = dbasis->basis(it->ps.patch).boundaryOffset(it->ps.side(),1);
586 mapper.markBoundary(it->ps.patch, bnd, 0);
598 void gsBiharmonicExprAssembler<T>::_getDirichletNeumannValuesL2Projection(
599 const gsMultiPatch<T> & mp,
600 const gsMultiBasis<T> & dbasis,
601 const gsBoundaryConditions<T> & bc,
602 const gsFunctionSet<T> & spaceBasis,
603 const expr::gsFeSpace<T> & u
606 gsDebugVar(bc.dirichletSides().size());
607 gsDebugVar(bc.neumannSides().size());
609 if (bc.dirichletSides().size()==0 && bc.neumannSides().size()==0)
611 if (
const gsMappedBasis<2,T> * bb2 =
dynamic_cast<const gsMappedBasis<2,T> *
>(&spaceBasis))
613 const gsDofMapper & mapper = u.mapper();
615 gsMatrix<index_t> bnd = mapper.findFree(mapper.numPatches()-1);
616 gsDofMapper mapperBdy;
617 mapperBdy.setIdentity(bb2->nPatches(), bb2->size(), 1);
618 mapperBdy.markBoundary(0, bnd, 0);
619 mapperBdy.finalize();
621 gsExprAssembler<T> A(1,1);
622 A.setIntegrationElements(dbasis);
624 auto G = A.getMap(mp);
625 auto uu = A.getSpace(*bb2);
626 auto g_bdy = A.getBdrFunction(G);
628 uu.setupMapper(mapperBdy);
629 gsMatrix<T> & fixedDofs_A =
const_cast<expr::gsFeSpace<T>&
>(uu).fixedPart();
630 fixedDofs_A.setZero( uu.mapper().boundarySize(), 1 );
633 A.assembleBdr(bc.get(
"Dirichlet"), uu * uu.tr() *
meas(G));
634 A.assembleBdr(bc.get(
"Dirichlet"), uu * g_bdy *
meas(G));
635 A.assembleBdr(bc.get(
"Neumann"),m_lambda * (igrad(uu, G) *
nv(G).normalized()) * (igrad(uu, G) *
nv(G).normalized()).tr() *
meas(G));
636 A.assembleBdr(bc.get(
"Neumann"),m_lambda * (igrad(uu, G) *
nv(G).normalized()) * (g_bdy.tr() *
nv(G).normalized()) *
meas(G));
638 typename gsSparseSolver<T>::SimplicialLDLT solver;
639 solver.compute( A.matrix() );
640 gsMatrix<T> & fixedDofs =
const_cast<expr::gsFeSpace<T>&
>(u).fixedPart();
641 fixedDofs = solver.solve(A.rhs());
643 else if (
dynamic_cast<const gsMultiBasis<T> *
>(&spaceBasis))
645 gsDofMapper mapper = u.mapper();
646 gsDofMapper mapperBdy(dbasis, u.dim());
647 for (gsBoxTopology::const_iiterator it = dbasis.topology().iBegin();
648 it != dbasis.topology().iEnd(); ++it)
650 dbasis.matchInterface(*it, mapperBdy);
652 for (
index_t np = 0; np < mp.nPieces(); np++)
654 gsMatrix<index_t> bnd = mapper.findFree(np);
655 mapperBdy.markBoundary(np, bnd, 0);
657 mapperBdy.finalize();
659 gsExprAssembler<T> A(1,1);
660 A.setIntegrationElements(dbasis);
662 auto G = A.getMap(mp);
663 auto uu = A.getSpace(dbasis);
664 auto g_bdy = A.getBdrFunction(G);
666 uu.setupMapper(mapperBdy);
667 gsMatrix<T> & fixedDofs_A =
const_cast<expr::gsFeSpace<T>&
>(uu).fixedPart();
668 fixedDofs_A.setZero( uu.mapper().boundarySize(), 1 );
671 A.assembleBdr(bc.get(
"Dirichlet"), uu * uu.tr() *
meas(G));
672 A.assembleBdr(bc.get(
"Dirichlet"), uu * g_bdy *
meas(G));
673 A.assembleBdr(bc.get(
"Neumann"),
674 m_lambda * (igrad(uu, G) *
nv(G).normalized()) * (igrad(uu, G) *
nv(G).normalized()).tr() *
meas(G));
675 A.assembleBdr(bc.get(
"Neumann"),
676 m_lambda * (igrad(uu, G) *
nv(G).normalized()) * (g_bdy.tr() *
nv(G).normalized()) *
meas(G));
678 typename gsSparseSolver<T>::SimplicialLDLT solver;
679 solver.compute( A.matrix() );
680 gsMatrix<T> & fixedDofs =
const_cast<expr::gsFeSpace<T>&
>(u).fixedPart();
681 gsMatrix<T> fixedDofs_temp = solver.solve(A.rhs());
684 fixedDofs.setZero(mapper.boundarySize(),1);
686 for (
index_t np = 0; np < mp.nPieces(); np++)
688 gsMatrix<index_t> bnd = mapperBdy.findFree(np);
690 for (
index_t i = 0; i < bnd.rows(); i++)
692 index_t ii = mapperBdy.asVector()(bnd(i,0));
693 fixedDofs(mapper.global_to_bindex(mapper.asVector()(bnd(i,0))),0) = fixedDofs_temp(ii,0);
695 sz += mapperBdy.patchSize(np,0);
705 void gsBiharmonicExprAssembler<T>::_computeStabilityParameter(
706 const gsMultiPatch<T> & mp,
707 const gsMultiBasis<T> & dbasis,
708 gsMatrix<T> & mu_interfaces)
710 mu_interfaces.setZero(mp.nInterfaces(),1);
713 for (
typename gsMultiPatch<T>::const_iiterator it = mp.iBegin(); it != mp.iEnd(); ++it, ++i)
715 gsMultiPatch<T> mp_temp;
716 mp_temp.addPatch(mp.patch(it->first().patch));
717 mp_temp.addPatch(mp.patch(it->second().patch));
718 mp_temp.computeTopology();
720 gsMultiBasis<T> dbasis_temp;
721 dbasis_temp.addBasis(dbasis.basis(it->first().patch).clone().release());
722 dbasis_temp.addBasis(dbasis.basis(it->second().patch).clone().release());
724 gsBoundaryConditions<T> bc;
737 for (
typename gsMultiPatch<T>::const_biterator bit = mp_temp.bBegin(); bit != mp_temp.bEnd(); ++bit)
740 gsExprAssembler<T> A2(1, 1), B2(1, 1);
743 A2.setIntegrationElements(dbasis_temp);
744 B2.setIntegrationElements(dbasis_temp);
747 auto GA = A2.getMap(mp_temp);
748 auto GB = B2.getMap(mp_temp);
751 auto uA = A2.getSpace(dbasis_temp);
752 auto uB = B2.getSpace(dbasis_temp);
754 uA.setup(bc, dirichlet::homogeneous, 0);
755 uB.setup(bc, dirichlet::homogeneous,0);
763 A2.assembleIfc(mp_temp.interfaces(),
764 c * ilapl(uA.left(), GA.left()) * ilapl(uA.left(), GA.left()).tr() *
nv(GA.left()).norm(),
765 c * ilapl(uA.left(), GA.left()) * ilapl(uA.right(), GA.right()).tr() *
nv(GA.left()).norm(),
766 c * ilapl(uA.right(), GA.right()) * ilapl(uA.left(), GA.left()).tr() *
nv(GA.left()).norm(),
767 c * ilapl(uA.right(), GA.right()) * ilapl(uA.right(), GA.right()).tr() *
nv(GA.left()).norm());
769 B2.assemble(ilapl(uB, GB) * ilapl(uB, GB).tr() *
meas(GB));
772 gsMatrix<T> AA = A2.matrix().toDense();
773 gsMatrix<T> BB = B2.matrix().toDense();
775 #ifdef gsSpectra_ENABLED
776 gsSpectraGenSymSolver<gsSparseMatrix<T>,Spectra::GEigsMode::Cholesky> ges(A2.matrix(),B2.matrix(),1,10);
777 ges.compute(Spectra::SortRule::LargestMagn,1000,1e-6,Spectra::SortRule::LargestMagn);
778 T maxEV = ges.eigenvalues()(0,0);
780 gsEigen::GeneralizedSelfAdjointEigenSolver<typename gsMatrix<T>::Base > ges(AA, BB);
781 T maxEV = ges.eigenvalues().array().maxCoeff();
783 T m_h = dbasis_temp.basis(0).getMinCellLength();
784 mu_interfaces(i,0) = 16.0 * m_h * maxEV;
shared_ptr< T > make_shared_not_owned(const T *x)
Creates a shared pointer which does not eventually delete the underlying raw pointer. Usefull to refer to objects which should not be destroyed.
Definition: gsMemory.h:189
Provides declaration of FunctionExpr class.
Dirichlet type.
Definition: gsBoundaryConditions.h:31
#define gsDebug
Definition: gsDebug.h:61
Provides declaration of Basis abstract interface.
S give(S &x)
Definition: gsMemory.h:266
#define index_t
Definition: gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
Provides declaration of Basis abstract interface.
EIGEN_STRONG_INLINE onormal_expr< T > nv(const gsGeometryMap< T > &u)
The (outer pointing) boundary normal of a geometry map.
Definition: gsExpressions.h:4506
Provides declaration of a gsPiecewiseFunction class.
Provides declaration of Basis abstract interface.
Provides assembler for a (planar) Biharmonic equation.
Header file for using Spectra extension.
#define GISMO_UNUSED(x)
Definition: gsDebug.h:112
Provides gsBoundaryConditions class.
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
EIGEN_STRONG_INLINE meas_expr< T > meas(const gsGeometryMap< T > &G)
The measure of a geometry map.
Definition: gsExpressions.h:4555