void RBEIMEvaluation::legacy_read_offline_data_from_files(const std::string & directory_name, bool read_error_bound_data, const bool read_binary_data) { LOG_SCOPE("legacy_read_offline_data_from_files()", "RBEIMEvaluation"); Parent::legacy_read_offline_data_from_files(directory_name, read_error_bound_data); // First, find out how many basis functions we had when Greedy terminated // This was set in RBSystem::read_offline_data_from_files unsigned int n_bfs = this->get_n_basis_functions(); // The writing mode: DECODE for binary, READ for ASCII XdrMODE mode = read_binary_data ? DECODE : READ; // The suffix to use for all the files that are written out const std::string suffix = read_binary_data ? ".xdr" : ".dat"; // Stream for creating file names std::ostringstream file_name; // Read in the interpolation matrix file_name.str(""); file_name << directory_name << "/interpolation_matrix" << suffix; assert_file_exists(file_name.str()); Xdr interpolation_matrix_in(file_name.str(), mode); for(unsigned int i=0; i<n_bfs; i++) { for(unsigned int j=0; j<=i; j++) { Number value; interpolation_matrix_in >> value; interpolation_matrix(i,j) = value; } } interpolation_matrix_in.close(); // Next read in interpolation_points file_name.str(""); file_name << directory_name << "/interpolation_points" << suffix; assert_file_exists(file_name.str()); Xdr interpolation_points_in(file_name.str(), mode); for(unsigned int i=0; i<n_bfs; i++) { Real x_val, y_val, z_val = 0.; interpolation_points_in >> x_val; if(LIBMESH_DIM >= 2) interpolation_points_in >> y_val; if(LIBMESH_DIM >= 3) interpolation_points_in >> z_val; Point p(x_val, y_val, z_val); interpolation_points.push_back(p); } interpolation_points_in.close(); // Next read in interpolation_points_var file_name.str(""); file_name << directory_name << "/interpolation_points_var" << suffix; assert_file_exists(file_name.str()); Xdr interpolation_points_var_in(file_name.str(), mode); for(unsigned int i=0; i<n_bfs; i++) { unsigned int var; interpolation_points_var_in >> var; interpolation_points_var.push_back(var); } interpolation_points_var_in.close(); // Read in the elements corresponding to the interpolation points legacy_read_in_interpolation_points_elem(directory_name); }
void RBEIMEvaluation::legacy_write_offline_data_to_files(const std::string & directory_name, const bool read_binary_data) { LOG_SCOPE("legacy_write_offline_data_to_files()", "RBEIMEvaluation"); Parent::legacy_write_offline_data_to_files(directory_name); // Get the number of basis functions unsigned int n_bfs = get_n_basis_functions(); // The writing mode: ENCODE for binary, WRITE for ASCII XdrMODE mode = read_binary_data ? ENCODE : WRITE; // The suffix to use for all the files that are written out const std::string suffix = read_binary_data ? ".xdr" : ".dat"; if(this->processor_id() == 0) { std::ostringstream file_name; // Next write out the interpolation_matrix file_name.str(""); file_name << directory_name << "/interpolation_matrix" << suffix; Xdr interpolation_matrix_out(file_name.str(), mode); for(unsigned int i=0; i<n_bfs; i++) { for(unsigned int j=0; j<=i; j++) { interpolation_matrix_out << interpolation_matrix(i,j); } } // Next write out interpolation_points file_name.str(""); file_name << directory_name << "/interpolation_points" << suffix; Xdr interpolation_points_out(file_name.str(), mode); for(unsigned int i=0; i<n_bfs; i++) { interpolation_points_out << interpolation_points[i](0); if(LIBMESH_DIM >= 2) interpolation_points_out << interpolation_points[i](1); if(LIBMESH_DIM >= 3) interpolation_points_out << interpolation_points[i](2); } interpolation_points_out.close(); // Next write out interpolation_points_var file_name.str(""); file_name << directory_name << "/interpolation_points_var" << suffix; Xdr interpolation_points_var_out(file_name.str(), mode); for(unsigned int i=0; i<n_bfs; i++) { interpolation_points_var_out << interpolation_points_var[i]; } interpolation_points_var_out.close(); } // Write out the elements associated with the interpolation points. // This uses mesh I/O, hence we have to do it on all processors. legacy_write_out_interpolation_points_elem(directory_name); }
Real RBEIMEvaluation::rb_solve(unsigned int N) { // Short-circuit if we are using the same parameters and value of N if( (_previous_parameters == get_parameters()) && (_previous_N == N) ) { return _previous_error_bound; } // Otherwise, update _previous parameters, _previous_N _previous_parameters = get_parameters(); _previous_N = N; LOG_SCOPE("rb_solve()", "RBEIMEvaluation"); if(N > get_n_basis_functions()) libmesh_error_msg("ERROR: N cannot be larger than the number of basis functions in rb_solve"); if(N==0) libmesh_error_msg("ERROR: N must be greater than 0 in rb_solve"); // Get the rhs by sampling parametrized_function // at the first N interpolation_points DenseVector<Number> EIM_rhs(N); for(unsigned int i=0; i<N; i++) { EIM_rhs(i) = evaluate_parametrized_function(interpolation_points_var[i], interpolation_points[i], *interpolation_points_elem[i]); } DenseMatrix<Number> interpolation_matrix_N; interpolation_matrix.get_principal_submatrix(N, interpolation_matrix_N); interpolation_matrix_N.lu_solve(EIM_rhs, RB_solution); // Optionally evaluate an a posteriori error bound. The EIM error estimate // recommended in the literature is based on using "next" EIM point, so // we skip this if N == get_n_basis_functions() if(evaluate_RB_error_bound && (N != get_n_basis_functions())) { // Compute the a posteriori error bound // First, sample the parametrized function at x_{N+1} Number g_at_next_x = evaluate_parametrized_function(interpolation_points_var[N], interpolation_points[N], *interpolation_points_elem[N]); // Next, evaluate the EIM approximation at x_{N+1} Number EIM_approx_at_next_x = 0.; for(unsigned int j=0; j<N; j++) { EIM_approx_at_next_x += RB_solution(j) * interpolation_matrix(N,j); } Real error_estimate = std::abs(g_at_next_x - EIM_approx_at_next_x); _previous_error_bound = error_estimate; return error_estimate; } else // Don't evaluate an error bound { _previous_error_bound = -1.; return -1.; } }
void RBEIMEvaluation::read_offline_data_from_files(const std::string& directory_name, bool read_error_bound_data, const bool read_binary_data) { START_LOG("read_offline_data_from_files()", "RBEIMEvaluation"); Parent::read_offline_data_from_files(directory_name, read_error_bound_data); // First, find out how many basis functions we had when Greedy terminated // This was set in RBSystem::read_offline_data_from_files unsigned int n_bfs = this->get_n_basis_functions(); // The writing mode: DECODE for binary, READ for ASCII XdrMODE mode = read_binary_data ? DECODE : READ; // The suffix to use for all the files that are written out const std::string suffix = read_binary_data ? ".xdr" : ".dat"; // Stream for creating file names OStringStream file_name; // Read in the interpolation matrix file_name.str(""); file_name << directory_name << "/interpolation_matrix" << suffix; Xdr interpolation_matrix_in(file_name.str(), mode); for(unsigned int i=0; i<n_bfs; i++) { for(unsigned int j=0; j<=i; j++) { Number value; interpolation_matrix_in >> value; interpolation_matrix(i,j) = value; } } interpolation_matrix_in.close(); // Also, read in the "extra" row file_name.str(""); file_name << directory_name << "/extra_interpolation_matrix_row" << suffix; Xdr extra_interpolation_matrix_row_in(file_name.str(), mode); for(unsigned int j=0; j<n_bfs; j++) { Number value; extra_interpolation_matrix_row_in >> value; extra_interpolation_matrix_row(j) = value; } extra_interpolation_matrix_row_in.close(); // Next read in interpolation_points file_name.str(""); file_name << directory_name << "/interpolation_points" << suffix; Xdr interpolation_points_in(file_name.str(), mode); for(unsigned int i=0; i<n_bfs; i++) { Real x_val, y_val, z_val = 0.; interpolation_points_in >> x_val; if(LIBMESH_DIM >= 2) interpolation_points_in >> y_val; if(LIBMESH_DIM >= 3) interpolation_points_in >> z_val; Point p(x_val, y_val, z_val); interpolation_points.push_back(p); } interpolation_points_in.close(); // Also, read in the extra interpolation point file_name.str(""); file_name << directory_name << "/extra_interpolation_point" << suffix; Xdr extra_interpolation_point_in(file_name.str(), mode); for(unsigned int i=0; i<n_bfs; i++) { Real x_val, y_val, z_val = 0.; extra_interpolation_point_in >> x_val; if(LIBMESH_DIM >= 2) extra_interpolation_point_in >> y_val; if(LIBMESH_DIM >= 3) extra_interpolation_point_in >> z_val; Point p(x_val, y_val, z_val); extra_interpolation_point = p; } extra_interpolation_point_in.close(); // Next read in interpolation_points_var file_name.str(""); file_name << directory_name << "/interpolation_points_var" << suffix; Xdr interpolation_points_var_in(file_name.str(), mode); for(unsigned int i=0; i<=n_bfs; i++) { unsigned int var; interpolation_points_var_in >> var; interpolation_points_var.push_back(var); } interpolation_points_var_in.close(); // Also, read in extra_interpolation_point_var file_name.str(""); file_name << directory_name << "/extra_interpolation_point_var" << suffix; Xdr extra_interpolation_point_var_in(file_name.str(), mode); for(unsigned int i=0; i<=n_bfs; i++) { unsigned int var; extra_interpolation_point_var_in >> var; extra_interpolation_point_var = var; } extra_interpolation_point_var_in.close(); STOP_LOG("read_offline_data_from_files()", "RBEIMEvaluation"); }
void RBEIMEvaluation::write_offline_data_to_files(const std::string& directory_name, const bool read_binary_data) { START_LOG("write_offline_data_to_files()", "RBEIMEvaluation"); Parent::write_offline_data_to_files(directory_name); // Get the number of basis functions unsigned int n_bfs = get_n_basis_functions(); // The writing mode: ENCODE for binary, WRITE for ASCII XdrMODE mode = read_binary_data ? ENCODE : WRITE; // The suffix to use for all the files that are written out const std::string suffix = read_binary_data ? ".xdr" : ".dat"; if(libMesh::processor_id() == 0) { OStringStream file_name; // Next write out the interpolation_matrix file_name.str(""); file_name << directory_name << "/interpolation_matrix" << suffix; Xdr interpolation_matrix_out(file_name.str(), mode); for(unsigned int i=0; i<n_bfs; i++) { for(unsigned int j=0; j<=i; j++) { interpolation_matrix_out << interpolation_matrix(i,j); } } // Also, write out the "extra" row file_name.str(""); file_name << directory_name << "/extra_interpolation_matrix_row" << suffix; Xdr extra_interpolation_matrix_row_out(file_name.str(), mode); for(unsigned int j=0; j<n_bfs; j++) { extra_interpolation_matrix_row_out << extra_interpolation_matrix_row(j); } extra_interpolation_matrix_row_out.close(); // Next write out interpolation_points file_name.str(""); file_name << directory_name << "/interpolation_points" << suffix; Xdr interpolation_points_out(file_name.str(), mode); for(unsigned int i=0; i<n_bfs; i++) { interpolation_points_out << interpolation_points[i](0); if(LIBMESH_DIM >= 2) interpolation_points_out << interpolation_points[i](1); if(LIBMESH_DIM >= 3) interpolation_points_out << interpolation_points[i](2); } interpolation_points_out.close(); // Also, write out the "extra" interpolation point file_name.str(""); file_name << directory_name << "/extra_interpolation_point" << suffix; Xdr extra_interpolation_point_out(file_name.str(), mode); extra_interpolation_point_out << extra_interpolation_point(0); if(LIBMESH_DIM >= 2) extra_interpolation_point_out << extra_interpolation_point(1); if(LIBMESH_DIM >= 3) extra_interpolation_point_out << extra_interpolation_point(2); extra_interpolation_point_out.close(); // Next write out interpolation_points_var file_name.str(""); file_name << directory_name << "/interpolation_points_var" << suffix; Xdr interpolation_points_var_out(file_name.str(), mode); for(unsigned int i=0; i<n_bfs; i++) { interpolation_points_var_out << interpolation_points_var[i]; } interpolation_points_var_out.close(); // Also, write out the "extra" interpolation variable file_name.str(""); file_name << directory_name << "/extra_interpolation_point_var" << suffix; Xdr extra_interpolation_point_var_out(file_name.str(), mode); extra_interpolation_point_var_out << extra_interpolation_point_var; extra_interpolation_point_var_out.close(); } STOP_LOG("write_offline_data_to_files()", "RBEIMEvaluation"); }
Real RBEIMEvaluation::rb_solve(unsigned int N) { // Short-circuit if we are using the same parameters and value of N if( (_previous_parameters == get_parameters()) && (_previous_N == N) ) { return _previous_error_bound; } // Otherwise, update _previous parameters, _previous_N _previous_parameters = get_parameters(); _previous_N = N; START_LOG("rb_solve()", "RBEIMEvaluation"); if(N > get_n_basis_functions()) { libMesh::err << "ERROR: N cannot be larger than the number " << "of basis functions in rb_solve" << std::endl; libmesh_error(); } if(N==0) { libMesh::err << "ERROR: N must be greater than 0 in rb_solve" << std::endl; libmesh_error(); } // Get the rhs by sampling parametrized_function // at the first N interpolation_points DenseVector<Number> EIM_rhs(N); for(unsigned int i=0; i<N; i++) { EIM_rhs(i) = evaluate_parametrized_function(interpolation_points_var[i], interpolation_points[i]); } DenseMatrix<Number> interpolation_matrix_N; interpolation_matrix.get_principal_submatrix(N, interpolation_matrix_N); interpolation_matrix_N.lu_solve(EIM_rhs, RB_solution); // Evaluate an a posteriori error bound if(evaluate_RB_error_bound) { // Compute the a posteriori error bound // First, sample the parametrized function at x_{N+1} Number g_at_next_x; if(N == get_n_basis_functions()) g_at_next_x = evaluate_parametrized_function(extra_interpolation_point_var, extra_interpolation_point); else g_at_next_x = evaluate_parametrized_function(interpolation_points_var[N], interpolation_points[N]); // Next, evaluate the EIM approximation at x_{N+1} Number EIM_approx_at_next_x = 0.; for(unsigned int j=0; j<N; j++) { if(N == get_n_basis_functions()) { EIM_approx_at_next_x += RB_solution(j) * extra_interpolation_matrix_row(j); } else { EIM_approx_at_next_x += RB_solution(j) * interpolation_matrix(N,j); } } Real error_estimate = std::abs(g_at_next_x - EIM_approx_at_next_x); STOP_LOG("rb_solve()", "RBEIMEvaluation"); _previous_error_bound = error_estimate; return error_estimate; } else // Don't evaluate an error bound { STOP_LOG("rb_solve()", "RBEIMEvaluation"); _previous_error_bound = -1.; return -1.; } }