📄 ex14.php
字号:
All done. </div><div class ="fragment"><pre> return libMesh::close (); } </pre></div><div class = "comment">We now define the exact solution, being carefulto obtain an angle from atan2 in the correctquadrant.</div><div class ="fragment"><pre> Number exact_solution(const Point& p, const Parameters&, // parameters, not needed const std::string&, // sys_name, not needed const std::string&) // unk_name, not needed { const Real x = p(0); const Real y = (dim > 1) ? p(1) : 0.; if (singularity) {</pre></div><div class = "comment">The exact solution to the singular problem,u_exact = r^(2/3)*sin(2*theta/3).</div><div class ="fragment"><pre> Real theta = atan2(y,x); </pre></div><div class = "comment">Make sure 0 <= theta <= 2*pi</div><div class ="fragment"><pre> if (theta < 0) theta += 2. * libMesh::pi; </pre></div><div class = "comment">Make the 3D solution similar</div><div class ="fragment"><pre> const Real z = (dim > 2) ? p(2) : 0; return pow(x*x + y*y, 1./3.)*sin(2./3.*theta) + z; } else {</pre></div><div class = "comment">The exact solution to a nonsingular problem,good for testing ideal convergence rates</div><div class ="fragment"><pre> const Real z = (dim > 2) ? p(2) : 0; return cos(x) * exp(y) * (1. - z); } } </pre></div><div class = "comment">We now define the gradient of the exact solution, again being carefulto obtain an angle from atan2 in the correctquadrant.</div><div class ="fragment"><pre> Gradient exact_derivative(const Point& p, const Parameters&, // parameters, not needed const std::string&, // sys_name, not needed const std::string&) // unk_name, not needed {</pre></div><div class = "comment">Gradient value to be returned.</div><div class ="fragment"><pre> Gradient gradu; </pre></div><div class = "comment">x and y coordinates in space</div><div class ="fragment"><pre> const Real x = p(0); const Real y = dim > 1 ? p(1) : 0.; if (singularity) {</pre></div><div class = "comment">We can't compute the gradient at x=0, it is not defined.</div><div class ="fragment"><pre> assert (x != 0.); </pre></div><div class = "comment">For convenience...</div><div class ="fragment"><pre> const Real tt = 2./3.; const Real ot = 1./3.; </pre></div><div class = "comment">The value of the radius, squared</div><div class ="fragment"><pre> const Real r2 = x*x + y*y; </pre></div><div class = "comment">The boundary value, given by the exact solution,u_exact = r^(2/3)*sin(2*theta/3).</div><div class ="fragment"><pre> Real theta = atan2(y,x); </pre></div><div class = "comment">Make sure 0 <= theta <= 2*pi</div><div class ="fragment"><pre> if (theta < 0) theta += 2. * libMesh::pi; </pre></div><div class = "comment">du/dx</div><div class ="fragment"><pre> gradu(0) = tt*x*pow(r2,-tt)*sin(tt*theta) - pow(r2,ot)*cos(tt*theta)*tt/(1.+y*y/x/x)*y/x/x; </pre></div><div class = "comment">du/dy</div><div class ="fragment"><pre> if (dim > 1) gradu(1) = tt*y*pow(r2,-tt)*sin(tt*theta) + pow(r2,ot)*cos(tt*theta)*tt/(1.+y*y/x/x)*1./x; if (dim > 2) gradu(2) = 1.; } else { const Real z = (dim > 2) ? p(2) : 0; gradu(0) = -sin(x) * exp(y) * (1. - z); if (dim > 1) gradu(1) = cos(x) * exp(y) * (1. - z); if (dim > 2) gradu(2) = -cos(x) * exp(y); } return gradu; } </pre></div><div class = "comment">We now define the matrix assembly function for theLaplace system. We need to first compute elementmatrices and right-hand sides, and then take intoaccount the boundary conditions, which will be handledvia a penalty method.</div><div class ="fragment"><pre> void assemble_laplace(EquationSystems& es, const std::string& system_name) { #ifdef ENABLE_AMR</pre></div><div class = "comment">It is a good idea to make sure we are assemblingthe proper system.</div><div class ="fragment"><pre> assert (system_name == "Laplace"); </pre></div><div class = "comment">Declare a performance log. Give it a descriptivestring to identify what part of the code we arelogging, since there may be many PerfLogs in anapplication.</div><div class ="fragment"><pre> PerfLog perf_log ("Matrix Assembly",false); </pre></div><div class = "comment">Get a constant reference to the mesh object.</div><div class ="fragment"><pre> const Mesh& mesh = es.get_mesh(); </pre></div><div class = "comment">The dimension that we are running</div><div class ="fragment"><pre> const unsigned int dim = mesh.mesh_dimension(); </pre></div><div class = "comment">Get a reference to the LinearImplicitSystem we are solving</div><div class ="fragment"><pre> LinearImplicitSystem& system = es.get_system<LinearImplicitSystem>("Laplace"); </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">Get a constant reference to the Finite Element typefor the first (and only) variable in the system.</div><div class ="fragment"><pre> FEType fe_type = dof_map.variable_type(0); </pre></div><div class = "comment">Build a Finite Element object of the specified type. Since the\p FEBase::build() member dynamically creates memory we willstore the object as an \p AutoPtr<FEBase>. This can be thoughtof as a pointer that will clean up after itself.</div><div class ="fragment"><pre> AutoPtr<FEBase> fe (FEBase::build(dim, fe_type)); AutoPtr<FEBase> fe_face (FEBase::build(dim, fe_type)); </pre></div><div class = "comment">Quadrature rules for numerical integration.</div><div class ="fragment"><pre> AutoPtr<QBase> qrule(fe_type.default_quadrature_rule(dim)); AutoPtr<QBase> qface(fe_type.default_quadrature_rule(dim-1)); </pre></div><div class = "comment">Tell the finite element object to use our quadrature rule.</div><div class ="fragment"><pre> fe->attach_quadrature_rule (qrule.get()); fe_face->attach_quadrature_rule (qface.get()); </pre></div><div class = "comment">Here we define some references to cell-specific data thatwill be used to assemble the linear system.We begin with the element Jacobian * quadrature weight at eachintegration point. </div><div class ="fragment"><pre> const std::vector<Real>& JxW = fe->get_JxW(); const std::vector<Real>& JxW_face = fe_face->get_JxW(); </pre></div><div class = "comment">The physical XY locations of the quadrature points on the element.These might be useful for evaluating spatially varying materialproperties or forcing functions at the quadrature points.</div><div class ="fragment"><pre> const std::vector<Point>& q_point = fe->get_xyz(); </pre></div><div class = "comment">The element shape functions evaluated at the quadrature points.For this simple problem we usually only need them on elementboundaries.</div><div class ="fragment"><pre> const std::vector<std::vector<Real> >& phi = fe->get_phi(); const std::vector<std::vector<Real> >& psi = fe_face->get_phi(); </pre></div><div class = "comment">The element shape function gradients evaluated at the quadraturepoints.</div><div class ="fragment">
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -