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

📄 ex6.php

📁 一个用来实现偏微分方程中网格的计算库
💻 PHP
📖 第 1 页 / 共 3 页
字号:
        }        </pre></div><div class = "comment">This function assembles the system matrix and right-hand-sidefor the discrete form of our wave equation.</div><div class ="fragment"><pre>        void assemble_wave(EquationSystems& es,        		   const std::string& system_name)        {</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 == "Wave");                        #ifdef ENABLE_INFINITE_ELEMENTS          </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">Get a reference to the system we are solving.</div><div class ="fragment"><pre>          LinearImplicitSystem & system = es.get_system&lt;LinearImplicitSystem&gt;("Wave");          </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.</div><div class ="fragment"><pre>          const DofMap& dof_map = system.get_dof_map();          </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">Copy the speed of sound to a local variable.</div><div class ="fragment"><pre>          const Real speed = es.parameters.get&lt;Real&gt;("speed");          </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>          const 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>.  Check ex5 for details.</div><div class ="fragment"><pre>          AutoPtr&lt;FEBase&gt; fe (FEBase::build(dim, fe_type));          </pre></div><div class = "comment">Do the same for an infinite element.</div><div class ="fragment"><pre>          AutoPtr&lt;FEBase&gt; inf_fe (FEBase::build_InfFE(dim, fe_type));          </pre></div><div class = "comment">A 2nd order Gauss quadrature rule for numerical integration.</div><div class ="fragment"><pre>          QGauss qrule (dim, SECOND);          </pre></div><div class = "comment">Tell the finite element object to use our quadrature rule.   </div><div class ="fragment"><pre>          fe-&gt;attach_quadrature_rule (&qrule);          </pre></div><div class = "comment">Due to its internal structure, the infinite element handles quadrature rules differently.  It takes the quadraturerule which has been initialized for the FE object, butcreates suitable quadrature rules by @e itself.  The userneed not worry about this.   </div><div class ="fragment"><pre>          inf_fe-&gt;attach_quadrature_rule (&qrule);          </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",  "Ce", "Me", and "Fe" for the stiffness, dampingand mass matrices, and the load vector.  Note that in Acoustics, these descriptors though do @e not match the true physical meaning of the projectors.  The final overall system, however, resembles the conventional notation again.   </div><div class ="fragment"><pre>          DenseMatrix&lt;Number&gt; Ke;          DenseMatrix&lt;Number&gt; Ce;          DenseMatrix&lt;Number&gt; Me;          DenseVector&lt;Number&gt; 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&lt;unsigned int&gt; dof_indices;          </pre></div><div class = "comment">Now we will loop over all the elements in the mesh.We will compute the element matrix and right-hand-sidecontribution.const_local_elem_iterator           el (mesh.elements_begin());const const_local_elem_iterator end_el (mesh.elements_end());<br><br></div><div class ="fragment"><pre>          MeshBase::const_element_iterator           el = mesh.local_elements_begin();          const MeshBase::const_element_iterator end_el = mesh.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);                      </pre></div><div class = "comment">The mesh contains both finite and infinite elements.  Theseelements are handled through different classes, namely\p FE and \p InfFE, respectively.  However, since bothare derived from \p FEBase, they share the same interface,and overall burden of coding is @e greatly reduced throughusing a pointer, which is adjusted appropriately to thecurrent element type.       </div><div class ="fragment"><pre>              FEBase* cfe=NULL;              </pre></div><div class = "comment">This here is almost the only place where we need todistinguish between finite and infinite elements.For faster computation, however, different approachesmay be feasible.<br><br>Up to now, we do not know what kind of element wehave.  Aske the element of what type it is:        </div><div class ="fragment"><pre>              if (elem-&gt;infinite())                {	   </pre></div><div class = "comment">We have an infinite element.  Let \p cfe pointto our \p InfFE object.  This is handled throughan AutoPtr.  Through the \p AutoPtr::get() we "borrow"the pointer, while the \p  AutoPtr \p inf_fe isstill in charge of memory management.	   </div><div class ="fragment"><pre>                  cfe = inf_fe.get();         	}              else                {</pre></div><div class = "comment">This is a conventional finite element.  Let \p fe handle it.	   </div><div class ="fragment"><pre>                    cfe = fe.get();        	  </pre></div><div class = "comment">Boundary conditions.Here we just zero the rhs-vector. For natural boundary conditions check e.g. previous examples.	   </div><div class ="fragment"><pre>                  {              </pre></div><div class = "comment">Zero the RHS for this element. 	       </div><div class ="fragment"><pre>                    Fe.resize (dof_indices.size());        	            	    system.rhs-&gt;add_vector (Fe, dof_indices);        	  } // end boundary condition section	             	} // else ( if (elem-&gt;infinite())) )        </pre></div><div class = "comment">This is slightly different from the Poisson solver:Since the finite element object may change, we have toinitialize the constant references to the data fieldseach time again, when a new element is processed.<br><br>The element Jacobian * quadrature weight at each integration point.          </div><div class ="fragment"><pre>              const std::vector&lt;Real&gt;& JxW = cfe-&gt;get_JxW();              </pre></div><div class = "comment">The element shape functions evaluated at the quadrature points.       </div><div class ="fragment"><pre>              const std::vector&lt;std::vector&lt;Real&gt; &gt;& phi = cfe-&gt;get_phi();              </pre></div><div class = "comment">The element shape function gradients evaluated at the quadraturepoints.       </div><div class ="fragment"><pre>              const std::vector&lt;std::vector&lt;RealGradient&gt; &gt;& dphi = cfe-&gt;get_dphi();        </pre></div><div class = "comment">The infinite elements need more data fields than conventional FE.  These are the gradients of the phase term \p dphase, an additional radial weight for the test functions \p Sobolev_weight, and itsgradient.<br><br>Note that these data fields are also initialized appropriately bythe \p FE method, so that the weak form (below) is valid for @e bothfinite and infinite elements.       </div><div class ="fragment"><pre>              const std::vector&lt;RealGradient&gt;& dphase  = cfe-&gt;get_dphase();              const std::vector&lt;Real&gt;&         weight  = cfe-&gt;get_Sobolev_weight();              const std::vector&lt;RealGradient&gt;& dweight = cfe-&gt;get_Sobolev_dweight();        </pre></div><div class = "comment">Now this is all independent of whether we use an \p FEor an \p InfFE.  Nice, hm? ;-)<br><br>Compute the element-specific data, as describedin previous examples.       </div><div class ="fragment"><pre>              cfe-&gt;reinit (elem);              </pre></div><div class = "comment">Zero the element matrices.  Boundary conditions were alreadyprocessed in the \p FE-only section, see above.       </div><div class ="fragment"><pre>              Ke.resize (dof_indices.size(), dof_indices.size());              Ce.resize (dof_indices.size(), dof_indices.size());              Me.resize (dof_indices.size(), dof_indices.size());              </pre></div><div class = "comment">The total number of quadrature points for infinite elements@e has to be determined in a different way, compared toconventional finite elements.  This type of access is alsovalid for finite elements, so this can safely be usedanytime, instead of asking the quadrature rule, asseen in previous examples.       </div><div class ="fragment"><pre>              unsigned int max_qp = cfe-&gt;n_quadrature_points();              </pre></div><div class = "comment">Loop over the quadrature points.        </div><div class ="fragment"><pre>              for (unsigned int qp=0; qp&lt;max_qp; qp++)                {	  </pre></div><div class = "comment">Similar to the modified access to the number of quadrature points, the number of shape functions may also be obtainedin a different manner.  This offers the great advantageof being valid for both finite and infinite elements.	   </div><div class ="fragment"><pre>                  const unsigned int n_sf = cfe-&gt;n_shape_functions();        </pre></div><div class = "comment">Now we will build the element matrices.  Since the infiniteelements are based on a Petrov-Galerkin scheme, theresulting system matrices are non-symmetric. The additionalweight, described before, is part of the trial space.<br><br>For the finite elements, though, these matrices are symmetricjust as we know them, since the additional fields \p dphase,\p weight, and \p dweight are initialized appropriately.<br><br>test functions:    weight[qp]*phi[i][qp]trial functions:   phi[j][qp]phase term:        phase[qp]<br><br>derivatives are similar, but note that these are of typePoint, not of type Real.	   </div>

⌨️ 快捷键说明

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