[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
physics_model.cpp
1 #include <cmath>
2 #include <vector>
3 #include <complex> // for the jacobian
4 #include <boost/preprocessor/seq/for_each.hpp>
5 
6 #include "ADTypes.hpp"
7 
8 #include "physics.h"
9 #include "euler.h"
10 #include "navier_stokes.h"
11 
12 #include "physics_model.h"
13 #include "physics_factory.h"
14 #include "model.h"
15 
16 namespace PHiLiP {
17 namespace Physics {
18 
19 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
21  const Parameters::AllParameters *const parameters_input,
23  std::shared_ptr< ModelBase<dim,nspecies,nstate,real> > model_input,
24  std::shared_ptr< ManufacturedSolutionFunction<dim,nspecies,real> > manufactured_solution_function,
25  const bool has_nonzero_diffusion,
26  const bool has_nonzero_physical_source)
27  : PhysicsBase<dim,nspecies,nstate,real>(parameters_input, has_nonzero_diffusion, has_nonzero_physical_source, manufactured_solution_function)
28  , n_model_equations(nstate-nstate_baseline_physics)
29  , physics_baseline(PhysicsFactory<dim,nspecies,nstate_baseline_physics,real>::create_Physics(parameters_input, baseline_physics_type))
30  , model(model_input)
31  , mpi_communicator(MPI_COMM_WORLD)
32  , mpi_rank(dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD))
33  , n_mpi(dealii::Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD))
34  , pcout(std::cout, mpi_rank==0)
35 { }
36 
37 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
39 ::convert_conservative_to_primitive ( const std::array<real,nstate> &conservative_soln ) const
40 {
41  std::array<real,nstate> primitive_soln;
42  if constexpr(nstate==nstate_baseline_physics) {
43  primitive_soln = physics_baseline->convert_conservative_to_primitive(conservative_soln);
44  } else {
45  pcout << "Error: convert_conservative_to_primitive() not implemented for nstate!=nstate_baseline_physics." << std::endl;
46  pcout << "Aborting..." << std::endl;
47  std::abort();
48  }
49  return primitive_soln;
50 }
51 
52 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
54 ::convert_primitive_to_conservative ( const std::array<real,nstate> &primitive_soln ) const
55 {
56  std::array<real,nstate> conservative_soln;
57  if constexpr(nstate==nstate_baseline_physics) {
58  conservative_soln = physics_baseline->convert_primitive_to_conservative(primitive_soln);
59  } else {
60  pcout << "Error: convert_primitive_to_conservative() not implemented for nstate!=nstate_baseline_physics." << std::endl;
61  pcout << "Aborting..." << std::endl;
62  std::abort();
63  }
64  return conservative_soln;
65 }
66 
67 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
68 std::array<dealii::Tensor<1,dim,real>,nstate> PhysicsModel<dim,nspecies,nstate,real,nstate_baseline_physics>
70  const std::array<real,nstate> &primitive_soln,
71  const std::array<dealii::Tensor<1,dim,real>,nstate> &primitive_soln_gradient) const
72 {
73  std::array<dealii::Tensor<1,dim,real>,nstate> conservative_soln_gradient;
74  if constexpr(nstate==nstate_baseline_physics) {
75  conservative_soln_gradient = physics_baseline->convert_primitive_gradient_to_conservative_gradient(primitive_soln,primitive_soln_gradient);
76  } else {
77  pcout << "Error: convert_primitive_gradient_to_conservative_gradient() not implemented for nstate!=nstate_baseline_physics." << std::endl;
78  pcout << "Aborting..." << std::endl;
79  std::abort();
80  }
81  return conservative_soln_gradient;
82 }
83 
84 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
85 std::array<dealii::Tensor<1,dim,real>,nstate> PhysicsModel<dim,nspecies,nstate,real,nstate_baseline_physics>
87  const std::array<real,nstate> &conservative_soln,
88  const std::array<dealii::Tensor<1,dim,real>,nstate> &conservative_soln_gradient) const
89 {
90  std::array<dealii::Tensor<1,dim,real>,nstate> primitive_soln_gradient;
91  if constexpr(nstate==nstate_baseline_physics) {
92  primitive_soln_gradient = physics_baseline->convert_conservative_gradient_to_primitive_gradient(conservative_soln,conservative_soln_gradient);
93  } else {
94  pcout << "Error: convert_conservative_gradient_to_primitive_gradient() not implemented for nstate!=nstate_baseline_physics." << std::endl;
95  pcout << "Aborting..." << std::endl;
96  std::abort();
97  }
98  return primitive_soln_gradient;
99 }
100 
101 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
102 std::array<dealii::Tensor<1,dim,real>,nstate> PhysicsModel<dim,nspecies,nstate,real,nstate_baseline_physics>
103 ::convective_flux (const std::array<real,nstate> &conservative_soln) const
104 {
105  // Get baseline conservative solution with nstate_baseline_physics
106  std::array<real,nstate_baseline_physics> baseline_conservative_soln;
107  for(int s=0; s<nstate_baseline_physics; ++s){
108  baseline_conservative_soln[s] = conservative_soln[s];
109  }
110 
111  // Get baseline convective flux
112  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_conv_flux
113  = physics_baseline->convective_flux(baseline_conservative_soln);
114 
115  // Initialize conv_flux as the model convective flux
116  std::array<dealii::Tensor<1,dim,real>,nstate> conv_flux = model->convective_flux(conservative_soln);
117 
118  // Add the baseline_conv_flux terms to conv_flux
119  for(int s=0; s<nstate_baseline_physics; ++s){
120  for (int d=0; d<dim; ++d) {
121  conv_flux[s][d] += baseline_conv_flux[s][d];
122  }
123  }
124  return conv_flux;
125 }
126 
127 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
130  const std::array<real,nstate> &solution,
131  const std::array<dealii::Tensor<1,dim,real>,nstate> &solution_gradient,
132  const std::array<real,nstate> &filtered_solution,
133  const std::array<dealii::Tensor<1,dim,real>,nstate> &filtered_solution_gradient,
134  const bool on_boundary,
135  const dealii::types::global_dof_index cell_index,
136  const dealii::Tensor<1,dim,real> &normal,
137  const int boundary_type)
138 {
139  this->model->set_unfiltered_conservative_solution(solution);
140 
141  // Get baseline conservative solution with nstate_baseline_physics
142  std::array<real,nstate_baseline_physics> baseline_conservative_soln;
143  for(int s=0; s<nstate_baseline_physics; ++s){
144  baseline_conservative_soln[s] = solution[s];
145  }
146 
147  // Get baseline conservative solution gradient with nstate_baseline_physics
148  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_solution_gradient;
149  for(int s=0; s<nstate_baseline_physics; ++s){
150  for (int d=0; d<dim; ++d) {
151  baseline_solution_gradient[s][d] = solution_gradient[s][d];
152  }
153  }
154 
155  // Get baseline dissipative flux dot normal
156  /* Note: Even though the physics baseline dissipative flux does not depend on cell_index, we pass it
157  anyways to accomodate the pure virtual member function defined in the PhysicsBase class */
158  std::array<real,nstate_baseline_physics> baseline_diss_flux_dot_n
159  = physics_baseline->dissipative_flux_dot_normal(baseline_conservative_soln, baseline_solution_gradient, baseline_conservative_soln, baseline_solution_gradient, on_boundary, cell_index, normal, boundary_type);
160 
161  // Initialize diss_flux_dot_n as the model dissipative flux dot normal
162  std::array<real,nstate> diss_flux_dot_n = model->dissipative_flux_dot_normal(solution, solution_gradient, filtered_solution, filtered_solution_gradient, on_boundary, cell_index, normal, boundary_type);
163 
164  // Add the baseline_diss_flux_dot_n terms to diss_flux_dot_n
165  for(int s=0; s<nstate_baseline_physics; ++s){
166  diss_flux_dot_n[s] += baseline_diss_flux_dot_n[s];
167  }
168  return diss_flux_dot_n;
169 }
170 
171 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
172 std::array<dealii::Tensor<1,dim,real>,nstate> PhysicsModel<dim,nspecies,nstate,real,nstate_baseline_physics>
174  const std::array<real,nstate> &solution,
175  const std::array<dealii::Tensor<1,dim,real>,nstate> &solution_gradient,
176  const std::array<real,nstate> &/*filtered_solution*/,
177  const std::array<dealii::Tensor<1,dim,real>,nstate> &/*filtered_solution_gradient*/,
178  const dealii::types::global_dof_index cell_index)
179 {
180  this->model->set_unfiltered_conservative_solution(solution);
181  return this->dissipative_flux(solution,solution_gradient,cell_index);
182 }
183 
184 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
185 std::array<dealii::Tensor<1,dim,real>,nstate> PhysicsModel<dim,nspecies,nstate,real,nstate_baseline_physics>
187  const std::array<real,nstate> &conservative_soln,
188  const std::array<dealii::Tensor<1,dim,real>,nstate> &solution_gradient,
189  const dealii::types::global_dof_index cell_index) const
190 {
191  // Get baseline conservative solution with nstate_baseline_physics
192  std::array<real,nstate_baseline_physics> baseline_conservative_soln;
193  for(int s=0; s<nstate_baseline_physics; ++s){
194  baseline_conservative_soln[s] = conservative_soln[s];
195  }
196 
197  // Get baseline conservative solution gradient with nstate_baseline_physics
198  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_solution_gradient;
199  for(int s=0; s<nstate_baseline_physics; ++s){
200  for (int d=0; d<dim; ++d) {
201  baseline_solution_gradient[s][d] = solution_gradient[s][d];
202  }
203  }
204 
205  // Get baseline dissipative flux
206  /* Note: Even though the physics baseline dissipative flux does not depend on cell_index, we pass it
207  anyways to accomodate the pure virtual member function defined in the PhysicsBase class */
208  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_diss_flux
209  = physics_baseline->dissipative_flux(baseline_conservative_soln, baseline_solution_gradient, cell_index);
210 
211  // Initialize diss_flux as the model dissipative flux
212  std::array<dealii::Tensor<1,dim,real>,nstate> diss_flux = model->dissipative_flux(conservative_soln, solution_gradient, cell_index);
213 
214  // Add the baseline_diss_flux terms to diss_flux
215  for(int s=0; s<nstate_baseline_physics; ++s){
216  for (int d=0; d<dim; ++d) {
217  diss_flux[s][d] += baseline_diss_flux[s][d];
218  }
219  }
220  return diss_flux;
221 }
222 
223 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
226  const dealii::Point<dim,real> &pos,
227  const std::array<real,nstate> &conservative_soln,
228  const std::array<dealii::Tensor<1,dim,real>,nstate> &solution_gradient,
229  const dealii::types::global_dof_index cell_index) const
230 {
231  // Initialize physical_source_term as the model source term
232  std::array<real,nstate> physical_source_term = model->physical_source_term(pos, conservative_soln, solution_gradient, cell_index);
233 
234  // Get baseline conservative solution with nstate_baseline_physics
235  std::array<real,nstate_baseline_physics> baseline_conservative_soln;
236  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_solution_gradient;
237  for(int s=0; s<nstate_baseline_physics; ++s){
238  baseline_conservative_soln[s] = conservative_soln[s];
239  baseline_solution_gradient[s] = solution_gradient[s];
240  }
241 
242  // Get the baseline physics physical source term
243  /* Note: Even though the physics baseline source term does not depend on cell_index, we pass it
244  anyways to accomodate the pure virtual member function defined in the PhysicsBase class */
245  std::array<real,nstate_baseline_physics> baseline_physical_source_term = physics_baseline->physical_source_term(pos,baseline_conservative_soln,baseline_solution_gradient,cell_index);
246 
247  // Add the baseline_physical_source_term terms to source_term
248  for(int s=0; s<nstate_baseline_physics; ++s){
249  physical_source_term[s] += baseline_physical_source_term[s];
250  }
251 
252  return physical_source_term;
253 }
254 
255 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
258  const dealii::Point<dim,real> &pos,
259  const std::array<real,nstate> &conservative_soln,
260  const real current_time,
261  const dealii::types::global_dof_index cell_index) const
262 {
263  // Initialize source_term as the model source term
264  std::array<real,nstate> source_term = model->source_term(
265  pos,
266  conservative_soln,
267  current_time,
268  cell_index);
269 
270  // Get baseline conservative solution with nstate_baseline_physics
271  std::array<real,nstate_baseline_physics> baseline_conservative_soln;
272  for(int s=0; s<nstate_baseline_physics; ++s){
273  baseline_conservative_soln[s] = conservative_soln[s];
274  }
275 
276  // Get the baseline physics source term
277  /* Note: Even though the physics baseline source term does not depend on cell_index, we pass it
278  anyways to accomodate the pure virtual member function defined in the PhysicsBase class */
279  std::array<real,nstate_baseline_physics> baseline_source_term = physics_baseline->source_term(
280  pos,
281  baseline_conservative_soln,
282  current_time,
283  cell_index);
284 
285  // Add the baseline_source_term terms to source_term
286  for(int s=0; s<nstate_baseline_physics; ++s){
287  source_term[s] += baseline_source_term[s];
288  }
289 
290  return source_term;
291 }
292 
293 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
294 std::array<dealii::Tensor<1,dim,real>,nstate> PhysicsModel<dim,nspecies,nstate,real,nstate_baseline_physics>
295 ::convective_numerical_split_flux(const std::array<real,nstate> &conservative_soln1,
296  const std::array<real,nstate> &conservative_soln2) const
297 {
298  std::array<dealii::Tensor<1,dim,real>,nstate> conv_num_split_flux;
299  if constexpr(nstate==nstate_baseline_physics) {
300  conv_num_split_flux = physics_baseline->convective_numerical_split_flux(conservative_soln1,conservative_soln2);
301  } else {
302  pcout << "Error: convective_numerical_split_flux() not implemented for nstate!=nstate_baseline_physics." << std::endl;
303  pcout << "Aborting..." << std::endl;
304  std::abort();
305  }
306  return conv_num_split_flux;
307 }
308 
309 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
312  const std::array<real,nstate> &conservative_soln) const
313 {
314  std::array<real,nstate> entropy_var;
315  if constexpr(nstate==nstate_baseline_physics) {
316  entropy_var = physics_baseline->compute_entropy_variables(conservative_soln);
317  } else {
318  // TO DO, make use of the physics_model object for nstate>nstate_baseline_physics
319  pcout << "Error: compute_entropy_variables() not implemented for nstate!=nstate_baseline_physics." << std::endl;
320  pcout << "Aborting..." << std::endl;
321  std::abort();
322  }
323  return entropy_var;
324 }
325 
326 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
329  const std::array<real,nstate> &entropy_var) const
330 {
331  std::array<real,nstate> conservative_soln;
332  if constexpr(nstate==nstate_baseline_physics) {
333  conservative_soln = physics_baseline->compute_conservative_variables_from_entropy_variables(entropy_var);
334  } else {
335  // TO DO, make use of the physics_model object for nstate>nstate_baseline_physics
336  pcout << "Error: compute_conservative_variables_from_entropy_variables() not implemented for nstate!=nstate_baseline_physics." << std::endl;
337  pcout << "Aborting..." << std::endl;
338  std::abort();
339  }
340  return conservative_soln;
341 }
342 
343 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
346  const std::array<real,nstate> &conservative_soln,
347  const dealii::Tensor<1,dim,real> &normal) const
348 {
349  std::array<real,nstate> eig;
350  if constexpr(nstate==nstate_baseline_physics) {
351  eig = physics_baseline->convective_eigenvalues(conservative_soln, normal);
352  } else {
353  eig = model->convective_eigenvalues(conservative_soln, normal);
354  std::array<real,nstate_baseline_physics> baseline_conservative_soln;
355  for(int s=0; s<nstate_baseline_physics; ++s){
356  baseline_conservative_soln[s] = conservative_soln[s];
357  }
358  std::array<real,nstate_baseline_physics> baseline_eig = physics_baseline->convective_eigenvalues(baseline_conservative_soln, normal);
359  for(int s=0; s<nstate_baseline_physics; ++s){
360  if(eig[s]!=0.0){
361  pcout << "Error: PhysicsModel does not currently support additional convective flux terms." << std::endl;
362  pcout << "Aborting..." << std::endl;
363  std::abort();
364  } else {
365  eig[s] += baseline_eig[s];
366  }
367  }
368  }
369 
370  return eig;
371 }
372 
373 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
375 ::max_convective_eigenvalue (const std::array<real,nstate> &conservative_soln) const
376 {
377  real max_eig;
378  if constexpr(nstate==nstate_baseline_physics) {
379  max_eig = physics_baseline->max_convective_eigenvalue(conservative_soln);
380  } else {
381  max_eig = model->max_convective_eigenvalue(conservative_soln);
382  std::array<real,nstate_baseline_physics> baseline_conservative_soln;
383  for(int s=0; s<nstate_baseline_physics; ++s){
384  baseline_conservative_soln[s] = conservative_soln[s];
385  }
386  real baseline_max_eig = physics_baseline->max_convective_eigenvalue(baseline_conservative_soln);
387  max_eig = max_eig > baseline_max_eig ? max_eig : baseline_max_eig;
388  }
389  return max_eig;
390 }
391 
392 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
395  const std::array<real,nstate> &conservative_soln,
396  const dealii::Tensor<1,dim,real> &normal) const
397 {
398  real max_eig;
399  if constexpr(nstate==nstate_baseline_physics) {
400  max_eig = physics_baseline->max_convective_normal_eigenvalue(conservative_soln,normal);
401  } else {
402  max_eig = model->max_convective_normal_eigenvalue(conservative_soln,normal);
403  std::array<real,nstate_baseline_physics> baseline_conservative_soln;
404  for(int s=0; s<nstate_baseline_physics; ++s){
405  baseline_conservative_soln[s] = conservative_soln[s];
406  }
407  real baseline_max_eig = physics_baseline->max_convective_normal_eigenvalue(baseline_conservative_soln,normal);
408  max_eig = max_eig > baseline_max_eig ? max_eig : baseline_max_eig;
409  }
410  return max_eig;
411 }
412 
413 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
415 ::max_viscous_eigenvalue (const std::array<real,nstate> &/*conservative_soln*/) const
416 {
417  return 0.0;
418 }
419 
420 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
423  const int boundary_type,
424  const dealii::Point<dim, real> &pos,
425  const dealii::Tensor<1,dim,real> &normal_int,
426  const std::array<real,nstate> &soln_int,
427  const std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_int,
428  const std::array<real,nstate> &filtered_soln_int,
429  const std::array<dealii::Tensor<1,dim,real>,nstate> &filtered_soln_grad_int,
430  std::array<real,nstate> &soln_bc,
431  std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_bc) const
432 {
433  if constexpr(nstate==nstate_baseline_physics) {
434  physics_baseline->boundary_face_values_viscous_flux(
435  boundary_type, pos, normal_int, soln_int, soln_grad_int, filtered_soln_int, filtered_soln_grad_int,
436  soln_bc, soln_grad_bc);
437  } else {
438  std::array<real,nstate_baseline_physics> baseline_soln_int;
439  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_soln_grad_int;
440  for(int s=0; s<nstate_baseline_physics; ++s){
441  baseline_soln_int[s] = soln_int[s];
442  baseline_soln_grad_int[s] = soln_grad_int[s];
443  }
444 
445  std::array<real,nstate_baseline_physics> baseline_soln_bc;
446  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_soln_grad_bc;
447 
448  for (int istate=0; istate<nstate_baseline_physics; istate++) {
449  baseline_soln_bc[istate] = 0;
450  baseline_soln_grad_bc[istate] = 0;
451  }
452 
453  physics_baseline->boundary_face_values(
454  boundary_type, pos, normal_int, baseline_soln_int, baseline_soln_grad_int,
455  baseline_soln_bc, baseline_soln_grad_bc);
456  /*TO DO NOT IMPLEMENTED YET
457  model->boundary_face_values(
458  boundary_type, pos, normal_int, soln_int, soln_grad_int,
459  soln_bc, soln_grad_bc);*/
460 
461  for(int s=0; s<nstate_baseline_physics; ++s){
462  soln_bc[s] += baseline_soln_bc[s];
463  soln_grad_bc[s] += baseline_soln_grad_bc[s];
464  }
465  // Only boundary_manufactured_solution (id 1000) can be used currently
466  if (boundary_type != 1000) {
467  pcout << "Error: boundary_face_values_viscous_flux() not implemented for nstate!=nstate_baseline_physics." << std::endl;
468  pcout << "Aborting..." << std::endl;
469  std::abort(); // <-- TO DO NOT IMPLEMENTED YET
470  }
471  }
472 }
473 
474 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
477  const int boundary_type,
478  const dealii::Point<dim, real> &pos,
479  const dealii::Tensor<1,dim,real> &normal_int,
480  const std::array<real,nstate> &soln_int,
481  const std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_int,
482  std::array<real,nstate> &soln_bc,
483  std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_bc) const
484 {
485  if constexpr(nstate==nstate_baseline_physics) {
486  physics_baseline->boundary_face_values(
487  boundary_type, pos, normal_int, soln_int, soln_grad_int,
488  soln_bc, soln_grad_bc);
489  } else {
490  std::array<real,nstate_baseline_physics> baseline_soln_int;
491  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_soln_grad_int;
492  for(int s=0; s<nstate_baseline_physics; ++s){
493  baseline_soln_int[s] = soln_int[s];
494  baseline_soln_grad_int[s] = soln_grad_int[s];
495  }
496 
497  std::array<real,nstate_baseline_physics> baseline_soln_bc;
498  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_soln_grad_bc;
499 
500  for (int istate=0; istate<nstate_baseline_physics; istate++) {
501  baseline_soln_bc[istate] = 0;
502  baseline_soln_grad_bc[istate] = 0;
503  }
504 
505  physics_baseline->boundary_face_values(
506  boundary_type, pos, normal_int, baseline_soln_int, baseline_soln_grad_int,
507  baseline_soln_bc, baseline_soln_grad_bc);
508 
509  model->boundary_face_values(
510  boundary_type, pos, normal_int, soln_int, soln_grad_int,
511  soln_bc, soln_grad_bc);
512 
513  for(int s=0; s<nstate_baseline_physics; ++s){
514  soln_bc[s] += baseline_soln_bc[s];
515  soln_grad_bc[s] += baseline_soln_grad_bc[s];
516  }
517  }
518 }
519 
520 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
522  const dealii::Vector<double> &uh,
523  const std::vector<dealii::Tensor<1,dim> > &duh,
524  const std::vector<dealii::Tensor<2,dim> > &dduh,
525  const dealii::Tensor<1,dim> &normals,
526  const dealii::Point<dim> &evaluation_points) const
527 {
528  dealii::Vector<double> computed_quantities;
529  if constexpr(nstate==nstate_baseline_physics) {
530  computed_quantities = physics_baseline->post_compute_derived_quantities_vector(
531  uh, duh, dduh, normals, evaluation_points);
532  } else {
533  dealii::Vector<double> computed_quantities_model;
534  computed_quantities_model = model->post_compute_derived_quantities_vector(
535  uh, duh, dduh, normals, evaluation_points);
536  dealii::Vector<double> computed_quantities_base;
537  computed_quantities_base = physics_baseline->post_compute_derived_quantities_vector(
538  uh, duh, dduh, normals, evaluation_points);
539 
540  dealii::Vector<double> computed_quantities_total(computed_quantities_base.size()+computed_quantities_model.size());
541  for (unsigned int i=0;i<computed_quantities_base.size();i++){
542  computed_quantities_total(i) = computed_quantities_base(i);
543  }
544  for (unsigned int i=0;i<computed_quantities_model.size();i++){
545  computed_quantities_total(i+computed_quantities_base.size()) = computed_quantities_model(i);
546  }
547  computed_quantities = computed_quantities_total;
548  }
549  return computed_quantities;
550 }
551 
552 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
555 {
556  std::vector<std::string> names;
557  if constexpr(nstate==nstate_baseline_physics) {
558  names = physics_baseline->post_get_names();
559  } else {
560  std::vector<std::string> names_model;
561  names = physics_baseline->post_get_names();
562  names_model = model->post_get_names();
563  names.insert(names.end(),names_model.begin(),names_model.end());
564  }
565  return names;
566 }
567 
568 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
569 std::vector<dealii::DataComponentInterpretation::DataComponentInterpretation> PhysicsModel<dim,nspecies,nstate,real,nstate_baseline_physics>
571 {
572  namespace DCI = dealii::DataComponentInterpretation;
573  std::vector<DCI::DataComponentInterpretation> interpretation;
574  if constexpr(nstate==nstate_baseline_physics) {
575  interpretation = physics_baseline->post_get_data_component_interpretation();
576  } else {
577  std::vector<DCI::DataComponentInterpretation> interpretation_model;
578  interpretation = physics_baseline->post_get_data_component_interpretation();
579  interpretation_model = model->post_get_data_component_interpretation();
580  interpretation.insert(interpretation.end(),interpretation_model.begin(),interpretation_model.end());
581  }
582  return interpretation;
583 }
584 
585 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
588 {
589  if constexpr(nstate==nstate_baseline_physics) {
590  return physics_baseline->post_get_needed_update_flags();
591  } else {
592  return dealii::update_values | dealii::update_quadrature_points | dealii::update_gradients;
593  }
594 }
595 
596 //===========================================================================================
597 // Physics Model Filtered
598 //===========================================================================================
599 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
601  const Parameters::AllParameters *const parameters_input,
603  std::shared_ptr< ModelBase<dim,nspecies,nstate,real> > model_input,
605  const bool has_nonzero_diffusion,
606  const bool has_nonzero_physical_source)
607  : PhysicsModel<dim,nspecies,nstate,real,nstate_baseline_physics>(parameters_input,
608  baseline_physics_type,
609  model_input,
611  has_nonzero_diffusion,
612  has_nonzero_physical_source)
613 { }
614 
615 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
616 std::array<dealii::Tensor<1,dim,real>,nstate> PhysicsModelFiltered<dim,nspecies,nstate,real,nstate_baseline_physics>
618  const std::array<real,nstate> &solution,
619  const std::array<dealii::Tensor<1,dim,real>,nstate> &solution_gradient,
620  const std::array<real,nstate> &filtered_solution,
621  const std::array<dealii::Tensor<1,dim,real>,nstate> &filtered_solution_gradient,
622  const dealii::types::global_dof_index cell_index)
623 {
624  this->model->set_unfiltered_conservative_solution(solution);
625 
626  // Get baseline conservative solution with nstate_baseline_physics
627  std::array<real,nstate_baseline_physics> baseline_conservative_soln;
628  for(int s=0; s<nstate_baseline_physics; ++s){
629  baseline_conservative_soln[s] = solution[s];
630  }
631 
632  // Get baseline conservative solution gradient with nstate_baseline_physics
633  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_solution_gradient;
634  for(int s=0; s<nstate_baseline_physics; ++s){
635  for (int d=0; d<dim; ++d) {
636  baseline_solution_gradient[s][d] = solution_gradient[s][d];
637  }
638  }
639 
640  // Get baseline dissipative flux
641  /* Note: Even though the physics baseline dissipative flux does not depend on cell_index, we pass it
642  anyways to accomodate the pure virtual member function defined in the PhysicsBase class */
643  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_diss_flux
644  = this->physics_baseline->dissipative_flux(baseline_conservative_soln, baseline_solution_gradient, cell_index);
645 
646  // Initialize diss_flux as the model dissipative flux; NOTE: passing the filtered solution
647  std::array<dealii::Tensor<1,dim,real>,nstate> diss_flux = this->model->dissipative_flux(filtered_solution, filtered_solution_gradient, cell_index);
648 
649  // Add the baseline_diss_flux terms to diss_flux
650  for(int s=0; s<nstate_baseline_physics; ++s){
651  for (int d=0; d<dim; ++d) {
652  diss_flux[s][d] += baseline_diss_flux[s][d];
653  }
654  }
655  return diss_flux;
656 }
657 
658 template <int dim, int nspecies, int nstate, typename real, int nstate_baseline_physics>
661  const std::array<real,nstate> &solution,
662  const std::array<dealii::Tensor<1,dim,real>,nstate> &solution_gradient,
663  const std::array<real,nstate> &filtered_solution,
664  const std::array<dealii::Tensor<1,dim,real>,nstate> &filtered_solution_gradient,
665  const bool on_boundary,
666  const dealii::types::global_dof_index cell_index,
667  const dealii::Tensor<1,dim,real> &normal,
668  const int boundary_type)
669 {
670  this->model->set_unfiltered_conservative_solution(solution);
671  // Get baseline conservative solution with nstate_baseline_physics
672  std::array<real,nstate_baseline_physics> baseline_conservative_soln;
673  for(int s=0; s<nstate_baseline_physics; ++s){
674  baseline_conservative_soln[s] = solution[s];
675  }
676 
677  // Get baseline conservative solution gradient with nstate_baseline_physics
678  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_solution_gradient;
679  for(int s=0; s<nstate_baseline_physics; ++s){
680  for (int d=0; d<dim; ++d) {
681  baseline_solution_gradient[s][d] = solution_gradient[s][d];
682  }
683  }
684 
685  // Get baseline dissipative flux dot normal
686  /* Note: Even though the physics baseline dissipative flux does not depend on cell_index, we pass it
687  anyways to accomodate the pure virtual member function defined in the PhysicsBase class */
688  std::array<real,nstate_baseline_physics> baseline_diss_flux_dot_n
689  = this->physics_baseline->dissipative_flux_dot_normal(baseline_conservative_soln, baseline_solution_gradient, baseline_conservative_soln, baseline_solution_gradient, on_boundary, cell_index, normal, boundary_type);
690 
691  // Initialize diss_flux_dot_n as the model dissipative flux dot normal; NOTE: passing the filtered solution
692  std::array<real,nstate> diss_flux_dot_n = this->model->dissipative_flux_dot_normal(filtered_solution, filtered_solution_gradient, filtered_solution, filtered_solution_gradient, on_boundary, cell_index, normal, boundary_type);
693 
694  // Add the baseline_diss_flux_dot_n terms to diss_flux_dot_n
695  for(int s=0; s<nstate_baseline_physics; ++s){
696  diss_flux_dot_n[s] += baseline_diss_flux_dot_n[s];
697  }
698  return diss_flux_dot_n;
699 }
700 
701 
702 // Instantiate explicitly
703 #if PHILIP_SPECIES==1
704  // Define a sequence of possible types
705  #define POSSIBLE_TYPES (double)(FadType)(RadType)(FadFadType)(RadFadType)
706 
707  // Define a macro to instantiate RANS and RANS functions for a specific type
708  #define INSTANTIATE_TYPES(r, data, type) \
709  template class PhysicsModel < PHILIP_DIM, PHILIP_SPECIES, PHILIP_DIM+2, type , PHILIP_DIM+2 >; \
710  template class PhysicsModel < PHILIP_DIM, PHILIP_SPECIES, PHILIP_DIM+3, type , PHILIP_DIM+2 >; \
711  template class PhysicsModelFiltered < PHILIP_DIM, PHILIP_SPECIES, PHILIP_DIM+2, type , PHILIP_DIM+2 >; \
712  template class PhysicsModelFiltered < PHILIP_DIM, PHILIP_SPECIES, PHILIP_DIM+3, type , PHILIP_DIM+2 >;
713  BOOST_PP_SEQ_FOR_EACH(INSTANTIATE_TYPES, _, POSSIBLE_TYPES)
714 #endif
715 } // Physics namespace
716 } // PHiLiP namespace
std::array< real, nstate > convert_primitive_to_conservative(const std::array< real, nstate > &primitive_soln) const
Convert primitive solution to conservative solution.
std::array< real, nstate > physical_source_term(const dealii::Point< dim, real > &pos, 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
Physical source term.
dealii::ConditionalOStream pcout
ConditionalOStream.
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.
const bool has_nonzero_diffusion
Flag to signal that diffusion term is non-zero.
Definition: physics.h:59
virtual std::array< real, nstate > dissipative_flux_dot_normal(const std::array< real, nstate > &solution, const std::array< dealii::Tensor< 1, dim, real >, nstate > &solution_gradient, const std::array< real, nstate > &filtered_solution, const std::array< dealii::Tensor< 1, dim, real >, nstate > &filtered_solution_gradient, const bool on_boundary, const dealii::types::global_dof_index cell_index, const dealii::Tensor< 1, dim, real > &normal, const int boundary_type) override
Dissipative (i.e. viscous) flux: dot normal vector.
Base class from which Advection, Diffusion, ConvectionDiffusion, and Euler is derived.
Definition: physics.h:34
Manufactured solution used for grid studies to check convergence orders.
Physics Model equations. Derived from PhysicsBase, holds a baseline physics and model terms and equat...
Definition: physics_model.h:14
std::shared_ptr< PhysicsBase< dim, nspecies, nstate_baseline_physics, real > > physics_baseline
Baseline physics object with nstate==nstate_baseline_physics.
Definition: physics_model.h:40
real max_convective_eigenvalue(const std::array< real, nstate > &soln) const
Maximum convective eigenvalue.
PartialDifferentialEquation
Possible Partial Differential Equations to solve.
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)
Files for the baseline physics.
Definition: ADTypes.hpp:10
const bool has_nonzero_physical_source
Flag to signal that physical source term is non-zero.
Definition: physics.h:62
std::array< real, nstate > convective_eigenvalues(const std::array< real, nstate > &, const dealii::Tensor< 1, dim, real > &) const
std::shared_ptr< ManufacturedSolutionFunction< dim, nspecies, real > > manufactured_solution_function
Manufactured solution function.
Definition: physics.h:71
Physics model additional terms and equations to the baseline physics.
Definition: model.h:18
std::array< dealii::Tensor< 1, dim, real >, nstate > convective_flux(const std::array< real, nstate > &conservative_soln) const
Convective flux: .
Main parameter class that contains the various other sub-parameter classes.
PhysicsModelFiltered(const Parameters::AllParameters *const parameters_input, Parameters::AllParameters::PartialDifferentialEquation baseline_physics_type, std::shared_ptr< ModelBase< dim, nspecies, nstate, real > > model_input, std::shared_ptr< ManufacturedSolutionFunction< dim, nspecies, real > > manufactured_solution_function, const bool has_nonzero_diffusion, const bool has_nonzero_physical_source)
Constructor.
real max_viscous_eigenvalue(const std::array< real, nstate > &soln) const
Maximum viscous eigenvalue.
void boundary_face_values_viscous_flux(const int boundary_type, const dealii::Point< dim, real > &pos, const dealii::Tensor< 1, dim, real > &normal, const std::array< real, nstate > &soln_int, const std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_int, const std::array< real, nstate > &, const std::array< dealii::Tensor< 1, dim, real >, nstate > &, std::array< real, nstate > &soln_bc, std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_bc) const override
Boundary face values for viscous fluxes.
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
Convective Numerical Split Flux for split form.
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
std::array< real, nstate > compute_entropy_variables(const std::array< real, nstate > &conservative_soln) const
Computes the entropy variables.
std::vector< std::string > post_get_names() const
Returns names of the solution to be used by PhysicsPostprocessor to output current solution...
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 that does not require differentiation.
std::shared_ptr< ModelBase< dim, nspecies, nstate, real > > model
Model object.
Definition: physics_model.h:43
Create specified physics as PhysicsBase object.
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
Returns current vector solution to be used by PhysicsPostprocessor to output current solution...
std::array< dealii::Tensor< 1, dim, real >, nstate > dissipative_flux(const std::array< real, nstate > &solution, const std::array< dealii::Tensor< 1, dim, real >, nstate > &solution_gradient, const std::array< real, nstate > &filtered_solution, const std::array< dealii::Tensor< 1, dim, real >, nstate > &filtered_solution_gradient, const dealii::types::global_dof_index cell_index) override
Dissipative (i.e. viscous) flux: .
dealii::UpdateFlags post_get_needed_update_flags() const
Returns required update flags of the solution to be used by PhysicsPostprocessor to output current so...
void boundary_face_values(const int, const dealii::Point< dim, real > &, const dealii::Tensor< 1, dim, real > &, const std::array< real, nstate > &, const std::array< dealii::Tensor< 1, dim, real >, nstate > &, std::array< real, nstate > &, std::array< dealii::Tensor< 1, dim, real >, nstate > &) const
Evaluates boundary values and gradients on the other side of the face.
virtual std::array< dealii::Tensor< 1, dim, real >, nstate > dissipative_flux(const std::array< real, nstate > &solution, const std::array< dealii::Tensor< 1, dim, real >, nstate > &solution_gradient, const std::array< real, nstate > &filtered_solution, const std::array< dealii::Tensor< 1, dim, real >, nstate > &filtered_solution_gradient, const dealii::types::global_dof_index cell_index) override
Dissipative (i.e. viscous) flux: .
std::vector< dealii::DataComponentInterpretation::DataComponentInterpretation > post_get_data_component_interpretation() const
Returns DataComponentInterpretation of the solution to be used by PhysicsPostprocessor to output curr...
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
PhysicsModel(const Parameters::AllParameters *const parameters_input, Parameters::AllParameters::PartialDifferentialEquation baseline_physics_type, std::shared_ptr< ModelBase< dim, nspecies, nstate, real > > model_input, std::shared_ptr< ManufacturedSolutionFunction< dim, nspecies, real > > manufactured_solution_function, const bool has_nonzero_diffusion, const bool has_nonzero_physical_source)
Constructor.
std::array< real, nstate > dissipative_flux_dot_normal(const std::array< real, nstate > &solution, const std::array< dealii::Tensor< 1, dim, real >, nstate > &solution_gradient, const std::array< real, nstate > &filtered_solution, const std::array< dealii::Tensor< 1, dim, real >, nstate > &filtered_solution_gradient, const bool on_boundary, const dealii::types::global_dof_index cell_index, const dealii::Tensor< 1, dim, real > &normal, const int boundary_type) override
Dissipative (i.e. viscous) flux: dot normal vector.
std::array< real, nstate > convert_conservative_to_primitive(const std::array< real, nstate > &conservative_soln) const
Convert conservative variables to primitive variables.