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"); }
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"); }
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); }