5 #include <deal.II/base/convergence_table.h> 7 #include <deal.II/dofs/dof_tools.h> 9 #include <deal.II/grid/grid_generator.h> 10 #include <deal.II/grid/grid_refinement.h> 11 #include <deal.II/grid/grid_tools.h> 12 #include <deal.II/grid/grid_out.h> 13 #include <deal.II/grid/grid_in.h> 15 #include <deal.II/numerics/vector_tools.h> 16 #include <deal.II/numerics/data_out.h> 18 #include <deal.II/fe/fe_values.h> 19 #include <deal.II/fe/mapping_q.h> 21 #include "diffusion_exact_adjoint.h" 23 #include "parameters/all_parameters.h" 25 #include "physics/euler.h" 26 #include "physics/manufactured_solution.h" 27 #include "dg/dg_factory.hpp" 28 #include "dg/dg_base_state.hpp" 29 #include "ode_solver/ode_solver_factory.h" 31 #include "functional/functional.h" 32 #include "functional/adjoint.h" 34 #include "post_processor/physics_post_processor.h" 36 #include "ADTypes.hpp" 43 template <
int dim,
int nspecies,
typename real>
50 val = (-1.0*pow(x,6)+3.0*pow(x,5)-3.0*pow(x,4)+pow(x,3));
52 real x = pos[0], y = pos[1];
53 val = (-1.0*pow(x,6)+3.0*pow(x,5)-3.0*pow(x,4)+pow(x,3))
54 * (-1.0*pow(y,6)+3.0*pow(y,5)-3.0*pow(y,4)+pow(y,3));
56 real x = pos[0], y = pos[1], z = pos[2];
57 val = (-1.0*pow(x,6)+3.0*pow(x,5)-3.0*pow(x,4)+pow(x,3))
58 * (-1.0*pow(y,6)+3.0*pow(y,5)-3.0*pow(y,4)+pow(y,3))
59 * (-1.0*pow(z,6)+3.0*pow(z,5)-3.0*pow(z,4)+pow(z,3));
66 template <
int dim,
int nspecies,
typename real>
69 dealii::Tensor<1,dim,real> gradient;
73 gradient[0] = (-6.0*pow(x,5)+15.0*pow(x,4)-12.0*pow(x,3)+3.0*pow(x,2));
75 real x = pos[0], y = pos[1];
76 gradient[0] = (-6.0*pow(x,5)+15.0*pow(x,4)-12.0*pow(x,3)+3.0*pow(x,2))
77 * (-1.0*pow(y,6)+ 3.0*pow(y,5)- 3.0*pow(y,4)+ pow(y,3));
78 gradient[1] = (-1.0*pow(x,6)+ 3.0*pow(x,5)- 3.0*pow(x,4)+ pow(x,3))
79 * (-6.0*pow(y,5)+15.0*pow(y,4)-12.0*pow(y,3)+3.0*pow(y,2));
81 real x = pos[0], y = pos[1], z = pos[2];
82 gradient[0] = (-6.0*pow(x,5)+15.0*pow(x,4)-12.0*pow(x,3)+3.0*pow(x,2))
83 * (-1.0*pow(y,6)+ 3.0*pow(y,5)- 3.0*pow(y,4)+ pow(y,3))
84 * (-1.0*pow(z,6)+ 3.0*pow(z,5)- 3.0*pow(z,4)+ pow(z,3));
85 gradient[1] = (-1.0*pow(x,6)+ 3.0*pow(x,5)- 3.0*pow(x,4)+ pow(x,3))
86 * (-6.0*pow(y,5)+15.0*pow(y,4)-12.0*pow(y,3)+3.0*pow(y,2))
87 * (-1.0*pow(z,6)+ 3.0*pow(z,5)- 3.0*pow(z,4)+ pow(z,3));
88 gradient[2] = (-1.0*pow(x,6)+ 3.0*pow(x,5)- 3.0*pow(x,4)+ pow(x,3))
89 * (-1.0*pow(y,6)+ 3.0*pow(y,5)- 3.0*pow(y,4)+ pow(y,3))
90 * (-6.0*pow(z,5)+15.0*pow(z,4)-12.0*pow(z,3)+3.0*pow(z,2));
97 template <
int dim,
int nspecies,
typename real>
100 const double pi = std::acos(-1);
108 real x = pos[0], y = pos[1];
112 real x = pos[0], y = pos[1], z = pos[2];
122 template <
int dim,
int nspecies,
typename real>
125 const double pi = std::acos(-1);
127 dealii::Tensor<1,dim,real> gradient;
131 gradient[0] = pi*cos(pi*x);
133 real x = pos[0], y = pos[1];
134 gradient[0] = (pi*cos(pi*x))
136 gradient[1] = ( sin(pi*x))
139 real x = pos[0], y = pos[1], z = pos[2];
140 gradient[0] = (pi*cos(pi*x))
143 gradient[1] = ( sin(pi*x))
146 gradient[2] = ( sin(pi*x))
155 template <
int dim,
int nspecies,
int nstate,
typename real>
157 const dealii::Point<dim,real> &pos,
158 const std::array<real,nstate> &,
160 const dealii::types::global_dof_index )
const 162 std::array<real,nstate> source;
168 val = (-30.0*pow(x,4)+60.0*pow(x,3)-36.0*pow(x,2)+6.0*x);
170 real x = pos[0], y = pos[1];
171 val = (-30.0*pow(x,4)+60.0*pow(x,3)-36.0*pow(x,2)+6.0*x)
172 * ( -1.0*pow(y,6)+ 3.0*pow(y,5)- 3.0*pow(y,4)+ pow(y,3))
173 + ( -1.0*pow(x,6)+ 3.0*pow(x,5)- 3.0*pow(x,4)+ pow(x,3))
174 * (-30.0*pow(y,4)+60.0*pow(y,3)-36.0*pow(y,2)+6.0*y);
176 real x = pos[0], y = pos[1], z = pos[2];
177 val = (-30.0*pow(x,4)+60.0*pow(x,3)-36.0*pow(x,2)+6.0*x)
178 * ( -1.0*pow(y,6)+ 3.0*pow(y,5)- 3.0*pow(y,4)+ pow(y,3))
179 * ( -1.0*pow(z,6)+ 3.0*pow(z,5)- 3.0*pow(z,4)+ pow(z,3))
180 + ( -1.0*pow(x,6)+ 3.0*pow(x,5)- 3.0*pow(x,4)+ pow(x,3))
181 * (-30.0*pow(y,4)+60.0*pow(y,3)-36.0*pow(y,2)+6.0*y)
182 * ( -1.0*pow(z,6)+ 3.0*pow(z,5)- 3.0*pow(z,4)+ pow(z,3))
183 + ( -1.0*pow(x,6)+ 3.0*pow(x,5)- 3.0*pow(x,4)+ pow(x,3))
184 * ( -1.0*pow(y,6)+ 3.0*pow(y,5)- 3.0*pow(y,4)+ pow(y,3))
185 * (-30.0*pow(z,4)+60.0*pow(z,3)-36.0*pow(z,2)+6.0*z);
188 for(
int istate = 0; istate < nstate; ++istate)
189 source[istate] = val;
194 template <
int dim,
int nspecies,
int nstate,
typename real>
196 const dealii::Point<dim,real> &pos)
const 198 const double pi = std::acos(-1);
204 val = -pi*pi*sin(pi*x);
206 real x = pos[0], y = pos[1];
207 val = -pi*pi*sin(pi*x)
212 real x = pos[0], y = pos[1], z = pos[2];
213 val = -pi*pi*sin(pi*x)
227 template <
int dim,
int nspecies,
int nstate,
typename real>
229 const dealii::Point<dim,real> &pos,
230 const std::array<real,nstate> &,
232 const dealii::types::global_dof_index )
const 234 const double pi = std::acos(-1);
236 std::array<real,nstate> source;
242 val = -pi*pi*sin(pi*x);
244 real x = pos[0], y = pos[1];
245 val = -pi*pi*sin(pi*x)
250 real x = pos[0], y = pos[1], z = pos[2];
251 val = -pi*pi*sin(pi*x)
262 for(
int istate = 0; istate < nstate; ++istate)
263 source[istate] = val;
268 template <
int dim,
int nspecies,
int nstate,
typename real>
270 const dealii::Point<dim,real> &pos)
const 276 val = (-30.0*pow(x,4)+60.0*pow(x,3)-36.0*pow(x,2)+6.0*x);
278 real x = pos[0], y = pos[1];
279 val = (-30.0*pow(x,4)+60.0*pow(x,3)-36.0*pow(x,2)+6.0*x)
280 * ( -1.0*pow(y,6)+ 3.0*pow(y,5)- 3.0*pow(y,4)+ pow(y,3))
281 + ( -1.0*pow(x,6)+ 3.0*pow(x,5)- 3.0*pow(x,4)+ pow(x,3))
282 * (-30.0*pow(y,4)+60.0*pow(y,3)-36.0*pow(y,2)+6.0*y);
284 real x = pos[0], y = pos[1], z = pos[2];
285 val = (-30.0*pow(x,4)+60.0*pow(x,3)-36.0*pow(x,2)+6.0*x)
286 * ( -1.0*pow(y,6)+ 3.0*pow(y,5)- 3.0*pow(y,4)+ pow(y,3))
287 * ( -1.0*pow(z,6)+ 3.0*pow(z,5)- 3.0*pow(z,4)+ pow(z,3))
288 + ( -1.0*pow(x,6)+ 3.0*pow(x,5)- 3.0*pow(x,4)+ pow(x,3))
289 * (-30.0*pow(y,4)+60.0*pow(y,3)-36.0*pow(y,2)+6.0*y)
290 * ( -1.0*pow(z,6)+ 3.0*pow(z,5)- 3.0*pow(z,4)+ pow(z,3))
291 + ( -1.0*pow(x,6)+ 3.0*pow(x,5)- 3.0*pow(x,4)+ pow(x,3))
292 * ( -1.0*pow(y,6)+ 3.0*pow(y,5)- 3.0*pow(y,4)+ pow(y,3))
293 * (-30.0*pow(z,4)+60.0*pow(z,3)-36.0*pow(z,2)+6.0*z);
300 template <
int dim,
int nspecies,
int nstate,
typename real>
301 template <
typename real2>
304 const dealii::Point<dim,real2> &phys_coord,
305 const std::array<real2,nstate> &soln_at_q,
306 const std::array<dealii::Tensor<1,dim,real2>,nstate> &)
const 317 for (
int istate=0; istate<nstate; ++istate) {
318 val += soln_at_q[istate] * objective_value;
325 template <
int dim,
int nspecies,
int nstate>
329 template <
int dim,
int nspecies,
int nstate>
332 pcout <<
"Running diffusion exact adjoint test case." << std::endl;
336 using GridEnum = ManParam::GridEnum;
346 const unsigned int p_start = manu_grid_conv_param.
degree_start;
347 const unsigned int p_end = manu_grid_conv_param.degree_end;
348 const unsigned int n_grids = manu_grid_conv_param.number_of_grids;
352 bool convection, diffusion;
353 if(pde_type == PdeEnum::diffusion){
357 pcout <<
"Can't run diffusion_exact_adjoint test case with other PDE types." << std::endl;
361 std::shared_ptr< Physics::PhysicsBase<dim, nspecies, nstate, double> > physics_u_double
362 = std::make_shared< diffusion_u<dim, nspecies, nstate, double> >(¶m, convection, diffusion);
363 std::shared_ptr< Physics::PhysicsBase<dim, nspecies, nstate, double> > physics_v_double
364 = std::make_shared< diffusion_v<dim, nspecies, nstate, double> >(¶m, convection, diffusion);
367 std::shared_ptr< Physics::PhysicsBase<dim, nspecies, nstate, FadType> > physics_u_fadtype
368 = std::make_shared< diffusion_u<dim, nspecies, nstate, FadType> >(¶m, convection, diffusion);
369 std::shared_ptr< Physics::PhysicsBase<dim, nspecies, nstate, FadType> > physics_v_fadtype
370 = std::make_shared< diffusion_v<dim, nspecies, nstate, FadType> >(¶m, convection, diffusion);
372 std::shared_ptr< Physics::PhysicsBase<dim, nspecies, nstate, RadType> > physics_u_radtype
373 = std::make_shared< diffusion_u<dim, nspecies, nstate, RadType> >(¶m, convection, diffusion);
374 std::shared_ptr< Physics::PhysicsBase<dim, nspecies, nstate, RadType> > physics_v_radtype
375 = std::make_shared< diffusion_v<dim, nspecies, nstate, RadType> >(¶m, convection, diffusion);
377 std::shared_ptr< Physics::PhysicsBase<dim, nspecies, nstate, FadFadType> > physics_u_fadfadtype
378 = std::make_shared< diffusion_u<dim, nspecies, nstate, FadFadType> >(¶m, convection, diffusion);
379 std::shared_ptr< Physics::PhysicsBase<dim, nspecies, nstate, FadFadType> > physics_v_fadfadtype
380 = std::make_shared< diffusion_v<dim, nspecies, nstate, FadFadType> >(¶m, convection, diffusion);
382 std::shared_ptr< Physics::PhysicsBase<dim, nspecies, nstate, RadFadType> > physics_u_radfadtype
383 = std::make_shared< diffusion_u<dim, nspecies, nstate, RadFadType> >(¶m, convection, diffusion);
384 std::shared_ptr< Physics::PhysicsBase<dim, nspecies, nstate, RadFadType> > physics_v_radfadtype
385 = std::make_shared< diffusion_v<dim, nspecies, nstate, RadFadType> >(¶m, convection, diffusion);
388 const double pi = std::acos(-1);
389 double exact_val = 0;
392 exact_val = (144*(pow(pi,2)-10)/pow(pi,5));
394 exact_val = 2 * (-144*(pow(pi,2)-10)/pow(pi,7)) * (144*(pow(pi,2)-10)/pow(pi,5));
396 exact_val = 3 * pow(-144*(pow(pi,2)-10)/pow(pi,7), 2) * (144*(pow(pi,2)-10)/pow(pi,5));
400 std::vector<dealii::ConvergenceTable> convergence_table_vector;
402 unsigned int n_fail = 0;
404 for(
unsigned int poly_degree = p_start; poly_degree <= p_end; ++poly_degree){
405 pcout <<
"Starting polynomial order: " << poly_degree << std::endl;
408 std::vector<double> grid_size(n_grids);
409 std::vector<double> output_error_u(n_grids);
410 std::vector<double> output_error_v(n_grids);
411 std::vector<double> soln_error_u(n_grids);
412 std::vector<double> soln_error_v(n_grids);
413 std::vector<double> adj_error_u(n_grids);
414 std::vector<double> adj_error_v(n_grids);
417 dealii::Vector<double> cellError_soln_u;
418 dealii::Vector<double> cellError_soln_v;
419 dealii::Vector<double> cellError_adj_u;
420 dealii::Vector<double> cellError_adj_v;
424 dealii::ConvergenceTable convergence_table;
427 using Triangulation = dealii::Triangulation<PHILIP_DIM>;
429 using Triangulation = dealii::parallel::distributed::Triangulation<PHILIP_DIM>;
431 std::shared_ptr <Triangulation> grid = std::make_shared<Triangulation> (
435 typename dealii::Triangulation<dim>::MeshSmoothing(
436 dealii::Triangulation<dim>::smoothing_on_refinement |
437 dealii::Triangulation<dim>::smoothing_on_coarsening));
440 const double left = 0.0;
441 const double right = 1.0;
443 for(
unsigned int igrid = 0; igrid < n_grids; ++igrid){
446 dealii::GridGenerator::subdivided_hyper_cube(*grid, n_1d_cells[igrid], left, right);
447 for (
auto cell = grid->begin_active(); cell != grid->end(); ++cell) {
448 cell->set_material_id(9002);
449 for (
unsigned int face=0; face<dealii::GeometryInfo<dim>::faces_per_cell; ++face) {
450 if (cell->face(face)->at_boundary()) cell->face(face)->set_boundary_id (1000);
464 dg_state_u->
set_physics(physics_u_double, physics_u_fadtype, physics_u_radtype, physics_u_fadfadtype, physics_u_radfadtype);
465 dg_state_v->set_physics(physics_v_double, physics_v_fadtype, physics_v_radtype, physics_v_fadfadtype, physics_v_radfadtype);
467 dg_u->allocate_system();
468 dg_v->allocate_system();
470 dg_u->solution *= 0.0;
471 dg_v->solution *= 0.0;
480 ode_solver_u->steady_state();
481 ode_solver_v->steady_state();
483 pcout <<
"Creating DiffusionFunctional... " << std::endl;
485 auto diffusion_functional_u = std::make_shared<DiffusionFunctional<dim,nspecies,nstate,double>>(dg_u,physics_u_fadfadtype,
true,
false);
486 auto diffusion_functional_v = std::make_shared<DiffusionFunctional<dim,nspecies,nstate,double>>(dg_v,physics_v_fadfadtype,
true,
false);
488 pcout <<
"Evaluating functional... " << std::endl;
490 double functional_val_u = diffusion_functional_u->evaluate_functional(
false,
false);
491 double functional_val_v = diffusion_functional_v->evaluate_functional(
false,
false);
494 pcout << std::endl <<
"Val1 = " << functional_val_u <<
"\tVal2 = " << functional_val_v << std::endl << std::endl;
497 double error_functional_u = std::abs(functional_val_u-exact_val);
498 double error_functional_v = std::abs(functional_val_v-exact_val);
500 pcout << std::endl <<
"error_val1 = " << error_functional_u <<
"\terror_val2 = " << error_functional_v << std::endl << std::endl;
507 pcout <<
"Solving for the discrete adjoints." << std::endl;
508 dealii::LinearAlgebra::distributed::Vector<double> adjoint_u = adj_u.
coarse_grid_adjoint();
509 dealii::LinearAlgebra::distributed::Vector<double> adjoint_v = adj_v.
coarse_grid_adjoint();
512 int overintegrate = 10;
513 dealii::QGauss<dim> quad_extra(poly_degree+overintegrate);
514 dealii::FEValues<dim,dim> fe_values_extra(*(dg_u->high_order_grid->mapping_fe_field), dg_u->fe_collection[poly_degree], quad_extra,
515 dealii::update_values | dealii::update_JxW_values | dealii::update_quadrature_points);
516 const unsigned int n_quad_pts = fe_values_extra.n_quadrature_points;
519 double l2error_soln_u = 0;
520 double l2error_soln_v = 0;
523 double l2error_adj_u = 0;
524 double l2error_adj_v = 0;
527 std::array<double,nstate> soln_at_q_u;
528 std::array<double,nstate> soln_at_q_v;
529 std::array<double,nstate> adj_at_q_u;
530 std::array<double,nstate> adj_at_q_v;
533 cellError_soln_u.reinit(grid->n_active_cells());
534 cellError_soln_v.reinit(grid->n_active_cells());
535 cellError_adj_u.reinit(grid->n_active_cells());
536 cellError_adj_v.reinit(grid->n_active_cells());
538 std::vector<dealii::types::global_dof_index> dofs_indices(fe_values_extra.dofs_per_cell);
539 for(
auto cell = dg_u->dof_handler.begin_active(); cell != dg_u->dof_handler.end(); ++cell){
540 if(!cell->is_locally_owned())
continue;
542 fe_values_extra.reinit (cell);
543 cell->get_dof_indices(dofs_indices);
545 double cell_l2error_soln_u = 0;
546 double cell_l2error_soln_v = 0;
547 double cell_l2error_adj_u = 0;
548 double cell_l2error_adj_v = 0;
549 for(
unsigned int iquad = 0; iquad < n_quad_pts; ++iquad){
550 std::fill(soln_at_q_u.begin(), soln_at_q_u.end(), 0);
551 std::fill(soln_at_q_v.begin(), soln_at_q_v.end(), 0);
552 std::fill(adj_at_q_u.begin(), adj_at_q_u.end(), 0);
553 std::fill(adj_at_q_v.begin(), adj_at_q_v.end(), 0);
555 for (
unsigned int idof = 0; idof < fe_values_extra.dofs_per_cell; ++idof) {
556 const unsigned int istate = fe_values_extra.get_fe().system_to_component_index(idof).first;
557 soln_at_q_u[istate] += dg_u->solution[dofs_indices[idof]] * fe_values_extra.shape_value_component(idof, iquad, istate);
558 soln_at_q_v[istate] += dg_v->solution[dofs_indices[idof]] * fe_values_extra.shape_value_component(idof, iquad, istate);
559 adj_at_q_u[istate] += adjoint_u[dofs_indices[idof]] * fe_values_extra.shape_value_component(idof, iquad, istate);
560 adj_at_q_v[istate] += adjoint_v[dofs_indices[idof]] * fe_values_extra.shape_value_component(idof, iquad, istate);
563 const dealii::Point<dim,double> qpoint = (fe_values_extra.quadrature_point(iquad));
565 for (
int istate = 0; istate < nstate; ++istate){
566 const double soln_exact_u = physics_u_double->manufactured_solution_function->value(qpoint, istate);
567 const double soln_exact_v = physics_v_double->manufactured_solution_function->value(qpoint, istate);
570 cell_l2error_soln_u += pow(soln_at_q_u[istate] - soln_exact_u, 2) * fe_values_extra.JxW(iquad);
571 cell_l2error_soln_v += pow(soln_at_q_v[istate] - soln_exact_v, 2) * fe_values_extra.JxW(iquad);
574 cell_l2error_adj_u += pow(adj_at_q_u[istate] - soln_exact_v, 2) * fe_values_extra.JxW(iquad);
575 cell_l2error_adj_v += pow(adj_at_q_v[istate] - soln_exact_u, 2) * fe_values_extra.JxW(iquad);
584 cellError_soln_u[cell->active_cell_index()] = cell_l2error_soln_u;
585 cellError_soln_v[cell->active_cell_index()] = cell_l2error_soln_v;
586 cellError_adj_u[cell->active_cell_index()] = cell_l2error_adj_u;
587 cellError_adj_v[cell->active_cell_index()] = cell_l2error_adj_v;
590 l2error_soln_u += cell_l2error_soln_u;
591 l2error_soln_v += cell_l2error_soln_v;
592 l2error_adj_u += cell_l2error_adj_u;
593 l2error_adj_v += cell_l2error_adj_v;
595 const double l2error_soln_u_mpi_sum = std::sqrt(dealii::Utilities::MPI::sum(l2error_soln_u, mpi_communicator));
596 const double l2error_soln_v_mpi_sum = std::sqrt(dealii::Utilities::MPI::sum(l2error_soln_v, mpi_communicator));
597 const double l2error_adj_u_mpi_sum = std::sqrt(dealii::Utilities::MPI::sum(l2error_adj_u, mpi_communicator));
598 const double l2error_adj_v_mpi_sum = std::sqrt(dealii::Utilities::MPI::sum(l2error_adj_v, mpi_communicator));
602 const std::string filename_u =
"sol-u-" + std::to_string(igrid) +
".gnuplot";
603 std::ofstream gnuplot_output_u(filename_u);
604 dealii::DataOut<dim, dealii::DoFHandler<dim>> data_out_u;
605 data_out_u.attach_dof_handler(dg_u->dof_handler);
606 data_out_u.add_data_vector(dg_u->solution,
"u");
607 data_out_u.build_patches();
608 data_out_u.write_gnuplot(gnuplot_output_u);
610 const std::string filename_v =
"sol-v-" + std::to_string(igrid) +
".gnuplot";
611 std::ofstream gnuplot_output_v(filename_v);
612 dealii::DataOut<dim, dealii::DoFHandler<dim>> data_out_v;
613 data_out_v.attach_dof_handler(dg_v->dof_handler);
614 data_out_v.add_data_vector(dg_v->solution,
"u");
615 data_out_v.build_patches();
616 data_out_v.write_gnuplot(gnuplot_output_v);
618 pcout <<
"Outputting the results" << std::endl;
631 dealii::DataOut<dim, dealii::DoFHandler<dim>> data_out;
632 data_out.attach_dof_handler(dg_u->dof_handler);
640 dealii::Vector<float> subdomain(dg_u->triangulation->n_active_cells());
641 for (
unsigned int i = 0; i < subdomain.size(); ++i) {
642 subdomain(i) = dg_u->triangulation->locally_owned_subdomain();
644 data_out.add_data_vector(subdomain,
"subdomain", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
646 std::vector<unsigned int> active_fe_indices;
647 dg_u->dof_handler.get_active_fe_indices(active_fe_indices);
648 dealii::Vector<double> active_fe_indices_dealiivector(active_fe_indices.begin(), active_fe_indices.end());
649 dealii::Vector<double> cell_poly_degree = active_fe_indices_dealiivector;
651 data_out.add_data_vector(active_fe_indices_dealiivector,
"PolynomialDegree", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
653 std::vector<std::string> solution_names_u;
654 std::vector<std::string> solution_names_v;
655 std::vector<std::string> residual_names_u;
656 std::vector<std::string> residual_names_v;
657 std::vector<std::string> dIdw_names_u;
658 std::vector<std::string> dIdw_names_v;
659 std::vector<std::string> adjoint_names_u;
660 std::vector<std::string> adjoint_names_v;
661 for(
int s=0;s<nstate;++s) {
662 std::string varname0_u =
"state" + dealii::Utilities::int_to_string(s,1) +
"_u";
663 std::string varname0_v =
"state" + dealii::Utilities::int_to_string(s,1) +
"_v";
664 std::string varname1_u =
"residual" + dealii::Utilities::int_to_string(s,1) +
"_u";
665 std::string varname1_v =
"residual" + dealii::Utilities::int_to_string(s,1) +
"_v";
666 std::string varname2_u =
"dIdw" + dealii::Utilities::int_to_string(s,1) +
"_u";
667 std::string varname2_v =
"dIdw" + dealii::Utilities::int_to_string(s,1) +
"_v";
668 std::string varname3_u =
"psi" + dealii::Utilities::int_to_string(s,1) +
"_u";
669 std::string varname3_v =
"psi" + dealii::Utilities::int_to_string(s,1) +
"_v";
671 solution_names_u.push_back(varname0_u);
672 solution_names_v.push_back(varname0_v);
673 residual_names_u.push_back(varname1_u);
674 residual_names_v.push_back(varname1_v);
675 dIdw_names_u.push_back(varname2_u);
676 dIdw_names_v.push_back(varname2_v);
677 adjoint_names_u.push_back(varname3_u);
678 adjoint_names_v.push_back(varname3_v);
681 data_out.add_data_vector(dg_u->solution, solution_names_u, dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_dof_data);
682 data_out.add_data_vector(dg_v->solution, solution_names_v, dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_dof_data);
683 data_out.add_data_vector(dg_u->right_hand_side, residual_names_u, dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_dof_data);
684 data_out.add_data_vector(dg_v->right_hand_side, residual_names_v, dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_dof_data);
685 data_out.add_data_vector(adj_u.
dIdw_coarse, dIdw_names_u, dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_dof_data);
686 data_out.add_data_vector(adj_v.
dIdw_coarse, dIdw_names_v, dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_dof_data);
687 data_out.add_data_vector(adj_u.
adjoint_coarse, adjoint_names_u, dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_dof_data);
688 data_out.add_data_vector(adj_v.
adjoint_coarse, adjoint_names_v, dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_dof_data);
690 data_out.add_data_vector(cellError_soln_u,
"soln_u_err", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
691 data_out.add_data_vector(cellError_soln_v,
"soln_v_err", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
692 data_out.add_data_vector(cellError_adj_u,
"adj_u_err", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
693 data_out.add_data_vector(cellError_adj_v,
"adj_v_err", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
695 const int iproc = dealii::Utilities::MPI::this_mpi_process(mpi_communicator);
696 data_out.build_patches();
699 std::string filename =
"diffusion_exact_adjoint-" ;
700 filename += dealii::Utilities::int_to_string(dim, 1) +
"D-";
701 filename += dealii::Utilities::int_to_string(poly_degree, 1) +
"P-";
702 filename += dealii::Utilities::int_to_string(igrid, 4) +
".";
703 filename += dealii::Utilities::int_to_string(iproc, 4);
705 std::ofstream output(filename);
706 data_out.write_vtu(output);
709 std::vector<std::string> filenames;
710 for (
unsigned int iproc = 0; iproc < dealii::Utilities::MPI::n_mpi_processes(mpi_communicator); ++iproc) {
711 std::string fn =
"diffusion_exact_adjoint-";
712 fn += dealii::Utilities::int_to_string(dim, 1) +
"D-";
713 fn += dealii::Utilities::int_to_string(poly_degree, 1) +
"P-";
714 fn += dealii::Utilities::int_to_string(igrid, 4) +
".";
715 fn += dealii::Utilities::int_to_string(iproc, 4);
717 filenames.push_back(fn);
719 std::string master_fn =
"diffusion_exact_adjoint-";
720 master_fn += dealii::Utilities::int_to_string(dim, 1) +
"D-";
721 master_fn += dealii::Utilities::int_to_string(poly_degree, 1) +
"P-";
722 master_fn += dealii::Utilities::int_to_string(igrid, 4) +
".pvtu";
723 std::ofstream master_output(master_fn);
724 data_out.write_pvtu_record(master_output, filenames);
729 const int n_dofs = dg_u->dof_handler.n_dofs();
730 const double dx = 1.0/pow(n_dofs,(1.0/dim));
733 convergence_table.add_value(
"p", poly_degree);
734 convergence_table.add_value(
"cells", grid->n_global_active_cells());
735 convergence_table.add_value(
"DoFs", n_dofs);
736 convergence_table.add_value(
"dx", dx);
737 convergence_table.add_value(
"soln_u_val", functional_val_u);
738 convergence_table.add_value(
"soln_v_val", functional_val_v);
739 convergence_table.add_value(
"soln_u_err", error_functional_u);
740 convergence_table.add_value(
"soln_v_err", error_functional_v);
741 convergence_table.add_value(
"soln_u_L2_err", l2error_soln_u_mpi_sum);
742 convergence_table.add_value(
"soln_v_L2_err", l2error_soln_v_mpi_sum);
743 convergence_table.add_value(
"adj_u_L2_err", l2error_adj_u_mpi_sum);
744 convergence_table.add_value(
"adj_v_L2_err", l2error_adj_v_mpi_sum);
747 grid_size[igrid] = dx;
748 output_error_u[igrid] = error_functional_u;
749 output_error_v[igrid] = error_functional_v;
750 soln_error_u[igrid] = l2error_soln_u_mpi_sum;
751 soln_error_v[igrid] = l2error_soln_v_mpi_sum;
752 adj_error_u[igrid] = l2error_adj_u_mpi_sum;
753 adj_error_v[igrid] = l2error_adj_v_mpi_sum;
757 convergence_table.evaluate_convergence_rates(
"soln_u_err",
"cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
758 convergence_table.evaluate_convergence_rates(
"soln_v_err",
"cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
759 convergence_table.evaluate_convergence_rates(
"soln_u_L2_err",
"cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
760 convergence_table.evaluate_convergence_rates(
"soln_v_L2_err",
"cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
761 convergence_table.evaluate_convergence_rates(
"adj_u_L2_err",
"cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
762 convergence_table.evaluate_convergence_rates(
"adj_v_L2_err",
"cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
763 convergence_table.set_scientific(
"dx",
true);
764 convergence_table.set_scientific(
"soln_u_val",
true);
765 convergence_table.set_scientific(
"soln_v_val",
true);
766 convergence_table.set_scientific(
"soln_u_err",
true);
767 convergence_table.set_scientific(
"soln_v_err",
true);
768 convergence_table.set_scientific(
"soln_u_L2_err",
true);
769 convergence_table.set_scientific(
"soln_v_L2_err",
true);
770 convergence_table.set_scientific(
"adj_u_L2_err",
true);
771 convergence_table.set_scientific(
"adj_v_L2_err",
true);
774 convergence_table_vector.push_back(convergence_table);
779 const double expected_slope_l2error_adj = poly_degree + 1;
786 const double avg_slope_error_l2error_adj_u = eval_avg_slope( adj_error_u, grid_size, n_grids);
787 const double avg_slope_error_l2error_adj_v = eval_avg_slope( adj_error_v, grid_size, n_grids);
794 const double diff_slope_error_l2error_adj_u = avg_slope_error_l2error_adj_u - expected_slope_l2error_adj;
795 const double diff_slope_error_l2error_adj_v = avg_slope_error_l2error_adj_v - expected_slope_l2error_adj;
798 double slope_deficit_tolerance = -std::abs(manu_grid_conv_param.slope_deficit_tolerance);
821 if(diff_slope_error_l2error_adj_u < slope_deficit_tolerance){
822 pcout <<
"Convergence order not achieved for l2error_adj_u." << std::endl
823 <<
"Average order of " << avg_slope_error_l2error_adj_u <<
" instead of expected " << expected_slope_l2error_adj << std::endl;
826 if(diff_slope_error_l2error_adj_v < slope_deficit_tolerance){
827 pcout <<
"Convergence order not achieved for l2error_adj_v." << std::endl
828 <<
"Average order of " << avg_slope_error_l2error_adj_v <<
" instead of expected " << expected_slope_l2error_adj << std::endl;
833 pcout << std::endl << std::endl << std::endl << std::endl;
834 pcout <<
" ********************************************" << std::endl;
835 pcout <<
" Convergence summary" << std::endl;
836 pcout <<
" ********************************************" << std::endl;
837 for (
auto conv = convergence_table_vector.begin(); conv!=convergence_table_vector.end(); conv++) {
838 if (
pcout.is_active()) conv->write_text(
pcout.get_stream());
839 pcout <<
" ********************************************" << std::endl;
846 double eval_avg_slope(std::vector<double> error, std::vector<double> grid_size,
unsigned int n_grids){
847 const double last_slope_error = log(error[n_grids-1]/error[n_grids-2])/(log(grid_size[n_grids-1]/grid_size[n_grids-2]));
848 double prev_slope_error = last_slope_error;
850 prev_slope_error = log(error[n_grids-2]/error[n_grids-3])/(log(grid_size[n_grids-2]/grid_size[n_grids-3]));
852 return 0.5*(last_slope_error+prev_slope_error);
855 #if PHILIP_SPECIES==1 unsigned int degree_start
First polynomial degree to start the loop. If diffusion, must be at least 1.
PartialDifferentialEquation pde_type
Store the PDE type to be solved.
std::array< real, nstate > source_term(const dealii::Point< dim, real > &pos, const std::array< real, nstate > &solution, const real current_time, const dealii::types::global_dof_index cell_index) const override
source term = g
Parameters related to the manufactured convergence study.
Base class from which Advection, Diffusion, ConvectionDiffusion, and Euler is derived.
const MPI_Comm mpi_communicator
MPI communicator.
real2 evaluate_volume_integrand(const PHiLiP::Physics::PhysicsBase< dim, nspecies, nstate, real2 > &physics, const dealii::Point< dim, real2 > &phys_coord, const std::array< real2, nstate > &soln_at_q, const std::array< dealii::Tensor< 1, dim, real2 >, nstate > &soln_grad_at_q) const
Templated volume integrand.
virtual real objective_function(const dealii::Point< dim, real > &pos) const =0
defnined directly as part of the physics to make passing to the functional simpler ...
PartialDifferentialEquation
Possible Partial Differential Equations to solve.
Files for the baseline physics.
ManufacturedSolutionParam manufactured_solution_param
Associated manufactured solution parameters.
unsigned int dimension
Number of dimensions. Note that it has to match the executable PHiLiP_xD.
Main parameter class that contains the various other sub-parameter classes.
void set_physics(std::shared_ptr< Physics::PhysicsBase< dim, nspecies, nstate, real > > pde_physics_double_input, std::shared_ptr< Physics::PhysicsBase< dim, nspecies, nstate, FadType > > pde_physics_fad_input, std::shared_ptr< Physics::PhysicsBase< dim, nspecies, nstate, RadType > > pde_physics_rad_input, std::shared_ptr< Physics::PhysicsBase< dim, nspecies, nstate, FadFadType > > pde_physics_fad_fad_input, std::shared_ptr< Physics::PhysicsBase< dim, nspecies, nstate, RadFadType > > pde_physics_rad_fad_input)
real value(const dealii::Point< dim, real > &pos, const unsigned int istate=0) const override
overriding the function for the value and gradient
ManufacturedConvergenceStudyParam manufactured_convergence_study_param
Contains parameters for manufactured convergence study.
const Parameters::AllParameters *const all_parameters
Pointer to all parameters.
real objective_function(const dealii::Point< dim, real > &pos) const override
objective function = f
dealii::LinearAlgebra::distributed::Vector< real > adjoint_coarse
coarse grid adjoint ( )
bool use_manufactured_source_term
Uses non-zero source term based on the manufactured solution and the PDE.
dealii::Tensor< 1, dim, real > gradient(const dealii::Point< dim, real > &pos, const unsigned int istate=0) const override
Gradient of the manufactured solution.
dealii::LinearAlgebra::distributed::Vector< real > dIdw_coarse
functional derivative (on the coarse grid)
dealii::Tensor< 1, dim, real > gradient(const dealii::Point< dim, real > &pos, const unsigned int istate=0) const override
Gradient of the manufactured solution.
static std::shared_ptr< DGBase< dim, nspecies, 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.
std::array< real, nstate > source_term(const dealii::Point< dim, real > &pos, const std::array< real, nstate > &solution, const real current_time, const dealii::types::global_dof_index cell_index) const override
source term = f
Abstract class templated on the number of state variables.
dealii::LinearAlgebra::distributed::Vector< real > coarse_grid_adjoint()
Computes the coarse grid adjoint.
dealii::ConditionalOStream pcout
ConditionalOStream.
real value(const dealii::Point< dim, real > &pos, const unsigned int istate=0) const override
overriding the function for the value and gradient
static std::shared_ptr< ODESolverBase< dim, nspecies, real, MeshType > > create_ODESolver(std::shared_ptr< DGBase< dim, nspecies, real, MeshType > > dg_input)
Creates either implicit or explicit ODE solver based on parameter value(no POD basis given) ...
std::vector< int > get_number_1d_cells(const int ngrids) const
Evaluates the number of cells to generate the grids for 1D grid based on input file.
Base class of all the tests.
DiffusionExactAdjoint(const Parameters::AllParameters *const parameters_input)
Constructor to call the TestsBase constructor to set parameters = parameters_input.
real objective_function(const dealii::Point< dim, real > &pos) const override
objective function = g
parent class to add the objective function directly to physics as a virtual class ...