[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
high_order_grid.h
1 #ifndef __HIGHORDERGRID_H__
2 #define __HIGHORDERGRID_H__
3 
4 #include <deal.II/base/conditional_ostream.h>
5 
6 #include <deal.II/grid/tria.h>
7 #include <deal.II/distributed/shared_tria.h>
8 #include <deal.II/distributed/tria.h>
9 
10 #include <deal.II/fe/fe_q.h>
11 #include <deal.II/fe/fe_system.h>
12 #include <deal.II/fe/mapping_fe_field.h>
13 #include <deal.II/fe/fe_dgq.h>
14 
15 #include <deal.II/dofs/dof_handler.h>
16 
17 #include <deal.II/numerics/solution_transfer.h>
18 #include <deal.II/distributed/solution_transfer.h>
19 
20 #include <deal.II/lac/vector.h>
21 #include <deal.II/lac/la_parallel_vector.templates.h>
22 
23 #include <deal.II/numerics/data_postprocessor.h>
24 #include <deal.II/numerics/data_out.h>
25 #include <deal.II/numerics/data_out_dof_data.h>
26 
27 #include <deal.II/lac/trilinos_sparse_matrix.h>
28 #include <deal.II/lac/trilinos_vector.h>
29 
30 #include "parameters/all_parameters.h"
31 
32 namespace PHiLiP {
33 
34 // determines the associated typenames for HO grid from the meshType
35 template <typename MeshType>
37 
38 // specializations
39 template <>
40 class MeshTypeHelper<dealii::Triangulation<PHILIP_DIM>>
41 {
42 public:
43  using VectorType = dealii::LinearAlgebra::distributed::Vector<double>;
44  using DoFHandlerType = dealii::DoFHandler<PHILIP_DIM>;
45 
46  template <int dim = PHILIP_DIM, typename Vector = VectorType, typename DoFHandler = DoFHandlerType>
47  using SolutionTransfer = dealii::SolutionTransfer<dim, Vector, DoFHandler>;
48 
49  // reinitialize vector based on parralel Dofhandler
50  static void reinit_vector(
51  VectorType &vector,
52  DoFHandlerType const &/* dof_handler */,
53  dealii::IndexSet const &locally_owned_dofs,
54  dealii::IndexSet const &ghost_dofs,
55  MPI_Comm const mpi_communicator)
56  {
57  vector.reinit(locally_owned_dofs, ghost_dofs, mpi_communicator);
58  }
59 };
60 
61 template <>
62 class MeshTypeHelper<dealii::parallel::distributed::Triangulation<PHILIP_DIM>>
63 {
64 public:
65  using VectorType = dealii::LinearAlgebra::distributed::Vector<double>;
66  using DoFHandlerType = dealii::DoFHandler<PHILIP_DIM>;
67 
68  template <int dim = PHILIP_DIM, typename Vector = VectorType, typename DoFHandler = DoFHandlerType>
69  using SolutionTransfer = dealii::parallel::distributed::SolutionTransfer<dim, Vector, DoFHandler>;
70 
71  // reinitialize vector based on parralel Dofhandler
72  static void reinit_vector(
73  VectorType &vector,
74  DoFHandlerType const &/* dof_handler */,
75  dealii::IndexSet const &locally_owned_dofs,
76  dealii::IndexSet const &ghost_dofs,
77  MPI_Comm const mpi_communicator)
78  {
79  vector.reinit(locally_owned_dofs, ghost_dofs, mpi_communicator);
80  }
81 };
82 
83 #if PHILIP_DIM1!=1 // dealii::parallel::distributed::Triangulation<dim> does not work for 1D
84 template <>
85 class MeshTypeHelper<dealii::parallel::shared::Triangulation<PHILIP_DIM>>
86 {
87 public:
88  using VectorType = dealii::LinearAlgebra::distributed::Vector<double>;
89  using DoFHandlerType = dealii::DoFHandler<PHILIP_DIM>;
90 
91  template <int dim = PHILIP_DIM, typename Vector = VectorType, typename DoFHandler = DoFHandlerType>
92  using SolutionTransfer = dealii::SolutionTransfer<dim, Vector, DoFHandler>;
93 
94  // reinitialize vector based on parralel Dofhandler
95  static void reinit_vector(
96  VectorType &vector,
97  DoFHandlerType const &/* dof_handler */,
98  dealii::IndexSet const &locally_owned_dofs,
99  dealii::IndexSet const &ghost_dofs,
100  MPI_Comm const mpi_communicator)
101  {
102  vector.reinit(locally_owned_dofs, ghost_dofs, mpi_communicator);
103  }
104 };
105 #endif
106 
117 #if PHILIP_DIM==1 // dealii::parallel::distributed::Triangulation<dim> does not work for 1D
118 template <int dim = PHILIP_DIM,
119  typename real = double,
120  typename MeshType = dealii::Triangulation<dim>,
121  typename VectorType = typename MeshTypeHelper<MeshType>::VectorType,
122  typename DoFHandlerType = typename MeshTypeHelper<MeshType>::DoFHandlerType>
123 #else
124 template <int dim = PHILIP_DIM,
125  typename real = double,
126  typename MeshType = dealii::parallel::distributed::Triangulation<dim>,
127  typename VectorType = typename MeshTypeHelper<MeshType>::VectorType,
128  typename DoFHandlerType = typename MeshTypeHelper<MeshType>::DoFHandlerType>
129 #endif
131 {
132  using SolutionTransfer = typename MeshTypeHelper<MeshType>::template SolutionTransfer<dim,VectorType,DoFHandlerType>;
133 public:
136  const unsigned int max_degree,
137  const std::shared_ptr<MeshType> triangulation_input,
138  const bool check_valid_metric_Jacobian_input=true,
139  const bool renumber_dof_handler_Cuthill_Mckee_input=true,
140  const bool output_high_order_grid=true);
141 
143  void reinit();
144 
146 
149  void update_mapping_fe_field();
150 
152  void ensure_conforming_mesh();
153 
155  void initialize_with_triangulation_manifold(const bool output_mesh = true);
156 
158  void allocate();
159 
161  dealii::MappingFEField<dim,dim,VectorType,DoFHandlerType> get_MappingFEField();
162 
164  const unsigned int max_degree;
165 
166  const std::shared_ptr<MeshType> triangulation;
167 
170 
173 
175  dealii::DoFHandler<dim> dof_handler_grid;
176 
178 
184  VectorType volume_nodes;
185 
186 
189  VectorType surface_nodes;
190 
192 
196 
199 
201  void reset_initial_nodes();
202 
206  dealii::LinearAlgebra::distributed::Vector<int> surface_to_volume_indices;
207 
213  dealii::TrilinosWrappers::SparseMatrix map_nodes_surf_to_vol;
214 
216  void update_map_nodes_surf_to_vol();
217 
224 
226  std::vector<unsigned int> n_locally_owned_surface_nodes_per_mpi;
227 
229 
236 
238  std::vector<dealii::types::global_dof_index> locally_relevant_surface_nodes_indices;
240  std::vector<dealii::types::global_dof_index> locally_relevant_surface_nodes_boundary_id;
241 
243 
249  std::vector<real> locally_owned_surface_nodes;
251 
255  std::vector<real> all_surface_nodes;
260  std::vector<dealii::types::global_dof_index> all_surface_indices;
261 
263  std::vector<dealii::types::global_dof_index> locally_owned_surface_nodes_indices;
264 
265  // /// List of cells associated with locally_relevant_surface_nodes_indices
266  // std::vector<dealii::types::global_dof_index> locally_relevant_surface_nodes_cells;
267  // /// List of points associated with locally_relevant_surface_nodes_indices
268  // std::vector<dealii::types::global_dof_index> locally_relevant_surface_nodes_points;
269  // /// List of direction associated with locally_relevant_surface_nodes_indices
270  // std::vector<dealii::types::global_dof_index> locally_relevant_surface_nodes_direction;
271 
273 
277  std::vector<dealii::Point<dim>> locally_relevant_surface_points;
278 
280 
282  std::vector<dealii::Point<dim>> initial_locally_relevant_surface_points;
283 
288  std::map<dealii::types::global_dof_index, std::pair<unsigned int, unsigned int>> global_index_to_point_and_axis;
293  std::map<std::pair<unsigned int, unsigned int>, dealii::types::global_dof_index> point_and_axis_to_global_index;
294 
295  // /** Given the Point index within the locally_relevant_surface_points and its component,
296  // * this will return the index of the surface_nodes' index.
297  // * This allows us to obtain a deformation vector matching the locally_relevant_surface_points, and then copy
298  // * its results to the surface_nodes.
299  // */
300  // std::map<std::pair<unsigned int, unsigned int>, dealii::types::global_dof_index> point_and_axis_to_surface_nodes_index;
301 
302 
303 
305  void update_surface_nodes();
306 
309  VectorType transform_surface_nodes(std::function<dealii::Point<dim>(dealii::Point<dim>)> transformation) const;
310 
312  //void deform_mesh(VectorType surface_displacements);
313  void deform_mesh(std::vector<real> local_surface_displacements);
314 
315  void test_jacobian();
316 
318  std::vector<real> evaluate_jacobian_at_points(
319  const VectorType &solution,
320  const typename DoFHandlerType::cell_iterator &cell,
321  const std::vector<dealii::Point<dim>> &points) const;
322 
324 
327  template <typename real2>
328  void evaluate_jacobian_at_points(
329  const std::vector<real2> &dofs,
330  const dealii::FESystem<dim> &fe,
331  const std::vector<dealii::Point<dim>> &points,
332  std::vector<real2> &jacobian_determinants) const;
334 
336  template <typename real2>
337  real2 evaluate_jacobian_at_point(
338  const std::vector<real2> &dofs,
339  const dealii::FESystem<dim> &fe,
340  const dealii::Point<dim> &point) const;
341 
343  bool check_valid_cell(const typename DoFHandlerType::cell_iterator &cell) const;
344 
346  bool fix_invalid_cell(const typename DoFHandlerType::cell_iterator &cell);
347 
349  dealii::FullMatrix<double> lagrange_to_bernstein_operator;
351 
354  void evaluate_lagrange_to_bernstein_operator(const unsigned int order);
355 
356  void output_results_vtk (const unsigned int cycle) const;
357 
358 
359  // /// Evaluate cell metric Jacobian
360  // /** The metric Jacobian is given by the gradient of the physical location
361  // * with respect to the reference locations
362  // */
363  // dealii::Tensor<2,dim,real> cell_jacobian (const typename dealii::Triangulation<dim,spacedim>::cell_iterator &cell, const dealii::Point<dim> &point) const override
364  // {
365  // }
366 
368  void refine_global();
369 
371 
374  void prepare_for_coarsening_and_refinement();
376 
379  void execute_coarsening_and_refinement(const bool output_mesh = false);
380 
382  const dealii::FE_Q<dim> fe_q;
384  const dealii::FESystem<dim> fe_system;
386 
394  const dealii::FE_DGQ<1> oneD_fe_q;
396  const dealii::FESystem<1> oneD_fe_system;
398  const dealii::QGaussLobatto<1> oneD_grid_nodes;
400  const dealii::QGaussLobatto<dim> dim_grid_nodes;
401 
402 
404 
408  std::shared_ptr<dealii::MappingFEField<dim,dim,VectorType,DoFHandlerType>> mapping_fe_field;
409 
411 
416  std::shared_ptr<dealii::MappingFEField<dim,dim,VectorType,DoFHandlerType>> initial_mapping_fe_field;
417 
418  dealii::IndexSet locally_owned_dofs_grid;
419  dealii::IndexSet ghost_dofs_grid;
420  dealii::IndexSet locally_relevant_dofs_grid;
421 
422  static unsigned int nth_refinement;
423 protected:
424  int n_mpi;
425  int mpi_rank;
426  void update_surface_indices();
428 
430  VectorType old_volume_nodes;
431 
435  SolutionTransfer solution_transfer;
436 
437  MPI_Comm mpi_communicator;
438  dealii::ConditionalOStream pcout;
439 
441 
443  template <typename real2>
444  real2 determinant(const std::array< dealii::Tensor<1,dim,real2>, dim > jacobian) const;
445 
447  void get_position_vector(const DoFHandlerType &dh, VectorType &vector, const dealii::ComponentMask &mask);
448 
451  void get_projected_position_vector(const DoFHandlerType &dh, VectorType &vector, const dealii::ComponentMask &mask);
452 
453 };
454 
456 template <int dim>
457 class GridPostprocessor : public dealii::DataPostprocessor<dim>
458 {
459 public:
460  // /// Constructor
461  // GridPostprocessor();
462 
464  virtual void evaluate_vector_field (const dealii::DataPostprocessorInputs::Vector<dim> &inputs, std::vector<dealii::Vector<double>> &computed_quantities) const override;
466  virtual std::vector<std::string> get_names () const override;
468  virtual std::vector<dealii::DataComponentInterpretation::DataComponentInterpretation> get_data_component_interpretation () const override;
470  virtual dealii::UpdateFlags get_needed_update_flags () const override;
471 };
472 
473 
474 } // namespace PHiLiP
475 
476 #endif
VectorType initial_volume_nodes
Initial nodal coefficients of the high-order grid.
std::vector< dealii::types::global_dof_index > locally_relevant_surface_nodes_indices
List of surface node indices.
std::vector< real > locally_relevant_surface_nodes
List of surface nodes.
std::shared_ptr< dealii::MappingFEField< dim, dim, VectorType, DoFHandlerType > > mapping_fe_field
MappingFEField that will provide the polynomial-based grid.
const dealii::QGaussLobatto< dim > dim_grid_nodes
Dim-Dimensional grid nodes in reference space.
std::vector< dealii::Point< dim > > initial_locally_relevant_surface_points
Initial locally relevant surface points.
dealii::IndexSet ghost_dofs_grid
Locally relevant ghost degrees of freedom for the grid.
const bool renumber_dof_handler_Cuthill_Mckee
Flag to renumber dof_handler_grid with Cuthill Mckee.
SolutionTransfer solution_transfer
MPI_Comm mpi_communicator
MPI communicator.
dealii::IndexSet ghost_surface_nodes_indexset
Files for the baseline physics.
Definition: ADTypes.hpp:10
const dealii::FE_Q< dim > fe_q
Use Lagrange polynomial to represent the spatial location.
VectorType initial_surface_nodes
Distributed ghosted vector of initial surface nodes.
dealii::ConditionalOStream pcout
Parallel std::cout that only outputs on mpi_rank==0.
dealii::TrilinosWrappers::SparseMatrix map_nodes_surf_to_vol
const std::shared_ptr< MeshType > triangulation
Mesh.
std::vector< real > all_surface_nodes
List of all surface nodes.
const bool check_valid_metric_Jacobian
Flag to check validity of Jacobian.
VectorType old_volume_nodes
Used for the SolutionTransfer when performing grid adaptation.
const dealii::FE_DGQ< 1 > oneD_fe_q
Use oneD Lagrange polynomial to represent the spatial location.
dealii::FullMatrix< double > lagrange_to_bernstein_operator
Used to transform coefficients from a Lagrange basis to a Bernstein basis.
std::vector< dealii::types::global_dof_index > locally_owned_surface_nodes_indices
List of surface node indices.
std::map< dealii::types::global_dof_index, std::pair< unsigned int, unsigned int > > global_index_to_point_and_axis
const dealii::QGaussLobatto< 1 > oneD_grid_nodes
One Dimensional grid nodes in reference space.
std::vector< dealii::types::global_dof_index > all_surface_indices
dealii::LinearAlgebra::distributed::Vector< int > surface_to_volume_indices
dealii::IndexSet locally_relevant_dofs_grid
Union of locally owned degrees of freedom and relevant ghost degrees of freedom for the grid...
const unsigned int max_degree
Maximum degree of the geometry polynomial representing the grid.
Postprocessor used to output the grid.
static unsigned int nth_refinement
Used to name the various files outputted.
int n_mpi
Number of MPI processes.
std::vector< unsigned int > n_locally_owned_surface_nodes_per_mpi
std::vector< dealii::Point< dim > > locally_relevant_surface_points
Locally relevant surface points.
std::shared_ptr< dealii::MappingFEField< dim, dim, VectorType, DoFHandlerType > > initial_mapping_fe_field
MappingFEField that will provide the polynomial-based grid for the initial volume_nodes.
std::vector< dealii::types::global_dof_index > locally_relevant_surface_nodes_boundary_id
List of surface node boundary IDs, corresponding to locally_relevant_surface_nodes_indices.
dealii::DoFHandler< dim > dof_handler_grid
Degrees of freedom handler for the high-order grid.
const dealii::FESystem< 1 > oneD_fe_system
One-dimensional fe system for each direction.
std::vector< real > locally_owned_surface_nodes
List of surface nodes.
dealii::IndexSet locally_owned_dofs_grid
Locally own degrees of freedom for the grid.
VectorType volume_nodes
Current nodal coefficients of the high-order grid.
std::map< std::pair< unsigned int, unsigned int >, dealii::types::global_dof_index > point_and_axis_to_global_index
dealii::IndexSet locally_owned_surface_nodes_indexset
const dealii::FESystem< dim > fe_system
Using system of polynomials to represent the x, y, and z directions.