[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
local_solution.cpp
1 #include "local_solution.hpp"
2 
3 #include "ADTypes.hpp"
4 
5 namespace PHiLiP {
6 
7 template <typename real, int dim, int n_components>
8 LocalSolution<real, dim, n_components>::LocalSolution(const dealii::FESystem<dim, dim> &i_finite_element)
9  : finite_element(i_finite_element), n_dofs(i_finite_element.dofs_per_cell) {
10  Assert(n_components == finite_element.n_components(),
11  dealii::ExcMessage("Number of components must match finite element system"));
12  coefficients.resize(finite_element.dofs_per_cell);
13 }
14 
15 template <typename real, int dim, int n_components>
16 std::vector<std::array<real, n_components>> LocalSolution<real, dim, n_components>::evaluate_values(
17  const std::vector<dealii::Point<dim>> &unit_points) const {
18  const unsigned int n_points = unit_points.size();
19  std::vector<std::array<real, n_components>> values(n_points);
20 
21  for (unsigned int i_point = 0; i_point < n_points; ++i_point) {
22  for (int i_component = 0; i_component < n_components; ++i_component) {
23  values[i_point][i_component] = 0;
24  }
25  for (unsigned int i_dof = 0; i_dof < n_dofs; ++i_dof) {
26  const int i_component = finite_element.system_to_component_index(i_dof).first;
27  values[i_point][i_component] +=
28  coefficients[i_dof] * finite_element.shape_value_component(i_dof, unit_points[i_point], i_component);
29  }
30  }
31 
32  return values;
33 }
34 
35 template <typename real, int dim, int n_components>
36 std::vector<std::array<dealii::Tensor<1, dim, real>, n_components>>
37 LocalSolution<real, dim, n_components>::evaluate_reference_gradients(const std::vector<dealii::Point<dim>> &unit_points) const {
38  const unsigned int n_points = unit_points.size();
39  std::vector<std::array<dealii::Tensor<1, dim, real>, n_components>> gradients(unit_points.size());
40 
41  for (unsigned int i_point = 0; i_point < n_points; ++i_point) {
42  for (int i_component = 0; i_component < n_components; ++i_component) {
43  gradients[i_point][i_component] = 0;
44  }
45  for (unsigned int i_dof = 0; i_dof < n_dofs; ++i_dof) {
46  const int i_component = finite_element.system_to_component_index(i_dof).first;
47  dealii::Tensor<1, dim, double> shape_grad =
48  finite_element.shape_grad_component(i_dof, unit_points[i_point], i_component);
49  for (int d = 0; d < dim; ++d) {
50  gradients[i_point][i_component][d] += coefficients[i_dof] * shape_grad[d];
51  }
52  }
53  }
54  return gradients;
55 }
56 
57 // Define a sequence of indices representing the range [1, 7]
58 #define POSSIBLE_NSTATE (1)(2)(3)(4)(5)(6)(7)
59 
60 // Define a macro to instantiate MyTemplate for a specific index
61 #define INSTANTIATE_DISTRIBUTED(r, data, nstate) \
62  template class LocalSolution<double, PHILIP_DIM, nstate>; \
63  template class LocalSolution<FadType, PHILIP_DIM, nstate>; \
64  template class LocalSolution<RadType, PHILIP_DIM, nstate>; \
65  template class LocalSolution<FadFadType, PHILIP_DIM, nstate>; \
66  template class LocalSolution<RadFadType, PHILIP_DIM, nstate>;
67 BOOST_PP_SEQ_FOR_EACH(INSTANTIATE_DISTRIBUTED, _, POSSIBLE_NSTATE)
68 } // namespace PHiLiP
LocalSolution(const dealii::FESystem< dim, dim > &finite_element)
Constructor.
const unsigned int n_dofs
Number of degrees of freedom.
Files for the baseline physics.
Definition: ADTypes.hpp:10
std::vector< std::array< real, n_components > > evaluate_values(const std::vector< dealii::Point< dim >> &unit_points) const
Obtain values at unit points.
std::vector< std::array< dealii::Tensor< 1, dim, real >, n_components > > evaluate_reference_gradients(const std::vector< dealii::Point< dim >> &unit_points) const
std::vector< real > coefficients
Solution coefficients in the finite element basis.
const dealii::FESystem< dim, dim > & finite_element
Reference to the finite element system used to represent the solution.