⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ex5.php

📁 一个用来实现偏微分方程中网格的计算库
💻 PHP
📖 第 1 页 / 共 3 页
字号:
          assert (system_name == "Poisson");                  const Mesh& mesh = es.get_mesh();                  const unsigned int dim = mesh.mesh_dimension();                  LinearImplicitSystem& system = es.get_system&lt;LinearImplicitSystem&gt;("Poisson");                    const DofMap& dof_map = system.get_dof_map();                    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>.  Below, thefunctionality of \p AutoPtr's is described more detailed in the context of building quadrature rules.</div><div class ="fragment"><pre>          AutoPtr&lt;FEBase&gt; fe (FEBase::build(dim, fe_type));                    </pre></div><div class = "comment">Now this deviates from example 4.  we create a 5th order quadrature rule of user-specified typefor numerical integration.  Note that not allquadrature rules support this order.</div><div class ="fragment"><pre>          AutoPtr&lt;QBase&gt; qrule(QBase::build(quad_type, dim, THIRD));                          </pre></div><div class = "comment">Tell the finte element object to use ourquadrature rule.  Note that a \p AutoPtr<QBase> returnsa QBase* pointer to the object it handles with \p get().  However, using \p get(), the \p AutoPtr<QBase> \p qrule is still in charge of this pointer. I.e., when \p qrule goes out of scope, it will safely delete the \p QBase object it points to.  This behavior may be overridden using\p AutoPtr<Xyz>::release(), but is currently notrecommended.</div><div class ="fragment"><pre>          fe-&gt;attach_quadrature_rule (qrule.get());                  </pre></div><div class = "comment">Declare a special finite element object forboundary integration.</div><div class ="fragment"><pre>          AutoPtr&lt;FEBase&gt; fe_face (FEBase::build(dim, fe_type));                    </pre></div><div class = "comment">As already seen in example 3, boundary integration requires a quadrature rule.  Here, however,we use the more convenient way of building thisrule at run-time using \p quad_type.  Note that one could also have initialized the face quadrature rules with the type directly determined from \p qrule, namely through:\verbatimAutoPtr<QBase>  qface (QBase::build(qrule->type(),dim-1, THIRD));\endverbatimAnd again: using the \p AutoPtr<QBase> relaxesthe need to delete the object afterwards,they clean up themselves.</div><div class ="fragment"><pre>          AutoPtr&lt;QBase&gt;  qface (QBase::build(quad_type,        				      dim-1,         				      THIRD));        	                </pre></div><div class = "comment">Tell the finte element object to use ourquadrature rule.  Note that a \p AutoPtr<QBase> returnsa \p QBase* pointer to the object it handles with \p get().  However, using \p get(), the \p AutoPtr<QBase> \p qface is still in charge of this pointer. I.e., when \p qface goes out of scope, it will safely delete the \p QBase object it points to.  This behavior may be overridden using\p AutoPtr<Xyz>::release(), but is not recommended.</div><div class ="fragment"><pre>          fe_face-&gt;attach_quadrature_rule (qface.get());        	                        </pre></div><div class = "comment">This is again identical to example 4, and not commented.</div><div class ="fragment"><pre>          const std::vector&lt;Real&gt;& JxW = fe-&gt;get_JxW();                    const std::vector&lt;Point&gt;& q_point = fe-&gt;get_xyz();                    const std::vector&lt;std::vector&lt;Real&gt; &gt;& phi = fe-&gt;get_phi();                    const std::vector&lt;std::vector&lt;RealGradient&gt; &gt;& dphi = fe-&gt;get_dphi();                      DenseMatrix&lt;Number&gt; Ke;          DenseVector&lt;Number&gt; Fe;                    std::vector&lt;unsigned int&gt; dof_indices;                                                  </pre></div><div class = "comment">Now we will loop over all the elements in the mesh.See example 3 for details.const_elem_iterator           el (mesh.elements_begin());const const_elem_iterator end_el (mesh.elements_end());<br><br></div><div class ="fragment"><pre>          MeshBase::const_element_iterator       el     = mesh.elements_begin();          const MeshBase::const_element_iterator end_el = mesh.elements_end();                    for ( ; el != end_el; ++el)            {              const Elem* elem = *el;                            dof_map.dof_indices (elem, dof_indices);                            fe-&gt;reinit (elem);                            Ke.resize (dof_indices.size(),        		 dof_indices.size());                            Fe.resize (dof_indices.size());                                            </pre></div><div class = "comment">Now loop over the quadrature points.  This handlesthe numeric integration.  Note the slightly differentaccess to the QBase members!</div><div class ="fragment"><pre>              for (unsigned int qp=0; qp&lt;qrule-&gt;n_points(); qp++)        	{</pre></div><div class = "comment">Add the matrix contribution</div><div class ="fragment"><pre>                  for (unsigned int i=0; i&lt;phi.size(); i++)        	    for (unsigned int j=0; j&lt;phi.size(); j++)        	      Ke(i,j) += JxW[qp]*(dphi[i][qp]*dphi[j][qp]);        	          	  </pre></div><div class = "comment">fxy is the forcing function for the Poisson equation.In this case we set fxy to be a finite differenceLaplacian approximation to the (known) exact solution.<br><br>We will use the second-order accurate FD Laplacianapproximation, which in 2D on a structured grid is<br><br>u_xx + u_yy = (u(i-1,j) + u(i+1,j) +u(i,j-1) + u(i,j+1) +-4*u(i,j))/h^2<br><br>Since the value of the forcing function depends onlyon the location of the quadrature point (q_point[qp])we will compute it here, outside of the i-loop	  </div><div class ="fragment"><pre>                  const Real x = q_point[qp](0);        	  const Real y = q_point[qp](1);        	  const Real z = q_point[qp](2);        	  const Real eps = 1.e-3;                	  const Real uxx = (exact_solution(x-eps,y,z) +        			    exact_solution(x+eps,y,z) +        			    -2.*exact_solution(x,y,z))/eps/eps;        	              	  const Real uyy = (exact_solution(x,y-eps,z) +        			    exact_solution(x,y+eps,z) +        			    -2.*exact_solution(x,y,z))/eps/eps;        	          	  const Real uzz = (exact_solution(x,y,z-eps) +        			    exact_solution(x,y,z+eps) +        			    -2.*exact_solution(x,y,z))/eps/eps;                	  const Real fxy = - (uxx + uyy + ((dim==2) ? 0. : uzz));        	          </pre></div><div class = "comment">Add the RHS contribution</div><div class ="fragment"><pre>                  for (unsigned int i=0; i&lt;phi.size(); i++)        	    Fe(i) += JxW[qp]*fxy*phi[i][qp];	          	}                                                            </pre></div><div class = "comment">Most of this has already been seen before, exceptfor the build routines of QBase, described below</div><div class ="fragment"><pre>              {        	for (unsigned int side=0; side&lt;elem-&gt;n_sides(); side++)        	  if (elem-&gt;neighbor(side) == NULL)        	    {	              	      const std::vector&lt;std::vector&lt;Real&gt; &gt;& phi_face    = fe_face-&gt;get_phi();        	      const std::vector&lt;Real&gt;&               JxW_face    = fe_face-&gt;get_JxW();	              	      const std::vector&lt;Point &gt;&             qface_point = fe_face-&gt;get_xyz();        	              	      </pre></div><div class = "comment">Compute the shape function values on the elementface.</div><div class ="fragment"><pre>                      fe_face-&gt;reinit(elem, side);        	              	      </pre></div><div class = "comment">Loop over the face quadrature points for integration.Note that the \p AutoPtr<QBase> overloaded the operator->,so that QBase methods may safely be accessed.  It maybe said: accessing an \p AutoPtr<Xyz> through the"." operator returns \p AutoPtr methods, while accessthrough the "->" operator returns Xyz methods.This allows almost no change in syntax when switchingto "safe pointers".</div><div class ="fragment"><pre>                      for (unsigned int qp=0; qp&lt;qface-&gt;n_points(); qp++)        		{        		  const Real xf = qface_point[qp](0);        		  const Real yf = qface_point[qp](1);        		  const Real zf = qface_point[qp](2);        		          		  const Real penalty = 1.e10;        		          		  const Real value = exact_solution(xf, yf, zf);        		          		  for (unsigned int i=0; i&lt;phi_face.size(); i++)        		    for (unsigned int j=0; j&lt;phi_face.size(); j++)        		      Ke(i,j) += JxW_face[qp]*penalty*phi_face[i][qp]*phi_face[j][qp];        		          		          		  for (unsigned int i=0; i&lt;phi_face.size(); i++)        		    Fe(i) += JxW_face[qp]*penalty*value*phi_face[i][qp];        		          		} // end face quadrature point loop	          	    } // end if (elem-&gt;neighbor(side) == NULL)              } // end boundary condition section	                                                                        </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.</div><div class ="fragment"><pre>              system.matrix-&gt;add_matrix (Ke, dof_indices);              system.rhs-&gt;add_vector    (Fe, dof_indices);                          } // end of element loop                                        </pre></div>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -