22 class gsBiharmonicAssembler2
27 gsBiharmonicAssembler2() { };
29 gsBiharmonicAssembler2(gsMultiPatch<T> & mp,
31 bool & second =
false)
34 gsFunctionExpr<>source(
"1*pi*pi*pi*pi*(4*cos(1*pi*x)*cos(1*pi*y) - cos(1*pi*x) - cos(1*pi*y))",2);
36 gsInfo <<
"Source function " << m_f <<
"\n";
38 gsFunctionExpr<> solution(
"(cos(1*pi*x) - 1) * (cos(1*pi*y) - 1)",2);
40 gsInfo <<
"Exact function " << m_ms <<
"\n";
42 gsBoundaryConditions<> bc;
43 for (gsMultiPatch<>::const_biterator bit = mp.bBegin(); bit != mp.bEnd(); ++bit)
46 gsFunctionExpr<> laplace (
"-1*pi*pi*(2*cos(1*pi*x)*cos(1*pi*y) - cos(1*pi*x) - cos(1*pi*y))",2);
49 gsFunctionExpr<> sol1der(
"-1*pi*(cos(1*pi*y) - 1)*sin(1*pi*x)",
50 "-1*pi*(cos(1*pi*x) - 1)*sin(1*pi*y)", 2);
60 gsInfo <<
"Boundary conditions:\n" << m_bc <<
"\n";
63 gsBiharmonicAssembler2(gsMultiPatch<T> & mp,
65 const gsBoundaryConditions<T> & bc,
66 const gsFunctionExpr<T> & f,
67 const gsFunctionExpr<T> & ms)
68 : m_mp(mp), m_mb(mb), m_bc(bc), m_f(f), m_ms(ms)
79 m_A = gsExprAssembler<real_t>(1,1);
82 m_A.setIntegrationElements(m_mb);
83 m_ev = gsExprEvaluator<real_t>(m_A);
86 void assemble(gsMappedBasis<2,T> & bb2)
89 auto G = m_A.getMap(m_mp);
92 auto ff = m_A.getCoeff(m_f, G);
95 auto u = m_A.getSpace(bb2);
98 gsMatrix<real_t> solVector;
99 auto u_sol = m_A.getSolution(u, solVector);
103 setMapperForBiharmonic(m_bc, bb2, map);
107 gsDirichletNeumannValuesL2Projection(m_mp, m_mb, m_bc, bb2, u);
113 m_A.assemble(ilapl(u, G) * ilapl(u, G).tr() *
meas(G),u * ff *
meas(G));
116 auto g_L = m_A.getBdrFunction(G);
118 m_A.assembleBdr(m_bc.get(
"Laplace"), (igrad(u, G) *
nv(G)) * g_L.tr() );
123 gsSparseSolver<real_t>::SimplicialLDLT solver;
124 solver.compute( m_A.matrix() );
125 m_solVector = solver.solve(m_A.rhs());
128 void computeError(gsMappedBasis<2,T> & bb2,
134 auto G = m_A.getMap(m_mp);
136 auto u = m_A.getSpace(bb2);
137 auto u_sol = m_A.getSolution(u, m_solVector);
140 auto u_ex = m_ev.getVariable(m_ms, G);
142 l2err = math::sqrt( m_ev.integral( (u_ex - u_sol).sqNorm() *
meas(G) ) );
143 h1err = l2err + math::sqrt(m_ev.integral( ( igrad(u_ex) - igrad(u_sol,G) ).sqNorm() *
meas(G) ));
144 h2err = h1err + math::sqrt(m_ev.integral( ( ihess(u_ex) - ihess(u_sol,G) ).sqNorm() *
meas(G) ));
147 T numDofs() {
return m_A.numDofs(); };
151 void setMapperForBiharmonic(gsBoundaryConditions<> & bc, gsMappedBasis<2,real_t> & bb2, gsDofMapper & mapper)
153 mapper.setIdentity(bb2.nPatches(), bb2.size(), 1);
155 gsMatrix<index_t> bnd;
156 for (
typename gsBoundaryConditions<real_t>::const_iterator
157 it = bc.begin(
"Dirichlet"); it != bc.end(
"Dirichlet"); ++it)
159 bnd = bb2.basis(it->ps.patch).boundary(it->ps.side());
160 mapper.markBoundary(it->ps.patch, bnd, 0);
163 for (
typename gsBoundaryConditions<real_t>::const_iterator
164 it = bc.begin(
"Neumann"); it != bc.end(
"Neumann"); ++it)
166 bnd = bb2.basis(it->ps.patch).boundaryOffset(it->ps.side(),1);
167 mapper.markBoundary(it->ps.patch, bnd, 0);
172 void gsDirichletNeumannValuesL2Projection(gsMultiPatch<> & mp,
173 gsMultiBasis<> & dbasis,
174 gsBoundaryConditions<> & bc,
175 gsMappedBasis<2,real_t> & bb2,
176 const expr::gsFeSpace<real_t> & u)
178 const gsDofMapper & mapper = u.mapper();
180 gsMatrix<index_t> bnd = mapper.findFree(mapper.numPatches()-1);
181 gsDofMapper mapperBdy;
182 mapperBdy.setIdentity(bb2.nPatches(), bb2.size(), 1);
183 mapperBdy.markBoundary(0, bnd, 0);
184 mapperBdy.finalize();
186 gsExprAssembler<real_t> A(1,1);
187 A.setIntegrationElements(dbasis);
189 auto G = A.getMap(mp);
190 auto uu = A.getSpace(bb2);
191 auto g_bdy = A.getBdrFunction(G);
193 uu.setupMapper(mapperBdy);
194 gsMatrix<real_t> & fixedDofs_A =
const_cast<expr::gsFeSpace<real_t>&
>(uu).fixedPart();
195 fixedDofs_A.setZero( uu.mapper().boundarySize(), 1 );
197 real_t lambda = 1e-5;
200 A.assembleBdr(bc.get(
"Dirichlet"), uu * uu.tr() *
meas(G));
201 A.assembleBdr(bc.get(
"Dirichlet"), uu * g_bdy *
meas(G));
202 A.assembleBdr(bc.get(
"Neumann"),
203 lambda * (igrad(uu, G) *
nv(G).normalized()) *
204 (igrad(uu, G) *
nv(G).normalized()).tr() *
meas(G));
205 A.assembleBdr(bc.get(
"Neumann"),
206 lambda * (igrad(uu, G) *
nv(G).normalized()) * (g_bdy.tr() *
nv(G).normalized()) *
meas(G));
208 gsSparseSolver<real_t>::SimplicialLDLT solver;
209 solver.compute( A.matrix() );
210 gsMatrix<real_t> & fixedDofs =
const_cast<expr::gsFeSpace<real_t>&
>(u).fixedPart();
211 fixedDofs = solver.solve(A.rhs());
216 gsMultiPatch<T> & m_mp;
217 gsMultiBasis<T> & m_mb;
219 gsBoundaryConditions<T> m_bc;
220 gsFunctionExpr<T> m_f;
221 gsFunctionExpr<T> m_ms;
223 gsExprAssembler<T> m_A;
224 gsExprEvaluator<T> m_ev;
226 gsMatrix<T> m_solVector;
Neumann type.
Definition: gsBoundaryConditions.h:33
Laplace type, e.g. u = g.
Definition: gsBoundaryConditions.h:38
Dirichlet type.
Definition: gsBoundaryConditions.h:31
Generic expressions helper.
EIGEN_STRONG_INLINE onormal_expr< T > nv(const gsGeometryMap< T > &u)
The (outer pointing) boundary normal of a geometry map.
Definition: gsExpressions.h:4506
#define gsInfo
Definition: gsDebug.h:43
EIGEN_STRONG_INLINE meas_expr< T > meas(const gsGeometryMap< T > &G)
The measure of a geometry map.
Definition: gsExpressions.h:4555