void AssembleOptimization::hessian (const NumericVector<Number> & /*soln*/,
                                    SparseMatrix<Number> & H_f,
                                    OptimizationSystem & sys)
{
  H_f.zero();
  H_f.add(1., *A_matrix);

  // We also need to add the Hessian of the inequality and equality constraints,
  //  \sum_i^n_eq lambda_eq_i H_eq_i + \sum_i^n_ineq lambda_ineq_i H_ineq_i
  // where lambda_eq and lambda_ineq denote Lagrange multipliers associated
  // with the equality and inequality constraints, respectively.
  // In this example, our equality constraints are linear, hence H_eq_i = 0.
  // However, our inequality constraint is nonlinear, so it will contribute
  // to the Hessian matrix.
  sys.optimization_solver->get_dual_variables();
  dof_id_type ineq_index = 0;
  Number lambda_ineq_0 = 0.;
  unsigned int lambda_rank = 0;
  if ((sys.lambda_ineq->first_local_index() <= ineq_index) &&
      (ineq_index < sys.lambda_ineq->last_local_index()))
    {
      lambda_ineq_0 = (*sys.lambda_ineq)(0);
      lambda_rank = sys.comm().rank();
    }

  // Sync lambda_rank across all processors.
  sys.comm().sum(lambda_rank);
  sys.comm().broadcast(lambda_rank, lambda_rank);

  if ((sys.get_dof_map().first_dof() <= 200) && (200 < sys.get_dof_map().end_dof()))
    H_f.add(200, 200, 2. * lambda_ineq_0);
}
Beispiel #2
0
void CSFSolver::compute_system_matrices(const Vector<double> &last_relax_step,
                                        const Vector<double> &previous_time_step,
                                        SparseMatrix<double> &mass_output,
                                        SparseMatrix<double> &stiffness_output) {
    mass_output = 0;
    stiffness_output = 0;
    const QGauss<2> quadrature_formula(3);
    FEValues<2> fe_values(fe, quadrature_formula,
        update_values | update_gradients | update_JxW_values | update_quadrature_points);
    const unsigned int dofs_per_cell = fe.dofs_per_cell;
    const unsigned int n_q_points = quadrature_formula.size();

    FullMatrix<double> local_mass_matrix(dofs_per_cell, dofs_per_cell);
    FullMatrix<double> local_stiffness_matrix(dofs_per_cell, dofs_per_cell);
    std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);

    std::vector<Tensor<1, 2, double>> last_relax_grads(n_q_points);
    std::vector<Tensor<1, 2, double>> previous_step_grads(n_q_points);

    for(auto cell : dof_handler.active_cell_iterators()) {
        local_mass_matrix = 0;
        local_stiffness_matrix = 0;
        fe_values.reinit(cell);
        fe_values.get_function_gradients(last_relax_step, last_relax_grads);
        fe_values.get_function_gradients(previous_time_step, previous_step_grads);

        for(unsigned int q_pt_idx = 0; q_pt_idx < n_q_points; q_pt_idx++) {
            for(unsigned int i = 0; i < dofs_per_cell; i++) {
                for(unsigned int j = 0; j < dofs_per_cell; j++) {
                    // Compute the shared denominator - normalizing to avoid infinities
                    double grad_sum = last_relax_grads[q_pt_idx].norm() + previous_step_grads[q_pt_idx].norm();
                    double grad_sum_inv = 1.0 / MAX(grad_sum, grad_epsilon);
                    // If there is a weight function, compute its value at the quad point
                    double weight_fn_value = weight_function(fe_values.quadrature_point(q_pt_idx));
                    // Compute the mass component
                    local_mass_matrix(i, j) += (fe_values.shape_value(i, q_pt_idx) * fe_values.shape_value(j, q_pt_idx) * weight_fn_value * grad_sum_inv * fe_values.JxW(q_pt_idx));
                    // Compute the stiffness component
                    local_stiffness_matrix(i, j) += (fe_values.shape_grad(i, q_pt_idx) * fe_values.shape_grad(j, q_pt_idx) * weight_fn_value * grad_sum_inv * fe_values.JxW(q_pt_idx));
                }
            }
        }

        // Copy the local matrices into the global output
        cell->get_dof_indices(local_dof_indices);
        for(unsigned int i = 0; i < dofs_per_cell; i++) {
            for(unsigned int j = 0; j < dofs_per_cell; j++) {
                mass_output.add(local_dof_indices[i], local_dof_indices[j], local_mass_matrix(i, j));
                stiffness_output.add(local_dof_indices[i], local_dof_indices[j], local_stiffness_matrix(i, j));
            }
        }
    }
}
Beispiel #3
0
void
NodalConstraint::computeJacobian(SparseMatrix<Number> & jacobian)
{
  _qp = 0;
  dof_id_type & dof_idx = _var.nodalDofIndex();
  dof_id_type & dof_idx_neighbor = _var.nodalDofIndexNeighbor();

  Real scaling_factor = _var.scalingFactor();
  jacobian.add(dof_idx, dof_idx, scaling_factor * computeQpJacobian(Moose::MasterMaster));
  jacobian.add(dof_idx, dof_idx_neighbor, scaling_factor * computeQpJacobian(Moose::MasterSlave));
  jacobian.add(dof_idx_neighbor, dof_idx_neighbor, scaling_factor * computeQpJacobian(Moose::SlaveSlave));
  jacobian.add(dof_idx_neighbor, dof_idx, scaling_factor * computeQpJacobian(Moose::SlaveMaster));
}
Beispiel #4
0
void AssembleOptimization::hessian (const NumericVector<Number> & /*soln*/,
                                    SparseMatrix<Number> & H_f,
                                    OptimizationSystem & /*sys*/)
{
  H_f.zero();
  H_f.add(1., *A_matrix);
}
Beispiel #5
0
void
Assembly::addCachedJacobian(SparseMatrix<Number> & jacobian)
{
  mooseAssert(_cached_jacobian_rows.size() == _cached_jacobian_cols.size(),
              "Error: Cached data sizes MUST be the same!");

  for(unsigned int i=0; i<_cached_jacobian_rows.size(); i++)
    jacobian.add(_cached_jacobian_rows[i], _cached_jacobian_cols[i], _cached_jacobian_values[i]);

  if (_max_cached_jacobians < _cached_jacobian_values.size())
    _max_cached_jacobians = _cached_jacobian_values.size();

  // Try to be more efficient from now on
  // The 2 is just a fudge factor to keep us from having to grow the vector during assembly
  _cached_jacobian_values.clear();
  _cached_jacobian_values.reserve(_max_cached_jacobians*2);

  _cached_jacobian_rows.clear();
  _cached_jacobian_rows.reserve(_max_cached_jacobians*2);

  _cached_jacobian_cols.clear();
  _cached_jacobian_cols.reserve(_max_cached_jacobians*2);
}
Beispiel #6
0
int main(int argc, char* argv[])
{
  // Load the mesh.
  Mesh mesh;
  H2DReader mloader;
  // We load the mesh on a (-1, 1)^2 domain.
  mloader.load("ref_square.mesh", &mesh);            

  // Enter boundary markers 
  // (If no markers are entered, default is a natural BC).
  BCTypes bc_types;

  // Create an H1 space with default shapeset,
  // natural BC, and linear elements.
  H1Space space(&mesh, &bc_types, P_INIT);
  // The type of element, mesh_mode = 4 means a rectangle element.
  int mesh_mode = 4;
  int ndof = Space::get_num_dofs(&space);
  printf("ndof = %d\n", ndof);
  if(ndof > FNS_NUM) error("Max number of shape functions exceeded.");

  int *fn_idx = new int [FNS_NUM];
  int m = 0;
  int order = P_INIT;

  // Get the vertex fns index.
  info("Get the vertex fns index.");
  for (int i = 0; i < mesh_mode; i++, m++)
  {
    fn_idx[m] = space.get_shapeset()->get_vertex_index(i);
    printf("m = %d, get_vertex_index(m) = %d\n",
          m, space.get_shapeset()->get_vertex_index(m));
  }
  // Get the edge fns index.
  info("Get the edge fns index.");
  for (int edge_order = 2; edge_order <= order; edge_order++)
  {
    for (int j = 0; j < mesh_mode; j++, m++)
    {
      fn_idx[m] = space.get_shapeset()->get_edge_index(j, 0, edge_order);
      printf("m = %d, get_edge_index(m) = %d\n", m, fn_idx[m]);
    }
  }
  // Get the bubble fns index.
  info("Get the bubble fns index.");
  int number_bubble = space.get_shapeset()->get_num_bubbles(H2D_MAKE_QUAD_ORDER(order, order));
  int *bubble_idx = space.get_shapeset()->get_bubble_indices(H2D_MAKE_QUAD_ORDER(order, order));
  for (int i = 0; i < number_bubble; i++, m++ )
  {
    fn_idx[m] = bubble_idx[i];
    printf("m = %d, get_bubble_index(m) = %d\n", m, fn_idx[m]);
  }
  
  // Initialize the matrix solver.
  SparseMatrix* mat = create_matrix(matrix_solver);
  Vector* rhs = create_vector(matrix_solver);
  Solver* solver = create_linear_solver(matrix_solver, mat, rhs);

  // precalc structure
  mat->prealloc(ndof);
  for (int i = 0; i < ndof; i++)
    for (int j = 0; j < ndof; j++)
      mat->pre_add_ij(i, j);
        
  mat->alloc();
  rhs->alloc(ndof);

  info("Assembling matrix ...");
  for (int i = 0; i < ndof; i++)
  {
    for (int j = 0; j < order; j++)
    {
      double x1 = -1 + (2.0/order)*j;
      double y1 = -1;
      double value = space.get_shapeset()->get_fn_value(fn_idx[i], x1, y1, 0);
      mat->add(i, j, value);
      printf("get fn[%d] value = %f  ", i, value); 
      printf("x1 = %f, y1 = %f\n", x1, y1);
    }
    for (int j = 0; j < order; j++)
    {
      double y2 = -1 + (2.0/order)*j;;
      double x2 = 1;
      double value = space.get_shapeset()->get_fn_value(fn_idx[i], x2, y2, 0);
      mat->add(i, j+order, value);
      printf("get fn[%d] value = %f  ", i, value); 
      printf("x2 = %f, y2 = %f\n", x2, y2);
    }
    for (int j = 0; j < order; j++)
    {
      double x3 = 1 + (-1.0)*(2.0/order)*j;
      double y3 = 1;
      double value = space.get_shapeset()->get_fn_value(fn_idx[i], x3, y3, 0);
      mat->add(i, j+2*order, value);
      printf("get fn[%d] value = %f  ", i, value); 
      printf("x3 = %f, y3 = %f\n", x3, y3);
    }
    for (int j = 0; j < order; j++)
    {
      double x4 = -1;
      double y4 = 1 + (-1.0)*(2.0/order)*j;
      double value = space.get_shapeset()->get_fn_value(fn_idx[i], x4, y4, 0);
      mat->add(i, j+3*order, value);
      printf("get fn[%d] value = %f  ", i, value); 
      printf("x4 = %f, y4 = %f\n", x4, y4);
    }
  }

  int bubble = 0;
  for (int i = order*4; i < ndof; i++)
  {
      double x = 0.0 + (1.0/number_bubble)*bubble;
      double y = 0.0 + (1.0/number_bubble)*bubble;
      double value = space.get_shapeset()->get_fn_value(fn_idx[i], x, y, 0);
      mat->add(i, i, value);
      printf("get fn[%d] value = %f  ", i, value); 
      printf("x = %f, y = %f\n", x, y);
      bubble++;
  }

  printf("Adding the rhs\n");
  for (int i = 0; i < ndof; i++)
  {
    rhs->add(i, 0.0);
  }

  // Initialize the solution.
  Solution sln;
   
  info("Solution ...");
  if(solver->solve())
    Solution::vector_to_solution(solver->get_solution(), &space, &sln);
  else
    error ("Matrix solver failed.\n");

  for (int i = 0; i < ndof; i++)
  {
    // Get the value of the matrix solution by calling Vector::get().
    if (rhs->get(i) >= EPS)
    {
      printf("Shape functions are not linearly independent\n");
      return ERR_FAILURE; 
    }
  }
  printf("Success!\n");
 
  // Clean up.
  delete solver;
  delete mat;
  delete rhs;
  delete [] fn_idx;
  return ERR_SUCCESS;
}