1 #include "adaptive_sampling_base.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" 10 #include "testing/rom_import_helper_functions.h" 12 #include "rbf_interpolation.h" 13 #include "ROL_Algorithm.hpp" 14 #include "ROL_LineSearchStep.hpp" 15 #include "ROL_StatusTest.hpp" 16 #include "ROL_Stream.hpp" 17 #include "ROL_Bounds.hpp" 19 #include "min_max_scaler.h" 23 template<
int dim,
int nstate>
25 const dealii::ParameterHandler ¶meter_handler_input)
26 : all_parameters(parameters_input)
27 , parameter_handler(parameter_handler_input)
28 , mpi_communicator(MPI_COMM_WORLD)
29 , mpi_rank(dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD))
30 , pcout(
std::cout, mpi_rank==0)
34 const bool compute_dRdW =
true;
35 flow_solver->dg->assemble_residual(compute_dRdW);
36 std::shared_ptr<dealii::TrilinosWrappers::SparseMatrix> system_matrix = std::make_shared<dealii::TrilinosWrappers::SparseMatrix>();
37 system_matrix->copy_from(flow_solver->dg->system_matrix);
38 current_pod = std::make_shared<ProperOrthogonalDecomposition::OnlinePOD<dim>>(system_matrix);
39 nearest_neighbors = std::make_shared<ProperOrthogonalDecomposition::NearestNeighbors>();
42 template <
int dim,
int nstate>
44 std::unique_ptr<dealii::TableHandler> snapshot_table = std::make_unique<dealii::TableHandler>();
46 std::ofstream solution_out_file(
"solution_snapshots_iteration_" + iteration +
".txt");
47 unsigned int precision = 16;
48 current_pod->dealiiSnapshotMatrix.print_formatted(solution_out_file, precision);
49 solution_out_file.close();
58 std::ofstream snapshot_table_file(
"snapshot_table_iteration_" + iteration +
".txt");
59 snapshot_table->write_text(snapshot_table_file, dealii::TableHandler::TextOutputFormat::org_mode_table);
60 snapshot_table_file.close();
62 std::unique_ptr<dealii::TableHandler> rom_table = std::make_unique<dealii::TableHandler>();
69 rom_table->add_value(
"ROM_errors", it->get()->total_error);
70 rom_table->set_precision(
"ROM_errors", 16);
73 std::ofstream rom_table_file(
"rom_table_iteration_" + iteration +
".txt");
74 rom_table->write_text(rom_table_file, dealii::TableHandler::TextOutputFormat::org_mode_table);
75 rom_table_file.close();
79 template <
int dim,
int nstate>
81 RowVectorXd params(1);
86 if (flow_type == FlowCaseEnum::burgers_rewienski_snapshot){
101 else if (flow_type == FlowCaseEnum::naca0012){
116 else if (flow_type == FlowCaseEnum::gaussian_bump){
124 this->
pcout <<
"Invalid flow case. You probably forgot to specify a flow case in the prm file." << std::endl;
130 template <
int dim,
int nstate>
132 this->
pcout <<
"Updating RBF interpolation..." << std::endl;
136 VectorXd errors(n_rows);
144 this->
pcout << i << std::endl;
147 parameters.row(i) = it->get()->parameter.array();
148 errors(i) = it->get()->total_error;
154 MatrixXd parameters_scaled = scaler.
fit_transform(parameters);
157 std::string kernel =
"thin_plate_spline";
161 ROL::ParameterList parlist;
162 parlist.sublist(
"Step").sublist(
"Line Search").sublist(
"Line-Search Method").set(
"Type",
"Backtracking");
163 parlist.sublist(
"Step").sublist(
"Line Search").sublist(
"Descent Method").set(
"Type",
"Quasi-Newton Method");
164 parlist.sublist(
"Step").sublist(
"Line Search").sublist(
"Secant").set(
"Type",
"Limited-Memory BFGS");
165 parlist.sublist(
"Status Test").set(
"Gradient Tolerance",1.e-10);
166 parlist.sublist(
"Status Test").set(
"Step Tolerance",1.e-14);
167 parlist.sublist(
"Status Test").set(
"Iteration Limit",100);
170 RowVectorXd max_error_params(parameters.cols());
175 Eigen::RowVectorXd rom_unscaled = it->get()->parameter;
176 Eigen::RowVectorXd rom_scaled = scaler.
transform(rom_unscaled);
179 int dimension = parameters.cols();
180 ROL::Ptr<std::vector<double>> l_ptr = ROL::makePtr<std::vector<double>>(dimension,0.0);
181 ROL::Ptr<std::vector<double>> u_ptr = ROL::makePtr<std::vector<double>>(dimension,1.0);
182 ROL::Ptr<ROL::Vector<double>> lo = ROL::makePtr<ROL::StdVector<double>>(l_ptr);
183 ROL::Ptr<ROL::Vector<double>> up = ROL::makePtr<ROL::StdVector<double>>(u_ptr);
184 ROL::Bounds<double> bcon(lo,up);
187 ROL::Ptr<ROL::Step<double>> step = ROL::makePtr<ROL::LineSearchStep<double>>(parlist);
188 ROL::Ptr<ROL::StatusTest<double>> status = ROL::makePtr<ROL::StatusTest<double>>(parlist);
189 ROL::Algorithm<double> algo(step,status,
false);
192 ROL::Ptr<std::vector<double>> x_ptr = ROL::makePtr<std::vector<double>>(dimension, 0.0);
195 for(
int j = 0 ; j < dimension ; j++){
196 (*x_ptr)[j] = rom_scaled(j);
199 this->
pcout <<
"Unscaled parameter: " << rom_unscaled << std::endl;
200 this->
pcout <<
"Scaled parameter: ";
201 for(
int j = 0 ; j < dimension ; j++){
202 this->
pcout << (*x_ptr)[j] <<
" ";
204 this->
pcout << std::endl;
206 ROL::StdVector<double> x(x_ptr);
209 algo.run(x, rbf, bcon,
false);
211 ROL::Ptr<std::vector<double>> x_min = x.getVector();
213 for(
int j = 0 ; j < dimension ; j++){
214 rom_scaled(j) = (*x_min)[j];
219 this->
pcout <<
"Parameters of optimization convergence: " << rom_unscaled_optim << std::endl;
221 double error = std::abs(rbf.
evaluate(rom_scaled));
222 this->
pcout <<
"RBF error at optimization convergence: " << error << std::endl;
223 if(error > max_error){
224 this->
pcout <<
"RBF error is greater than current max error. Updating max error." << std::endl;
226 max_error_params = rom_unscaled_optim;
227 this->
pcout <<
"RBF Max error: " << max_error << std::endl;
233 if(max_error_params.isApprox(it->get()->parameter)){
234 this->
pcout <<
"Max error location is approximately the same as a ROM location. Removing ROM location." << std::endl;
240 return max_error_params;
243 template <
int dim,
int nstate>
246 this->
pcout <<
"Sampling initial snapshot at " << snap_param << std::endl;
247 dealii::LinearAlgebra::distributed::Vector<double> fom_solution =
solveSnapshotFOM(snap_param);
254 template <
int dim,
int nstate>
256 this->
pcout <<
"Solving FOM at " << parameter << std::endl;
262 auto ode_solver_type = Parameters::ODESolverParam::ODESolverEnum::implicit_solver;
264 flow_solver->ode_solver->allocate_ode_system();
267 this->
pcout <<
"Done solving FOM." << std::endl;
268 return flow_solver->dg->solution;
271 template <
int dim,
int nstate>
279 if (flow_type == FlowCaseEnum::burgers_rewienski_snapshot){
293 else if (flow_type == FlowCaseEnum::naca0012){
307 else if (flow_type == FlowCaseEnum::gaussian_bump){
315 this->
pcout <<
"Invalid flow case. You probably forgot to specify a flow case in the prm file." << std::endl;
321 template <
int dim,
int nstate>
324 const double pi = atan(1.0) * 4.0;
329 RowVectorXd parameter1_range;
330 parameter1_range.resize(2);
333 parameter1_range *= pi/180;
340 (parameter1_range[0]+parameter1_range[1])/2;
344 double *seq =
nullptr;
345 for (
int i = 0; i < n_halton; i++)
347 seq = ProperOrthogonalDecomposition::halton(i+2, 1);
348 snapshot_parameters(i+3) = seq[0]*(parameter1_range[1] - parameter1_range[0])+parameter1_range[0];
355 RowVectorXd parameter1_range;
356 parameter1_range.resize(2);
359 RowVectorXd parameter2_range;
360 parameter2_range.resize(2);
363 parameter2_range *= pi/180;
369 parameter1_range[0], parameter2_range[1],
370 parameter1_range[1], parameter2_range[1],
371 parameter1_range[1], parameter2_range[0],
372 0.5*(parameter1_range[1] - parameter1_range[0])+parameter1_range[0], parameter2_range[0],
373 0.5*(parameter1_range[1] - parameter1_range[0])+parameter1_range[0], parameter2_range[1],
374 parameter1_range[0], 0.5*(parameter2_range[1] - parameter2_range[0])+parameter2_range[0],
375 parameter1_range[1], 0.5*(parameter2_range[1] - parameter2_range[0])+parameter2_range[0],
376 0.5*(parameter1_range[1] - parameter1_range[0])+parameter1_range[0], 0.5*(parameter2_range[1] - parameter2_range[0])+parameter2_range[0];
380 double *seq =
nullptr;
381 for (
int i = 0; i < n_halton; i++)
383 seq = ProperOrthogonalDecomposition::halton(i+1, 2);
384 for (
int j = 0; j < 2; j++)
387 snapshot_parameters(i+9, j) = seq[j]*(parameter1_range[1] - parameter1_range[0])+parameter1_range[0];
390 snapshot_parameters(i+9, j) = seq[j]*(parameter2_range[1] - parameter2_range[0])+parameter2_range[0];
397 this->
pcout << path << std::endl;
399 this->
pcout <<
"LHS Points " << std::endl;
static std::shared_ptr< ODESolverBase< dim, real, MeshType > > create_ODESolver_manual(Parameters::ODESolverParam::ODESolverEnum ode_solver_type, std::shared_ptr< DGBase< dim, real, MeshType > > dg_input)
Creates either implicit or explicit ODE solver based on manual input (no POD basis given) ...
double max_error
Maximum error.
FlowCaseType
Selects the flow case to be simulated.
FlowCaseType flow_case_type
Selected FlowCaseType from the input file.
const dealii::ParameterHandler & parameter_handler
Parameter handler for storing the .prm file being ran.
FlowSolverParam flow_solver_param
Contains the parameters for simulation cases (flow solver test)
std::vector< std::string > parameter_names
Names of parameters.
double evaluate(const RowVectorXd &evaluate_coordinate) const
Evaluate RBF.
dealii::ConditionalOStream pcout
ConditionalOStream.
RowVectorXd readROMFunctionalPoint() const
Find point to solve for functional from param file.
std::shared_ptr< ProperOrthogonalDecomposition::NearestNeighbors > nearest_neighbors
Nearest neighbors of snapshots.
double mach_inf
Mach number at infinity.
int num_halton
Number of Halton sequence points to add to initial snapshot set.
std::vector< double > parameter_min_values
Minimum value of parameters.
dealii::LinearAlgebra::distributed::Vector< double > solveSnapshotFOM(const RowVectorXd ¶meter) const
Solve full-order snapshot.
Files for the baseline physics.
ReducedOrderModelParam reduced_order_param
Contains parameters for the Reduced-Order model.
EulerParam euler_param
Contains parameters for the Euler equations non-dimensionalization.
void configureInitialParameterSpace() const
Set up parameter space depending on test case.
Main parameter class that contains the various other sub-parameter classes.
MatrixXd fit_transform(const MatrixXd &snapshot_parameters)
Fit and transform data.
static std::unique_ptr< FlowSolver< dim, 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.
std::shared_ptr< ProperOrthogonalDecomposition::OnlinePOD< dim > > current_pod
Most up to date POD basis.
std::string file_path_for_snapshot_locations
Path to search for file with pre-determined snapshot locations used to build POD (actual FOM snapshot...
virtual void outputIterationData(std::string iteration) const
Output for each iteration.
void placeInitialSnapshots() const
Placement of initial snapshots.
double angle_of_attack
Input file provides in degrees, but the value stored here is in radians.
std::vector< double > parameter_max_values
Maximum value of parameters.
AdaptiveSamplingBase(const PHiLiP::Parameters::AllParameters *const parameters_input, const dealii::ParameterHandler ¶meter_handler_input)
Default constructor that will set the constants.
MatrixXd inverse_transform(const MatrixXd &snapshot_parameters)
Unscale data.
MatrixXd transform(const MatrixXd &snapshot_parameters)
Transform data to previously fitted dataset.
std::vector< dealii::LinearAlgebra::distributed::Vector< double > > fom_locations
Vector of parameter-ROMTestLocation pairs.
Radial basis function interpolation.
MatrixXd snapshot_parameters
Matrix of snapshot parameters.
const Parameters::AllParameters *const all_parameters
Pointer to all parameters.
Scale data between 0 and 1.
BurgersParam burgers_param
Contains parameters for Burgers equation.
std::vector< std::unique_ptr< ProperOrthogonalDecomposition::ROMTestLocation< dim, nstate > > > rom_locations
Vector of parameter-ROMTestLocation pairs.
virtual RowVectorXd getMaxErrorROM() const
Compute RBF and find max error.