[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
burgers.cpp
1 #include "ADTypes.hpp"
2 
3 #include "burgers.h"
4 
5 namespace PHiLiP {
6 namespace Physics {
7 
8 template <int dim, int nspecies, int nstate, typename real>
10  const Parameters::AllParameters *const parameters_input,
11  const double diffusion_coefficient,
12  const bool convection,
13  const bool diffusion,
14  const dealii::Tensor<2,3,double> input_diffusion_tensor,
15  std::shared_ptr< ManufacturedSolutionFunction<dim,nspecies,real> > manufactured_solution_function,
16  const Parameters::AllParameters::TestType parameters_test,
17  const bool has_nonzero_physical_source)
18  : PhysicsBase<dim,nspecies,nstate,real>(parameters_input, diffusion, has_nonzero_physical_source, input_diffusion_tensor, manufactured_solution_function)
19  , diffusion_scaling_coeff(diffusion_coefficient)
20  , hasConvection(convection)
21  , hasDiffusion(diffusion)
22  , test_type(parameters_test)
23 {
24  static_assert(nstate==dim, "Physics::Burgers() should be created with nstate==dim");
25 }
26 
27 template <int dim, int nspecies, int nstate, typename real>
30  const int /*boundary_type*/,
31  const dealii::Point<dim, real> &pos,
32  const dealii::Tensor<1,dim,real> &normal_int,
33  const std::array<real,nstate> &soln_int,
34  const std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_int,
35  std::array<real,nstate> &soln_bc,
36  std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_bc) const
37 {
38  std::array<real,nstate> boundary_values;
39  std::array<dealii::Tensor<1,dim,real>,nstate> boundary_gradients;
40  for (int i=0; i<nstate; i++) {
41  boundary_values[i] = this->manufactured_solution_function->value (pos, i);
42  boundary_gradients[i] = this->manufactured_solution_function->gradient (pos, i);
43  }
44 
45  for (int istate=0; istate<nstate; ++istate) {
46 
47  std::array<real,nstate> characteristic_dot_n = convective_eigenvalues(boundary_values, normal_int);
48  const bool inflow = (characteristic_dot_n[istate] <= 0.);
49 
50  if (inflow || hasDiffusion) { // Dirichlet boundary condition
51  // soln_bc[istate] = boundary_values[istate];
52  // soln_grad_bc[istate] = soln_grad_int[istate];
53 
54  soln_bc[istate] = boundary_values[istate];
55  soln_grad_bc[istate] = soln_grad_int[istate];
56 
57  } else { // Neumann boundary condition
58  // //soln_bc[istate] = soln_int[istate];
59  // //soln_bc[istate] = boundary_values[istate];
60  //soln_bc[istate] = -soln_int[istate]+2*boundary_values[istate];
61  soln_bc[istate] = soln_int[istate];
62 
63  // **************************************************************************************************************
64  // Note I don't know how to properly impose the soln_grad_bc to obtain an adjoint consistent scheme
65  // Currently, Neumann boundary conditions are only imposed for the linear advection
66  // Therefore, soln_grad_bc does not affect the solution
67  // **************************************************************************************************************
68  soln_grad_bc[istate] = soln_grad_int[istate];
69  //soln_grad_bc[istate] = boundary_gradients[istate];
70  //soln_grad_bc[istate] = -soln_grad_int[istate]+2*boundary_gradients[istate];
71  }
72  }
73 }
74 
75 template <int dim, int nspecies, int nstate, typename real>
76 std::array<dealii::Tensor<1,dim,real>,nstate> Burgers<dim,nspecies,nstate,real>
77 ::convective_flux (const std::array<real,nstate> &solution) const
78 {
79  std::array<dealii::Tensor<1,dim,real>,nstate> conv_flux;
80  for (int flux_dim=0; flux_dim<dim; ++flux_dim) {
81  for (int s=0; s<nstate; ++s) {
82  conv_flux[s][flux_dim] = 0.5*solution[flux_dim]*solution[s];
83  }
84  }
85  return conv_flux;
86 }
87 
88 template <int dim, int nspecies, int nstate, typename real>
89 std::array<dealii::Tensor<1,dim,real>,nstate> Burgers<dim,nspecies,nstate,real>::convective_numerical_split_flux (
90  const std::array<real,nstate> &conservative_soln1,
91  const std::array<real,nstate> &conservative_soln2) const
92 {
93  std::array<dealii::Tensor<1,dim,real>,nstate> conv_flux;
94  for (int flux_dim=0; flux_dim<dim; ++flux_dim) {
95  for (int s=0; s<nstate; ++s) {
96  conv_flux[s][flux_dim] = 1./6. * (conservative_soln1[flux_dim]*conservative_soln1[flux_dim] + conservative_soln1[flux_dim]*conservative_soln2[s] + conservative_soln2[s]*conservative_soln2[s]);
97  }
98  }
99  return conv_flux;
100 }
101 
102 template <int dim, int nspecies, int nstate, typename real>
103 std::array<real,nstate> Burgers<dim,nspecies,nstate,real>
104 ::convert_conservative_to_primitive ( const std::array<real,nstate> &conservative_soln ) const
105 {
106  return conservative_soln;
107 }
108 
109 template <int dim, int nspecies, int nstate, typename real>
110 std::array<real,nstate> Burgers<dim,nspecies,nstate,real>
111 ::convert_primitive_to_conservative ( const std::array<real,nstate> &primitive_soln ) const
112 {
113  return primitive_soln;
114 }
115 
116 template <int dim, int nspecies, int nstate, typename real>
117 std::array<dealii::Tensor<1,dim,real>,nstate> Burgers<dim,nspecies,nstate,real>
119  const std::array<real,nstate> &/*primitive_soln*/,
120  const std::array<dealii::Tensor<1,dim,real>,nstate> &primitive_soln_gradient) const
121 {
122  return primitive_soln_gradient;
123 }
124 
125 template <int dim, int nspecies, int nstate, typename real>
126 std::array<dealii::Tensor<1,dim,real>,nstate> Burgers<dim,nspecies,nstate,real>
128  const std::array<real,nstate> &/*conservative_soln*/,
129  const std::array<dealii::Tensor<1,dim,real>,nstate> &conservative_soln_gradient) const
130 {
131  return conservative_soln_gradient;
132 }
133 
134 template <int dim, int nspecies, int nstate, typename real>
135 std::array<real,nstate> Burgers<dim, nspecies, nstate, real>
137  const std::array<real,nstate> &conservative_soln) const
138 {
139  return conservative_soln;
140 }
141 
142 template <int dim, int nspecies, int nstate, typename real>
143 std::array<real,nstate> Burgers<dim, nspecies, nstate, real>
145  const std::array<real,nstate> &entropy_var) const
146 {
147  return entropy_var;
148 }
149 
150 template <int dim, int nspecies, int nstate, typename real>
153 {
154  if(hasDiffusion) return this->diffusion_scaling_coeff;
155  const real zero = 0.0;
156  return zero;
157 }
158 
159 template <int dim, int nspecies, int nstate, typename real>
160 std::array<real,nstate> Burgers<dim,nspecies,nstate,real>
162  const std::array<real,nstate> &solution,
163  const dealii::Tensor<1,dim,real> &normal) const
164 {
165  std::array<real,nstate> eig;
166  for (int i=0; i<nstate; i++) {
167  eig[i] = 0.0;
168  for (int d=0;d<dim;++d) {
169  eig[i] += solution[d]*normal[d];
170  }
171  }
172  return eig;
173 }
174 
175 template <int dim, int nspecies, int nstate, typename real>
177 ::max_convective_eigenvalue (const std::array<real,nstate> &soln) const
178 {
179  real max_eig = 0;
180  for (int i=0; i<dim; i++) {
181  //max_eig = std::max(max_eig,std::abs(soln[i]));
182  const real abs_soln = abs(soln[i]);
183  max_eig = std::max(max_eig, abs_soln);
184  //max_eig += soln[i] * soln[i];
185  }
186  return max_eig;
187 }
188 
189 template <int dim, int nspecies, int nstate, typename real>
191 ::max_viscous_eigenvalue (const std::array<real,nstate> &/*conservative_soln*/) const
192 {
193  return 0.0;
194 }
195 
196 template <int dim, int nspecies, int nstate, typename real>
197 std::array<dealii::Tensor<1,dim,real>,nstate> Burgers<dim,nspecies,nstate,real>
199  const std::array<real,nstate> &solution,
200  const std::array<dealii::Tensor<1,dim,real>,nstate> &solution_gradient,
201  const dealii::types::global_dof_index /*cell_index*/) const
202 {
203  return dissipative_flux(solution, solution_gradient);
204 }
205 
206 template <int dim, int nspecies, int nstate, typename real>
207 std::array<dealii::Tensor<1,dim,real>,nstate> Burgers<dim,nspecies,nstate,real>
209  const std::array<real,nstate> &/*solution*/,
210  const std::array<dealii::Tensor<1,dim,real>,nstate> &solution_gradient) const
211 {
212  std::array<dealii::Tensor<1,dim,real>,nstate> diss_flux;
213  const real diff_coeff = diffusion_coefficient();
214  for (int i=0; i<nstate; i++) {
215  for (int d1=0; d1<dim; d1++) {
216  diss_flux[i][d1] = 0.0;
217  for (int d2=0; d2<dim; d2++) {
218  diss_flux[i][d1] += -diff_coeff*((this->diffusion_tensor[d1][d2])*solution_gradient[i][d2]);
219  }
220  }
221  }
222  return diss_flux;
223 }
224 
225 template <int dim, int nspecies, int nstate, typename real>
226 std::array<real,nstate> Burgers<dim,nspecies,nstate,real>
228  const dealii::Point<dim,real> &pos,
229  const std::array<real,nstate> &solution,
230  const real current_time,
231  const dealii::types::global_dof_index /*cell_index*/) const
232 {
233  return source_term(pos,solution,current_time);
234 }
235 
236 template <int dim, int nspecies, int nstate, typename real>
237 std::array<real,nstate> Burgers<dim,nspecies,nstate,real>
239  const dealii::Point<dim,real> &pos,
240  const std::array<real,nstate> &/*solution*/,
241  const real current_time) const
242 {
243  std::array<real,nstate> source;
244 
245  using TestType = Parameters::AllParameters::TestType;
246 
247  if(this->test_type == TestType::burgers_energy_stability || this->test_type == TestType::burgers_limiter
248  || this->test_type == TestType::stability_fr_parameter_range){
249  for(int istate =0; istate<nstate; istate++){
250  source[istate] = 0.0;
251  const double pi = atan(1)*4.0;
252  const real pi_xmt = pi * (pos[0] - current_time);
253  const real pi_ymt = pi * (pos[1] - current_time);
254  const real pi_zmt = pi * (pos[2] - current_time);
255 
256  if(dim==1)
257  {
258  source[istate] = pi * sin(pi_xmt)
259  *(1.0 - cos(pi_xmt));
260  }
261 
262  if(dim==2)
263  {
264  const real sourcedt = pi*sin(pi_xmt)*cos(pi_ymt)
265  +pi*cos(pi_xmt)*sin(pi_ymt);
266  const real sourcedx = -pi*sin(pi_xmt)*(cos(pi_xmt))
267  *pow(cos(pi_ymt),2.0);
268  const real sourcedy = -pi*sin(pi_ymt)*(cos(pi_ymt))
269  *pow(cos(pi_xmt),2.0);
270  source[istate] = sourcedt + sourcedx + sourcedy;
271  }
272 
273  if(dim==3)
274  {
275  const real sourcedt = pi*sin(pi_xmt)*cos(pi_ymt)*cos(pi_zmt)
276  +pi*cos(pi_xmt)*sin(pi_ymt)*cos(pi_zmt)
277  +pi*cos(pi_xmt)*cos(pi_ymt)*sin(pi_zmt);
278  const real sourcedx = -pi*sin(pi_xmt)*(cos(pi_xmt))
279  *pow(cos(pi_ymt),2.0)*pow(cos(pi_zmt),2.0);
280  const real sourcedy = -pi*sin(pi_ymt)*(cos(pi_ymt))
281  *pow(cos(pi_xmt),2.0)*pow(cos(pi_zmt),2.0);
282  const real sourcedz = -pi*sin(pi_zmt)*(cos(pi_zmt))
283  *pow(cos(pi_xmt),2.0)*pow(cos(pi_ymt),2.0);
284  source[istate] = sourcedt + sourcedx + sourcedy + sourcedz;
285  }
286  }
287  }
288  else{
289  const real diff_coeff = diffusion_coefficient();
290  // for (int istate=0; istate<nstate; istate++) {
291  // dealii::Tensor<1,dim,real> manufactured_gradient = this->manufactured_solution_function.gradient (pos, istate);
292  // dealii::SymmetricTensor<2,dim,real> manufactured_hessian = this->manufactured_solution_function.hessian (pos, istate);
293  // source[istate] = 0.0;
294  // for (int d=0;d<dim;++d) {
295  // real manufactured_solution = this->manufactured_solution_function.value (pos, d);
296  // source[istate] += manufactured_solution*manufactured_gradient[d];
297  // }
298  // source[istate] += -diff_coeff*scalar_product((this->diffusion_tensor),manufactured_hessian);
299  // }
300  for (int istate=0; istate<nstate; istate++) {
301  source[istate] = 0.0;
302  dealii::Tensor<1,dim,real> manufactured_gradient = this->manufactured_solution_function->gradient (pos, istate);
303  dealii::SymmetricTensor<2,dim,real> manufactured_hessian = this->manufactured_solution_function->hessian (pos, istate);
304  for (int d=0;d<dim;++d) {
305  real manufactured_solution = this->manufactured_solution_function->value (pos, d);
306  source[istate] += 0.5*manufactured_solution*manufactured_gradient[d];
307  }
308  //source[istate] += -diff_coeff*scalar_product((this->diffusion_tensor),manufactured_hessian);
309  real hess = 0.0;
310  for (int dr=0; dr<dim; ++dr) {
311  for (int dc=0; dc<dim; ++dc) {
312  hess += (this->diffusion_tensor)[dr][dc] * manufactured_hessian[dr][dc];
313  }
314  }
315  source[istate] += -diff_coeff*hess;
316  }
317  for (int istate=0; istate<nstate; istate++) {
318  real manufactured_solution = this->manufactured_solution_function->value (pos, istate);
319  real divergence = 0.0;
320  for (int d=0;d<dim;++d) {
321  dealii::Tensor<1,dim,real> manufactured_gradient = this->manufactured_solution_function->gradient (pos, d);
322  divergence += manufactured_gradient[d];
323  }
324  source[istate] += 0.5*manufactured_solution*divergence;
325  }
326 
327  }
328  // for (int istate=0; istate<nstate; istate++) {
329  // source[istate] = 0.0;
330  // for (int d=0;d<dim;++d) {
331  // dealii::Point<dim,real> posp = pos;
332  // dealii::Point<dim,real> posm = pos;
333  // posp[d] += 1e-8;
334  // posm[d] -= 1e-8;
335  // std::array<real,nstate> solp,solm;
336  // for (int s=0; s<nstate; s++) {
337  // solp[s] = this->manufactured_solution_function.value (posp, s);
338  // solm[s] = this->manufactured_solution_function.value (posm, s);
339  // }
340  // std::array<dealii::Tensor<1,dim,real>,nstate> convp = convective_flux (solp);
341  // std::array<dealii::Tensor<1,dim,real>,nstate> convm = convective_flux (solm);
342  // source[istate] += (convp[istate][d] - convm[istate][d]) / 2e-8;
343  // }
344  // }
345  return source;
346 }
347 
348 #if PHILIP_SPECIES==1
354 #endif
355 } // Physics namespace
356 } // PHiLiP namespace
357 
358 
359 
360 
const Parameters::AllParameters::TestType test_type
Allows Burgers to distinguish between different unsteady test types.
Definition: burgers.h:53
TestType
Possible integration tests to run.
Base class from which Advection, Diffusion, ConvectionDiffusion, and Euler is derived.
Definition: physics.h:34
std::array< real, nstate > source_term(const dealii::Point< dim, real > &pos, const std::array< real, nstate > &solution, const real current_time, const dealii::types::global_dof_index cell_index) const
Source term is zero or depends on manufactured solution.
Definition: burgers.cpp:227
Manufactured solution used for grid studies to check convergence orders.
real max_convective_eigenvalue(const std::array< real, nstate > &soln) const
Maximum convective eigenvalue.
Definition: burgers.cpp:177
Files for the baseline physics.
Definition: ADTypes.hpp:10
real diffusion_coefficient() const
Diffusion coefficient.
Definition: burgers.cpp:152
std::array< dealii::Tensor< 1, dim, real >, nstate > convert_conservative_gradient_to_primitive_gradient(const std::array< real, nstate > &conservative_soln, const std::array< dealii::Tensor< 1, dim, real >, nstate > &conservative_soln_gradient) const
Definition: burgers.cpp:127
std::shared_ptr< ManufacturedSolutionFunction< dim, nspecies, real > > manufactured_solution_function
Manufactured solution function.
Definition: physics.h:71
Main parameter class that contains the various other sub-parameter classes.
std::array< dealii::Tensor< 1, dim, real >, nstate > convective_flux(const std::array< real, nstate > &solution) const
Convective flux: .
Definition: burgers.cpp:77
std::array< real, nstate > compute_conservative_variables_from_entropy_variables(const std::array< real, nstate > &entropy_var) const
Computes the conservative variables from the entropy variables.
Definition: burgers.cpp:144
const bool hasDiffusion
Turns on diffusive part of the Burgers problem.
Definition: burgers.h:51
std::array< real, nstate > compute_entropy_variables(const std::array< real, nstate > &conservative_soln) const
Computes the entropy variables.
Definition: burgers.cpp:136
std::array< dealii::Tensor< 1, dim, real >, nstate > dissipative_flux(const std::array< real, nstate > &solution, const std::array< dealii::Tensor< 1, dim, real >, nstate > &solution_gradient, const dealii::types::global_dof_index cell_index) const
Dissipative flux: u.
Definition: burgers.cpp:198
real max_viscous_eigenvalue(const std::array< real, nstate > &soln) const
Maximum viscous eigenvalue.
Definition: burgers.cpp:191
void boundary_face_values(const int, const dealii::Point< dim, real > &, const dealii::Tensor< 1, dim, real > &, const std::array< real, nstate > &, const std::array< dealii::Tensor< 1, dim, real >, nstate > &, std::array< real, nstate > &, std::array< dealii::Tensor< 1, dim, real >, nstate > &) const
If diffusion is present, assign Dirichlet boundary condition.
Definition: burgers.cpp:29
std::array< real, nstate > convert_primitive_to_conservative(const std::array< real, nstate > &primitive_soln) const
Convert primitive solution to conservative solution.
Definition: burgers.cpp:111
std::array< real, nstate > convective_eigenvalues(const std::array< real, nstate > &, const dealii::Tensor< 1, dim, real > &) const
Spectral radius of convective term Jacobian is &#39;c&#39;.
Definition: burgers.cpp:161
std::array< real, nstate > convert_conservative_to_primitive(const std::array< real, nstate > &conservative_soln) const
Convert conservative variables to primitive variables.
Definition: burgers.cpp:104
Burger&#39;s equation with nonlinear advective term and linear diffusive term. Derived from PhysicsBase...
Definition: burgers.h:30
std::array< dealii::Tensor< 1, dim, real >, nstate > convective_numerical_split_flux(const std::array< real, nstate > &conservative_soln1, const std::array< real, nstate > &conservative_soln2) const override
Convective split flux.
Definition: burgers.cpp:89
double diffusion_scaling_coeff
Diffusion scaling coefficient in front of the diffusion tensor.
Definition: burgers.h:45
std::array< dealii::Tensor< 1, dim, real >, nstate > convert_primitive_gradient_to_conservative_gradient(const std::array< real, nstate > &primitive_soln, const std::array< dealii::Tensor< 1, dim, real >, nstate > &primitive_soln_gradient) const
Definition: burgers.cpp:118
Burgers(const Parameters::AllParameters *const parameters_input, const double diffusion_coefficient, const bool convection=true, const bool diffusion=true, const dealii::Tensor< 2, 3, double > input_diffusion_tensor=Parameters::ManufacturedSolutionParam::get_default_diffusion_tensor(), std::shared_ptr< ManufacturedSolutionFunction< dim, nspecies, real > > manufactured_solution_function=nullptr, const Parameters::AllParameters::TestType parameters_test=Parameters::AllParameters::TestType::run_control, const bool has_nonzero_physical_source=false)
Constructor.
Definition: burgers.cpp:9
dealii::Tensor< 2, dim, double > diffusion_tensor
Anisotropic diffusion matrix.
Definition: physics.h:291