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;
59 virtual dealii::Point<dim> pull_back(
const dealii::Point<dim> &space_point)
const override;
60 virtual dealii::Point<dim> push_forward(
const dealii::Point<dim> &chart_point)
const override;
61 virtual dealii::DerivativeForm<1,dim,dim> push_forward_gradient(
const dealii::Point<dim> &chart_point)
const override;
63 virtual std::unique_ptr<dealii::Manifold<dim,dim> > clone()
const override;
70 const double pi = atan(1)*4.0;
71 dealii::Point<dim> x_ref;
72 dealii::Point<dim> x_phys;
73 for(
int idim=0; idim<dim; idim++){
74 x_ref[idim] = space_point[idim];
75 x_phys[idim] = space_point[idim];
77 dealii::Vector<double>
function(dim);
78 dealii::FullMatrix<double> derivative(dim);
79 double beta =1.0/10.0;
80 double alpha =1.0/10.0;
84 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]);
85 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]);
88 function[0] = x_ref[0] - x_phys[0] +alpha*(std::cos(pi * x_ref[2]) + std::cos(pi * x_ref[1]));
89 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]));
90 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]));
94 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]);
95 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]);
97 derivative[1][0] = beta*2.0*pi*std::cos(2.0*pi*(x_ref[0]))*std::cos(pi/2.0*x_ref[1]);
98 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 derivative[0][0] = 1.0;
102 derivative[0][1] = - alpha*pi*std::sin(pi*x_ref[1]);
103 derivative[0][2] = - alpha*pi*std::sin(pi*x_ref[2]);
105 derivative[1][0] = alpha*pi*exp(1.0-x_ref[1])*std::cos(pi*x_ref[0]);
106 derivative[1][1] = 1.0 -alpha*exp(1.0-x_ref[1])*(std::sin(pi*x_ref[0])+std::sin(pi*x_ref[2]));
107 derivative[1][2] = alpha*pi*exp(1.0-x_ref[1])*std::cos(pi*x_ref[2]);
108 derivative[2][0] = 1.0/10.0*pi*std::cos(2.0*pi*x_ref[0]);
109 derivative[2][1] = 1.0/10.0*pi*std::cos(2.0*pi*x_ref[1]);
110 derivative[2][2] = 1.0;
113 dealii::FullMatrix<double> Jacobian_inv(dim);
114 Jacobian_inv.invert(derivative);
115 dealii::Vector<double> Newton_Step(dim);
116 Jacobian_inv.vmult(Newton_Step,
function);
117 for(
int idim=0; idim<dim; idim++){
118 x_ref[idim] -= Newton_Step[idim];
121 for(
int idim=0; idim<dim; idim++){
122 if(std::abs(
function[idim]) < 1e-15)
128 std::vector<double> function_check(dim);
130 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]);
131 function_check[1] = x_ref[1] + beta*std::sin(2.0*pi*(x_ref[0]))*std::cos(pi/2.0*x_ref[1]);
134 function_check[0] = x_ref[0] +alpha*(std::cos(pi * x_ref[2]) + std::cos(pi * x_ref[1]));
135 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]));
136 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]));
138 std::vector<double> error(dim);
139 for(
int idim=0; idim<dim; idim++)
140 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);
255 all_parameters_new.
flux_nodes_type = Parameters::AllParameters::FluxNodes::GLL;
259 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(0);
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 );
282 double max_GCL = 0.0;
285 for(
unsigned int poly_degree = 2; poly_degree<5; poly_degree++){
286 unsigned int grid_degree = poly_degree;
289 dg->allocate_system ();
291 dealii::QGaussLobatto<1> grid_quad(grid_degree +1);
292 const dealii::FE_DGQ<1> fe_grid(grid_degree);
293 const dealii::FESystem<1,1> fe_sys_grid(fe_grid, nstate);
294 dealii::QGauss<1> flux_quad(poly_degree +1);
295 dealii::QGauss<0> flux_quad_face(poly_degree +1);
301 const unsigned int n_quad_pts = pow(poly_degree+1,dim);
303 const dealii::FESystem<dim> &fe_metric = (dg->high_order_grid->fe_system);
304 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
305 auto metric_cell = dg->high_order_grid->dof_handler_grid.begin_active();
306 for (
auto current_cell = dg->dof_handler.begin_active(); current_cell!=dg->dof_handler.end(); ++current_cell, ++metric_cell) {
307 if (!current_cell->is_locally_owned())
continue;
309 pcout<<
" degree "<<grid_degree<<
" metric dofs "<<n_metric_dofs<<std::endl;
310 std::vector<dealii::types::global_dof_index> current_metric_dofs_indices(n_metric_dofs);
311 metric_cell->get_dof_indices (current_metric_dofs_indices);
312 std::array<std::vector<real>,dim> mapping_support_points;
313 for(
int idim=0; idim<dim; idim++){
314 mapping_support_points[idim].resize(n_metric_dofs/dim);
316 dealii::QGaussLobatto<dim> vol_GLL(grid_degree +1);
317 for (
unsigned int igrid_node = 0; igrid_node< n_metric_dofs/dim; ++igrid_node) {
318 for (
unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
319 const real val = (dg->high_order_grid->volume_nodes[current_metric_dofs_indices[idof]]);
320 const unsigned int istate = fe_metric.system_to_component_index(idof).first;
321 mapping_support_points[istate][igrid_node] += val * fe_metric.shape_value_component(idof,vol_GLL.point(igrid_node),istate);
327 n_quad_pts, n_metric_dofs/dim,
328 mapping_support_points,
332 std::array<std::vector<real>,dim> GCL;
333 for(
int idim=0; idim<dim; idim++){
334 GCL[idim].resize(n_quad_pts);
337 const dealii::FE_DGQArbitraryNodes<1> fe_poly(flux_quad);
338 const dealii::FESystem<1,1> fe_sys_poly(fe_poly, nstate);
342 for(
int idim=0; idim<dim; idim++){
352 for(
int idim=0; idim<dim; idim++){
354 for(
unsigned int idof=0; idof<n_quad_pts; idof++){
356 if(std::abs(GCL[idim][idof]) > max_GCL){
357 max_GCL = std::abs(GCL[idim][idof]);
364 const double max_GCL_mpi= (dealii::Utilities::MPI::max(max_GCL, MPI_COMM_WORLD));
366 if(max_GCL_mpi > 1e-10){
367 pcout<<
" Metrics Do NOT Satisfy GCL Condition\n"<<std::endl;
371 pcout<<
" Metrics Satisfy GCL Condition\n"<<std::endl;
dealii::Tensor< 2, dim, std::vector< real > > metric_cofactor_vol
The volume metric cofactor matrix.
void build_1D_gradient_state_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
void build_1D_volume_state_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
virtual dealii::Point< dim > pull_back(const dealii::Point< dim > &space_point) const override
See dealii::Manifold.
Files for the baseline physics.
void build_1D_shape_functions_at_flux_nodes(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature, const dealii::Quadrature< 0 > &face_quadrature)
Constructs the volume, gradient, surface, and surface gradient operator.
Main parameter class that contains the various other sub-parameter classes.
void build_volume_metric_operators(const unsigned int n_quad_pts, const unsigned int n_metric_dofs, const std::array< std::vector< real >, dim > &mapping_support_points, mapping_shape_functions< dim, n_faces > &mapping_basis, const bool use_invariant_curl_form=false)
Builds the volume metric operators.
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...
The basis functions separated by nstate with n shape functions.
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.
void build_1D_shape_functions_at_grid_nodes(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Constructs the volume operator and gradient operator.
FluxNodes flux_nodes_type
Store selected FluxNodes from the input file.
void divergence_matrix_vector_mult(const dealii::Tensor< 1, dim, std::vector< real >> &input_vect, std::vector< real > &output_vect, const dealii::FullMatrix< double > &basis_x, const dealii::FullMatrix< double > &basis_y, const dealii::FullMatrix< double > &basis_z, const dealii::FullMatrix< double > &gradient_basis_x, const dealii::FullMatrix< double > &gradient_basis_y, const dealii::FullMatrix< double > &gradient_basis_z)
Computes the divergence using the sum factorization matrix-vector multiplication. ...
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.