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 nstate = 1;
247 dealii::ParameterHandler parameter_handler;
249 dealii::ConditionalOStream pcout(std::cout, dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)==0);
259 const bool colorize =
true;
261 using Triangulation = dealii::parallel::distributed::Triangulation<dim>;
262 std::shared_ptr<Triangulation> grid = std::make_shared<Triangulation>(
264 typename dealii::Triangulation<dim>::MeshSmoothing(
265 dealii::Triangulation<dim>::smoothing_on_refinement |
266 dealii::Triangulation<dim>::smoothing_on_coarsening));
267 dealii::GridGenerator::hyper_cube (*grid, left, right, colorize);
268 grid->refine_global(1);
272 dealii::GridTools::transform (&warp<dim>, *grid);
276 unsigned int manifold_id=0;
277 grid->reset_all_manifolds();
278 grid->set_all_manifold_ids(manifold_id);
279 grid->set_manifold ( manifold_id, curv_manifold );
282 for(
unsigned int poly_degree = 2; poly_degree<6; poly_degree++){
283 unsigned int grid_degree = poly_degree;
286 dg->allocate_system ();
288 dealii::QGaussLobatto<1> grid_quad(grid_degree +1);
289 const dealii::FE_DGQ<1> fe_grid(grid_degree);
290 const dealii::FESystem<1,1> fe_sys_grid(fe_grid, nstate);
291 dealii::QGauss<1> flux_quad(poly_degree +1);
292 dealii::QGauss<0> flux_quad_face(poly_degree +1);
295 mapping_basis.build_1D_shape_functions_at_grid_nodes(fe_sys_grid, grid_quad);
296 mapping_basis.build_1D_shape_functions_at_flux_nodes(fe_sys_grid, flux_quad, flux_quad_face);
301 const dealii::FESystem<dim> &fe_metric = (dg->high_order_grid->fe_system);
302 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
303 auto metric_cell = dg->high_order_grid->dof_handler_grid.begin_active();
304 for (
auto current_cell = dg->dof_handler.begin_active(); current_cell!=dg->dof_handler.end(); ++current_cell, ++metric_cell) {
305 if (!current_cell->is_locally_owned())
continue;
307 std::vector<dealii::types::global_dof_index> current_metric_dofs_indices(n_metric_dofs);
308 metric_cell->get_dof_indices (current_metric_dofs_indices);
309 std::array<std::vector<real>,dim> mapping_support_points;
310 for(
int idim=0; idim<dim; idim++){
311 mapping_support_points[idim].resize(n_metric_dofs/dim);
313 dealii::QGaussLobatto<dim> vol_GLL(grid_degree +1);
314 for (
unsigned int igrid_node = 0; igrid_node< n_metric_dofs/dim; ++igrid_node) {
315 for (
unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
316 const real val = (dg->high_order_grid->volume_nodes[current_metric_dofs_indices[idof]]);
317 const unsigned int istate = fe_metric.system_to_component_index(idof).first;
318 mapping_support_points[istate][igrid_node] += val * fe_metric.shape_value_component(idof,vol_GLL.point(igrid_node),istate);
322 const unsigned int n_quad_face_pts = dg->face_quadrature_collection[poly_degree].size();
323 for (
unsigned int iface=0; iface < dealii::GeometryInfo<dim>::faces_per_cell; ++iface) {
324 auto current_face = current_cell->face(iface);
325 if(current_face->at_boundary())
328 metric_oper.build_facet_metric_operators(
330 n_quad_face_pts, n_metric_dofs/dim,
331 mapping_support_points,
336 auto metric_neighbor_cell = metric_cell->neighbor(iface);
337 std::vector<dealii::types::global_dof_index> neighbor_metric_dofs_indices(n_metric_dofs);
338 metric_neighbor_cell->get_dof_indices(neighbor_metric_dofs_indices);
339 const unsigned int neighbor_iface = metric_cell->neighbor_face_no(iface);
340 std::array<std::vector<real>,dim> mapping_support_points_neigh;
341 for(
int idim=0; idim<dim; idim++){
342 mapping_support_points_neigh[idim].resize(n_metric_dofs/dim);
345 for (
unsigned int igrid_node = 0; igrid_node< n_metric_dofs/dim; ++igrid_node) {
346 for (
unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
347 const real val = (dg->high_order_grid->volume_nodes[neighbor_metric_dofs_indices[idof]]);
348 const unsigned int istate = fe_metric.system_to_component_index(idof).first;
349 mapping_support_points_neigh[istate][igrid_node] += val * fe_metric.shape_value_component(idof,vol_GLL.point(igrid_node),istate);
353 metric_oper_neigh.build_facet_metric_operators(
355 n_quad_face_pts, n_metric_dofs/dim,
356 mapping_support_points_neigh,
360 const dealii::Tensor<1,dim> unit_normal_int = dealii::GeometryInfo<dim>::unit_normal_vector[iface];
361 std::vector<dealii::Tensor<1,dim> > normal_phys_int(n_quad_face_pts);
362 std::vector<dealii::Tensor<1,dim> > normal_phys_ext(n_quad_face_pts);
363 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);
364 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);
366 for(
unsigned int iquad=0; iquad<n_quad_face_pts; iquad++){
367 for(
int idim=0; idim<dim; idim++){
368 if(std::abs(normal_phys_int[iquad][idim] - normal_phys_ext[iquad][idim]) > 1e-12){
369 pcout<<
" phys normal int "<<normal_phys_int[iquad][idim]<<
" phys normal ext "<<normal_phys_ext[iquad][idim]<<
" iquad "<<iquad<<
" idim "<<idim<<std::endl;
379 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.
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.
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.
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.