[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 
5 #include "ADTypes.hpp"
6 
7 #include "physics.h"
8 #include "euler.h"
9 #include "navier_stokes.h"
10 
11 #include "physics_model.h"
12 #include "physics_factory.h"
13 #include "model.h"
14 
15 namespace PHiLiP {
16 namespace Physics {
17 
18 template <int dim, int nstate, typename real, int nstate_baseline_physics>
20  const Parameters::AllParameters *const parameters_input,
22  std::shared_ptr< ModelBase<dim,nstate,real> > model_input,
23  std::shared_ptr< ManufacturedSolutionFunction<dim,real> > manufactured_solution_function,
24  const bool has_nonzero_diffusion,
25  const bool has_nonzero_physical_source)
26  : PhysicsBase<dim,nstate,real>(parameters_input, has_nonzero_diffusion, has_nonzero_physical_source, manufactured_solution_function)
27  , n_model_equations(nstate-nstate_baseline_physics)
28  , physics_baseline(PhysicsFactory<dim,nstate_baseline_physics,real>::create_Physics(parameters_input, baseline_physics_type))
29  , model(model_input)
30  , mpi_communicator(MPI_COMM_WORLD)
31  , mpi_rank(dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD))
32  , n_mpi(dealii::Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD))
33  , pcout(std::cout, mpi_rank==0)
34 { }
35 
36 template <int dim, int nstate, typename real, int nstate_baseline_physics>
37 std::array<dealii::Tensor<1,dim,real>,nstate> PhysicsModel<dim,nstate,real,nstate_baseline_physics>
38 ::convective_flux (const std::array<real,nstate> &conservative_soln) const
39 {
40  // Get baseline conservative solution with nstate_baseline_physics
41  std::array<real,nstate_baseline_physics> baseline_conservative_soln;
42  for(int s=0; s<nstate_baseline_physics; ++s){
43  baseline_conservative_soln[s] = conservative_soln[s];
44  }
45 
46  // Get baseline convective flux
47  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_conv_flux
48  = physics_baseline->convective_flux(baseline_conservative_soln);
49 
50  // Initialize conv_flux as the model convective flux
51  std::array<dealii::Tensor<1,dim,real>,nstate> conv_flux = model->convective_flux(conservative_soln);
52 
53  // Add the baseline_conv_flux terms to conv_flux
54  for(int s=0; s<nstate_baseline_physics; ++s){
55  for (int d=0; d<dim; ++d) {
56  conv_flux[s][d] += baseline_conv_flux[s][d];
57  }
58  }
59  return conv_flux;
60 }
61 
62 template <int dim, int nstate, typename real, int nstate_baseline_physics>
63 std::array<dealii::Tensor<1,dim,real>,nstate> PhysicsModel<dim,nstate,real,nstate_baseline_physics>
65  const std::array<real,nstate> &conservative_soln,
66  const std::array<dealii::Tensor<1,dim,real>,nstate> &solution_gradient,
67  const dealii::types::global_dof_index cell_index) const
68 {
69  // Get baseline conservative solution with nstate_baseline_physics
70  std::array<real,nstate_baseline_physics> baseline_conservative_soln;
71  for(int s=0; s<nstate_baseline_physics; ++s){
72  baseline_conservative_soln[s] = conservative_soln[s];
73  }
74 
75  // Get baseline conservative solution gradient with nstate_baseline_physics
76  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_solution_gradient;
77  for(int s=0; s<nstate_baseline_physics; ++s){
78  for (int d=0; d<dim; ++d) {
79  baseline_solution_gradient[s][d] = solution_gradient[s][d];
80  }
81  }
82 
83  // Get baseline dissipative flux
84  /* Note: Even though the physics baseline dissipative flux does not depend on cell_index, we pass it
85  anyways to accomodate the pure virtual member function defined in the PhysicsBase class */
86  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_diss_flux
87  = physics_baseline->dissipative_flux(baseline_conservative_soln, baseline_solution_gradient, cell_index);
88 
89  // Initialize diss_flux as the model dissipative flux
90  std::array<dealii::Tensor<1,dim,real>,nstate> diss_flux = model->dissipative_flux(conservative_soln, solution_gradient, cell_index);
91 
92  // Add the baseline_diss_flux terms to diss_flux
93  for(int s=0; s<nstate_baseline_physics; ++s){
94  for (int d=0; d<dim; ++d) {
95  diss_flux[s][d] += baseline_diss_flux[s][d];
96  }
97  }
98  return diss_flux;
99 }
100 
101 template <int dim, int nstate, typename real, int nstate_baseline_physics>
104  const dealii::Point<dim,real> &pos,
105  const std::array<real,nstate> &conservative_soln,
106  const std::array<dealii::Tensor<1,dim,real>,nstate> &solution_gradient,
107  const dealii::types::global_dof_index cell_index) const
108 {
109  // Initialize physical_source_term as the model source term
110  std::array<real,nstate> physical_source_term = model->physical_source_term(pos, conservative_soln, solution_gradient, cell_index);
111 
112  // Get baseline conservative solution with nstate_baseline_physics
113  std::array<real,nstate_baseline_physics> baseline_conservative_soln;
114  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_solution_gradient;
115  for(int s=0; s<nstate_baseline_physics; ++s){
116  baseline_conservative_soln[s] = conservative_soln[s];
117  baseline_solution_gradient[s] = solution_gradient[s];
118  }
119 
120  // Get the baseline physics physical source term
121  /* Note: Even though the physics baseline source term does not depend on cell_index, we pass it
122  anyways to accomodate the pure virtual member function defined in the PhysicsBase class */
123  std::array<real,nstate_baseline_physics> baseline_physical_source_term = physics_baseline->physical_source_term(pos,baseline_conservative_soln,baseline_solution_gradient,cell_index);
124 
125  // Add the baseline_physical_source_term terms to source_term
126  for(int s=0; s<nstate_baseline_physics; ++s){
127  physical_source_term[s] += baseline_physical_source_term[s];
128  }
129 
130  return physical_source_term;
131 }
132 
133 template <int dim, int nstate, typename real, int nstate_baseline_physics>
136  const dealii::Point<dim,real> &pos,
137  const std::array<real,nstate> &conservative_soln,
138  const real current_time,
139  const dealii::types::global_dof_index cell_index) const
140 {
141  // Initialize source_term as the model source term
142  std::array<real,nstate> source_term = model->source_term(
143  pos,
144  conservative_soln,
145  current_time,
146  cell_index);
147 
148  // Get baseline conservative solution with nstate_baseline_physics
149  std::array<real,nstate_baseline_physics> baseline_conservative_soln;
150  for(int s=0; s<nstate_baseline_physics; ++s){
151  baseline_conservative_soln[s] = conservative_soln[s];
152  }
153 
154  // Get the baseline physics source term
155  /* Note: Even though the physics baseline source term does not depend on cell_index, we pass it
156  anyways to accomodate the pure virtual member function defined in the PhysicsBase class */
157  std::array<real,nstate_baseline_physics> baseline_source_term = physics_baseline->source_term(
158  pos,
159  baseline_conservative_soln,
160  current_time,
161  cell_index);
162 
163  // Add the baseline_source_term terms to source_term
164  for(int s=0; s<nstate_baseline_physics; ++s){
165  source_term[s] += baseline_source_term[s];
166  }
167 
168  return source_term;
169 }
170 
171 template <int dim, int nstate, typename real, int nstate_baseline_physics>
172 std::array<dealii::Tensor<1,dim,real>,nstate> PhysicsModel<dim,nstate,real,nstate_baseline_physics>
173 ::convective_numerical_split_flux(const std::array<real,nstate> &conservative_soln1,
174  const std::array<real,nstate> &conservative_soln2) const
175 {
176  std::array<dealii::Tensor<1,dim,real>,nstate> conv_num_split_flux;
177  if constexpr(nstate==nstate_baseline_physics) {
178  conv_num_split_flux = physics_baseline->convective_numerical_split_flux(conservative_soln1,conservative_soln2);
179  } else {
180  pcout << "Error: convective_numerical_split_flux() not implemented for nstate!=nstate_baseline_physics." << std::endl;
181  pcout << "Aborting..." << std::endl;
182  std::abort();
183  }
184  return conv_num_split_flux;
185 }
186 
187 template <int dim, int nstate, typename real, int nstate_baseline_physics>
190  const std::array<real,nstate> &conservative_soln) const
191 {
192  std::array<real,nstate> entropy_var;
193  if constexpr(nstate==nstate_baseline_physics) {
194  entropy_var = physics_baseline->compute_entropy_variables(conservative_soln);
195  } else {
196  // TO DO, make use of the physics_model object for nstate>nstate_baseline_physics
197  std::abort();
198  }
199  return entropy_var;
200 }
201 
202 template <int dim, int nstate, typename real, int nstate_baseline_physics>
205  const std::array<real,nstate> &entropy_var) const
206 {
207  std::array<real,nstate> conservative_soln;
208  if constexpr(nstate==nstate_baseline_physics) {
209  conservative_soln = physics_baseline->compute_conservative_variables_from_entropy_variables(entropy_var);
210  } else {
211  // TO DO, make use of the physics_model object for nstate>nstate_baseline_physics
212  std::abort();
213  }
214  return conservative_soln;
215 }
216 
217 template <int dim, int nstate, typename real, int nstate_baseline_physics>
220  const std::array<real,nstate> &conservative_soln,
221  const dealii::Tensor<1,dim,real> &normal) const
222 {
223  std::array<real,nstate> eig;
224  if constexpr(nstate==nstate_baseline_physics) {
225  eig = physics_baseline->convective_eigenvalues(conservative_soln, normal);
226  } else {
227  eig = model->convective_eigenvalues(conservative_soln, normal);
228  std::array<real,nstate_baseline_physics> baseline_conservative_soln;
229  for(int s=0; s<nstate_baseline_physics; ++s){
230  baseline_conservative_soln[s] = conservative_soln[s];
231  }
232  std::array<real,nstate_baseline_physics> baseline_eig = physics_baseline->convective_eigenvalues(baseline_conservative_soln, normal);
233  for(int s=0; s<nstate_baseline_physics; ++s){
234  if(eig[s]!=0.0){
235  pcout << "Error: PhysicsModel does not currently support additional convective flux terms." << std::endl;
236  pcout << "Aborting..." << std::endl;
237  std::abort();
238  } else {
239  eig[s] += baseline_eig[s];
240  }
241  }
242  }
243 
244  return eig;
245 }
246 
247 template <int dim, int nstate, typename real, int nstate_baseline_physics>
249 ::max_convective_eigenvalue (const std::array<real,nstate> &conservative_soln) const
250 {
251  real max_eig;
252  if constexpr(nstate==nstate_baseline_physics) {
253  max_eig = physics_baseline->max_convective_eigenvalue(conservative_soln);
254  } else {
255  max_eig = model->max_convective_eigenvalue(conservative_soln);
256  std::array<real,nstate_baseline_physics> baseline_conservative_soln;
257  for(int s=0; s<nstate_baseline_physics; ++s){
258  baseline_conservative_soln[s] = conservative_soln[s];
259  }
260  real baseline_max_eig = physics_baseline->max_convective_eigenvalue(baseline_conservative_soln);
261  max_eig = max_eig > baseline_max_eig ? max_eig : baseline_max_eig;
262  }
263  return max_eig;
264 }
265 
266 template <int dim, int nstate, typename real, int nstate_baseline_physics>
269  const std::array<real,nstate> &conservative_soln,
270  const dealii::Tensor<1,dim,real> &normal) const
271 {
272  real max_eig;
273  if constexpr(nstate==nstate_baseline_physics) {
274  max_eig = physics_baseline->max_convective_normal_eigenvalue(conservative_soln,normal);
275  } else {
276  max_eig = model->max_convective_normal_eigenvalue(conservative_soln,normal);
277  std::array<real,nstate_baseline_physics> baseline_conservative_soln;
278  for(int s=0; s<nstate_baseline_physics; ++s){
279  baseline_conservative_soln[s] = conservative_soln[s];
280  }
281  real baseline_max_eig = physics_baseline->max_convective_normal_eigenvalue(baseline_conservative_soln,normal);
282  max_eig = max_eig > baseline_max_eig ? max_eig : baseline_max_eig;
283  }
284  return max_eig;
285 }
286 
287 template <int dim, int nstate, typename real, int nstate_baseline_physics>
289 ::max_viscous_eigenvalue (const std::array<real,nstate> &/*conservative_soln*/) const
290 {
291  return 0.0;
292 }
293 
294 template <int dim, int nstate, typename real, int nstate_baseline_physics>
297  const int boundary_type,
298  const dealii::Point<dim, real> &pos,
299  const dealii::Tensor<1,dim,real> &normal_int,
300  const std::array<real,nstate> &soln_int,
301  const std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_int,
302  std::array<real,nstate> &soln_bc,
303  std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_bc) const
304 {
305  if constexpr(nstate==nstate_baseline_physics) {
306  physics_baseline->boundary_face_values(
307  boundary_type, pos, normal_int, soln_int, soln_grad_int,
308  soln_bc, soln_grad_bc);
309  } else {
310  std::array<real,nstate_baseline_physics> baseline_soln_int;
311  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_soln_grad_int;
312  for(int s=0; s<nstate_baseline_physics; ++s){
313  baseline_soln_int[s] = soln_int[s];
314  baseline_soln_grad_int[s] = soln_grad_int[s];
315  }
316 
317  std::array<real,nstate_baseline_physics> baseline_soln_bc;
318  std::array<dealii::Tensor<1,dim,real>,nstate_baseline_physics> baseline_soln_grad_bc;
319 
320  for (int istate=0; istate<nstate_baseline_physics; istate++) {
321  baseline_soln_bc[istate] = 0;
322  baseline_soln_grad_bc[istate] = 0;
323  }
324 
325  physics_baseline->boundary_face_values(
326  boundary_type, pos, normal_int, baseline_soln_int, baseline_soln_grad_int,
327  baseline_soln_bc, baseline_soln_grad_bc);
328 
329  model->boundary_face_values(
330  boundary_type, pos, normal_int, soln_int, soln_grad_int,
331  soln_bc, soln_grad_bc);
332 
333  for(int s=0; s<nstate_baseline_physics; ++s){
334  soln_bc[s] += baseline_soln_bc[s];
335  soln_grad_bc[s] += baseline_soln_grad_bc[s];
336  }
337  }
338 }
339 
340 template <int dim, int nstate, typename real, int nstate_baseline_physics>
342  const dealii::Vector<double> &uh,
343  const std::vector<dealii::Tensor<1,dim> > &duh,
344  const std::vector<dealii::Tensor<2,dim> > &dduh,
345  const dealii::Tensor<1,dim> &normals,
346  const dealii::Point<dim> &evaluation_points) const
347 {
348  dealii::Vector<double> computed_quantities;
349  if constexpr(nstate==nstate_baseline_physics) {
350  computed_quantities = physics_baseline->post_compute_derived_quantities_vector(
351  uh, duh, dduh, normals, evaluation_points);
352  } else {
353  dealii::Vector<double> computed_quantities_model;
354  computed_quantities_model = model->post_compute_derived_quantities_vector(
355  uh, duh, dduh, normals, evaluation_points);
356  dealii::Vector<double> computed_quantities_base;
357  computed_quantities_base = physics_baseline->post_compute_derived_quantities_vector(
358  uh, duh, dduh, normals, evaluation_points);
359 
360  dealii::Vector<double> computed_quantities_total(computed_quantities_base.size()+computed_quantities_model.size());
361  for (unsigned int i=0;i<computed_quantities_base.size();i++){
362  computed_quantities_total(i) = computed_quantities_base(i);
363  }
364  for (unsigned int i=0;i<computed_quantities_model.size();i++){
365  computed_quantities_total(i+computed_quantities_base.size()) = computed_quantities_model(i);
366  }
367  computed_quantities = computed_quantities_total;
368  }
369  return computed_quantities;
370 }
371 
372 template <int dim, int nstate, typename real, int nstate_baseline_physics>
375 {
376  std::vector<std::string> names;
377  if constexpr(nstate==nstate_baseline_physics) {
378  names = physics_baseline->post_get_names();
379  } else {
380  std::vector<std::string> names_model;
381  names = physics_baseline->post_get_names();
382  names_model = model->post_get_names();
383  names.insert(names.end(),names_model.begin(),names_model.end());
384  }
385  return names;
386 }
387 
388 template <int dim, int nstate, typename real, int nstate_baseline_physics>
389 std::vector<dealii::DataComponentInterpretation::DataComponentInterpretation> PhysicsModel<dim,nstate,real,nstate_baseline_physics>
391 {
392  namespace DCI = dealii::DataComponentInterpretation;
393  std::vector<DCI::DataComponentInterpretation> interpretation;
394  if constexpr(nstate==nstate_baseline_physics) {
395  interpretation = physics_baseline->post_get_data_component_interpretation();
396  } else {
397  std::vector<DCI::DataComponentInterpretation> interpretation_model;
398  interpretation = physics_baseline->post_get_data_component_interpretation();
399  interpretation_model = model->post_get_data_component_interpretation();
400  interpretation.insert(interpretation.end(),interpretation_model.begin(),interpretation_model.end());
401  }
402  return interpretation;
403 }
404 
405 template <int dim, int nstate, typename real, int nstate_baseline_physics>
408 {
409  // Note: This is the exact same function as in the class PhysicsBase::Euler
410  //return update_values | update_gradients;
411  return dealii::update_values
412  | dealii::update_quadrature_points
413  ;
414 }
415 
416 // Instantiate explicitly
422 
428 
429 } // Physics namespace
430 } // PHiLiP namespace
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 > &conservative_soln, const std::array< dealii::Tensor< 1, dim, real >, nstate > &solution_gradient, const dealii::types::global_dof_index cell_index) const
Dissipative (i.e. viscous) flux: .
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
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.
PartialDifferentialEquation
Possible Partial Differential Equations to solve.
Files for the baseline physics.
Definition: ADTypes.hpp:10
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.
std::vector< dealii::DataComponentInterpretation::DataComponentInterpretation > post_get_data_component_interpretation() const
Returns DataComponentInterpretation of the solution to be used by PhysicsPostprocessor to output curr...
Physics model additional terms and equations to the baseline physics.
Definition: model.h:18
Main parameter class that contains the various other sub-parameter classes.
std::array< dealii::Tensor< 1, dim, real >, nstate > convective_flux(const std::array< real, nstate > &conservative_soln) const
Convective flux: .
real max_viscous_eigenvalue(const std::array< real, nstate > &soln) const
Maximum viscous eigenvalue.
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::array< real, nstate > convective_eigenvalues(const std::array< real, nstate > &, const dealii::Tensor< 1, dim, real > &) const
real max_convective_eigenvalue(const std::array< real, nstate > &soln) const
Maximum convective eigenvalue.
std::shared_ptr< PhysicsBase< dim, nstate_baseline_physics, real > > physics_baseline
Baseline physics object with nstate==nstate_baseline_physics.
Definition: physics_model.h:30
std::array< real, nstate > compute_entropy_variables(const std::array< real, nstate > &conservative_soln) const
Computes the entropy variables.
Create specified physics as PhysicsBase object.
std::shared_ptr< ModelBase< dim, nstate, real > > model
Model object.
Definition: physics_model.h:33
dealii::ConditionalOStream pcout
ConditionalOStream.
dealii::UpdateFlags post_get_needed_update_flags() const
Returns required update flags of the solution to be used by PhysicsPostprocessor to output current so...
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.
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)
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.
PhysicsModel(const Parameters::AllParameters *const parameters_input, Parameters::AllParameters::PartialDifferentialEquation baseline_physics_type, std::shared_ptr< ModelBase< dim, nstate, real > > model_input, std::shared_ptr< ManufacturedSolutionFunction< dim, real > > manufactured_solution_function, const bool has_nonzero_diffusion, const bool has_nonzero_physical_source)
Constructor.