include/meltpooldg/compressible_flow/utils.hpp Source File

Developer Documentation: include/meltpooldg/compressible_flow/utils.hpp Source File
Developer Documentation
utils.hpp
Go to the documentation of this file.
1
5#pragma once
6
7#include <deal.II/base/aligned_vector.h>
8#include <deal.II/base/quadrature.h>
9#include <deal.II/base/tensor.h>
10#include <deal.II/base/vectorization.h>
11
12#include <deal.II/grid/reference_cell.h>
13#include <deal.II/grid/tria_accessor.h>
14#include <deal.II/grid/tria_iterator.h>
15
16#include <deal.II/lac/affine_constraints.h>
17#include <deal.II/lac/la_parallel_vector.h>
18
23#include <meltpooldg/utilities/better_enum.hpp>
25
27{
29 BETTER_ENUM(Idx1D, char, density, momentum_x, energy);
30 BETTER_ENUM(Idx2D, char, density, momentum_x, momentum_y, energy);
31 BETTER_ENUM(Idx3D, char, density, momentum_x, momentum_y, momentum_z, energy);
32
43 template <int dim, typename Number>
44 void
46 dealii::AlignedVector<dealii::VectorizedArray<Number>> &array_penalty_parameter,
47 const dealii::MatrixFree<dim, Number> &matrix_free,
48 const std::string &domain_representation_type,
49 const unsigned int dof_index = 0,
50 const Number scaling_factor = 1.0);
51
65 template <int dim, typename number, typename ConservedVariablesType>
66 void
68 dealii::LinearAlgebra::distributed::Vector<number> &solution_primitive_variables,
69 const dealii::LinearAlgebra::distributed::Vector<number> &solution,
70 const ScratchData<dim, dim, number> &scratch_data,
71 const unsigned int dof_idx,
72 const unsigned int quad_idx,
73 const MaterialPhaseData<number> *material_liquid,
74 const MaterialPhaseData<number> *material_gas = nullptr);
75
85 template <int dim,
86 Flow::EOSIsConservativeValueView ConservativeValueView,
87 Flow::EOSIsWritablePrimitiveValueView WritablePrimitiveValueView>
88 inline DEAL_II_ALWAYS_INLINE //
89 void
90 conservative_to_primitive(const ConservativeValueView &conservative,
91 WritablePrimitiveValueView &primitive);
92
102 template <int dim,
103 Flow::EOSIsWritableConservativeValueView WritableConservativeValueView,
104 Flow::EOSIsPrimitiveValueView PrimitiveValueView>
105 inline DEAL_II_ALWAYS_INLINE //
106 void
107 primitive_to_conservative(const PrimitiveValueView &primitive,
108 WritableConservativeValueView &conservative);
109
118 template <typename DofViewType, typename VectorizedArrayType>
119 inline DEAL_II_ALWAYS_INLINE //
120 VectorizedArrayType
121 maximum_local_wave_speed(const DofViewType &u_m, const DofViewType &u_p);
122
137 template <typename number, int n_species, typename PrimitiveVariablesView>
138 inline std::bitset<dealii::VectorizedArray<number>::size()>
140 const PrimitiveVariablesView &w_view,
141 const unsigned int n_active_lanes = dealii::VectorizedArray<number>::size());
142
158 template <int dim, typename number>
159 inline DEAL_II_ALWAYS_INLINE //
160 dealii::Tensor<2, dim, dealii::VectorizedArray<number>>
162 const dealii::VectorizedArray<number> &pressure,
163 const dealii::Tensor<2, dim, dealii::VectorizedArray<number>> &viscous_stress_tensor);
164
173 template <typename number, int n_species>
174 inline bool
175 is_viscous_flow(const MaterialPhaseData<number> &material_data);
176
185 template <int dim, typename number, int n_species = 1>
187 {
188 virtual ~ExternalFlowForce() = default;
189
205 value(number time_step_size,
206 unsigned int cell_batch_id,
207 const dealii::Point<dim, dealii::VectorizedArray<number>> &points,
209 };
210
211
212 template <int dim, typename number, int n_species = 1>
214 {
215 virtual ~ExternalFlowForceJacobian() = default;
216
233 value(number time_step_size,
234 unsigned int cell_batch_id,
235 const dealii::Point<dim, dealii::VectorizedArray<number>> &points,
238 };
239
240 /********************************************************************************************
241 * Inlined function definitions
242 * *************************************************************************************+****/
243 template <typename number, int n_species>
244 inline bool
246 {
247 for (unsigned int species = 0; species < n_species; ++species)
248 if (material_data.species_data[species].dynamic_viscosity > 0.0)
249 return true;
250 return false;
251 }
252
253 template <typename number, int n_species, typename PrimitiveVariablesView>
254 inline std::bitset<dealii::VectorizedArray<number>::size()>
255 physical_admissibility_mask(const PrimitiveVariablesView &w_view,
256 const unsigned int n_active_lanes)
257 {
258 dealii::VectorizedArray<number> is_admissible = 1.;
259
260 const auto require_greater_than = [&](const dealii::VectorizedArray<number> &value,
261 const dealii::VectorizedArray<number> &threshold) {
262 is_admissible = dealii::compare_and_apply_mask<dealii::SIMDComparison::greater_than>(
263 value, threshold, is_admissible, dealii::VectorizedArray<number>(0.));
264 };
265
266 const auto require_less_than = [&](const dealii::VectorizedArray<number> &value,
267 const dealii::VectorizedArray<number> &threshold) {
268 is_admissible = dealii::compare_and_apply_mask<dealii::SIMDComparison::less_than>(
269 value, threshold, is_admissible, dealii::VectorizedArray<number>(0.));
270 };
271
272 require_greater_than(w_view.density(), dealii::VectorizedArray<number>(0.));
273 require_greater_than(w_view.pressure(), dealii::VectorizedArray<number>(0.));
274
275 if constexpr (n_species > 1)
276 {
277 dealii::VectorizedArray<number> tolerance = 1e-12;
278 for (unsigned int species = 0; species < n_species; ++species)
279 {
280 // mass fractions must be between 0 and 1, with a small tolerance to account for
281 // numerical errors
282 require_greater_than(w_view.mass_fraction(species), -tolerance);
283 require_less_than(w_view.mass_fraction(species),
284 dealii::VectorizedArray<number>(1.) + tolerance);
285 }
286
287 // sum of mass fractions must be equal to 1, with a small tolerance to account for numerical
288 // errors
289 dealii::VectorizedArray<number> mass_fraction_sum = 0.0;
290 for (unsigned int species = 0; species < n_species; ++species)
291 mass_fraction_sum += w_view.mass_fraction(species);
292
293 require_greater_than(mass_fraction_sum, dealii::VectorizedArray<number>(1.) - tolerance);
294 require_less_than(mass_fraction_sum, dealii::VectorizedArray<number>(1.) + tolerance);
295 }
296
297 std::bitset<dealii::VectorizedArray<number>::size()> admissibility_mask;
298 for (unsigned int lane = 0; lane < n_active_lanes; ++lane)
299 admissibility_mask.set(lane, is_admissible[lane] > 0.);
300 return admissibility_mask;
301 }
302
303 template <int dim, typename Number>
304 void
306 dealii::AlignedVector<dealii::VectorizedArray<Number>> &array_penalty_parameter,
307 const dealii::MatrixFree<dim, Number> &matrix_free,
308 const std::string &domain_representation_type,
309 const unsigned int dof_index,
310 const Number scaling_factor)
311 {
312 const unsigned int n_cells = matrix_free.n_cell_batches() + matrix_free.n_ghost_cell_batches();
313 array_penalty_parameter.resize(n_cells);
314
315 dealii::Mapping<dim> const &mapping = *matrix_free.get_mapping_info().mapping;
316 dealii::FiniteElement<dim> const &fe = matrix_free.get_dof_handler(dof_index).get_fe();
317 unsigned int const degree = fe.degree;
318
319 // use penalty factor for hypercube elements according to K. Hillewaert, Development of the
320 // discontinuous Galerkin method for high-resolution, large scale CFD and acoustics in
321 // industrial geometries, PhD thesis, Univ. de Louvain, 2013.
322 const Number fac = scaling_factor * (degree + 1.0) * (degree + 1.0);
323
324 const std::vector<dealii::ReferenceCell<dim>> reference_cells =
325 matrix_free.get_dof_handler(dof_index).get_triangulation().get_reference_cells();
326 AssertThrow(reference_cells.size() == 1, dealii::ExcMessage("No mixed meshes allowed."));
327
328
329 const dealii::Quadrature<dim> quadrature =
330 reference_cells[0].get_gauss_type_quadrature(degree + 1);
331 dealii::FEValues<dim> fe_values(mapping, fe, quadrature, dealii::update_JxW_values);
332
333 const dealii::Quadrature<dim - 1> face_quadrature =
334 reference_cells[0].face_reference_cell(0).get_gauss_type_quadrature(degree + 1);
335 dealii::FEFaceValues<dim> fe_face_values(mapping,
336 fe,
337 face_quadrature,
338 dealii::update_JxW_values);
339
340 if (domain_representation_type == "fitted")
341 {
342 for (unsigned int i = 0; i < n_cells; ++i)
343 {
344 for (unsigned int v = 0; v < matrix_free.n_active_entries_per_cell_batch(i); ++v)
345 {
346 typename dealii::DoFHandler<dim>::cell_iterator cell =
347 matrix_free.get_cell_iterator(i, v, dof_index);
348 fe_values.reinit(cell);
349
350 // calculate cell volume
351 Number volume = 0;
352 for (unsigned int q = 0; q < quadrature.size(); ++q)
353 {
354 volume += fe_values.JxW(q);
355 }
356
357 // calculate surface area
358 Number surface_area = 0;
359 for (unsigned int const f : cell->face_indices())
360 {
361 fe_face_values.reinit(cell, f);
362 Number const factor =
363 (cell->at_boundary(f) and not(cell->has_periodic_neighbor(f))) ? 1. : 0.5;
364 for (unsigned int q = 0; q < face_quadrature.size(); ++q)
365 {
366 surface_area += fe_face_values.JxW(q) * factor;
367 }
368 }
369
370 array_penalty_parameter[i][v] = surface_area / volume * fac;
371 }
372 }
373 }
374 else if (domain_representation_type == "cut")
375 {
376 for (unsigned int i = 0; i < n_cells; ++i)
377 {
378 for (unsigned int v = 0; v < matrix_free.n_active_entries_per_cell_batch(i); ++v)
379 {
380 typename dealii::DoFHandler<dim>::cell_iterator cell =
381 matrix_free.get_cell_iterator(i, v, dof_index);
382
383 // simplified computation for hypercube elements
384 array_penalty_parameter[i][v] = fac / cell->minimum_vertex_distance();
385 }
386 }
387 }
388 else
389 AssertThrow(false,
390 dealii::ExcMessage("The domain representation type '" +
391 domain_representation_type + "' is not supported."));
392 }
393
394 template <int dim, typename number, typename ConservedVariablesType>
395 void
397 dealii::LinearAlgebra::distributed::Vector<number> &solution_primitive_variables,
398 const dealii::LinearAlgebra::distributed::Vector<number> &solution,
399 const ScratchData<dim, dim, number> &scratch_data,
400 const unsigned int dof_idx,
401 const unsigned int quad_idx,
402 const MaterialPhaseData<number> *material_liquid,
403 const MaterialPhaseData<number> *material_gas)
404 {
407
408 const dealii::MatrixFree<dim, number, dealii::VectorizedArray<number>> &matrix_free =
409 scratch_data.get_matrix_free();
410 unsigned int n_support_points_per_cell = scratch_data.get_n_dofs_per_cell(dof_idx) / (dim + 2);
411
412 auto process_cell = [&](CutUtil::CellCategory category,
413 unsigned int first_component,
414 const MaterialPhaseData<number> *material,
415 const unsigned int cell_batch) {
416 if (!material)
417 return;
419 matrix_free, dof_idx, quad_idx, first_component, category);
420 eval.reinit(cell_batch);
421 eval.read_dof_values(solution);
422
423 for (unsigned int i = 0; i < n_support_points_per_cell; ++i)
424 {
425 const auto &u_cons = eval.get_dof_value(i);
426 StateView u_cons_view(u_cons, *material);
427 ConservedVariablesType u_prim_data;
428 PrimitiveValueView u_prim_view(u_prim_data);
429 conservative_to_primitive<dim, StateView, PrimitiveValueView>(u_cons_view, u_prim_view);
430 eval.submit_dof_value(u_prim_view.value(), i);
431 }
432
433 eval.set_dof_values(solution_primitive_variables);
434 };
435
436 if (!matrix_free.get_dof_info(dof_idx).cell_active_fe_index.empty())
437 {
438 // using hp::FECollection (cutFEM/DG)
439 for (unsigned int cell_batch = 0; cell_batch < matrix_free.n_cell_batches(); ++cell_batch)
440 {
441 const auto cell_category = matrix_free.get_cell_category(cell_batch);
442
443 if (cell_category == CutUtil::CellCategory::liquid)
444 {
445 process_cell(CutUtil::CellCategory::liquid, 0, material_liquid, cell_batch);
446 }
447 else if (cell_category == CutUtil::CellCategory::gas)
448 {
449 process_cell(CutUtil::CellCategory::gas, dim + 2, material_gas, cell_batch);
450 }
451 else if (cell_category == CutUtil::CellCategory::intersected)
452 {
453 process_cell(CutUtil::CellCategory::intersected, 0, material_liquid, cell_batch);
454 process_cell(CutUtil::CellCategory::intersected, dim + 2, material_gas, cell_batch);
455 }
456 }
457 }
458 else
459 {
460 // not using hp::FECollection (fitted mesh)
461 for (unsigned int cell_batch = 0; cell_batch < matrix_free.n_cell_batches(); ++cell_batch)
462 {
463 process_cell(CutUtil::CellCategory::liquid, 0, material_liquid, cell_batch);
464 }
465 }
466 }
467
468 template <int dim,
469 Flow::EOSIsConservativeValueView ConservativeValueView,
470 Flow::EOSIsWritablePrimitiveValueView WritablePrimitiveValueView>
471 inline DEAL_II_ALWAYS_INLINE //
472 void
473 conservative_to_primitive(const ConservativeValueView &conservative,
474 WritablePrimitiveValueView &primitive)
475 {
476 primitive.pressure() = conservative.pressure();
477
478 for (unsigned int d = 0; d < dim; ++d)
479 primitive.velocity(d) = conservative.velocity(d);
480
481 primitive.temperature() = conservative.temperature();
482 }
483
484 template <int dim,
485 Flow::EOSIsWritableConservativeValueView WritableConservativeValueView,
486 Flow::EOSIsPrimitiveValueView PrimitiveValueView>
487 inline DEAL_II_ALWAYS_INLINE //
488 void
489 primitive_to_conservative(const PrimitiveValueView &primitive,
490 WritableConservativeValueView &conservative)
491 {
492 Flow::dispatch_eos<PrimitiveValueView>(primitive.eos_type(), [&](auto eos) {
493 eos.template conservative_from_primitive<dim>(conservative, primitive, primitive);
494 });
495 }
496
497 template <typename DofViewType, typename VectorizedArrayType>
498 inline DEAL_II_ALWAYS_INLINE //
499 VectorizedArrayType
500 maximum_local_wave_speed(const DofViewType &u_m, const DofViewType &u_p)
501 {
502 const auto velocity_m = u_m.velocity();
503 const auto velocity_p = u_p.velocity();
504
505 const auto sound_speed_p = u_p.speed_of_sound();
506 const auto sound_speed_m = u_m.speed_of_sound();
507
508 const auto sound_speed_p2 = sound_speed_p * sound_speed_p;
509 const auto sound_speed_m2 = sound_speed_m * sound_speed_m;
510
511 const auto lambda = 0.5 * std::sqrt(std::max(velocity_p.norm_square() + sound_speed_p2,
512 velocity_m.norm_square() + sound_speed_m2));
513 return lambda;
514 }
515
516 template <int dim, typename number>
517 inline DEAL_II_ALWAYS_INLINE //
518 dealii::Tensor<2, dim, dealii::VectorizedArray<number>>
520 const dealii::VectorizedArray<number> &pressure,
521 const dealii::Tensor<2, dim, dealii::VectorizedArray<number>> &viscous_stress_tensor)
522 {
523 auto stress_tensor = viscous_stress_tensor;
524
525 for (unsigned int d = 0; d < dim; ++d)
526 stress_tensor[d][d] -= pressure;
527
528 return stress_tensor;
529 }
530} // namespace MeltPoolDG::CompressibleFlow
Container for shared scratch data between operations/operators.
Definition scratch_data.hpp:61
unsigned int get_n_dofs_per_cell(const unsigned int dof_idx) const
Get the number of DoFs per cell for a given DoFHandler index.
Definition scratch_data.cpp:466
dealii::MatrixFree< dim, number, VectorizedArrayType > & get_matrix_free()
Access the internal MatrixFree object (non-const).
Definition scratch_data.cpp:424
Definition equation_of_state.hpp:24
Definition equation_of_state.hpp:41
Definition equation_of_state.hpp:58
Definition equation_of_state.hpp:75
This file contains various functions that can be used to set and evaluate boundary conditions for the...
Definition boundary_condition_functions.hpp:17
DEAL_II_ALWAYS_INLINE void conservative_to_primitive(const ConservativeValueView &conservative, WritablePrimitiveValueView &primitive)
Convert a state from conservative (density, momentum, total energy) to primitive (pressure,...
Definition utils.hpp:473
void update_primitive_variables_solution(dealii::LinearAlgebra::distributed::Vector< number > &solution_primitive_variables, const dealii::LinearAlgebra::distributed::Vector< number > &solution, const ScratchData< dim, dim, number > &scratch_data, const unsigned int dof_idx, const unsigned int quad_idx, const MaterialPhaseData< number > *material_liquid, const MaterialPhaseData< number > *material_gas=nullptr)
Update the primitive variable solution according to the current solution vector.
Definition utils.hpp:396
DEAL_II_ALWAYS_INLINE dealii::Tensor< 1, dim, dealii::Tensor< 1, dim, dealii::VectorizedArray< number > > > viscous_stress_tensor(const dealii::Tensor< 1, dim, dealii::Tensor< 1, dim, dealii::VectorizedArray< number > > > &grad_velocity, const dealii::VectorizedArray< number > dynamic_viscosity)
Definition kernels.hpp:51
DEAL_II_ALWAYS_INLINE VectorizedArrayType maximum_local_wave_speed(const DofViewType &u_m, const DofViewType &u_p)
Calculate the maximum local wave speed between two states on a face.
Definition utils.hpp:500
void calculate_penalty_parameter(dealii::AlignedVector< dealii::VectorizedArray< Number > > &array_penalty_parameter, const dealii::MatrixFree< dim, Number > &matrix_free, const std::string &domain_representation_type, const unsigned int dof_index=0, const Number scaling_factor=1.0)
This function computes the local values of the internal penalty parameter used in the viscous numeric...
Definition utils.hpp:305
bool is_viscous_flow(const MaterialPhaseData< number > &material_data)
Definition utils.hpp:245
dealii::Tensor< 1, n_conserved_variables< dim, n_species >, VectorizedArrayType > ConservedVariablesType
Definition data_types.hpp:45
DEAL_II_ALWAYS_INLINE dealii::Tensor< 2, dim, dealii::VectorizedArray< number > > calculate_cauchy_stress_tensor(const dealii::VectorizedArray< number > &pressure, const dealii::Tensor< 2, dim, dealii::VectorizedArray< number > > &viscous_stress_tensor)
Calculate the total stress tensor (Cauchy stress tensor) from pressure contribution and viscous stres...
Definition utils.hpp:519
DEAL_II_ALWAYS_INLINE void primitive_to_conservative(const PrimitiveValueView &primitive, WritableConservativeValueView &conservative)
Convert a state from primitive (pressure, velocity, temperature) to conservative (density,...
Definition utils.hpp:489
BETTER_ENUM(RampUpType, char, none, linear, exponential, cosine)
Enum for the type of ramp up function used for the velocity at an inflow boundary.
std::bitset< dealii::VectorizedArray< number >::size()> physical_admissibility_mask(const PrimitiveVariablesView &w_view, const unsigned int n_active_lanes=dealii::VectorizedArray< number >::size())
Definition utils.hpp:255
CellCategory
Definition of the cell category numbering (active FE index).
Definition util.hpp:62
@ liquid
Definition util.hpp:63
@ intersected
Definition util.hpp:64
@ gas
Definition util.hpp:65
dealii::FEEvaluation< dim, -1, 0, n_components, number, VectorizedArrayType > FECellIntegrator
Definition fe_integrator.hpp:14
This file provides a collection of view types for the compressible Navier–Stokes solver....
Definition state_views.hpp:186
virtual ConservedVariablesType< dim, number, n_species > value(number time_step_size, unsigned int cell_batch_id, const dealii::Point< dim, dealii::VectorizedArray< number > > &points, const ConservedVariablesType< dim, number, n_species > &w, const ConservedVariablesType< dim, number, n_species > &delta_w)=0
An abstract interface for defining external forces acting on the fluid that must be evaluated and inc...
Definition utils.hpp:187
virtual ConservedVariablesType< dim, number, n_species > value(number time_step_size, unsigned int cell_batch_id, const dealii::Point< dim, dealii::VectorizedArray< number > > &points, const ConservedVariablesType< dim, number, n_species > &w)=0
Collection of material parameters for a specific fluid phase.
Definition material.hpp:140
std::array< MaterialSpeciesData< number >, n_max_species > species_data
Definition material.hpp:160