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

📄 ex11.c

📁 一个用来实现偏微分方程中网格的计算库
💻 C
📖 第 1 页 / 共 2 页
字号:
    Kuu(Ke), Kuv(Ke), Kup(Ke),    Kvu(Ke), Kvv(Ke), Kvp(Ke),    Kpu(Ke), Kpv(Ke), Kpp(Ke);  DenseSubVector<Number>    Fu(Fe),    Fv(Fe),    Fp(Fe);  // This vector will hold the degree of freedom indices for  // the element.  These define where in the global system  // the element degrees of freedom get mapped.  std::vector<unsigned int> dof_indices;  std::vector<unsigned int> dof_indices_u;  std::vector<unsigned int> dof_indices_v;  std::vector<unsigned int> dof_indices_p;    // Now we will loop over all the elements in the mesh that  // live on the local processor. We will compute the element  // matrix and right-hand-side contribution.  Since the mesh  // will be refined we want to only consider the ACTIVE elements,  // hence we use a variant of the \p active_elem_iterator.//   const_active_local_elem_iterator           el (mesh.elements_begin());//   const const_active_local_elem_iterator end_el (mesh.elements_end());  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)    {          // Store a pointer to the element we are currently      // working on.  This allows for nicer syntax later.      const Elem* elem = *el;            // Get the degree of freedom indices for the      // current element.  These define where in the global      // matrix and right-hand-side this element will      // contribute to.      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();            // Compute the element-specific data for the current      // element.  This involves computing the location of the      // quadrature points (q_point) and the shape functions      // (phi, dphi) for the current element.      fe_vel->reinit  (elem);      fe_pres->reinit (elem);      // Zero the element matrix and right-hand side before      // summing them.  We use the resize member here because      // the number of degrees of freedom might have changed from      // the last element.  Note that this will be the case if the      // element type is different (i.e. the last element was a      // triangle, now we are on a quadrilateral).      Ke.resize (n_dofs, n_dofs);      Fe.resize (n_dofs);      // Reposition the submatrices...  The idea is this:      //      //         -           -          -  -      //        | Kuu Kuv Kup |        | Fu |      //   Ke = | Kvu Kvv Kvp |;  Fe = | Fv |      //        | Kpu Kpv Kpp |        | Fp |      //         -           -          -  -      //      // The \p DenseSubMatrix.repostition () member takes the      // (row_offset, column_offset, row_size, column_size).      //       // Similarly, the \p DenseSubVector.reposition () member      // takes the (row_offset, row_size)      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);            // Now we will build the element matrix.      for (unsigned int qp=0; qp<qrule.n_points(); qp++)        {          // Assemble the u-velocity row          // uu coupling          for (unsigned int i=0; i<n_u_dofs; i++)            for (unsigned int j=0; j<n_u_dofs; j++)              Kuu(i,j) += JxW[qp]*(dphi[i][qp]*dphi[j][qp]);          // up coupling          for (unsigned int i=0; i<n_u_dofs; i++)            for (unsigned int j=0; j<n_p_dofs; j++)              Kup(i,j) += -JxW[qp]*psi[j][qp]*dphi[i][qp](0);          // Assemble the v-velocity row          // vv coupling          for (unsigned int i=0; i<n_v_dofs; i++)            for (unsigned int j=0; j<n_v_dofs; j++)              Kvv(i,j) += JxW[qp]*(dphi[i][qp]*dphi[j][qp]);          // vp coupling          for (unsigned int i=0; i<n_v_dofs; i++)            for (unsigned int j=0; j<n_p_dofs; j++)              Kvp(i,j) += -JxW[qp]*psi[j][qp]*dphi[i][qp](1);                    // Assemble the pressure row          // pu coupling          for (unsigned int i=0; i<n_p_dofs; i++)            for (unsigned int j=0; j<n_u_dofs; j++)              Kpu(i,j) += -JxW[qp]*psi[i][qp]*dphi[j][qp](0);          // pv coupling          for (unsigned int i=0; i<n_p_dofs; i++)            for (unsigned int j=0; j<n_v_dofs; j++)              Kpv(i,j) += -JxW[qp]*psi[i][qp]*dphi[j][qp](1);                  } // end of the quadrature point qp-loop      // At this point the interior element integration has      // been completed.  However, we have not yet addressed      // boundary conditions.  For this example we will only      // consider simple Dirichlet boundary conditions imposed      // via the penalty method. The penalty method used here      // is equivalent (for Lagrange basis functions) to lumping      // the matrix resulting from the L2 projection penalty      // approach introduced in example 3.      {        // The following loops over the sides of the element.        // If the element has no neighbor on a side then that        // side MUST live on a boundary of the domain.        for (unsigned int s=0; s<elem->n_sides(); s++)          if (elem->neighbor(s) == NULL)            {              AutoPtr<Elem> side (elem->build_side(s));                                          // Loop over the nodes on the side.              for (unsigned int ns=0; ns<side->n_nodes(); ns++)                {                  // The location on the boundary of the current                  // node.                                     // const Real xf = side->point(ns)(0);                  const Real yf = side->point(ns)(1);                                    // The penalty value.  \f$ \frac{1}{\epsilon \f$                  const Real penalty = 1.e10;                                    // The boundary values.                                     // Set u = 1 on the top boundary, 0 everywhere else                  const Real u_value = (yf > .99) ? 1. : 0.;                                    // Set v = 0 everywhere                  const Real v_value = 0.;                                    // Find the node on the element matching this node on                  // the side.  That defined where in the element matrix                  // the boundary condition will be applied.                  for (unsigned int n=0; n<elem->n_nodes(); n++)                    if (elem->node(n) == side->node(ns))                      {                        // Matrix contribution.                        Kuu(n,n) += penalty;                        Kvv(n,n) += penalty;                                                            // Right-hand-side contribution.                        Fu(n) += penalty*u_value;                        Fv(n) += penalty*v_value;                      }                } // end face node loop                      } // end if (elem->neighbor(side) == NULL)      } // end boundary condition section                      // The element matrix and right-hand-side are now built      // for this element.  Add them to the global matrix and      // right-hand-side vector.  The \p PetscMatrix::add_matrix()      // and \p PetscVector::add_vector() members do this for us.      system.matrix->add_matrix (Ke, dof_indices);      system.rhs->add_vector    (Fe, dof_indices);    } // end of element loop    // That's it.  return;}

⌨️ 快捷键说明

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