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 DerivedRBConstruction<RBConstruction>::update_RB_system_matrices() { START_LOG("update_RB_system_matrices()", "DerivedRBConstruction"); DerivedRBEvaluation<RBEvaluation>& der_rb_eval = libmesh_cast_ref<DerivedRBEvaluation<RBEvaluation>&>(get_rb_evaluation()); EquationSystems& es = this->get_equation_systems(); RBConstruction& uber_system = es.get_system<RBConstruction>(uber_system_name); unsigned int derived_RB_size = get_rb_evaluation().get_n_basis_functions(); unsigned int uber_RB_size = uber_system.get_rb_evaluation().get_n_basis_functions(); const unsigned int Q_a = get_rb_theta_expansion().get_n_A_terms(); const unsigned int Q_f = get_rb_theta_expansion().get_n_F_terms(); DenseVector<Number> temp_vector; for(unsigned int q_f=0; q_f<Q_f; q_f++) { for(unsigned int i=(derived_RB_size-delta_N); i<derived_RB_size; i++) { uber_system.get_rb_evaluation().RB_Fq_vector[q_f].get_principal_subvector(uber_RB_size, temp_vector); get_rb_evaluation().RB_Fq_vector[q_f](i) = temp_vector.dot(der_rb_eval.derived_basis_functions[i]); } } DenseMatrix<Number> temp_matrix; for(unsigned int i=(derived_RB_size-delta_N); i<derived_RB_size; i++) { for(unsigned int n=0; n<get_rb_theta_expansion().get_n_outputs(); n++) for(unsigned int q_l=0; q_l<get_rb_theta_expansion().get_n_output_terms(n); q_l++) { uber_system.get_rb_evaluation().RB_output_vectors[n][q_l].get_principal_subvector(uber_RB_size, temp_vector); get_rb_evaluation().RB_output_vectors[n][q_l](i) = temp_vector.dot(der_rb_eval.derived_basis_functions[i]); } for(unsigned int j=0; j<derived_RB_size; j++) { for(unsigned int q_a=0; q_a<Q_a; q_a++) { // Compute reduced Aq matrix uber_system.get_rb_evaluation().RB_Aq_vector[q_a].get_principal_submatrix(uber_RB_size, temp_matrix); temp_matrix.vector_mult(temp_vector, der_rb_eval.derived_basis_functions[j]); get_rb_evaluation().RB_Aq_vector[q_a](i,j) = der_rb_eval.derived_basis_functions[i].dot(temp_vector); if(i!=j) { temp_vector.zero(); temp_matrix.vector_mult(temp_vector, der_rb_eval.derived_basis_functions[i]); get_rb_evaluation().RB_Aq_vector[q_a](j,i) = (der_rb_eval.derived_basis_functions[j]).dot(temp_vector); } } } } STOP_LOG("update_RB_system_matrices()", "DerivedRBConstruction"); }
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"); }
void RBSCMConstruction::resize_SCM_vectors() { // Clear SCM data vectors rb_scm_eval->B_min.clear(); rb_scm_eval->B_max.clear(); rb_scm_eval->C_J.clear(); rb_scm_eval->C_J_stability_vector.clear(); for(unsigned int i=0; i<rb_scm_eval->SCM_UB_vectors.size(); i++) rb_scm_eval->SCM_UB_vectors[i].clear(); rb_scm_eval->SCM_UB_vectors.clear(); // 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()); }
void RBSCMConstruction::enrich_C_J(unsigned int new_C_J_index) { START_LOG("enrich_C_J()", "RBSCMConstruction"); set_params_from_training_set_and_broadcast(new_C_J_index); rb_scm_eval->C_J.push_back(get_parameters()); libMesh::out << std::endl << "SCM: Added mu = ("; RBParameters::const_iterator it = get_parameters().begin(); RBParameters::const_iterator it_end = get_parameters().end(); for( ; it != it_end; ++it) { if(it != get_parameters().begin()) libMesh::out << ","; std::string param_name = it->first; RBParameters C_J_params = rb_scm_eval->C_J[rb_scm_eval->C_J.size()-1]; libMesh::out << C_J_params.get_value(param_name); } libMesh::out << ")" << std::endl; // Finally, resize C_J_stability_vector and SCM_UB_vectors rb_scm_eval->C_J_stability_vector.push_back(0.); std::vector<Real> zero_vector(get_rb_theta_expansion().get_n_A_terms()); rb_scm_eval->SCM_UB_vectors.push_back(zero_vector); STOP_LOG("enrich_C_J()", "RBSCMConstruction"); }
void RBSCMConstruction::print_info() { // Print out info that describes the current setup libMesh::out << std::endl << "RBSCMConstruction parameters:" << std::endl; libMesh::out << "system name: " << this->name() << std::endl; libMesh::out << "SCM Greedy tolerance: " << get_SCM_training_tolerance() << std::endl; if(rb_scm_eval) { libMesh::out << "A_q operators attached: " << get_rb_theta_expansion().get_n_A_terms() << std::endl; libMesh::out << "Number of parameters: " << get_n_params() << std::endl; } else { libMesh::out << "RBThetaExpansion member is not set yet" << std::endl; } RBParameters::const_iterator it = get_parameters().begin(); RBParameters::const_iterator it_end = get_parameters().end(); for( ; it != it_end; ++it) { std::string param_name = it->first; libMesh::out << "Parameter " << param_name << ": Min = " << get_parameter_min(param_name) << ", Max = " << get_parameter_max(param_name) << ", value = " << get_parameters().get_value(param_name) << std::endl; } libMesh::out << "n_training_samples: " << get_n_training_samples() << std::endl; libMesh::out << std::endl; }
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); }
void DerivedRBConstruction<RBConstruction>::update_residual_terms(bool compute_inner_products) { START_LOG("update_residual_terms()", "DerivedRBConstruction"); DerivedRBEvaluation<RBEvaluation>& der_rb_eval = libmesh_cast_ref<DerivedRBEvaluation<RBEvaluation>&>(get_rb_evaluation()); EquationSystems& es = this->get_equation_systems(); RBConstruction& uber_system = es.get_system<RBConstruction>(uber_system_name); const unsigned int Q_a = get_rb_theta_expansion().get_n_A_terms(); const unsigned int Q_f = get_rb_theta_expansion().get_n_F_terms(); switch(der_rb_eval.residual_type_flag) { case(SteadyDerivedRBEvaluation::RESIDUAL_WRT_UBER): { unsigned int derived_RB_size = get_rb_evaluation().get_n_basis_functions(); unsigned int uber_RB_size = uber_system.get_rb_evaluation().get_n_basis_functions(); DenseVector<Number> temp_vector1, temp_vector2; // Now compute and store the inner products (if requested) if (compute_inner_products) { DenseMatrix<Number> temp_matrix; for(unsigned int q_f=0; q_f<Q_f; q_f++) { for(unsigned int q_a=0; q_a<Q_a; q_a++) { for(unsigned int i=(derived_RB_size-delta_N); i<derived_RB_size; i++) { uber_system.get_rb_evaluation().RB_Aq_vector[q_a].get_principal_submatrix(uber_RB_size, temp_matrix); temp_matrix.vector_mult(temp_vector1, der_rb_eval.derived_basis_functions[i]); uber_system.get_rb_evaluation().RB_Fq_vector[q_f].get_principal_subvector(uber_RB_size, temp_vector2); get_rb_evaluation().Fq_Aq_representor_innerprods[q_f][q_a][i] = -temp_vector1.dot(temp_vector2); } } } unsigned int q=0; for(unsigned int q_a1=0; q_a1<Q_a; q_a1++) { for(unsigned int q_a2=q_a1; q_a2<Q_a; q_a2++) { for(unsigned int i=(derived_RB_size-delta_N); i<derived_RB_size; i++) { for(unsigned int j=0; j<derived_RB_size; j++) { uber_system.get_rb_evaluation().RB_Aq_vector[q_a1].get_principal_submatrix(uber_RB_size, temp_matrix); temp_matrix.vector_mult(temp_vector1, der_rb_eval.derived_basis_functions[i]); uber_system.get_rb_evaluation().RB_Aq_vector[q_a2].get_principal_submatrix(uber_RB_size, temp_matrix); temp_matrix.vector_mult(temp_vector2, der_rb_eval.derived_basis_functions[j]); get_rb_evaluation().Aq_Aq_representor_innerprods[q][i][j] = temp_vector1.dot(temp_vector2); if(i != j) { uber_system.get_rb_evaluation().RB_Aq_vector[q_a1].get_principal_submatrix(uber_RB_size, temp_matrix); temp_matrix.vector_mult(temp_vector1, der_rb_eval.derived_basis_functions[j]); uber_system.get_rb_evaluation().RB_Aq_vector[q_a2].get_principal_submatrix(uber_RB_size, temp_matrix); temp_matrix.vector_mult(temp_vector2, der_rb_eval.derived_basis_functions[i]); get_rb_evaluation().Aq_Aq_representor_innerprods[q][j][i] = temp_vector1.dot(temp_vector2); } } } q++; } } } // end if (compute_inner_products) break; } case(SteadyDerivedRBEvaluation::RESIDUAL_WRT_TRUTH): { unsigned int RB_size = get_rb_evaluation().get_n_basis_functions(); for(unsigned int q_f=0; q_f<Q_f; q_f++) { for(unsigned int q_a=0; q_a<Q_a; q_a++) { for(unsigned int i=(RB_size-delta_N); i<RB_size; i++) { get_rb_evaluation().Fq_Aq_representor_innerprods[q_f][q_a][i] = 0.; for(unsigned int j=0; j<uber_system.get_rb_evaluation().get_n_basis_functions(); j++) // Evaluate the dot product { get_rb_evaluation().Fq_Aq_representor_innerprods[q_f][q_a][i] += uber_system.get_rb_evaluation().Fq_Aq_representor_innerprods[q_f][q_a][j] * der_rb_eval.derived_basis_functions[i](j); } } } } unsigned int q=0; for(unsigned int q_a1=0; q_a1<Q_a; q_a1++) { for(unsigned int q_a2=q_a1; q_a2<Q_a; q_a2++) { for(unsigned int i=(RB_size-delta_N); i<RB_size; i++) { for(unsigned int j=0; j<RB_size; j++) { get_rb_evaluation().Aq_Aq_representor_innerprods[q][i][j] = 0.; if(i != j) get_rb_evaluation().Aq_Aq_representor_innerprods[q][j][i] = 0.; for(unsigned int k=0; k<uber_system.get_rb_evaluation().get_n_basis_functions(); k++) for(unsigned int k_prime=0; k_prime<uber_system.get_rb_evaluation().get_n_basis_functions(); k_prime++) { get_rb_evaluation().Aq_Aq_representor_innerprods[q][i][j] += der_rb_eval.derived_basis_functions[i](k)*der_rb_eval.derived_basis_functions[j](k_prime)* uber_system.get_rb_evaluation().Aq_Aq_representor_innerprods[q][k][k_prime]; if(i != j) { get_rb_evaluation().Aq_Aq_representor_innerprods[q][j][i] += der_rb_eval.derived_basis_functions[j](k)*der_rb_eval.derived_basis_functions[i](k_prime)* uber_system.get_rb_evaluation().Aq_Aq_representor_innerprods[q][k][k_prime]; } } } } q++; } } break; } default: { libMesh::out << "Invalid RESIDUAL_TYPE in update_residual_terms" << std::endl; break; } } STOP_LOG("update_residual_terms()", "DerivedRBConstruction"); }
void DerivedRBConstruction<RBConstruction>::compute_Fq_representor_innerprods(bool compute_inner_products) { START_LOG("compute_Fq_representor_innerprods()", "DerivedRBConstruction"); // We don't short-circuit here even if Fq_representor_innerprods_computed = true because // the residual mode may have changed (this function is very cheap so not much // incentive to make sure we do not call it extra times) EquationSystems& es = this->get_equation_systems(); RBConstruction& uber_system = es.get_system<RBConstruction>(uber_system_name); SteadyDerivedRBEvaluation& drb_eval = libmesh_cast_ref< SteadyDerivedRBEvaluation& >(get_rb_evaluation()); const unsigned int Q_f = get_rb_theta_expansion().get_n_F_terms(); switch(drb_eval.residual_type_flag) { case(SteadyDerivedRBEvaluation::RESIDUAL_WRT_UBER): { unsigned int uber_RB_size = uber_system.get_rb_evaluation().get_n_basis_functions(); DenseVector<Number> temp_vector1, temp_vector2; // Assume inner product matrix is the identity, hence don't need to // do any solves if (compute_inner_products) { unsigned int q=0; for(unsigned int q_f1=0; q_f1<Q_f; q_f1++) { for(unsigned int q_f2=q_f1; q_f2<Q_f; q_f2++) { uber_system.get_rb_evaluation().RB_Fq_vector[q_f2].get_principal_subvector(uber_RB_size, temp_vector1); uber_system.get_rb_evaluation().RB_Fq_vector[q_f1].get_principal_subvector(uber_RB_size, temp_vector2); Fq_representor_innerprods[q] = temp_vector1.dot( temp_vector2 ); q++; } } } // end if (compute_inner_products) break; } case(SteadyDerivedRBEvaluation::RESIDUAL_WRT_TRUTH): { // Copy the output terms over from uber_system for(unsigned int n=0; n<get_rb_theta_expansion().get_n_outputs(); n++) { output_dual_innerprods[n] = uber_system.output_dual_innerprods[n]; } // Copy the Fq terms over from uber_system Fq_representor_innerprods = uber_system.Fq_representor_innerprods; break; } default: { libMesh::out << "Invalid RESIDUAL_TYPE in compute_Fq_representor_innerprods" << std::endl; break; } } Fq_representor_innerprods_computed = true; // Copy the Fq_representor_innerprods and output_dual_innerprods to the rb_eval, // where they are actually needed // (we store them in DerivedRBConstruction as well in order to cache // the data and possibly save work) get_rb_evaluation().Fq_representor_innerprods = Fq_representor_innerprods; get_rb_evaluation().output_dual_innerprods = output_dual_innerprods; STOP_LOG("compute_Fq_representor_innerprods()", "DerivedRBConstruction"); }