1 #include "pod_adaptive_sampling.h" 4 #include "functional/functional.h" 5 #include <deal.II/lac/trilinos_sparse_matrix.h> 6 #include <deal.II/lac/vector_operation.h> 7 #include "reduced_order_solution.h" 8 #include "flow_solver/flow_solver.h" 9 #include "flow_solver/flow_solver_factory.h" 11 #include "rbf_interpolation.h" 12 #include "ROL_Algorithm.hpp" 13 #include "ROL_LineSearchStep.hpp" 14 #include "ROL_StatusTest.hpp" 15 #include "ROL_Stream.hpp" 16 #include "ROL_Bounds.hpp" 18 #include "min_max_scaler.h" 19 #include <deal.II/base/timer.h> 23 template<
int dim,
int nspecies,
int nstate>
25 const dealii::ParameterHandler ¶meter_handler_input)
29 template <
int dim,
int nspecies,
int nstate>
32 this->
pcout <<
"Starting adaptive sampling process" << std::endl;
33 auto stream = this->
pcout;
34 dealii::TimerOutput timer(stream,dealii::TimerOutput::summary,dealii::TimerOutput::wall_times);
36 timer.enter_subsection (
"Iteration " + std::to_string(iteration));
40 MatrixXd rom_points = this->
nearest_neighbors->kPairwiseNearestNeighborsMidpoint();
41 this->
pcout << rom_points << std::endl;
49 this->
pcout <<
"Solving FOM at " << functional_ROM << std::endl;
55 auto ode_solver_type = Parameters::ODESolverParam::ODESolverEnum::implicit_solver;
57 flow_solver_FOM->ode_solver->allocate_ode_system();
58 flow_solver_FOM->run();
62 this->
pcout <<
"FUNCTIONAL FROM FOM" << std::endl;
63 this->
pcout << functional_FOM->evaluate_functional(
false,
false) << std::endl;
70 timer.leave_subsection();
71 timer.enter_subsection (
"Iteration " + std::to_string(iteration+1));
73 this->
pcout <<
"Sampling snapshot at " << max_error_params << std::endl;
74 dealii::LinearAlgebra::distributed::Vector<double> fom_solution = this->
solveSnapshotFOM(max_error_params);
84 it->get()->compute_initial_rom_to_final_rom_error(this->
current_pod);
85 it->get()->compute_total_error();
90 rom_points = this->
nearest_neighbors->kNearestNeighborsMidpoint(max_error_params);
91 this->
pcout << rom_points << std::endl;
102 this->
pcout <<
"FUNCTIONAL FROM ROMs" << std::endl;
103 std::ofstream output_file(
"rom_functional" + std::to_string(iteration+1) +
".txt");
105 std::ostream_iterator<double> output_iterator(output_file,
"\n");
113 timer.leave_subsection();
115 this->
pcout <<
"FUNCTIONAL FROM ROMs" << std::endl;
116 std::ofstream output_file(
"rom_functional.txt");
118 std::ostream_iterator<double> output_iterator(output_file,
"\n");
124 template <
int dim,
int nspecies,
int nstate>
126 bool error_greater_than_tolerance =
false;
127 for(
auto midpoint : rom_points.rowwise()){
130 auto element = std::find_if(this->
rom_locations.begin(), this->
rom_locations.end(), [&midpoint](std::unique_ptr<ProperOrthogonalDecomposition::ROMTestLocation<dim,nspecies,nstate>>& location){
return location->parameter.isApprox(midpoint);} );
133 bool snapshot_exists =
false;
135 if(snap_param.isApprox(midpoint)){
136 snapshot_exists =
true;
140 if(element == this->
rom_locations.end() && snapshot_exists ==
false){
141 std::unique_ptr<ProperOrthogonalDecomposition::ROMSolution<dim, nspecies, nstate>> rom_solution =
solveSnapshotROM(midpoint);
144 error_greater_than_tolerance =
true;
148 this->
pcout <<
"ROM already computed." << std::endl;
151 return error_greater_than_tolerance;
154 template <
int dim,
int nspecies,
int nstate>
157 std::unique_ptr<dealii::TableHandler> rom_table = std::make_unique<dealii::TableHandler>();
159 for(
auto rom : rom_points.rowwise()){
160 for(
int i = 0 ; i < rom_points.cols() ; i++){
165 this->
pcout <<
"Error in the functional: " << error << std::endl;
166 rom_table->add_value(
"ROM_errors", error);
167 rom_table->set_precision(
"ROM_errors", 16);
170 std::ofstream rom_table_file(
"true_error_table_iteration_ROM_post_sampling.txt");
171 rom_table->write_text(rom_table_file, dealii::TableHandler::TextOutputFormat::org_mode_table);
172 rom_table_file.close();
175 template <
int dim,
int nspecies,
int nstate>
177 this->
pcout <<
"Solving ROM at " << parameter << std::endl;
183 auto ode_solver_type_ROM = Parameters::ODESolverParam::ODESolverEnum::pod_petrov_galerkin_solver;
185 flow_solver_ROM->ode_solver->allocate_ode_system();
186 flow_solver_ROM->ode_solver->steady_state();
188 this->
pcout <<
"Done solving ROM." << std::endl;
193 this->
pcout <<
"Solving FOM at " << parameter << std::endl;
198 auto ode_solver_type = Parameters::ODESolverParam::ODESolverEnum::implicit_solver;
200 flow_solver_FOM->ode_solver->allocate_ode_system();
201 flow_solver_FOM->run();
206 this->
pcout <<
"Done solving FOM." << std::endl;
207 return functional_ROM->evaluate_functional(
false,
false) - functional_FOM->evaluate_functional(
false,
false);
210 template <
int dim,
int nspecies,
int nstate>
212 this->
pcout <<
"Solving ROM at " << parameter << std::endl;
218 auto ode_solver_type_ROM = Parameters::ODESolverParam::ODESolverEnum::pod_petrov_galerkin_solver;
220 flow_solver_ROM->ode_solver->allocate_ode_system();
221 flow_solver_ROM->ode_solver->steady_state();
223 this->
pcout <<
"Done solving ROM." << std::endl;
228 rom_functional.emplace_back(functional_ROM->evaluate_functional(
false,
false));
231 template <
int dim,
int nspecies,
int nstate>
234 this->
pcout <<
"Verifying ROM points for recomputation." << std::endl;
236 MatrixXd rom_points(0,0);
238 rom_points.conservativeResize(rom_points.rows()+1, it->get()->parameter.cols());
239 rom_points.row(rom_points.rows()-1) = it->get()->parameter;
243 for(
auto point : rom_points.rowwise()) {
245 MatrixXd scaled_rom_points = scaler.
fit_transform(rom_points);
246 RowVectorXd scaled_point = scaler.
transform(point);
248 VectorXd distances = (scaled_rom_points.rowwise() - scaled_point).rowwise().squaredNorm();
250 std::vector<int> index(distances.size());
251 std::iota(index.begin(), index.end(), 0);
253 std::sort(index.begin(), index.end(),
254 [&](
const int &a,
const int &b) {
255 return distances[a] < distances[b];
258 this->
pcout <<
"Searching ROM points near: " << point << std::endl;
259 double local_mean_error = 0;
260 for (
int i = 1; i < rom_points.cols() + 2; i++) {
261 local_mean_error = local_mean_error + std::abs(this->
rom_locations[index[i]]->total_error);
263 local_mean_error = local_mean_error / (rom_points.cols() + 1);
265 this->
pcout <<
"Total error greater than tolerance. Recomputing ROM solution" << std::endl;
266 std::unique_ptr<ProperOrthogonalDecomposition::ROMSolution<dim, nspecies, nstate>> rom_solution =
solveSnapshotROM(this->
rom_locations[index[0]]->parameter);
267 std::unique_ptr<ProperOrthogonalDecomposition::ROMTestLocation<dim, nspecies, nstate>> rom_location = std::make_unique<ProperOrthogonalDecomposition::ROMTestLocation<dim, nspecies, nstate>>(this->
rom_locations[index[0]]->parameter, std::move(rom_solution));
273 template <
int dim,
int nspecies,
int nstate>
275 this->
pcout <<
"Solving ROM at " << parameter << std::endl;
281 auto ode_solver_type = Parameters::ODESolverParam::ODESolverEnum::pod_petrov_galerkin_solver;
283 flow_solver->ode_solver->allocate_ode_system();
284 flow_solver->ode_solver->steady_state();
288 functional->evaluate_functional(
true,
false,
false);
290 dealii::LinearAlgebra::distributed::Vector<double> solution(flow_solver->dg->solution);
291 dealii::LinearAlgebra::distributed::Vector<double> gradient(functional->dIdw);
293 std::unique_ptr<ProperOrthogonalDecomposition::ROMSolution<dim,nspecies,nstate>> rom_solution = std::make_unique<ProperOrthogonalDecomposition::ROMSolution<dim, nspecies, nstate>>(params, solution, gradient);
294 this->
pcout <<
"Done solving ROM." << std::endl;
299 #if PHILIP_DIM==1 && PHILIP_SPECIES==1 303 #if PHILIP_DIM!=1 && PHILIP_SPECIES==1 std::vector< double > rom_functional
Functional value predicted by the rom at each sammpling iteration at parameter location specified in ...
std::vector< std::string > parameter_names
Names of parameters.
int run_sampling() const override
Run Sampling Procedure.
double solveSnapshotROMandFOM(const RowVectorXd ¶meter) const
Solve FOM and ROM, return error in functional between the models.
Files for the baseline physics.
dealii::LinearAlgebra::distributed::Vector< double > solveSnapshotFOM(const RowVectorXd ¶meter) const
Solve full-order snapshot.
void placeInitialSnapshots() const
Placement of initial snapshots.
MatrixXd snapshot_parameters
Matrix of snapshot parameters.
static std::shared_ptr< ODESolverBase< dim, nspecies, real, MeshType > > create_ODESolver_manual(Parameters::ODESolverParam::ODESolverEnum ode_solver_type, std::shared_ptr< DGBase< dim, nspecies, real, MeshType > > dg_input)
Creates either implicit or explicit ODE solver based on manual input (no POD basis given) ...
ReducedOrderModelParam reduced_order_param
Contains parameters for the Reduced-Order model.
static std::unique_ptr< FlowSolver< dim, nspecies, nstate > > select_flow_case(const Parameters::AllParameters *const parameters_input, const dealii::ParameterHandler ¶meter_handler_input)
Factory to return the correct flow solver given input file.
Parameters::AllParameters reinit_params(const RowVectorXd ¶meter) const
Reinitialize parameters.
const Parameters::AllParameters *const all_parameters
Pointer to all parameters.
dealii::ConditionalOStream pcout
ConditionalOStream.
Main parameter class that contains the various other sub-parameter classes.
Class to compute and store adjoint-based error estimates.
MatrixXd fit_transform(const MatrixXd &snapshot_parameters)
Fit and transform data.
AdaptiveSampling(const PHiLiP::Parameters::AllParameters *const parameters_input, const dealii::ParameterHandler ¶meter_handler_input)
Constructor.
void updateNearestExistingROMs(const RowVectorXd ¶meter) const
Updates nearest ROM points to snapshot if error discrepancy is above tolerance.
int recomputation_coefficient
Recomputation parameter for adaptive sampling algorithm.
virtual void outputIterationData(std::string iteration) const
Output for each iteration.
std::vector< dealii::LinearAlgebra::distributed::Vector< double > > fom_locations
Vector of parameter-ROMTestLocation pairs.
const dealii::ParameterHandler & parameter_handler
Parameter handler for storing the .prm file being ran.
double max_error
Maximum error.
std::vector< std::unique_ptr< ProperOrthogonalDecomposition::ROMTestLocation< dim, nspecies, nstate > > > rom_locations
Vector of parameter-ROMTestLocation pairs.
static std::shared_ptr< Functional< dim, nspecies, nstate, real, MeshType > > create_Functional(PHiLiP::Parameters::AllParameters const *const param, std::shared_ptr< PHiLiP::DGBase< dim, nspecies, real, MeshType > > dg)
Create standard functional object from constant parameter file.
std::unique_ptr< ProperOrthogonalDecomposition::ROMSolution< dim, nspecies, nstate > > solveSnapshotROM(const RowVectorXd ¶meter) const
Solve reduced-order solution.
void trueErrorROM(const MatrixXd &rom_points) const
Compute true/actual error at all ROM points (error in functional between FOM and ROM solution) ...
RowVectorXd readROMFunctionalPoint() const
Find point to solve for functional from param file.
virtual RowVectorXd getMaxErrorROM() const
Compute RBF and find max error.
MatrixXd transform(const MatrixXd &snapshot_parameters)
Transform data to previously fitted dataset.
std::shared_ptr< ProperOrthogonalDecomposition::OnlinePOD< dim, nspecies > > current_pod
Most up to date POD basis.
bool placeROMLocations(const MatrixXd &rom_points) const
Placement of ROMs.
FunctionalParam functional_param
Contains parameters for functional.
void solveFunctionalROM(const RowVectorXd ¶meter) const
Solve ROM and track functional.
double adaptation_tolerance
Tolerance for POD adaptation.
Scale data between 0 and 1.
std::shared_ptr< ProperOrthogonalDecomposition::NearestNeighbors > nearest_neighbors
Nearest neighbors of snapshots.