[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
viscous_numerical_flux.cpp
1 #include "ADTypes.hpp"
2 
3 #include "viscous_numerical_flux.hpp"
4 
5 namespace PHiLiP {
6 namespace NumericalFlux {
7 
8 using AllParam = Parameters::AllParameters;
9 
10 // Protyping low level functions
11 template<int nstate, typename real>
12 std::array<real, nstate> array_average(
13  const std::array<real, nstate> &array1,
14  const std::array<real, nstate> &array2)
15 {
16  std::array<real,nstate> array_average;
17  for (int s=0; s<nstate; s++) {
18  array_average[s] = 0.5*(array1[s] + array2[s]);
19  }
20  return array_average;
21 }
22 
23 template<int nstate, int dim, typename real>
24 std::array<dealii::Tensor<1,dim,real>, nstate> array_average(
25  const std::array<dealii::Tensor<1,dim,real>,nstate> &array1,
26  const std::array<dealii::Tensor<1,dim,real>,nstate> &array2)
27 {
28  std::array<dealii::Tensor<1,dim,real>,nstate> array_average;
29  for (int s=0; s<nstate; s++) {
30  for (int d=0; d<dim; d++) {
31  array_average[s][d] = 0.5*(array1[s][d] + array2[s][d]);
32  }
33  }
34  return array_average;
35 }
36 
37 template<int dim, int nstate, typename real>
38 std::array<dealii::Tensor<1,dim,real>,nstate> array_jump(
39  const std::array<real, nstate> &array1,
40  const std::array<real, nstate> &array2,
41  const dealii::Tensor<1,dim,real> &normal1)
42 {
43  std::array<dealii::Tensor<1,dim,real>,nstate> array_jump;
44  for (int s=0; s<nstate; s++) {
45  for (int d=0; d<dim; d++) {
46  array_jump[s][d] = (array1[s] - array2[s])*normal1[d];
47  }
48  }
49  return array_jump;
50 }
51 
52 template<int dim, int nstate, typename real>
53 std::array<real, nstate> CentralViscousNumericalFlux<dim,nstate,real>
55  const std::array<real, nstate> &soln_int,
56  const std::array<real, nstate> &soln_ext,
57  const dealii::Tensor<1,dim,real> &/*normal_int*/) const
58 {
59  std::array<real,nstate> soln_avg = array_average<nstate,real>(soln_int, soln_ext);
60 
61  return soln_avg;
62 }
63 
64 template<int dim, int nstate, typename real>
65 std::array<real, nstate> CentralViscousNumericalFlux<dim,nstate,real>
67  const dealii::types::global_dof_index current_cell_index,
68  const dealii::types::global_dof_index neighbor_cell_index,
69  const real artificial_diss_coeff_int,
70  const real artificial_diss_coeff_ext,
71  const std::array<real, nstate> &soln_int,
72  const std::array<real, nstate> &soln_ext,
73  const std::array<dealii::Tensor<1,dim,real>, nstate> &soln_grad_int,
74  const std::array<dealii::Tensor<1,dim,real>, nstate> &soln_grad_ext,
75  const dealii::Tensor<1,dim,real> &normal_int,
76  const real &penalty,
77  const bool on_boundary) const
78 {
79  using ArrayTensor1 = std::array<dealii::Tensor<1,dim,real>, nstate>;
80 
81  if (on_boundary) {
82  // Following the the boundary treatment given by
83  // Hartmann, R., Numerical Analysis of Higher Order Discontinuous Galerkin Finite Element Methods, Institute of Aerodynamics and Flow Technology, DLR (German Aerospace Center), 2008.
84  // Details given on page 93
85  const std::array<real, nstate> soln_bc = soln_ext;
86  const std::array<dealii::Tensor<1,dim,real>, nstate> soln_grad_bc = soln_grad_int;
87  //const std::array<dealii::Tensor<1,dim,real>, nstate> soln_grad_bc = soln_grad_ext;
88  real artificial_diss_coeff_bc = artificial_diss_coeff_int;
89  const dealii::types::global_dof_index boundary_cell_index = current_cell_index;
90 
91  return evaluate_auxiliary_flux ( current_cell_index, boundary_cell_index,
92  artificial_diss_coeff_int, artificial_diss_coeff_bc,
93  soln_int, soln_bc,
94  soln_grad_int, soln_grad_bc,
95  normal_int, penalty,
96  false);
97  }
98 
99  ArrayTensor1 phys_flux_int, phys_flux_ext;
100 
101  // {{A*grad_u}}
102  phys_flux_int = pde_physics->dissipative_flux (soln_int, soln_grad_int, current_cell_index);
103  phys_flux_ext = pde_physics->dissipative_flux (soln_ext, soln_grad_ext, neighbor_cell_index);
104 
105  ArrayTensor1 phys_flux_avg = array_average<nstate,dim,real>(phys_flux_int, phys_flux_ext);
106 
107  std::array<real,nstate> auxiliary_flux_dot_n;
108  for (int s=0; s<nstate; s++) {
109  //auxiliary_flux_dot_n[s] = (phys_flux_avg[s]) * normal_int;
110  real phys = 0.0;
111  for (int d=0; d<dim; ++d) {
112  phys += (phys_flux_avg[s][d]) * normal_int[d];
113  }
114  auxiliary_flux_dot_n[s] = phys;
115  }
116 
117  if (artificial_diss_coeff_int > 1e-13 || artificial_diss_coeff_ext > 1e-13) {
118  ArrayTensor1 artificial_phys_flux_int, artificial_phys_flux_ext;
119 
120  // {{A*grad_u}}
121  artificial_phys_flux_int = artificial_dissip->calc_artificial_dissipation_flux (soln_int, soln_grad_int, artificial_diss_coeff_int);
122  artificial_phys_flux_ext = artificial_dissip->calc_artificial_dissipation_flux (soln_ext, soln_grad_ext, artificial_diss_coeff_ext);
123  ArrayTensor1 artificial_phys_flux_avg = array_average<nstate,dim,real>(artificial_phys_flux_int, artificial_phys_flux_ext);
124 
125  // {{A}}*[[u]]
126  ArrayTensor1 soln_jump = array_jump<dim,nstate,real>(soln_int, soln_ext, normal_int);
127  ArrayTensor1 artificial_A_jumpu_int, artificial_A_jumpu_ext;
128  artificial_A_jumpu_int = artificial_dissip->calc_artificial_dissipation_flux (soln_int, soln_jump, artificial_diss_coeff_int);
129  artificial_A_jumpu_ext = artificial_dissip->calc_artificial_dissipation_flux (soln_ext, soln_jump, artificial_diss_coeff_ext);
130  const ArrayTensor1 artificial_A_jumpu_avg = array_average<nstate,dim,real>(artificial_A_jumpu_int, artificial_A_jumpu_ext);
131 
132  for (int s=0; s<nstate; s++) {
133  //auxiliary_flux_dot_n[s] += (artificial_phys_flux_avg[s] - penalty * artificial_A_jumpu_avg[s]) * normal_int;
134  real arti = 0.0;
135  for (int d=0; d<dim; ++d) {
136  arti += (artificial_phys_flux_avg[s][d] - penalty * artificial_A_jumpu_avg[s][d]) * normal_int[d];
137  }
138  auxiliary_flux_dot_n[s] += arti;
139  }
140  }
141 
142  return auxiliary_flux_dot_n;
143 }
144 
145 template<int dim, int nstate, typename real>
146 std::array<real, nstate> SymmetricInternalPenalty<dim,nstate,real>
148  const std::array<real, nstate> &soln_int,
149  const std::array<real, nstate> &soln_ext,
150  const dealii::Tensor<1,dim,real> &/*normal_int*/) const
151 {
152  std::array<real,nstate> soln_avg = array_average<nstate,real>(soln_int, soln_ext);
153 
154  return soln_avg;
155 }
156 
157 template<int dim, int nstate, typename real>
158 std::array<real, nstate> SymmetricInternalPenalty<dim,nstate,real>
160  const dealii::types::global_dof_index current_cell_index,
161  const dealii::types::global_dof_index neighbor_cell_index,
162  const real artificial_diss_coeff_int,
163  const real artificial_diss_coeff_ext,
164  const std::array<real, nstate> &soln_int,
165  const std::array<real, nstate> &soln_ext,
166  const std::array<dealii::Tensor<1,dim,real>, nstate> &soln_grad_int,
167  const std::array<dealii::Tensor<1,dim,real>, nstate> &soln_grad_ext,
168  const dealii::Tensor<1,dim,real> &normal_int,
169  const real &penalty,
170  const bool on_boundary) const
171 {
172  using ArrayTensor1 = std::array<dealii::Tensor<1,dim,real>, nstate>;
173 
174  if (on_boundary) {
175  // Following the the boundary treatment given by
176  // Hartmann, R., Numerical Analysis of Higher Order Discontinuous Galerkin Finite Element Methods, Institute of Aerodynamics and Flow Technology, DLR (German Aerospace Center), 2008.
177  // Details given on page 93
178  const std::array<real, nstate> soln_bc = soln_ext;
179  const std::array<dealii::Tensor<1,dim,real>, nstate> soln_grad_bc = soln_grad_int;
180  //const std::array<dealii::Tensor<1,dim,real>, nstate> soln_grad_bc = soln_grad_ext;
181  real artificial_diss_coeff_bc = artificial_diss_coeff_int;
182  const dealii::types::global_dof_index boundary_cell_index = current_cell_index;
183 
184  return evaluate_auxiliary_flux ( current_cell_index, boundary_cell_index,
185  artificial_diss_coeff_int, artificial_diss_coeff_bc,
186  soln_int, soln_bc,
187  soln_grad_int, soln_grad_bc,
188  normal_int, penalty,
189  false);
190  }
191 
192  ArrayTensor1 phys_flux_int, phys_flux_ext;
193 
194  // {{A*grad_u}}
195  phys_flux_int = pde_physics->dissipative_flux (soln_int, soln_grad_int, current_cell_index);
196  phys_flux_ext = pde_physics->dissipative_flux (soln_ext, soln_grad_ext, neighbor_cell_index);
197 
198  ArrayTensor1 phys_flux_avg = array_average<nstate,dim,real>(phys_flux_int, phys_flux_ext);
199 
200  // {{A}}*[[u]]
201  ArrayTensor1 soln_jump = array_jump<dim,nstate,real>(soln_int, soln_ext, normal_int);
202  ArrayTensor1 A_jumpu_int, A_jumpu_ext;
203  A_jumpu_int = pde_physics->dissipative_flux (soln_int, soln_jump, current_cell_index);
204  A_jumpu_ext = pde_physics->dissipative_flux (soln_ext, soln_jump, neighbor_cell_index);
205  const ArrayTensor1 A_jumpu_avg = array_average<nstate,dim,real>(A_jumpu_int, A_jumpu_ext);
206 
207  std::array<real,nstate> auxiliary_flux_dot_n;
208  for (int s=0; s<nstate; s++) {
209  //auxiliary_flux_dot_n[s] = (phys_flux_avg[s] - penalty * A_jumpu_avg[s]) * normal_int;
210  real phys = 0.0;
211  for (int d=0; d<dim; ++d) {
212  phys += (phys_flux_avg[s][d] - penalty * A_jumpu_avg[s][d]) * normal_int[d];
213  }
214  auxiliary_flux_dot_n[s] = phys;
215  }
216 
217  if (artificial_diss_coeff_int > 1e-13 || artificial_diss_coeff_ext > 1e-13) {
218  ArrayTensor1 artificial_phys_flux_int, artificial_phys_flux_ext;
219 
220  // {{A*grad_u}}
221  artificial_phys_flux_int = artificial_dissip->calc_artificial_dissipation_flux (soln_int, soln_grad_int, artificial_diss_coeff_int);
222  artificial_phys_flux_ext = artificial_dissip->calc_artificial_dissipation_flux (soln_ext, soln_grad_ext, artificial_diss_coeff_ext);
223  ArrayTensor1 artificial_phys_flux_avg = array_average<nstate,dim,real>(artificial_phys_flux_int, artificial_phys_flux_ext);
224 
225  // {{A}}*[[u]]
226  ArrayTensor1 artificial_A_jumpu_int, artificial_A_jumpu_ext;
227  artificial_A_jumpu_int = artificial_dissip->calc_artificial_dissipation_flux (soln_int, soln_jump, artificial_diss_coeff_int);
228  artificial_A_jumpu_ext = artificial_dissip->calc_artificial_dissipation_flux (soln_ext, soln_jump, artificial_diss_coeff_ext);
229  const ArrayTensor1 artificial_A_jumpu_avg = array_average<nstate,dim,real>(artificial_A_jumpu_int, artificial_A_jumpu_ext);
230 
231  for (int s=0; s<nstate; s++) {
232  //auxiliary_flux_dot_n[s] += (artificial_phys_flux_avg[s] - penalty * artificial_A_jumpu_avg[s]) * normal_int;
233  real arti = 0.0;
234  for (int d=0; d<dim; ++d) {
235  arti += (artificial_phys_flux_avg[s][d] - penalty * artificial_A_jumpu_avg[s][d]) * normal_int[d];
236  }
237  auxiliary_flux_dot_n[s] += arti;
238  }
239  }
240 
241  return auxiliary_flux_dot_n;
242 }
243 
244 template<int dim, int nstate, typename real>
245 std::array<real, nstate> BassiRebay2<dim,nstate,real>
247  const std::array<real, nstate> &soln_int,
248  const std::array<real, nstate> &soln_ext,
249  const dealii::Tensor<1,dim,real> &/*normal_int*/) const
250 {
251  std::array<real,nstate> soln_avg = array_average<nstate,real>(soln_int, soln_ext);
252 
253  return soln_avg;
254 }
255 
256 template<int dim, int nstate, typename real>
257 std::array<real, nstate> BassiRebay2<dim,nstate,real>
259  const dealii::types::global_dof_index current_cell_index,
260  const dealii::types::global_dof_index neighbor_cell_index,
261  const real artificial_diss_coeff_int,
262  const real artificial_diss_coeff_ext,
263  const std::array<real, nstate> &soln_int,
264  const std::array<real, nstate> &soln_ext,
265  const std::array<dealii::Tensor<1,dim,real>, nstate> &soln_grad_int,
266  const std::array<dealii::Tensor<1,dim,real>, nstate> &soln_grad_ext,
267  const dealii::Tensor<1,dim,real> &normal_int,
268  const real &penalty,
269  const bool on_boundary) const
270 {
271  using ArrayTensor1 = std::array<dealii::Tensor<1,dim,real>, nstate>;
272 
273  (void) on_boundary;
274  (void) penalty;
275  //if (on_boundary) {
276  // // Following the the boundary treatment given by
277  // // Hartmann, R., Numerical Analysis of Higher Order Discontinuous Galerkin Finite Element Methods, Institute of Aerodynamics and Flow Technology, DLR (German Aerospace Center), 2008.
278  // // Details given on page 93
279  // const std::array<real, nstate> soln_bc = soln_ext;
280  // const std::array<dealii::Tensor<1,dim,real>, nstate> soln_grad_bc = soln_grad_int;
281  // //const std::array<dealii::Tensor<1,dim,real>, nstate> soln_grad_bc = soln_grad_ext;
282  // real artificial_diss_coeff_bc = artificial_diss_coeff_int;
283 
284  // return evaluate_auxiliary_flux ( artificial_diss_coeff_int, artificial_diss_coeff_bc,
285  // soln_int, soln_bc,
286  // soln_grad_int, soln_grad_bc,
287  // normal_int, penalty,
288  // false);
289  //}
290 
291  ArrayTensor1 phys_flux_int, phys_flux_ext;
292 
293  // {{A*grad_u}}
294  phys_flux_int = pde_physics->dissipative_flux (soln_int, soln_grad_int, current_cell_index);
295  phys_flux_ext = pde_physics->dissipative_flux (soln_ext, soln_grad_ext, neighbor_cell_index);
296 
297  ArrayTensor1 phys_flux_avg = array_average<nstate,dim,real>(phys_flux_int, phys_flux_ext);
298 
299  std::array<real,nstate> auxiliary_flux_dot_n;
300  for (int s=0; s<nstate; s++) {
301  real phys = 0.0;
302  for (int d=0; d<dim; ++d) {
303  phys += phys_flux_avg[s][d] * normal_int[d];
304  }
305  auxiliary_flux_dot_n[s] = phys;
306  }
307 
308  if (artificial_diss_coeff_int > 1e-13 || artificial_diss_coeff_ext > 1e-13) {
309  ArrayTensor1 artificial_phys_flux_int, artificial_phys_flux_ext;
310 
311  // {{A*grad_u}}
312  artificial_phys_flux_int = artificial_dissip->calc_artificial_dissipation_flux (soln_int, soln_grad_int, artificial_diss_coeff_int);
313  artificial_phys_flux_ext = artificial_dissip->calc_artificial_dissipation_flux (soln_ext, soln_grad_ext, artificial_diss_coeff_ext);
314  ArrayTensor1 artificial_phys_flux_avg = array_average<nstate,dim,real>(artificial_phys_flux_int, artificial_phys_flux_ext);
315 
316  for (int s=0; s<nstate; s++) {
317  real arti = 0.0;
318  for (int d=0; d<dim; ++d) {
319  arti += artificial_phys_flux_avg[s][d] * normal_int[d];
320  }
321  auxiliary_flux_dot_n[s] += arti;
322  }
323  }
324 
325  return auxiliary_flux_dot_n;
326 }
327 
328 // Instantiation
359 
360 
391 
422 
453 
454 } // NumericalFlux namespace
455 } // PHiLiP namespace
std::array< real, nstate > evaluate_auxiliary_flux(const dealii::types::global_dof_index current_cell_index, const dealii::types::global_dof_index neighbor_cell_index, const real artificial_diss_coeff_int, const real artificial_diss_coeff_ext, const std::array< real, nstate > &soln_int, const std::array< real, nstate > &soln_ext, const std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_int, const std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_ext, const dealii::Tensor< 1, dim, real > &normal_int, const real &penalty, const bool on_boundary=false) const override
Evaluate auxiliary flux at the interface.
std::array< real, nstate > evaluate_solution_flux(const std::array< real, nstate > &soln_int, const std::array< real, nstate > &soln_ext, const dealii::Tensor< 1, dim, real > &normal_int) const override
Evaluate solution flux at the interface.
Base class of numerical flux associated with dissipation.
Files for the baseline physics.
Definition: ADTypes.hpp:10
std::array< real, nstate > evaluate_solution_flux(const std::array< real, nstate > &soln_int, const std::array< real, nstate > &soln_ext, const dealii::Tensor< 1, dim, real > &normal_int) const override
Evaluate solution flux at the interface.
virtual std::array< real, nstate > evaluate_auxiliary_flux(const dealii::types::global_dof_index current_cell_index, const dealii::types::global_dof_index neighbor_cell_index, const real artificial_diss_coeff_int, const real artificial_diss_coeff_ext, const std::array< real, nstate > &soln_int, const std::array< real, nstate > &soln_ext, const std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_int, const std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_ext, const dealii::Tensor< 1, dim, real > &normal_int, const real &penalty, const bool on_boundary=false) const =0
Auxiliary flux at the interface.
std::array< real, nstate > evaluate_auxiliary_flux(const dealii::types::global_dof_index current_cell_index, const dealii::types::global_dof_index neighbor_cell_index, const real artificial_diss_coeff_int, const real artificial_diss_coeff_ext, const std::array< real, nstate > &soln_int, const std::array< real, nstate > &soln_ext, const std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_int, const std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_ext, const dealii::Tensor< 1, dim, real > &normal_int, const real &penalty, const bool on_boundary=false) const override
Evaluate auxiliary flux at the interface.
std::array< real, nstate > evaluate_solution_flux(const std::array< real, nstate > &soln_int, const std::array< real, nstate > &soln_ext, const dealii::Tensor< 1, dim, real > &normal_int) const override
Evaluate solution flux at the interface.