[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
real_gas.cpp
1 #include <cmath>
2 #include <vector>
3 #include <fstream>
4 
5 #include "ADTypes.hpp"
6 
7 #include "physics.h"
8 #include "euler.h"
9 #include "real_gas.h"
10 
11 namespace PHiLiP {
12 namespace Physics {
13 
14 template <int dim, int nspecies, int nstate, typename real>
16  const Parameters::AllParameters *const parameters_input,
17  std::shared_ptr< ManufacturedSolutionFunction<dim,nspecies,real> > manufactured_solution_function,
18  const bool has_nonzero_diffusion,
19  const bool has_nonzero_physical_source)
20  : PhysicsBase<dim,nspecies,nstate,real>(parameters_input, has_nonzero_diffusion,has_nonzero_physical_source,manufactured_solution_function)
21  , gam_ref(parameters_input->euler_param.gamma_gas)
22  , mach_ref(parameters_input->euler_param.mach_inf)
23  , mach_ref_sqr(mach_ref*mach_ref)
24  , two_point_num_flux_type(parameters_input->two_point_num_flux_type)
25  , Ru(8.31446261815324)
26  , MW_Air(28.9651159 * pow(10,-3))
27  , R_ref(Ru/MW_Air)
28  , temperature_ref(298.15)
29  , u_ref(mach_ref*sqrt(gam_ref*R_ref*temperature_ref))
30  , u_ref_sqr(u_ref*u_ref)
31  , tol(1.0e-14)
32  , density_ref(1.225)
33 {
34  static_assert(nstate==dim+nspecies+1, "Physics::RealGas() should be created with nstate=PHILIP_DIM+PHILIP_SPECIES+1"); // Note: update this with nspecies in the future
35  if(parameters_input->chemistry_input_file=="") {
36  this->pcout << "Name of chemistry file containing NASA CAP data for species has not been passed in. Aborting..." << std::endl;
37  std::abort();
38  }
39  readspeciesdata(parameters_input->chemistry_input_file);
40 }
41 
42 // Read chemistry file
43 template <int dim, int nspecies, int nstate, typename real>
45 ::readspeciesdata(std::string NASADataFilename)
46 {
47  std::string line, dum_char;
48 
49  std::ifstream chemfile (NASADataFilename);
50  std::getline(chemfile, line);
51  std::getline(chemfile, line);
52  int N_species = (int)std::stof(line);
53  if(nspecies != N_species) {
54  std::cout << std::endl << std::endl
55  << "----------------------------------------------------"
56  << std::endl
57  << "Number of species in chemistry file does not match PHILIP_SPECIES." << std::endl
58  << "Number of species in file = " << N_species << " and PHILIP_SPECIES = " << PHILIP_SPECIES << std::endl
59  << "Aborting!" << std::endl
60  << "----------------------------------------------------"
61  << std::endl;
62  std::abort();
63  }
64 
65  std::string dummy_name;
66  std::string::size_type sz1;
67  //===============================================
68  /*-------------------------------------------
69  * SPECIES SECTION
70  *-------------------------------------------*/
71  for(int i=0; i<nspecies; i++)
72  {
73  // Init
74  sz1 = 0;
75  std::getline(chemfile, line);
76  std::getline(chemfile, line);
77  std::getline(chemfile, line);
78  species_name[i] = line;
79  std::getline(chemfile, line);
80  std::getline(chemfile, line);
81  std::getline(chemfile, line);
82  species_weight[i] = std::stof(line); // Species molecular weight [g/mol]
83  species_weight[i] /= 1000.0; // Species molecular weight [kg/mol]
84 
85  std::getline(chemfile, line);
86  std::getline(chemfile, line);
87  std::getline(chemfile, line);
88  species_enthalpy_offset[i] = std::stof(line); // Species enthalpy from T = 0 to T= 298.15K [J/mol]
89  species_enthalpy_offset[i] /= (this->species_weight[i]*this->u_ref_sqr); // nondimensionalized mass value
90 
91  std::getline(chemfile, line);
92  std::getline(chemfile, line);
93  std::getline(chemfile, line);
94  for(int j=0; j<4; j++)
95  {
96  line = line.substr(sz1);
97  sz1 = 0;
98  NASACAPTemperatureLimits[i][j] = std::stof(line,&sz1);
99  }
100 
101  std::getline(chemfile, line);
102  std::getline(chemfile, line);
103  // Init
104  for(int k=0; k<3; k++) {
105  sz1 = 0;
106  std::getline(chemfile, line);
107  for(int j=0; j<9; j++)
108  {
109  line = line.substr(sz1);
110  sz1 = 0;
111  NASACAPCoeffs[i][j][k] = std::stod(line,&sz1);
112  }
113  }
114  }
115 
116  this->Rs = compute_Rs(this->Ru);
117 }
118 
119 // Get the temperature index of the species
120 template <int dim, int nspecies, int nstate, typename real>
121 std::array<int,nspecies> RealGas<dim, nspecies, nstate, real>
122 ::GetNASACAP_TemperatureIndex( const real temperature) const
123 {
124  if (temperature != temperature) {
125  std::cout<<"Temperature passed in is NaN...Aborting." << std::endl;
126  std::abort();
127  }
128  if (temperature < 0) {
129  std::cout<<"Temperature passed in is negative... Temperature = " << temperature << "...Aborting." << std::endl;
130  std::abort();
131  }
132  std::array<int,nspecies> species_tempindex;
133  for(int ispecies=0; ispecies<nspecies; ispecies++)
134  {
135  species_tempindex[ispecies] = -2; // initialize to value with no meaning
136  if(temperature < NASACAPTemperatureLimits[ispecies][0]) {
137  species_tempindex[ispecies] = -1; // clip to lower bound
138  }
139  else if((temperature >= NASACAPTemperatureLimits[ispecies][0]) && (temperature < NASACAPTemperatureLimits[ispecies][1]))
140  {
141  species_tempindex[ispecies] = 0; // low temp
142  }
143  else if((temperature >= NASACAPTemperatureLimits[ispecies][1]) && (temperature < NASACAPTemperatureLimits[ispecies][2]))
144  {
145  species_tempindex[ispecies] = 1; // mid temp
146  }
147  else if((temperature >= NASACAPTemperatureLimits[ispecies][2]) && (temperature <= NASACAPTemperatureLimits[ispecies][3]))
148  {
149  species_tempindex[ispecies] = 2; // high temp
150  }
151  else if(temperature > NASACAPTemperatureLimits[ispecies][2]) {
152  species_tempindex[ispecies] = 3; // clip to higher bound
153  }
154  else
155  {
156  std::cout<<"Invalid temperature of " << temperature << " was passed in...Aborting." << std::endl;
157  std::abort();
158  }
159  }
160 
161  return species_tempindex;
162 }
163 
164 template <int dim, int nspecies, int nstate, typename real>
165 std::array<real,nstate> RealGas<dim,nspecies,nstate,real>
167  const std::array<real,nstate> &conservative_soln,
168  const dealii::Tensor<1,dim,real> &normal) const
169 {
170  const dealii::Tensor<1,dim,real> vel = compute_velocities(conservative_soln);
171  std::array<real,nstate> eig;
172  real vel_dot_n = 0.0;
173  for (int d=0;d<dim;++d) { vel_dot_n += vel[d]*normal[d]; };
174  for (int i=0; i<nstate; i++) {
175  eig[i] = vel_dot_n;
176  }
177 
178  return eig;
179 }
180 
181 template <int dim, int nspecies, int nstate, typename real>
183 ::max_convective_eigenvalue (const std::array<real,nstate> &conservative_soln) const
184 {
185  const real sound = compute_sound(conservative_soln);
186  real vel2 = compute_velocity_squared_from_conservative_solution(conservative_soln);
187 
188  const real max_eig = sqrt(vel2) + sound;
189 
190  return max_eig;
191 }
192 
193 template <int dim, int nspecies, int nstate, typename real>
196  const std::array<real,nstate> &conservative_soln,
197  const dealii::Tensor<1,dim,real> &normal) const
198 {
199  const dealii::Tensor<1,dim,real> vel = compute_velocities(conservative_soln);
200 
201  const real sound = compute_sound (conservative_soln);
202 
203  real vel_dot_n = 0.0;
204  for (int d=0;d<dim;++d) { vel_dot_n += vel[d]*normal[d]; };
205  const real max_normal_eig = abs(vel_dot_n) + sound;
206 
207  return max_normal_eig;
208 }
209 
210 template <int dim, int nspecies, int nstate, typename real>
212 ::max_viscous_eigenvalue (const std::array<real,nstate> &/*conservative_soln*/) const
213 {
214  // zero because inviscid
215  const real max_eig = 0.0;
216  return max_eig;
217 }
218 
219 template <int dim, int nspecies, int nstate, typename real>
220 std::array<dealii::Tensor<1,dim,real>,nstate> RealGas<dim,nspecies,nstate,real>
222  const std::array<real,nstate> &/*conservative_soln*/,
223  const std::array<dealii::Tensor<1,dim,real>,nstate> &/*solution_gradient*/,
224  const dealii::types::global_dof_index /*cell_index*/) const
225 {
226  std::array<dealii::Tensor<1,dim,real>,nstate> diss_flux;
227  // No dissipative flux (i.e. viscous terms) for this physics class
228  for (int i=0; i<nstate; i++) {
229  diss_flux[i] = 0;
230  }
231  return diss_flux;
232 }
233 
234 template <int dim, int nspecies, int nstate, typename real>
235 std::array<real,nstate> RealGas<dim,nspecies,nstate,real>
237  const dealii::Point<dim,real> &/*pos*/,
238  const std::array<real,nstate> &/*conservative_soln*/,
239  const real /*current_time*/,
240  const dealii::types::global_dof_index /*cell_index*/) const
241 {
242  this->pcout<<"Source Terms not implemented for RealGas."<<std::endl;
243  std::abort();
244  std::array<real,nstate> source_term;
245  source_term.fill(0.0);
246  return source_term;
247 }
248 
249 template <int dim, int nspecies, int nstate, typename real>
252  const dealii::Tensor<1,dim,real> &normal_int,
253  const std::array<real,nstate> &soln_int,
254  const std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_int,
255  std::array<real,nstate> &soln_bc,
256  std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_bc) const
257 {
258  // Slip wall boundary for Euler
259  boundary_slip_wall(normal_int, soln_int, soln_grad_int, soln_bc, soln_grad_bc);
260 }
261 
262 template <int dim, int nspecies, int nstate, typename real>
265  const dealii::Tensor<1,dim,real> &normal_int,
266  const std::array<real,nstate> &soln_int,
267  const std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_int,
268  std::array<real,nstate> &soln_bc,
269  std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_bc) const
270 {
271  // Slip wall boundary conditions (No penetration)
272  // Given by Algorithm II of the following paper
273  // Krivodonova, L., and Berger, M.,
274  // “High-order accurate implementation of solid wall boundary conditions in curved geometries,”
275  // Journal of Computational Physics, vol. 211, 2006, pp. 492–512.
276  const std::array<real,nstate> primitive_interior_values = convert_conservative_to_primitive(soln_int);
277 
278  // Copy density and pressure and mass fractions
279  std::array<real,nstate> primitive_boundary_values;
280  primitive_boundary_values[0] = primitive_interior_values[0];
281  primitive_boundary_values[dim+1] = primitive_interior_values[dim+1];
282  for (int ispecies = 0; ispecies < nspecies-1; ++ispecies) {
283  primitive_boundary_values[dim+2+ispecies] = primitive_interior_values[dim+2+ispecies];
284  }
285 
286  const dealii::Tensor<1,dim,real> surface_normal = -normal_int;
287  dealii::Tensor<1,dim,real> velocities_int;
288  for (int d=0; d<dim; d++) { velocities_int[d] = primitive_interior_values[1+d]; }
289  //const dealii::Tensor<1,dim,real> velocities_bc = velocities_int - 2.0*(velocities_int*surface_normal)*surface_normal;
290  real vel_int_dot_normal = 0.0;
291  for (int d=0; d<dim; d++) {
292  vel_int_dot_normal = vel_int_dot_normal + velocities_int[d]*surface_normal[d];
293  }
294  dealii::Tensor<1,dim,real> velocities_bc;
295  for (int d=0; d<dim; d++) {
296  velocities_bc[d] = velocities_int[d] - 2.0*(vel_int_dot_normal)*surface_normal[d];
297  //velocities_bc[d] = velocities_int[d] - (vel_int_dot_normal)*surface_normal[d];
298  //velocities_bc[d] += velocities_int[d] * surface_normal.norm_square();
299  }
300  for (int d=0; d<dim; ++d) {
301  primitive_boundary_values[1+d] = velocities_bc[d];
302  }
303 
304  const std::array<real,nstate> modified_conservative_boundary_values = convert_primitive_to_conservative(primitive_boundary_values);
305  for (int istate=0; istate<nstate; ++istate) {
306  soln_bc[istate] = modified_conservative_boundary_values[istate];
307  }
308 
309  for (int istate=0; istate<nstate; ++istate) {
310  soln_grad_bc[istate] = -soln_grad_int[istate];
311  }
312 }
313 
314 template <int dim, int nspecies, int nstate, typename real>
317  const int boundary_type,
318  const dealii::Point<dim, real> &/*pos*/,
319  const dealii::Tensor<1,dim,real> &normal_int,
320  const std::array<real,nstate> &soln_int,
321  const std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_int,
322  std::array<real,nstate> &soln_bc,
323  std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_bc) const
324 {
325  if (boundary_type == 1001) {
326  // Wall boundary condition (slip for Real Gas, no-slip for Navier-Stokes-Real-Gas)
327  boundary_wall (normal_int, soln_int, soln_grad_int, soln_bc, soln_grad_bc);
328  } else if (boundary_type == 1006) {
329  // Slip wall boundary condition
330  boundary_slip_wall (normal_int, soln_int, soln_grad_int, soln_bc, soln_grad_bc);
331  } else {
332  this->pcout<<"Boundary condition #" << boundary_type << " not implemented for RealGas."<<std::endl;
333  std::abort();
334  }
335 }
336 
337 // Details of the following algorithms are presented in Liki's Master's thesis.
338 /* MAIN FUNCTIONS */
339 // Algorithm 1 (f_M1): Compute mixture density
340 template <int dim, int nspecies, int nstate, typename real>
341 template<typename real2>
343 :: compute_mixture_density ( const std::array<real2,nstate> &conservative_soln ) const
344 {
345  const real2 mixture_density = conservative_soln[0];
346 
347  return mixture_density;
348 }
349 
350 // Algorithm 2 (f_M2): Compute velocities
351 template <int dim, int nspecies, int nstate, typename real>
352 inline dealii::Tensor<1,dim,real> RealGas<dim,nspecies,nstate,real>
353 ::compute_velocities ( const std::array<real,nstate> &conservative_soln ) const
354 {
355  const real mixture_density = compute_mixture_density(conservative_soln);
356  dealii::Tensor<1,dim,real> vel;
357  for (int d=0; d<dim; ++d) { vel[d] = conservative_soln[1+d]/mixture_density; }
358 
359  return vel;
360 }
361 
362 // Algorithm 3 (f_M3): Compute squared velocities
363 template <int dim, int nspecies, int nstate, typename real>
365 ::compute_velocity_squared_from_conservative_solution ( const std::array<real,nstate> &conservative_soln ) const
366 {
367  const dealii::Tensor<1,dim,real> vel = compute_velocities(conservative_soln);
368  real vel2 = 0.0;
369  for (int d=0; d<dim; d++) {
370  vel2 = vel2 + vel[d]*vel[d];
371  }
372 
373  return vel2;
374 }
375 
376 template <int dim, int nspecies, int nstate, typename real>
378 ::compute_velocity_squared ( const dealii::Tensor<1,dim,real> &velocities ) const
379 {
380  real vel2 = 0.0;
381  for (int d=0; d<dim; d++) {
382  vel2 = vel2 + velocities[d]*velocities[d];
383  }
384 
385  return vel2;
386 }
387 
388 template <int dim, int nspecies, int nstate, typename real>
389 inline dealii::Tensor<1,dim,real> RealGas<dim,nspecies,nstate,real>
390 ::extract_velocities_from_primitive ( const std::array<real,nstate> &primitive_soln ) const
391 {
392  dealii::Tensor<1,dim,real> velocities;
393  for (int d=0; d<dim; d++) { velocities[d] = primitive_soln[1+d]; }
394  return velocities;
395 }
396 
397 // Algorithm 4 (f_M4): Compute specific kinetic energy
398 template <int dim, int nspecies, int nstate, typename real>
400 ::compute_specific_kinetic_energy ( const std::array<real,nstate> &conservative_soln ) const
401 {
402  const real vel2 = compute_velocity_squared_from_conservative_solution(conservative_soln);
403  const real k = 0.5*vel2;
404 
405  return k;
406 }
407 
408 // Algorithm 5 (f_M5): Compute mixture specific total energy
409 template <int dim, int nspecies, int nstate, typename real>
411 ::compute_mixture_specific_total_energy ( const std::array<real,nstate> &conservative_soln ) const
412 {
413  const real mixture_density = compute_mixture_density(conservative_soln);
414  const real mixture_specific_total_energy = conservative_soln[dim+1]/mixture_density;
415 
416  return mixture_specific_total_energy;
417 }
418 
419 // Algorithm 6 (f_M6): Compute species densities
420 template <int dim, int nspecies, int nstate, typename real>
421 inline std::array<real,nspecies> RealGas<dim,nspecies,nstate,real>
422 ::compute_species_densities ( const std::array<real,nstate> &conservative_soln ) const
423 {
424  const real mixture_density = compute_mixture_density(conservative_soln);
425  std::array<real,nspecies> species_densities;
426  real sum = 0.0;
427  for (int s=0; s<nspecies-1; ++s)
428  {
429  species_densities[s] = conservative_soln[dim+2+s];
430  sum += species_densities[s];
431  }
432  species_densities[nspecies-1] = mixture_density - sum;
433 
434  return species_densities;
435 }
436 
437 // Algorithm 7 (f_M7): Compute mass fractions
438 template <int dim, int nspecies, int nstate, typename real>
439 inline std::array<real,nspecies> RealGas<dim,nspecies,nstate,real>
440 ::compute_mass_fractions ( const std::array<real,nstate> &conservative_soln ) const
441 {
442  const real mixture_density = compute_mixture_density(conservative_soln);
443  const std::array<real,nspecies> species_densities = compute_species_densities(conservative_soln);
444  std::array<real,nspecies> mass_fractions;
445  for (int s=0; s<nspecies; ++s)
446  {
447  mass_fractions[s] = species_densities[s]/mixture_density;
448  }
449 
450  return mass_fractions;
451 }
452 
453 // Algorithm 8 (f_M8): Compute mixture from species
454 template <int dim, int nspecies, int nstate, typename real>
456 ::compute_mixture_from_species ( const std::array<real,nspecies> &mass_fractions, const std::array<real,nspecies> &species) const
457 {
458  real mixture = 0.0;
459  for (int s=0; s<nspecies; ++s)
460  {
461  mixture += mass_fractions[s]*species[s];
462  }
463 
464  return mixture;
465 }
466 
467 // Algorithm 9 (f_M9): Compute dimensional temperature
468 template <int dim, int nspecies, int nstate, typename real>
470 ::compute_dimensional_temperature ( const real temperature ) const
471 {
472  const real dimensional_temperature = temperature*this->temperature_ref;
473 
474  return dimensional_temperature;
475 }
476 
477 // Algorithm 10 (f_M10): Compute species gas constants
478 template <int dim, int nspecies, int nstate, typename real>
479 std::array<real,nspecies> RealGas<dim,nspecies,nstate,real>
480 ::compute_Rs ( const real Ru ) const
481 {
482  std::array<real,nspecies> Rs;
483  for (int s=0; s<nspecies; ++s)
484  {
485  Rs[s] = Ru/this->species_weight[s]/this->R_ref;
486  }
487 
488  return Rs;
489 }
490 
491 // Algorithm 11 (f_M11): Compute species specific heat at constant pressure
492 // This function has been modified by Shruthi
493 // Modification: separates the temperature index into its own separate function since two different functions use it
494 template <int dim, int nspecies, int nstate, typename real>
495 std::array<real,nspecies> RealGas<dim,nspecies,nstate,real>
496 ::compute_species_specific_Cp ( const real temperature ) const
497 {
498  real dimensional_temperature = compute_dimensional_temperature(temperature);
499  std::array<real,nspecies> Cp;
500  // const std::array<real,nspecies> Rs = compute_Rs(this->Ru);
501 
502  if (dimensional_temperature < 0) {
503  std::cout<<"Cp Calculation Error: Temperature passed in is negative... Temperature = " << dimensional_temperature << "...Aborting." << std::endl;
504  std::abort();
505  }
506  std::array<int,nspecies> species_tempindex = GetNASACAP_TemperatureIndex(dimensional_temperature);
507  // species loop
508  for (int s=0; s<nspecies; ++s)
509  {
510  // main computation
511  Cp[s] = 0.0;
512  if(species_tempindex[s] == -1) { // clip to lower temperature bound's Cp (Refer to NASA FUN3D manual v14.2 sec.B.8)
513  species_tempindex[s] = 0;
514  dimensional_temperature = NASACAPTemperatureLimits[s][0];
515  }
516  if(species_tempindex[s] == 3) { // clip to higher temperature bound's Cp (Refer to NASA FUN3D manual v14.2 sec.B.8)
517  species_tempindex[s] = 2;
518  dimensional_temperature = NASACAPTemperatureLimits[s][2];
519  }
520  for (int i=0; i<7; i++)
521  {
522  Cp[s] += this->NASACAPCoeffs[s][i][species_tempindex[s]]*pow(dimensional_temperature,i-2);
523  }
524  Cp[s] *= this->Rs[s];
525  }
526 
527  return Cp; // nondimensional mass value
528 }
529 
530 // Algorithm 12 (f_M12): Compute species specific heat at constant volume
531 template <int dim, int nspecies, int nstate, typename real>
532 std::array<real,nspecies> RealGas<dim,nspecies,nstate,real>
533 ::compute_species_specific_Cv ( const real temperature ) const
534 {
535  const std::array<real,nspecies> Cp = compute_species_specific_Cp(temperature);
536  std::array<real,nspecies> Cv;
537 
538  for (int s=0; s<nspecies; ++s)
539  {
540  Cv[s] = Cp[s] - this->Rs[s];
541  }
542 
543  return Cv; // nondimensional mass value
544 }
545 
546 // Algorithm 13 (f_M13): Compute species specific enthalpy
547 // This function has been modified by Shruthi
548 // Modification: separates the temperature index into its own separate function since two different functions use it
549 // Modification #2: includes a clipping process to ensure we can still calculate for temps outside range
550 template <int dim, int nspecies, int nstate, typename real>
551 std::array<real,nspecies> RealGas<dim,nspecies,nstate,real>
552 ::compute_species_specific_enthalpy ( const real temperature ) const
553 {
554  real dimensional_temperature = compute_dimensional_temperature(temperature);
555  std::array<real,nspecies> h;
556 
557  if (dimensional_temperature < 0) {
558  std::cout<<"Species Enthalpy Calculation Error: Temperature passed in is negative... Temperature = " << dimensional_temperature << "...Aborting." << std::endl;
559  std::abort();
560  }
561  std::array<int,nspecies> species_tempindex = GetNASACAP_TemperatureIndex(dimensional_temperature);
563  for (int s=0; s<nspecies; ++s)
564  {
565  // main computation
566  real Cp = 0.0;
567  real out_of_bounds_temp = -1.0;
568  if(species_tempindex[s] == -1) { // Calculate enthalpy using calorically perfect gas (CPG) model (Refer to NASA FUN3D manual v14.2 sec.B.8)
569  species_tempindex[s] = 0;
570  std::array<real,nspecies> Cp_species = compute_species_specific_Cp(NASACAPTemperatureLimits[s][0]);
571  Cp = Cp_species[s]; // obtain Cp so the enthalpy can be calculated with CPG model
572  Cp /= this->Rs[s]; // nondimensional molar value of Cp;
573  out_of_bounds_temp = dimensional_temperature; // save the temperature value to calculate enthalpy using CPG model
574  dimensional_temperature = NASACAPTemperatureLimits[s][0];
575  }
576  if(species_tempindex[s] == 3) { // Calculate enthalpy using calorically perfect gas (CPG) model (Refer to NASA FUN3D manual v14.2 sec.B.8)
577  species_tempindex[s] = 2;
578  std::array<real,nspecies> Cp_species = compute_species_specific_Cp(NASACAPTemperatureLimits[s][2]);
579  Cp = Cp_species[s]; // obtain Cp so the enthalpy can be calculated with CPG model
580  Cp /= this->Rs[s]; // nondimensional molar value of Cp;
581  out_of_bounds_temp = dimensional_temperature; // save the temperature value to calculate enthalpy using CPG model
582  dimensional_temperature = NASACAPTemperatureLimits[s][2];
583  }
584  h[s] = -this->NASACAPCoeffs[s][0][species_tempindex[s]]*pow(dimensional_temperature,-2)
585  +this->NASACAPCoeffs[s][1][species_tempindex[s]]*pow(dimensional_temperature,-1)*log(dimensional_temperature)
586  +this->NASACAPCoeffs[s][7][species_tempindex[s]]*pow(dimensional_temperature,-1); // The first 2 terms and the last term are added
587  for (int i=2; i<7; i++)
588  {
589  h[s] += this->NASACAPCoeffs[s][i][species_tempindex[s]]*pow(dimensional_temperature,i-2)/((double)(i-1)); // The other terms are added
590  }
591 
592  if(out_of_bounds_temp != -1.0) {
593  h[s] = h[s]*(dimensional_temperature/out_of_bounds_temp) + ((out_of_bounds_temp - dimensional_temperature)/out_of_bounds_temp) * Cp;
594  }
595 
596  if(out_of_bounds_temp != -1.0)
597  h[s] *= ((this->Ru*out_of_bounds_temp)/(this->species_weight[s]*this->u_ref_sqr)); //nondimensional mass value
598  else
599  h[s] *= ((this->Ru*dimensional_temperature)/(this->species_weight[s]*this->u_ref_sqr)); //nondimensional mass value
600 
601  h[s] += species_enthalpy_offset[s]; // add the species_enthalpy_offset to account for enthalpy of formation for T=0 -> T=298.15K
602 
603  // set dimensional temp back to the out of bounds temp for the next species in the loop
604  if (out_of_bounds_temp != -1.0)
605  dimensional_temperature = out_of_bounds_temp;
606  }
607  return h;
608 }
609 
610 // Algorithm 14 (f_M14): Compute species specific internal energy
611 template <int dim, int nspecies, int nstate, typename real>
612 std::array<real,nspecies> RealGas<dim,nspecies,nstate,real>
613 ::compute_species_specific_internal_energy( const real temperature ) const
614 {
615  const std::array<real,nspecies> h = compute_species_specific_enthalpy(temperature);
616  const std::array<real,nspecies> Rs = compute_Rs(this->Ru);
617  std::array<real,nspecies> e;
618  for (int s=0; s<nspecies; ++s)
619  {
620  e[s] = h[s] - (this->R_ref*this->temperature_ref/this->u_ref_sqr)* Rs[s]*temperature;
621  }
622 
623  return e;
624 }
625 
626 // Compute the Cv integral component of species entropy (ie. \int_{T_ref}^T c_v(\tau)/\tau d\tau) using NASA polynomials
627 template <int dim, int nspecies, int nstate, typename real>
628 std::array<real,nspecies> RealGas<dim, nspecies, nstate, real>
630  const real temperature) const
631 {
632  real dimensional_temperature = compute_dimensional_temperature(temperature);
633  std::array<real,nspecies> species_entropy;
634 
635  if (dimensional_temperature < 0) {
636  std::cout<<" Species Entropy Calculation Error: Temperature passed in is negative... Temperature = " << dimensional_temperature << "...Aborting." << std::endl;
637  std::abort();
638  }
639  std::array<int,nspecies> species_tempindex = GetNASACAP_TemperatureIndex(dimensional_temperature);
640 
642  for (int s=0; s<nspecies; ++s)
643  {
644  // main computation
645  real Cp = 0.0;
646  real out_of_bounds_temp = -1.0;
647  if(species_tempindex[s] == -1) { // Calculate entropy using calorically perfect gas (CPG) model (Refer to NASA FUN3D manual v14.2 sec.B.8)
648  species_tempindex[s] = 0;
649  std::array<real,nspecies> Cp_species = compute_species_specific_Cp(NASACAPTemperatureLimits[s][0]);
650  Cp = Cp_species[s]; // obtain Cp so the entropy can be calculated with CPG model
651  Cp /= this->Rs[s]; // nondimensional molar value of Cp;
652  out_of_bounds_temp = dimensional_temperature; // save the temperature value to calculate entropy using CPG model
653  dimensional_temperature = NASACAPTemperatureLimits[s][0];
654  }
655  if(species_tempindex[s] == 3) { // Calculate entropy using calorically perfect gas (CPG) model (Refer to NASA FUN3D manual v14.2 sec.B.8)
656  species_tempindex[s] = 2;
657  std::array<real,nspecies> Cp_species = compute_species_specific_Cp(NASACAPTemperatureLimits[s][2]);
658  Cp = Cp_species[s]; // obtain Cp so the entropy can be calculated with CPG model
659  Cp /= this->Rs[s]; // nondimensional molar value of Cp;
660  out_of_bounds_temp = dimensional_temperature; // save the temperature value to calculate entropy using CPG model
661  dimensional_temperature = NASACAPTemperatureLimits[s][2];
662  }
663  species_entropy[s] = -this->NASACAPCoeffs[s][0][species_tempindex[s]]*pow(dimensional_temperature,-2)*0.5
664  -this->NASACAPCoeffs[s][1][species_tempindex[s]]*pow(dimensional_temperature,-1)
665  +this->NASACAPCoeffs[s][2][species_tempindex[s]]*log(dimensional_temperature)
666  +this->NASACAPCoeffs[s][8][species_tempindex[s]];
667  for (int i=3; i<7; i++)
668  {
669  species_entropy[s] += this->NASACAPCoeffs[s][i][species_tempindex[s]]*pow(dimensional_temperature,double(i-2))/((double)(i-2)); // The other terms are added
670  }
671 
672  if(out_of_bounds_temp != -1.0) {
673  species_entropy[s] = species_entropy[s] + log(dimensional_temperature/out_of_bounds_temp) * Cp;
674  }
675 
676  // set dimensional temp back to the out of bounds temp for the next species in the loop
677  if (out_of_bounds_temp != -1.0)
678  dimensional_temperature = out_of_bounds_temp;
679  species_entropy[s] *= this->Rs[s];
680  species_entropy[s] -= this->Rs[s]*log(temperature);
681  }
682 
683  return species_entropy;
684 }
685 
686 // Compute species entropy by calculating integral and adding in density contribution (ie. R_k ln \rho_k)
687 template <int dim, int nspecies, int nstate, typename real>
688 std::array<real,nspecies> RealGas<dim, nspecies, nstate, real>
690  const std::array<real,nstate> &conservative_soln) const
691 {
692  const real temperature = compute_temperature(conservative_soln);
693  const std::array<real,nspecies> species_densities = compute_species_densities(conservative_soln);
694 
695  std::array<real,nspecies> species_entropy = compute_species_entropy_cv_integral(temperature);
696  for(int ispecies = 0; ispecies < nspecies; ispecies++) {
697  species_entropy[ispecies] -= this->Rs[ispecies]*log(temperature*species_densities[ispecies]*this->density_ref);
698  }
699 
700  return species_entropy;
701 }
702 
703 
704 // Compute mixture entropy
705 template <int dim, int nspecies, int nstate, typename real>
708  const std::array<real,nstate> &conservative_soln) const
709 {
710  const std::array<real,nspecies> species_entropy = compute_species_entropy(conservative_soln);
711  const std::array<real,nspecies> mass_fractions = compute_mass_fractions(conservative_soln);
712 
713  const real entropy = compute_mixture_from_species(mass_fractions,species_entropy);
714  if(entropy != entropy) {
715  std::cout << "The calculated entropy is NaN - this is likely due to a species having a mass fraction of zero...Aborting." << std::endl;
716  std::abort();
717  }
718 
719  return entropy;
720 }
721 
722 // Compute Gibbs' energy of species using species entropy and species Cp
723 template <int dim, int nspecies, int nstate, typename real>
724 std::array<real,nspecies> RealGas<dim, nspecies, nstate, real>
726  const std::array<real,nstate> &conservative_soln) const
727 {
728  const real temperature = compute_temperature(conservative_soln);
729 
730  std::array<real,nspecies> species_entropy = compute_species_entropy(conservative_soln);
731  std::array<real,nspecies> species_Cp = compute_species_specific_Cp(temperature);
732 
733  std::array<real, nspecies> species_gibbs;
734  for(int ispecies = 0; ispecies < nspecies; ++ispecies) {
735  species_gibbs[ispecies] = temperature*(species_Cp[ispecies] - species_entropy[ispecies]);
736  }
737 
738  return species_gibbs;
739 }
740 
741 // Compute the entropy variables from conservative solution
742 template <int dim, int nspecies, int nstate, typename real>
743 std::array<real,nstate> RealGas<dim, nspecies, nstate, real>
745  const std::array<real,nstate> &conservative_soln) const
746 {
747  std::array<real,nstate> entropy_var;
748  const real temperature = compute_temperature(conservative_soln);
749  std::array<real,nspecies> species_gibbs = compute_species_gibbs_energy(conservative_soln);
750  real vel2 = compute_velocity_squared_from_conservative_solution(conservative_soln);
751 
752  entropy_var[0] = species_gibbs[nspecies-1] - (0.5*vel2);
753  entropy_var[dim+1] = -1.0;
754 
755  const dealii::Tensor<1,dim,real> vel = compute_velocities(conservative_soln);
756  for (int idim = 0; idim < dim; ++idim) {
757  entropy_var[idim+1] = vel[idim];
758  }
759 
760  for (int ispecies = 0; ispecies < nspecies - 1; ++ispecies) {
761  entropy_var[dim+2+ispecies] = species_gibbs[ispecies] - species_gibbs[nspecies-1];
762  }
763 
764  for (int istate = 0; istate < nstate; ++istate) {
765  entropy_var[istate] /= temperature;
766  }
767 
768  return entropy_var;
769 }
770 
771 // Map entropy variables back to conservative solution
772 template <int dim, int nspecies, int nstate, typename real>
773 std::array<real,nstate> RealGas<dim, nspecies, nstate, real>
775  const std::array<real,nstate> &entropy_var) const
776 {
777  std::array<real,nstate> conservative_var;
778  const real temperature = -1/entropy_var[dim+1];
779  const int nth_species_idx = nspecies - 1;
780 
781  std::array<real,nspecies> species_gibbs;
782 
783  real entropy_var_vel_squared = 0.0;
784  for(int idim=0; idim<dim; idim++){
785  entropy_var_vel_squared += pow(entropy_var[idim + 1]*temperature, 2.0);
786  }
787 
788  species_gibbs[nth_species_idx] = temperature*entropy_var[0] + entropy_var_vel_squared/2.0;
789  for(int ispecies = 0; ispecies < nth_species_idx; ++ispecies) {
790  species_gibbs[ispecies] = temperature*entropy_var[dim+2+ispecies] + species_gibbs[nth_species_idx];
791  }
792 
793  std::array<real,nspecies> species_entropy;
794  std::array<real,nspecies> species_Cp = compute_species_specific_Cp(temperature);
795  for(int ispecies = 0; ispecies < nth_species_idx; ++ispecies) {
796  species_entropy[ispecies] = species_Cp[ispecies] - (species_gibbs[ispecies]/temperature);
797  }
798  species_entropy[nth_species_idx] = species_Cp[nth_species_idx] - (species_gibbs[nth_species_idx]/temperature);
799 
800  std::array<real,nspecies> species_density;
801  const std::array<real,nspecies> Rs = compute_Rs(this->Ru);
802  conservative_var[0] = 0.0;
803  for(int ispecies = 0; ispecies < nspecies; ++ispecies) {
804  std::array<real,nspecies> species_entropy_integral = compute_species_entropy_cv_integral(temperature);
805 
806  species_density[ispecies] = (exp((species_entropy_integral[ispecies] - species_entropy[ispecies])/(Rs[ispecies])))/(temperature*this->density_ref);
807  conservative_var[0] += species_density[ispecies];
808 
809  if (dim + 2 + ispecies < nstate)
810  conservative_var[dim+2+ispecies] = species_density[ispecies];
811  }
812 
813  const real mixture_density = conservative_var[0];
814 
815  for (int idim = 0; idim < dim; ++idim) {
816  conservative_var[idim+1] = mixture_density*entropy_var[idim+1]*temperature;
817  }
818 
819  // specific kinetic energy
820  const real specific_kinetic_energy = 0.50*entropy_var_vel_squared;
821  // species specific enthalpy
822  const std::array<real,nspecies> species_specific_enthalpy = compute_species_specific_enthalpy(temperature);
823  std::array<real,nspecies> species_specific_internal_energy;
824  std::array<real,nspecies> species_specific_total_energy;
825  // species energy
826  for (int s=0; s<nspecies; ++s)
827  {
828  species_specific_internal_energy[s] = species_specific_enthalpy[s] - (this->R_ref*this->temperature_ref/this->u_ref_sqr)* Rs[s]*temperature;
829  species_specific_total_energy[s] = species_specific_internal_energy[s] + specific_kinetic_energy;
830  }
831  // mixture energy
832  real mixture_specific_total_energy = 0.0;
833  for(int ispecies = 0; ispecies < nspecies; ++ispecies) {
834  mixture_specific_total_energy += species_specific_total_energy[ispecies] *(species_density[ispecies]/mixture_density);
835  }
836  conservative_var[dim+1] = mixture_density*mixture_specific_total_energy;
837 
838  return conservative_var;
839 }
840 
841 // Computes the kinetic energy variables (Based off Cicchino 2025, Eq. 59)
842 template <int dim, int nspecies, int nstate, typename real>
843 std::array<real,nstate> RealGas<dim, nspecies, nstate, real>
845  const std::array<real,nstate> &conservative_soln) const
846 {
847  std::array<real,nstate> kin_energy_var;
848  const dealii::Tensor<1,dim,real> vel = compute_velocities(conservative_soln);
849  const real vel2 = compute_velocity_squared_from_conservative_solution(conservative_soln);
850 
851  kin_energy_var[0] = - 0.5 * vel2;
852  for(int idim=0; idim<dim; idim++){
853  kin_energy_var[idim+1] = vel[idim];
854  }
855  kin_energy_var[dim+1] = 0.0;
856  for(int ispecies=0; ispecies<nspecies-1; ispecies++) {
857  int index = dim+2+ispecies;
858  kin_energy_var[index] = 0.0;
859  }
860 
861  return kin_energy_var;
862 }
863 
864 // Algorithm 15 (f_M15): Compute temperature
865 template <int dim, int nspecies, int nstate, typename real>
867 ::compute_temperature ( const std::array<real,nstate> &conservative_soln ) const
868 {
869  /* definitions */
870  const std::array<real,nspecies> mass_fractions = compute_mass_fractions(conservative_soln);
871  const real specific_kinetic_energy= compute_specific_kinetic_energy(conservative_soln);
872  const real mixture_gas_constant = compute_mixture_gas_constant(conservative_soln);
873  const real mixture_specific_total_energy = compute_mixture_specific_total_energy(conservative_soln);
874 
875  std::array<real,nspecies> species_specific_enthalpy;
876  real mixture_specific_internal_energy;
877  real mixture_specific_enthalpy;
878 
879  real f;
880  std::array<real,nspecies> Cv;
881  real mixture_Cv;
882  real f_d; // f'
883  real T_npo; // T_(n+1)
884  real err = 999.9;
885  int itr = 0;
886 
887  /* compute temperature using the Newton-Raphson method */
888  real T_n = 2.0*this->temperature_ref; // the initial guess
889  do
890  {
892  // mixture specific internal energy: e = E - k
893  mixture_specific_internal_energy = (mixture_specific_total_energy - specific_kinetic_energy)*this->u_ref_sqr; // dimensional value
894  // species specific enthalpy at T_n
895  species_specific_enthalpy = compute_species_specific_enthalpy(T_n/this->temperature_ref); // nondimensional mass value
896  // mixture specific enthalpy at T_n
897  mixture_specific_enthalpy = compute_mixture_from_species(mass_fractions,species_specific_enthalpy)*this->u_ref_sqr; // dimensional value
898  // Newton-Raphson function
899  f = (mixture_specific_enthalpy - mixture_gas_constant*this->R_ref* T_n) - mixture_specific_internal_energy; // dimensional value
900 
902  // Cv at T_n
903  Cv = compute_species_specific_Cv(T_n/this->temperature_ref); // nondimensional mass value
904 
905  // mixture Cv
906  mixture_Cv = compute_mixture_from_species(mass_fractions,Cv)*this->R_ref; // dimensional value
907 
908  // Newton-Raphson derivative function
909  f_d = mixture_Cv;
910 
912  T_npo = T_n - f/f_d; // dimensional value
913  err = abs((T_npo-T_n)/this->temperature_ref);
914  itr += 1;
915 
916  // update T
917  if(itr > 9.99999e6) {
918  // output temperature values for the last 10 iterations
919  // included this output so user can determine if the tolerance is the issue
920  std::cout << "Nearing the max iterations...iteration #" << itr << " old temperature: " << T_n
921  << " new temperature: " << T_npo << std::endl;
922  std::cout << " Mixture Cv: " << mixture_Cv << std::endl << std::endl;
923  }
924  T_n = T_npo;
925  }
926  while (err>this->tol && itr < 1e7);
927  if(itr == 1e7) {
928  std::cout << "Maximum iterations for temperature reached without converging...Aborting..." << std::endl;
929  std::abort();
930  }
931  T_n /= temperature_ref; // non-dimensional value
932  if(T_n < 0) {
933  std::cout << "Computed temperature is a negative value...Aborting..." << std::endl;
934  std::abort();
935  }
936  if(T_n != T_n) {
937  std::cout << "Computed temperature is NaN...Aborting..." << std::endl;
938  std::abort();
939  }
940  return T_n;
941 }
942 
943 // Algorithm 16 (f_M16): Compute mixture gas constant
944 template <int dim, int nspecies, int nstate, typename real>
946 ::compute_mixture_gas_constant ( const std::array<real,nstate> &conservative_soln ) const
947 {
948  const std::array<real,nspecies> mass_fractions = compute_mass_fractions(conservative_soln);
949  const real mixture_gas_constant = compute_mixture_from_species(mass_fractions,this->Rs);
950  return mixture_gas_constant;
951 }
952 
953 // Algorithm 17 (f_M17): Compute mixture pressure
954 template <int dim, int nspecies, int nstate, typename real>
956 ::compute_mixture_pressure ( const std::array<real,nstate> &conservative_soln ) const
957 {
958  const real mixture_density = compute_mixture_density(conservative_soln);
959  const real mixture_gas_constant = compute_mixture_gas_constant(conservative_soln);
960  const real temperature = compute_temperature(conservative_soln);
961  const real mixture_pressure = mixture_density*mixture_gas_constant*temperature/(this->gam_ref*this->mach_ref_sqr);
962 
963  return mixture_pressure;
964 }
965 
966 // Algorithm 17 (f_M17): Compute pressure -> calls compute_pressure (allows other classes to use PhysicsBase ptr)
967 template <int dim, int nspecies, int nstate, typename real>
969 ::compute_pressure ( const std::array<real,nstate> &conservative_soln ) const
970 {
971  return compute_mixture_pressure(conservative_soln);
972 }
973 template <int dim, int nspecies, int nstate, typename real>
975 ::compute_pressure_from_density_temperature ( const real density, const real temperature, const std::array<real,nstate> &conservative_soln ) const
976 {
977  const real mixture_gas_constant = compute_mixture_gas_constant(conservative_soln);
978  const real mixture_pressure = density*mixture_gas_constant*temperature/(this->gam_ref*this->mach_ref_sqr);
979  return mixture_pressure;
980 }
981 
982 // Algorithm 18 (f_M18): Compute mixture specific total enthalpy
983 template <int dim, int nspecies, int nstate, typename real>
985 ::compute_mixture_specific_total_enthalpy ( const std::array<real,nstate> &conservative_soln ) const
986 {
987  const real mixture_specific_total_energy = compute_mixture_specific_total_energy(conservative_soln);
988  const real mixture_pressure = compute_mixture_pressure(conservative_soln);
989  const real mixture_density = compute_mixture_density(conservative_soln);
990  const real mixture_specific_total_enthalpy = mixture_specific_total_energy + mixture_pressure/mixture_density;
991 
992  return mixture_specific_total_enthalpy;
993 }
994 
995 // Algorithm 19 (f_M19): Compute convective flux
996 template <int dim, int nspecies, int nstate, typename real>
997 std::array<dealii::Tensor<1,dim,real>,nstate> RealGas<dim,nspecies,nstate,real>
998 ::convective_flux (const std::array<real,nstate> &conservative_soln) const
999 {
1000  /* definitions */
1001  std::array<dealii::Tensor<1,dim,real>,nstate> conv_flux;
1002  const real mixture_density = compute_mixture_density(conservative_soln);
1003  const dealii::Tensor<1,dim,real> vel = compute_velocities(conservative_soln);
1004  const real mixture_pressure = compute_mixture_pressure(conservative_soln);
1005  const real mixture_specific_total_enthalpy = compute_mixture_specific_total_enthalpy(conservative_soln);
1006  const std::array<real,nspecies> species_densities = compute_species_densities(conservative_soln);
1007 
1008  // flux dimension loop; E -> F -> G
1009  for (int flux_dim=0; flux_dim<dim; ++flux_dim)
1010  {
1011  /* A) mixture density equations */
1012  conv_flux[0][flux_dim] = conservative_soln[1+flux_dim];
1013 
1014  /* B) mixture momentum equations */
1015  for (int velocity_dim=0; velocity_dim<dim; ++velocity_dim)
1016  {
1017  conv_flux[1+velocity_dim][flux_dim] = mixture_density*vel[flux_dim]*vel[velocity_dim];
1018  }
1019  conv_flux[1+flux_dim][flux_dim] += mixture_pressure; // Add diagonal of pressure
1020 
1021  /* C) mixture energy equations */
1022  conv_flux[dim+1][flux_dim] = mixture_density*vel[flux_dim]*mixture_specific_total_enthalpy;
1023 
1024  /* D) species density equations */
1025  for (int s=0; s<nspecies-1; ++s)
1026  {
1027  conv_flux[dim+2+s][flux_dim] = species_densities[s]*vel[flux_dim];
1028  }
1029  }
1030 
1031  return conv_flux;
1032 }
1033 
1034 template <int dim, int nspecies, int nstate, typename real>
1035 dealii::Tensor<2,nstate,real> RealGas<dim,nspecies,nstate,real>
1037  const std::array<real,nstate> &conservative_soln,
1038  const dealii::Tensor<1,dim,real> &normal) const
1039 {
1040  // Real Gas version of function in Euler
1041  const dealii::Tensor<1,dim,real> vel = compute_velocities(conservative_soln);
1042  real vel_normal = 0.0;
1043  for (int d=0;d<dim;d++) { vel_normal += vel[d] * normal[d]; }
1044 
1045  const real gam = compute_gamma(conservative_soln);
1046  const real gamm1 = gam - 1.0;
1047  const real vel2 = compute_velocity_squared_from_conservative_solution(conservative_soln);
1048  const real phi = 0.5*gamm1 * vel2;
1049 
1050  const real density = conservative_soln[0];
1051  const real tot_energy = conservative_soln[dim+1];
1052  const real E = tot_energy / density;
1053  const real a1 = gam*E-phi;
1054  const real a2 = gamm1;
1055  const real a3 = gam-2.0;
1056 
1057  dealii::Tensor<2,nstate,real> jacobian;
1058  for (int d=0; d<dim; ++d) {
1059  jacobian[0][1+d] = normal[d];
1060  }
1061  for (int row_dim=0; row_dim<dim; ++row_dim) {
1062  jacobian[1+row_dim][0] = normal[row_dim]*phi - vel[row_dim] * vel_normal;
1063  for (int col_dim=0; col_dim<dim; ++col_dim){
1064  if (row_dim == col_dim) {
1065  jacobian[1+row_dim][1+col_dim] = vel_normal - a3*normal[row_dim]*vel[row_dim];
1066  } else {
1067  jacobian[1+row_dim][1+col_dim] = normal[col_dim]*vel[row_dim] - a2*normal[row_dim]*vel[col_dim];
1068  }
1069  }
1070  jacobian[1+row_dim][dim+1] = normal[row_dim]*a2;
1071  }
1072  jacobian[dim+1][0] = vel_normal*(phi-a1);
1073  for (int d=0; d<dim; ++d){
1074  jacobian[dim+1][1+d] = normal[d]*a1 - a2*vel[d]*vel_normal;
1075  }
1076  jacobian[dim+1][dim+1] = gam*vel_normal;
1077 
1078  return jacobian;
1079 }
1080 
1082 template <int dim, int nspecies, int nstate, typename real>
1083 std::array<dealii::Tensor<1,dim,real>,nstate> RealGas<dim, nspecies, nstate, real>
1084 ::convective_numerical_split_flux(const std::array<real,nstate> &conservative_soln1,
1085  const std::array<real,nstate> &conservative_soln2) const
1086 {
1087  std::array<dealii::Tensor<1,dim,real>,nstate> conv_num_split_flux;
1088  if(two_point_num_flux_type == two_point_num_flux_enum::KG) {
1089  conv_num_split_flux = convective_numerical_split_flux_kennedy_gruber(conservative_soln1, conservative_soln2);
1090  } else if(two_point_num_flux_type == two_point_num_flux_enum::IR) {
1091  std::cout << "The Ismail Roe two-point flux has not been implemented for multispecies...Aborting." << std::endl;
1092  std::abort();
1093  } else if(two_point_num_flux_type == two_point_num_flux_enum::CH) {
1094  std::cout << "The Chandrashekar two-point flux has not been implemented for multispecies...Aborting." << std::endl;
1095  std::abort();
1096  } else if(two_point_num_flux_type == two_point_num_flux_enum::Ra) {
1097  std::cout << "The Ranocha Fix for the Chandrashekar two-point flux has not been implemented for multispecies...Aborting." << std::endl;
1098  std::abort();
1099  }
1100 
1101  return conv_num_split_flux;
1102 }
1103 
1104 template <int dim, int nspecies, int nstate, typename real>
1105 std::array<dealii::Tensor<1,dim,real>,nstate> RealGas<dim, nspecies, nstate, real>
1106 ::convective_numerical_split_flux_kennedy_gruber(const std::array<real,nstate> &conservative_soln1,
1107  const std::array<real,nstate> &conservative_soln2) const
1108 {
1109  std::array<dealii::Tensor<1,dim,real>,nstate> conv_num_split_flux;
1110  const std::array<real,nspecies> rho_species1 = compute_species_densities(conservative_soln1);
1111  const std::array<real,nspecies> rho_species2 = compute_species_densities(conservative_soln2);
1112 
1113  // compute mean densities
1114  std::array<real, nspecies> mean_species_densities;
1115  real mean_density = 0.0;
1116  for (int ispecies = 0; ispecies < nspecies; ++ispecies) {
1117  mean_species_densities[ispecies] = (rho_species1[ispecies]+rho_species2[ispecies])/2.0;
1118  mean_density += mean_species_densities[ispecies];
1119  }
1120 
1121  // compute mean velocities
1122  dealii::Tensor<1,dim,real> vel_1 = compute_velocities(conservative_soln1);
1123  dealii::Tensor<1,dim,real> vel_2 = compute_velocities(conservative_soln2);
1124  dealii::Tensor<1,dim,real> mean_vel;
1125  for (int d=0; d<dim; ++d) {
1126  mean_vel[d] = 0.5*(vel_1[d]+vel_2[d]);
1127  }
1128 
1129  // compute mean pressure
1130  real pressure1 = compute_mixture_pressure(conservative_soln1);
1131  real pressure2 = compute_mixture_pressure(conservative_soln2);
1132  real mean_pressure = (pressure1 + pressure2)/2.0;
1133  // this->pcout << "the calculated mean pressure is: " << mean_pressure << std::endl;
1134 
1135  // compute mean total energy
1136  real total_energy1 = compute_mixture_specific_total_energy(conservative_soln1);
1137  real total_energy2 = compute_mixture_specific_total_energy(conservative_soln2);
1138  real mean_total_energy = (total_energy1 + total_energy2)/2.0;
1139 
1140  for (int flux_dim = 0; flux_dim < dim; ++flux_dim)
1141  {
1142  // Density equation
1143  conv_num_split_flux[0][flux_dim] = mean_density * mean_vel[flux_dim];
1144  // Momentum equation
1145  for (int velocity_dim=0; velocity_dim<dim; ++velocity_dim){
1146  conv_num_split_flux[1+velocity_dim][flux_dim] = mean_density*mean_vel[flux_dim]*mean_vel[velocity_dim];
1147  }
1148  conv_num_split_flux[1+flux_dim][flux_dim] += mean_pressure; // Add diagonal of pressure
1149  // Energy equation
1150  conv_num_split_flux[dim+1][flux_dim] = mean_density*mean_vel[flux_dim]*mean_total_energy + mean_pressure * mean_vel[flux_dim];
1151  // Species density equation
1152  for (int ispecies = 0; ispecies < nspecies - 1; ++ispecies) {
1153  conv_num_split_flux[dim+2+ispecies][flux_dim] = mean_species_densities[ispecies] * mean_vel[flux_dim];
1154  }
1155  }
1156 
1157  return conv_num_split_flux;
1158 }
1159 
1160 /* Supporting FUNCTIONS */
1161 // Algorithm 20 (f_S20): Convert primitive to conservative
1162 template <int dim, int nspecies, int nstate, typename real>
1163 inline std::array<real,nstate> RealGas<dim,nspecies,nstate,real>
1164 ::convert_primitive_to_conservative ( const std::array<real,nstate> &primitive_soln ) const
1165 {
1166  /* definitions */
1167  std::array<real, nstate> conservative_soln;
1168  const real mixture_density = compute_mixture_density(primitive_soln);
1169  std::array<real, dim> vel;
1170 
1171  real vel2 = 0.0;
1172  real sum = 0.0;
1173  std::array<real,nspecies> species_densities;
1174  std::array<real,nspecies> mass_fractions;
1175  const real mixture_pressure = primitive_soln[dim+1];
1176 
1177  /* mixture density */
1178  conservative_soln[0] = mixture_density;
1179 
1180  /* mixture momentum */
1181  for (int d=0; d<dim; ++d)
1182  {
1183  vel[d] = primitive_soln[1+d];
1184  vel2 = vel2 + vel[d]*vel[d]; ;
1185  conservative_soln[1+d] = mixture_density*vel[d];
1186  }
1187 
1188  /* mixture energy */
1189  // mass fractions
1190  for (int s=0; s<nspecies-1; ++s)
1191  {
1192  mass_fractions[s] = primitive_soln[dim+2+s];
1193  sum += mass_fractions[s];
1194  }
1195  mass_fractions[nspecies-1] = 1.00 - sum;
1196  // species densities
1197  for (int s=0; s<nspecies; ++s)
1198  {
1199  species_densities[s] = mixture_density*mass_fractions[s];
1200  }
1201  // mixturegas constant
1202  const real mixture_gas_constant = compute_mixture_from_species(mass_fractions,this->Rs);
1203  // temperature
1204  const real temperature = mixture_pressure/(mixture_density*mixture_gas_constant) * (this->u_ref_sqr/(this->R_ref*this->temperature_ref));
1205  // specific kinetic energy
1206  const real specific_kinetic_energy = 0.50*vel2;
1207  // species specific enthalpy
1208  const std::array<real,nspecies> species_specific_enthalpy = compute_species_specific_enthalpy(temperature);
1209  // mixture enthalpy
1210  const real mixture_specific_enthalpy = compute_mixture_from_species(mass_fractions,species_specific_enthalpy);
1211  // mixture specific internal energy
1212  const real mixture_specific_internal_energy = mixture_specific_enthalpy - mixture_pressure/mixture_density;
1213  // mixture specific total energy
1214  const real mixture_specific_total_energy = mixture_specific_internal_energy + specific_kinetic_energy;
1215 
1216  // mixture energy
1217  conservative_soln[dim+1] = mixture_density*mixture_specific_total_energy;
1218 
1219  /* species densities */
1220  for (int s=0; s<nspecies-1; ++s)
1221  {
1222  conservative_soln[dim+2+s] = species_densities[s];
1223  }
1224 
1225  return conservative_soln;
1226 }
1227 
1228 // Algorithm 20b : Convert conservative to primitive
1229 // This function has been added by Shruthi
1230 template <int dim, int nspecies, int nstate, typename real>
1231 inline std::array<real,nstate> RealGas<dim,nspecies,nstate,real>
1232 ::convert_conservative_to_primitive ( const std::array<real,nstate> &conservative_soln ) const
1233 {
1234  /* definitions */
1235  std::array<real, nstate> primitive_soln;
1236  primitive_soln[0] = conservative_soln[0];
1237 
1238  const dealii::Tensor<1,dim,real> vel = compute_velocities(conservative_soln);
1239  for (int idim = 0; idim < dim; ++idim) {
1240  primitive_soln[idim+1] = vel[idim];
1241  }
1242 
1243  primitive_soln[dim+1] = compute_mixture_pressure(conservative_soln);
1244 
1245  const std::array<real,nspecies> mass_fractions = compute_mass_fractions(conservative_soln);
1246  for(int ispecies = 0; ispecies < nspecies-1; ++ispecies) {
1247  primitive_soln[dim+2+ispecies] = mass_fractions[ispecies];
1248  }
1249 
1250  return primitive_soln;
1251 }
1252 
1253 template <int dim, int nspecies, int nstate, typename real>
1254 std::array<dealii::Tensor<1,dim,real>,nstate> RealGas<dim,nspecies,nstate,real>
1256  const std::array<real,nstate> &/*primitive_soln*/,
1257  const std::array<dealii::Tensor<1,dim,real>,nstate> &primitive_soln_gradient) const
1258 {
1259  this->pcout << "WARNING: convert_primitive_gradient_to_conservative_gradient() is not defined for current physics." << std::endl;
1260  this->pcout << "Aborting..." << std::endl;
1261  std::abort();
1262  return primitive_soln_gradient;
1263 }
1264 
1265 template <int dim, int nspecies, int nstate, typename real>
1266 std::array<dealii::Tensor<1,dim,real>,nstate> RealGas<dim,nspecies,nstate,real>
1268  const std::array<real,nstate> &/*conservative_soln*/,
1269  const std::array<dealii::Tensor<1,dim,real>,nstate> &conservative_soln_gradient) const
1270 {
1271  this->pcout << "WARNING: convert_conservative_gradient_to_primitive_gradient() is not defined for current physics." << std::endl;
1272  this->pcout << "Aborting..." << std::endl;
1273  std::abort();
1274  return conservative_soln_gradient;
1275 }
1276 
1277 // Algorithm 21 (f_S21): Compute species specific heat ratio
1278 template <int dim, int nspecies, int nstate, typename real>
1279 inline std::array<real,nspecies> RealGas<dim,nspecies,nstate,real>
1280 ::compute_species_specific_heat_ratio ( const std::array<real,nstate> &conservative_soln ) const
1281 {
1282  const real temperature = compute_temperature(conservative_soln);
1283  const std::array<real,nspecies> Cp = compute_species_specific_Cp(temperature);
1284  const std::array<real,nspecies> Cv = compute_species_specific_Cv(temperature);
1285  std::array<real,nspecies> gamma;
1286 
1287  for (int s=0; s<nspecies; ++s)
1288  {
1289  gamma[s] = Cp[s]/Cv[s];
1290  }
1291 
1292  return gamma;
1293 }
1294 
1295 template <int dim, int nspecies, int nstate, typename real>
1297 ::compute_gamma ( const std::array<real,nstate> &conservative_soln ) const
1298 {
1299  // Uses the definition given in Gouasmi thesis
1300  const real temperature = compute_temperature(conservative_soln);
1301  const std::array<real,nspecies> mass_fractions = compute_mass_fractions(conservative_soln);
1302  const std::array<real,nspecies> Cp = compute_species_specific_Cp(temperature);
1303  const std::array<real,nspecies> Cv = compute_species_specific_Cv(temperature);
1304 
1305  real mixture_Cp = compute_mixture_from_species(mass_fractions,Cp);
1306  real mixture_Cv = compute_mixture_from_species(mass_fractions,Cv);
1307 
1308  real gamma = mixture_Cp/mixture_Cv;
1309  return gamma;
1310 }
1311 
1312 // Algorithm 22 (f_S22): Compute species speed of sound
1313 template <int dim, int nspecies, int nstate, typename real>
1314 inline std::array<real,nspecies> RealGas<dim,nspecies,nstate,real>
1315 ::compute_species_speed_of_sound ( const std::array<real,nstate> &conservative_soln ) const
1316 {
1317  const real temperature = compute_temperature(conservative_soln);
1318  const std::array<real,nspecies> gamma = compute_species_specific_heat_ratio(conservative_soln);
1319  const std::array<real,nspecies> Rs = compute_Rs(this->Ru);
1320  std::array<real,nspecies> speed_of_sound;
1321  for (int s=0; s<nspecies; ++s)
1322  {
1323  speed_of_sound[s] = sqrt(gamma[s]*Rs[s]*temperature/(this->mach_ref_sqr));
1324  }
1325 
1326  return speed_of_sound;
1327 }
1328 
1329 template <int dim, int nspecies, int nstate, typename real>
1331 ::compute_sound ( const std::array<real,nstate> &conservative_soln ) const
1332 {
1333  // This is the appropriate method for deriving mixture
1334  // speed of sound for thermally perfect gas as per
1335  // Hypersonic and High Temperature Gas Dynamics, 2nd Ed.
1336  // John D. Anderson
1337  // Chapter 14.7 Eqn 14.53
1338  const real R_mix = compute_mixture_gas_constant(conservative_soln);
1339  const real temperature = compute_temperature(conservative_soln);
1340  const real gamma = compute_gamma(conservative_soln);
1341 
1342  const real sound = sqrt(gamma*R_mix*temperature/(this->mach_ref_sqr));
1343 
1344  return sound;
1345 }
1346 
1347 // Compute mixture solution vector (without species solution)
1348 template <int dim, int nspecies, int nstate, typename real>
1349 inline std::array<real,dim+2> RealGas<dim,nspecies,nstate,real>
1350 ::get_mixture_solution_vector ( const std::array<real,nstate> &full_soln ) const
1351 {
1352  /* definitions */
1353  std::array<real, dim+2> mixture_soln;
1354  for (int s=0; s<(dim+2); ++s)
1355  {
1356  mixture_soln[s] = full_soln[s];
1357  }
1358  return mixture_soln;
1359 }
1360 
1361 // Compute mixture gradient
1362 template <int dim, int nspecies, int nstate, typename real>
1363 std::array<dealii::Tensor<1,dim,real>,dim+2> RealGas<dim,nspecies,nstate,real>
1365  const std::array<dealii::Tensor<1,dim,real>,nstate> &conservative_soln_gradient) const
1366 {
1367  std::array<dealii::Tensor<1,dim,real>,dim+2> mixture_soln_gradient;
1368  for (int d1=0; d1<dim; d1++) {
1369  mixture_soln_gradient[0][d1] = conservative_soln_gradient[0][d1];
1370  for (int d2=0; d2<dim; d2++) {
1371  mixture_soln_gradient[1+d1][d2] = conservative_soln_gradient[1+d2][d1];
1372  }
1373  mixture_soln_gradient[dim+1][d1] = conservative_soln_gradient[dim+1][d1];
1374  }
1375  return mixture_soln_gradient;
1376 }
1377 
1378 template <int dim, int nspecies, int nstate, typename real>
1380  const dealii::Vector<double> &uh,
1381  const std::vector<dealii::Tensor<1,dim> > &duh,
1382  const std::vector<dealii::Tensor<2,dim> > &dduh,
1383  const dealii::Tensor<1,dim> &normals,
1384  const dealii::Point<dim> &evaluation_points) const
1385 {
1386  std::vector<std::string> names = post_get_names ();
1387  dealii::Vector<double> computed_quantities = PhysicsBase<dim,nspecies,nstate,real>::post_compute_derived_quantities_vector ( uh, duh, dduh, normals, evaluation_points);
1388  unsigned int current_data_index = computed_quantities.size() - 1;
1389  computed_quantities.grow_or_shrink(names.size());
1390  if constexpr (std::is_same<real,double>::value) {
1391  // get the solution
1392  std::array<double, nstate> conservative_soln;
1393  for (unsigned int s=0; s<nstate; ++s) {
1394  conservative_soln[s] = uh(s);
1395  }
1396 
1397  // get the solution gradient
1398  std::array<dealii::Tensor<1,dim,double>,nstate> conservative_soln_gradient;
1399  for (unsigned int s=0; s<nstate; ++s) {
1400  for (unsigned int d=0; d<dim; ++d) {
1401  conservative_soln_gradient[s][d] = duh[s][d];
1402  }
1403  }
1404 
1405  // Mixture density
1406  computed_quantities(++current_data_index) = compute_mixture_density(conservative_soln);
1407  // Velocities
1408  const dealii::Tensor<1,dim,real> vel = compute_velocities(conservative_soln);
1409  for (unsigned int d=0; d<dim; ++d) {
1410  computed_quantities(++current_data_index) = vel[d];
1411  }
1412  // Mixture momentum
1413  for (unsigned int d=0; d<dim; ++d) {
1414  computed_quantities(++current_data_index) = conservative_soln[1+d];
1415  }
1416  // Mixture energy
1417  computed_quantities(++current_data_index) = compute_mixture_specific_total_energy(conservative_soln);
1418  // Mixture pressure
1419  computed_quantities(++current_data_index) = compute_mixture_pressure(conservative_soln);
1420  // Non-dimensional temperature
1421  computed_quantities(++current_data_index) = compute_temperature(conservative_soln);
1422  // Dimensional temperature
1423  computed_quantities(++current_data_index) = compute_dimensional_temperature(compute_temperature(conservative_soln));
1424  // Mixture specific total enthalpy
1425  computed_quantities(++current_data_index) = compute_mixture_specific_total_enthalpy(conservative_soln);
1426  // Mass fractions
1427  const std::array<real,nspecies> mass_fractions = compute_mass_fractions(conservative_soln);
1428  for (unsigned int s=0; s<nspecies; ++s)
1429  {
1430  computed_quantities(++current_data_index) = mass_fractions[s];
1431  }
1432  // Species densities
1433  const std::array<real,nspecies> species_densities = compute_species_densities(conservative_soln);
1434  for (unsigned int s=0; s<nspecies; ++s)
1435  {
1436  computed_quantities(++current_data_index) = species_densities[s];
1437  }
1438  }
1439  if (computed_quantities.size()-1 != current_data_index) {
1440  this->pcout << " Did not assign a value to all the data. Missing " << computed_quantities.size() - current_data_index << " variables."
1441  << " If you added a new output variable, make sure the names and DataComponentInterpretation match the above. "
1442  << std::endl;
1443  }
1444 
1445  return computed_quantities;
1446 }
1447 
1448 template <int dim, int nspecies, int nstate, typename real>
1449 std::vector<dealii::DataComponentInterpretation::DataComponentInterpretation> RealGas<dim,nspecies,nstate,real>
1451 {
1452  namespace DCI = dealii::DataComponentInterpretation;
1453  std::vector<DCI::DataComponentInterpretation> interpretation = PhysicsBase<dim,nspecies,nstate,real>::post_get_data_component_interpretation (); // state variables
1454  interpretation.push_back (DCI::component_is_scalar); // Mixture density
1455  for (unsigned int d=0; d<dim; ++d) {
1456  interpretation.push_back (DCI::component_is_part_of_vector); // Velocity
1457  }
1458  for (unsigned int d=0; d<dim; ++d) {
1459  interpretation.push_back (DCI::component_is_part_of_vector); // Mixture momentum
1460  }
1461  interpretation.push_back (DCI::component_is_scalar); // Mixture energy
1462  interpretation.push_back (DCI::component_is_scalar); // Mixture pressure
1463  interpretation.push_back (DCI::component_is_scalar); // Non-dimensional temperature
1464  interpretation.push_back (DCI::component_is_scalar); // Dimensional temperature
1465  interpretation.push_back (DCI::component_is_scalar); // Mixture specific total enthalpy
1466  for (unsigned int s=0; s<nspecies; ++s) {
1467  interpretation.push_back (DCI::component_is_scalar); // Mass fractions
1468  }
1469  for (unsigned int s=0; s<nspecies; ++s) {
1470  interpretation.push_back (DCI::component_is_scalar); // Species densities
1471  }
1472 
1473  std::vector<std::string> names = post_get_names();
1474  if (names.size() != interpretation.size()) {
1475  this->pcout << "Number of DataComponentInterpretation is not the same as number of names for output file" << std::endl;
1476  }
1477  return interpretation;
1478 }
1479 
1480 template <int dim, int nspecies, int nstate, typename real>
1481 std::vector<std::string> RealGas<dim,nspecies,nstate,real>
1483 {
1484  std::vector<std::string> names = PhysicsBase<dim,nspecies,nstate,real>::post_get_names ();
1485  names.push_back ("mixture_density");
1486  for (unsigned int d=0; d<dim; ++d) {
1487  names.push_back ("velocity");
1488  }
1489  for (unsigned int d=0; d<dim; ++d) {
1490  names.push_back ("mixture_momentum");
1491  }
1492  names.push_back ("mixture_energy");
1493  names.push_back ("mixture_pressure");
1494  names.push_back ("temperature");
1495  names.push_back ("dimensional_temperature");
1496  names.push_back ("mixture_specific_total_enthalpy");
1497  for (unsigned int s=0; s<nspecies; ++s)
1498  {
1499  std::string string_mass_fraction = "mass_fraction";
1500  std::string string_species_mass_fraction = string_mass_fraction + "_" + this->species_name[s];
1501  names.push_back (string_species_mass_fraction);
1502  }
1503  for (unsigned int s=0; s<nspecies; ++s)
1504  {
1505  std::string string_density = "species_density";
1506  std::string string_species_density = string_density + "_" + this->species_name[s];
1507  names.push_back (string_species_density);
1508  }
1509 
1510  return names;
1511 }
1512 
1513 template <int dim, int nspecies, int nstate, typename real>
1514 dealii::UpdateFlags RealGas<dim,nspecies,nstate,real>
1516 {
1517  return dealii::update_values
1518  | dealii::update_gradients
1519  | dealii::update_quadrature_points;
1520 }
1521 
1522 // Instantiate explicitly
1528 } // Physics namespace
1529 } // PHiLiP namespace
RealGas(const Parameters::AllParameters *const parameters_input, std::shared_ptr< ManufacturedSolutionFunction< dim, nspecies, real > > manufactured_solution_function=nullptr, const bool has_nonzero_diffusion=false, const bool has_nonzero_physical_source=false)
Constructor.
Definition: real_gas.cpp:15
std::array< std::array< std::array< double, 3 >, 9 >, nspecies > NASACAPCoeffs
Variables to store NASA Coefficients.
Definition: real_gas.h:314
RealGas equations. Derived from PhysicsBase.
Definition: real_gas.h:18
real max_viscous_eigenvalue(const std::array< real, nstate > &soln) const
Maximum viscous eigenvalue.
Definition: real_gas.cpp:212
std::string chemistry_input_file
Name of file containing NASA CAP data for species.
std::array< real, nstate > compute_entropy_variables(const std::array< real, nstate > &conservative_soln) const
Computes the entropy variables.
Definition: real_gas.cpp:744
Base class from which Advection, Diffusion, ConvectionDiffusion, and Euler is derived.
Definition: physics.h:34
virtual std::array< real, nstate > compute_kinetic_energy_variables(const std::array< real, nstate > &conservative_soln) const
Computes the kinetic energy variables.
Definition: real_gas.cpp:844
Manufactured solution used for grid studies to check convergence orders.
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: real_gas.cpp:221
virtual dealii::Vector< double > post_compute_derived_quantities_vector(const dealii::Vector< double > &uh, const std::vector< dealii::Tensor< 1, dim > > &, const std::vector< dealii::Tensor< 2, dim > > &, const dealii::Tensor< 1, dim > &, const dealii::Point< dim > &) const
Returns current vector solution to be used by PhysicsPostprocessor to output current solution...
Definition: physics.cpp:266
real compute_entropy(const std::array< real, nstate > &conservative_soln) const
Compute entropy from conservative solution.
Definition: real_gas.cpp:707
Files for the baseline physics.
Definition: ADTypes.hpp:10
void readspeciesdata(std::string reactionFilename)
Reads in data from chemistry file.
Definition: real_gas.cpp:45
virtual real compute_temperature(const std::array< real, nstate > &conservative_soln) const
Definition: real_gas.cpp:867
virtual real compute_pressure(const std::array< real, nstate > &conservative_soln) const
Compute pressure from conservative solution.
Definition: real_gas.cpp:969
real compute_sound(const std::array< real, nstate > &conservative_soln) const
Evaluate speed of sound from conservative variables.
Definition: real_gas.cpp:1331
virtual dealii::Vector< double > post_compute_derived_quantities_vector(const dealii::Vector< double > &uh, const std::vector< dealii::Tensor< 1, dim > > &duh, const std::vector< dealii::Tensor< 2, dim > > &dduh, const dealii::Tensor< 1, dim > &normals, const dealii::Point< dim > &evaluation_points) const
For post processing purposes (update comment later)
Definition: real_gas.cpp:1379
virtual std::array< real, nstate > convert_conservative_to_primitive(const std::array< real, nstate > &conservative_soln) const
Convert conservative variables to primitive variables.
Definition: real_gas.cpp:1232
virtual std::array< real, nstate > convert_primitive_to_conservative(const std::array< real, nstate > &primitive_soln) const
Convert primitive solution to conservative solution.
Definition: real_gas.cpp:1164
const double tol
tolerance for NRM (Newton-raphson Method) [m/s]
Definition: real_gas.h:54
const two_point_num_flux_enum two_point_num_flux_type
Two point numerical flux type (for split form)
Definition: real_gas.h:45
const double R_ref
reference gas constant: [J/(kg·K)]
Definition: real_gas.h:50
Main parameter class that contains the various other sub-parameter classes.
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: real_gas.cpp:1255
const double density_ref
reference mixture density: [kg/m^3]
Definition: real_gas.h:55
const double Ru
universal gas constant: [J/(mol·K)]
Definition: real_gas.h:48
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: real_gas.cpp:166
std::array< dealii::Tensor< 1, dim, real >, nstate > convective_flux(const std::array< real, nstate > &conservative_soln) const
Convective fluxes that will be differentiated once in space.
Definition: real_gas.cpp:998
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
Evaluates convective flux based on the chosen split form.
Definition: real_gas.cpp:1084
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: real_gas.cpp:236
const double gam_ref
reference gamma
Definition: real_gas.h:40
std::array< dealii::Tensor< 1, dim, real >, dim+2 > get_mixture_solution_gradient(const std::array< dealii::Tensor< 1, dim, real >, nstate > &conservative_soln_gradient) const
returns the solution gradient vector without the species conservation states (only mixture) ...
Definition: real_gas.cpp:1364
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: real_gas.cpp:774
std::array< dealii::Tensor< 1, dim, real >, nstate > convective_numerical_split_flux_kennedy_gruber(const std::array< real, nstate > &conservative_soln1, const std::array< real, nstate > &conservative_soln2) const
Definition: real_gas.cpp:1106
real max_convective_eigenvalue(const std::array< real, nstate > &soln) const
Maximum convective eigenvalue.
Definition: real_gas.cpp:183
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
Boundary condition handler.
Definition: real_gas.cpp:316
std::array< real, nspecies > compute_species_entropy_cv_integral(const real temperature) const
Definition: real_gas.cpp:629
dealii::Tensor< 1, dim, real > extract_velocities_from_primitive(const std::array< real, nstate > &primitive_soln) const
Given primitive variables, returns velocities.
Definition: real_gas.cpp:390
dealii::ConditionalOStream pcout
ConditionalOStream.
Definition: physics.h:285
virtual std::vector< std::string > post_get_names() const
For post processing purposes, sets the base names (with no prefix or suffix) of the computed quantiti...
Definition: real_gas.cpp:1482
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: real_gas.cpp:1267
const double u_ref_sqr
reference velocity squared[m/s]^2
Definition: real_gas.h:53
real max_convective_normal_eigenvalue(const std::array< real, nstate > &soln, const dealii::Tensor< 1, dim, real > &normal) const override
Maximum convective normal eigenvalue (used in Lax-Friedrichs)
Definition: real_gas.cpp:195
void boundary_slip_wall(const dealii::Tensor< 1, dim, real > &normal_int, const std::array< real, nstate > &soln_int, const std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_int, std::array< real, nstate > &soln_bc, std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_bc) const
Definition: real_gas.cpp:264
const double mach_ref_sqr
reference mach number (Farfield Mach number squared)
Definition: real_gas.h:44
const double temperature_ref
reference temperature [K]
Definition: real_gas.h:51
virtual std::vector< dealii::DataComponentInterpretation::DataComponentInterpretation > post_get_data_component_interpretation() const
For post processing purposes, sets the interpretation of each computed quantity as either scalar or v...
Definition: real_gas.cpp:1450
virtual real compute_gamma(const std::array< real, nstate > &conservative_soln) const
Compute gamma from conservative solution.
Definition: real_gas.cpp:1297
virtual std::vector< dealii::DataComponentInterpretation::DataComponentInterpretation > post_get_data_component_interpretation() const
Returns DataComponentInterpretation of the solution to be used by PhysicsPostprocessor to output curr...
Definition: physics.cpp:309
virtual void boundary_wall(const dealii::Tensor< 1, dim, real > &normal_int, const std::array< real, nstate > &soln_int, const std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_int, std::array< real, nstate > &soln_bc, std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_bc) const
Wall boundary condition.
Definition: real_gas.cpp:251
virtual std::vector< std::string > post_get_names() const
Returns names of the solution to be used by PhysicsPostprocessor to output current solution...
Definition: physics.cpp:297
std::array< int, nspecies > GetNASACAP_TemperatureIndex(const real temperature) const
Determine the.
Definition: real_gas.cpp:122
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: real_gas.cpp:1036
virtual dealii::UpdateFlags post_get_needed_update_flags() const
For post processing purposes (update comment later)
Definition: real_gas.cpp:1515
std::array< real, nspecies > compute_species_specific_enthalpy(const real temperature) const
Definition: real_gas.cpp:552
real compute_pressure_from_density_temperature(const real density, const real temperature, const std::array< real, nstate > &conservative_soln) const
Given density and temperature, returns NON-DIMENSIONALIZED pressure using free-stream non-dimensional...
Definition: real_gas.cpp:975
std::array< real, dim+2 > get_mixture_solution_vector(const std::array< real, nstate > &full_soln) const
returns the solution vector without the species conservation states (only mixture) ...
Definition: real_gas.cpp:1350