[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
metric_split_form_gradient.cpp
1 #include <iomanip>
2 #include <cmath>
3 #include <limits>
4 #include <type_traits>
5 #include <math.h>
6 #include <iostream>
7 #include <stdlib.h>
8 
9 #include <deal.II/distributed/solution_transfer.h>
10 
11 #include "testing/tests.h"
12 
13 #include<fstream>
14 #include <deal.II/base/parameter_handler.h>
15 #include <deal.II/base/tensor.h>
16 #include <deal.II/numerics/vector_tools.h>
17 
18 #include <deal.II/grid/grid_generator.h>
19 #include <deal.II/grid/grid_refinement.h>
20 #include <deal.II/grid/grid_tools.h>
21 #include <deal.II/grid/grid_out.h>
22 #include <deal.II/grid/grid_in.h>
23 
24 #include <deal.II/dofs/dof_handler.h>
25 #include <deal.II/dofs/dof_tools.h>
26 #include <deal.II/dofs/dof_renumbering.h>
27 
28 #include <deal.II/dofs/dof_accessor.h>
29 
30 #include <deal.II/lac/vector.h>
31 #include <deal.II/lac/dynamic_sparsity_pattern.h>
32 #include <deal.II/lac/sparse_matrix.h>
33 
34 #include <deal.II/meshworker/dof_info.h>
35 
36 #include <deal.II/base/convergence_table.h>
37 
38 // Finally, we take our exact solution from the library as well as volume_quadrature
39 // and additional tools.
40 #include <deal.II/numerics/data_out.h>
41 #include <deal.II/numerics/data_out_dof_data.h>
42 #include <deal.II/numerics/vector_tools.h>
43 #include <deal.II/numerics/vector_tools.templates.h>
44 
45 #include "parameters/all_parameters.h"
46 #include "parameters/parameters.h"
47 #include "dg/dg_base.hpp"
48 #include <deal.II/grid/manifold_lib.h>
49 #include <deal.II/fe/mapping_q.h>
50 #include "dg/dg_factory.hpp"
51 #include "operators/operators.h"
52 //#include <GCL_test.h>
53 
54 const double TOLERANCE = 1E-6;
55 using namespace std;
56 //namespace PHiLiP {
57 
58 template <int dim>
59 class CurvManifold: public dealii::ChartManifold<dim,dim,dim> {
60  virtual dealii::Point<dim> pull_back(const dealii::Point<dim> &space_point) const override;
61  virtual dealii::Point<dim> push_forward(const dealii::Point<dim> &chart_point) const override;
62  virtual dealii::DerivativeForm<1,dim,dim> push_forward_gradient(const dealii::Point<dim> &chart_point) const override;
63 
64  virtual std::unique_ptr<dealii::Manifold<dim,dim> > clone() const override;
65 };
66 
67 template<int dim>
68 dealii::Point<dim> CurvManifold<dim>::pull_back(const dealii::Point<dim> &space_point) const
69 {
70  using namespace PHiLiP;
71  const double pi = atan(1)*4.0;
72  dealii::Point<dim> x_ref;
73  dealii::Point<dim> x_phys;
74  for(int idim=0; idim<dim; idim++){
75  x_ref[idim] = space_point[idim];
76  x_phys[idim] = space_point[idim];
77  }
78  dealii::Vector<double> function(dim);
79  dealii::FullMatrix<double> derivative(dim);
80  double beta =1.0/10.0;
81  double alpha =1.0/10.0;
82  int flag =0;
83  while(flag != dim){
84  if(dim==2){
85  function[0] = x_ref[0] - x_phys[0] +beta*std::cos(pi/2.0*x_ref[0])*std::cos(3.0*pi/2.0*x_ref[1]);
86  function[1] = x_ref[1] - x_phys[1] +beta*std::sin(2.0*pi*(x_ref[0]))*std::cos(pi/2.0*x_ref[1]);
87  }
88  else{
89  function[0] = x_ref[0] - x_phys[0] +alpha*(std::cos(pi * x_ref[2]) + std::cos(pi * x_ref[1]));
90  function[1] = x_ref[1] - x_phys[1] +alpha*exp(1.0-x_ref[1])*(std::sin(pi * x_ref[0]) + std::sin(pi* x_ref[2]));
91  function[2] = x_ref[2] - x_phys[2] +1.0/20.0*( std::sin(2.0 * pi * x_ref[0]) + std::sin(2.0 * pi * x_ref[1]));
92  }
93 
94 
95  if(dim==2){
96  derivative[0][0] = 1.0 - beta* pi/2.0 * std::sin(pi/2.0*x_ref[0])*std::cos(3.0*pi/2.0*x_ref[1]);
97  derivative[0][1] = - beta*3.0 *pi/2.0 * std::cos(pi/2.0*x_ref[0])*std::sin(3.0*pi/2.0*x_ref[1]);
98 
99  derivative[1][0] = beta*2.0*pi*std::cos(2.0*pi*(x_ref[0]))*std::cos(pi/2.0*x_ref[1]);
100  derivative[1][1] = 1.0 -beta*pi/2.0*std::sin(2.0*pi*(x_ref[0]))*std::sin(pi/2.0*x_ref[1]);
101  }
102  else{
103  derivative[0][0] = 1.0;
104  derivative[0][1] = - alpha*pi*std::sin(pi*x_ref[1]);
105  derivative[0][2] = - alpha*pi*std::sin(pi*x_ref[2]);
106 
107  derivative[1][0] = alpha*pi*exp(1.0-x_ref[1])*std::cos(pi*x_ref[0]);
108  derivative[1][1] = 1.0 -alpha*exp(1.0-x_ref[1])*(std::sin(pi*x_ref[0])+std::sin(pi*x_ref[2]));
109  derivative[1][2] = alpha*pi*exp(1.0-x_ref[1])*std::cos(pi*x_ref[2]);
110  derivative[2][0] = 1.0/10.0*pi*std::cos(2.0*pi*x_ref[0]);
111  derivative[2][1] = 1.0/10.0*pi*std::cos(2.0*pi*x_ref[1]);
112  derivative[2][2] = 1.0;
113  }
114 
115  dealii::FullMatrix<double> Jacobian_inv(dim);
116  Jacobian_inv.invert(derivative);
117  dealii::Vector<double> Newton_Step(dim);
118  Jacobian_inv.vmult(Newton_Step, function);
119  for(int idim=0; idim<dim; idim++){
120  x_ref[idim] -= Newton_Step[idim];
121  }
122  flag=0;
123  for(int idim=0; idim<dim; idim++){
124  if(std::abs(function[idim]) < 1e-15)
125  flag++;
126  }
127  if(flag == dim)
128  break;
129  }
130  std::vector<double> function_check(dim);
131  if(dim==2){
132  function_check[0] = x_ref[0] + beta*std::cos(pi/2.0*x_ref[0])*std::cos(3.0*pi/2.0*x_ref[1]);
133  function_check[1] = x_ref[1] + beta*std::sin(2.0*pi*(x_ref[0]))*std::cos(pi/2.0*x_ref[1]);
134  }
135  else{
136  function_check[0] = x_ref[0] +alpha*(std::cos(pi * x_ref[2]) + std::cos(pi * x_ref[1]));
137  function_check[1] = x_ref[1] +alpha*exp(1.0-x_ref[1])*(std::sin(pi * x_ref[0]) + std::sin(pi* x_ref[2]));
138  function_check[2] = x_ref[2] +1.0/20.0*( std::sin(2.0 * pi * x_ref[0]) + std::sin(2.0 * pi * x_ref[1]));
139  }
140  std::vector<double> error(dim);
141  for(int idim=0; idim<dim; idim++)
142  error[idim] = std::abs(function_check[idim] - x_phys[idim]);
143  if (error[0] > 1e-13) {
144  std::cout << "Large error " << error[0] << std::endl;
145  for(int idim=0;idim<dim; idim++)
146  std::cout << "dim " << idim << " xref " << x_ref[idim] << " x_phys " << x_phys[idim] << " function Check " << function_check[idim] << " Error " << error[idim] << " Flag " << flag << std::endl;
147  }
148 
149  return x_ref;
150 }
151 
152 template<int dim>
153 dealii::Point<dim> CurvManifold<dim>::push_forward(const dealii::Point<dim> &chart_point) const
154 {
155  const double pi = atan(1)*4.0;
156 
157  dealii::Point<dim> x_ref;
158  dealii::Point<dim> x_phys;
159  for(int idim=0; idim<dim; idim++)
160  x_ref[idim] = chart_point[idim];
161  double beta = 1.0/10.0;
162  double alpha = 1.0/10.0;
163  if(dim==2){
164  x_phys[0] = x_ref[0] + beta*std::cos(pi/2.0*x_ref[0])*std::cos(3.0*pi/2.0*x_ref[1]);
165  x_phys[1] = x_ref[1] + beta*std::sin(2.0*pi*(x_ref[0]))*std::cos(pi/2.0*x_ref[1]);
166  }
167  else{
168  x_phys[0] =x_ref[0] + alpha*(std::cos(pi * x_ref[2]) + std::cos(pi * x_ref[1]));
169  x_phys[1] =x_ref[1] + alpha*exp(1.0-x_ref[1])*(std::sin(pi * x_ref[0]) + std::sin(pi* x_ref[2]));
170  x_phys[2] =x_ref[2] + 1.0/20.0*( std::sin(2.0 * pi * x_ref[0]) + std::sin(2.0 * pi * x_ref[1]));
171  }
172  return dealii::Point<dim> (x_phys); // Trigonometric
173 }
174 
175 template<int dim>
176 dealii::DerivativeForm<1,dim,dim> CurvManifold<dim>::push_forward_gradient(const dealii::Point<dim> &chart_point) const
177 {
178  const double pi = atan(1)*4.0;
179  dealii::DerivativeForm<1, dim, dim> dphys_dref;
180  double beta = 1.0/10.0;
181  double alpha = 1.0/10.0;
182  dealii::Point<dim> x_ref;
183  for(int idim=0; idim<dim; idim++){
184  x_ref[idim] = chart_point[idim];
185  }
186 
187  if(dim==2){
188  dphys_dref[0][0] = 1.0 - beta*pi/2.0 * std::sin(pi/2.0*x_ref[0])*std::cos(3.0*pi/2.0*x_ref[1]);
189  dphys_dref[0][1] = - beta*3.0*pi/2.0 * std::cos(pi/2.0*x_ref[0])*std::sin(3.0*pi/2.0*x_ref[1]);
190 
191  dphys_dref[1][0] = beta*2.0*pi*std::cos(2.0*pi*(x_ref[0]))*std::cos(pi/2.0*x_ref[1]);
192  dphys_dref[1][1] = 1.0 -beta*pi/2.0*std::sin(2.0*pi*(x_ref[0]))*std::sin(pi/2.0*x_ref[1]);
193  }
194  else{
195  dphys_dref[0][0] = 1.0;
196  dphys_dref[0][1] = - alpha*pi*std::sin(pi*x_ref[1]);
197  dphys_dref[0][2] = - alpha*pi*std::sin(pi*x_ref[2]);
198 
199  dphys_dref[1][0] = alpha*pi*exp(1.0-x_ref[1])*std::cos(pi*x_ref[0]);
200  dphys_dref[1][1] = 1.0 -alpha*exp(1.0-x_ref[1])*(std::sin(pi*x_ref[0])+std::sin(pi*x_ref[2]));
201  dphys_dref[1][2] = alpha*pi*exp(1.0-x_ref[1])*std::cos(pi*x_ref[2]);
202  dphys_dref[2][0] = 1.0/10.0*pi*std::cos(2.0*pi*x_ref[0]);
203  dphys_dref[2][1] = 1.0/10.0*pi*std::cos(2.0*pi*x_ref[1]);
204  dphys_dref[2][2] = 1.0;
205  }
206 
207  return dphys_dref;
208 }
209 
210 template<int dim>
211 std::unique_ptr<dealii::Manifold<dim,dim> > CurvManifold<dim>::clone() const
212 {
213  return std::make_unique<CurvManifold<dim>>();
214 }
215 
216 template <int dim>
217 static dealii::Point<dim> warp (const dealii::Point<dim> &p)
218 {
219  const double pi = atan(1)*4.0;
220  dealii::Point<dim> q = p;
221 
222  double beta =1.0/10.0;
223  double alpha =1.0/10.0;
224  if (dim == 2){
225  q[dim-2] =p[dim-2] + beta*std::cos(pi/2.0 * p[dim-2]) * std::cos(3.0 * pi/2.0 * p[dim-1]);
226  q[dim-1] =p[dim-1] + beta*std::sin(2.0 * pi * (p[dim-2])) * std::cos(pi /2.0 * p[dim-1]);
227  }
228  if(dim==3){
229  q[0] =p[0] + alpha*(std::cos(pi * p[2]) + std::cos(pi * p[1]));
230  q[1] =p[1] + alpha*exp(1.0-p[1])*(std::sin(pi * p[0]) + std::sin(pi* p[2]));
231  q[2] =p[2] + 1.0/20.0*( std::sin(2.0 * pi * p[0]) + std::sin(2.0 * pi * p[1]));
232  }
233 
234  return q;
235 }
236 
237 /****************************
238  * End of Curvilinear Grid
239  * ***************************/
240 
241 int main (int argc, char * argv[])
242 {
243  dealii::Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);
244  using real = double;
245  using namespace PHiLiP;
246  std::cout << std::setprecision(std::numeric_limits<long double>::digits10 + 1) << std::scientific;
247  const int dim = PHILIP_DIM;
248  const int nspecies = 1;
249  const int nstate = 1;
250  dealii::ParameterHandler parameter_handler;
252  dealii::ConditionalOStream pcout(std::cout, dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)==0);
253 
254  PHiLiP::Parameters::AllParameters all_parameters_new;
255  all_parameters_new.parse_parameters (parameter_handler);
256 
257  all_parameters_new.use_curvilinear_split_form=true;
258  const int dim_check = 1;
259 
260  double left = 0.0;
261  double right = 1.0;
262  const bool colorize = true;
263  dealii::ConvergenceTable convergence_table;
264  const unsigned int igrid_start = 2;
265  const unsigned int n_grids = 5;
266  std::array<double,n_grids> grid_size;
267  std::array<double,n_grids> soln_error;
268  std::array<double,n_grids> soln_error_inf;
269  // loop poly degree
270  for(unsigned int poly_degree = 2; poly_degree<5; poly_degree++){
271  unsigned int grid_degree = poly_degree;
272  for(unsigned int igrid=igrid_start; igrid<n_grids; ++igrid){
273  pcout<<" Grid Index"<<igrid<<std::endl;
274  //Generate a standard grid
275  using Triangulation = dealii::parallel::distributed::Triangulation<dim>;
276  std::shared_ptr<Triangulation> grid = std::make_shared<Triangulation>(
277  MPI_COMM_WORLD,
278  typename dealii::Triangulation<dim>::MeshSmoothing(
279  dealii::Triangulation<dim>::smoothing_on_refinement |
280  dealii::Triangulation<dim>::smoothing_on_coarsening));
281  dealii::GridGenerator::hyper_cube (*grid, left, right, colorize);
282  grid->refine_global(igrid);
283  pcout<<" made grid for Index"<<igrid<<std::endl;
284 
285  //Warp the grid
286  //IF WANT NON-WARPED GRID COMMENT UNTIL SAYS "NOT COMMENT"
287  dealii::GridTools::transform (&warp<dim>, *grid);
288 
289  // Assign a manifold to have curved geometry
290  const CurvManifold<dim> curv_manifold;
291  unsigned int manifold_id=0; // top face, see GridGenerator::hyper_rectangle, colorize=true
292  grid->reset_all_manifolds();
293  grid->set_all_manifold_ids(manifold_id);
294  grid->set_manifold ( manifold_id, curv_manifold );
295  //"END COMMENT" TO NOT WARP GRID
296 
297  //setup operator
298  OPERATOR::OperatorsBaseState<dim,real,nstate,2*dim> operators(&all_parameters_new, poly_degree, poly_degree);
299  //setup DG
300  std::shared_ptr < PHiLiP::DGBase<dim, nspecies, double> > dg = PHiLiP::DGFactory<dim,nspecies,double>::create_discontinuous_galerkin(&all_parameters_new, poly_degree, poly_degree, grid_degree, grid);
301  dg->allocate_system ();
302 
303  dealii::IndexSet locally_owned_dofs;
304  dealii::IndexSet ghost_dofs;
305  dealii::IndexSet locally_relevant_dofs;
306  locally_owned_dofs = dg->dof_handler.locally_owned_dofs();
307  dealii::DoFTools::extract_locally_relevant_dofs(dg->dof_handler, ghost_dofs);
308  locally_relevant_dofs = ghost_dofs;
309  ghost_dofs.subtract_set(locally_owned_dofs);
310  dealii::LinearAlgebra::distributed::Vector<double> solution_deriv;
311  solution_deriv.reinit(locally_owned_dofs, ghost_dofs, MPI_COMM_WORLD);
312  //setup metric and solve
313 
314  const unsigned int max_dofs_per_cell = dg->dof_handler.get_fe_collection().max_dofs_per_cell();
315  std::vector<dealii::types::global_dof_index> current_dofs_indices(max_dofs_per_cell);
316  const unsigned int n_dofs_cell = dg->operators->fe_collection_basis[poly_degree].dofs_per_cell;
317  const unsigned int n_quad_pts = dg->operators->volume_quadrature_collection[poly_degree].size();
318 
319  const dealii::FESystem<dim> &fe_metric = (dg->high_order_grid->fe_system);
320  const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
321  auto metric_cell = dg->high_order_grid->dof_handler_grid.begin_active();
322  for (auto current_cell = dg->dof_handler.begin_active(); current_cell!=dg->dof_handler.end(); ++current_cell, ++metric_cell) {
323  if (!current_cell->is_locally_owned()) continue;
324 
325  std::vector<dealii::types::global_dof_index> current_metric_dofs_indices(n_metric_dofs);
326  metric_cell->get_dof_indices (current_metric_dofs_indices);
327  std::array<std::vector<real>,dim> mapping_support_points;
328  std::vector<std::vector<real>> phys_quad_pts(dim);
329  for(int idim=0; idim<dim; idim++){
330  mapping_support_points[idim].resize(n_metric_dofs/dim);
331  phys_quad_pts[idim].resize(n_quad_pts);
332  }
333  dealii::QGaussLobatto<dim> vol_GLL(grid_degree +1);
334  for (unsigned int igrid_node = 0; igrid_node< n_metric_dofs/dim; ++igrid_node) {
335  for (unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
336  const real val = (dg->high_order_grid->volume_nodes[current_metric_dofs_indices[idof]]);
337  const unsigned int istate = fe_metric.system_to_component_index(idof).first;
338  mapping_support_points[istate][igrid_node] += val * fe_metric.shape_value_component(idof,vol_GLL.point(igrid_node),istate);
339  }
340  }
341  std::vector<dealii::FullMatrix<real>> metric_cofactor(n_quad_pts);
342  std::vector<real> determinant_Jacobian(n_quad_pts);
343  for(unsigned int iquad=0;iquad<n_quad_pts; iquad++){
344  metric_cofactor[iquad].reinit(dim, dim);
345  }
346  operators.build_local_vol_metric_cofactor_matrix_and_det_Jac(grid_degree, poly_degree, n_quad_pts, n_metric_dofs/dim, mapping_support_points, determinant_Jacobian, metric_cofactor);
347 
348  //get physical split grdient in covariant basis
349  std::array<std::array<dealii::FullMatrix<real>,dim>,nstate> physical_gradient;
350  for(unsigned int istate=0; istate<nstate; istate++){
351  for(int idim=0; idim<dim; idim++){
352  physical_gradient[istate][idim].reinit(n_quad_pts, n_quad_pts);
353  }
354  }
355  operators.get_Jacobian_scaled_physical_gradient(true, operators.gradient_flux_basis[poly_degree], metric_cofactor, n_quad_pts, physical_gradient);
356 
357  //interpolate solution
358  current_dofs_indices.resize(n_dofs_cell);
359  current_cell->get_dof_indices (current_dofs_indices);
360  for(int idim=0; idim<dim; idim++){
361  for(unsigned int iquad=0; iquad<n_quad_pts; iquad++){
362  phys_quad_pts[idim][iquad] = 0.0;
363  for(unsigned int jquad=0; jquad<n_metric_dofs/dim; jquad++){
364  phys_quad_pts[idim][iquad] += operators.mapping_shape_functions_vol_flux_nodes[grid_degree][poly_degree][iquad][jquad]
365  * mapping_support_points[idim][jquad];
366  }
367  }
368  }
369  std::vector<real> soln(n_quad_pts);
370  for(unsigned int iquad=0; iquad<n_quad_pts; iquad++){
371  double exact = 1.0;
372  for (int idim=0; idim<dim; idim++){
373  exact *= exp(-(phys_quad_pts[idim][iquad])*(phys_quad_pts[idim][iquad]));
374  }
375  soln[iquad] = exact;
376  }//end interpolated solution
377 
378  dealii::Vector<real> soln_derivative_x(n_quad_pts);
379  for(int istate=0; istate<nstate; istate++){
380  for(unsigned int iquad=0; iquad<n_quad_pts; iquad++){
381  soln_derivative_x[iquad]=0.0;
382  for(unsigned int idof=0; idof<n_quad_pts; idof++){
383  soln_derivative_x[iquad] += physical_gradient[istate][dim_check][iquad][idof] * soln[idof];
384  }
385  soln_derivative_x[iquad] /= determinant_Jacobian[iquad];
386  }
387 
388  for(unsigned int idof=0; idof<n_dofs_cell; idof++){
389  solution_deriv[current_dofs_indices[idof]] = 0.0;
390  for(unsigned int iquad=0; iquad<n_quad_pts; iquad++){
391  solution_deriv[current_dofs_indices[idof]] += operators.vol_projection_operator[poly_degree][idof][iquad]
392  * soln_derivative_x[iquad];
393  }
394  }
395  }
396  }// end cell loop
397 
398  //TEST ERROR OOA
399  pcout<<"OOA here"<<std::endl;
400  double l2error = 0.0;
401  double linf_error = 0.0;
402  int overintegrate = 4;
403  dealii::QGauss<dim> quad_extra(poly_degree+1+overintegrate);
404  dealii::FEValues<dim,dim> fe_values_extra(*(dg->high_order_grid->mapping_fe_field), dg->operators->fe_collection_basis[poly_degree], quad_extra,
405  dealii::update_values | dealii::update_JxW_values |
406  dealii::update_jacobians |
407  dealii::update_quadrature_points | dealii::update_inverse_jacobians);
408  const unsigned int n_quad_pts_extra = fe_values_extra.n_quadrature_points;
409  std::vector<dealii::types::global_dof_index> dofs_indices (fe_values_extra.dofs_per_cell);
410  dealii::Vector<real> soln_at_q(n_quad_pts_extra);
411  for (auto current_cell = dg->dof_handler.begin_active(); current_cell!=dg->dof_handler.end(); ++current_cell) {
412  if (!current_cell->is_locally_owned()) continue;
413  fe_values_extra.reinit(current_cell);
414  dofs_indices.resize(fe_values_extra.dofs_per_cell);
415  current_cell->get_dof_indices (dofs_indices);
416 
417  for (unsigned int iquad=0; iquad<n_quad_pts_extra; ++iquad){
418  soln_at_q[iquad] = 0.0;
419  for (unsigned int idof=0; idof<fe_values_extra.dofs_per_cell; ++idof){
420  soln_at_q[iquad] += solution_deriv[dofs_indices[idof]] * fe_values_extra.shape_value_component(idof, iquad, 0);
421  }
422  const dealii::Point<dim> qpoint = (fe_values_extra.quadrature_point(iquad));
423  double uexact_x=1.0;
424  for(int idim=0; idim<dim; idim++){
425  uexact_x *= exp(-((qpoint[idim]) * (qpoint[idim])));
426  }
427  uexact_x *= - 2.0 * qpoint[dim_check];
428  l2error += pow(soln_at_q[iquad] - uexact_x, 2) * fe_values_extra.JxW(iquad);
429  double inf_temp = std::abs(soln_at_q[iquad]-uexact_x);
430  if(inf_temp > linf_error){
431  linf_error = inf_temp;
432  }
433  }
434 
435  }//end cell loop
436  pcout<<"got OOA here"<<std::endl;
437 
438  const unsigned int n_global_active_cells = grid->n_global_active_cells();
439  const double l2error_mpi_sum = std::sqrt(dealii::Utilities::MPI::sum(l2error, MPI_COMM_WORLD));
440  const double linferror_mpi= (dealii::Utilities::MPI::max(linf_error, MPI_COMM_WORLD));
441  // Convergence table
442  const unsigned int n_dofs = dg->dof_handler.n_dofs();
443  const double dx = 1.0/pow(n_dofs,(1.0/dim));
444  grid_size[igrid] = dx;
445  soln_error[igrid] = l2error_mpi_sum;
446  soln_error_inf[igrid] = linferror_mpi;
447 
448  convergence_table.add_value("p", poly_degree);
449  convergence_table.add_value("cells", n_global_active_cells);
450  convergence_table.add_value("DoFs", n_dofs);
451  convergence_table.add_value("dx", dx);
452  convergence_table.add_value("soln_L2_error", l2error_mpi_sum);
453  convergence_table.add_value("soln_Linf_error", linferror_mpi);
454 
455  pcout << " Grid size h: " << dx
456  << " L2-soln_error: " << l2error_mpi_sum
457  << " Linf-soln_error: " << linferror_mpi
458  << std::endl;
459 
460  if (igrid > igrid_start) {
461  const double slope_soln_err = log(soln_error[igrid]/soln_error[igrid-1])
462  / log(grid_size[igrid]/grid_size[igrid-1]);
463  const double slope_soln_err_inf = log(soln_error_inf[igrid]/soln_error_inf[igrid-1])
464  / log(grid_size[igrid]/grid_size[igrid-1]);
465  pcout << "From grid " << igrid-1
466  << " to grid " << igrid
467  << " dimension: " << dim
468  << " polynomial degree p: " << poly_degree
469  << std::endl
470  << " solution_error1 " << soln_error[igrid-1]
471  << " solution_error2 " << soln_error[igrid]
472  << " slope " << slope_soln_err
473  << " solution_error1_inf " << soln_error_inf[igrid-1]
474  << " solution_error2_inf " << soln_error_inf[igrid]
475  << " slope " << slope_soln_err_inf
476  << std::endl;
477  }
478  }//end grid refinement loop
479 
480  const int igrid = n_grids-1;
481  const double slope_soln_err = log(soln_error[igrid]/soln_error[igrid-1])
482  / log(grid_size[igrid]/grid_size[igrid-1]);
483  if(std::abs(slope_soln_err-poly_degree)>0.05){
484  return 1;
485  }
486  pcout << " ********************************************"
487  << std::endl
488  << " Convergence rates for p = " << poly_degree
489  << std::endl
490  << " ********************************************"
491  << std::endl;
492  convergence_table.evaluate_convergence_rates("soln_L2_error", "cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
493  convergence_table.evaluate_convergence_rates("soln_Linf_error", "cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
494  convergence_table.set_scientific("dx", true);
495  convergence_table.set_scientific("soln_L2_error", true);
496  convergence_table.set_scientific("soln_Linf_error", true);
497  if (pcout.is_active()) convergence_table.write_text(pcout.get_stream());
498  }//end poly degree loop
499 }// end of main
virtual dealii::Point< dim > pull_back(const dealii::Point< dim > &space_point) const override
See dealii::Manifold.
Files for the baseline physics.
Definition: ADTypes.hpp:10
Main parameter class that contains the various other sub-parameter classes.
virtual std::unique_ptr< dealii::Manifold< dim, dim > > clone() const override
See dealii::Manifold.
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.
Definition: dg_factory.cpp:11
virtual dealii::DerivativeForm< 1, dim, dim > push_forward_gradient(const dealii::Point< dim > &chart_point) const override
See dealii::Manifold.
void parse_parameters(dealii::ParameterHandler &prm)
Retrieve parameters from dealii::ParameterHandler.
virtual dealii::Point< dim > push_forward(const dealii::Point< dim > &chart_point) const override
See dealii::Manifold.
static void declare_parameters(dealii::ParameterHandler &prm)
Declare parameters that can be set as inputs and set up the default options.
bool use_curvilinear_split_form
Flag to use curvilinear metric split form.