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

📄 ex9.c

📁 一个用来实现偏微分方程中网格的计算库
💻 C
📖 第 1 页 / 共 2 页
字号:
  // the proper system.  libmesh_assert (system_name == "Convection-Diffusion");  // Get a reference to the Convection-Diffusion system object.  TransientLinearImplicitSystem & system =    es.get_system<TransientLinearImplicitSystem>("Convection-Diffusion");  // Project initial conditions at time 0  es.parameters.set<Real> ("time") = 0;    system.project_solution(exact_value, NULL, es.parameters);}// Now we define the assemble function which will be used// by the EquationSystems object at each timestep to assemble// the linear system for solution.void assemble_cd (EquationSystems& es,                  const std::string& system_name){#ifdef ENABLE_AMR  // It is a good idea to make sure we are assembling  // the proper system.  libmesh_assert (system_name == "Convection-Diffusion");    // Get a constant reference to the mesh object.  const MeshBase& mesh = es.get_mesh();    // The dimension that we are running  const unsigned int dim = mesh.mesh_dimension();    // Get a reference to the Convection-Diffusion system object.  TransientLinearImplicitSystem & system =    es.get_system<TransientLinearImplicitSystem> ("Convection-Diffusion");    // Get a constant reference to the Finite Element type  // for the first (and only) variable in the system.  FEType fe_type = system.variable_type(0);    // Build a Finite Element object of the specified type.  Since the  // \p FEBase::build() member dynamically creates memory we will  // store the object as an \p AutoPtr<FEBase>.  This can be thought  // of as a pointer that will clean up after itself.  AutoPtr<FEBase> fe      (FEBase::build(dim, fe_type));  AutoPtr<FEBase> fe_face (FEBase::build(dim, fe_type));    // A Gauss quadrature rule for numerical integration.  // Let the \p FEType object decide what order rule is appropriate.  QGauss qrule (dim,   fe_type.default_quadrature_order());  QGauss qface (dim-1, fe_type.default_quadrature_order());  // Tell the finite element object to use our quadrature rule.  fe->attach_quadrature_rule      (&qrule);  fe_face->attach_quadrature_rule (&qface);  // Here we define some references to cell-specific data that  // will be used to assemble the linear system.  We will start  // with the element Jacobian * quadrature weight at each integration point.     const std::vector<Real>& JxW      = fe->get_JxW();  const std::vector<Real>& JxW_face = fe_face->get_JxW();    // The element shape functions evaluated at the quadrature points.  const std::vector<std::vector<Real> >& phi = fe->get_phi();  const std::vector<std::vector<Real> >& psi = fe_face->get_phi();  // The element shape function gradients evaluated at the quadrature  // points.  const std::vector<std::vector<RealGradient> >& dphi = fe->get_dphi();  // The XY locations of the quadrature points used for face integration  const std::vector<Point>& qface_points = fe_face->get_xyz();    // A reference to the \p DofMap object for this system.  The \p DofMap  // object handles the index translation from node and element numbers  // to degree of freedom numbers.  We will talk more about the \p DofMap  // in future examples.  const DofMap& dof_map = system.get_dof_map();  // Define data structures to contain the element matrix  // and right-hand-side vector contribution.  Following  // basic finite element terminology we will denote these  // "Ke" and "Fe".  DenseMatrix<Number> Ke;  DenseVector<Number> 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;  // Here we extract the velocity & parameters that we put in the  // EquationSystems object.  const RealVectorValue velocity =    es.parameters.get<RealVectorValue> ("velocity");  const Real dt = es.parameters.get<Real>   ("dt");  const Real time = es.parameters.get<Real> ("time");  // 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);            // 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->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 (dof_indices.size(),                 dof_indices.size());      Fe.resize (dof_indices.size());            // Now we will build the element matrix and right-hand-side.      // Constructing the RHS requires the solution and its      // gradient from the previous timestep.  This myst be      // calculated at each quadrature point by summing the      // solution degree-of-freedom values by the appropriate      // weight functions.      for (unsigned int qp=0; qp<qrule.n_points(); qp++)        {          // Values to hold the old solution & its gradient.          Number   u_old = 0.;          Gradient grad_u_old;                    // Compute the old solution & its gradient.          for (unsigned int l=0; l<phi.size(); l++)            {              u_old      += phi[l][qp]*system.old_solution  (dof_indices[l]);                            // This will work,              // grad_u_old += dphi[l][qp]*system.old_solution (dof_indices[l]);              // but we can do it without creating a temporary like this:              grad_u_old.add_scaled (dphi[l][qp],system.old_solution (dof_indices[l]));            }                    // Now compute the element matrix and RHS contributions.          for (unsigned int i=0; i<phi.size(); i++)            {              // The RHS contribution              Fe(i) += JxW[qp]*(                                // Mass matrix term                                u_old*phi[i][qp] +                                -.5*dt*(                                        // Convection term                                        // (grad_u_old may be complex, so the                                        // order here is important!)                                        (grad_u_old*velocity)*phi[i][qp] +                                                                                // Diffusion term                                        0.01*(grad_u_old*dphi[i][qp]))                                     );                            for (unsigned int j=0; j<phi.size(); j++)                {                  // The matrix contribution                  Ke(i,j) += JxW[qp]*(                                      // Mass-matrix                                      phi[i][qp]*phi[j][qp] +                                       .5*dt*(                                             // Convection term                                             (velocity*dphi[j][qp])*phi[i][qp] +                                                                                          // Diffusion term                                             0.01*(dphi[i][qp]*dphi[j][qp]))                                            );                }             }         }       // 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 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.      {        // The penalty value.          const Real penalty = 1.e10;        // 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)            {              fe_face->reinit(elem,s);                            for (unsigned int qp=0; qp<qface.n_points(); qp++)                {                  const Number value = exact_solution (qface_points[qp](0),                                                       qface_points[qp](1),                                                       time);                                                                         // RHS contribution                  for (unsigned int i=0; i<psi.size(); i++)                    Fe(i) += penalty*JxW_face[qp]*value*psi[i][qp];                  // Matrix contribution                  for (unsigned int i=0; i<psi.size(); i++)                    for (unsigned int j=0; j<psi.size(); j++)                      Ke(i,j) += penalty*JxW_face[qp]*psi[i][qp]*psi[j][qp];                }            }       }       // 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);    }    // That concludes the system matrix assembly routine.#endif // #ifdef ENABLE_AMR}

⌨️ 快捷键说明

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