[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
grid_refinement_study.cpp
1 #include "grid_refinement_study.h"
2 
3 #include <deal.II/base/convergence_table.h>
4 #include <deal.II/distributed/shared_tria.h>
5 #include <deal.II/distributed/tria.h>
6 #include <deal.II/dofs/dof_tools.h>
7 #include <deal.II/fe/fe_values.h>
8 #include <deal.II/grid/grid_generator.h>
9 #include <deal.II/grid/grid_in.h>
10 #include <deal.II/grid/grid_out.h>
11 #include <deal.II/grid/grid_refinement.h>
12 #include <deal.II/grid/grid_tools.h>
13 #include <deal.II/grid/tria.h>
14 #include <deal.II/numerics/vector_tools.h>
15 #include <stdlib.h> /* srand, rand */
16 
17 #include <Sacado.hpp>
18 #include <chrono>
19 #include <iostream>
20 #include <type_traits>
21 
22 #include "dg/dg_base.hpp"
23 #include "dg/dg_factory.hpp"
24 #include "functional/adjoint.h"
25 #include "functional/functional.h"
26 #include "grid_refinement/gmsh_out.h"
27 #include "grid_refinement/gnu_out.h"
28 #include "grid_refinement/grid_refinement.h"
29 #include "grid_refinement/msh_out.h"
30 #include "grid_refinement/size_field.h"
31 #include "ode_solver/ode_solver_factory.h"
32 #include "physics/manufactured_solution.h"
33 #include "physics/model_factory.h"
34 #include "physics/physics_factory.h"
35 #include "tests.h"
36 
37 namespace PHiLiP {
38 
39 namespace Tests {
40 
41 template <int dim, int nstate>
42 class InitialConditions : public dealii::Function<dim>
43 {
44 public:
45  InitialConditions() : dealii::Function<dim,double>(nstate){}
46 
47  double value(const dealii::Point<dim> &/* point */, const unsigned int /* istate */) const override
48  {
49  return 0.0;
50  }
51 };
52 
53 template <int dim, int nstate, typename MeshType>
55  const Parameters::AllParameters *const parameters_input) :
56  TestsBase::TestsBase(parameters_input){}
57 
58 template <int dim, int nstate, typename MeshType>
60 {
61  pcout << " Running Grid Refinement Study. " << std::endl;
64 
65  using ADtype = Sacado::Fad::DFad<double>;
66 
67  const unsigned int poly_degree = grs_param.poly_degree;
68  const unsigned int poly_degree_max = grs_param.poly_degree_max;
69  const unsigned int poly_degree_grid = grs_param.poly_degree_grid;
70 
71  const unsigned int num_refinements = grs_param.num_refinements;
72 
73  // creating the model object for physics
74  std::shared_ptr< Physics::ModelBase<dim,nstate,double> > model_double
76  std::shared_ptr< Physics::ModelBase<dim,nstate,ADtype> > model_adtype
78 
79  // creating the physics object
80  std::shared_ptr< Physics::PhysicsBase<dim,nstate,double> > physics_double
82  std::shared_ptr< Physics::PhysicsBase<dim,nstate,ADtype> > physics_adtype
84 
85  // for each of the runs, a seperate refinement table
86  std::vector<dealii::ConvergenceTable> convergence_table_vector;
87 
88  // output for convergence figure
91 
92  std::vector<double> error_per_cell;
93 
94  // start of loop for each grid refinement run
95  for(unsigned int iref = 0; iref < (num_refinements?num_refinements:1); ++iref){
96  // getting the parameters for this run
97  const Parameters::GridRefinementParam gr_param = grs_param.grid_refinement_param_vector[iref];
98 
99  const unsigned int refinement_steps = gr_param.refinement_steps;
100 
101  std::shared_ptr<MeshType> grid =
103 
104  // getting the grid from GridEnum type
105  get_grid(grid, grs_param);
106 
107  // approximating the exact functional solution using a fine grid version
108  double functional_value_exact;
109  if(grs_param.approximate_functional){
110  functional_value_exact = approximate_exact_functional(
111  physics_double,
112  physics_adtype,
113  param,
114  grs_param);
115  }else{
116  functional_value_exact = grs_param.functional_value;
117  }
118  std::cout << "Functional estimate = " << functional_value_exact << std::endl;
119 
120  // generate DG
121  std::shared_ptr< DGBase<dim, double, MeshType> > dg
123  &param,
124  poly_degree,
125  poly_degree_max,
126  poly_degree_grid,
127  grid);
128  dg->allocate_system();
129 
130  // initialize the solution
131  std::shared_ptr<dealii::Function<dim>> initial_conditions =
132  std::make_shared<InitialConditions<dim,nstate>>();
133 
134  dealii::LinearAlgebra::distributed::Vector<double> solution_no_ghost;
135  solution_no_ghost.reinit(dg->locally_owned_dofs, MPI_COMM_WORLD);
136  const auto mapping = *(dg->high_order_grid->mapping_fe_field);
137  dealii::VectorTools::interpolate(mapping, dg->dof_handler, *initial_conditions, solution_no_ghost);
138  dg->solution = solution_no_ghost;
139 
140  // generate ODE solver
141  std::shared_ptr< ODE::ODESolverBase<dim,double,MeshType> > ode_solver
143  // ode_solver->steady_state();
144  // ode_solver->initialize_steady_polynomial_ramping(poly_degree);
145 
146  // generate Functional
147  std::shared_ptr< Functional<dim,nstate,double,MeshType> > functional
149 
150  // generate Adjoint
151  std::shared_ptr< Adjoint<dim,nstate,double,MeshType> > adjoint
152  = std::make_shared< Adjoint<dim,nstate,double,MeshType> >(dg, functional, physics_adtype);
153 
154  // generate the GridRefinement
155  std::shared_ptr< GridRefinement::GridRefinementBase<dim,nstate,double,MeshType> > grid_refinement
157 
158  // starting the iterations
159  dealii::ConvergenceTable convergence_table;
160  dealii::Vector<float> estimated_error_per_cell(grid->n_active_cells());
161 
162  // for plotting the error convergence with gnuplot
163  std::vector<double> solution_error;
164  std::vector<double> functional_error;
165  std::vector<double> dofs;
166 
167  for(unsigned int igrid = 0; igrid < refinement_steps; ++igrid){
168  if(igrid > 0){
169  grid_refinement->refine_grid();
170 
171  // option to quit here for testing mesh output
172  if(gr_param.exit_after_refine)
173  continue;
174  }
175 
176  // outputting the grid information
177  const unsigned int n_global_active_cells = grid->n_global_active_cells();
178  const unsigned int n_dofs = dg->dof_handler.n_dofs();
179  pcout << "Dimension: " << dim << "\t Polynomial degree p: " << poly_degree << std::endl
180  << "Grid number: " << igrid+1 << "/" << refinement_steps
181  << ". Number of active cells: " << n_global_active_cells
182  << ". Number of degrees of freedom: " << n_dofs
183  << std::endl;
184 
185  /* temp, zeroing solution */
186  // {
187  // dg->solution *= 0.;
188  // }
189 
190  // solving the system
191  // option of whether to solve the problem or interpolate it from the manufactured solution
192  auto solve_start = std::chrono::steady_clock::now();
193  if(!grs_param.use_interpolation){
194  ode_solver->steady_state();
195  }else{
196  dealii::LinearAlgebra::distributed::Vector<double> solution_no_ghost;
197  solution_no_ghost.reinit(dg->locally_owned_dofs, MPI_COMM_WORLD);
198  dealii::VectorTools::interpolate(dg->dof_handler, *(physics_double->manufactured_solution_function), solution_no_ghost);
199  dg->solution = solution_no_ghost;
200  }
201  auto solve_end = std::chrono::steady_clock::now();
202  auto solve_diff = solve_end - solve_start;
203 
204  // TODO: computing necessary values
205  int overintegrate = 10;
206  dealii::QGauss<dim> quad_extra(dg->max_degree+overintegrate);
207  dealii::FEValues<dim,dim> fe_values_extra(*(dg->high_order_grid->mapping_fe_field), dg->fe_collection[poly_degree], quad_extra,
208  dealii::update_values | dealii::update_JxW_values | dealii::update_quadrature_points);
209  const unsigned int n_quad_pts = fe_values_extra.n_quadrature_points;
210  std::array<double,nstate> soln_at_q;
211 
212  double linf_norm = 0.0;
213  double l2_norm = 0.0;
214 
215  std::vector<dealii::types::global_dof_index> dofs_indices(fe_values_extra.dofs_per_cell);
216 
217  error_per_cell.resize(n_global_active_cells);
218 
219  for(auto cell = dg->dof_handler.begin_active(); cell < dg->dof_handler.end(); ++cell){
220  if(!cell->is_locally_owned()) continue;
221 
222  fe_values_extra.reinit(cell);
223  cell->get_dof_indices(dofs_indices);
224 
225  double cell_l2error = 0.0;
226  std::array<double,nstate> cell_linf;
227  std::fill(cell_linf.begin(), cell_linf.end(), 0);
228 
229  for(unsigned int iquad = 0; iquad < n_quad_pts; ++iquad){
230  std::fill(soln_at_q.begin(), soln_at_q.end(), 0);
231  for(unsigned int idof = 0; idof < fe_values_extra.dofs_per_cell; ++idof){
232  const unsigned int istate = fe_values_extra.get_fe().system_to_component_index(idof).first;
233  soln_at_q[istate] += dg->solution[dofs_indices[idof]] * fe_values_extra.shape_value_component(idof, iquad, istate);
234  }
235 
236  const dealii::Point<dim> qpoint = (fe_values_extra.quadrature_point(iquad));
237 
238  for(unsigned int istate = 0; istate < nstate; ++ istate){
239  const double uexact = physics_double->manufactured_solution_function->value(qpoint, istate);
240  cell_l2error += pow(soln_at_q[istate] - uexact, 2) * fe_values_extra.JxW(iquad);
241  cell_linf[istate] = std::max(cell_linf[istate], abs(soln_at_q[istate]-uexact));
242  }
243  }
244 
245  error_per_cell[cell->active_cell_index()] = l2_norm;
246 
247  l2_norm += cell_l2error;
248  for(unsigned int istate = 0; istate < nstate; ++ istate){
249  linf_norm = std::max(linf_norm, cell_linf[istate]);
250  }
251  }
252  const double l2_norm_mpi = std::sqrt(dealii::Utilities::MPI::sum(l2_norm, mpi_communicator));
253  const double linf_norm_mpi = dealii::Utilities::MPI::max(linf_norm, mpi_communicator);
254 
255  // computing the functional value
256  double functional_value = functional->evaluate_functional();
257 
258  // getting the functional error from the approximated fine grid functional value
259  double func_error = abs(functional_value - functional_value_exact);
260 
261  // reinitializing the adjoint
262  adjoint->reinit();
263 
264  // optional output of the adjoint results to vtk
265  if(grs_param.output_adjoint_vtk){
266  // evaluating the derivatives and the fine grid adjoint
267  if(dg->get_max_fe_degree() + 1 <= dg->max_degree){ // don't output if at max order (as p-enrichment will segfault)
268  auto adj_start = std::chrono::steady_clock::now();
270  adjoint->fine_grid_adjoint();
271  estimated_error_per_cell.reinit(grid->n_active_cells());
272  estimated_error_per_cell = adjoint->dual_weighted_residual();
273  auto adj_end = std::chrono::steady_clock::now();
274  auto adj_diff = adj_end - adj_start;
275 
276  // entries for timing
277  if(grs_param.output_adjoint_time){
278  convergence_table.add_value("adj_time", ((double)std::chrono::duration_cast<std::chrono::milliseconds>(adj_diff).count())/1000.);
279  }
280 
281  adjoint->output_results_vtk(iref*10+igrid);
282  }
283 
284  // and for the coarse grid
285  adjoint->convert_to_state(PHiLiP::Adjoint<dim,nstate,double,MeshType>::AdjointStateEnum::coarse); // this one is necessary though
286  adjoint->coarse_grid_adjoint();
287  adjoint->output_results_vtk(iref*10+igrid);
288  }
289 
290  // outputting the results from the grid refinement method
291  if(grs_param.output_vtk)
292  grid_refinement->output_results_vtk(iref);
293 
294  // convergence table
295  if(grs_param.output_solution_error || grs_param.output_functional_error){
296  convergence_table.add_value("cells", n_global_active_cells);
297  convergence_table.add_value("DoFs", n_dofs);
298  }
299 
300  // entries corresponding to the functional error
301  if(grs_param.output_functional_error){
302  convergence_table.add_value("value", functional_value);
303  convergence_table.add_value("func_error", func_error);
304  }
305 
306  // entries corresponding to the solution error
307  if(grs_param.output_solution_error){
308  convergence_table.add_value("l2_error", l2_norm_mpi);
309  convergence_table.add_value("linf_error", linf_norm_mpi);
310  }
311 
312  // entries for timing
313  if(grs_param.output_solution_time){
314  convergence_table.add_value("solve_time", ((double)std::chrono::duration_cast<std::chrono::milliseconds>(solve_diff).count())/1000.);
315  }
316 
317  solution_error.push_back(l2_norm_mpi);
318  functional_error.push_back(func_error);
319 
320  dofs.push_back(n_dofs);
321 
322  // temp
323  PHiLiP::GridRefinement::MshOut<dim,double> msh_out(dg->dof_handler);
324  std::string write_msh_name = "test-msh-" + dealii::Utilities::int_to_string(iref*10+igrid) + ".msh";
325  std::ofstream out_msh(write_msh_name);
326  msh_out.add_data_vector(error_per_cell, PHiLiP::GridRefinement::StorageType::element);
327  msh_out.write_msh(out_msh);
328  }
329 
330  if(grs_param.output_solution_error || grs_param.output_functional_error){
331  pcout << " ********************************************" << std::endl
332  << " Convergence rates for p = " << poly_degree << std::endl
333  << " ********************************************" << std::endl;
334  }
335 
336  // entries corresponding to the functional
337  if(grs_param.output_functional_error){
338  convergence_table.evaluate_convergence_rates("value", "cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
339  convergence_table.set_scientific("value", true);
340  convergence_table.evaluate_convergence_rates("func_error", "cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
341  convergence_table.set_scientific("func_error", true);
342  }
343 
344  // entries corresponding to the solution
345  if(grs_param.output_solution_error){
346  convergence_table.evaluate_convergence_rates("l2_error", "cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
347  convergence_table.set_scientific("l2_error", true);
348  convergence_table.evaluate_convergence_rates("linf_error", "cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
349  convergence_table.set_scientific("linf_error", true);
350  }
351 
352  if(pcout.is_active()) convergence_table.write_text(pcout.get_stream());
353 
354  convergence_table_vector.push_back(convergence_table);
355 
356  // adding the data to gnuplot figure
357  if(pcout.is_active() && grs_param.output_gnuplot_solution){
358  gf_solution.add_xy_data(dofs, solution_error, "l2error."+dealii::Utilities::int_to_string(iref,1));
359 
360  // if refresh flag is set, output the plot at each iteration
361  if(grs_param.refresh_gnuplot)
362  output_gnufig_solution(gf_solution);
363  }
364 
365  if(pcout.is_active() && grs_param.output_gnuplot_functional){
366  gf_functional.add_xy_data(dofs, functional_error, "ferror."+dealii::Utilities::int_to_string(iref,1));
367 
368  // if refresh flag is set, output the plot at each iteration
369  if(grs_param.refresh_gnuplot)
370  output_gnufig_functional(gf_functional);
371  }
372 
373  }
374 
375  pcout << std::endl << std::endl << std::endl << std::endl
376  << " ********************************************" << std::endl
377  << " Convergence summary" << std::endl
378  << " ********************************************" << std::endl;
379  for(auto conv = convergence_table_vector.begin(); conv != convergence_table_vector.end(); ++conv){
380  if(pcout.is_active()) conv->write_text(pcout.get_stream());
381  pcout << " ********************************************" << std::endl;
382  }
383 
384  if(pcout.is_active() && grs_param.output_gnuplot_solution)
385  output_gnufig_solution(gf_solution);
386 
387  if(pcout.is_active() && grs_param.output_gnuplot_functional)
388  output_gnufig_functional(gf_functional);
389 
390  return 0;
391 }
392 
393 // gets the grid from the enum and reads file if neccesary
394 template <int dim, int nstate, typename MeshType>
396  const std::shared_ptr<MeshType>& grid,
397  const Parameters::GridRefinementStudyParam& grs_param) const
398 {
399  const unsigned int grid_size = grs_param.grid_size;
400 
401  const double left = grs_param.grid_left;
402  const double right = grs_param.grid_right;
403 
404  // generating the mesh
406 
407  // considering different cases
408  if(grs_param.grid_type == GridEnum::hypercube){
409 
410  dealii::Point<dim,double> p_left;
411  dealii::Point<dim,double> p_right;
412  std::vector<unsigned int> repetitions;
413  for(unsigned int i = 0; i < dim; ++i){
414  p_left[i] = left;
415  p_right[i] = right;
416  repetitions.push_back(grid_size);
417  }
418 
419  // subdivided cube
420  bool colorize = true;
421  dealii::GridGenerator::subdivided_hyper_rectangle(*grid, repetitions, p_left, p_right, colorize);
422  // dealii::GridGenerator::subdivided_hyper_cube(*grid, grid_size, left, right);
423  for(auto cell = grid->begin_active(); cell != grid->end(); ++cell){
424  cell->set_material_id(9002);
425  for(unsigned int face = 0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face)
426  if(cell->face(face)->at_boundary()){
427  // temporarily disable
428  // cell->face(face)->set_boundary_id(1000);
429  // std::cout << cell->face(face)->boundary_id() << ", " << cell->face(face)->center() << std::endl;
430  }
431  }
432 
433  }else if(grs_param.grid_type == GridEnum::read_grid){
434 
435  // input grid file
436  std::string read_mshname = grs_param.input_grid;
437  std::cout << "Reading grid from: " << read_mshname << std::endl;
438 
439  // performing the read from file
440  std::ifstream in_msh(read_mshname);
441  dealii::GridIn<dim,dim> grid_in;
442 
443  grid_in.attach_triangulation(*grid);
444  grid_in.read_msh(in_msh);
445 
446  }
447 }
448 
449 // performs the approximation of the functional value using a refined grid with interpolation
450 template <int dim, int nstate, typename MeshType>
452  const std::shared_ptr<Physics::PhysicsBase<dim,nstate,double>>& physics_double,
453  const std::shared_ptr<Physics::PhysicsBase<dim,nstate,Sacado::Fad::DFad<double>>>& /* physics_adtype */,
454  const Parameters::AllParameters& param,
455  const Parameters::GridRefinementStudyParam& grs_param) const
456 {
457  // temporary meshtype object
458  std::shared_ptr<MeshType> grid_fine =
460 
461  // getting the grid from GridEnum type
462  get_grid(grid_fine, grs_param);
463 
464  // performing refinement
465  const int N_ref = 5;
466  std::cout << "Starting refinement." << std::endl;
467  grid_fine->refine_global(N_ref);
468  std::cout << "Finished refinement." << std::endl;
469 
470  const unsigned int poly_degree = grs_param.poly_degree;
471  const unsigned int poly_degree_max = grs_param.poly_degree_max;
472  const unsigned int poly_degree_grid = grs_param.poly_degree_grid;
473 
474  // building the discontinuous galerkin solver
475  std::cout << "Creating fine dg." << std::endl;
476  std::shared_ptr< DGBase<dim, double, MeshType> > dg_fine =
478  &param,
479  poly_degree,
480  poly_degree_max,
481  poly_degree_grid,
482  grid_fine);
483  dg_fine->allocate_system();
484 
485  // interpolating the solution from the manufactured solution
486  std::cout << "Performing solution transfer." << std::endl;
487  dealii::LinearAlgebra::distributed::Vector<double> solution_no_ghost;
488  solution_no_ghost.reinit(dg_fine->locally_owned_dofs, MPI_COMM_WORLD);
489  dealii::VectorTools::interpolate(dg_fine->dof_handler, *(physics_double->manufactured_solution_function), solution_no_ghost);
490  dg_fine->solution = solution_no_ghost;
491 
492  // creating a functional
493  std::cout << "Generating the functional." << std::endl;
494  std::shared_ptr< Functional<dim,nstate,double,MeshType> > functional_fine
496 
497  // getting the "exact" value using it
498  std::cout << "Computing and returning approximation" << std::endl;
499  return functional_fine->evaluate_functional();
500 }
501 
502 // function to perform the formatted output to gnuplot (of the solution error)
503 void output_gnufig_solution(PHiLiP::GridRefinement::GnuFig<double> &gf)
504 {
505  // formatting for the figure and outputting .gp
506  gf.set_name("ErrorPlot");
507  gf.set_title("Error Convergence, |u|_2 vs. Dofs");
508  gf.set_x_label("# Dofs");
509  gf.set_y_label("L2 Error, |u|_2");
510  gf.set_grid(false);
511  gf.set_x_scale_log(true);
512  gf.set_y_scale_log(true);
513  gf.set_legend(true);
514  gf.write_gnuplot();
515 
516  // performing plotting
517  gf.exec_gnuplot();
518 }
519 
520 // function to perform the formatted output to gnuplot (of the funcitonal error)
521 void output_gnufig_functional(
523 {
524  // formatting for the figure and outputting .gp
525  gf.set_name("FunctionalPlot");
526  gf.set_title("Functional Convergence, |J(u)-J_h(u_h)| vs. Dofs");
527  gf.set_x_label("# Dofs");
528  gf.set_y_label("Functional error, |J(u)-J_h(u_h)|");
529  gf.set_grid(false);
530  gf.set_x_scale_log(true);
531  gf.set_y_scale_log(true);
532  gf.set_legend(true);
533  gf.write_gnuplot();
534 
535  // performing plotting
536  gf.exec_gnuplot();
537 }
538 
539 // mesh factory specializations
540 template <>
541 std::shared_ptr<dealii::Triangulation<PHILIP_DIM>>
542 MeshFactory<dealii::Triangulation<PHILIP_DIM>>::create_MeshType(const MPI_Comm /* mpi_communicator */)
543 {
544  return std::make_shared<dealii::Triangulation<PHILIP_DIM>>();
545  // new dealii::Triangulation<PHILIP_DIM>(
546  // typename dealii::Triangulation<PHILIP_DIM>::MeshSmoothing(
547  // dealii::Triangulation<PHILIP_DIM>::smoothing_on_refinement |
548  // dealii::Triangulation<PHILIP_DIM>::smoothing_on_coarsening)));
549 }
550 
551 template <>
552 std::shared_ptr<dealii::parallel::shared::Triangulation<PHILIP_DIM>>
554 {
555  return std::make_shared<dealii::parallel::shared::Triangulation<PHILIP_DIM>>(
557  typename dealii::Triangulation<PHILIP_DIM>::MeshSmoothing(
558  dealii::Triangulation<PHILIP_DIM>::smoothing_on_refinement |
559  dealii::Triangulation<PHILIP_DIM>::smoothing_on_coarsening));
560 }
561 
562 #if PHILIP_DIM != 1
563 template <>
564 std::shared_ptr<dealii::parallel::distributed::Triangulation<PHILIP_DIM>>
565 MeshFactory<dealii::parallel::distributed::Triangulation<PHILIP_DIM>>::create_MeshType(const MPI_Comm mpi_communicator)
566 {
567  return std::make_shared<dealii::parallel::distributed::Triangulation<PHILIP_DIM>>(
569  typename dealii::Triangulation<PHILIP_DIM>::MeshSmoothing(
570  dealii::Triangulation<PHILIP_DIM>::smoothing_on_refinement |
571  dealii::Triangulation<PHILIP_DIM>::smoothing_on_coarsening));
572 }
573 #endif
574 
580 
586 
587 #if PHILIP_DIM!=1
593 #endif
594 
595 } // namespace Tests
596 
597 } // namespace PHiLiP
Output class for GMSH .msh v4.1 file format.
Definition: msh_out.h:208
void set_y_scale_log(const bool ylog_bool_input)
Set flag for logarithmic y-axis.
Definition: gnu_out.cpp:72
bool output_gnuplot_functional
Flag to enable output of gnuplot graph of functional error convergence.
void add_data_vector(std::vector< T > data, StorageType storage_type)
Add data vector of specified storage type and values.
Definition: msh_out.h:229
bool refresh_gnuplot
Flag to enable gnuplot refresh between iteration runs.
void set_x_label(const std::string &xlabel_input)
Sets the x-axis label.
Definition: gnu_out.cpp:44
void set_y_label(const std::string &ylabel_input)
Sets the y-axis label.
Definition: gnu_out.cpp:51
Adjoint class.
Definition: adjoint.h:39
const MPI_Comm mpi_communicator
MPI communicator.
Definition: tests.h:39
unsigned int poly_degree_grid
Initial grid polynomial degree.
void set_name(const std::string &name_input)
Sets the file output name (without extension)
Definition: gnu_out.cpp:30
bool use_interpolation
Flag to enable interpolation operation.
double approximate_exact_functional(const std::shared_ptr< Physics::PhysicsBase< dim, nstate, double >> &physics_double, const std::shared_ptr< Physics::PhysicsBase< dim, nstate, Sacado::Fad::DFad< double >>> &physics_adtype, const Parameters::AllParameters &param, const Parameters::GridRefinementStudyParam &grs_param) const
Approximates the exact functional using a uniformly refined grid.
Gnuplot utility class.
Definition: gnu_out.h:16
void set_legend(const bool legend_bool_input)
Sets display visibility of figure legend.
Definition: gnu_out.cpp:79
unsigned int num_refinements
Number of different refinement procedures stored, 0 indicates to use the default pathway.
Files for the baseline physics.
Definition: ADTypes.hpp:10
bool output_solution_time
Flag to enable output of grid refinement wall-clock solution time.
GridRefinementStudyParam grid_refinement_study_param
Contains the parameters for grid refinement study.
void write_msh(std::ostream &out)
Output formatted .msh v4.1 file with mesh description and data field.
Definition: msh_out.cpp:31
std::array< GridRefinementParam, MAX_REFINEMENTS > grid_refinement_param_vector
Array of grid refinement parameters to be run as part of grid refinement study.
unsigned int poly_degree_max
Maximimum allocated solution polynomial degree.
void add_xy_data(const std::vector< real > &x_data, const std::vector< real > &y_data)
Adds 2D x vs. y data to be plotted (default legend label)
Definition: gnu_out.cpp:86
Main parameter class that contains the various other sub-parameter classes.
bool approximate_functional
Flag to enable approximation of the functional value on a fine grid before refinement run...
void exec_gnuplot()
Executes the gnuplot file.
Definition: gnu_out.cpp:209
Performs grid convergence for various polynomial degrees.
GridRefinementStudy()=delete
Constructor. Deleted the default constructor since it should not be used.
const Parameters::AllParameters *const all_parameters
Pointer to all parameters.
Definition: tests.h:20
std::string input_grid
Input pathway for GridEnum::read_grid type.
static std::shared_ptr< DGBase< dim, real, MeshType > > create_discontinuous_galerkin(const Parameters::AllParameters *const parameters_input, const unsigned int degree, const unsigned int max_degree_input, const unsigned int grid_degree_input, const std::shared_ptr< Triangulation > triangulation_input)
Creates a derived object DG, but returns it as DGBase.
Definition: dg_factory.cpp:10
bool output_solution_error
Flag to enable output of grid refinement solution error convergence.
bool output_gnuplot_solution
Flag to enable output of gnuplot graph of solution error convergence.
bool output_vtk
Flag to enable output of grid refinement .vtk file.
FunctionalParam functional_param
Functional parameters to be used with grid refinement study.
static std::shared_ptr< ModelBase< dim, nstate, real > > create_Model(const Parameters::AllParameters *const parameters_input)
Factory to return the correct model given input parameters.
unsigned int refinement_steps
Number of refinement steps to be performed.
void write_gnuplot()
Main write function call.
Definition: gnu_out.cpp:110
bool exit_after_refine
Flag to exit after call to refinement.
static std::shared_ptr< PhysicsBase< dim, nstate, real > > create_Physics(const Parameters::AllParameters *const parameters_input, std::shared_ptr< ModelBase< dim, nstate, real > > model_input=nullptr)
Factory to return the correct physics given input file.
Parameters related to individual grid refinement run.
void set_grid(const bool grid_bool_input)
Set flag for enabling background grid.
Definition: gnu_out.cpp:58
static std::shared_ptr< Functional< dim, nstate, real, MeshType > > create_Functional(PHiLiP::Parameters::AllParameters const *const param, std::shared_ptr< PHiLiP::DGBase< dim, real, MeshType > > dg)
Create standard functional object from constant parameter file.
Parameters related to collection of grid refinement runs.
double functional_value
Specified exact functional value for comparison of error convergence.
static std::shared_ptr< GridRefinementBase< dim, nstate, real, MeshType > > create_GridRefinement(PHiLiP::Parameters::GridRefinementParam gr_param, std::shared_ptr< PHiLiP::Adjoint< dim, nstate, real, MeshType > > adj, std::shared_ptr< PHiLiP::Physics::PhysicsBase< dim, nstate, real > > physics_input)
Construct grid refinement class based on adjoint and physics.
void set_x_scale_log(const bool xlog_bool_input)
Set flag for logarithmic x-axis.
Definition: gnu_out.cpp:65
int run_test() const
Basically the main and only function of this class.
dealii::ConditionalOStream pcout
ConditionalOStream.
Definition: tests.h:45
bool output_functional_error
Flag to enable output of grid refinement functional error convergence.
unsigned int grid_size
Number of initial elements in each axis for GridEnum::hypercube type.
void set_title(const std::string &title_input)
Sets the figure title.
Definition: gnu_out.cpp:37
double grid_left
Lower coordinate bound for GridEnum::hypercube type.
bool output_adjoint_time
Flag to enable output of grid refinement wall-clock adjoint time.
static std::shared_ptr< ODESolverBase< dim, real, MeshType > > create_ODESolver(std::shared_ptr< DGBase< dim, real, MeshType > > dg_input)
Creates either implicit or explicit ODE solver based on parameter value(no POD basis given) ...
unsigned int poly_degree
Initial solution polynomial degree.
double grid_right
Upper coordinate bound for GridEnum::hypercube type.
Base class of all the tests.
Definition: tests.h:17
GridEnum
Types of grids that can be used for convergence study.
void get_grid(const std::shared_ptr< MeshType > &grid, const Parameters::GridRefinementStudyParam &grs_param) const
gets the grid from the enum and reads file if neccesary
bool output_adjoint_vtk
Flag to enable output of adjoint .vtk file.