[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
physics.cpp
1 #include <assert.h>
2 #include <cmath>
3 #include <vector>
4 #include <stdlib.h>
5 #include <deal.II/base/utilities.h>
6 #include <deal.II/base/mpi.h>
7 #include <boost/preprocessor/seq/for_each.hpp>
8 
9 #include "ADTypes.hpp"
10 
11 #include "physics.h"
12 
13 namespace PHiLiP {
14 namespace Physics {
15 
16 template <int dim, int nspecies, int nstate, typename real>
18  const Parameters::AllParameters *const parameters_input,
19  const bool has_nonzero_diffusion_input,
20  const bool has_nonzero_physical_source_input,
21  const dealii::Tensor<2,3,double> input_diffusion_tensor,
22  std::shared_ptr< ManufacturedSolutionFunction<dim,nspecies,real> > manufactured_solution_function_input)
23  : has_nonzero_diffusion(has_nonzero_diffusion_input)
24  , has_nonzero_physical_source(has_nonzero_physical_source_input)
25  , all_parameters(parameters_input)
26  , non_physical_behavior_type(all_parameters->non_physical_behavior_type)
27  , manufactured_solution_function(manufactured_solution_function_input)
28  , pcout(std::cout, dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD)==0)
29 {
30  // if provided with a null ptr, give it the default manufactured solution
31  // currently only necessary for the unit test
32  if(!manufactured_solution_function)
33  manufactured_solution_function = std::make_shared<ManufacturedSolutionSine<dim,nspecies,real>>(nstate);
34 
35  // anisotropic diffusion matrix
36  diffusion_tensor[0][0] = input_diffusion_tensor[0][0];
37  if constexpr(dim >= 2) {
38  diffusion_tensor[0][1] = input_diffusion_tensor[0][1];
39  diffusion_tensor[1][0] = input_diffusion_tensor[1][0];
40  diffusion_tensor[1][1] = input_diffusion_tensor[1][1];
41  }
42  if constexpr(dim >= 3) {
43  diffusion_tensor[0][2] = input_diffusion_tensor[0][2];
44  diffusion_tensor[2][0] = input_diffusion_tensor[2][0];
45  diffusion_tensor[1][2] = input_diffusion_tensor[1][2];
46  diffusion_tensor[2][1] = input_diffusion_tensor[2][1];
47  diffusion_tensor[2][2] = input_diffusion_tensor[2][2];
48  }
49 }
50 
51 template <int dim, int nspecies, int nstate, typename real>
53  const Parameters::AllParameters *const parameters_input,
54  const bool has_nonzero_diffusion_input,
55  const bool has_nonzero_physical_source_input,
56  std::shared_ptr< ManufacturedSolutionFunction<dim,nspecies,real> > manufactured_solution_function_input)
57  : PhysicsBase<dim,nspecies,nstate,real>(
58  parameters_input,
59  has_nonzero_diffusion_input,
60  has_nonzero_physical_source_input,
61  Parameters::ManufacturedSolutionParam::get_default_diffusion_tensor(),
62  manufactured_solution_function_input)
63 { }
64 
65 template <int dim, int nspecies, int nstate, typename real>
66 std::array<dealii::Tensor<1,dim,real>,nstate> PhysicsBase<dim,nspecies,nstate,real>::convective_numerical_split_flux (
67  const std::array<real,nstate> &/*conservative_soln1*/,
68  const std::array<real,nstate> &/*conservative_soln2*/) const
69 {
70  pcout << "ERROR: convective_numerical_split_flux() has not yet been implemented for (overridden by) the selected PDE. Aborting..." <<std::flush;
71  std::abort();
72  std::array<dealii::Tensor<1,dim,real>,nstate> dummy;
73  return dummy;
74 }
75 
76 template <int dim, int nspecies, int nstate, typename real>
79  const std::array<real,nstate> &conservative_soln,
80  const dealii::Tensor<1,dim,real> &/*normal*/) const
81 {
82  return max_convective_eigenvalue(conservative_soln);
83 }
84 
85 /*
86 template <int dim, int nspecies, int nstate, typename real>
87 std::array<dealii::Tensor<1,dim,real>,nstate> PhysicsBase<dim,nspecies,nstate,real>
88 ::artificial_dissipative_flux (
89  const real viscosity_coefficient,
90  const std::array<real,nstate> &,//solution,
91  const std::array<dealii::Tensor<1,dim,real>,nstate> &solution_gradient) const
92 {
93  std::array<dealii::Tensor<1,dim,real>,nstate> diss_flux;
94  for (int i=0; i<nstate; i++) {
95  for (int d=0; d<dim; d++) {
96  diss_flux[i][d] = -viscosity_coefficient*(solution_gradient[i][d]);
97  }
98  }
99  return diss_flux;
100 }
101 */
102 
103 template <int dim, int nspecies, int nstate, typename real>
104 std::array<real,nstate> PhysicsBase<dim,nspecies,nstate,real>
106  const std::array<real,nstate> &solution,
107  const std::array<dealii::Tensor<1,dim,real>,nstate> &solution_gradient,
108  const std::array<real,nstate> &filtered_solution,
109  const std::array<dealii::Tensor<1,dim,real>,nstate> &filtered_solution_gradient,
110  const bool /*on_boundary*/,
111  const dealii::types::global_dof_index cell_index,
112  const dealii::Tensor<1,dim,real> &normal,
113  const int /*boundary_type*/)
114 {
115  std::array<dealii::Tensor<1,dim,real>,nstate> dissipative_flux = this->dissipative_flux(solution,solution_gradient,filtered_solution,filtered_solution_gradient,cell_index);
116  std::array<real,nstate> dissipative_flux_dot_normal;
117  dissipative_flux_dot_normal.fill(0.0); // initialize
118  for (int s=0; s<nstate; s++) {
119  for (int d=0; d<dim; ++d) {
120  dissipative_flux_dot_normal[s] += dissipative_flux[s][d] * normal[d];//compute dot product
121  }
122  }
123  return dissipative_flux_dot_normal;
124 }
125 
126 template <int dim, int nspecies, int nstate, typename real>
127 std::array<dealii::Tensor<1,dim,real>,nstate> PhysicsBase<dim,nspecies,nstate,real>
129  const std::array<real,nstate> &solution,
130  const std::array<dealii::Tensor<1,dim,real>,nstate> &solution_gradient,
131  const std::array<real,nstate> &/*filtered_solution*/,
132  const std::array<dealii::Tensor<1,dim,real>,nstate> &/*filtered_solution_gradient*/,
133  const dealii::types::global_dof_index cell_index)
134 {
135  return this->dissipative_flux(solution,solution_gradient,cell_index);
136 }
137 
138 template <int dim, int nspecies, int nstate, typename real>
139 std::array<real,nstate> PhysicsBase<dim,nspecies,nstate,real>
141  const real viscosity_coefficient,
142  const dealii::Point<dim,real> &pos,
143  const std::array<real,nstate> &/*solution*/) const
144 {
145  std::array<real,nstate> source;
146 
147  dealii::Tensor<2,dim,double> artificial_diffusion_tensor;
148  for (int i=0;i<dim;i++)
149  for (int j=0;j<dim;j++)
150  artificial_diffusion_tensor[i][j] = (i==j) ? 1.0 : 0.0;
151 
152  for (int istate=0; istate<nstate; istate++) {
153  dealii::SymmetricTensor<2,dim,real> manufactured_hessian = this->manufactured_solution_function->hessian (pos, istate);
154  //source[istate] = -viscosity_coefficient*scalar_product(artificial_diffusion_tensor,manufactured_hessian);
155  source[istate] = 0.0;
156  for (int dr=0; dr<dim; ++dr) {
157  for (int dc=0; dc<dim; ++dc) {
158  source[istate] += artificial_diffusion_tensor[dr][dc] * manufactured_hessian[dr][dc];
159  }
160  }
161  source[istate] *= -viscosity_coefficient;
162  }
163  return source;
164 }
165 
166 template <int dim, int nspecies, int nstate, typename real>
168 ::compute_pressure ( const std::array<real,nstate> &/*conservative_soln*/ ) const
169 {
170  std::cout << "The compute_pressure function has not been implemented for this PDE...Aborting." << std::endl;
171  std::abort();
172  return 0;
173 }
174 
175 template <int dim, int nspecies, int nstate, typename real>
177 ::compute_entropy ( const std::array<real,nstate> &/*conservative_soln*/ ) const
178 {
179  std::cout << "The compute_entropy function has not been implemented for this PDE...Aborting." << std::endl;
180  std::abort();
181  return 0;
182 }
183 
184 template <int dim, int nspecies, int nstate, typename real>
186 ::compute_gamma ( const std::array<real,nstate> &/*conservative_soln*/ ) const
187 {
188  std::cout << "The compute_gamma function has not been implemented for this PDE...Aborting." << std::endl;
189  std::abort();
190  return 0;
191 }
192 
193 template <int dim, int nspecies, int nstate, typename real>
194 std::array<real,nstate> PhysicsBase<dim,nspecies,nstate,real>
195 ::compute_kinetic_energy_variables ( const std::array<real,nstate> &/*conservative_soln*/ ) const
196 {
197  std::cout << "The compute_kinetic_energy_variables function has not been implemented for this PDE...Aborting." << std::endl;
198  std::abort();
199 
200  std::array<real,nstate> kinetic_energy_var;
201  std::fill(kinetic_energy_var.begin(), kinetic_energy_var.end(), 0.0);
202 
203  return kinetic_energy_var;
204 }
205 
206 template <int dim, int nspecies, int nstate, typename real>
209  const int boundary_type,
210  const dealii::Point<dim, real> &pos,
211  const dealii::Tensor<1,dim,real> &normal,
212  const std::array<real,nstate> &soln_int,
213  const std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_int,
214  const std::array<real,nstate> &/*filtered_soln_int*/,
215  const std::array<dealii::Tensor<1,dim,real>,nstate> &/*filtered_soln_grad_int*/,
216  std::array<real,nstate> &soln_bc,
217  std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_bc) const
218 {
219  this->boundary_face_values(boundary_type,
220  pos,
221  normal,
222  soln_int,
223  soln_grad_int,
224  soln_bc,
225  soln_grad_bc);
226 }
227 
228 template <int dim, int nspecies, int nstate, typename real>
231  const int boundary_type,
232  const dealii::Point<dim, real> &pos,
233  const dealii::Tensor<1,dim,real> &normal,
234  const std::array<real,nstate> &soln_int,
235  const std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_int,
236  const std::array<real,nstate> &/*filtered_soln_int*/,
237  const std::array<dealii::Tensor<1,dim,real>,nstate> &/*filtered_soln_grad_int*/,
238  std::array<real,nstate> &soln_bc,
239  std::array<dealii::Tensor<1,dim,real>,nstate> &soln_grad_bc) const
240 {
241  this->boundary_face_values(boundary_type,
242  pos,
243  normal,
244  soln_int,
245  soln_grad_int,
246  soln_bc,
247  soln_grad_bc);
248 }
249 
250 template <int dim, int nspecies, int nstate, typename real>
251 std::array<real,nstate> PhysicsBase<dim,nspecies,nstate,real>
253  const dealii::Point<dim,real> &/*pos*/,
254  const std::array<real,nstate> &/*solution*/,
255  const std::array<dealii::Tensor<1,dim,real>,nstate> &/*solution_gradient*/,
256  const dealii::types::global_dof_index /*cell_index*/) const
257 {
258  std::array<real,nstate> physical_source;
259  for (int i=0; i<nstate; i++) {
260  physical_source[i] = 0;
261  }
262  return physical_source;
263 }
264 
265 template <int dim, int nspecies, int nstate, typename real>
267  const dealii::Vector<double> &uh,
268  const std::vector<dealii::Tensor<1,dim> > &/*duh*/,
269  const std::vector<dealii::Tensor<2,dim> > &/*dduh*/,
270  const dealii::Tensor<1,dim> &/*normals*/,
271  const dealii::Point<dim> &/*evaluation_points*/) const
272 {
273  dealii::Vector<double> computed_quantities(nstate);
274  for (unsigned int s=0; s<nstate; ++s) {
275  computed_quantities(s) = uh(s);
276  }
277  return computed_quantities;
278 }
279 
280 template <int dim, int nspecies, int nstate, typename real>
282  const double &uh,
283  const dealii::Tensor<1,dim> &/*duh*/,
284  const dealii::Tensor<2,dim> &/*dduh*/,
285  const dealii::Tensor<1,dim> &/*normals*/,
286  const dealii::Point<dim> &/*evaluation_points*/) const
287 {
288  assert(nstate == 1);
289  dealii::Vector<double> computed_quantities(nstate);
290  for (unsigned int s=0; s<nstate; ++s) {
291  computed_quantities(s) = uh;
292  }
293  return computed_quantities;
294 }
295 
296 template <int dim, int nspecies, int nstate, typename real>
298 {
299  std::vector<std::string> names;
300  for (unsigned int s=0; s<nstate; ++s) {
301  std::string varname = "state" + dealii::Utilities::int_to_string(s,1);
302  names.push_back(varname);
303  }
304  return names;
305 }
306 
307 template <int dim, int nspecies, int nstate, typename real>
308 std::vector<dealii::DataComponentInterpretation::DataComponentInterpretation> PhysicsBase<dim,nspecies,nstate,real>
310 {
311  namespace DCI = dealii::DataComponentInterpretation;
312  std::vector<DCI::DataComponentInterpretation> interpretation;
313  for (unsigned int s=0; s<nstate; ++s) {
314  interpretation.push_back (DCI::component_is_scalar);
315  }
316  return interpretation;
317 }
318 
319 template <int dim, int nspecies, int nstate, typename real>
320 dealii::UpdateFlags PhysicsBase<dim,nspecies,nstate,real>
322 {
323  return dealii::update_values;
324 }
325 
326 template <int dim, int nspecies, int nstate, typename real>
327 template<typename real2>
329 ::handle_non_physical_result(const std::string message) const
330 {
331  if (this->non_physical_behavior_type == NonPhysicalBehaviorEnum::abort_run) {
332  std::cout << "ERROR: Non-physical result has been detected. ";
333  if (!message.empty()) {
334  std::cout << std::endl << " Message: " << message << std::endl;
335  }
336  std::cout << " Aborting... " << std::endl << std::flush;
337  std::abort();
338  } else if (this->non_physical_behavior_type == NonPhysicalBehaviorEnum::print_warning) {
339  std::cout << "WARNING: Non-physical result has been detected at a node." << std::endl;
340  if (!message.empty()) {
341  std::cout << std::endl << " Message: " << message << std::endl;
342  }
343  } else if (this->non_physical_behavior_type == NonPhysicalBehaviorEnum::return_big_number) {
344  // do nothing -- assume that the test or iterative solver can handle this.
345  }
346 
347  return (real2)BIG_NUMBER;
348 }
349 #if PHILIP_SPECIES==1
350  // Define a sequence of indices representing the range of nstate
351  #define POSSIBLE_NSTATE (1)(2)(3)(4)(5)(6)(8)
352 
353  // Define a macro to instantiate functions for a specific nstate
354  #define INSTANTIATE_FOR_NSTATE(r, data, nstate) \
355  template class PhysicsBase < PHILIP_DIM, PHILIP_SPECIES, nstate, double >; \
356  template class PhysicsBase < PHILIP_DIM, PHILIP_SPECIES, nstate, FadType >; \
357  template class PhysicsBase < PHILIP_DIM, PHILIP_SPECIES, nstate, RadType >; \
358  template class PhysicsBase < PHILIP_DIM, PHILIP_SPECIES, nstate, FadFadType >; \
359  template class PhysicsBase < PHILIP_DIM, PHILIP_SPECIES, nstate, RadFadType >; \
360  /* -- handle_non_physical_result */ \
361  template double PhysicsBase < PHILIP_DIM, PHILIP_SPECIES, nstate, double >::handle_non_physical_result<double>(const std::string message) const; \
362  template FadType PhysicsBase < PHILIP_DIM, PHILIP_SPECIES, nstate, FadType >::handle_non_physical_result<FadType>(const std::string message) const; \
363  template RadType PhysicsBase < PHILIP_DIM, PHILIP_SPECIES, nstate, RadType >::handle_non_physical_result<RadType>(const std::string message) const; \
364  template FadFadType PhysicsBase < PHILIP_DIM, PHILIP_SPECIES, nstate, FadFadType >::handle_non_physical_result<FadFadType>(const std::string message) const; \
365  template RadFadType PhysicsBase < PHILIP_DIM, PHILIP_SPECIES, nstate, RadFadType >::handle_non_physical_result<RadFadType>(const std::string message) const; \
366  /* instantiate all the real types with real2 = FadType for automatic differentiation in NavierStokes::dissipative_flux_directional_jacobian() */ \
367  template FadType PhysicsBase < PHILIP_DIM, PHILIP_SPECIES, nstate, double >::handle_non_physical_result<FadType>(const std::string message) const; \
368  template FadType PhysicsBase < PHILIP_DIM, PHILIP_SPECIES, nstate, RadType >::handle_non_physical_result<FadType>(const std::string message) const; \
369  template FadType PhysicsBase < PHILIP_DIM, PHILIP_SPECIES, nstate, FadFadType >::handle_non_physical_result<FadType>(const std::string message) const; \
370  template FadType PhysicsBase < PHILIP_DIM, PHILIP_SPECIES, nstate, RadFadType >::handle_non_physical_result<FadType>(const std::string message) const;
371  BOOST_PP_SEQ_FOR_EACH(INSTANTIATE_FOR_NSTATE, _, POSSIBLE_NSTATE)
372 #else
373  #define POSSIBLE_TYPE (double)(FadType)(RadType)(FadFadType)(RadFadType)
374  #define INSTANTIATE_TYPES(r, data, type) \
375  template class PhysicsBase < PHILIP_DIM, PHILIP_SPECIES, PHILIP_DIM+PHILIP_SPECIES+1, type >; \
376  template type PhysicsBase < PHILIP_DIM, PHILIP_SPECIES, PHILIP_DIM+PHILIP_SPECIES+1, type >::handle_non_physical_result<type>(const std::string message) const;
377  BOOST_PP_SEQ_FOR_EACH(INSTANTIATE_TYPES, _, POSSIBLE_TYPE)
382 #endif
383 } // Physics namespace
384 } // PHiLiP namespace
385 
Sacado::Fad::DFad< double > FadType
Sacado AD type for first derivatives.
Definition: ADTypes.hpp:11
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.
PhysicsBase(const Parameters::AllParameters *const parameters_input, const bool has_nonzero_diffusion_input, const bool has_nonzero_physical_source_input, const dealii::Tensor< 2, 3, double > input_diffusion_tensor=Parameters::ManufacturedSolutionParam::get_default_diffusion_tensor(), std::shared_ptr< ManufacturedSolutionFunction< dim, nspecies, real > > manufactured_solution_function_input=nullptr)
Default constructor that will set the constants.
Definition: physics.cpp:17
Files for the baseline physics.
Definition: ADTypes.hpp:10
Main parameter class that contains the various other sub-parameter classes.