9 #include <deal.II/distributed/solution_transfer.h> 11 #include "testing/tests.h" 14 #include <deal.II/base/parameter_handler.h> 15 #include <deal.II/base/tensor.h> 16 #include <deal.II/numerics/vector_tools.h> 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> 24 #include <deal.II/dofs/dof_handler.h> 25 #include <deal.II/dofs/dof_tools.h> 26 #include <deal.II/dofs/dof_renumbering.h> 28 #include <deal.II/dofs/dof_accessor.h> 30 #include <deal.II/lac/vector.h> 31 #include <deal.II/lac/dynamic_sparsity_pattern.h> 32 #include <deal.II/lac/sparse_matrix.h> 34 #include <deal.II/meshworker/dof_info.h> 38 #include <deal.II/fe/mapping_q.h> 39 #include <deal.II/grid/manifold_lib.h> 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> 45 #include "dg/dg_base.hpp" 46 #include "dg/dg_factory.hpp" 47 #include "operators/operators.h" 48 #include "parameters/all_parameters.h" 49 #include "parameters/parameters.h" 52 const double TOLERANCE = 1E-6;
57 class CurvManifold:
public dealii::ChartManifold<dim,dim,dim> {
58 virtual dealii::Point<dim> pull_back(
const dealii::Point<dim> &space_point)
const override;
59 virtual dealii::Point<dim> push_forward(
const dealii::Point<dim> &chart_point)
const override;
60 virtual dealii::DerivativeForm<1,dim,dim> push_forward_gradient(
const dealii::Point<dim> &chart_point)
const override;
62 virtual std::unique_ptr<dealii::Manifold<dim,dim> > clone()
const override;
69 const double pi = atan(1)*4.0;
70 dealii::Point<dim> x_ref;
71 dealii::Point<dim> x_phys;
72 for(
int idim=0; idim<dim; idim++){
73 x_ref[idim] = space_point[idim];
74 x_phys[idim] = space_point[idim];
76 dealii::Vector<double>
function(dim);
77 dealii::FullMatrix<double> derivative(dim);
78 double beta =1.0/10.0;
79 double alpha =1.0/10.0;
83 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]);
84 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 function[0] = x_ref[0] - x_phys[0] +alpha*(std::cos(pi * x_ref[2]) + std::cos(pi * x_ref[1]));
88 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]));
89 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]));
93 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]);
94 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]);
96 derivative[1][0] = beta*2.0*pi*std::cos(2.0*pi*(x_ref[0]))*std::cos(pi/2.0*x_ref[1]);
97 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]);
100 derivative[0][0] = 1.0;
101 derivative[0][1] = - alpha*pi*std::sin(pi*x_ref[1]);
102 derivative[0][2] = - alpha*pi*std::sin(pi*x_ref[2]);
104 derivative[1][0] = alpha*pi*exp(1.0-x_ref[1])*std::cos(pi*x_ref[0]);
105 derivative[1][1] = 1.0 -alpha*exp(1.0-x_ref[1])*(std::sin(pi*x_ref[0])+std::sin(pi*x_ref[2]));
106 derivative[1][2] = alpha*pi*exp(1.0-x_ref[1])*std::cos(pi*x_ref[2]);
107 derivative[2][0] = 1.0/10.0*pi*std::cos(2.0*pi*x_ref[0]);
108 derivative[2][1] = 1.0/10.0*pi*std::cos(2.0*pi*x_ref[1]);
109 derivative[2][2] = 1.0;
112 dealii::FullMatrix<double> Jacobian_inv(dim);
113 Jacobian_inv.invert(derivative);
114 dealii::Vector<double> Newton_Step(dim);
115 Jacobian_inv.vmult(Newton_Step,
function);
116 for(
int idim=0; idim<dim; idim++){
117 x_ref[idim] -= Newton_Step[idim];
120 for(
int idim=0; idim<dim; idim++){
121 if(std::abs(
function[idim]) < 1e-15)
127 std::vector<double> function_check(dim);
129 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]);
130 function_check[1] = x_ref[1] + beta*std::sin(2.0*pi*(x_ref[0]))*std::cos(pi/2.0*x_ref[1]);
133 function_check[0] = x_ref[0] +alpha*(std::cos(pi * x_ref[2]) + std::cos(pi * x_ref[1]));
134 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]));
135 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]));
137 std::vector<double> error(dim);
138 for(
int idim=0; idim<dim; idim++){
139 error[idim] = std::abs(function_check[idim] - x_phys[idim]);
141 if (error[0] > 1e-13) {
142 std::cout <<
"Large error " << error[0] << std::endl;
143 for(
int idim=0;idim<dim; idim++)
144 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;
153 const double pi = atan(1)*4.0;
155 dealii::Point<dim> x_ref;
156 dealii::Point<dim> x_phys;
157 for(
int idim=0; idim<dim; idim++)
158 x_ref[idim] = chart_point[idim];
159 double beta = 1.0/10.0;
160 double alpha = 1.0/10.0;
162 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]);
163 x_phys[1] = x_ref[1] + beta*std::sin(2.0*pi*(x_ref[0]))*std::cos(pi/2.0*x_ref[1]);
166 x_phys[0] =x_ref[0] + alpha*(std::cos(pi * x_ref[2]) + std::cos(pi * x_ref[1]));
167 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]));
168 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]));
170 return dealii::Point<dim> (x_phys);
176 const double pi = atan(1)*4.0;
177 dealii::DerivativeForm<1, dim, dim> dphys_dref;
178 double beta = 1.0/10.0;
179 double alpha = 1.0/10.0;
180 dealii::Point<dim> x_ref;
181 for(
int idim=0; idim<dim; idim++){
182 x_ref[idim] = chart_point[idim];
186 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]);
187 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]);
189 dphys_dref[1][0] = beta*2.0*pi*std::cos(2.0*pi*(x_ref[0]))*std::cos(pi/2.0*x_ref[1]);
190 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 dphys_dref[0][0] = 1.0;
194 dphys_dref[0][1] = - alpha*pi*std::sin(pi*x_ref[1]);
195 dphys_dref[0][2] = - alpha*pi*std::sin(pi*x_ref[2]);
197 dphys_dref[1][0] = alpha*pi*exp(1.0-x_ref[1])*std::cos(pi*x_ref[0]);
198 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]));
199 dphys_dref[1][2] = alpha*pi*exp(1.0-x_ref[1])*std::cos(pi*x_ref[2]);
200 dphys_dref[2][0] = 1.0/10.0*pi*std::cos(2.0*pi*x_ref[0]);
201 dphys_dref[2][1] = 1.0/10.0*pi*std::cos(2.0*pi*x_ref[1]);
202 dphys_dref[2][2] = 1.0;
211 return std::make_unique<CurvManifold<dim>>();
215 static dealii::Point<dim> warp (
const dealii::Point<dim> &p)
217 const double pi = atan(1)*4.0;
218 dealii::Point<dim> q = p;
220 double beta =1.0/10.0;
221 double alpha =1.0/10.0;
223 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]);
224 q[dim-1] =p[dim-1] + beta*std::sin(2.0 * pi * (p[dim-2])) * std::cos(pi /2.0 * p[dim-1]);
227 q[0] =p[0] + alpha*(std::cos(pi * p[2]) + std::cos(pi * p[1]));
228 q[1] =p[1] + alpha*exp(1.0-p[1])*(std::sin(pi * p[0]) + std::sin(pi* p[2]));
229 q[2] =p[2] + 1.0/20.0*( std::sin(2.0 * pi * p[0]) + std::sin(2.0 * pi * p[1]));
239 int main (
int argc,
char * argv[])
241 dealii::Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);
244 std::cout << std::setprecision(std::numeric_limits<long double>::digits10 + 1) << std::scientific;
245 const int dim = PHILIP_DIM;
246 const int nspecies = 1;
247 const int nstate = 1;
248 dealii::ParameterHandler parameter_handler;
250 dealii::ConditionalOStream pcout(std::cout, dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)==0);
260 const bool colorize =
true;
262 using Triangulation = dealii::parallel::distributed::Triangulation<dim>;
263 std::shared_ptr<Triangulation> grid = std::make_shared<Triangulation>(
265 typename dealii::Triangulation<dim>::MeshSmoothing(
266 dealii::Triangulation<dim>::smoothing_on_refinement |
267 dealii::Triangulation<dim>::smoothing_on_coarsening));
268 dealii::GridGenerator::hyper_cube (*grid, left, right, colorize);
269 grid->refine_global(1);
273 dealii::GridTools::transform (&warp<dim>, *grid);
277 unsigned int manifold_id=0;
278 grid->reset_all_manifolds();
279 grid->set_all_manifold_ids(manifold_id);
280 grid->set_manifold ( manifold_id, curv_manifold );
283 for(
unsigned int poly_degree = 2; poly_degree<6; poly_degree++){
284 unsigned int grid_degree = poly_degree;
287 dg->allocate_system ();
289 dealii::QGaussLobatto<1> grid_quad(grid_degree +1);
290 const dealii::FE_DGQ<1> fe_grid(grid_degree);
291 const dealii::FESystem<1,1> fe_sys_grid(fe_grid, nstate);
292 dealii::QGauss<1> flux_quad(poly_degree +1);
293 dealii::QGauss<0> flux_quad_face(poly_degree +1);
296 mapping_basis.build_1D_shape_functions_at_grid_nodes(fe_sys_grid, grid_quad);
297 mapping_basis.build_1D_shape_functions_at_flux_nodes(fe_sys_grid, flux_quad, flux_quad_face);
302 const dealii::FESystem<dim> &fe_metric = (dg->high_order_grid->fe_system);
303 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
304 auto metric_cell = dg->high_order_grid->dof_handler_grid.begin_active();
305 for (
auto current_cell = dg->dof_handler.begin_active(); current_cell!=dg->dof_handler.end(); ++current_cell, ++metric_cell) {
306 if (!current_cell->is_locally_owned())
continue;
308 std::vector<dealii::types::global_dof_index> current_metric_dofs_indices(n_metric_dofs);
309 metric_cell->get_dof_indices (current_metric_dofs_indices);
310 std::array<std::vector<real>,dim> mapping_support_points;
311 for(
int idim=0; idim<dim; idim++){
312 mapping_support_points[idim].resize(n_metric_dofs/dim);
314 dealii::QGaussLobatto<dim> vol_GLL(grid_degree +1);
315 for (
unsigned int igrid_node = 0; igrid_node< n_metric_dofs/dim; ++igrid_node) {
316 for (
unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
317 const real val = (dg->high_order_grid->volume_nodes[current_metric_dofs_indices[idof]]);
318 const unsigned int istate = fe_metric.system_to_component_index(idof).first;
319 mapping_support_points[istate][igrid_node] += val * fe_metric.shape_value_component(idof,vol_GLL.point(igrid_node),istate);
323 const unsigned int n_quad_face_pts = dg->face_quadrature_collection[poly_degree].size();
324 for (
unsigned int iface=0; iface < dealii::GeometryInfo<dim>::faces_per_cell; ++iface) {
325 auto current_face = current_cell->face(iface);
326 if(current_face->at_boundary())
329 metric_oper.build_facet_metric_operators(
331 n_quad_face_pts, n_metric_dofs/dim,
332 mapping_support_points,
337 auto metric_neighbor_cell = metric_cell->neighbor(iface);
338 std::vector<dealii::types::global_dof_index> neighbor_metric_dofs_indices(n_metric_dofs);
339 metric_neighbor_cell->get_dof_indices(neighbor_metric_dofs_indices);
340 const unsigned int neighbor_iface = metric_cell->neighbor_face_no(iface);
341 std::array<std::vector<real>,dim> mapping_support_points_neigh;
342 for(
int idim=0; idim<dim; idim++){
343 mapping_support_points_neigh[idim].resize(n_metric_dofs/dim);
346 for (
unsigned int igrid_node = 0; igrid_node< n_metric_dofs/dim; ++igrid_node) {
347 for (
unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
348 const real val = (dg->high_order_grid->volume_nodes[neighbor_metric_dofs_indices[idof]]);
349 const unsigned int istate = fe_metric.system_to_component_index(idof).first;
350 mapping_support_points_neigh[istate][igrid_node] += val * fe_metric.shape_value_component(idof,vol_GLL.point(igrid_node),istate);
354 metric_oper_neigh.build_facet_metric_operators(
356 n_quad_face_pts, n_metric_dofs/dim,
357 mapping_support_points_neigh,
361 const dealii::Tensor<1,dim> unit_normal_int = dealii::GeometryInfo<dim>::unit_normal_vector[iface];
362 std::vector<dealii::Tensor<1,dim> > normal_phys_int(n_quad_face_pts);
363 std::vector<dealii::Tensor<1,dim> > normal_phys_ext(n_quad_face_pts);
364 metric_oper.transform_reference_unit_normal_to_physical_unit_normal(n_quad_face_pts, unit_normal_int, metric_oper.metric_cofactor_surf, normal_phys_int);
365 metric_oper_neigh.transform_reference_unit_normal_to_physical_unit_normal(n_quad_face_pts, unit_normal_int, metric_oper_neigh.metric_cofactor_surf, normal_phys_ext);
367 for(
unsigned int iquad=0; iquad<n_quad_face_pts; iquad++){
368 for(
int idim=0; idim<dim; idim++){
369 if(std::abs(normal_phys_int[iquad][idim] - normal_phys_ext[iquad][idim]) > 1e-12){
370 pcout<<
" phys normal int "<<normal_phys_int[iquad][idim]<<
" phys normal ext "<<normal_phys_ext[iquad][idim]<<
" iquad "<<iquad<<
" idim "<<idim<<std::endl;
380 pcout<<
" Metrics Satisfy Surface Conforming Condition\n"<<std::endl;
virtual dealii::Point< dim > pull_back(const dealii::Point< dim > &space_point) const override
See dealii::Manifold.
Files for the baseline physics.
Main parameter class that contains the various other sub-parameter classes.
Base metric operators class that stores functions used in both the volume and on surface.
The mapping shape functions evaluated at the desired nodes (facet set included in volume grid nodes f...
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.
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.