📄 ex15.php
字号:
Now we will loop over all the elements in the mesh. We willcompute the element matrix and right-hand-side contribution. Seeexample 3 for a discussion of the element iterators.<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">Start logging the shape function initialization.This is done through a simple function call withthe name of the event to log.</div><div class ="fragment"><pre> perf_log.start_event("elem init"); </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); </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->reinit (elem); </pre></div><div class = "comment">Zero the element matrix and right-hand side beforesumming them.</div><div class ="fragment"><pre> Ke.resize (dof_indices.size(), dof_indices.size()); Fe.resize (dof_indices.size()); </pre></div><div class = "comment">Make sure there is enough room in this cache</div><div class ="fragment"><pre> shape_laplacian.resize(dof_indices.size()); </pre></div><div class = "comment">Stop logging the shape function initialization.If you forget to stop logging an event the PerfLogobject will probably catch the error and abort.</div><div class ="fragment"><pre> perf_log.stop_event("elem init"); </pre></div><div class = "comment">Now we will build the element matrix. This involvesa double loop to integrate laplacians of the test funcions(i) against laplacians of the trial functions (j).<br><br>This step is why we need the Clough-Tocher elements -these C1 differentiable elements have square-integrablesecond derivatives.<br><br>Now start logging the element matrix computation</div><div class ="fragment"><pre> perf_log.start_event ("Ke"); for (unsigned int qp=0; qp<qrule->n_points(); qp++) { for (unsigned int i=0; i<phi.size(); i++) { shape_laplacian[i] = d2phi[i][qp](0,0)+d2phi[i][qp](1,1); if (dim == 3) shape_laplacian[i] += d2phi[i][qp](2,2); } for (unsigned int i=0; i<phi.size(); i++) for (unsigned int j=0; j<phi.size(); j++) Ke(i,j) += JxW[qp]* shape_laplacian[i]*shape_laplacian[j]; } </pre></div><div class = "comment">Stop logging the matrix computation</div><div class ="fragment"><pre> perf_log.stop_event ("Ke"); </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. Note that this is a fourth-orderproblem: Dirichlet boundary conditions include *both*boundary values and boundary normal fluxes.</div><div class ="fragment"><pre> {</pre></div><div class = "comment">Start logging the boundary condition computation</div><div class ="fragment"><pre> perf_log.start_event ("BCs"); </pre></div><div class = "comment">The penalty values, for solution boundary trace and flux. </div><div class ="fragment"><pre> const Real penalty = 1e10; const Real penalty2 = 1e10; </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) {</pre></div><div class = "comment">The value of the shape functions at the quadraturepoints.</div><div class ="fragment"><pre> const std::vector<std::vector<Real> >& phi_face = fe_face->get_phi(); </pre></div><div class = "comment">The value of the shape function derivatives at thequadrature points.</div><div class ="fragment"><pre> const std::vector<std::vector<RealGradient> >& dphi_face = fe_face->get_dphi(); </pre></div><div class = "comment">The Jacobian * Quadrature Weight at the quadraturepoints on the face.</div><div class ="fragment"><pre> const std::vector<Real>& JxW_face = fe_face->get_JxW(); </pre></div><div class = "comment">The XYZ locations (in physical space) of thequadrature points on the face. This is wherewe will interpolate the boundary value function.</div><div class ="fragment"><pre> const std::vector<Point>& qface_point = fe_face->get_xyz(); const std::vector<Point>& face_normals = fe_face->get_normals(); </pre></div><div class = "comment">Compute the shape function values on the elementface.</div><div class ="fragment"><pre> fe_face->reinit(elem, s); </pre></div><div class = "comment">Loop over the face quagrature points for integration.</div><div class ="fragment"><pre> for (unsigned int qp=0; qp<qface->n_points(); qp++) {</pre></div><div class = "comment">The boundary value.</div><div class ="fragment"><pre> Number value = exact_solution(qface_point[qp], es.parameters, "null", "void"); Gradient flux = exact_2D_derivative(qface_point[qp], es.parameters, "null", "void"); </pre></div><div class = "comment">Matrix contribution of the L2 projection.Note that the basis function values areintegrated against test function values whilebasis fluxes are integrated against test functionfluxes.</div><div class ="fragment"><pre> for (unsigned int i=0; i<phi_face.size(); i++) for (unsigned int j=0; j<phi_face.size(); j++) Ke(i,j) += JxW_face[qp] * (penalty * phi_face[i][qp] * phi_face[j][qp] + penalty2 * (dphi_face[i][qp] * face_normals[qp]) * (dphi_face[j][qp] * face_normals[qp])); </pre></div><div class = "comment">Right-hand-side contribution of the L2projection.</div><div class ="fragment"><pre> for (unsigned int i=0; i<phi_face.size(); i++) Fe(i) += JxW_face[qp] * (penalty * value * phi_face[i][qp] + penalty2 * (flux * face_normals[qp]) * (dphi_face[i][qp] * face_normals[qp])); } } </pre></div><div class = "comment">Stop logging the boundary condition computation</div><div class ="fragment"><pre> perf_log.stop_event ("BCs"); } for (unsigned int qp=0; qp<qrule->n_points(); qp++) for (unsigned int i=0; i<phi.size(); i++) Fe(i) += JxW[qp]*phi[i][qp]*forcing_function(q_point[qp]); </pre></div><div class = "comment">The element matrix and right-hand-side are now builtfor this element. Add them to the global matrix andright-hand-side vector. The \p PetscMatrix::add_matrix()and \p PetscVector::add_vector() members do this for us.Start logging the insertion of the local (element)matrix and vector into the global matrix and vector</div><div class ="fragment"><pre> perf_log.start_event ("matrix insertion"); dof_map.constrain_element_matrix_and_vector(Ke, Fe, dof_indices); system.matrix->add_matrix (Ke, dof_indices); system.rhs->add_vector (Fe, dof_indices); </pre></div><div class = "comment">Stop logging the insertion of the local (element)matrix and vector into the global matrix and vector</div><div class ="fragment"><pre> perf_log.stop_event ("matrix insertion"); } </pre></div><div class = "comment">That's it. We don't need to do anything else to thePerfLog. When it goes out of scope (at this function return)it will print its log to the screen. Pretty easy, huh?<br><br></div><div class ="fragment"><pre> #else #endif // #ifdef ENABLE_SECOND_DERIVATIVES #endif // #ifdef ENABLE_AMR }</pre></div><a name="nocomments"></a> <br><br><br> <h1> The program without comments: </h1> <pre> #include <B><FONT COLOR="#BC8F8F">"mesh.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"equation_systems.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"linear_implicit_system.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"gmv_io.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"fe.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"quadrature.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"dense_matrix.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"dense_vector.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"sparse_matrix.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"mesh_generation.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"mesh_modification.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"mesh_refinement.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"error_vector.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"fourth_error_estimators.h"</FONT></B>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -