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>
64class SpatialOperatorBase;
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
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
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_linear() 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_nonlinear() const;
170
171 unsigned int
172 get_quad_index_velocity_gauss_lobatto() const;
173
174 unsigned int
175 get_quad_index_pressure_gauss_lobatto() 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 // FSI: coupling fluid -> structure
242 // fills a DoF-vector (velocity) with values of traction on fluid-structure interface
243 void
244 interpolate_stress_bc(VectorType & stress,
245 VectorType const & velocity,
246 VectorType const & pressure) const;
247
248 /*
249 * Time step calculation.
250 */
251
252 /*
253 * Calculate time step size according to maximum efficiency criterion
254 */
255 double
256 calculate_time_step_max_efficiency(unsigned int const order_time_integrator) const;
257
258 // global CFL criterion
259 double
260 calculate_time_step_cfl_global() const;
261
262 // Calculate time step size according to local CFL criterion
263 double
264 calculate_time_step_cfl(VectorType const & velocity) const;
265
266 // Calculate CFL numbers of cells
267 void
268 calculate_cfl_from_time_step(VectorType & cfl,
269 VectorType const & velocity,
270 double const time_step_size) const;
271
272 /*
273 * Returns characteristic element length for high-order elements / shape functions
274 */
275 double
276 get_characteristic_element_length() const;
277
278 /*
279 * For certain setups and types of boundary conditions, the pressure field is only defined up to
280 * an additive constant which originates from the fact that only the derivative of the pressure
281 * appears in the incompressible Navier-Stokes equations. Examples of such a scenario are problems
282 * where the velocity is prescribed on the whole boundary or periodic boundaries.
283 */
284
285 // This function can be used to query whether the pressure level is undefined.
286 bool
287 is_pressure_level_undefined() const;
288
289 // This function adjust the pressure level, where different options are available to fix the
290 // pressure level. The method selected by this function depends on the specified parameter.
291 void
292 adjust_pressure_level_if_undefined(VectorType & pressure, double const & time) const;
293
294 /*
295 * Boussinesq approximation
296 */
297 void
298 set_temperature(VectorType const & temperature);
299
300 /*
301 * Computation of derived quantities which is needed for postprocessing but some of them are also
302 * needed, e.g., for special splitting-type time integration schemes.
303 */
304
305 // vorticity
306 void
307 compute_vorticity(VectorType & dst, VectorType const & src) const;
308
309 // divergence
310 void
311 compute_divergence(VectorType & dst, VectorType const & src) const;
312
313 // shear rate
314 void
315 compute_shear_rate(VectorType & dst, VectorType const & src) const;
316
317 // velocity_magnitude
318 void
319 compute_velocity_magnitude(VectorType & dst, VectorType const & src) const;
320
321 // vorticity_magnitude
322 void
323 compute_vorticity_magnitude(VectorType & dst, VectorType const & src) const;
324
325 // streamfunction
326 void
327 compute_streamfunction(VectorType & dst, VectorType const & src) const;
328
329 // Q criterion
330 void
331 compute_q_criterion(VectorType & dst, VectorType const & src) const;
332
333 /*
334 * Operators.
335 */
336
337 // mass operator
338 void
339 apply_mass_operator(VectorType & dst, VectorType const & src) const;
340
341 void
342 apply_mass_operator_add(VectorType & dst, VectorType const & src) const;
343
344 // body force term
345 void
346 evaluate_add_body_force_term(VectorType & dst, double const time) const;
347
348 // convective term
349 void
350 evaluate_convective_term(VectorType & dst, VectorType const & src, Number const time) const;
351
352 // pressure gradient term
353 void
354 evaluate_pressure_gradient_term(VectorType & dst,
355 VectorType const & src,
356 double const time) const;
357
358 // velocity divergence
359 void
360 evaluate_velocity_divergence_term(VectorType & dst,
361 VectorType const & src,
362 double const time) const;
363
364 // inverse velocity mass operator
365 unsigned int
366 apply_inverse_mass_operator(VectorType & dst, VectorType const & src) const;
367
368 /*
369 * Update variable viscosity.
370 */
371 void
372 update_viscosity(VectorType const & velocity) const;
373
374 /*
375 * Projection step.
376 */
377 void
378 update_projection_operator(VectorType const & velocity, double const time_step_size) const;
379
380 void
381 rhs_add_projection_operator(VectorType & dst, double const time) const;
382
383 unsigned int
384 solve_projection(VectorType & dst,
385 VectorType const & src,
386 bool const & update_preconditioner) const;
387
388 /*
389 * Postprocessing.
390 */
391 double
392 calculate_dissipation_convective_term(VectorType const & velocity, double const time) const;
393
394 double
395 calculate_dissipation_viscous_term(VectorType const & velocity) const;
396
397 double
398 calculate_dissipation_divergence_term(VectorType const & velocity) const;
399
400 double
401 calculate_dissipation_continuity_term(VectorType const & velocity) const;
402
403 /*
404 * Updates operators after grid has been moved.
405 */
406 virtual void
407 update_after_grid_motion(bool const update_matrix_free);
408
409 /*
410 * Sets the grid velocity.
411 */
412 void
413 set_grid_velocity(VectorType const & velocity);
414
415 /*
416 * Calls constraint_u.distribute(u) and updates the constrained DoFs of the velocity field
417 */
418 void
419 distribute_constraint_u(VectorType & velocity) const;
420
421protected:
422 /*
423 * Projection step.
424 */
425 void
426 setup_projection_solver();
427
428 bool
429 unsteady_problem_has_to_be_solved() const;
430
431 /*
432 * Grid
433 */
434 std::shared_ptr<Grid<dim> const> grid;
435
436 /*
437 * dealii::Mapping (In case of moving meshes (ALE), this is the dynamic mapping describing the
438 * deformed configuration.)
439 */
440 std::shared_ptr<dealii::Mapping<dim> const> mapping;
441
442 std::shared_ptr<MultigridMappings<dim, Number>> const multigrid_mappings;
443
444 /*
445 * User interface: Boundary conditions and field functions.
446 */
447 std::shared_ptr<BoundaryDescriptor<dim> const> boundary_descriptor;
448 std::shared_ptr<FieldFunctions<dim> const> field_functions;
449
450 /*
451 * List of parameters.
452 */
453 Parameters const & param;
454
455 /*
456 * A name describing the field being solved.
457 */
458 std::string const field;
459
460 /*
461 * In case of projection type incompressible Navier-Stokes solvers this variable is needed to
462 * solve the pressure Poisson equation. However, this variable is also needed in case of a
463 * coupled solution approach. In that case, it is used for the block preconditioner (or more
464 * precisely for the Schur-complement preconditioner and the preconditioner used to approximately
465 * invert the Laplace operator).
466 *
467 * While the functions specified in BoundaryDescriptorLaplace are relevant for projection-type
468 * solvers (pressure Poisson equation has to be solved), the function specified in
469 * BoundaryDescriptorLaplace are irrelevant for a coupled solution approach (since the pressure
470 * Poisson operator is only needed for preconditioning, and hence, only the homogeneous part of
471 * the operator has to be evaluated so that the boundary conditions are never applied).
472 *
473 */
474 std::shared_ptr<Poisson::BoundaryDescriptor<0, dim>> boundary_descriptor_laplace;
475
476 /*
477 * Special case: pure Dirichlet boundary conditions.
478 */
479 dealii::Point<dim> first_point;
480 dealii::types::global_dof_index dof_index_first_point;
481
482 /*
483 * Element variable used to store the current physical time. This variable is needed for the
484 * evaluation of certain integrals or weak forms.
485 */
486 mutable double evaluation_time;
487
488private:
489 /*
490 * Basic finite element ingredients.
491 */
492 std::shared_ptr<dealii::FiniteElement<dim>> fe_u;
493 std::shared_ptr<dealii::FiniteElement<dim>> fe_p;
494 std::shared_ptr<dealii::FiniteElement<dim>> fe_u_scalar;
495
496 dealii::DoFHandler<dim> dof_handler_u;
497 dealii::DoFHandler<dim> dof_handler_p;
498 dealii::DoFHandler<dim> dof_handler_u_scalar;
499
500 dealii::AffineConstraints<Number> constraint_u, constraint_p, constraint_u_scalar;
501
502 std::string const dof_index_u = "velocity";
503 std::string const dof_index_p = "pressure";
504 std::string const dof_index_u_scalar = "velocity_scalar";
505
506 std::string const quad_index_u = "velocity";
507 std::string const quad_index_p = "pressure";
508 std::string const quad_index_u_nonlinear = "velocity_nonlinear";
509 std::string const quad_index_u_gauss_lobatto = "velocity_gauss_lobatto";
510 std::string const quad_index_p_gauss_lobatto = "pressure_gauss_lobatto";
511
512 std::shared_ptr<MatrixFreeData<dim, Number> const> matrix_free_data;
513 std::shared_ptr<dealii::MatrixFree<dim, Number> const> matrix_free;
514
515 // If we want to be able to update the mapping, we need a pointer to a non-const MatrixFree
516 // object. In case this object is created, we let the above object called matrix_free point to
517 // matrix_free_own_storage. This variable is needed for ALE formulations.
518 std::shared_ptr<dealii::MatrixFree<dim, Number>> matrix_free_own_storage;
519
520 bool pressure_level_is_undefined;
521
522 /*
523 * Interface coupling
524 */
525 std::shared_ptr<ContainerInterfaceData<1, dim, double>> interface_data_dirichlet_cached;
526
527protected:
528 /*
529 * Operator kernels.
530 */
531 Operators::ConvectiveKernelData convective_kernel_data;
532 Operators::ViscousKernelData viscous_kernel_data;
533
534 std::shared_ptr<Operators::ConvectiveKernel<dim, Number>> convective_kernel;
535 std::shared_ptr<Operators::ViscousKernel<dim, Number>> viscous_kernel;
536
537 std::shared_ptr<Operators::DivergencePenaltyKernel<dim, Number>> div_penalty_kernel;
538 std::shared_ptr<Operators::ContinuityPenaltyKernel<dim, Number>> conti_penalty_kernel;
539
540 /*
541 * Basic operators.
542 */
543 MassOperator<dim, dim, Number> mass_operator;
544 ConvectiveOperator<dim, Number> convective_operator;
545 ViscousOperator<dim, Number> viscous_operator;
546 RHSOperator<dim, Number> rhs_operator;
547 GradientOperator<dim, Number> gradient_operator;
548 DivergenceOperator<dim, Number> divergence_operator;
549
550 DivergencePenaltyOperator<dim, Number> div_penalty_operator;
551 ContinuityPenaltyOperator<dim, Number> conti_penalty_operator;
552
553 /*
554 * Linear(ized) momentum operator.
555 */
556 mutable MomentumOperator<dim, Number> momentum_operator;
557
558 /*
559 * Inverse mass operator (for L2 spaces)
560 */
561 InverseMassOperator<dim, dim, Number> inverse_mass_velocity;
562 InverseMassOperator<dim, 1, Number> inverse_mass_velocity_scalar;
563
564 /*
565 * Inverse mass operator used in case of H(div)-conforming space
566 */
568
569 /*
570 * Projection operator.
571 */
573 std::shared_ptr<ProjOperator> projection_operator;
574
575 /*
576 * Projection solver.
577 */
578
579 // Elementwise solver/preconditioner used in case that only the divergence penalty term is used
580 // and the system of equations is block-diagonal.
582 std::shared_ptr<ELEMENTWISE_PROJ_OPERATOR> elementwise_projection_operator;
583
586 std::shared_ptr<ELEMENTWISE_PRECONDITIONER> elementwise_preconditioner_projection;
587
588 // global solver/preconditioner to be used if the continuity penalty term is applied.
589 std::shared_ptr<Krylov::SolverBase<VectorType>> projection_solver;
590 std::shared_ptr<PreconditionerBase<Number>> preconditioner_projection;
591
592 /*
593 * Calculators used to obtain derived quantities.
594 */
595 VorticityCalculator<dim, Number> vorticity_calculator;
596 DivergenceCalculator<dim, Number> divergence_calculator;
597 ShearRateCalculator<dim, Number> shear_rate_calculator;
598 MagnitudeCalculator<dim, Number> magnitude_calculator;
599 QCriterionCalculator<dim, Number> q_criterion_calculator;
600
601 MPI_Comm const mpi_comm;
602
603 dealii::ConditionalOStream pcout;
604
605private:
606 // Minimum element length h_min required for global CFL condition.
607 double
608 calculate_minimum_element_length() const;
609
610 /*
611 * Initialization functions called during setup phase.
612 */
613 void
614 initialize_boundary_descriptor_laplace();
615
616 void
617 initialize_dof_handler_and_constraints();
618
619 void
620 initialize_dirichlet_cached_bc();
621
622 void
623 initialize_operators(std::string const & dof_index_temperature);
624
625 void
626 initialize_calculators_for_derived_quantities();
627
628 void
629 initialization_pure_dirichlet_bc();
630
631 void
632 cell_loop_empty(dealii::MatrixFree<dim, Number> const &,
633 VectorType &,
634 VectorType const &,
635 Range const &) const
636 {
637 }
638
639 void
640 face_loop_empty(dealii::MatrixFree<dim, Number> const &,
641 VectorType &,
642 VectorType const &,
643 Range const &) const
644 {
645 }
646
647 void
648 local_interpolate_stress_bc_boundary_face(dealii::MatrixFree<dim, Number> const & matrix_free,
649 VectorType & dst,
650 VectorType const & src,
651 Range const & face_range) const;
652
653 // Interpolation of stress requires velocity and pressure, but the MatrixFree interface
654 // only provides one argument, so we store pointers to have access to both velocity and
655 // pressure.
656 mutable VectorType const * velocity_ptr;
657 mutable VectorType const * pressure_ptr;
658
659 /*
660 * Variable viscosity models.
661 */
662 mutable TurbulenceModel<dim, Number> turbulence_model;
663 mutable GeneralizedNewtonianModel<dim, Number> generalized_newtonian_model;
664};
665
666} // namespace IncNS
667} // namespace ExaDG
668
669#endif /* INCLUDE_EXADG_INCOMPRESSIBLE_NAVIER_STOKES_SPATIAL_DISCRETIZATION_SPATIAL_OPERATOR_BASE_H_ \
670 */
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:284
Definition convective_operator.h:858
Definition divergence_operator.h:109
Definition divergence_penalty_operator.h:230
Definition generalized_newtonian_model.h:37
Definition gradient_operator.h:108
Definition momentum_operator.h:40
Definition parameters.h:46
Definition projection_operator.h:64
Definition rhs_operator.h:126
Definition spatial_operator_base.h:68
void setup()
Definition spatial_operator_base.cpp:676
Definition turbulence_model.h:37
Definition viscous_operator.h:550
Definition inverse_mass_operator.h:284
Definition inverse_mass_operator.h:53
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:23
Definition viscous_operator.h:26
Definition matrix_free_data.h:40