예제 #1
0
void AssemblyA0::interior_assembly(FEMContext & c)
{
  const unsigned int n_components = rb_sys.n_vars();

  // make sure we have three components
  libmesh_assert_equal_to (n_components, 3);

  const unsigned int u_var = rb_sys.u_var;
  const unsigned int v_var = rb_sys.v_var;
  const unsigned int w_var = rb_sys.w_var;

  FEBase * elem_fe = libmesh_nullptr;
  c.get_element_fe(u_var, elem_fe);

  const std::vector<Real> & JxW = elem_fe->get_JxW();

  // The velocity shape function gradients at interior
  // quadrature points.
  const std::vector<std::vector<RealGradient>> & dphi = elem_fe->get_dphi();

  // Now we will build the affine operator
  unsigned int n_qpoints = c.get_element_qrule().n_points();

  std::vector<unsigned int> n_var_dofs(n_components);
  n_var_dofs[u_var] = c.get_dof_indices(u_var).size();
  n_var_dofs[v_var] = c.get_dof_indices(v_var).size();
  n_var_dofs[w_var] = c.get_dof_indices(w_var).size();

  for (unsigned int C_i = 0; C_i < n_components; C_i++)
    {
      unsigned int C_j = 0;
      for (unsigned int C_k = 0; C_k < n_components; C_k++)
        for (unsigned int C_l = 1; C_l < n_components; C_l++)
          {
            Real C_ijkl = elasticity_tensor(C_i, C_j, C_k, C_l);
            for (unsigned int qp=0; qp<n_qpoints; qp++)
              for (unsigned int i=0; i<n_var_dofs[C_i]; i++)
                for (unsigned int j=0; j<n_var_dofs[C_k]; j++)
                  (c.get_elem_jacobian(C_i,C_k))(i,j) +=
                    JxW[qp]*(C_ijkl * dphi[i][qp](C_j)*dphi[j][qp](C_l));
          }
    }

  for (unsigned int C_i = 0; C_i < n_components; C_i++)
    for (unsigned int C_j = 1; C_j < n_components; C_j++)
      for (unsigned int C_k = 0; C_k < n_components; C_k++)
        {
          unsigned int C_l = 0;

          Real C_ijkl = elasticity_tensor(C_i, C_j, C_k, C_l);
          for (unsigned int qp=0; qp<n_qpoints; qp++)
            for (unsigned int i=0; i<n_var_dofs[C_i]; i++)
              for (unsigned int j=0; j<n_var_dofs[C_k]; j++)
                (c.get_elem_jacobian(C_i,C_k))(i,j) +=
                  JxW[qp]*(C_ijkl * dphi[i][qp](C_j)*dphi[j][qp](C_l));
        }

}
예제 #2
0
AutoPtr<DiffContext> FEMSystem::build_context ()
{
  FEMContext* fc = new FEMContext(*this);

  AutoPtr<DiffContext> ap(fc);

  DifferentiablePhysics* phys = this->get_physics();

  libmesh_assert (phys);

  // If we are solving a moving mesh problem, tell that to the Context
  fc->set_mesh_system(phys->get_mesh_system());
  fc->set_mesh_x_var(phys->get_mesh_x_var());
  fc->set_mesh_y_var(phys->get_mesh_y_var());
  fc->set_mesh_z_var(phys->get_mesh_z_var());

  ap->set_deltat_pointer( &deltat );

  // If we are solving the adjoint problem, tell that to the Context
  ap->is_adjoint() = this->get_time_solver().is_adjoint();

  return ap;
}
예제 #3
0
파일: assembly.C 프로젝트: YSB330/libmesh
void InnerProductAssembly::interior_assembly(FEMContext & c)
{
  const unsigned int u_var = rb_sys.u_var;
  const unsigned int v_var = rb_sys.v_var;
  const unsigned int w_var = rb_sys.w_var;

  FEBase * elem_fe = libmesh_nullptr;
  c.get_element_fe(u_var, elem_fe);

  const std::vector<Real> & JxW = elem_fe->get_JxW();

  // The velocity shape function gradients at interior
  // quadrature points.
  const std::vector<std::vector<RealGradient> >& dphi = elem_fe->get_dphi();

  // The number of local degrees of freedom in each variable
  const unsigned int n_u_dofs = c.get_dof_indices(u_var).size();
  const unsigned int n_v_dofs = c.get_dof_indices(v_var).size();
  const unsigned int n_w_dofs = c.get_dof_indices(w_var).size();

  // Now we will build the affine operator
  unsigned int n_qpoints = c.get_element_qrule().n_points();

  DenseSubMatrix<Number> & Kuu = c.get_elem_jacobian(u_var, u_var);
  DenseSubMatrix<Number> & Kvv = c.get_elem_jacobian(v_var, v_var);
  DenseSubMatrix<Number> & Kww = c.get_elem_jacobian(w_var, w_var);

  for (unsigned int qp=0; qp<n_qpoints; qp++)
    {
      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]);

      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]);

      for (unsigned int i=0; i<n_w_dofs; i++)
        for (unsigned int j=0; j<n_w_dofs; j++)
          Kww(i,j) += JxW[qp]*(dphi[i][qp]*dphi[j][qp]);
    }
}
예제 #4
0
void FEMSystem::numerical_jacobian (TimeSolverResPtr res,
                                    FEMContext &context)
{
  // Logging is done by numerical_elem_jacobian
  // or numerical_side_jacobian

  DenseVector<Number> original_residual(context.elem_residual);
  DenseVector<Number> backwards_residual(context.elem_residual);
  DenseMatrix<Number> numerical_jacobian(context.elem_jacobian);
#ifdef DEBUG
  DenseMatrix<Number> old_jacobian(context.elem_jacobian);
#endif

  Real numerical_point_h = 0.;
  if (_mesh_sys == this)
    numerical_point_h = numerical_jacobian_h * context.elem->hmin();

  for (unsigned int j = 0; j != context.dof_indices.size(); ++j)
    {
      // Take the "minus" side of a central differenced first derivative
      Number original_solution = context.elem_solution(j);
      context.elem_solution(j) -= numerical_jacobian_h;

      // Make sure to catch any moving mesh terms
      // FIXME - this could be less ugly
      Real *coord = NULL;
      if (_mesh_sys == this)
        {
          if (_mesh_x_var != libMesh::invalid_uint)
            for (unsigned int k = 0;
                 k != context.dof_indices_var[_mesh_x_var].size(); ++k)
              if (context.dof_indices_var[_mesh_x_var][k] ==
                  context.dof_indices[j])
                coord = &(const_cast<Elem*>(context.elem)->point(k)(0));
          if (_mesh_y_var != libMesh::invalid_uint)
            for (unsigned int k = 0;
                 k != context.dof_indices_var[_mesh_y_var].size(); ++k)
              if (context.dof_indices_var[_mesh_y_var][k] ==
                  context.dof_indices[j])
                coord = &(const_cast<Elem*>(context.elem)->point(k)(1));
          if (_mesh_z_var != libMesh::invalid_uint)
            for (unsigned int k = 0;
                 k != context.dof_indices_var[_mesh_z_var].size(); ++k)
	      if (context.dof_indices_var[_mesh_z_var][k] ==
                  context.dof_indices[j])
                coord = &(const_cast<Elem*>(context.elem)->point(k)(2));
        }
      if (coord)
        {
          // We have enough information to scale the perturbations
          // here appropriately
          context.elem_solution(j) = original_solution - numerical_point_h;
          *coord = libmesh_real(context.elem_solution(j));
        }

      context.elem_residual.zero();
      ((*time_solver).*(res))(false, context);
#ifdef DEBUG
      libmesh_assert_equal_to (old_jacobian, context.elem_jacobian);
#endif
      backwards_residual = context.elem_residual;

      // Take the "plus" side of a central differenced first derivative
      context.elem_solution(j) = original_solution + numerical_jacobian_h;
      if (coord)
        {
          context.elem_solution(j) = original_solution + numerical_point_h;
          *coord = libmesh_real(context.elem_solution(j));
        }
      context.elem_residual.zero();
      ((*time_solver).*(res))(false, context);
#ifdef DEBUG
      libmesh_assert_equal_to (old_jacobian, context.elem_jacobian);
#endif

      context.elem_solution(j) = original_solution;
      if (coord)
        {
          *coord = libmesh_real(context.elem_solution(j));
	  for (unsigned int i = 0; i != context.dof_indices.size(); ++i)
            {
              numerical_jacobian(i,j) =
                (context.elem_residual(i) - backwards_residual(i)) /
                2. / numerical_point_h;
            }
        }
      else
        {
          for (unsigned int i = 0; i != context.dof_indices.size(); ++i)
            {
              numerical_jacobian(i,j) =
                (context.elem_residual(i) - backwards_residual(i)) /
                2. / numerical_jacobian_h;
            }
        }
    }

  context.elem_residual = original_residual;
  context.elem_jacobian = numerical_jacobian;
}