📄 ex14.php
字号:
<pre> const std::vector<std::vector<RealGradient> >& dphi = fe->get_dphi(); </pre></div><div class = "comment">The XY locations of the quadrature points used for face integration</div><div class ="fragment"><pre> const std::vector<Point>& qface_points = fe_face->get_xyz(); </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". More detail is in example 3.</div><div class ="fragment"><pre> DenseMatrix<Number> Ke; DenseVector<Number> 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; </pre></div><div class = "comment">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. Here we usethe \p const_active_local_elem_iterator to indicate we only wantto loop over elements that are assigned to the local processorwhich are "active" in the sense of AMR. This allows eachprocessor to compute its components of the global matrix foractive elements while ignoring parent elements which have beenrefined.</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. 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 (dof_indices.size(), dof_indices.size()); Fe.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 the test funcions (i) againstthe trial functions (j).<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<dphi.size(); i++) for (unsigned int j=0; j<dphi.size(); j++) Ke(i,j) += JxW[qp]*(dphi[i][qp]*dphi[j][qp]); </pre></div><div class = "comment">We need a forcing function to make the 1D case interesting</div><div class ="fragment"><pre> if (dim == 1) for (unsigned int qp=0; qp<qrule->n_points(); qp++) { Real x = q_point[qp](0); Real f = singularity ? sqrt(3.)/9.*pow(-x, -4./3.) : cos(x); for (unsigned int i=0; i<dphi.size(); ++i) Fe(i) += JxW[qp]*phi[i][qp]*f; } </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.<br><br>This approach adds the L2 projection of the boundarydata in penalty form to the weak statement. This isa more generic approach for applying Dirichlet BCswhich is applicable to non-Lagrange finite elementdiscretizations.</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 value. </div><div class ="fragment"><pre> const Real penalty = 1.e10; </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) { fe_face->reinit(elem,s); for (unsigned int qp=0; qp<qface->n_points(); qp++) { const Number value = exact_solution (qface_points[qp], es.parameters, "null", "void"); </pre></div><div class = "comment">RHS contribution</div><div class ="fragment"><pre> for (unsigned int i=0; i<psi.size(); i++) Fe(i) += penalty*JxW_face[qp]*value*psi[i][qp]; </pre></div><div class = "comment">Matrix contribution</div><div class ="fragment"><pre> for (unsigned int i=0; i<psi.size(); i++) for (unsigned int j=0; j<psi.size(); j++) Ke(i,j) += penalty*JxW_face[qp]*psi[i][qp]*psi[j][qp]; } } </pre></div><div class = "comment">Stop logging the boundary condition computation</div><div class ="fragment"><pre> perf_log.stop_event ("BCs"); } </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">Start 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?</div><div class ="fragment"><pre> #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">"tecplot_io.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"fe.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"quadrature_gauss.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_refinement.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"error_vector.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"exact_error_estimator.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"kelly_error_estimator.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"patch_recovery_error_estimator.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"uniform_refinement_estimator.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"hp_coarsentest.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"hp_singular.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">"getpot.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"exact_solution.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"dof_map.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"numeric_vector.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"elem.h"</FONT></B> #include <B><FONT COLOR="#BC8F8F">"string_to_enum.h"</FONT></B> <B><FONT COLOR="#228B22">void</FONT></B> assemble_laplace(EquationSystems& es, <B><FONT COLOR="#228B22">const</FONT></B> std::string& system_name); Number exact_solution(<B><FONT COLOR="#228B22">const</FONT></B> Point& p, <B><FONT COLOR="#228B22">const</FONT></B> Parameters&, <I><FONT COLOR="#B22222">// EquationSystem parameters, not needed</FONT></I> <B><FONT COLOR="#228B22">const</FONT></B> std::string&, <I><FONT COLOR="#B22222">// sys_name, not needed</FONT></I> <B><FONT COLOR="#228B22">const</FONT></B> std::string&); <I><FONT COLOR="#B22222">// unk_name, not needed);</FONT></I> Gradient exact_derivative(<B><FONT COLOR="#228B22">const</FONT></B> Point& p, <B><FONT COLOR="#228B22">const</FONT></B> Parameters&, <I><FONT COLOR="#B22222">// EquationSystems parameters, not needed</FONT></I> <B><FONT COLOR="#228B22">const</FONT></B> std::string&, <I><FONT COLOR="#B22222">// sys_name, not needed</FONT></I> <B><FONT COLOR="#228B22">const</FONT></B> std::string&); <I><FONT COLOR="#B22222">// unk_name, not needed);</FONT></I> <B><FONT COLOR="#228B22">unsigned</FONT></B> <B><FONT COLOR="#228B22">int</FONT></B> dim = 2; <B><FONT COLOR="#228B22">bool</FONT></B> singularity = true; <B><FONT COLOR="#228B22">int</FONT></B> main(<B><FONT COLOR="#228B22">int</FONT></B> argc, <B><FONT COLOR="#228B22">char</FONT></B>** argv) { <B><FONT COLOR="#5F9EA0">libMesh</FONT></B>::init (argc, argv); #ifndef ENABLE_AMR <B><FONT COLOR="#5F9EA0">std</FONT></B>::cerr << <B><FONT COLOR="#BC8F8F">"ERROR: This example requires libMesh to be\n"</FONT></B> << <B><FONT COLOR="#BC8F8F">"compiled with AMR support!"</FONT></B> << std::endl; <B><FONT COLOR="#A020F0">return</FONT></B> 0; #<B><FONT COLOR="#A020F0">else</FONT></B> { GetPot input_file(<B><FONT COLOR="#BC8F8F">"ex14.in"</FONT></B>); <B><FONT COLOR="#228B22">const</FONT></B> <B><FONT COLOR="#228B22">unsigned</FONT></B> <B><FONT COLOR="#228B22">int</FONT></B> max_r_steps = input_file(<B><FONT COLOR="#BC8F8F">"max_r_steps"</FONT></B>, 3);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -