コード例 #1
0
void RBSCMConstruction::compute_SCM_bounding_box()
{
  START_LOG("compute_SCM_bounding_box()", "RBSCMConstruction");

  // Resize the bounding box vectors
  rb_scm_eval->B_min.resize(get_rb_theta_expansion().get_n_A_terms());
  rb_scm_eval->B_max.resize(get_rb_theta_expansion().get_n_A_terms());

  for(unsigned int q=0; q<get_rb_theta_expansion().get_n_A_terms(); q++)
  {
    matrix_A->zero();
    add_scaled_symm_Aq(q, 1.);

    // Compute B_min(q)
    eigen_solver->set_position_of_spectrum(SMALLEST_REAL);
    set_eigensolver_properties(q);

    solve();
    unsigned int nconv = get_n_converged();
    if (nconv != 0)
    {
      std::pair<Real, Real> eval = get_eigenpair(0);

      // ensure that the eigenvalue is real
      libmesh_assert_less (eval.second, TOLERANCE);

      rb_scm_eval->set_B_min(q, eval.first);
      libMesh::out << std::endl << "B_min("<<q<<") = " << rb_scm_eval->get_B_min(q) << std::endl;
    }
    else
    {
      libMesh::err << "Eigen solver for computing B_min did not converge" << std::endl;
      libmesh_error();
    }

    // Compute B_max(q)
    eigen_solver->set_position_of_spectrum(LARGEST_REAL);
    set_eigensolver_properties(q);

    solve();
    nconv = get_n_converged();
    if (nconv != 0)
    {
      std::pair<Real, Real> eval = get_eigenpair(0);

      // ensure that the eigenvalue is real
      libmesh_assert_less (eval.second, TOLERANCE);

      rb_scm_eval->set_B_max(q,eval.first);
      libMesh::out << "B_max("<<q<<") = " << rb_scm_eval->get_B_max(q) << std::endl;
    }
    else
    {
      libMesh::err << "Eigen solver for computing B_max did not converge" << std::endl;
      libmesh_error();
    }
  }

  STOP_LOG("compute_SCM_bounding_box()", "RBSCMConstruction");
}
コード例 #2
0
void RBSCMConstruction::evaluate_stability_constant()
{
  START_LOG("evaluate_stability_constant()", "RBSCMConstruction");

  // Get current index of C_J
  const unsigned int j = rb_scm_eval->C_J.size()-1;

  eigen_solver->set_position_of_spectrum(SMALLEST_REAL);

  // We assume B is set in system assembly
  // For coercive problems, B is set to the inner product matrix
  // For non-coercive time-dependent problems, B is set to the mass matrix

  // Set matrix A corresponding to mu_star
  matrix_A->zero();
  for(unsigned int q=0; q<get_rb_theta_expansion().get_n_A_terms(); q++)
  {
    add_scaled_symm_Aq(q, get_rb_theta_expansion().eval_A_theta(q,get_parameters()));
  }

  set_eigensolver_properties(-1);
  solve();
  unsigned int nconv = get_n_converged();
  if (nconv != 0)
  {
    std::pair<Real, Real> eval = get_eigenpair(0);

    // ensure that the eigenvalue is real
    libmesh_assert_less (eval.second, TOLERANCE);

    // Store the coercivity constant corresponding to mu_star
    rb_scm_eval->set_C_J_stability_constraint(j,eval.first);
    libMesh::out << std::endl << "Stability constant for C_J("<<j<<") = "
                 << rb_scm_eval->get_C_J_stability_constraint(j) << std::endl << std::endl;

    // Compute and store the vector y = (y_1, \ldots, y_Q) for the
    // eigenvector currently stored in eigen_system.solution.
    // We use this later to compute the SCM upper bounds.
    Real norm_B2 = libmesh_real( B_inner_product(*solution, *solution) );

    for(unsigned int q=0; q<get_rb_theta_expansion().get_n_A_terms(); q++)
    {
      Real norm_Aq2 = libmesh_real( Aq_inner_product(q, *solution, *solution) );

      rb_scm_eval->set_SCM_UB_vector(j,q,norm_Aq2/norm_B2);
    }
  }
  else
  {
    libMesh::err << "Error: Eigensolver did not converge in evaluate_stability_constant"
                 << std::endl;
    libmesh_error();
  }

  STOP_LOG("evaluate_stability_constant()", "RBSCMConstruction");
}
コード例 #3
0
Number RBSCMConstruction::Aq_inner_product(unsigned int q,
                                           const NumericVector<Number>& v,
                                           const NumericVector<Number>& w)
{
  if(q >= get_rb_theta_expansion().get_n_A_terms())
    libmesh_error_msg("Error: We must have q < Q_a in Aq_inner_product.");

  matrix_A->zero();
  add_scaled_symm_Aq(q, 1.);
  matrix_A->vector_mult(*inner_product_storage_vector, w);

  return v.dot(*inner_product_storage_vector);
}