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

📄 ex13.php

📁 一个用来实现偏微分方程中网格的计算库
💻 PHP
📖 第 1 页 / 共 5 页
字号:
variables evaluated at the quadrature points.</div><div class ="fragment"><pre>          const std::vector&lt;std::vector&lt;RealGradient&gt; &gt;& dphi = fe_vel-&gt;get_dphi();        </pre></div><div class = "comment">The element shape functions for the pressure variableevaluated at the quadrature points.</div><div class ="fragment"><pre>          const std::vector&lt;std::vector&lt;Real&gt; &gt;& psi = fe_pres-&gt;get_phi();        </pre></div><div class = "comment">The value of the linear shape function gradients at the quadrature pointsconst std::vector<std::vector<RealGradient> >& dpsi = fe_pres->get_dphi();  <br><br>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 = navier_stokes_system.get_dof_map();        </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".</div><div class ="fragment"><pre>          DenseMatrix&lt;Number&gt; Ke;          DenseVector&lt;Number&gt; Fe;                  DenseSubMatrix&lt;Number&gt;            Kuu(Ke), Kuv(Ke), Kup(Ke),            Kvu(Ke), Kvv(Ke), Kvp(Ke),            Kpu(Ke), Kpv(Ke), Kpp(Ke);                  DenseSubVector&lt;Number&gt;            Fu(Fe),            Fv(Fe),            Fp(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;          std::vector&lt;unsigned int&gt; dof_indices_u;          std::vector&lt;unsigned int&gt; dof_indices_v;          std::vector&lt;unsigned int&gt; dof_indices_p;        </pre></div><div class = "comment">Find out what the timestep size parameter is from the system, andthe value of theta for the theta method.  We use implicit Euler (theta=1)for this simulation even though it is only first-order accurate in time.The reason for this decision is that the second-order Crank-Nicolsonmethod is notoriously oscillatory for problems with discontinuousinitial data such as the lid-driven cavity.  Therefore,we sacrifice accuracy in time for stability, but since the solutionreaches steady state relatively quickly we can afford to take smalltimesteps.  If you monitor the initial nonlinear residual for thissimulation, you should see that it is monotonically decreasing in time.</div><div class ="fragment"><pre>          const Real dt    = es.parameters.get&lt;Real&gt;("dt");</pre></div><div class = "comment">const Real time  = es.parameters.get<Real>("time");</div><div class ="fragment"><pre>          const Real theta = 1.;            </pre></div><div class = "comment">Now we will loop over all the elements in the mesh thatlive on the local processor. We will compute the elementmatrix and right-hand-side contribution.  Since the meshwill be refined we want to only consider the ACTIVE elements,hence we use a variant of the \p active_elem_iterator.</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">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);              dof_map.dof_indices (elem, dof_indices_u, u_var);              dof_map.dof_indices (elem, dof_indices_v, v_var);              dof_map.dof_indices (elem, dof_indices_p, p_var);                      const unsigned int n_dofs   = dof_indices.size();              const unsigned int n_u_dofs = dof_indices_u.size();               const unsigned int n_v_dofs = dof_indices_v.size();               const unsigned int n_p_dofs = dof_indices_p.size();              </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_vel-&gt;reinit  (elem);              fe_pres-&gt;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 (n_dofs, n_dofs);              Fe.resize (n_dofs);        </pre></div><div class = "comment">Reposition the submatrices...  The idea is this:<br><br>-           -          -  -| Kuu Kuv Kup |        | Fu |Ke = | Kvu Kvv Kvp |;  Fe = | Fv || Kpu Kpv Kpp |        | Fp |-           -          -  -<br><br>The \p DenseSubMatrix.repostition () member takes the(row_offset, column_offset, row_size, column_size).<br><br>Similarly, the \p DenseSubVector.reposition () membertakes the (row_offset, row_size)</div><div class ="fragment"><pre>              Kuu.reposition (u_var*n_u_dofs, u_var*n_u_dofs, n_u_dofs, n_u_dofs);              Kuv.reposition (u_var*n_u_dofs, v_var*n_u_dofs, n_u_dofs, n_v_dofs);              Kup.reposition (u_var*n_u_dofs, p_var*n_u_dofs, n_u_dofs, n_p_dofs);                            Kvu.reposition (v_var*n_v_dofs, u_var*n_v_dofs, n_v_dofs, n_u_dofs);              Kvv.reposition (v_var*n_v_dofs, v_var*n_v_dofs, n_v_dofs, n_v_dofs);              Kvp.reposition (v_var*n_v_dofs, p_var*n_v_dofs, n_v_dofs, n_p_dofs);                            Kpu.reposition (p_var*n_u_dofs, u_var*n_u_dofs, n_p_dofs, n_u_dofs);              Kpv.reposition (p_var*n_u_dofs, v_var*n_u_dofs, n_p_dofs, n_v_dofs);              Kpp.reposition (p_var*n_u_dofs, p_var*n_u_dofs, n_p_dofs, n_p_dofs);                      Fu.reposition (u_var*n_u_dofs, n_u_dofs);              Fv.reposition (v_var*n_u_dofs, n_v_dofs);              Fp.reposition (p_var*n_u_dofs, n_p_dofs);        </pre></div><div class = "comment">Now we will build the element matrix and right-hand-side.Constructing the RHS requires the solution and itsgradient from the previous timestep.  This must becalculated at each quadrature point by summing thesolution degree-of-freedom values by the appropriateweight functions.</div><div class ="fragment"><pre>              for (unsigned int qp=0; qp&lt;qrule.n_points(); qp++)        	{</pre></div><div class = "comment">Values to hold the solution & its gradient at the previous timestep.</div><div class ="fragment"><pre>                  Number   u = 0., u_old = 0.;        	  Number   v = 0., v_old = 0.;        	  Number   p_old = 0.;        	  Gradient grad_u, grad_u_old;        	  Gradient grad_v, grad_v_old;        	  </pre></div><div class = "comment">Compute the velocity & its gradient from the previous timestepand the old Newton iterate.</div><div class ="fragment"><pre>                  for (unsigned int l=0; l&lt;n_u_dofs; l++)        	    {</pre></div><div class = "comment">From the old timestep:</div><div class ="fragment"><pre>                      u_old += phi[l][qp]*navier_stokes_system.old_solution (dof_indices_u[l]);        	      v_old += phi[l][qp]*navier_stokes_system.old_solution (dof_indices_v[l]);        	      grad_u_old.add_scaled (dphi[l][qp],navier_stokes_system.old_solution (dof_indices_u[l]));        	      grad_v_old.add_scaled (dphi[l][qp],navier_stokes_system.old_solution (dof_indices_v[l]));        </pre></div><div class = "comment">From the previous Newton iterate:</div><div class ="fragment"><pre>                      u += phi[l][qp]*navier_stokes_system.current_solution (dof_indices_u[l]);         	      v += phi[l][qp]*navier_stokes_system.current_solution (dof_indices_v[l]);        	      grad_u.add_scaled (dphi[l][qp],navier_stokes_system.current_solution (dof_indices_u[l]));        	      grad_v.add_scaled (dphi[l][qp],navier_stokes_system.current_solution (dof_indices_v[l]));        	    }        </pre></div><div class = "comment">Compute the old pressure value at this quadrature point.</div><div class ="fragment"><pre>                  for (unsigned int l=0; l&lt;n_p_dofs; l++)        	    {        	      p_old += psi[l][qp]*navier_stokes_system.old_solution (dof_indices_p[l]);        	    }        </pre></div><div class = "comment">Definitions for convenience.  It is sometimes simpler to do adot product if you have the full vector at your disposal.</div><div class ="fragment"><pre>                  const NumberVectorValue U_old (u_old, v_old);        	  const NumberVectorValue U     (u,     v);        	  const Number  u_x = grad_u(0);        	  const Number  u_y = grad_u(1);        	  const Number  v_x = grad_v(0);        	  const Number  v_y = grad_v(1);        	  </pre></div><div class = "comment">First, an i-loop over the velocity degrees of freedom.We know that n_u_dofs == n_v_dofs so we can compute contributionsfor both at the same time.</div><div class ="fragment"><pre>                  for (unsigned int i=0; i&lt;n_u_dofs; i++)        	    {        	      Fu(i) += JxW[qp]*(u_old*phi[i][qp] -                            // mass-matrix term         				(1.-theta)*dt*(U_old*grad_u_old)*phi[i][qp] + // convection term        				(1.-theta)*dt*p_old*dphi[i][qp](0)  -         // pressure term on rhs        				(1.-theta)*dt*(grad_u_old*dphi[i][qp]) +      // diffusion term on rhs        				theta*dt*(U*grad_u)*phi[i][qp]);              // Newton term                		        	      Fv(i) += JxW[qp]*(v_old*phi[i][qp] -                             // mass-matrix term        				(1.-theta)*dt*(U_old*grad_v_old)*phi[i][qp] +  // convection term        				(1.-theta)*dt*p_old*dphi[i][qp](1) -           // pressure term on rhs        				(1.-theta)*dt*(grad_v_old*dphi[i][qp]) +       // diffusion term on rhs        				theta*dt*(U*grad_v)*phi[i][qp]);               // Newton term        	            </pre></div><div class = "comment">Note that the Fp block is identically zero unless we are usingsome kind of artificial compressibility scheme...<br><br>Matrix contributions for the uu and vv couplings.</div><div class ="fragment"><pre>                      for (unsigned int j=0; j&lt;n_u_dofs; j++)        		{        		  Kuu(i,j) += JxW[qp]*(phi[i][qp]*phi[j][qp] +                // mass matrix term        				       theta*dt*(dphi[i][qp]*dphi[j][qp]) +   // diffusion term        				       theta*dt*(U*dphi[j][qp])*phi[i][qp] +  // convection term        				       theta*dt*u_x*phi[i][qp]*phi[j][qp]);   // Newton term                		  Kuv(i,j) += JxW[qp]*theta*dt*u_y*phi[i][qp]*phi[j][qp];     // Newton term        		          		  Kvv(i,j) += JxW[qp]*(phi[i][qp]*phi[j][qp] +                // mass matrix term        				       theta*dt*(dphi[i][qp]*dphi[j][qp]) +   // diffusion term        				       theta*dt*(U*dphi[j][qp])*phi[i][qp] +  // convection term        				       theta*dt*v_y*phi[i][qp]*phi[j][qp]);   // Newton term                		  Kvu(i,j) += JxW[qp]*theta*dt*v_x*phi[i][qp]*phi[j][qp];     // Newton term        		}        </pre></div><div class = "comment">Matrix contributions for the up and vp couplings.</div><div class ="fragment">

⌨️ 快捷键说明

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