ExaDG
Loading...
Searching...
No Matches
spatial_operator_base.h
1/* ______________________________________________________________________
2 *
3 * ExaDG - High-Order Discontinuous Galerkin for the Exa-Scale
4 *
5 * Copyright (C) 2021 by the ExaDG authors
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * ______________________________________________________________________
20 */
21
22#ifndef INCLUDE_EXADG_INCOMPRESSIBLE_NAVIER_STOKES_SPATIAL_DISCRETIZATION_SPATIAL_OPERATOR_BASE_H_
23#define INCLUDE_EXADG_INCOMPRESSIBLE_NAVIER_STOKES_SPATIAL_DISCRETIZATION_SPATIAL_OPERATOR_BASE_H_
24
25// deal.II
26#include <deal.II/fe/fe_dgq.h>
27#include <deal.II/fe/fe_raviart_thomas.h>
28#include <deal.II/fe/fe_simplex_p.h>
29#include <deal.II/fe/fe_system.h>
30#include <deal.II/lac/la_parallel_block_vector.h>
31#include <deal.II/lac/la_parallel_vector.h>
32
33
34// ExaDG
35#include <exadg/grid/grid.h>
36#include <exadg/incompressible_navier_stokes/spatial_discretization/calculators/streamfunction_calculator_rhs_operator.h>
37#include <exadg/incompressible_navier_stokes/spatial_discretization/generalized_newtonian_model.h>
38#include <exadg/incompressible_navier_stokes/spatial_discretization/operators/convective_operator.h>
39#include <exadg/incompressible_navier_stokes/spatial_discretization/operators/divergence_operator.h>
40#include <exadg/incompressible_navier_stokes/spatial_discretization/operators/gradient_operator.h>
41#include <exadg/incompressible_navier_stokes/spatial_discretization/operators/momentum_operator.h>
42#include <exadg/incompressible_navier_stokes/spatial_discretization/operators/projection_operator.h>
43#include <exadg/incompressible_navier_stokes/spatial_discretization/operators/rhs_operator.h>
44#include <exadg/incompressible_navier_stokes/spatial_discretization/operators/viscous_operator.h>
45#include <exadg/incompressible_navier_stokes/spatial_discretization/turbulence_model.h>
46#include <exadg/incompressible_navier_stokes/spatial_discretization/viscosity_model_base.h>
47#include <exadg/incompressible_navier_stokes/user_interface/boundary_descriptor.h>
48#include <exadg/incompressible_navier_stokes/user_interface/field_functions.h>
49#include <exadg/incompressible_navier_stokes/user_interface/parameters.h>
50#include <exadg/matrix_free/matrix_free_data.h>
51#include <exadg/operators/inverse_mass_operator.h>
52#include <exadg/operators/mass_operator.h>
53#include <exadg/operators/navier_stokes_calculators.h>
54#include <exadg/poisson/preconditioners/multigrid_preconditioner.h>
55#include <exadg/poisson/spatial_discretization/laplace_operator.h>
56#include <exadg/solvers_and_preconditioners/preconditioners/preconditioner_base.h>
57#include <exadg/time_integration/interpolate.h>
58
59namespace ExaDG
60{
61namespace IncNS
62{
63template<int dim, typename Number>
65
66template<int dim, typename Number>
67class SpatialOperatorBase : public dealii::Subscriptor
68{
69protected:
70 typedef dealii::LinearAlgebra::distributed::Vector<Number> VectorType;
71 typedef dealii::LinearAlgebra::distributed::BlockVector<Number> BlockVectorType;
72
73 typedef SpatialOperatorBase<dim, Number> This;
74
75 typedef dealii::VectorizedArray<Number> scalar;
76 typedef dealii::Tensor<1, dim, dealii::VectorizedArray<Number>> vector;
77 typedef dealii::Tensor<2, dim, dealii::VectorizedArray<Number>> tensor;
78
79 typedef std::pair<unsigned int, unsigned int> Range;
80
81 typedef FaceIntegrator<dim, dim, Number> FaceIntegratorU;
82 typedef FaceIntegrator<dim, 1, Number> FaceIntegratorP;
83
84 typedef typename Poisson::MultigridPreconditioner<dim, Number, 1> MultigridPoisson;
85
86public:
87 /*
88 * Constructor.
89 */
90 SpatialOperatorBase(std::shared_ptr<Grid<dim> const> grid,
91 std::shared_ptr<dealii::Mapping<dim> const> mapping,
92 std::shared_ptr<MultigridMappings<dim, Number>> const multigrid_mappings,
93 std::shared_ptr<BoundaryDescriptor<dim> const> boundary_descriptor,
94 std::shared_ptr<FieldFunctions<dim> const> field_functions,
95 Parameters const & parameters,
96 std::string const & field,
97 MPI_Comm const & mpi_comm);
98
99 /*
100 * Destructor.
101 */
102 virtual ~SpatialOperatorBase(){};
103
104 void
105 fill_matrix_free_data(MatrixFreeData<dim, Number> & matrix_free_data) const;
106
110 void
111 setup();
112
119 void
120 setup(std::shared_ptr<dealii::MatrixFree<dim, Number> const> matrix_free,
121 std::shared_ptr<MatrixFreeData<dim, Number> const> matrix_free_data,
122 std::string const & dof_index_temperature = "");
123
124protected:
125 /*
126 * This function initializes operators, preconditioners, and solvers related to the solution of
127 * (non-)linear systems of equation required for implicit formulations. It has to be extended
128 * by derived classes if necessary.
129 */
130 virtual void
131 setup_preconditioners_and_solvers()
132 {
133 }
134
135private:
139 virtual void
140 setup_derived() = 0;
141
142public:
143 /*
144 * Getters and setters.
145 */
146 dealii::MatrixFree<dim, Number> const &
147 get_matrix_free() const;
148
149 std::string
150 get_dof_name_velocity() const;
151
152 unsigned int
153 get_dof_index_velocity() const;
154
155 unsigned int
156 get_dof_index_pressure() const;
157
158 unsigned int
159 get_quad_index_velocity_standard() const;
160
161 unsigned int
162 get_quad_index_pressure() const;
163
164protected:
165 unsigned int
166 get_dof_index_velocity_scalar() const;
167
168 unsigned int
169 get_quad_index_velocity_overintegration() const;
170
171 unsigned int
172 get_quad_index_velocity_nodal_points() const;
173
174 unsigned int
175 get_quad_index_pressure_nodal_points() const;
176
177 unsigned int
178 get_quad_index_velocity_linearized() const;
179
180public:
181 std::shared_ptr<dealii::Mapping<dim> const>
182 get_mapping() const;
183
184 dealii::FiniteElement<dim> const &
185 get_fe_u() const;
186
187 dealii::FiniteElement<dim> const &
188 get_fe_p() const;
189
190 dealii::DoFHandler<dim> const &
191 get_dof_handler_u() const;
192
193 dealii::DoFHandler<dim> const &
194 get_dof_handler_u_scalar() const;
195
196 dealii::DoFHandler<dim> const &
197 get_dof_handler_p() const;
198
199 dealii::AffineConstraints<Number> const &
200 get_constraint_p() const;
201
202 dealii::AffineConstraints<Number> const &
203 get_constraint_u() const;
204
205 dealii::types::global_dof_index
206 get_number_of_dofs() const;
207
208 dealii::VectorizedArray<Number>
209 get_viscosity_boundary_face(unsigned int const face, unsigned int const q) const;
210
211 // Multiphysics coupling via "Cached" boundary conditions
212 std::shared_ptr<ContainerInterfaceData<1, dim, double>>
213 get_container_interface_data();
214
215 void
216 set_velocity_ptr(VectorType const & velocity) const;
217
218 /*
219 * Initialization of vectors.
220 */
221 void
222 initialize_vector_velocity(VectorType & src) const;
223
224 void
225 initialize_vector_velocity_scalar(VectorType & src) const;
226
227 void
228 initialize_vector_pressure(VectorType & src) const;
229
230 void
231 initialize_block_vector_velocity_pressure(BlockVectorType & src) const;
232
233 /*
234 * Prescribe initial conditions using a specified analytical/initial solution function.
235 */
236 void
237 prescribe_initial_conditions(VectorType & velocity,
238 VectorType & pressure,
239 double const time) const;
240
241 /*
242 * Interpolate given functions to the corresponding vectors.
243 */
244 void
245 interpolate_functions(VectorType & velocity,
246 std::shared_ptr<dealii::Function<dim>> const & f_velocity,
247 VectorType & pressure,
248 std::shared_ptr<dealii::Function<dim>> const & f_pressure,
249 double const time) const;
250
251 /*
252 * Interpolate analytical solution functions.
253 */
254 void
255 interpolate_analytical_solution(VectorType & velocity,
256 VectorType & pressure,
257 double const time) const;
258
259 // FSI: coupling fluid -> structure
260 // fills a DoF-vector (velocity) with values of traction on fluid-structure interface
261 void
262 interpolate_stress_bc(VectorType & stress,
263 VectorType const & velocity,
264 VectorType const & pressure) const;
265
266 /*
267 * Time step calculation.
268 */
269
270 /*
271 * Calculate time step size according to maximum efficiency criterion
272 */
273 double
274 calculate_time_step_max_efficiency(unsigned int const order_time_integrator) const;
275
276 // global CFL criterion
277 double
278 calculate_time_step_cfl_global() const;
279
280 // Calculate time step size according to local CFL criterion
281 double
282 calculate_time_step_cfl(VectorType const & velocity) const;
283
284 // Calculate CFL numbers of cells
285 void
286 calculate_cfl_from_time_step(VectorType & cfl,
287 VectorType const & velocity,
288 double const time_step_size) const;
289
290 /*
291 * Returns characteristic element length for high-order elements / shape functions
292 */
293 double
294 get_characteristic_element_length() const;
295
296 /*
297 * For certain setups and types of boundary conditions, the pressure field is only defined up to
298 * an additive constant which originates from the fact that only the derivative of the pressure
299 * appears in the incompressible Navier-Stokes equations. Examples of such a scenario are problems
300 * where the velocity is prescribed on the whole boundary or periodic boundaries.
301 */
302
303 // This function can be used to query whether the pressure level is undefined.
304 bool
305 is_pressure_level_undefined() const;
306
307 // This function adjust the pressure level, where different options are available to fix the
308 // pressure level. The method selected by this function depends on the specified parameter.
309 void
310 adjust_pressure_level_if_undefined(VectorType & pressure, double const & time) const;
311
312 /*
313 * Boussinesq approximation
314 */
315 void
316 set_temperature(VectorType const & temperature);
317
318 /*
319 * Computation of derived quantities which is needed for postprocessing but some of them are also
320 * needed, e.g., for special splitting-type time integration schemes.
321 */
322
323 // vorticity
324 void
325 compute_vorticity(VectorType & dst, VectorType const & src) const;
326
327 // divergence
328 void
329 compute_divergence(VectorType & dst, VectorType const & src) const;
330
331 // shear rate
332 void
333 compute_shear_rate(VectorType & dst, VectorType const & src) const;
334
335 // velocity_magnitude
336 void
337 compute_velocity_magnitude(VectorType & dst, VectorType const & src) const;
338
339 // vorticity_magnitude
340 void
341 compute_vorticity_magnitude(VectorType & dst, VectorType const & src) const;
342
343 // streamfunction
344 void
345 compute_streamfunction(VectorType & dst, VectorType const & src) const;
346
347 // Q criterion
348 void
349 compute_q_criterion(VectorType & dst, VectorType const & src) const;
350
351 /*
352 * Operators.
353 */
354
355 // mass operator
356 void
357 apply_mass_operator(VectorType & dst, VectorType const & src) const;
358
359 void
360 apply_mass_operator_add(VectorType & dst, VectorType const & src) const;
361
362 // body force term
363 void
364 evaluate_add_body_force_term(VectorType & dst, double const time) const;
365
366 // convective term
367 void
368 evaluate_convective_term(VectorType & dst, VectorType const & src, Number const time) const;
369
370 // pressure gradient term
371 void
372 evaluate_pressure_gradient_term(VectorType & dst,
373 VectorType const & src,
374 double const time) const;
375
376 // velocity divergence
377 void
378 evaluate_velocity_divergence_term(VectorType & dst,
379 VectorType const & src,
380 double const time) const;
381
382 // inverse velocity mass operator
383 unsigned int
384 apply_inverse_mass_operator(VectorType & dst, VectorType const & src) const;
385
386 /*
387 * Update variable viscosity.
388 */
389 void
390 update_viscosity(VectorType const & velocity) const;
391
392 /*
393 * Projection step.
394 */
395 void
396 update_projection_operator(VectorType const & velocity, double const time_step_size) const;
397
398 void
399 rhs_add_projection_operator(VectorType & dst, double const time) const;
400
401 unsigned int
402 solve_projection(VectorType & dst,
403 VectorType const & src,
404 bool const & update_preconditioner) const;
405
406 /*
407 * Postprocessing.
408 */
409 double
410 calculate_dissipation_convective_term(VectorType const & velocity, double const time) const;
411
412 double
413 calculate_dissipation_viscous_term(VectorType const & velocity) const;
414
415 double
416 calculate_dissipation_divergence_term(VectorType const & velocity) const;
417
418 double
419 calculate_dissipation_continuity_term(VectorType const & velocity) const;
420
421 /*
422 * Updates operators after grid has been moved.
423 */
424 virtual void
425 update_after_grid_motion(bool const update_matrix_free);
426
427 /*
428 * Sets the grid velocity.
429 */
430 void
431 set_grid_velocity(VectorType const & velocity);
432
433 /*
434 * Calls constraint_u.distribute(u) and updates the constrained DoFs of the velocity field
435 */
436 void
437 distribute_constraint_u(VectorType & velocity) const;
438
439protected:
440 /*
441 * Projection step.
442 */
443 void
444 setup_projection_solver();
445
446 bool
447 unsteady_problem_has_to_be_solved() const;
448
449 /*
450 * Grid
451 */
452 std::shared_ptr<Grid<dim> const> grid;
453
454 /*
455 * dealii::Mapping (In case of moving meshes (ALE), this is the dynamic mapping describing the
456 * deformed configuration.)
457 */
458 std::shared_ptr<dealii::Mapping<dim> const> mapping;
459
460 std::shared_ptr<MultigridMappings<dim, Number>> const multigrid_mappings;
461
462 /*
463 * User interface: Boundary conditions and field functions.
464 */
465 std::shared_ptr<BoundaryDescriptor<dim> const> boundary_descriptor;
466 std::shared_ptr<FieldFunctions<dim> const> field_functions;
467
468 /*
469 * List of parameters.
470 */
471 Parameters const & param;
472
473 /*
474 * A name describing the field being solved.
475 */
476 std::string const field;
477
478 /*
479 * In case of projection type incompressible Navier-Stokes solvers this variable is needed to
480 * solve the pressure Poisson equation. However, this variable is also needed in case of a
481 * coupled solution approach. In that case, it is used for the block preconditioner (or more
482 * precisely for the Schur-complement preconditioner and the preconditioner used to approximately
483 * invert the Laplace operator).
484 *
485 * While the functions specified in BoundaryDescriptorLaplace are relevant for projection-type
486 * solvers (pressure Poisson equation has to be solved), the function specified in
487 * BoundaryDescriptorLaplace are irrelevant for a coupled solution approach (since the pressure
488 * Poisson operator is only needed for preconditioning, and hence, only the homogeneous part of
489 * the operator has to be evaluated so that the boundary conditions are never applied).
490 *
491 */
492 std::shared_ptr<Poisson::BoundaryDescriptor<0, dim>> boundary_descriptor_laplace;
493
494 /*
495 * Special case: pure Dirichlet boundary conditions.
496 */
497 dealii::Point<dim> first_point;
498 dealii::types::global_dof_index dof_index_first_point;
499
500 /*
501 * Element variable used to store the current physical time. This variable is needed for the
502 * evaluation of certain integrals or weak forms.
503 */
504 mutable double evaluation_time;
505
506private:
507 /*
508 * Basic finite element ingredients.
509 */
510 std::shared_ptr<dealii::FiniteElement<dim>> fe_u;
511 std::shared_ptr<dealii::FiniteElement<dim>> fe_p;
512 std::shared_ptr<dealii::FiniteElement<dim>> fe_u_scalar;
513
514 dealii::DoFHandler<dim> dof_handler_u;
515 dealii::DoFHandler<dim> dof_handler_p;
516 dealii::DoFHandler<dim> dof_handler_u_scalar;
517
518 dealii::AffineConstraints<Number> constraint_u, constraint_p, constraint_u_scalar;
519
520 std::string const dof_index_u = "velocity";
521 std::string const dof_index_p = "pressure";
522 std::string const dof_index_u_scalar = "velocity_scalar";
523
524 std::string const quad_index_u = "velocity";
525 std::string const quad_index_p = "pressure";
526 std::string const quad_index_u_overintegration = "velocity_overintegration";
527 std::string const quad_index_u_nodal_points = "velocity_nodal_points";
528 std::string const quad_index_p_nodal_points = "pressure_nodal_points";
529
530 std::shared_ptr<MatrixFreeData<dim, Number> const> matrix_free_data;
531 std::shared_ptr<dealii::MatrixFree<dim, Number> const> matrix_free;
532
533 // If we want to be able to update the mapping, we need a pointer to a non-const MatrixFree
534 // object. In case this object is created, we let the above object called matrix_free point to
535 // matrix_free_own_storage. This variable is needed for ALE formulations.
536 std::shared_ptr<dealii::MatrixFree<dim, Number>> matrix_free_own_storage;
537
538 bool pressure_level_is_undefined;
539
540 /*
541 * Interface coupling
542 */
543 std::shared_ptr<ContainerInterfaceData<1, dim, double>> interface_data_dirichlet_cached;
544
545protected:
546 /*
547 * Operator kernels.
548 */
549 Operators::ConvectiveKernelData convective_kernel_data;
550 Operators::ViscousKernelData viscous_kernel_data;
551
552 std::shared_ptr<Operators::ConvectiveKernel<dim, Number>> convective_kernel;
553 std::shared_ptr<Operators::ViscousKernel<dim, Number>> viscous_kernel;
554
555 std::shared_ptr<Operators::DivergencePenaltyKernel<dim, Number>> div_penalty_kernel;
556 std::shared_ptr<Operators::ContinuityPenaltyKernel<dim, Number>> conti_penalty_kernel;
557
558 /*
559 * Basic operators.
560 */
561 MassOperator<dim, dim, Number> mass_operator;
562 ConvectiveOperator<dim, Number> convective_operator;
563 ViscousOperator<dim, Number> viscous_operator;
564 RHSOperator<dim, Number> rhs_operator;
565 GradientOperator<dim, Number> gradient_operator;
566 DivergenceOperator<dim, Number> divergence_operator;
567
568 DivergencePenaltyOperator<dim, Number> div_penalty_operator;
569 ContinuityPenaltyOperator<dim, Number> conti_penalty_operator;
570
571 /*
572 * Linear(ized) momentum operator.
573 */
574 mutable MomentumOperator<dim, Number> momentum_operator;
575
576 /*
577 * Inverse mass operator (for L2 spaces)
578 */
579 InverseMassOperator<dim, dim, Number> inverse_mass_velocity;
580 InverseMassOperator<dim, 1, Number> inverse_mass_velocity_scalar;
581
582 /*
583 * Inverse mass operator used in case of H(div)-conforming space
584 */
586
587 /*
588 * Projection operator.
589 */
590 typedef ProjectionOperator<dim, Number> ProjOperator;
591 std::shared_ptr<ProjOperator> projection_operator;
592
593 /*
594 * Projection solver.
595 */
596
597 // Elementwise solver/preconditioner used in case that only the divergence penalty term is used
598 // and the system of equations is block-diagonal.
599 typedef Elementwise::OperatorBase<dim, Number, ProjOperator> ELEMENTWISE_PROJ_OPERATOR;
600 std::shared_ptr<ELEMENTWISE_PROJ_OPERATOR> elementwise_projection_operator;
601
603 ELEMENTWISE_PRECONDITIONER;
604 std::shared_ptr<ELEMENTWISE_PRECONDITIONER> elementwise_preconditioner_projection;
605
606 // global solver/preconditioner to be used if the continuity penalty term is applied.
607 std::shared_ptr<Krylov::SolverBase<VectorType>> projection_solver;
608 std::shared_ptr<PreconditionerBase<Number>> preconditioner_projection;
609
610 /*
611 * Calculators used to obtain derived quantities.
612 */
613 VorticityCalculator<dim, Number> vorticity_calculator;
614 DivergenceCalculator<dim, Number> divergence_calculator;
615 ShearRateCalculator<dim, Number> shear_rate_calculator;
616 MagnitudeCalculator<dim, Number> magnitude_calculator;
617 QCriterionCalculator<dim, Number> q_criterion_calculator;
618
619 MPI_Comm const mpi_comm;
620
621 dealii::ConditionalOStream pcout;
622
623private:
624 // Minimum element length h_min required for global CFL condition.
625 double
626 calculate_minimum_element_length() const;
627
628 /*
629 * Initialization functions called during setup phase.
630 */
631 void
632 initialize_boundary_descriptor_laplace();
633
634 void
635 initialize_dof_handler_and_constraints();
636
637 void
638 initialize_dirichlet_cached_bc();
639
640 void
641 initialize_operators(std::string const & dof_index_temperature);
642
643 void
644 initialize_calculators_for_derived_quantities();
645
646 void
647 initialization_pure_dirichlet_bc();
648
649 void
650 cell_loop_empty(dealii::MatrixFree<dim, Number> const &,
651 VectorType &,
652 VectorType const &,
653 Range const &) const
654 {
655 }
656
657 void
658 face_loop_empty(dealii::MatrixFree<dim, Number> const &,
659 VectorType &,
660 VectorType const &,
661 Range const &) const
662 {
663 }
664
665 void
666 local_interpolate_stress_bc_boundary_face(dealii::MatrixFree<dim, Number> const & matrix_free,
667 VectorType & dst,
668 VectorType const & src,
669 Range const & face_range) const;
670
671 // Interpolation of stress requires velocity and pressure, but the MatrixFree interface
672 // only provides one argument, so we store pointers to have access to both velocity and
673 // pressure.
674 mutable VectorType const * velocity_ptr;
675 mutable VectorType const * pressure_ptr;
676
677 /*
678 * Variable viscosity models.
679 */
680 mutable TurbulenceModel<dim, Number> turbulence_model;
681 mutable GeneralizedNewtonianModel<dim, Number> generalized_newtonian_model;
682};
683
684} // namespace IncNS
685} // namespace ExaDG
686
687#endif /* INCLUDE_EXADG_INCOMPRESSIBLE_NAVIER_STOKES_SPATIAL_DISCRETIZATION_SPATIAL_OPERATOR_BASE_H_ \
688 */
Definition navier_stokes_calculators.h:35
Definition elementwise_operator.h:33
Definition elementwise_preconditioners.h:41
Definition grid.h:40
Definition continuity_penalty_operator.h:298
Definition convective_operator.h:986
Definition divergence_operator.h:123
Definition divergence_penalty_operator.h:244
Definition generalized_newtonian_model.h:37
Definition gradient_operator.h:122
Definition momentum_operator.h:54
Definition parameters.h:46
Definition projection_operator.h:78
Definition rhs_operator.h:140
Definition spatial_operator_base.h:68
void setup()
Definition spatial_operator_base.cpp:681
Definition turbulence_model.h:37
Definition viscous_operator.h:564
Definition inverse_mass_operator.h:284
Definition navier_stokes_calculators.h:150
Definition mass_operator.h:41
Definition grid.h:84
Definition multigrid_preconditioner.h:38
Definition navier_stokes_calculators.h:191
Definition navier_stokes_calculators.h:72
Definition navier_stokes_calculators.h:114
Definition driver.cpp:33
Definition boundary_descriptor.h:240
Definition field_functions.h:31
Definition convective_operator.h:37
Definition viscous_operator.h:40
Definition matrix_free_data.h:40