[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
mhd.cpp
1 #include <cmath>
2 #include <vector>
3 
4 #include "ADTypes.hpp"
5 
6 #include "physics.h"
7 #include "mhd.h"
8 
9 
10 namespace PHiLiP {
11 namespace Physics {
12 
13 template <int dim, int nspecies, int nstate, typename real>
14 std::array<real,nstate> MHD<dim,nspecies,nstate,real>
16  const dealii::Point<dim,real> &pos,
17  const std::array<real,nstate> &conservative_soln,
18  const real current_time,
19  const dealii::types::global_dof_index /*cell_index*/) const
20 {
21  return source_term(pos,conservative_soln,current_time);
22 }
23 
24 template <int dim, int nspecies, int nstate, typename real>
25 std::array<real,nstate> MHD<dim,nspecies,nstate,real>
27  const dealii::Point<dim,real> &/*pos*/,
28  const std::array<real,nstate> &/*conservative_soln*/,
29  const real /*current_time*/) const
30 {
31  std::array<real,nstate> source_term;
32  for (int s=0; s<nstate; s++) {
33  source_term[s] = 0;
34  }
35 
36  return source_term;
37 }
38 
39 //incomplete
40 template <int dim, int nspecies, int nstate, typename real>
41 inline std::array<real,nstate> MHD<dim,nspecies,nstate,real>
42 ::convert_conservative_to_primitive ( const std::array<real,nstate> &conservative_soln ) const
43 {
44  std::array<real, nstate> primitive_soln;
45 
46  real density = conservative_soln[0];
47  dealii::Tensor<1,dim,real> vel = compute_velocities (conservative_soln);
48  real pressure = compute_pressure (conservative_soln);
49 
50  primitive_soln[0] = density;
51  for (int d=0; d<dim; ++d) {
52  primitive_soln[1+d] = vel[d];
53  }
54  primitive_soln[nstate-1] = pressure;
55  return primitive_soln;
56 }
57 
58 //incomplete
59 template <int dim, int nspecies, int nstate, typename real>
60 inline std::array<real,nstate> MHD<dim,nspecies,nstate,real>
61 ::convert_primitive_to_conservative ( const std::array<real,nstate> &primitive_soln ) const
62 {
63 
64  const real density = primitive_soln[0];
65  const dealii::Tensor<1,dim,real> velocities = extract_velocities_from_primitive(primitive_soln);
66 
67  std::array<real, nstate> conservative_soln;
68  conservative_soln[0] = density;
69  for (int d=0; d<dim; ++d) {
70  conservative_soln[1+d] = density*velocities[d];
71  }
72  conservative_soln[nstate-1] = compute_total_energy(primitive_soln);
73 
74  return conservative_soln;
75 }
76 
77 template <int dim, int nspecies, int nstate, typename real>
78 std::array<dealii::Tensor<1,dim,real>,nstate> MHD<dim,nspecies,nstate,real>
80  const std::array<real,nstate> &/*primitive_soln*/,
81  const std::array<dealii::Tensor<1,dim,real>,nstate> &primitive_soln_gradient) const
82 {
83  this->pcout << "WARNING: convert_primitive_gradient_to_conservative_gradient() is not defined for current physics." << std::endl;
84  this->pcout << "Aborting..." << std::endl;
85  std::abort();
86  return primitive_soln_gradient;
87 }
88 
89 template <int dim, int nspecies, int nstate, typename real>
90 std::array<dealii::Tensor<1,dim,real>,nstate> MHD<dim,nspecies,nstate,real>
92  const std::array<real,nstate> &/*conservative_soln*/,
93  const std::array<dealii::Tensor<1,dim,real>,nstate> &conservative_soln_gradient) const
94 {
95  return conservative_soln_gradient;
96 }
97 
98 template <int dim, int nspecies, int nstate, typename real>
99 inline dealii::Tensor<1,dim,real> MHD<dim,nspecies,nstate,real>
100 ::compute_velocities ( const std::array<real,nstate> &conservative_soln ) const
101 {
102  const real density = conservative_soln[0];
103  dealii::Tensor<1,dim,real> vel;
104  for (int d=0; d<dim; ++d) { vel[d] = conservative_soln[1+d]/density; }
105  return vel;
106 }
107 
108 template <int dim, int nspecies, int nstate, typename real>
110 ::compute_velocity_squared ( const dealii::Tensor<1,dim,real> &velocities ) const
111 {
112  real vel2 = 0.0;
113  for (int d=0; d<dim; d++) { vel2 = vel2 + velocities[d]*velocities[d]; }
114  return vel2;
115 }
116 
117 template <int dim, int nspecies, int nstate, typename real>
118 inline dealii::Tensor<1,dim,real> MHD<dim,nspecies,nstate,real>
119 ::extract_velocities_from_primitive ( const std::array<real,nstate> &primitive_soln ) const
120 {
121  dealii::Tensor<1,dim,real> velocities;
122  for (int d=0; d<dim; d++) { velocities[d] = primitive_soln[1+d]; }
123  return velocities;
124 }
125 
126 
127 //incomplete
128 template <int dim, int nspecies, int nstate, typename real>
130 ::compute_total_energy ( const std::array<real,nstate> &primitive_soln ) const
131 {
132  const real density = primitive_soln[0];
133  const real pressure = primitive_soln[nstate-1];
134  const dealii::Tensor<1,dim,real> velocities = extract_velocities_from_primitive(primitive_soln);
135  const real vel2 = compute_velocity_squared(velocities);
136 
137  const real tot_energy = pressure / gamm1 + 0.5*density*vel2;
138  return tot_energy;
139 }
140 
141 //incomplete
142 template <int dim, int nspecies, int nstate, typename real>
144 ::compute_entropy_measure ( const std::array<real,nstate> &conservative_soln ) const
145 {
146  const real density = conservative_soln[0];
147  const real pressure = compute_pressure(conservative_soln);
148  const real entropy_measure = pressure*pow(density,-gam);
149  return entropy_measure;
150 }
151 
152 //incomplete
153 template <int dim, int nspecies, int nstate, typename real>
155 ::compute_specific_enthalpy ( const std::array<real,nstate> &conservative_soln, const real pressure ) const
156 {
157  const real density = conservative_soln[0];
158  const real total_energy = conservative_soln[nstate-1];
159  const real specific_enthalpy = (total_energy+pressure)/density;
160  return specific_enthalpy;
161 }
162 
163 
164 template <int dim, int nspecies, int nstate, typename real>
166 ::compute_dimensional_temperature ( const std::array<real,nstate> &primitive_soln ) const
167 {
168  const real density = primitive_soln[0];
169  const real pressure = primitive_soln[nstate-1];
170  const real temperature = gam*pressure/density;
171  return temperature;
172 }
173 
174 template <int dim, int nspecies, int nstate, typename real>
176 ::compute_temperature ( const std::array<real,nstate> &primitive_soln ) const
177 {
178  const real dimensional_temperature = compute_dimensional_temperature(primitive_soln);
179  const real temperature = dimensional_temperature ;
180  return temperature;
181 }
182 
183 template <int dim, int nspecies, int nstate, typename real>
185 ::compute_density_from_pressure_temperature ( const real pressure, const real temperature ) const
186 {
187  const real density = gam*pressure/temperature ;
188  return density;
189 }
190 template <int dim, int nspecies, int nstate, typename real>
192 ::compute_temperature_from_density_pressure ( const real density, const real pressure ) const
193 {
194  const real temperature = gam*pressure/density /* mach_inf_sqr*/;
195  return temperature;
196 }
197 
198 
199 template <int dim, int nspecies, int nstate, typename real>
201 ::compute_pressure ( const std::array<real,nstate> &conservative_soln ) const
202 {
203  const real density = conservative_soln[0];
204  //std::cout << "density " << density << std::endl;
205 
206  const real tot_energy = conservative_soln[nstate-1];
207  // std::cout << "tot_energy " << tot_energy << std::endl;
208 
209  const dealii::Tensor<1,dim,real> vel = compute_velocities(conservative_soln);
210  // std::cout << "vel1 " << vel[0] << std::endl
211  // << vel[1] << std::endl
212 // << vel[2] <<std::endl;
213 
214  const real vel2 = compute_velocity_squared(vel);
215  //std::cout << "vel ^2 " << vel2 <<std::endl;
216  real pressure = gamm1*(tot_energy - 0.5*density*vel2);
217  //std::cout << "calculated pressure is" << pressure << std::endl;
218  if(pressure<0.0) {
219  std::cout<<"Cannot compute pressure..."<<std::endl;
220  std::cout<<"density "<<density<<std::endl;
221  for(int d=0;d<dim;d++) std::cout<<"vel"<<d<<" "<<vel[d]<<std::endl;
222  std::cout<<"energy "<<tot_energy<<std::endl;
223  }
224  assert(pressure>0.0);
225  //if(pressure<1e-4) pressure = 0.01;
226  return pressure;
227 }
228 
229 template <int dim, int nspecies, int nstate, typename real>
231 ::compute_sound ( const std::array<real,nstate> &conservative_soln ) const
232 {
233  real density = conservative_soln[0];
234  //if(density<1e-4) density = 0.01;
235  if(density<0.0) {
236  std::cout<<"density"<<density<<std::endl;
237  std::abort();
238  }
239  assert(density > 0);
240  const real pressure = compute_pressure(conservative_soln);
241  //std::cout << "pressure is" << pressure << std::endl;
242  const real sound = sqrt(pressure*gam/density);
243  //std::cout << "sound is " << sound << std::endl;
244  return sound;
245 }
246 
247 template <int dim, int nspecies, int nstate, typename real>
249 ::compute_sound ( const real density, const real pressure ) const
250 {
251  assert(density > 0);
252  const real sound = sqrt(pressure*gam/density);
253  return sound;
254 }
255 
256 template <int dim, int nspecies, int nstate, typename real>
258 ::compute_mach_number ( const std::array<real,nstate> &conservative_soln ) const
259 {
260  const dealii::Tensor<1,dim,real> vel = compute_velocities(conservative_soln);
261  const real velocity = sqrt(compute_velocity_squared(vel));
262  const real sound = compute_sound (conservative_soln);
263  const real mach_number = velocity/sound;
264  return mach_number;
265 }
266 
267 template <int dim, int nspecies, int nstate, typename real>
269 ::compute_magnetic_energy (const std::array<real,nstate> &conservative_soln) const
270 {
271  real magnetic_energy = 0;
272  for (int i = 1; i <= 3; ++i)
273  magnetic_energy += 1./2. * (conservative_soln[nstate - i] * conservative_soln[nstate - i] );
274  return magnetic_energy;
275 }
276 
277 
278 // Split form functions:
279 
280 template <int dim, int nspecies, int nstate, typename real>
282 compute_mean_density(const std::array<real,nstate> &soln_const,
283  const std::array<real,nstate> &soln_loop) const
284 {
285  return (soln_const[0] + soln_loop[0])/2.;
286 }
287 
288 template <int dim, int nspecies, int nstate, typename real>
290 compute_mean_pressure(const std::array<real,nstate> &soln_const,
291  const std::array<real,nstate> &soln_loop) const
292 {
293  real pressure_const = compute_pressure(soln_const);
294  real pressure_loop = compute_pressure(soln_loop);
295  return (pressure_const + pressure_loop)/2.;
296 }
297 
298 template <int dim, int nspecies, int nstate, typename real>
299 inline dealii::Tensor<1,dim,real> MHD<dim,nspecies,nstate,real>::
300 compute_mean_velocities(const std::array<real,nstate> &soln_const,
301  const std::array<real,nstate> &soln_loop) const
302 {
303  dealii::Tensor<1,dim,real> vel_const = compute_velocities(soln_const);
304  dealii::Tensor<1,dim,real> vel_loop = compute_velocities(soln_loop);
305  //return (vel_const + vel_loop)/2.;
306  dealii::Tensor<1,dim,real> mean_vel;
307  for (int d=0; d<0; ++d) {
308  mean_vel[d] = (vel_const[d] + vel_loop[d]) * 0.5;
309  }
310  return mean_vel;
311 }
312 
313 template <int dim, int nspecies, int nstate, typename real>
315 compute_mean_specific_energy(const std::array<real,nstate> &soln_const,
316  const std::array<real,nstate> &soln_loop) const
317 {
318  return ((soln_const[nstate-1]/soln_const[0]) + (soln_loop[nstate-1]/soln_loop[0]))/2.;
319 }
320 
321 
322 template <int dim, int nspecies, int nstate, typename real>
323 std::array<dealii::Tensor<1,dim,real>,nstate> MHD<dim,nspecies,nstate,real>
324 ::convective_flux (const std::array<real,nstate> &conservative_soln) const
325 {
326  std::array<dealii::Tensor<1,dim,real>,nstate> conv_flux;
327  const real density = conservative_soln[0];
328  const real pressure = compute_pressure (conservative_soln);
329  const dealii::Tensor<1,dim,real> vel = compute_velocities(conservative_soln);
330  const real specific_total_energy = conservative_soln[nstate-1]/conservative_soln[0];
331  const real specific_total_enthalpy = specific_total_energy + pressure/density;
332  const real magnetic_energy = compute_magnetic_energy(conservative_soln);
333 
334  for (int flux_dim=0; flux_dim<dim; ++flux_dim) {
335  // Density equation
336  conv_flux[0][flux_dim] = conservative_soln[1+flux_dim];
337  // Momentum equation
338  for (int velocity_dim=0; velocity_dim<dim; ++velocity_dim){
339  conv_flux[1+velocity_dim][flux_dim] = density*vel[flux_dim]*vel[velocity_dim];
340  }
341  conv_flux[1+flux_dim][flux_dim] += pressure + magnetic_energy; // Add diagonal of pressure and magnetic energy
342  // Energy equation
343  conv_flux[nstate-4][flux_dim] = density*vel[flux_dim]*specific_total_enthalpy;
344  }
345  return conv_flux;
346 }
347 
348 template <int dim, int nspecies, int nstate, typename real>
349 std::array<real,nstate> MHD<dim, nspecies, nstate, real>
351  const std::array<real,nstate> &conservative_soln) const
352 {
353  std::cout<<"Entropy variables for MHD hasn't been done yet."<<std::endl;
354  std::abort();
355  return conservative_soln;
356 }
357 
358 template <int dim, int nspecies, int nstate, typename real>
359 std::array<real,nstate> MHD<dim, nspecies, nstate, real>
361  const std::array<real,nstate> &entropy_var) const
362 {
363  std::cout<<"Entropy variables for MHD hasn't been done yet."<<std::endl;
364  std::abort();
365  return entropy_var;
366 }
367 
368 template <int dim, int nspecies, int nstate, typename real>
369 std::array<real,nstate> MHD<dim,nspecies,nstate,real>
370 ::convective_normal_flux (const std::array<real,nstate> &conservative_soln, const dealii::Tensor<1,dim,real> &normal) const
371 {
372  std::array<real, nstate> conv_normal_flux;
373  const real density = conservative_soln[0];
374  const real pressure = compute_pressure (conservative_soln);
375  const dealii::Tensor<1,dim,real> vel = compute_velocities(conservative_soln);
376  //const real normal_vel = vel*normal;
377  real normal_vel = 0.0;
378  for (int d=0; d<dim; ++d) {
379  normal_vel += vel[d]*normal[d];
380  }
381  const real total_energy = conservative_soln[nstate-1];
382  const real specific_total_enthalpy = (total_energy + pressure) / density;
383 
384  const real rhoV = density*normal_vel;
385  // Density equation
386  conv_normal_flux[0] = rhoV;
387  // Momentum equation
388  for (int velocity_dim=0; velocity_dim<dim; ++velocity_dim){
389  conv_normal_flux[1+velocity_dim] = rhoV*vel[velocity_dim] + normal[velocity_dim] * pressure;
390  }
391  // Energy equation
392  conv_normal_flux[nstate-1] = rhoV*specific_total_enthalpy;
393  return conv_normal_flux;
394 }
395 
396 template <int dim, int nspecies, int nstate, typename real>
397 dealii::Tensor<2,nstate,real> MHD<dim,nspecies,nstate,real>
399  const std::array<real,nstate> &conservative_soln,
400  const dealii::Tensor<1,dim,real> &normal) const
401 {
402  // See Blazek Appendix A.9 p. 429-430
403  const dealii::Tensor<1,dim,real> vel = compute_velocities(conservative_soln);
404  real vel_normal = 0.0;
405  for (int d=0;d<dim;d++) { vel_normal += vel[d] * normal[d]; }
406 
407  const real vel2 = compute_velocity_squared(vel);
408  const real phi = 0.5*gamm1 * vel2;
409 
410  const real density = conservative_soln[0];
411  const real tot_energy = conservative_soln[nstate-1];
412  const real E = tot_energy / density;
413  const real a1 = gam*E-phi;
414  const real a2 = gam-1.0;
415  const real a3 = gam-2.0;
416 
417  dealii::Tensor<2,nstate,real> jacobian;
418  for (int d=0; d<dim; ++d) {
419  jacobian[0][1+d] = normal[d];
420  }
421  for (int row_dim=0; row_dim<dim; ++row_dim) {
422  jacobian[1+row_dim][0] = normal[row_dim]*phi - vel[row_dim] * vel_normal;
423  for (int col_dim=0; col_dim<dim; ++col_dim){
424  if (row_dim == col_dim) {
425  jacobian[1+row_dim][1+col_dim] = vel_normal - a3*normal[row_dim]*vel[row_dim];
426  } else {
427  jacobian[1+row_dim][1+col_dim] = normal[col_dim]*vel[row_dim] - a2*normal[row_dim]*vel[col_dim];
428  }
429  }
430  jacobian[1+row_dim][nstate-1] = normal[row_dim]*a2;
431  }
432  jacobian[nstate-1][0] = vel_normal*(phi-a1);
433  for (int d=0; d<dim; ++d){
434  jacobian[nstate-1][1+d] = normal[d]*a1 - a2*vel[d]*vel_normal;
435  }
436  jacobian[nstate-1][nstate-1] = gam*vel_normal;
437 
438  return jacobian;
439 }
440 
441 template <int dim, int nspecies, int nstate, typename real>
442 std::array<real,nstate> MHD<dim,nspecies,nstate,real>
444  const std::array<real,nstate> &conservative_soln,
445  const dealii::Tensor<1,dim,real> &normal) const
446 {
447  const dealii::Tensor<1,dim,real> vel = compute_velocities(conservative_soln);
448  std::array<real,nstate> eig;
449  real vel_dot_n = 0.0;
450  for (int d=0;d<dim;++d) { vel_dot_n += vel[d]*normal[d]; };
451  for (int i=0; i<nstate; i++) {
452  eig[i] = vel_dot_n;
453  //eig[i] = advection_speed*normal;
454 
455  //eig[i] = 1.0;
456  //eig[i] = -1.0;
457  }
458  return eig;
459 }
460 template <int dim, int nspecies, int nstate, typename real>
462 ::max_convective_eigenvalue (const std::array<real,nstate> &conservative_soln) const
463 {
464  //std::cout << "going to calculate max eig" << std::endl;
465  const dealii::Tensor<1,dim,real> vel = compute_velocities(conservative_soln);
466  //std::cout << "velocities calculated" << std::endl;
467 
468  const real sound = compute_sound (conservative_soln);
469  //std::cout << "sound calculated" << std::endl;
470 
471  /*const*/ real vel2 = compute_velocity_squared(vel);
472  //std::cout << "vel2 calculated" << std::endl;
473 
474  if (vel2 < 0.0001)
475  vel2 = 0.0001;
476 
477  const real max_eig = sqrt(vel2) + sound;
478  //std::cout << "max eig calculated" << std::endl;
479 
480  return max_eig;
481 }
482 
483 template <int dim, int nspecies, int nstate, typename real>
485 ::max_viscous_eigenvalue (const std::array<real,nstate> &/*conservative_soln*/) const
486 {
487  return 0.0;
488 }
489 
490 template <int dim, int nspecies, int nstate, typename real>
491 std::array<dealii::Tensor<1,dim,real>,nstate> MHD<dim,nspecies,nstate,real>
493  const std::array<real,nstate> &conservative_soln,
494  const std::array<dealii::Tensor<1,dim,real>,nstate> &solution_gradient,
495  const dealii::types::global_dof_index /*cell_index*/) const
496 {
497  return dissipative_flux(conservative_soln,solution_gradient);
498 }
499 
500 template <int dim, int nspecies, int nstate, typename real>
501 std::array<dealii::Tensor<1,dim,real>,nstate> MHD<dim,nspecies,nstate,real>
503  const std::array<real,nstate> &/*conservative_soln*/,
504  const std::array<dealii::Tensor<1,dim,real>,nstate> &/*solution_gradient*/) const
505 {
506  std::array<dealii::Tensor<1,dim,real>,nstate> diss_flux;
507  // No dissipation
508  for (int i=0; i<nstate; i++) {
509  diss_flux[i] = 0;
510  }
511  return diss_flux;
512 }
513 
514 template <int dim, int nspecies, int nstate, typename real>
517  const int /*boundary_type*/,
518  const dealii::Point<dim, real> &pos,
519  const dealii::Tensor<1,dim,real> &normal_int,
520  const std::array<real,nstate> &soln_int,
521  const std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_int,
522  std::array<real,nstate> &soln_bc,
523  std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_bc) const
524 {
525  std::array<real,nstate> boundary_values;
526  std::array<dealii::Tensor<1,dim,real>,nstate> boundary_gradients;
527  for (int s=0; s<nstate; s++) {
528  boundary_values[s] = this->manufactured_solution_function->value (pos, s);
529  boundary_gradients[s] = this->manufactured_solution_function->gradient (pos, s);
530  }
531 
532  for (int istate=0; istate<nstate; ++istate) {
533 
534  std::array<real,nstate> characteristic_dot_n = convective_eigenvalues(boundary_values, normal_int);
535  const bool inflow = (characteristic_dot_n[istate] <= 0.);
536 
537  if (inflow) { // Dirichlet boundary condition
538  // soln_bc[istate] = boundary_values[istate];
539  // soln_grad_bc[istate] = soln_grad_int[istate];
540 
541  soln_bc[istate] = boundary_values[istate];
542  soln_grad_bc[istate] = soln_grad_int[istate];
543 
544  } else { // Neumann boundary condition
545  // //soln_bc[istate] = soln_int[istate];
546  // //soln_bc[istate] = boundary_values[istate];
547  // soln_bc[istate] = -soln_int[istate]+2*boundary_values[istate];
548 
549  soln_bc[istate] = soln_int[istate];
550 
551  // **************************************************************************************************************
552  // Note I don't know how to properly impose the soln_grad_bc to obtain an adjoint consistent scheme
553  // Currently, Neumann boundary conditions are only imposed for the linear advection
554  // Therefore, soln_grad_bc does not affect the solution
555  // **************************************************************************************************************
556  soln_grad_bc[istate] = soln_grad_int[istate];
557  //soln_grad_bc[istate] = boundary_gradients[istate];
558  //soln_grad_bc[istate] = -soln_grad_int[istate]+2*boundary_gradients[istate];
559  }
560  }
561 }
562 
563 //template <int dim, int nspecies, int nstate, typename real>
564 //void MHD<dim,nspecies,nstate,real>
565 //::boundary_face_values (
566 // const int boundary_type,
567 // const dealii::Point<dim, real> &pos,
568 // const dealii::Tensor<1,dim,real> &normal_int,
569 // const std::array<real,nstate> &soln_int,
570 // const std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_int,
571 // std::array<real,nstate> &soln_bc,
572 // std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_bc) const
573 //{
574 // // NEED TO PROVIDE AS INPUT **************************************
575 // const real total_inlet_pressure = pressure_inf*pow(1.0+0.5*gamm1*mach_inf_sqr, gam/gamm1);
576 // const real total_inlet_temperature = temperature_inf*pow(total_inlet_pressure/pressure_inf, gamm1/gam);
577 //
578 // if (boundary_type == 1000) {
579 // // Manufactured solution
580 // std::array<real,nstate> conservative_boundary_values;
581 // std::array<dealii::Tensor<1,dim,real>,nstate> boundary_gradients;
582 // for (int s=0; s<nstate; s++) {
583 // conservative_boundary_values[s] = this->manufactured_solution_function.value (pos, s);
584 // boundary_gradients[s] = this->manufactured_solution_function.gradient (pos, s);
585 // }
586 // std::array<real,nstate> primitive_boundary_values = convert_conservative_to_primitive(conservative_boundary_values);
587 // for (int istate=0; istate<nstate; ++istate) {
588 //
589 // std::array<real,nstate> characteristic_dot_n = convective_eigenvalues(conservative_boundary_values, normal_int);
590 // const bool inflow = (characteristic_dot_n[istate] <= 0.);
591 //
592 // if (inflow) { // Dirichlet boundary condition
593 //
594 // soln_bc[istate] = conservative_boundary_values[istate];
595 // soln_grad_bc[istate] = soln_grad_int[istate];
596 //
597 // // Only set the pressure and velocity
598 // // primitive_boundary_values[0] = soln_int[0];;
599 // // for(int d=0;d<dim;d++){
600 // // primitive_boundary_values[1+d] = soln_int[1+d]/soln_int[0];;
601 // //}
602 // conservative_boundary_values = convert_primitive_to_conservative(primitive_boundary_values);
603 // //conservative_boundary_values[nstate-1] = soln_int[nstate-1];
604 // soln_bc[istate] = conservative_boundary_values[istate];
605 //
606 // } else { // Neumann boundary condition
607 // // soln_bc[istate] = -soln_int[istate]+2*conservative_boundary_values[istate];
608 // soln_bc[istate] = soln_int[istate];
609 //
610 // // **************************************************************************************************************
611 // // Note I don't know how to properly impose the soln_grad_bc to obtain an adjoint consistent scheme
612 // // Currently, Neumann boundary conditions are only imposed for the linear advection
613 // // Therefore, soln_grad_bc does not affect the solution
614 // // **************************************************************************************************************
615 // soln_grad_bc[istate] = soln_grad_int[istate];
616 // //soln_grad_bc[istate] = boundary_gradients[istate];
617 // //soln_grad_bc[istate] = -soln_grad_int[istate]+2*boundary_gradients[istate];
618 // }
619 //
620 // // HARDCODE DIRICHLET BC
621 // soln_bc[istate] = conservative_boundary_values[istate];
622 //
623 // }
624 // } else if (boundary_type == 1001) {
625 // // No penetration,
626 // // Given by Algorithm II of the following paper
627 // // Krivodonova, L., and Berger, M.,
628 // // “High-order accurate implementation of solid wall boundary conditions in curved geometries,”
629 // // Journal of Computational Physics, vol. 211, 2006, pp. 492–512.
630 // const std::array<real,nstate> primitive_interior_values = convert_conservative_to_primitive(soln_int);
631 //
632 // // Copy density and pressure
633 // std::array<real,nstate> primitive_boundary_values;
634 // primitive_boundary_values[0] = primitive_interior_values[0];
635 // primitive_boundary_values[nstate-1] = primitive_interior_values[nstate-1];
636 //
637 // const dealii::Tensor<1,dim,real> surface_normal = -normal_int;
638 // const dealii::Tensor<1,dim,real> velocities_int = extract_velocities_from_primitive(primitive_interior_values);
639 // const dealii::Tensor<1,dim,real> velocities_bc = velocities_int - 2.0*(velocities_int*surface_normal)*surface_normal;
640 // for (int d=0; d<dim; ++d) {
641 // primitive_boundary_values[1+d] = velocities_bc[d];
642 // }
643 //
644 // soln_bc = convert_primitive_to_conservative(primitive_boundary_values);
645 //
646 // } else if (boundary_type == 1002) {
647 // // Pressure Outflow Boundary Condition (back pressure)
648 // // Carlson 2011, sec. 2.4
649 //
650 // const real back_pressure = 0.99; // Make it as an input later on
651 //
652 // const real mach_int = compute_mach_number(soln_int);
653 // const std::array<real,nstate> primitive_interior_values = convert_conservative_to_primitive(soln_int);
654 // const real pressure_int = primitive_interior_values[nstate-1];
655 //
656 // const real radicant = 1.0+0.5*gamm1*mach_inf_sqr;
657 // const real pressure_inlet = total_inlet_pressure * pow(radicant, -gam/gamm1);
658 // const real pressure_bc = (mach_int >= 1) ? pressure_int : back_pressure*pressure_inlet;
659 // const real temperature_int = compute_temperature(primitive_interior_values);
660 //
661 // // Assign primitive boundary values
662 // std::array<real,nstate> primitive_boundary_values;
663 // primitive_boundary_values[0] = compute_density_from_pressure_temperature(pressure_bc, temperature_int);
664 // for (int d=0;d<dim;d++) { primitive_boundary_values[1+d] = primitive_interior_values[1+d]; }
665 // primitive_boundary_values[nstate-1] = pressure_bc;
666 //
667 // soln_bc = convert_primitive_to_conservative(primitive_boundary_values);
668 //
669 // // Supersonic, simply extrapolate
670 // if (mach_int > 1.0) {
671 // soln_bc = soln_int;
672 // }
673 //
674 // } else if (boundary_type == 1003) {
675 // // Inflow
676 // // Carlson 2011, sec. 2.2 & sec 2.9
677 //
678 // const std::array<real,nstate> primitive_interior_values = convert_conservative_to_primitive(soln_int);
679 //
680 // const dealii::Tensor<1,dim,real> normal = -normal_int;
681 //
682 // const real density_i = primitive_interior_values[0];
683 // const dealii::Tensor<1,dim,real> velocities_i = extract_velocities_from_primitive(primitive_interior_values);
684 // const real pressure_i = primitive_interior_values[nstate-1];
685 //
686 // const real normal_vel_i = velocities_i*normal;
687 // const real sound_i = compute_sound(soln_int);
688 // //const real mach_i = std::abs(normal_vel_i)/sound_i;
689 //
690 // //const dealii::Tensor<1,dim,real> velocities_o = velocities_inf;
691 // //const real normal_vel_o = velocities_o*normal;
692 // //const real sound_o = sound_inf;
693 // //const real mach_o = mach_inf;
694 //
695 // if(mach_inf < 1.0) {
696 // //std::cout << "Subsonic inflow, mach=" << mach_i << std::endl;
697 // // Subsonic inflow, sec 2.7
698 //
699 // // Want to solve for c_b (sound_bc), to then solve for U (velocity_magnitude_bc) and M_b (mach_bc)
700 // // Eq. 37
701 // const real riemann_pos = normal_vel_i + 2.0*sound_i/gamm1;
702 // // Could evaluate enthalpy from primitive like eq.36, but easier to use the following
703 // const real specific_total_energy = soln_int[nstate-1]/density_i;
704 // const real specific_total_enthalpy = specific_total_energy + pressure_i/density_i;
705 // // Eq. 43
706 // const real a = 1.0+2.0/gamm1;
707 // const real b = -2.0*riemann_pos;
708 // const real c = 0.5*gamm1 * (riemann_pos*riemann_pos - 2.0*specific_total_enthalpy);
709 // // Eq. 42
710 // const real term1 = -0.5*b/a;
711 // const real term2= 0.5*sqrt(b*b-4.0*a*c)/a;
712 // const real sound_bc1 = term1 + term2;
713 // const real sound_bc2 = term1 - term2;
714 // // Eq. 44
715 // const real sound_bc = std::max(sound_bc1, sound_bc2);
716 // // Eq. 45
717 // //const real velocity_magnitude_bc = 2.0*sound_bc/gamm1 - riemann_pos;
718 // const real velocity_magnitude_bc = riemann_pos - 2.0*sound_bc/gamm1;
719 // const real mach_bc = velocity_magnitude_bc/sound_bc;
720 // // Eq. 46
721 // const real radicant = 1.0+0.5*gamm1*mach_bc*mach_bc;
722 // const real pressure_bc = total_inlet_pressure * pow(radicant, -gam/gamm1);
723 // const real temperature_bc = total_inlet_temperature * pow(radicant, -1.0);
724 // //std::cout << " pressure_bc " << pressure_bc << "pressure_inf" << pressure_inf << std::endl;
725 // //std::cout << " temperature_bc " << temperature_bc << "temperature_inf" << temperature_inf << std::endl;
726 // //
727 //
728 // const real density_bc = compute_density_from_pressure_temperature(pressure_bc, temperature_bc);
729 // std::array<real,nstate> primitive_boundary_values;
730 // primitive_boundary_values[0] = density_bc;
731 // for (int d=0;d<dim;d++) { primitive_boundary_values[1+d] = velocity_magnitude_bc*normal[d]; }
732 // primitive_boundary_values[nstate-1] = pressure_bc;
733 // soln_bc = convert_primitive_to_conservative(primitive_boundary_values);
734 //
735 // //std::cout << " entropy_bc " << compute_entropy_measure(soln_bc) << "entropy_inf" << entropy_inf << std::endl;
736 //
737 // } else {
738 // // Supersonic inflow, sec 2.9
739 // // Specify all quantities through
740 // // total_inlet_pressure, total_inlet_temperature, mach_inf & angle_of_attack
741 // //std::cout << "Supersonic inflow, mach=" << mach_i << std::endl;
742 // const real radicant = 1.0+0.5*gamm1*mach_inf_sqr;
743 // const real static_inlet_pressure = total_inlet_pressure * pow(radicant, -gam/gamm1);
744 // const real static_inlet_temperature = total_inlet_temperature * pow(radicant, -1.0);
745 //
746 // const real pressure_bc = static_inlet_pressure;
747 // const real temperature_bc = static_inlet_temperature;
748 // const real density_bc = compute_density_from_pressure_temperature(pressure_bc, temperature_bc);
749 // const real sound_bc = sqrt(gam * pressure_bc / density_bc);
750 // const real velocity_magnitude_bc = mach_inf * sound_bc;
751 //
752 // // Assign primitive boundary values
753 // std::array<real,nstate> primitive_boundary_values;
754 // primitive_boundary_values[0] = density_bc;
755 // for (int d=0;d<dim;d++) { primitive_boundary_values[1+d] = -velocity_magnitude_bc*normal_int[d]; } // minus since it's inflow
756 // primitive_boundary_values[nstate-1] = pressure_bc;
757 // soln_bc = convert_primitive_to_conservative(primitive_boundary_values);
758 // //std::cout << "Inlet density : " << density_bc << std::endl;
759 // //std::cout << "Inlet vel_x : " << primitive_boundary_values[1] << std::endl;
760 // //std::cout << "Inlet vel_y : " << primitive_boundary_values[2] << std::endl;
761 // //std::cout << "Inlet pressure: " << pressure_bc << std::endl;
762 // }
763 //
764 // } else if (boundary_type == 1004) {
765 // // Farfield boundary condition
766 // const real density_bc = density_inf;
767 // const real pressure_bc = 1.0/(gam*mach_inf_sqr);
768 // std::array<real,nstate> primitive_boundary_values;
769 // primitive_boundary_values[0] = density_bc;
770 // for (int d=0;d<dim;d++) { primitive_boundary_values[1+d] = velocities_inf[d]; } // minus since it's inflow
771 // primitive_boundary_values[nstate-1] = pressure_bc;
772 // soln_bc = convert_primitive_to_conservative(primitive_boundary_values);
773 // //std::cout << "Density inf " << soln_bc[0] << std::endl;
774 // //std::cout << "momxinf " << soln_bc[1] << std::endl;
775 // //std::cout << "momxinf " << soln_bc[2] << std::endl;
776 // //std::cout << "energy inf " << soln_bc[3] << std::endl;
777 // } else{
778 // std::cout << "Invalid boundary_type: " << boundary_type << std::endl;
779 // std::abort();
780 // }
781 //}
782 //
783 //template <int dim, int nspecies, int nstate, typename real>
784 //dealii::Vector<double> MHD<dim,nspecies,nstate,real>::post_compute_derived_quantities_vector (
785 // const dealii::Vector<double> &uh,
786 // const std::vector<dealii::Tensor<1,dim> > &duh,
787 // const std::vector<dealii::Tensor<2,dim> > &dduh,
788 // const dealii::Tensor<1,dim> &normals,
789 // const dealii::Point<dim> &evaluation_points) const
790 //{
791 // std::vector<std::string> names = post_get_names ();
792 // dealii::Vector<double> computed_quantities = PhysicsBase<dim,nspecies,nstate,real>::post_compute_derived_quantities_vector ( uh, duh, dduh, normals, evaluation_points);
793 // unsigned int current_data_index = computed_quantities.size() - 1;
794 // computed_quantities.grow_or_shrink(names.size());
795 // if constexpr (std::is_same<real,double>::value) {
796 //
797 // std::array<double, nstate> conservative_soln;
798 // for (unsigned int s=0; s<nstate; ++s) {
799 // conservative_soln[s] = uh(s);
800 // }
801 // const std::array<double, nstate> primitive_soln = convert_conservative_to_primitive(conservative_soln);
802 //
803 // // Density
804 // computed_quantities(++current_data_index) = primitive_soln[0];
805 // // Velocities
806 // for (unsigned int d=0; d<dim; ++d) {
807 // computed_quantities(++current_data_index) = primitive_soln[1+d];
808 // }
809 // // Momentum
810 // for (unsigned int d=0; d<dim; ++d) {
811 // computed_quantities(++current_data_index) = conservative_soln[1+d];
812 // }
813 // // Energy
814 // computed_quantities(++current_data_index) = conservative_soln[nstate-1];
815 // // Pressure
816 // computed_quantities(++current_data_index) = primitive_soln[nstate-1];
817 // // Pressure
818 // computed_quantities(++current_data_index) = compute_temperature(primitive_soln);
819 // // Entropy generation
820 // computed_quantities(++current_data_index) = compute_entropy_measure(conservative_soln) - entropy_inf;
821 // // Mach Number
822 // computed_quantities(++current_data_index) = compute_mach_number(conservative_soln);
823 //
824 // }
825 // if (computed_quantities.size()-1 != current_data_index) {
826 // std::cout << " Did not assign a value to all the data. Missing " << computed_quantities.size() - current_data_index << " variables."
827 // << " If you added a new output variable, make sure the names and DataComponentInterpretation match the above. "
828 // << std::endl;
829 // }
830 //
831 // return computed_quantities;
832 //}
833 //
834 //template <int dim, int nspecies, int nstate, typename real>
835 //std::vector<dealii::DataComponentInterpretation::DataComponentInterpretation> MHD<dim,nspecies,nstate,real>
836 //::post_get_data_component_interpretation () const
837 //{
838 // namespace DCI = dealii::DataComponentInterpretation;
839 // std::vector<DCI::DataComponentInterpretation> interpretation = PhysicsBase<dim,nspecies,nstate,real>::post_get_data_component_interpretation (); // state variables
840 // interpretation.push_back (DCI::component_is_scalar); // Density
841 // for (unsigned int d=0; d<dim; ++d) {
842 // interpretation.push_back (DCI::component_is_part_of_vector); // Velocity
843 // }
844 // for (unsigned int d=0; d<dim; ++d) {
845 // interpretation.push_back (DCI::component_is_part_of_vector); // Momentum
846 // }
847 // interpretation.push_back (DCI::component_is_scalar); // Energy
848 // interpretation.push_back (DCI::component_is_scalar); // Pressure
849 // interpretation.push_back (DCI::component_is_scalar); // Temperature
850 // interpretation.push_back (DCI::component_is_scalar); // Entropy generation
851 // interpretation.push_back (DCI::component_is_scalar); // Mach number
852 //
853 // std::vector<std::string> names = post_get_names();
854 // if (names.size() != interpretation.size()) {
855 // std::cout << "Number of DataComponentInterpretation is not the same as number of names for output file" << std::endl;
856 // }
857 // return interpretation;
858 //}
859 //
860 //
861 //template <int dim, int nspecies, int nstate, typename real>
862 //std::vector<std::string> MHD<dim,nspecies,nstate,real> ::post_get_names () const
863 //{
864 // std::vector<std::string> names = PhysicsBase<dim,nspecies,nstate,real>::post_get_names ();
865 // names.push_back ("density");
866 // for (unsigned int d=0; d<dim; ++d) {
867 // names.push_back ("velocity");
868 // }
869 // for (unsigned int d=0; d<dim; ++d) {
870 // names.push_back ("momentum");
871 // }
872 // names.push_back ("energy");
873 // names.push_back ("pressure");
874 // names.push_back ("temperature");
875 //
876 // names.push_back ("entropy_generation");
877 // names.push_back ("mach_number");
878 // return names;
879 //}
880 //
881 //template <int dim, int nspecies, int nstate, typename real>
882 //dealii::UpdateFlags MHD<dim,nspecies,nstate,real>
883 //::post_get_needed_update_flags () const
884 //{
885 // //return update_values | update_gradients;
886 // return dealii::update_values;
887 //}
888 
889 #if PHILIP_SPECIES==1
890 // Instantiate explicitly
896 #endif
897 } // Physics namespace
898 } // PHiLiP namespace
dealii::Tensor< 1, dim, real > compute_velocities(const std::array< real, nstate > &conservative_soln) const
Evaluate velocities from conservative variables.
Definition: mhd.cpp:100
std::array< real, nstate > convert_conservative_to_primitive(const std::array< real, nstate > &conservative_soln) const
Definition: mhd.cpp:42
real compute_temperature_from_density_pressure(const real density, const real pressure) const
Given density and pressure, returns NON-DIMENSIONALIZED temperature using free-stream non-dimensional...
Definition: mhd.cpp:192
real compute_velocity_squared(const dealii::Tensor< 1, dim, real > &velocities) const
Given the velocity vector , returns the dot-product .
Definition: mhd.cpp:110
std::array< real, nstate > compute_entropy_variables(const std::array< real, nstate > &conservative_soln) const
Computes the entropy variables.
Definition: mhd.cpp:350
Files for the baseline physics.
Definition: ADTypes.hpp:10
dealii::Tensor< 1, dim, real > compute_mean_velocities(const std::array< real, nstate > &conservative_soln1, const std::array< real, nstate > &convervative_soln2) const
Mean velocities given two sets of conservative solutions.
Definition: mhd.cpp:300
real compute_temperature(const std::array< real, nstate > &primitive_soln) const
Given primitive variables, returns NON-DIMENSIONALIZED temperature using free-stream non-dimensionali...
Definition: mhd.cpp:176
real compute_mean_density(const std::array< real, nstate > &conservative_soln1, const std::array< real, nstate > &convervative_soln2) const
Mean density given two sets of conservative solutions.
Definition: mhd.cpp:282
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: mhd.cpp:91
real compute_mean_pressure(const std::array< real, nstate > &conservative_soln1, const std::array< real, nstate > &convervative_soln2) const
Mean pressure given two sets of conservative solutions.
Definition: mhd.cpp:290
real max_viscous_eigenvalue(const std::array< real, nstate > &soln) const
Maximum viscous eigenvalue.
Definition: mhd.cpp:485
std::array< real, nstate > source_term(const dealii::Point< dim, real > &pos, const std::array< real, nstate > &conservative_soln, const real current_time, const dealii::types::global_dof_index cell_index) const
Source term is zero or depends on manufactured solution.
Definition: mhd.cpp:15
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
Evaluates boundary values and gradients on the other side of the face.
Definition: mhd.cpp:516
real compute_dimensional_temperature(const std::array< real, nstate > &primitive_soln) const
Given primitive variables, returns DIMENSIONALIZED temperature using the equation of state...
Definition: mhd.cpp:166
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: mhd.cpp:360
dealii::Tensor< 2, nstate, real > convective_flux_directional_jacobian(const std::array< real, nstate > &conservative_soln, const dealii::Tensor< 1, dim, real > &normal) const
Convective flux Jacobian: .
Definition: mhd.cpp:398
real compute_magnetic_energy(const std::array< real, nstate > &conservative_soln) const
Evaluate Magnetic Energy.
Definition: mhd.cpp:269
std::array< dealii::Tensor< 1, dim, real >, nstate > convective_flux(const std::array< real, nstate > &conservative_soln) const
Convective flux: .
Definition: mhd.cpp:324
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: mhd.cpp:443
real max_convective_eigenvalue(const std::array< real, nstate > &soln) const
Maximum convective eigenvalue.
Definition: mhd.cpp:462
std::array< real, nstate > convective_normal_flux(const std::array< real, nstate > &conservative_soln, const dealii::Tensor< 1, dim, real > &normal) const
Convective flux: .
Definition: mhd.cpp:370
real compute_pressure(const std::array< real, nstate > &conservative_soln) const
Evaluate pressure from conservative variables.
Definition: mhd.cpp:201
real compute_specific_enthalpy(const std::array< real, nstate > &conservative_soln, const real pressure) const
Evaluate pressure from conservative variables.
Definition: mhd.cpp:155
real compute_mean_specific_energy(const std::array< real, nstate > &conservative_soln1, const std::array< real, nstate > &convervative_soln2) const
Mean specific energy given two sets of conservative solutions.
Definition: mhd.cpp:315
std::array< dealii::Tensor< 1, dim, real >, nstate > dissipative_flux(const std::array< real, nstate > &conservative_soln, const std::array< dealii::Tensor< 1, dim, real >, nstate > &solution_gradient, const dealii::types::global_dof_index cell_index) const
Dissipative flux: 0.
Definition: mhd.cpp:492
real compute_total_energy(const std::array< real, nstate > &primitive_soln) const
Given primitive variables, returns total energy.
Definition: mhd.cpp:130
dealii::Tensor< 1, dim, real > extract_velocities_from_primitive(const std::array< real, nstate > &primitive_soln) const
Given primitive variables, returns velocities.
Definition: mhd.cpp:119
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: mhd.cpp:79
Magnetohydrodynamics (MHD) equations. Derived from PhysicsBase.
Definition: mhd.h:77
std::array< real, nstate > convert_primitive_to_conservative(const std::array< real, nstate > &primitive_soln) const
Definition: mhd.cpp:61
real compute_mach_number(const std::array< real, nstate > &conservative_soln) const
Given conservative variables, returns Mach number.
Definition: mhd.cpp:258
real compute_entropy_measure(const std::array< real, nstate > &conservative_soln) const
Evaluate entropy from conservative variables.
Definition: mhd.cpp:144
real compute_sound(const std::array< real, nstate > &conservative_soln) const
Evaluate speed of sound from conservative variables.
Definition: mhd.cpp:231
real compute_density_from_pressure_temperature(const real pressure, const real temperature) const
Given pressure and temperature, returns NON-DIMENSIONALIZED density using free-stream non-dimensional...
Definition: mhd.cpp:185