Real RBEIMConstruction::truth_solve(int plot_solution) { START_LOG("truth_solve()", "RBEIMConstruction"); int training_parameters_found_index = -1; if( _parametrized_functions_in_training_set_initialized ) { // Check if parameters are in the training set. If so, we can just load the // solution from _parametrized_functions_in_training_set for(unsigned int i=0; i<get_n_training_samples(); i++) { if(get_parameters() == get_params_from_training_set(i)) { training_parameters_found_index = i; break; } } } // If the parameters are in the training set, just copy the solution vector if(training_parameters_found_index >= 0) { *solution = *_parametrized_functions_in_training_set[training_parameters_found_index]; update(); // put the solution into current_local_solution as well } // Otherwise, we have to compute the projection else { RBEIMEvaluation& eim_eval = cast_ref<RBEIMEvaluation&>(get_rb_evaluation()); eim_eval.set_parameters( get_parameters() ); // Compute truth representation via projection const MeshBase& mesh = this->get_mesh(); UniquePtr<DGFEMContext> c = this->build_context(); DGFEMContext &context = cast_ref<DGFEMContext&>(*c); this->init_context(context); rhs->zero(); MeshBase::const_element_iterator el = mesh.active_local_elements_begin(); const MeshBase::const_element_iterator end_el = mesh.active_local_elements_end(); for ( ; el != end_el; ++el) { context.pre_fe_reinit(*this, *el); context.elem_fe_reinit(); // All variables should have the same quadrature rule, hence // we can get JxW and xyz based on first_elem_fe. FEBase* first_elem_fe = NULL; context.get_element_fe( 0, first_elem_fe ); unsigned int n_qpoints = context.get_element_qrule().n_points(); const std::vector<Real> &JxW = first_elem_fe->get_JxW(); const std::vector<Point> &xyz = first_elem_fe->get_xyz(); // Loop over qp before var because parametrized functions often use // some caching based on qp. for (unsigned int qp=0; qp<n_qpoints; qp++) { for (unsigned int var=0; var<n_vars(); var++) { FEBase* elem_fe = NULL; context.get_element_fe( var, elem_fe ); const std::vector<std::vector<Real> >& phi = elem_fe->get_phi(); DenseSubVector<Number>& subresidual_var = context.get_elem_residual( var ); unsigned int n_var_dofs = cast_int<unsigned int>(context.get_dof_indices( var ).size()); Number eval_result = eim_eval.evaluate_parametrized_function(var, xyz[qp], *(*el)); for (unsigned int i=0; i != n_var_dofs; i++) subresidual_var(i) += JxW[qp] * eval_result * phi[i][qp]; } } // Apply constraints, e.g. periodic constraints this->get_dof_map().constrain_element_vector(context.get_elem_residual(), context.get_dof_indices() ); // Add element vector to global vector rhs->add_vector(context.get_elem_residual(), context.get_dof_indices() ); } // Solve to find the best fit, then solution stores the truth representation // of the function to be approximated solve_for_matrix_and_rhs(*inner_product_solver, *inner_product_matrix, *rhs); if (assert_convergence) check_convergence(*inner_product_solver); } if(plot_solution > 0) { #ifdef LIBMESH_HAVE_EXODUS_API ExodusII_IO(get_mesh()).write_equation_systems ("truth.exo", this->get_equation_systems()); #endif } STOP_LOG("truth_solve()", "RBEIMConstruction"); return 0.; }
Real RBEIMConstruction::truth_solve(int plot_solution) { START_LOG("truth_solve()", "RBEIMConstruction"); // matrix should have been set to inner_product_matrix during initialization // if(!single_matrix_mode) // { // matrix->zero(); // matrix->add(1., *inner_product_matrix); // } // else // { // assemble_inner_product_matrix(matrix); // } int training_parameters_found_index = -1; if( _parametrized_functions_in_training_set_initialized ) { // Check if parameters are in the training set. If so, we can just load the // solution from _parametrized_functions_in_training_set for(unsigned int i=0; i<get_n_training_samples(); i++) { if(get_parameters() == get_params_from_training_set(i)) { training_parameters_found_index = i; break; } } } // If the parameters are in the training set, just copy the solution vector if(training_parameters_found_index >= 0) { *solution = *_parametrized_functions_in_training_set[training_parameters_found_index]; update(); // put the solution into current_local_solution as well } // Otherwise, we have to compute the projection else { RBEIMEvaluation& eim_eval = libmesh_cast_ref<RBEIMEvaluation&>(get_rb_evaluation()); eim_eval.set_parameters( get_parameters() ); // Compute truth representation via projection const MeshBase& mesh = this->get_mesh(); AutoPtr<FEMContext> c = this->build_context(); FEMContext &context = libmesh_cast_ref<FEMContext&>(*c); this->init_context(context); rhs->zero(); MeshBase::const_element_iterator el = mesh.active_local_elements_begin(); const MeshBase::const_element_iterator end_el = mesh.active_local_elements_end(); for ( ; el != end_el; ++el) { context.pre_fe_reinit(*this, *el); context.elem_fe_reinit(); for(unsigned int var=0; var<n_vars(); var++) { const std::vector<Real> &JxW = context.element_fe_var[var]->get_JxW(); const std::vector<std::vector<Real> >& phi = context.element_fe_var[var]->get_phi(); const std::vector<Point> &xyz = context.element_fe_var[var]->get_xyz(); unsigned int n_qpoints = context.element_qrule->n_points(); unsigned int n_var_dofs = libmesh_cast_int<unsigned int> (context.dof_indices_var[var].size()); DenseSubVector<Number>& subresidual_var = *context.elem_subresiduals[var]; for(unsigned int qp=0; qp<n_qpoints; qp++) for(unsigned int i=0; i != n_var_dofs; i++) subresidual_var(i) += JxW[qp] * eim_eval.evaluate_parametrized_function(var, xyz[qp]) * phi[i][qp]; } // Apply constraints, e.g. periodic constraints this->get_dof_map().constrain_element_vector(context.get_elem_residual(), context.dof_indices); // Add element vector to global vector rhs->add_vector(context.get_elem_residual(), context.dof_indices); } // Solve to find the best fit, then solution stores the truth representation // of the function to be approximated solve(); // Make sure we didn't max out the number of iterations if( (this->n_linear_iterations() >= this->get_equation_systems().parameters.get<unsigned int>("linear solver maximum iterations")) && (this->final_linear_residual() > this->get_equation_systems().parameters.get<Real>("linear solver tolerance")) ) { libMesh::out << "Warning: Linear solver may not have converged! Final linear residual = " << this->final_linear_residual() << ", number of iterations = " << this->n_linear_iterations() << std::endl << std::endl; // libmesh_error(); } if(reuse_preconditioner) { // After we've done a solve we can now reuse the preconditioner // because the matrix is not changing linear_solver->reuse_preconditioner(true); } } if(plot_solution > 0) { #ifdef LIBMESH_HAVE_EXODUS_API ExodusII_IO(get_mesh()).write_equation_systems ("truth.e", this->get_equation_systems()); #endif } STOP_LOG("truth_solve()", "RBEIMConstruction"); return 0.; }
void RBConstructionBase<Base>::set_params_from_training_set(unsigned int index) { set_parameters(get_params_from_training_set(index)); }