📄 ex11.php
字号:
</div><div class ="fragment"><pre> QGauss qrule (dim, fe_vel_type.default_quadrature_order()); </pre></div><div class = "comment">Tell the finite element objects to use our quadrature rule.</div><div class ="fragment"><pre> fe_vel->attach_quadrature_rule (&qrule); fe_pres->attach_quadrature_rule (&qrule); </pre></div><div class = "comment">Here we define some references to cell-specific data thatwill be used to assemble the linear system.<br><br>The element Jacobian * quadrature weight at each integration point. </div><div class ="fragment"><pre> const std::vector<Real>& JxW = fe_vel->get_JxW(); </pre></div><div class = "comment">The element shape function gradients for the velocityvariables evaluated at the quadrature points.</div><div class ="fragment"><pre> const std::vector<std::vector<RealGradient> >& dphi = fe_vel->get_dphi(); </pre></div><div class = "comment">The element shape functions for the pressure variableevaluated at the quadrature points.</div><div class ="fragment"><pre> const std::vector<std::vector<Real> >& psi = fe_pres->get_phi(); </pre></div><div class = "comment">A reference to the \p DofMap object for this system. The \p DofMapobject handles the index translation from node and element numbersto degree of freedom numbers. We will talk more about the \p DofMapin future examples.</div><div class ="fragment"><pre> const DofMap & dof_map = system.get_dof_map(); </pre></div><div class = "comment">Define data structures to contain the element matrixand right-hand-side vector contribution. Followingbasic finite element terminology we will denote these"Ke" and "Fe".</div><div class ="fragment"><pre> DenseMatrix<Number> Ke; DenseVector<Number> Fe; DenseSubMatrix<Number> Kuu(Ke), Kuv(Ke), Kup(Ke), Kvu(Ke), Kvv(Ke), Kvp(Ke), Kpu(Ke), Kpv(Ke), Kpp(Ke); DenseSubVector<Number> Fu(Fe), Fv(Fe), Fp(Fe); </pre></div><div class = "comment">This vector will hold the degree of freedom indices forthe element. These define where in the global systemthe element degrees of freedom get mapped.</div><div class ="fragment"><pre> std::vector<unsigned int> dof_indices; std::vector<unsigned int> dof_indices_u; std::vector<unsigned int> dof_indices_v; std::vector<unsigned int> dof_indices_p; </pre></div><div class = "comment">Now we will loop over all the elements in the mesh thatlive on the local processor. We will compute the elementmatrix and right-hand-side contribution. Since the meshwill be refined we want to only consider the ACTIVE elements,hence we use a variant of the \p active_elem_iterator.const_active_local_elem_iterator el (mesh.elements_begin());const const_active_local_elem_iterator end_el (mesh.elements_end());<br><br></div><div class ="fragment"><pre> MeshBase::const_element_iterator el = mesh.active_local_elements_begin(); const MeshBase::const_element_iterator end_el = mesh.active_local_elements_end(); for ( ; el != end_el; ++el) { </pre></div><div class = "comment">Store a pointer to the element we are currentlyworking on. This allows for nicer syntax later.</div><div class ="fragment"><pre> const Elem* elem = *el; </pre></div><div class = "comment">Get the degree of freedom indices for thecurrent element. These define where in the globalmatrix and right-hand-side this element willcontribute to.</div><div class ="fragment"><pre> dof_map.dof_indices (elem, dof_indices); dof_map.dof_indices (elem, dof_indices_u, u_var); dof_map.dof_indices (elem, dof_indices_v, v_var); dof_map.dof_indices (elem, dof_indices_p, p_var); const unsigned int n_dofs = dof_indices.size(); const unsigned int n_u_dofs = dof_indices_u.size(); const unsigned int n_v_dofs = dof_indices_v.size(); const unsigned int n_p_dofs = dof_indices_p.size(); </pre></div><div class = "comment">Compute the element-specific data for the currentelement. This involves computing the location of thequadrature points (q_point) and the shape functions(phi, dphi) for the current element.</div><div class ="fragment"><pre> fe_vel->reinit (elem); fe_pres->reinit (elem); </pre></div><div class = "comment">Zero the element matrix and right-hand side beforesumming them. We use the resize member here becausethe number of degrees of freedom might have changed fromthe last element. Note that this will be the case if theelement type is different (i.e. the last element was atriangle, now we are on a quadrilateral).</div><div class ="fragment"><pre> Ke.resize (n_dofs, n_dofs); Fe.resize (n_dofs); </pre></div><div class = "comment">Reposition the submatrices... The idea is this:<br><br>- - - -| Kuu Kuv Kup | | Fu |Ke = | Kvu Kvv Kvp |; Fe = | Fv || Kpu Kpv Kpp | | Fp |- - - -<br><br>The \p DenseSubMatrix.repostition () member takes the(row_offset, column_offset, row_size, column_size).<br><br>Similarly, the \p DenseSubVector.reposition () membertakes the (row_offset, row_size)</div><div class ="fragment"><pre> Kuu.reposition (u_var*n_u_dofs, u_var*n_u_dofs, n_u_dofs, n_u_dofs); Kuv.reposition (u_var*n_u_dofs, v_var*n_u_dofs, n_u_dofs, n_v_dofs); Kup.reposition (u_var*n_u_dofs, p_var*n_u_dofs, n_u_dofs, n_p_dofs); Kvu.reposition (v_var*n_v_dofs, u_var*n_v_dofs, n_v_dofs, n_u_dofs); Kvv.reposition (v_var*n_v_dofs, v_var*n_v_dofs, n_v_dofs, n_v_dofs); Kvp.reposition (v_var*n_v_dofs, p_var*n_v_dofs, n_v_dofs, n_p_dofs); Kpu.reposition (p_var*n_u_dofs, u_var*n_u_dofs, n_p_dofs, n_u_dofs); Kpv.reposition (p_var*n_u_dofs, v_var*n_u_dofs, n_p_dofs, n_v_dofs); Kpp.reposition (p_var*n_u_dofs, p_var*n_u_dofs, n_p_dofs, n_p_dofs); Fu.reposition (u_var*n_u_dofs, n_u_dofs); Fv.reposition (v_var*n_u_dofs, n_v_dofs); Fp.reposition (p_var*n_u_dofs, n_p_dofs); </pre></div><div class = "comment">Now we will build the element matrix.</div><div class ="fragment"><pre> for (unsigned int qp=0; qp<qrule.n_points(); qp++) {</pre></div><div class = "comment">Assemble the u-velocity rowuu coupling</div><div class ="fragment"><pre> for (unsigned int i=0; i<n_u_dofs; i++) for (unsigned int j=0; j<n_u_dofs; j++) Kuu(i,j) += JxW[qp]*(dphi[i][qp]*dphi[j][qp]); </pre></div><div class = "comment">up coupling</div><div class ="fragment"><pre> for (unsigned int i=0; i<n_u_dofs; i++) for (unsigned int j=0; j<n_p_dofs; j++) Kup(i,j) += -JxW[qp]*psi[j][qp]*dphi[i][qp](0); </pre></div><div class = "comment">Assemble the v-velocity rowvv coupling</div><div class ="fragment"><pre> for (unsigned int i=0; i<n_v_dofs; i++) for (unsigned int j=0; j<n_v_dofs; j++) Kvv(i,j) += JxW[qp]*(dphi[i][qp]*dphi[j][qp]); </pre></div><div class = "comment">vp coupling</div><div class ="fragment"><pre> for (unsigned int i=0; i<n_v_dofs; i++) for (unsigned int j=0; j<n_p_dofs; j++) Kvp(i,j) += -JxW[qp]*psi[j][qp]*dphi[i][qp](1); </pre></div><div class = "comment">Assemble the pressure rowpu coupling</div><div class ="fragment"><pre> for (unsigned int i=0; i<n_p_dofs; i++) for (unsigned int j=0; j<n_u_dofs; j++) Kpu(i,j) += -JxW[qp]*psi[i][qp]*dphi[j][qp](0); </pre></div><div class = "comment">pv coupling</div><div class ="fragment"><pre> for (unsigned int i=0; i<n_p_dofs; i++) for (unsigned int j=0; j<n_v_dofs; j++) Kpv(i,j) += -JxW[qp]*psi[i][qp]*dphi[j][qp](1); } // end of the quadrature point qp-loop </pre></div><div class = "comment">At this point the interior element integration hasbeen completed. However, we have not yet addressedboundary conditions. For this example we will onlyconsider simple Dirichlet boundary conditions imposedvia the penalty method. The penalty method used hereis equivalent (for Lagrange basis functions) to lumpingthe matrix resulting from the L2 projection penaltyapproach introduced in example 3.</div><div class ="fragment"><pre> {</pre></div><div class = "comment">The following loops over the sides of the element.If the element has no neighbor on a side then thatside MUST live on a boundary of the domain.</div><div class ="fragment"><pre> for (unsigned int s=0; s<elem->n_sides(); s++) if (elem->neighbor(s) == NULL) { AutoPtr<Elem> side (elem->build_side(s)); </pre></div><div class = "comment">Loop over the nodes on the side.</div><div class ="fragment"><pre> for (unsigned int ns=0; ns<side->n_nodes(); ns++) {</pre></div><div class = "comment">The location on the boundary of the currentnode. <br><br></div><div class ="fragment"><pre> const Real xf = side->point(ns)(0); const Real yf = side->point(ns)(1); </pre></div><div class = "comment">The penalty value. \f$ \frac{1}{\epsilon \f$</div><div class ="fragment"><pre> const Real penalty = 1.e10;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -