[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
initial_condition_function.cpp
1 #include <deal.II/base/function.h>
2 #include "initial_condition_function.h"
3 // For initial conditions which need to refer to physics
4 #include "physics/physics_factory.h"
5 
6 namespace PHiLiP {
7 
8 // =========================================================
9 // Initial Condition Base Class
10 // =========================================================
11 template <int dim, int nstate, typename real>
14  : dealii::Function<dim,real>(nstate)//,0.0) // 0.0 denotes initial time (t=0)
15 {
16  // Nothing to do here yet
17 }
18 
19 // ========================================================
20 // TAYLOR GREEN VORTEX -- Initial Condition (Uniform density)
21 // ========================================================
22 template <int dim, int nstate, typename real>
25  Parameters::AllParameters const *const param)
26  : InitialConditionFunction_EulerBase<dim, nstate, real>(param)
27  , gamma_gas(param->euler_param.gamma_gas)
28  , mach_inf(param->euler_param.mach_inf)
29  , mach_inf_sqr(mach_inf*mach_inf)
30 {}
31 template <int dim, int nstate, typename real>
33 ::primitive_value(const dealii::Point<dim,real> &point, const unsigned int istate) const
34 {
35  // Note: This is in non-dimensional form (free-stream values as reference)
36  real value = 0.;
37  if constexpr(dim == 3) {
38  const real x = point[0], y = point[1], z = point[2];
39 
40  if(istate==0) {
41  // density
42  value = this->density(point);
43  }
44  if(istate==1) {
45  // x-velocity
46  value = sin(x)*cos(y)*cos(z);
47  }
48  if(istate==2) {
49  // y-velocity
50  value = -cos(x)*sin(y)*cos(z);
51  }
52  if(istate==3) {
53  // z-velocity
54  value = 0.0;
55  }
56  if(istate==4) {
57  // pressure
58  value = 1.0/(this->gamma_gas*this->mach_inf_sqr) + (1.0/16.0)*(cos(2.0*x)+cos(2.0*y))*(cos(2.0*z)+2.0);
59  }
60  }
61  return value;
62 }
63 
64 template <int dim, int nstate, typename real>
66 ::density(const dealii::Point<dim,real> &/*point*/) const
67 {
68  // Note: This is in non-dimensional form (free-stream values as reference)
69  real value = 0.;
70  // density
71  value = 1.0;
72  return value;
73 }
74 
75 // ========================================================
76 // TAYLOR GREEN VORTEX -- Initial Condition (Isothermal density)
77 // ========================================================
78 template <int dim, int nstate, typename real>
81  Parameters::AllParameters const *const param)
82  : InitialConditionFunction_TaylorGreenVortex<dim,nstate,real>(param)
83 {}
84 
85 template <int dim, int nstate, typename real>
87 ::density(const dealii::Point<dim,real> &point) const
88 {
89  // Note: This is in non-dimensional form (free-stream values as reference)
90  real value = 0.;
91  // density
92  value = this->primitive_value(point, 4); // get pressure
93  value *= this->gamma_gas*this->mach_inf_sqr;
94  return value;
95 }
96 
97 // ========================================================
98 // 1D BURGERS REWIENSKI -- Initial Condition
99 // ========================================================
100 template <int dim, int nstate, typename real>
103  : InitialConditionFunction<dim,nstate,real>()
104 {
105  // Nothing to do here yet
106 }
107 
108 template <int dim, int nstate, typename real>
110 ::value(const dealii::Point<dim,real> &/*point*/, const unsigned int /*istate*/) const
111 {
112  real value = 1.0;
113  return value;
114 }
115 
116 // ========================================================
117 // 1D BURGERS VISCOUS -- Initial Condition
118 // ========================================================
119 template <int dim, int nstate, typename real>
122  : InitialConditionFunction<dim,nstate,real>()
123 {
124  // Nothing to do here yet
125 }
126 
127 template <int dim, int nstate, typename real>
129 ::value(const dealii::Point<dim,real> &point, const unsigned int /*istate*/) const
130 {
131  real value = 0;
132  if(point[0] >= 0 && point[0] <= 0.25){
133  value = sin(4*dealii::numbers::PI*point[0]);
134  }
135  return value;
136 
137 }
138 
139 // ========================================================
140 // 1D BURGERS Inviscid -- Initial Condition
141 // ========================================================
142 template <int dim, int nstate, typename real>
145  : InitialConditionFunction<dim,nstate,real>()
146 {
147  // Nothing to do here yet
148 }
149 
150 template <int dim, int nstate, typename real>
152 ::value(const dealii::Point<dim,real> &point, const unsigned int /*istate*/) const
153 {
154  real value = 1.0;
155  if constexpr(dim >= 1)
156  value *= cos(dealii::numbers::PI*point[0]);
157  if constexpr(dim >= 2)
158  value *= cos(dealii::numbers::PI*point[1]);
159  if constexpr(dim == 3)
160  value *= cos(dealii::numbers::PI*point[2]);
161 
162  return value;
163 }
164 
165 // ========================================================
166 // 1D BURGERS Inviscid Energy-- Initial Condition
167 // ========================================================
168 template <int dim, int nstate, typename real>
171  : InitialConditionFunction<dim,nstate,real>()
172 {
173  // Nothing to do here yet
174 }
175 
176 template <int dim, int nstate, typename real>
178 ::value(const dealii::Point<dim,real> &point, const unsigned int /*istate*/) const
179 {
180  real value = 1.0;
181  if constexpr(dim >= 1)
182  value *= sin(dealii::numbers::PI*point[0]);
183  if constexpr(dim >= 2)
184  value *= sin(dealii::numbers::PI*point[1]);
185  if constexpr(dim == 3)
186  value *= sin(dealii::numbers::PI*point[2]);
187 
188  value += 0.01;
189  return value;
190 }
191 
192 // ========================================================
193 // Advection -- Initial Condition
194 // ========================================================
195 template <int dim, int nstate, typename real>
198  : InitialConditionFunction<dim,nstate,real>()
199 {
200  // Nothing to do here yet
201 }
202 
203 template <int dim, int nstate, typename real>
205 ::value(const dealii::Point<dim,real> &point, const unsigned int /*istate*/) const
206 {
207  real value = 1.0;
208  if constexpr(dim >= 1)
209  value *= exp(-20.0*point[0]*point[0]);
210  if constexpr(dim >= 2)
211  value *= exp(-20.0*point[1]*point[1]);
212  if constexpr(dim == 3)
213  value *= exp(-20.0*point[2]*point[2]);
214 
215  return value;
216 }
217 
218 // ========================================================
219 // Advection OOA -- Initial Condition
220 // ========================================================
221 template <int dim, int nstate, typename real>
224  : InitialConditionFunction<dim,nstate,real>()
225 {
226  // Nothing to do here yet
227 }
228 
229 template <int dim, int nstate, typename real>
231 ::value(const dealii::Point<dim,real> &point, const unsigned int /*istate*/) const
232 {
233  real value = 1.0;
234  if constexpr(dim >= 1)
235  value *= sin(2.0*dealii::numbers::PI*point[0]);
236  if constexpr(dim >= 2)
237  value *= sin(2.0*dealii::numbers::PI*point[1]);
238  if constexpr(dim == 3)
239  value *= sin(2.0*dealii::numbers::PI*point[2]);
240 
241  return value;
242 }
243 
244 // ========================================================
245 // Convection_diffusion -- Initial Condition
246 // ========================================================
247 template <int dim, int nstate, typename real>
250  : InitialConditionFunction<dim,nstate,real>()
251 {
252  // Nothing to do here yet
253 }
254 
255 template <int dim, int nstate, typename real>
257 ::value(const dealii::Point<dim,real> &point, const unsigned int /*istate*/) const
258 {
259  real value = 1.0;
260  if constexpr(dim >= 1)
261  value *= sin(dealii::numbers::PI*point[0]);
262  if constexpr(dim >= 2)
263  value *= sin(dealii::numbers::PI*point[1]);
264  if constexpr(dim == 3)
265  value *= sin(dealii::numbers::PI*point[2]);
266 
267  return value;
268 }
269 
270 // ========================================================
271 // Convection_diffusion Energy -- Initial Condition
272 // ========================================================
273 template <int dim, int nstate, typename real>
276  : InitialConditionFunction<dim,nstate,real>()
277 {
278  // Nothing to do here yet
279 }
280 
281 template <int dim, int nstate, typename real>
283 ::value(const dealii::Point<dim,real> &point, const unsigned int /*istate*/) const
284 {
285  real value = 1.0;
286  if constexpr(dim >= 1)
287  value *= sin(dealii::numbers::PI*point[0]);
288  if constexpr(dim >= 2)
289  value *= sin(dealii::numbers::PI*point[1]);
290  if constexpr(dim == 3)
291  value *= sin(dealii::numbers::PI*point[2]);
292 
293  value += 0.1;
294 
295  return value;
296 }
297 
298 // ========================================================
299 // 1D SINE -- Initial Condition for advection_explicit_time_study
300 // ========================================================
301 template <int dim, int nstate, typename real>
304  : InitialConditionFunction<dim,nstate,real>()
305 {
306  // Nothing to do here yet
307 }
308 
309 template <int dim, int nstate, typename real>
311 ::value(const dealii::Point<dim,real> &point, const unsigned int /*istate*/) const
312 {
313  real value = 0;
314  real pi = dealii::numbers::PI;
315  if(point[0] >= 0.0 && point[0] <= 2.0){
316  value = sin(2*pi*point[0]/2.0);
317  }
318  return value;
319 }
320 
321 // ========================================================
322 // Inviscid Isentropic Vortex
323 // ========================================================
324 template <int dim, int nstate, typename real>
327  Parameters::AllParameters const *const param)
328  : InitialConditionFunction<dim,nstate,real>()
329 {
330  // Euler object; create using dynamic_pointer_cast and the create_Physics factory
331  // This test should only be used for Euler
332  this->euler_physics = std::dynamic_pointer_cast<Physics::Euler<dim,dim+2,double>>(
334 }
335 
336 template <int dim, int nstate, typename real>
338 ::value(const dealii::Point<dim,real> &point, const unsigned int istate) const
339 {
340  // Setting constants
341  const double pi = dealii::numbers::PI;
342  const double gam = 1.4;
343  const double M_infty = sqrt(2/gam);
344  const double R = 1;
345  const double sigma = 1;
346  const double beta = M_infty * 5 * sqrt(2.0)/4.0/pi * exp(1.0/2.0);
347  const double alpha = pi/4; //rad
348 
349  // Centre of the vortex at t=0
350  const double x0 = 0.0;
351  const double y0 = 0.0;
352  const double x = point[0] - x0;
353  const double y = point[1] - y0;
354 
355  const double Omega = beta * exp(-0.5/sigma/sigma* (x/R * x/R + y/R * y/R));
356  const double delta_Ux = -y/R * Omega;
357  const double delta_Uy = x/R * Omega;
358  const double delta_T = -(gam-1.0)/2.0 * Omega * Omega;
359 
360  // Primitive
361  std::array<real,nstate> soln_primitive;
362  soln_primitive[0] = pow((1 + delta_T), 1.0/(gam-1.0));
363  soln_primitive[1] = M_infty * cos(alpha) + delta_Ux;
364  soln_primitive[2] = M_infty * sin(alpha) + delta_Uy;
365  #if PHILIP_DIM==3
366  soln_primitive[3] = 0;
367  #endif
368  soln_primitive[nstate-1] = 1.0/gam*pow(1+delta_T, gam/(gam-1.0));
369 
370  const std::array<real,nstate> soln_conservative = this->euler_physics->convert_primitive_to_conservative(soln_primitive);
371  return soln_conservative[istate];
372 }
373 
374 // ========================================================
375 // KELVIN-HELMHOLTZ INSTABILITY
376 // See Chan et al., On the entropy projection..., 2022, Pg. 15
377 // Note that some equations are not typed correctly
378 // See github.com/trixi-framework/paper-2022-robustness-entropy-projection
379 // for initial condition which is implemented herein
380 // ========================================================
381 template <int dim, int nstate, typename real>
384  Parameters::AllParameters const *const param)
385  : InitialConditionFunction<dim,nstate,real>()
386  , atwood_number(param->flow_solver_param.atwood_number)
387 {
388  // Euler object; create using dynamic_pointer_cast and the create_Physics factory
389  // This test should only be used for Euler
390  this->euler_physics = std::dynamic_pointer_cast<Physics::Euler<dim,dim+2,double>>(
392 }
393 
394 template <int dim, int nstate, typename real>
396 ::value(const dealii::Point<dim,real> &point, const unsigned int istate) const
397 {
398  const double pi = dealii::numbers::PI;
399 
400  const double B = 0.5 * (tanh(15*point[1] + 7.5) - tanh(15*point[1] - 7.5));
401 
402  const double rho1 = 0.5;
403  const double rho2 = rho1 * (1 + atwood_number) / (1 - atwood_number);
404 
405  std::array<real,nstate> soln_primitive;
406  soln_primitive[0] = rho1 + B * (rho2-rho1);
407  soln_primitive[nstate-1] = 1;
408  soln_primitive[1] = B - 0.5;
409  soln_primitive[2] = 0.1 * sin(2 * pi * point[0]);
410 
411  const std::array<real,nstate> soln_conservative = this->euler_physics->convert_primitive_to_conservative(soln_primitive);
412  return soln_conservative[istate];
413 }
414 
415 // ========================================================
416 // Initial Condition - Euler Base
417 // ========================================================
418 template <int dim, int nstate, typename real>
421  Parameters::AllParameters const* const param)
422  : InitialConditionFunction<dim, nstate, real>()
423 {
424  // Euler object; create using dynamic_pointer_cast and the create_Physics factory
425  // Note that Euler primitive/conservative vars are the same as NS
426  PHiLiP::Parameters::AllParameters parameters_euler = *param;
427  parameters_euler.pde_type = Parameters::AllParameters::PartialDifferentialEquation::euler;
428  this->euler_physics = std::dynamic_pointer_cast<Physics::Euler<dim,dim+2,double>>(
430 }
431 
432 template <int dim, int nstate, typename real>
435  const dealii::Point<dim, real>& point, const unsigned int istate) const
436 {
437  real value = 0.0;
438  std::array<real, nstate> soln_primitive;
439 
440  soln_primitive[0] = primitive_value(point, 0);
441  soln_primitive[1] = primitive_value(point, 1);
442  soln_primitive[2] = primitive_value(point, 2);
443 
444  if constexpr (dim > 1)
445  soln_primitive[3] = primitive_value(point, 3);
446  if constexpr (dim > 2)
447  soln_primitive[4] = primitive_value(point, 4);
448 
449  const std::array<real, nstate> soln_conservative = this->euler_physics->convert_primitive_to_conservative(soln_primitive);
450  value = soln_conservative[istate];
451 
452  return value;
453 }
454 
455 template <int dim, int nstate, typename real>
457 ::value(const dealii::Point<dim, real>& point, const unsigned int istate) const
458 {
459  real value = 0.0;
460  value = convert_primitive_to_conversative_value(point, istate);
461  return value;
462 }
463 
464 // ========================================================
465 // 1D Sod Shock tube -- Initial Condition
466 // See Chen & Shu, Entropy stable high order..., 2017, Pg. 25
467 // 2D and 3D can be run by extruding grid in those directions
468 // ========================================================
469 template <int dim, int nstate, typename real>
472  Parameters::AllParameters const* const param)
473  : InitialConditionFunction_EulerBase<dim,nstate,real>(param)
474 {}
475 
476 template <int dim, int nstate, typename real>
478 ::primitive_value(const dealii::Point<dim, real>& point, const unsigned int istate) const
479 {
480  real value = 0.0;
481  if constexpr (dim == 1 && nstate == (dim+2)) {
482  const real x = point[0];
483  if (x < 0) {
484  if (istate == 0) {
485  // density
486  value = 1.0;
487  }
488  if (istate == nstate - 1) {
489  // pressure
490  value = 1.0;
491  }
492  } else {
493  if (istate == 0) {
494  // density
495  value = 0.125;
496  }
497  if (istate == nstate - 1) {
498  // pressure
499  value = 0.1;
500  }
501  }
502  }
503 
504  return value;
505 }
506 
507 // ========================================================
508 // 1D Leblanc Shock tube -- Initial Condition
509 // See Zhang & Shu, On positivity-preserving..., 2010 Pg. 14
510 // ========================================================
511 template <int dim, int nstate, typename real>
514  Parameters::AllParameters const* const param)
515  : InitialConditionFunction_EulerBase<dim, nstate, real>(param)
516 {}
517 
518 template <int dim, int nstate, typename real>
520 ::primitive_value(const dealii::Point<dim, real>& point, const unsigned int istate) const
521 {
522  real value = 0.0;
523  if constexpr (dim == 1 && nstate == (dim + 2)) {
524  const real x = point[0];
525  if (x < 0) {
526  if (istate == 0) {
527  // density
528  value = 2.0;
529  }
530  if (istate == 1) {
531  // x-velocity
532  value = 0.0;
533  }
534  if (istate == 2) {
535  // pressure
536  value = pow(10.0, 9.0);
537  }
538  }
539  else {
540  if (istate == 0) {
541  // density
542  value = 0.001;
543  }
544  if (istate == 1) {
545  // x-velocity
546  value = 0.0;
547  }
548  if (istate == 2) {
549  // pressure
550  value = 1.0;
551  }
552  }
553  }
554  return value;
555 }
556 
557 // ========================================================
558 // 1D Shu-Osher Problem -- Initial Condition
559 // See Johnsen et al., Assessment of high-resolution..., 2010 Pg. 7
560 // ========================================================
561 template <int dim, int nstate, typename real>
564  Parameters::AllParameters const* const param)
565  : InitialConditionFunction_EulerBase<dim, nstate, real>(param)
566 {}
567 
568 template <int dim, int nstate, typename real>
570 ::primitive_value(const dealii::Point<dim, real>& point, const unsigned int istate) const
571 {
572  real value = 0.0;
573  if constexpr (dim == 1 && nstate == (dim + 2)) {
574  const real x = point[0];
575  if (x < -4) {
576  if (istate == 0) {
577  // density
578  value = 3.857143;
579  }
580  else if (istate == 1) {
581  // x-velocity
582  value = 2.629369;
583  }
584  else if (istate == 2) {
585  // pressure
586  value = 10.33333;
587  }
588  }
589  else {
590  if (istate == 0) {
591  // density
592  value = 1 + 0.2 * sin(5 * x);
593  }
594  else if (istate == 1) {
595  // x-velocity
596  value = 0.0;
597  }
598  else if (istate == 2) {
599  // pressure
600  value = 1.0;
601  }
602  }
603  }
604  return value;
605 }
606 
607 // =====================================================================
608 // Low Density Euler -- Initial Condition
609 // See Dzanic & Martinelli, High-order limiting..., 2025, Pg. 15
610 // =====================================================================
611 template <int dim, int nstate, typename real>
614  Parameters::AllParameters const* const param)
615  : InitialConditionFunction_EulerBase<dim, nstate, real>(param)
616 {}
617 
618 template <int dim, int nstate, typename real>
620 ::primitive_value(const dealii::Point<dim, real>& point, const unsigned int istate) const
621 {
622  real value = 0.0;
623  if constexpr (dim == 1 && nstate == (dim + 2)) {
624  const real x = point[0];
625  if (istate == 0) {
626  // density
627  value = 0.01 + exp(-500.0*pow(x,2.0));
628  }
629  else {
630  value = 1.0;
631  }
632  }
633 
634  if constexpr (dim == 2 && nstate == (dim + 2)) {
635  const real x = point[0];
636  const real y = point[1];
637 
638  if (istate == 0) {
639  // density
640  value = 0.01 + exp(-500.0*(pow(x, 2.0)+pow(y, 2.0)));
641  }
642  else {
643  // x-velocity
644  value = 1.0;
645  }
646  }
647  return value;
648 }
649 
650 // ==================================================================
651 // Double Mach Reflection Problem (2D) -- Initial Condition
652 // See Lin, Chan, and Tomas. "A positivity preserving ...", 2023, p20
653 // ==================================================================
654 template <int dim, int nstate, typename real>
657  Parameters::AllParameters const* const param)
658  : InitialConditionFunction_EulerBase<dim, nstate, real>(param)
659 {}
660 
661 template <int dim, int nstate, typename real>
663 ::primitive_value(const dealii::Point<dim, real>& point, const unsigned int istate) const
664 {
665  real value = 0.0;
666  if constexpr (dim == 2 && nstate == (dim + 2)) {
667  const real x = point[0];
668  const real y = point[1];
669  if (y > sqrt(3)*(x - (1.0/6.0))) {
670  if (istate == 0) {
671  // density
672  value = 8.0;
673  }
674  else if (istate == 1) {
675  // x-velocity
676  value = 33.0*sqrt(3.0)/8.0;
677  }
678  else if (istate == 2) {
679  // y-velocity
680  value = -33.0/8.0;
681  }
682  else if (istate == 3) {
683  // pressure
684  value = 116.5;
685  }
686  }
687  else {
688  if (istate == 0) {
689  // density
690  value = 1.4;
691  }
692  else if (istate == 1) {
693  // x-velocity
694  value = 0.0;
695  }
696  else if (istate == 2) {
697  // y-velocity
698  value = 0.0;
699  }
700  else if (istate == 3) {
701  // pressure
702  value = 1.0;
703  }
704  }
705  }
706  return value;
707 }
708 
709 // ========================================================
710 // Shock Diffraction (backwards facing step) (2D) -- Initial Condition
711 // See Zhang & Shu, On positivity-preserving..., 2010 Pg. 15
712 // ========================================================
713 template <int dim, int nstate, typename real>
716  Parameters::AllParameters const* const param)
717  : InitialConditionFunction_EulerBase<dim, nstate, real>(param)
718 {}
719 
720 template <int dim, int nstate, typename real>
722 ::primitive_value(const dealii::Point<dim, real>& point, const unsigned int istate) const
723 {
724  real value = 0.0;
725  const real x = point[0];
726  //real y = point[1];
727  if constexpr (dim == 2 && nstate == (dim + 2)) {
728  if (x <= 0.5) {
729  if (istate == 0) {
730  // density
731  value = 7.041132906907898;
732  }
733  else if (istate == 1) {
734  // x-velocity
735  value = 4.07794695481336;
736  }
737  else if (istate == 2) {
738  // y-velocity
739  value = 0.0;
740  }
741  else if (istate == 3) {
742  // pressure
743  value = 30.05945;
744  }
745  }
746  else {
747  if (istate == 0) {
748  // density
749  value = 1.4;
750  }
751  else if (istate == 1) {
752  // x-velocity
753  value = 0.0;
754  }
755  else if (istate == 2) {
756  // y-velocity
757  value = 0.0;
758  }
759  else if (istate == 3) {
760  // pressure
761  value = 1.0;
762  }
763  }
764  }
765  return value;
766 }
767 
768 
769 // ========================================================
770 // Astrophysical Mach Jet (2D) -- Initial Condition
771 // See Zhang & Shu, On positivity-preserving..., 2010 Pg. 14
772 // ========================================================
773 template <int dim, int nstate, typename real>
776  Parameters::AllParameters const* const param)
777  : InitialConditionFunction_EulerBase<dim, nstate, real>(param)
778 {}
779 
780 template <int dim, int nstate, typename real>
782 ::primitive_value(const dealii::Point<dim, real>& /*point*/, const unsigned int istate) const
783 {
784  real value = 0.0;
785  if constexpr (dim == 2 && nstate == (dim + 2)) {
786 
787  if (istate == 0) {
788  // density
789  value = 0.5;
790  }
791  else if (istate == 1) {
792  // x-velocity
793  value = 0.0;
794  }
795  else if (istate == 2) {
796  // y-velocity
797  value = 0.0;
798  }
799  else if (istate == 3) {
800  // pressure
801  value = 0.4127;
802  }
803  }
804  return value;
805 }
806 
807 
808 // ========================================================
809 // Strong Vortex Shock Wave Interaction (2D) -- Initial Condition
810 // See High Fidelity CFD Workshop 2022
811 // Unsteady Supersonic/Hypersonic Test Suite
812 // ========================================================
813 template <int dim, int nstate, typename real>
816  Parameters::AllParameters const* const param)
817  : InitialConditionFunction_EulerBase<dim, nstate, real>(param)
818 {}
819 
820 template <int dim, int nstate, typename real>
822 ::primitive_value(const dealii::Point<dim, real>& point, const unsigned int istate) const
823 {
824  real value = 0.0;
825  const real x = point[0];
826  const real y = point[1];
827 
828  if constexpr (dim == 2 && nstate == (dim + 2)) {
829  // Ideal gas
830  const real gamma = 1.4;
831  const real R = 1.0;
832 
833  // Upstream conditions
834  const real rho_u = 1.0;
835  const real u_u = 1.5*sqrt(1.4);
836  const real v_u = 0.0;
837  const real p_u = 1.0;
838  const real t_u = p_u/(rho_u*R);
839 
840 
841 
842  // Shock condition
843  const real M_s = 1.5;
844 
845  // Downstream conditions
846  const real rho_d = (rho_u * (gamma + 1.0) * M_s * M_s) / (2.0 + (gamma - 1.0) * M_s * M_s);
847  const real u_d = (u_u * (2.0 + ((gamma - 1.0) * M_s * M_s)))/((gamma + 1.0) * M_s * M_s);
848  const real v_d = 0.0;
849  const real p_d = p_u * (1.0 + (2.0 * gamma / (gamma + 1.0)) * (M_s * M_s - 1.0));
850 
851  if (x <= 0.5){
852  if (istate == 0) {
853  // density
854  value = rho_u;
855  }
856  else if (istate == 1) {
857  // x-velocity
858  value = u_u;
859  }
860  else if (istate == 2) {
861  // y-velocity
862  value = v_u;
863  }
864  else if (istate == 3) {
865  // pressure
866  value = p_u;
867  }
868  } else {
869  if (istate == 0) {
870  // density
871  value = rho_d;
872  }
873  else if (istate == 1) {
874  // x-velocity
875  value = u_d;
876  }
877  else if (istate == 2) {
878  // y-velocity
879  value = v_d;
880  }
881  else if (istate == 3) {
882  // pressure
883  value = p_d;
884  }
885  }
886 
887  if(x <= 0.5) {
888  // Vortex location
889  const real x_c = 0.25; const real y_c = 0.5;
890 
891  // Vortex sizes
892  const real a = 0.075; const real b = 0.175;
893 
894  // Vortex strength
895  const real M_v = 0.9; const real v_m = M_v * sqrt(gamma);
896 
897  // Distance from vortex
898  const real dx = x - x_c;
899  const real dy = y - y_c;
900  const real r = sqrt((dx*dx) + (dy*dy));
901 
902  real temperature = 0.0;
903 
904  // Superimpose vortex
905  if (r<=b) {
906  const double sin_theta = dy/r;
907  const double cos_theta = dx/r;
908 
909  if (r<=a) {
910  const real mag = v_m * r / a;
911  if(istate == 1)
912  value = u_u - mag*sin_theta;
913  else if(istate == 2)
914  value = v_u + mag*cos_theta;
915  else {
916  // Temperature at a, integrated from ODE
917  real radial_term = -2.0 * b * b * log(b) - (0.5 * a * a) + (2.0 * b * b * log(a)) + (0.5 * b * b * b * b / (a * a));
918  const real t_a = t_u - (gamma - 1.0) * pow(v_m * a / (a * a - b * b), 2.0) * radial_term / (R * gamma);
919  radial_term = 0.5 * (1.0 - r * r / (a * a));
920  temperature = t_a - (gamma - 1.0) * v_m * v_m * radial_term / (R * gamma);
921  }
922  } else {
923  const real mag = v_m * a * (r - b * b / r)/(a * a - b * b);
924  if(istate == 1)
925  value = u_u - mag * sin_theta;
926  else if (istate == 2)
927  value = v_u + mag * cos_theta;
928  else {
929  const real radial_term = -2.0 * b * b * log(b) - (0.5 * r * r) + (2.0 * b * b * log(r)) + (0.5 * b * b * b * b / (r * r));
930  temperature = t_u - (gamma - 1.0) * pow(v_m * a/(a * a - b * b), 2.0) * radial_term / (R * gamma);
931  }
932  }
933 
934  if (istate == 0)
935  value = rho_u * pow(temperature/t_u, 1.0/(gamma - 1.0));
936  else if (istate == 3)
937  value = p_u * pow(temperature/t_u, gamma/(gamma - 1.0));
938  }
939  }
940  }
941  return value;
942 }
943 
944 // ========================================================
945 // ZERO INITIAL CONDITION
946 // ========================================================
947 template <int dim, int nstate, typename real>
950  : InitialConditionFunction<dim,nstate,real>()
951 {
952  // Nothing to do here yet
953 }
954 
955 template <int dim, int nstate, typename real>
957 ::value(const dealii::Point<dim,real> &/*point*/, const unsigned int /*istate*/) const
958 {
959  return 0.0;
960 }
961 
962 // =========================================================
963 // Initial Condition Factory
964 // =========================================================
965 template <int dim, int nstate, typename real>
966 std::shared_ptr<InitialConditionFunction<dim, nstate, real>>
968  Parameters::AllParameters const *const param)
969 {
970  // Get the flow case type
971  const FlowCaseEnum flow_type = param->flow_solver_param.flow_case_type;
972  if (flow_type == FlowCaseEnum::taylor_green_vortex) {
973  if constexpr (dim==3 && nstate==dim+2){
974  // Get the density initial condition type
975  const DensityInitialConditionEnum density_initial_condition_type = param->flow_solver_param.density_initial_condition_type;
976  if(density_initial_condition_type == DensityInitialConditionEnum::uniform) {
977  return std::make_shared<InitialConditionFunction_TaylorGreenVortex<dim,nstate,real> >(
978  param);
979  } else if (density_initial_condition_type == DensityInitialConditionEnum::isothermal) {
980  return std::make_shared<InitialConditionFunction_TaylorGreenVortex_Isothermal<dim,nstate,real> >(
981  param);
982  }
983  }
984  } else if (flow_type == FlowCaseEnum::decaying_homogeneous_isotropic_turbulence) {
985  if constexpr (dim==3 && nstate==dim+2) return nullptr; // nullptr since DHIT case initializes values from file
986  } else if (flow_type == FlowCaseEnum::burgers_rewienski_snapshot) {
987  if constexpr (dim==1 && nstate==1) return std::make_shared<InitialConditionFunction_BurgersRewienski<dim,nstate,real> > ();
988  } else if (flow_type == FlowCaseEnum::burgers_viscous_snapshot) {
989  if constexpr (dim==1 && nstate==1) return std::make_shared<InitialConditionFunction_BurgersViscous<dim,nstate,real> > ();
990  } else if (flow_type == FlowCaseEnum::naca0012 || flow_type == FlowCaseEnum::gaussian_bump) {
991  if constexpr ((dim==2 || dim==3) && nstate==dim+2) {
993  param,
994  param->euler_param.ref_length,
995  param->euler_param.gamma_gas,
996  param->euler_param.mach_inf,
997  param->euler_param.angle_of_attack,
998  param->euler_param.side_slip_angle);
999  return std::make_shared<FreeStreamInitialConditions<dim,nstate,real>>(euler_physics_double);
1000  }
1001  } else if (flow_type == FlowCaseEnum::burgers_inviscid && param->use_energy==false) {
1002  if constexpr (nstate==dim && dim<3) return std::make_shared<InitialConditionFunction_BurgersInviscid<dim, nstate, real> >();
1003  } else if (flow_type == FlowCaseEnum::burgers_inviscid && param->use_energy==true) {
1004  if constexpr (dim==1 && nstate==1) return std::make_shared<InitialConditionFunction_BurgersInviscidEnergy<dim,nstate,real> > ();
1005  } else if (flow_type == FlowCaseEnum::advection && param->use_energy==true) {
1006  if constexpr (nstate==1) return std::make_shared<InitialConditionFunction_AdvectionEnergy<dim,nstate,real> > ();
1007  } else if (flow_type == FlowCaseEnum::advection && param->use_energy==false) {
1008  if constexpr (nstate==1) return std::make_shared<InitialConditionFunction_Advection<dim,nstate,real> > ();
1009  } else if (flow_type == FlowCaseEnum::convection_diffusion && !param->use_energy) {
1010  if constexpr (nstate==1) return std::make_shared<InitialConditionFunction_ConvDiff<dim,nstate,real> > ();
1011  } else if (flow_type == FlowCaseEnum::convection_diffusion && param->use_energy) {
1012  return std::make_shared<InitialConditionFunction_ConvDiffEnergy<dim,nstate,real> > ();
1013  } else if (flow_type == FlowCaseEnum::periodic_1D_unsteady) {
1014  if constexpr (dim==1 && nstate==1) return std::make_shared<InitialConditionFunction_1DSine<dim,nstate,real> > ();
1015  } else if (flow_type == FlowCaseEnum::isentropic_vortex) {
1016  if constexpr (dim>1 && nstate==dim+2) return std::make_shared<InitialConditionFunction_IsentropicVortex<dim,nstate,real> > (param);
1017  } else if (flow_type == FlowCaseEnum::kelvin_helmholtz_instability) {
1018  if constexpr (dim>1 && nstate==dim+2) return std::make_shared<InitialConditionFunction_KHI<dim,nstate,real> > (param);
1019  } else if (flow_type == FlowCaseEnum::non_periodic_cube_flow) {
1020  if constexpr (dim==2 && nstate==1) return std::make_shared<InitialConditionFunction_Zero<dim,nstate,real> > ();
1021  } else if (flow_type == FlowCaseEnum::sod_shock_tube) {
1022  if constexpr (dim == 1 && nstate == dim+2) return std::make_shared<InitialConditionFunction_SodShockTube<dim,nstate,real> > (param);
1023  } else if (flow_type == FlowCaseEnum::low_density) {
1024  if constexpr (dim < 3 && nstate == dim+2) return std::make_shared<InitialConditionFunction_LowDensity<dim,nstate,real> > (param);
1025  } else if (flow_type == FlowCaseEnum::leblanc_shock_tube) {
1026  if constexpr (dim == 1 && nstate == dim+2) return std::make_shared<InitialConditionFunction_LeblancShockTube<dim,nstate,real> > (param);
1027  } else if (flow_type == FlowCaseEnum::shu_osher_problem) {
1028  if constexpr (dim == 1 && nstate == dim + 2) return std::make_shared<InitialConditionFunction_ShuOsherProblem<dim, nstate, real> >(param);
1029  } else if (flow_type == FlowCaseEnum::double_mach_reflection) {
1030  if constexpr (dim == 2 && nstate == dim + 2) return std::make_shared<InitialConditionFunction_DoubleMachReflection<dim, nstate, real> >(param);
1031  } else if (flow_type == FlowCaseEnum::shock_diffraction) {
1032  if constexpr (dim == 2 && nstate == dim + 2) return std::make_shared<InitialConditionFunction_ShockDiffraction<dim, nstate, real> >(param);
1033  } else if (flow_type == FlowCaseEnum::astrophysical_jet) {
1034  if constexpr (dim == 2 && nstate == dim + 2) return std::make_shared<InitialConditionFunction_AstrophysicalJet<dim, nstate, real> >(param);
1035  } else if (flow_type == FlowCaseEnum::strong_vortex_shock_wave) {
1036  if constexpr (dim == 2 && nstate == dim + 2) return std::make_shared<InitialConditionFunction_SVSW<dim, nstate, real> >(param);
1037  } else if (flow_type == FlowCaseEnum::advection_limiter) {
1038  if constexpr (dim < 3 && nstate == 1) return std::make_shared<InitialConditionFunction_Advection<dim, nstate, real> >();
1039  } else if (flow_type == FlowCaseEnum::burgers_limiter) {
1040  if constexpr (nstate==dim && dim<3) return std::make_shared<InitialConditionFunction_BurgersInviscid<dim, nstate, real> >();
1041  }else {
1042  std::cout << "Invalid Flow Case Type. You probably forgot to add it to the list of flow cases in initial_condition_function.cpp" << std::endl;
1043  std::abort();
1044  }
1045  return nullptr;
1046 }
1047 
1060 
1061 #if PHILIP_DIM==1
1066 #endif
1067 
1068 #if PHILIP_DIM==3
1071 #endif
1072 
1073 #if PHILIP_DIM>1
1075 #endif
1076 
1077 #if PHILIP_DIM==2
1083 #endif
1084 
1085 #if PHILIP_DIM < 3
1087 #endif
1088 
1089 // functions instantiated for all dim
1102 
1103 } // PHiLiP namespace
InitialConditionFunction_1DSine()
< dealii::Function we are templating on
InitialConditionFunction_BurgersInviscidEnergy()
< dealii::Function we are templating on
FlowCaseType
Selects the flow case to be simulated.
PartialDifferentialEquation pde_type
Store the PDE type to be solved.
real primitive_value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const override
Value of initial condition expressed in terms of primitive variables.
Initial Condition Function: Advection Energy.
Initial Condition Function: Taylor Green Vortex (isothermal density)
FlowCaseType flow_case_type
Selected FlowCaseType from the input file.
const double mach_inf
Farfield Mach number.
Definition: euler.h:113
real primitive_value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const override
Value of initial condition expressed in terms of primitive variables.
real primitive_value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const override
Value of initial condition expressed in terms of primitive variables.
FlowSolverParam flow_solver_param
Contains the parameters for simulation cases (flow solver test)
const double angle_of_attack
Angle of attack.
Definition: euler.h:118
real value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const override
Value of initial condition.
Initial Condition Function: 1D Burgers Viscous.
InitialConditionFunction_LowDensity(Parameters::AllParameters const *const param)
Constructor for InitialConditionFunction_SodShockTube.
InitialConditionFunction_EulerBase(Parameters::AllParameters const *const param)
< dealii::Function we are templating on
Initial Condition Function: 2D Low Density Euler.
InitialConditionFunction()
< dealii::Function we are templating on
bool use_energy
Flag to use an energy monotonicity test.
InitialConditionFunction_BurgersRewienski()
< dealii::Function we are templating on
InitialConditionFunction_TaylorGreenVortex_Isothermal(Parameters::AllParameters const *const param)
Constructor for TaylorGreenVortex_InitialCondition with isothermal density.
Initial Condition Function: 2D Strong Vortex Shock Wave Interaction.
InitialConditionFunction_LeblancShockTube(Parameters::AllParameters const *const param)
Constructor for InitialConditionFunction_SodShockTube.
Files for the baseline physics.
Definition: ADTypes.hpp:10
real value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const override
Value of initial condition expressed in terms of conservative variables.
Initial Condition Function: Euler Equations (primitive values)
InitialConditionFunction_SVSW(Parameters::AllParameters const *const param)
Constructor for InitialConditionFunction_AstrophysicalJet.
const double side_slip_angle
Sideslip angle.
Definition: euler.h:122
Initial Condition Function: 1D Shu Osher Problem.
Initial Condition Function: 2D Astrophysical Mach Jet.
real value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const override
Value of initial condition.
Initial Condition Function: Convection Diffusion Orders of Accuracy.
real primitive_value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const override
Value of initial condition expressed in terms of primitive variables.
real convert_primitive_to_conversative_value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const
Converts value from: primitive to conservative.
Initial Condition Function: Isentropic vortex.
real value(const dealii::Point< dim, real > &point, const unsigned int istate) const override
Value of initial condition.
Main parameter class that contains the various other sub-parameter classes.
InitialConditionFunction_ShuOsherProblem(Parameters::AllParameters const *const param)
Constructor for InitialConditionFunction_SodShockTube.
InitialConditionFunction_BurgersInviscid()
< dealii::Function we are templating on
virtual real density(const dealii::Point< dim, real > &point) const
Value of initial condition for density.
real value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const override
Value of initial condition.
InitialConditionFunction_ConvDiffEnergy()
< dealii::Function we are templating on
real value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const override
Returns zero.
real density(const dealii::Point< dim, real > &point) const override
Value of initial condition for density.
real value(const dealii::Point< dim, real > &point, const unsigned int istate) const override
Value of initial condition.
Initial Condition Function: 1D Burgers Inviscid Energy.
Initial condition function factory.
real primitive_value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const override
Value of initial condition expressed in terms of primitive variables.
real primitive_value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const override
Value of initial condition expressed in terms of primitive variables.
real primitive_value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const
Value of initial condition expressed in terms of primitive variables.
InitialConditionFunction_TaylorGreenVortex(Parameters::AllParameters const *const param)
< dealii::Function we are templating on
InitialConditionFunction_DoubleMachReflection(Parameters::AllParameters const *const param)
Constructor for InitialConditionFunction_DoubleMachReflection.
real value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const override
Value of initial condition.
Euler equations. Derived from PhysicsBase.
Definition: euler.h:78
real value(const dealii::Point< dim, real > &point, const unsigned int istate) const override
Value of initial condition.
Initial Condition Function: 1D Burgers Inviscid.
real value(const dealii::Point< dim, real > &point, const unsigned int istate) const override
Value of initial condition.
InitialConditionFunction_Advection()
< dealii::Function we are templating on
real primitive_value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const override
Value of initial condition expressed in terms of primitive variables.
Initial condition function used to initialize a particular flow setup/case.
Initial Condition Function: 1D Burgers Rewienski.
Kelvin-Helmholtz Instability, parametrized by Atwood number.
Initial Condition Function: 2D Double Mach Reflection Problem.
InitialConditionFunction_ConvDiff()
< dealii::Function we are templating on
InitialConditionFunction_SodShockTube(Parameters::AllParameters const *const param)
Constructor for InitialConditionFunction_SodShockTube.
static std::shared_ptr< PhysicsBase< dim, nstate, real > > create_Physics(const Parameters::AllParameters *const parameters_input, std::shared_ptr< ModelBase< dim, nstate, real > > model_input=nullptr)
Factory to return the correct physics given input file.
InitialConditionFunction_AdvectionEnergy()
< dealii::Function we are templating on
real value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const override
Value of initial condition.
InitialConditionFunction_BurgersViscous()
< dealii::Function we are templating on
InitialConditionFunction_AstrophysicalJet(Parameters::AllParameters const *const param)
Constructor for InitialConditionFunction_AstrophysicalJet.
InitialConditionFunction_KHI(Parameters::AllParameters const *const param)
< dealii::Function we are templating on
Initial Condition Function: 1D Burgers Inviscid.
DensityInitialConditionType
For taylor green vortex, selects the type of density initialization.
real value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const override
Value of initial condition.
InitialConditionFunction_ShockDiffraction(Parameters::AllParameters const *const param)
Constructor for InitialConditionFunction_SodShockTube.
const double ref_length
Reference length.
Definition: euler.h:104
Initial Condition Function: 2D Shock Diffraction Problem.
real value(const dealii::Point< dim, real > &point, const unsigned int istate) const override
Value of initial condition.
Initial Condition Function: Taylor Green Vortex (uniform density)
InitialConditionFunction_Zero()
< dealii::Function we are templating on
Initial Condition Function: Convection Diffusion Energy.
real primitive_value(const dealii::Point< dim, real > &point, const unsigned int istate=0) const override
Value of initial condition expressed in terms of primitive variables.
static std::shared_ptr< InitialConditionFunction< dim, nstate, real > > create_InitialConditionFunction(Parameters::AllParameters const *const param)
Construct InitialConditionFunction object from global parameter file.
InitialConditionFunction_IsentropicVortex(Parameters::AllParameters const *const param)
< dealii::Function we are templating on
DensityInitialConditionType density_initial_condition_type
Selected DensityInitialConditionType from the input file.