From 51cf063ea7c8fff9a977026f16cde04fb61d9afb Mon Sep 17 00:00:00 2001 From: blaisb Date: Fri, 12 Jul 2024 12:19:57 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20chaos-po?= =?UTF-8?q?lymtl/lethe@49a2616679d509ca1008cd85d564450e4522efe7=20?= =?UTF-8?q?=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doxygen/cfd__dem__coupling_8cc_source.html | 2 +- doxygen/classCFDDEMSolver.html | 2 +- doxygen/classGLSNavierStokesSolver.html | 20 +- .../classGLSNitscheNavierStokesSolver.html | 4 +- doxygen/classGLSSharpNavierStokesSolver.html | 6 +- .../classMFNavierStokesPreconditionGMG.html | 14 +- doxygen/classMFNavierStokesSolver.html | 42 +- doxygen/classNavierStokesBase.html | 34 +- doxygen/classNavierStokesOperatorBase.html | 32 +- .../classNavierStokesStabilizedOperator.html | 4 +- doxygen/gls__navier__stokes_8cc_source.html | 1482 +++--- ...s__nitsche__navier__stokes_8cc_source.html | 4 +- ...gls__sharp__navier__stokes_8cc_source.html | 6 +- doxygen/mf__navier__stokes_8cc_source.html | 4505 +++++++++-------- ..._navier__stokes__operators_8cc_source.html | 1695 ++++--- doxygen/navier__stokes__base_8cc_source.html | 3240 ++++++------ 16 files changed, 5581 insertions(+), 5511 deletions(-) diff --git a/doxygen/cfd__dem__coupling_8cc_source.html b/doxygen/cfd__dem__coupling_8cc_source.html index 6e7b5b3b27..744a494e22 100644 --- a/doxygen/cfd__dem__coupling_8cc_source.html +++ b/doxygen/cfd__dem__coupling_8cc_source.html @@ -1888,7 +1888,7 @@
Definition: gls_vans.h:116
virtual void monitor_mass_conservation()
Definition: gls_vans.cc:1799
virtual void refine_mesh()
Allow the refinement of the mesh according to one of the 2 methods proposed.
-
virtual void postprocess_fd(bool first_iteration)
postprocess Post-process fluid dynamics after an iteration
+
virtual void postprocess_fd(bool first_iteration)
postprocess Post-process fluid dynamics after an iteration
Definition: visualization.h:45
void build_patches(Particles::ParticleHandler< dim > &particle_handler, std::vector< std::pair< std::string, int >> properties)
Small class that is used to store statistics (min,max,total,average) of variables that are used in si...
Definition: utilities.h:42
diff --git a/doxygen/classCFDDEMSolver.html b/doxygen/classCFDDEMSolver.html index f6ecb89bc6..4bce1dde46 100644 --- a/doxygen/classCFDDEMSolver.html +++ b/doxygen/classCFDDEMSolver.html @@ -1188,7 +1188,7 @@

Definition at line 1231 of file cfd_dem_coupling.cc.

-

References NavierStokesBase< dim, GlobalVectorType, IndexSet >::postprocess_fd().

+

References NavierStokesBase< dim, GlobalVectorType, IndexSet >::postprocess_fd().

diff --git a/doxygen/classGLSNavierStokesSolver.html b/doxygen/classGLSNavierStokesSolver.html index fc3f00dedd..785c290be4 100644 --- a/doxygen/classGLSNavierStokesSolver.html +++ b/doxygen/classGLSNavierStokesSolver.html @@ -478,7 +478,7 @@

This L2 projection matrix can be used to set the initial condition for the Navier-Stokes problem.

-

Definition at line 1270 of file gls_navier_stokes.cc.

+

Definition at line 1280 of file gls_navier_stokes.cc.

References pressure.

@@ -887,7 +887,7 @@

Definition at line 1122 of file gls_navier_stokes.cc.

-

References Parameters::Timer::end, fluid_dynamics, Parameters::LinearSolver::gmres, Parameters::L2projection, Parameters::nodal, Parameters::ramp, read_checkpoint(), PhysicsSolver< VectorType >::solve_non_linear_system(), Parameters::SimulationControl::steady, and Parameters::viscous.

+

References fluid_dynamics, Parameters::LinearSolver::gmres, Parameters::L2projection, Parameters::nodal, Parameters::Timer::none, Parameters::ramp, read_checkpoint(), PhysicsSolver< VectorType >::solve_non_linear_system(), Parameters::SimulationControl::steady, and Parameters::viscous.

@@ -915,7 +915,7 @@

Definition at line 1435 of file gls_navier_stokes.cc.

+

Definition at line 1445 of file gls_navier_stokes.cc.

References fluid_dynamics.

@@ -1009,7 +1009,7 @@

Definition at line 1415 of file gls_navier_stokes.cc.

+

Definition at line 1425 of file gls_navier_stokes.cc.

References fluid_dynamics.

@@ -1041,7 +1041,7 @@

PhysicsSolver< VectorType >.

-

Definition at line 1390 of file gls_navier_stokes.cc.

+

Definition at line 1400 of file gls_navier_stokes.cc.

References Parameters::LinearSolver::amg, fluid_dynamics, and Parameters::LinearSolver::ilu.

@@ -1074,7 +1074,7 @@

GLSNitscheNavierStokesSolver< dim, spacedim >, GLSVANSSolver< dim >, GLSSharpNavierStokesSolver< dim >, and CFDDEMSolver< dim >.

-

Definition at line 1796 of file gls_navier_stokes.cc.

+

Definition at line 1806 of file gls_navier_stokes.cc.

References Parameters::MeshAdaptation::none, read_mesh_and_manifolds(), and NavierStokesBase< dim, VectorType, DofsType >::refine_mesh().

@@ -1128,7 +1128,7 @@

PhysicsSolver< VectorType >.

-

Definition at line 1353 of file gls_navier_stokes.cc.

+

Definition at line 1363 of file gls_navier_stokes.cc.

References Parameters::LinearSolver::bicgstab, Parameters::LinearSolver::direct, fluid_dynamics, and Parameters::LinearSolver::gmres.

@@ -1178,7 +1178,7 @@

Definition at line 1652 of file gls_navier_stokes.cc.

+

Definition at line 1662 of file gls_navier_stokes.cc.

References Parameters::extra_verbose, fluid_dynamics, Parameters::LinearSolver::ilu, and Parameters::quiet.

@@ -1228,7 +1228,7 @@

Definition at line 1759 of file gls_navier_stokes.cc.

+

Definition at line 1769 of file gls_navier_stokes.cc.

References fluid_dynamics.

@@ -1278,7 +1278,7 @@

Definition at line 1508 of file gls_navier_stokes.cc.

+

Definition at line 1518 of file gls_navier_stokes.cc.

References Parameters::LinearSolver::amg, Parameters::extra_verbose, fluid_dynamics, Parameters::LinearSolver::ilu, and Parameters::quiet.

diff --git a/doxygen/classGLSNitscheNavierStokesSolver.html b/doxygen/classGLSNitscheNavierStokesSolver.html index 843625126a..6a5a0dcea8 100644 --- a/doxygen/classGLSNitscheNavierStokesSolver.html +++ b/doxygen/classGLSNitscheNavierStokesSolver.html @@ -928,7 +928,7 @@

Definition at line 1014 of file gls_nitsche_navier_stokes.cc.

-

References fill_table_from_file(), and NavierStokesBase< dim, GlobalVectorType, IndexSet >::read_checkpoint().

+

References fill_table_from_file(), and NavierStokesBase< dim, GlobalVectorType, IndexSet >::read_checkpoint().

@@ -1025,7 +1025,7 @@

Definition at line 973 of file gls_nitsche_navier_stokes.cc.

-

References NavierStokesBase< dim, GlobalVectorType, IndexSet >::write_checkpoint().

+

References NavierStokesBase< dim, GlobalVectorType, IndexSet >::write_checkpoint().

diff --git a/doxygen/classGLSSharpNavierStokesSolver.html b/doxygen/classGLSSharpNavierStokesSolver.html index 8ed711eee4..adaf0dbfc5 100644 --- a/doxygen/classGLSSharpNavierStokesSolver.html +++ b/doxygen/classGLSSharpNavierStokesSolver.html @@ -1462,7 +1462,7 @@

Definition at line 1737 of file gls_sharp_navier_stokes.cc.

-

References NavierStokesBase< dim, VectorType, DofsType >::postprocess_fd(), Parameters::SimulationControl::steady, and Parameters::verbose.

+

References NavierStokesBase< dim, VectorType, DofsType >::postprocess_fd(), Parameters::SimulationControl::steady, and Parameters::verbose.

@@ -1494,7 +1494,7 @@

Definition at line 4318 of file gls_sharp_navier_stokes.cc.

-

References GLSSharpNavierStokesSolver< dim >::cfd_dem_parameters, GLSSharpNavierStokesSolver< dim >::check_whether_all_particles_are_sphere(), NavierStokesBase< dim, GlobalVectorType, IndexSet >::computing_timer, NavierStokesBase< dim, GlobalVectorType, IndexSet >::dof_handler, fill_table_from_file(), fill_vectors_from_file(), GLSSharpNavierStokesSolver< dim >::ib_dem, GLSSharpNavierStokesSolver< dim >::ib_particles_pvdhandler, GLSSharpNavierStokesSolver< dim >::particles, PVDHandler::read(), NavierStokesBase< dim, GlobalVectorType, IndexSet >::read_checkpoint(), NavierStokesBase< dim, GlobalVectorType, IndexSet >::simulation_parameters, GLSSharpNavierStokesSolver< dim >::table_p, and GLSSharpNavierStokesSolver< dim >::update_precalculations_for_ib().

+

References GLSSharpNavierStokesSolver< dim >::cfd_dem_parameters, GLSSharpNavierStokesSolver< dim >::check_whether_all_particles_are_sphere(), NavierStokesBase< dim, GlobalVectorType, IndexSet >::computing_timer, NavierStokesBase< dim, GlobalVectorType, IndexSet >::dof_handler, fill_table_from_file(), fill_vectors_from_file(), GLSSharpNavierStokesSolver< dim >::ib_dem, GLSSharpNavierStokesSolver< dim >::ib_particles_pvdhandler, GLSSharpNavierStokesSolver< dim >::particles, PVDHandler::read(), NavierStokesBase< dim, GlobalVectorType, IndexSet >::read_checkpoint(), NavierStokesBase< dim, GlobalVectorType, IndexSet >::simulation_parameters, GLSSharpNavierStokesSolver< dim >::table_p, and GLSSharpNavierStokesSolver< dim >::update_precalculations_for_ib().

@@ -1757,7 +1757,7 @@

Definition at line 4175 of file gls_sharp_navier_stokes.cc.

-

References GLSSharpNavierStokesSolver< dim >::ib_particles_pvdhandler, NavierStokesBase< dim, GlobalVectorType, IndexSet >::mpi_communicator, GLSSharpNavierStokesSolver< dim >::particles, NavierStokesBase< dim, GlobalVectorType, IndexSet >::pvdhandler, PVDHandler::save(), NavierStokesBase< dim, GlobalVectorType, IndexSet >::simulation_control, NavierStokesBase< dim, GlobalVectorType, IndexSet >::simulation_parameters, and NavierStokesBase< dim, GlobalVectorType, IndexSet >::write_checkpoint().

+

References GLSSharpNavierStokesSolver< dim >::ib_particles_pvdhandler, NavierStokesBase< dim, GlobalVectorType, IndexSet >::mpi_communicator, GLSSharpNavierStokesSolver< dim >::particles, NavierStokesBase< dim, GlobalVectorType, IndexSet >::pvdhandler, PVDHandler::save(), NavierStokesBase< dim, GlobalVectorType, IndexSet >::simulation_control, NavierStokesBase< dim, GlobalVectorType, IndexSet >::simulation_parameters, and NavierStokesBase< dim, GlobalVectorType, IndexSet >::write_checkpoint().

diff --git a/doxygen/classMFNavierStokesPreconditionGMG.html b/doxygen/classMFNavierStokesPreconditionGMG.html index 0b9902165d..ed04ab1a78 100644 --- a/doxygen/classMFNavierStokesPreconditionGMG.html +++ b/doxygen/classMFNavierStokesPreconditionGMG.html @@ -490,7 +490,7 @@

Definition at line 211 of file mf_navier_stokes.cc.

-

References SimulationParameters< dim >::boundary_conditions, MFNavierStokesPreconditionGMG< dim >::coarse_grid_triangulations, MFNavierStokesPreconditionGMG< dim >::dof_handler, MFNavierStokesPreconditionGMG< dim >::dof_handler_fe_q_iso_q1, MFNavierStokesPreconditionGMG< dim >::dof_handlers, fluid_dynamics, BoundaryConditions::function_weak, Parameters::LinearSolver::gcmg, PhysicalPropertiesManager::get_kinematic_viscosity_scale(), SimulationParameters< dim >::linear_solver, MFNavierStokesPreconditionGMG< dim >::ls_mg_interface_in, MFNavierStokesPreconditionGMG< dim >::ls_mg_operators, Parameters::LinearSolver::lsmg, MFNavierStokesPreconditionGMG< dim >::maxlevel, MFNavierStokesPreconditionGMG< dim >::mg_constrained_dofs, MFNavierStokesPreconditionGMG< dim >::mg_operators, MFNavierStokesPreconditionGMG< dim >::mg_setup_timer, MFNavierStokesPreconditionGMG< dim >::mg_transfer_gc, MFNavierStokesPreconditionGMG< dim >::mg_transfer_ls, MFNavierStokesPreconditionGMG< dim >::minlevel, BoundaryConditions::outlet, BoundaryConditions::partial_slip, MFNavierStokesPreconditionGMG< dim >::pcout, BoundaryConditions::periodic, SimulationParameters< dim >::physical_properties_manager, BoundaryConditions::pressure, pressure, Parameters::quiet, BoundaryConditions::slip, Parameters::Stabilization::stabilization, SimulationParameters< dim >::stabilization, and MFNavierStokesPreconditionGMG< dim >::transfers.

+

References SimulationParameters< dim >::boundary_conditions, MFNavierStokesPreconditionGMG< dim >::coarse_grid_triangulations, MFNavierStokesPreconditionGMG< dim >::dof_handler, MFNavierStokesPreconditionGMG< dim >::dof_handler_fe_q_iso_q1, MFNavierStokesPreconditionGMG< dim >::dof_handlers, Parameters::extra_verbose, fluid_dynamics, BoundaryConditions::function_weak, Parameters::LinearSolver::gcmg, PhysicalPropertiesManager::get_kinematic_viscosity_scale(), SimulationParameters< dim >::linear_solver, MFNavierStokesPreconditionGMG< dim >::ls_mg_interface_in, MFNavierStokesPreconditionGMG< dim >::ls_mg_operators, Parameters::LinearSolver::lsmg, MFNavierStokesPreconditionGMG< dim >::maxlevel, MFNavierStokesPreconditionGMG< dim >::mg_constrained_dofs, MFNavierStokesPreconditionGMG< dim >::mg_operators, MFNavierStokesPreconditionGMG< dim >::mg_setup_timer, MFNavierStokesPreconditionGMG< dim >::mg_transfer_gc, MFNavierStokesPreconditionGMG< dim >::mg_transfer_ls, MFNavierStokesPreconditionGMG< dim >::minlevel, BoundaryConditions::outlet, BoundaryConditions::partial_slip, MFNavierStokesPreconditionGMG< dim >::pcout, BoundaryConditions::periodic, SimulationParameters< dim >::physical_properties_manager, BoundaryConditions::pressure, pressure, Parameters::quiet, BoundaryConditions::slip, Parameters::Stabilization::stabilization, SimulationParameters< dim >::stabilization, and MFNavierStokesPreconditionGMG< dim >::transfers.

@@ -512,7 +512,7 @@

Returns
Multigrid object that contains all level operators.
-

Definition at line 1291 of file mf_navier_stokes.cc.

+

Definition at line 1315 of file mf_navier_stokes.cc.

@@ -567,7 +567,7 @@

Definition at line 838 of file mf_navier_stokes.cc.

+

Definition at line 862 of file mf_navier_stokes.cc.

References Parameters::LinearSolver::amg, Parameters::LinearSolver::direct, fluid_dynamics, Parameters::LinearSolver::gcmg, FlowControl< dim >::get_beta(), Parameters::LinearSolver::gmres, Parameters::LinearSolver::ilu, is_bdf(), Parameters::LinearSolver::lsmg, and Parameters::quiet.

@@ -589,7 +589,7 @@

Definition at line 1264 of file mf_navier_stokes.cc.

+

Definition at line 1288 of file mf_navier_stokes.cc.

References fluid_dynamics, and Parameters::LinearSolver::gmres.

@@ -619,7 +619,7 @@

Definition at line 1298 of file mf_navier_stokes.cc.

+

Definition at line 1322 of file mf_navier_stokes.cc.

References fluid_dynamics, Parameters::LinearSolver::gcmg, and Parameters::LinearSolver::lsmg.

@@ -649,7 +649,7 @@

Definition at line 1404 of file mf_navier_stokes.cc.

+

Definition at line 1428 of file mf_navier_stokes.cc.

References fluid_dynamics.

@@ -692,7 +692,7 @@

Definition at line 1244 of file mf_navier_stokes.cc.

+

Definition at line 1268 of file mf_navier_stokes.cc.

References fluid_dynamics, and Parameters::LinearSolver::gmres.

diff --git a/doxygen/classMFNavierStokesSolver.html b/doxygen/classMFNavierStokesSolver.html index 6f1e0d187c..197d37eb30 100644 --- a/doxygen/classMFNavierStokesSolver.html +++ b/doxygen/classMFNavierStokesSolver.html @@ -457,7 +457,7 @@

Definition at line 1427 of file mf_navier_stokes.cc.

+

Definition at line 1451 of file mf_navier_stokes.cc.

References NavierStokesBase< dim, LinearAlgebra::distributed::Vector< double >, IndexSet >::fe, SimulationParameters< dim >::fem_parameters, NavierStokesBase< dim, LinearAlgebra::distributed::Vector< double >, IndexSet >::forcing_function, Parameters::FEM::pressure_order, NavierStokesBase< dim, LinearAlgebra::distributed::Vector< double >, IndexSet >::simulation_parameters, MFNavierStokesSolver< dim >::system_operator, and Parameters::FEM::velocity_order.

@@ -479,7 +479,7 @@

Definition at line 1450 of file mf_navier_stokes.cc.

+

Definition at line 1474 of file mf_navier_stokes.cc.

@@ -508,7 +508,7 @@

Definition at line 2378 of file mf_navier_stokes.cc.

+

Definition at line 2412 of file mf_navier_stokes.cc.

@@ -538,7 +538,7 @@

PhysicsSolver< VectorType >.

-

Definition at line 1953 of file mf_navier_stokes.cc.

+

Definition at line 1987 of file mf_navier_stokes.cc.

@@ -568,7 +568,7 @@

PhysicsSolver< VectorType >.

-

Definition at line 1961 of file mf_navier_stokes.cc.

+

Definition at line 1995 of file mf_navier_stokes.cc.

@@ -596,7 +596,7 @@

Definition at line 1999 of file mf_navier_stokes.cc.

+

Definition at line 2033 of file mf_navier_stokes.cc.

References number_of_previous_solutions().

@@ -626,7 +626,7 @@

Definition at line 2152 of file mf_navier_stokes.cc.

+

Definition at line 2186 of file mf_navier_stokes.cc.

References BoundaryConditions::function, BoundaryConditions::noslip, BoundaryConditions::periodic, pressure, and BoundaryConditions::slip.

@@ -656,7 +656,7 @@

Definition at line 2242 of file mf_navier_stokes.cc.

+

Definition at line 2276 of file mf_navier_stokes.cc.

References BoundaryConditions::function_weak, BoundaryConditions::outlet, BoundaryConditions::partial_slip, BoundaryConditions::periodic, BoundaryConditions::pressure, pressure, and BoundaryConditions::slip.

@@ -686,7 +686,7 @@

Definition at line 2066 of file mf_navier_stokes.cc.

+

Definition at line 2100 of file mf_navier_stokes.cc.

References announce_string(), Parameters::extra_verbose, and fluid_dynamics.

@@ -739,9 +739,9 @@

NavierStokesBase< dim, LinearAlgebra::distributed::Vector< double >, IndexSet >.

-

Definition at line 1718 of file mf_navier_stokes.cc.

+

Definition at line 1742 of file mf_navier_stokes.cc.

-

References Parameters::Timer::end, fluid_dynamics, Parameters::LinearSolver::gcmg, Parameters::LinearSolver::lsmg, Parameters::nodal, Parameters::ramp, read_checkpoint(), Parameters::SimulationControl::steady, and Parameters::viscous.

+

References fluid_dynamics, Parameters::LinearSolver::gcmg, Parameters::LinearSolver::lsmg, Parameters::nodal, Parameters::Timer::none, Parameters::ramp, read_checkpoint(), Parameters::SimulationControl::steady, and Parameters::viscous.

@@ -771,7 +771,7 @@

NavierStokesBase< dim, LinearAlgebra::distributed::Vector< double >, IndexSet >.

-

Definition at line 1552 of file mf_navier_stokes.cc.

+

Definition at line 1576 of file mf_navier_stokes.cc.

References fluid_dynamics, and Parameters::LinearSolver::lsmg.

@@ -801,7 +801,7 @@

Definition at line 2018 of file mf_navier_stokes.cc.

+

Definition at line 2052 of file mf_navier_stokes.cc.

@@ -829,7 +829,7 @@

Definition at line 2041 of file mf_navier_stokes.cc.

+

Definition at line 2075 of file mf_navier_stokes.cc.

References fluid_dynamics.

@@ -861,7 +861,7 @@

PhysicsSolver< VectorType >.

-

Definition at line 2321 of file mf_navier_stokes.cc.

+

Definition at line 2355 of file mf_navier_stokes.cc.

References Parameters::LinearSolver::amg, fluid_dynamics, Parameters::LinearSolver::gcmg, Parameters::LinearSolver::ilu, and Parameters::LinearSolver::lsmg.

@@ -891,7 +891,7 @@

Definition at line 1457 of file mf_navier_stokes.cc.

+

Definition at line 1481 of file mf_navier_stokes.cc.

References Parameters::Timer::end, is_bdf(), Parameters::Timer::iteration, Parameters::MeshAdaptation::none, read_mesh_and_manifolds(), and NavierStokesBase< dim, VectorType, DofsType >::refine_mesh().

@@ -944,7 +944,7 @@

PhysicsSolver< VectorType >.

-

Definition at line 2358 of file mf_navier_stokes.cc.

+

Definition at line 2392 of file mf_navier_stokes.cc.

References fluid_dynamics, and Parameters::LinearSolver::gmres.

@@ -1002,7 +1002,7 @@

Definition at line 2385 of file mf_navier_stokes.cc.

+

Definition at line 2419 of file mf_navier_stokes.cc.

References fluid_dynamics, Parameters::LinearSolver::gcmg, Parameters::LinearSolver::ilu, Parameters::LinearSolver::lsmg, and Parameters::quiet.

@@ -1032,7 +1032,7 @@

Definition at line 1689 of file mf_navier_stokes.cc.

+

Definition at line 1713 of file mf_navier_stokes.cc.

@@ -1062,7 +1062,7 @@

NavierStokesBase< dim, LinearAlgebra::distributed::Vector< double >, IndexSet >.

-

Definition at line 1978 of file mf_navier_stokes.cc.

+

Definition at line 2012 of file mf_navier_stokes.cc.

References convert_vector_dealii_to_trilinos(), and fluid_dynamics.

@@ -1092,7 +1092,7 @@

Definition at line 2103 of file mf_navier_stokes.cc.

+

Definition at line 2137 of file mf_navier_stokes.cc.

References convert_vector_dealii_to_trilinos(), fluid_dynamics, and number_of_previous_solutions().

diff --git a/doxygen/classNavierStokesBase.html b/doxygen/classNavierStokesBase.html index 1f5c41f981..8ee6e77a20 100644 --- a/doxygen/classNavierStokesBase.html +++ b/doxygen/classNavierStokesBase.html @@ -461,7 +461,7 @@

Definition at line 2069 of file navier_stokes_base.cc.

+

Definition at line 2073 of file navier_stokes_base.cc.

References StasisConstraintWithTemperature::dofs_are_connected_to_fluid, StasisConstraintWithTemperature::dofs_are_in_solid, StasisConstraintWithTemperature::max_solid_temperature, StasisConstraintWithTemperature::min_solid_temperature, and temperature.

@@ -553,7 +553,7 @@

Definition at line 2098 of file navier_stokes_base.cc.

+

Definition at line 2102 of file navier_stokes_base.cc.

References StasisConstraintWithTemperature::dofs_are_connected_to_fluid, and StasisConstraintWithTemperature::dofs_are_in_solid.

@@ -844,7 +844,7 @@

Definition at line 1956 of file navier_stokes_base.cc.

+

Definition at line 1960 of file navier_stokes_base.cc.

References heat_transfer.

@@ -895,7 +895,7 @@

Definition at line 1991 of file navier_stokes_base.cc.

+

Definition at line 1995 of file navier_stokes_base.cc.

References heat_transfer, and VOF.

@@ -999,7 +999,7 @@

Definition at line 1879 of file navier_stokes_base.cc.

+

Definition at line 1883 of file navier_stokes_base.cc.

@@ -1536,7 +1536,7 @@

This function initializes correctly a temporary vector depending on the vector type

-

Definition at line 2723 of file navier_stokes_base.cc.

+

Definition at line 2727 of file navier_stokes_base.cc.

@@ -1602,7 +1602,7 @@

GLSVANSSolver< dim >, and GLSSharpNavierStokesSolver< dim >.

-

Definition at line 2130 of file navier_stokes_base.cc.

+

Definition at line 2134 of file navier_stokes_base.cc.

@@ -1642,7 +1642,7 @@

PhysicsSolver< VectorType >.

-

Definition at line 2630 of file navier_stokes_base.cc.

+

Definition at line 2634 of file navier_stokes_base.cc.

References pressure.

@@ -1744,7 +1744,7 @@

GLSSharpNavierStokesSolver< dim >, and CFDDEMSolver< dim >.

-

Definition at line 1206 of file navier_stokes_base.cc.

+

Definition at line 1210 of file navier_stokes_base.cc.

References announce_string(), calculate_apparent_viscosity(), calculate_enstrophy(), calculate_flow_rate(), calculate_kinetic_energy(), calculate_L2_error(), calculate_pressure_drop(), calculate_pressure_power(), calculate_viscous_dissipation(), Parameters::SimulationControl::steady, and Parameters::verbose.

@@ -1841,7 +1841,7 @@

GLSNitscheNavierStokesSolver< dim, spacedim >, GLSSharpNavierStokesSolver< dim >, and CFDDEMSolver< dim >.

-

Definition at line 1716 of file navier_stokes_base.cc.

+

Definition at line 1720 of file navier_stokes_base.cc.

References Parameters::PostProcessing::apparent_viscosity_output_name, Parameters::PostProcessing::calculate_apparent_viscosity, Parameters::PostProcessing::calculate_enstrophy, Parameters::PostProcessing::calculate_flow_rate, Parameters::PostProcessing::calculate_kinetic_energy, Parameters::PostProcessing::calculate_pressure_drop, Parameters::PostProcessing::calculate_pressure_power, Parameters::PostProcessing::calculate_viscous_dissipation, deserialize_table(), Parameters::PostProcessing::enstrophy_output_name, Parameters::PostProcessing::flow_rate_output_name, Parameters::PostProcessing::kinetic_energy_output_name, Parameters::PostProcessing::pressure_drop_output_name, Parameters::PostProcessing::pressure_power_output_name, and Parameters::PostProcessing::viscous_dissipation_output_name.

@@ -1933,7 +1933,7 @@

Definition at line 1130 of file navier_stokes_base.cc.

+

Definition at line 1132 of file navier_stokes_base.cc.

@@ -1961,7 +1961,7 @@

This function is used to rescale pressure DOFs in the newton correction

-

Definition at line 2582 of file navier_stokes_base.cc.

+

Definition at line 2586 of file navier_stokes_base.cc.

@@ -2078,7 +2078,7 @@

Definition at line 1669 of file navier_stokes_base.cc.

+

Definition at line 1673 of file navier_stokes_base.cc.

References Parameters::SimulationControl::initial_solution, and pressure.

@@ -2207,7 +2207,7 @@

GLSNitscheNavierStokesSolver< dim, spacedim >, GLSSharpNavierStokesSolver< dim >, and CFDDEMSolver< dim >.

-

Definition at line 2470 of file navier_stokes_base.cc.

+

Definition at line 2474 of file navier_stokes_base.cc.

References Parameters::PostProcessing::apparent_viscosity_output_name, Parameters::PostProcessing::calculate_apparent_viscosity, Parameters::PostProcessing::calculate_enstrophy, Parameters::PostProcessing::calculate_flow_rate, Parameters::PostProcessing::calculate_kinetic_energy, Parameters::PostProcessing::calculate_pressure_drop, Parameters::PostProcessing::calculate_pressure_power, Parameters::PostProcessing::calculate_viscous_dissipation, Parameters::PostProcessing::enstrophy_output_name, Parameters::PostProcessing::flow_rate_output_name, Parameters::PostProcessing::kinetic_energy_output_name, Parameters::PostProcessing::pressure_drop_output_name, Parameters::PostProcessing::pressure_power_output_name, serialize_table(), and Parameters::PostProcessing::viscous_dissipation_output_name.

@@ -2237,7 +2237,7 @@

Definition at line 2426 of file navier_stokes_base.cc.

+

Definition at line 2430 of file navier_stokes_base.cc.

@@ -2269,7 +2269,7 @@

Definition at line 2136 of file navier_stokes_base.cc.

+

Definition at line 2140 of file navier_stokes_base.cc.

References PostProcessorSmoothing< dim, VectorType >::calculate_smoothed_field(), PostProcessorSmoothing< dim, VectorType >::get_dof_handler(), and Parameters::VelocitySource::srf.

@@ -2299,7 +2299,7 @@

Definition at line 2448 of file navier_stokes_base.cc.

+

Definition at line 2452 of file navier_stokes_base.cc.

diff --git a/doxygen/classNavierStokesOperatorBase.html b/doxygen/classNavierStokesOperatorBase.html index 5aa2d2af91..71609bbc0f 100644 --- a/doxygen/classNavierStokesOperatorBase.html +++ b/doxygen/classNavierStokesOperatorBase.html @@ -529,7 +529,7 @@

Definition at line 730 of file mf_navier_stokes_operators.cc.

+

Definition at line 751 of file mf_navier_stokes_operators.cc.

References NavierStokesOperatorBase< dim, number >::do_cell_integral_local().

@@ -632,7 +632,7 @@

Definition at line 753 of file mf_navier_stokes_operators.cc.

+

Definition at line 774 of file mf_navier_stokes_operators.cc.

@@ -704,7 +704,7 @@

Definition at line 602 of file mf_navier_stokes_operators.cc.

+

Definition at line 623 of file mf_navier_stokes_operators.cc.

References is_bdf().

@@ -747,7 +747,7 @@

Definition at line 717 of file mf_navier_stokes_operators.cc.

+

Definition at line 738 of file mf_navier_stokes_operators.cc.

References NavierStokesOperatorBase< dim, number >::local_evaluate_residual().

@@ -779,7 +779,7 @@

Definition at line 678 of file mf_navier_stokes_operators.cc.

+

Definition at line 699 of file mf_navier_stokes_operators.cc.

@@ -800,7 +800,7 @@

Returns
Aligned vector with the size of all elements.
-

Definition at line 595 of file mf_navier_stokes_operators.cc.

+

Definition at line 616 of file mf_navier_stokes_operators.cc.

@@ -839,7 +839,7 @@

Returns
Set containing the indices of the refinement edges.
-

Definition at line 775 of file mf_navier_stokes_operators.cc.

+

Definition at line 796 of file mf_navier_stokes_operators.cc.

@@ -860,7 +860,7 @@

Returns
Trilinos sparse matrix.
-

Definition at line 465 of file mf_navier_stokes_operators.cc.

+

Definition at line 467 of file mf_navier_stokes_operators.cc.

@@ -881,7 +881,7 @@

Returns
Matrix free object.
-

Definition at line 588 of file mf_navier_stokes_operators.cc.

+

Definition at line 609 of file mf_navier_stokes_operators.cc.

@@ -1201,7 +1201,7 @@

Definition at line 406 of file mf_navier_stokes_operators.cc.

+

Definition at line 408 of file mf_navier_stokes_operators.cc.

@@ -1231,7 +1231,7 @@

Definition at line 705 of file mf_navier_stokes_operators.cc.

+

Definition at line 726 of file mf_navier_stokes_operators.cc.

@@ -1274,7 +1274,7 @@

Definition at line 368 of file mf_navier_stokes_operators.cc.

-

References NavierStokesOperatorBase< dim, number >::do_cell_integral_range().

+

References NavierStokesOperatorBase< dim, number >::do_cell_integral_range().

@@ -1315,9 +1315,9 @@

Definition at line 414 of file mf_navier_stokes_operators.cc.

+

Definition at line 416 of file mf_navier_stokes_operators.cc.

-

References NavierStokesOperatorBase< dim, number >::do_cell_integral_range().

+

References NavierStokesOperatorBase< dim, number >::do_cell_integral_range().

@@ -1358,9 +1358,9 @@

Definition at line 429 of file mf_navier_stokes_operators.cc.

+

Definition at line 431 of file mf_navier_stokes_operators.cc.

-

References NavierStokesOperatorBase< dim, number >::do_cell_integral_range().

+

References NavierStokesOperatorBase< dim, number >::do_cell_integral_range().

diff --git a/doxygen/classNavierStokesStabilizedOperator.html b/doxygen/classNavierStokesStabilizedOperator.html index 2146b4eb23..a0842cac49 100644 --- a/doxygen/classNavierStokesStabilizedOperator.html +++ b/doxygen/classNavierStokesStabilizedOperator.html @@ -347,7 +347,7 @@

NavierStokesOperatorBase< dim, number >.

-

Definition at line 815 of file mf_navier_stokes_operators.cc.

+

Definition at line 836 of file mf_navier_stokes_operators.cc.

References Parameters::Stabilization::gls, and is_bdf().

@@ -415,7 +415,7 @@

NavierStokesOperatorBase< dim, number >.

-

Definition at line 1032 of file mf_navier_stokes_operators.cc.

+

Definition at line 1053 of file mf_navier_stokes_operators.cc.

References Parameters::Stabilization::gls, and is_bdf().

diff --git a/doxygen/gls__navier__stokes_8cc_source.html b/doxygen/gls__navier__stokes_8cc_source.html index cb8a88d1fe..c51a6e799f 100644 --- a/doxygen/gls__navier__stokes_8cc_source.html +++ b/doxygen/gls__navier__stokes_8cc_source.html @@ -1204,742 +1204,752 @@
1123  Parameters::InitialConditionType initial_condition_type,
1124  bool restart)
1125 {
-
1126  if (this->simulation_parameters.timer.type == Parameters::Timer::Type::end)
-
1127  TimerOutput::Scope t(this->computing_timer, "Set initial conditions");
-
1128 
-
1129  if (restart)
-
1130  {
-
1131  this->pcout << "************************" << std::endl;
-
1132  this->pcout << "---> Simulation Restart " << std::endl;
-
1133  this->pcout << "************************" << std::endl;
-
1134  this->read_checkpoint();
-
1135  }
-
1136  else if (initial_condition_type ==
- -
1138  {
-
1139  assemble_L2_projection();
-
1140  setup_preconditioner();
-
1141 
-
1142  if (this->simulation_parameters.linear_solver
- - -
1145  solve_system_GMRES(true, 1e-15, 1e-15);
-
1146 
-
1147  this->present_solution = this->newton_update;
-
1148  this->finish_time_step();
-
1149  }
-
1150  else if (initial_condition_type == Parameters::InitialConditionType::nodal)
-
1151  {
-
1152  this->set_nodal_values();
-
1153  this->finish_time_step();
-
1154  }
-
1155  else if (initial_condition_type == Parameters::InitialConditionType::viscous)
-
1156  {
-
1157  this->set_nodal_values();
-
1158  std::shared_ptr<RheologicalModel> original_viscosity_model =
-
1159  this->simulation_parameters.physical_properties_manager.get_rheology();
-
1160 
-
1161  // Temporarily set the rheology to be newtonian with predefined viscosity
-
1162  std::shared_ptr<Newtonian> temporary_rheology =
-
1163  std::make_shared<Newtonian>(
-
1164  this->simulation_parameters.initial_condition->kinematic_viscosity);
+
1126  if (restart)
+
1127  {
+
1128  this->pcout << "************************" << std::endl;
+
1129  this->pcout << "---> Simulation Restart " << std::endl;
+
1130  this->pcout << "************************" << std::endl;
+
1131  this->read_checkpoint();
+
1132  }
+
1133  else if (initial_condition_type ==
+ +
1135  {
+
1136  assemble_L2_projection();
+
1137  setup_preconditioner();
+
1138 
+
1139  if (this->simulation_parameters.linear_solver
+ + +
1142  solve_system_GMRES(true, 1e-15, 1e-15);
+
1143 
+
1144  this->present_solution = this->newton_update;
+
1145  this->finish_time_step();
+
1146  }
+
1147  else if (initial_condition_type == Parameters::InitialConditionType::nodal)
+
1148  {
+
1149  this->set_nodal_values();
+
1150  this->finish_time_step();
+
1151  }
+
1152  else if (initial_condition_type == Parameters::InitialConditionType::viscous)
+
1153  {
+
1154  this->set_nodal_values();
+
1155  std::shared_ptr<RheologicalModel> original_viscosity_model =
+
1156  this->simulation_parameters.physical_properties_manager.get_rheology();
+
1157 
+
1158  // Temporarily set the rheology to be newtonian with predefined viscosity
+
1159  std::shared_ptr<Newtonian> temporary_rheology =
+
1160  std::make_shared<Newtonian>(
+
1161  this->simulation_parameters.initial_condition->kinematic_viscosity);
+
1162 
+
1163  this->simulation_parameters.physical_properties_manager.set_rheology(
+
1164  temporary_rheology);
1165 
-
1166  this->simulation_parameters.physical_properties_manager.set_rheology(
-
1167  temporary_rheology);
-
1168 
-
1169 
-
1170  this->simulation_control->set_assembly_method(
- - -
1173  this->finish_time_step();
-
1174 
-
1175  this->simulation_parameters.physical_properties_manager.set_rheology(
-
1176  original_viscosity_model);
-
1177  }
-
1178  else if (initial_condition_type == Parameters::InitialConditionType::ramp)
-
1179  {
-
1180  this->pcout << "*********************************" << std::endl;
-
1181  this->pcout << " Initial condition using ramp " << std::endl;
-
1182  this->pcout << "*********************************" << std::endl;
-
1183 
-
1184  this->set_nodal_values();
-
1185 
-
1186  // Create a pointer to the current viscosity model
-
1187  std::shared_ptr<RheologicalModel> viscosity_model =
-
1188  this->simulation_parameters.physical_properties_manager.get_rheology();
-
1189 
-
1190  // Gather n and viscosity final paramerters
-
1191  const double n_end = viscosity_model->get_n();
-
1192  const double viscosity_end = viscosity_model->get_kinematic_viscosity();
-
1193 
-
1194  // n ramp parameters
-
1195  double n =
-
1196  this->simulation_parameters.initial_condition->ramp.ramp_n.n_init;
-
1197  const int n_iter_n =
-
1198  this->simulation_parameters.initial_condition->ramp.ramp_n.n_iter;
-
1199  const double alpha_n =
-
1200  this->simulation_parameters.initial_condition->ramp.ramp_n.alpha;
-
1201 
-
1202  // Kinematic viscosity ramp parameters
-
1203  const int n_iter_viscosity =
-
1204  this->simulation_parameters.initial_condition->ramp.ramp_viscosity
-
1205  .n_iter;
-
1206  double kinematic_viscosity =
-
1207  n_iter_viscosity > 0 ?
-
1208  this->simulation_parameters.initial_condition->ramp.ramp_viscosity
-
1209  .kinematic_viscosity_init :
-
1210  viscosity_end;
-
1211  const double alpha_viscosity =
-
1212  this->simulation_parameters.initial_condition->ramp.ramp_viscosity
-
1213  .alpha;
-
1214 
-
1215  viscosity_model->set_kinematic_viscosity(kinematic_viscosity);
-
1216 
-
1217  // Ramp on n
-
1218  for (int i = 0; i < n_iter_n; ++i)
-
1219  {
-
1220  this->pcout << std::setprecision(4)
-
1221  << "********* Solution for n = " + std::to_string(n) +
-
1222  " and viscosity = " +
-
1223  std::to_string(kinematic_viscosity) + " *********"
-
1224  << std::endl;
-
1225 
-
1226  viscosity_model->set_n(n);
-
1227 
-
1228  this->simulation_control->set_assembly_method(
- - -
1231  this->finish_time_step();
-
1232 
-
1233  n += alpha_n * (n_end - n);
-
1234  }
-
1235 
-
1236  // Reset n to simulation parameters
-
1237  viscosity_model->set_n(n_end);
-
1238 
-
1239  // Ramp on kinematic viscosity
-
1240  for (int i = 0; i < n_iter_viscosity; ++i)
-
1241  {
-
1242  this->pcout << std::setprecision(4)
-
1243  << "********* Solution for n = " + std::to_string(n_end) +
-
1244  " and viscosity = " +
-
1245  std::to_string(kinematic_viscosity) + " *********"
-
1246  << std::endl;
-
1247 
-
1248  viscosity_model->set_kinematic_viscosity(kinematic_viscosity);
-
1249 
-
1250  this->simulation_control->set_assembly_method(
- - -
1253  this->finish_time_step();
-
1254 
-
1255  kinematic_viscosity +=
-
1256  alpha_viscosity * (viscosity_end - kinematic_viscosity);
-
1257  }
-
1258 
-
1259  // Reset kinematic viscosity to simulation parameters
-
1260  viscosity_model->set_kinematic_viscosity(viscosity_end);
-
1261  }
-
1262  else
-
1263  {
-
1264  throw std::runtime_error("GLSNS - Initial condition could not be set");
-
1265  }
-
1266 }
-
1267 
-
1268 template <int dim>
-
1269 void
- -
1271 {
-
1272  system_matrix = 0;
-
1273  this->system_rhs = 0;
-
1274  FEValues<dim> fe_values(*this->mapping,
-
1275  *this->fe,
-
1276  *this->cell_quadrature,
-
1277  update_values | update_quadrature_points |
-
1278  update_JxW_values);
-
1279  const unsigned int dofs_per_cell = this->fe->dofs_per_cell;
-
1280  const unsigned int n_q_points = this->cell_quadrature->size();
-
1281  FullMatrix<double> local_matrix(dofs_per_cell, dofs_per_cell);
-
1282  Vector<double> local_rhs(dofs_per_cell);
-
1283  std::vector<Vector<double>> initial_velocity(n_q_points,
-
1284  Vector<double>(dim + 1));
-
1285  std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
-
1286  const FEValuesExtractors::Vector velocities(0);
-
1287  const FEValuesExtractors::Scalar pressure(dim);
-
1288 
-
1289  Tensor<1, dim> rhs_initial_velocity_pressure;
-
1290  double rhs_initial_pressure;
-
1291 
-
1292  std::vector<Tensor<1, dim>> phi_u(dofs_per_cell);
-
1293  std::vector<double> phi_p(dofs_per_cell);
-
1294 
-
1295  for (const auto &cell : this->dof_handler.active_cell_iterators())
-
1296  {
-
1297  if (cell->is_locally_owned())
-
1298  {
-
1299  fe_values.reinit(cell);
-
1300  local_matrix = 0;
-
1301  local_rhs = 0;
-
1302  this->simulation_parameters.initial_condition->uvwp.vector_value_list(
-
1303  fe_values.get_quadrature_points(), initial_velocity);
-
1304  for (unsigned int q = 0; q < n_q_points; ++q)
-
1305  {
-
1306  for (unsigned int k = 0; k < dofs_per_cell; ++k)
-
1307  {
-
1308  phi_p[k] = fe_values[pressure].value(k, q);
-
1309  phi_u[k] = fe_values[velocities].value(k, q);
-
1310  }
-
1311 
-
1312  // Establish the rhs tensor operator
-
1313  for (int i = 0; i < dim; ++i)
-
1314  {
-
1315  const unsigned int component_i =
-
1316  this->fe->system_to_component_index(i).first;
-
1317  rhs_initial_velocity_pressure[i] =
-
1318  initial_velocity[q](component_i);
-
1319  }
-
1320  rhs_initial_pressure = initial_velocity[q](dim);
+
1166 
+
1167  this->simulation_control->set_assembly_method(
+ + +
1170  this->finish_time_step();
+
1171 
+
1172  this->simulation_parameters.physical_properties_manager.set_rheology(
+
1173  original_viscosity_model);
+
1174  }
+
1175  else if (initial_condition_type == Parameters::InitialConditionType::ramp)
+
1176  {
+
1177  this->pcout << "*********************************" << std::endl;
+
1178  this->pcout << " Initial condition using ramp " << std::endl;
+
1179  this->pcout << "*********************************" << std::endl;
+
1180 
+
1181  Timer timer(this->mpi_communicator);
+
1182 
+
1183  this->set_nodal_values();
+
1184 
+
1185  // Create a pointer to the current viscosity model
+
1186  std::shared_ptr<RheologicalModel> viscosity_model =
+
1187  this->simulation_parameters.physical_properties_manager.get_rheology();
+
1188 
+
1189  // Gather n and viscosity final paramerters
+
1190  const double n_end = viscosity_model->get_n();
+
1191  const double viscosity_end = viscosity_model->get_kinematic_viscosity();
+
1192 
+
1193  // n ramp parameters
+
1194  double n =
+
1195  this->simulation_parameters.initial_condition->ramp.ramp_n.n_init;
+
1196  const int n_iter_n =
+
1197  this->simulation_parameters.initial_condition->ramp.ramp_n.n_iter;
+
1198  const double alpha_n =
+
1199  this->simulation_parameters.initial_condition->ramp.ramp_n.alpha;
+
1200 
+
1201  // Kinematic viscosity ramp parameters
+
1202  const int n_iter_viscosity =
+
1203  this->simulation_parameters.initial_condition->ramp.ramp_viscosity
+
1204  .n_iter;
+
1205  double kinematic_viscosity =
+
1206  n_iter_viscosity > 0 ?
+
1207  this->simulation_parameters.initial_condition->ramp.ramp_viscosity
+
1208  .kinematic_viscosity_init :
+
1209  viscosity_end;
+
1210  const double alpha_viscosity =
+
1211  this->simulation_parameters.initial_condition->ramp.ramp_viscosity
+
1212  .alpha;
+
1213 
+
1214  viscosity_model->set_kinematic_viscosity(kinematic_viscosity);
+
1215 
+
1216  // Ramp on n
+
1217  for (int i = 0; i < n_iter_n; ++i)
+
1218  {
+
1219  this->pcout << std::setprecision(4)
+
1220  << "********* Solution for n = " + std::to_string(n) +
+
1221  " and viscosity = " +
+
1222  std::to_string(kinematic_viscosity) + " *********"
+
1223  << std::endl;
+
1224 
+
1225  viscosity_model->set_n(n);
+
1226 
+
1227  this->simulation_control->set_assembly_method(
+ + +
1230  this->finish_time_step();
+
1231 
+
1232  n += alpha_n * (n_end - n);
+
1233  }
+
1234 
+
1235  // Reset n to simulation parameters
+
1236  viscosity_model->set_n(n_end);
+
1237 
+
1238  // Ramp on kinematic viscosity
+
1239  for (int i = 0; i < n_iter_viscosity; ++i)
+
1240  {
+
1241  this->pcout << std::setprecision(4)
+
1242  << "********* Solution for n = " + std::to_string(n_end) +
+
1243  " and viscosity = " +
+
1244  std::to_string(kinematic_viscosity) + " *********"
+
1245  << std::endl;
+
1246 
+
1247  viscosity_model->set_kinematic_viscosity(kinematic_viscosity);
+
1248 
+
1249  this->simulation_control->set_assembly_method(
+ + +
1252  this->finish_time_step();
+
1253 
+
1254  kinematic_viscosity +=
+
1255  alpha_viscosity * (viscosity_end - kinematic_viscosity);
+
1256  }
+
1257 
+
1258  // Reset kinematic viscosity to simulation parameters
+
1259  viscosity_model->set_kinematic_viscosity(viscosity_end);
+
1260 
+
1261  timer.stop();
+
1262 
+
1263  if (this->simulation_parameters.timer.type !=
+ +
1265  {
+
1266  this->pcout << "*********************************" << std::endl;
+
1267  this->pcout << " Time spent in ramp: " << timer.wall_time() << "s"
+
1268  << std::endl;
+
1269  this->pcout << "*********************************" << std::endl;
+
1270  }
+
1271  }
+
1272  else
+
1273  {
+
1274  throw std::runtime_error("GLSNS - Initial condition could not be set");
+
1275  }
+
1276 }
+
1277 
+
1278 template <int dim>
+
1279 void
+ +
1281 {
+
1282  system_matrix = 0;
+
1283  this->system_rhs = 0;
+
1284  FEValues<dim> fe_values(*this->mapping,
+
1285  *this->fe,
+
1286  *this->cell_quadrature,
+
1287  update_values | update_quadrature_points |
+
1288  update_JxW_values);
+
1289  const unsigned int dofs_per_cell = this->fe->dofs_per_cell;
+
1290  const unsigned int n_q_points = this->cell_quadrature->size();
+
1291  FullMatrix<double> local_matrix(dofs_per_cell, dofs_per_cell);
+
1292  Vector<double> local_rhs(dofs_per_cell);
+
1293  std::vector<Vector<double>> initial_velocity(n_q_points,
+
1294  Vector<double>(dim + 1));
+
1295  std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
+
1296  const FEValuesExtractors::Vector velocities(0);
+
1297  const FEValuesExtractors::Scalar pressure(dim);
+
1298 
+
1299  Tensor<1, dim> rhs_initial_velocity_pressure;
+
1300  double rhs_initial_pressure;
+
1301 
+
1302  std::vector<Tensor<1, dim>> phi_u(dofs_per_cell);
+
1303  std::vector<double> phi_p(dofs_per_cell);
+
1304 
+
1305  for (const auto &cell : this->dof_handler.active_cell_iterators())
+
1306  {
+
1307  if (cell->is_locally_owned())
+
1308  {
+
1309  fe_values.reinit(cell);
+
1310  local_matrix = 0;
+
1311  local_rhs = 0;
+
1312  this->simulation_parameters.initial_condition->uvwp.vector_value_list(
+
1313  fe_values.get_quadrature_points(), initial_velocity);
+
1314  for (unsigned int q = 0; q < n_q_points; ++q)
+
1315  {
+
1316  for (unsigned int k = 0; k < dofs_per_cell; ++k)
+
1317  {
+
1318  phi_p[k] = fe_values[pressure].value(k, q);
+
1319  phi_u[k] = fe_values[velocities].value(k, q);
+
1320  }
1321 
-
1322  for (unsigned int i = 0; i < dofs_per_cell; ++i)
-
1323  {
-
1324  // Matrix assembly
-
1325  for (unsigned int j = 0; j < dofs_per_cell; ++j)
-
1326  {
-
1327  local_matrix(i, j) +=
-
1328  (phi_u[j] * phi_u[i]) * fe_values.JxW(q);
-
1329  local_matrix(i, j) +=
-
1330  (phi_p[j] * phi_p[i]) * fe_values.JxW(q);
-
1331  }
-
1332  local_rhs(i) += (phi_u[i] * rhs_initial_velocity_pressure +
-
1333  phi_p[i] * rhs_initial_pressure) *
-
1334  fe_values.JxW(q);
-
1335  }
-
1336  }
-
1337 
-
1338  cell->get_dof_indices(local_dof_indices);
-
1339  this->nonzero_constraints.distribute_local_to_global(
-
1340  local_matrix,
-
1341  local_rhs,
-
1342  local_dof_indices,
-
1343  system_matrix,
-
1344  this->system_rhs);
-
1345  }
-
1346  }
-
1347  system_matrix.compress(VectorOperation::add);
-
1348  this->system_rhs.compress(VectorOperation::add);
-
1349 }
-
1350 
-
1351 template <int dim>
-
1352 void
- -
1354  const bool /* renewed_matrix */)
-
1355 {
-
1356  const double absolute_residual =
-
1357  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1358  .minimum_residual;
-
1359  const double relative_residual =
-
1360  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1361  .relative_residual;
-
1362 
-
1363  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
- -
1365  solve_system_GMRES(initial_step, absolute_residual, relative_residual);
-
1366  else if (this->simulation_parameters.linear_solver
- - -
1369  solve_system_BiCGStab(initial_step, absolute_residual, relative_residual);
-
1370  else if (this->simulation_parameters.linear_solver
- - -
1373  solve_system_direct(initial_step, absolute_residual, relative_residual);
-
1374  else
-
1375  AssertThrow(
-
1376  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
- -
1378  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
- -
1380  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
- -
1382  ExcMessage(
-
1383  "This linear solver is not supported. Only <gmres>, <bicgstab> and <direct> linear solvers are supported."));
-
1384 
-
1385  this->rescale_pressure_dofs_in_newton_update();
-
1386 }
-
1387 
-
1388 template <int dim>
-
1389 void
- -
1391 {
-
1392  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
- -
1394  setup_ILU();
-
1395  else if (this->simulation_parameters.linear_solver
- -
1397  .preconditioner ==
- -
1399  setup_AMG();
-
1400  else
-
1401  AssertThrow(
-
1402  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1403  .preconditioner ==
- -
1405  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1406  .preconditioner ==
- -
1408  ExcMessage(
-
1409  "This linear solver does not support this preconditioner. Only <ilu> and <amg> preconditioners are supported."));
-
1410 }
-
1411 
-
1412 
-
1413 template <int dim>
-
1414 void
- -
1416 {
-
1417  TimerOutput::Scope t(this->computing_timer, "Setup ILU");
-
1418 
-
1419  const double ilu_atol =
-
1420  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1421  .ilu_precond_atol;
-
1422  const double ilu_rtol =
-
1423  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1424  .ilu_precond_rtol;
-
1425  TrilinosWrappers::PreconditionILU::AdditionalData preconditionerOptions(
-
1426  current_preconditioner_fill_level, ilu_atol, ilu_rtol, 0);
-
1427 
-
1428  ilu_preconditioner = std::make_shared<TrilinosWrappers::PreconditionILU>();
-
1429 
-
1430  ilu_preconditioner->initialize(system_matrix, preconditionerOptions);
-
1431 }
-
1432 
-
1433 template <int dim>
-
1434 void
- -
1436 {
-
1437  TimerOutput::Scope t(this->computing_timer, "setup_AMG");
-
1438 
-
1439  // Constant modes for velocity
-
1440  std::vector<std::vector<bool>> constant_modes;
-
1441 
-
1442  // Constant modes include pressure since everything is in the same matrix
-
1443  ComponentMask components(dim + 1, true);
-
1444  DoFTools::extract_constant_modes(this->dof_handler,
-
1445  components,
-
1446  constant_modes);
-
1447 
-
1448  const bool elliptic = false;
-
1449  bool higher_order_elements = false;
-
1450  if (this->velocity_fem_degree > 1)
-
1451  higher_order_elements = true;
-
1452  const unsigned int n_cycles =
-
1453  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1454  .amg_n_cycles;
-
1455  const bool w_cycle =
-
1456  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1457  .amg_w_cycles;
-
1458  const double aggregation_threshold =
-
1459  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1460  .amg_aggregation_threshold;
-
1461  const unsigned int smoother_sweeps =
-
1462  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1463  .amg_smoother_sweeps;
-
1464  const unsigned int smoother_overlap =
-
1465  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1466  .amg_smoother_overlap;
-
1467  const bool output_details = false;
-
1468  const char *smoother_type = "ILU";
-
1469  const char *coarse_type = "ILU";
-
1470  TrilinosWrappers::PreconditionAMG::AdditionalData preconditionerOptions(
-
1471  elliptic,
-
1472  higher_order_elements,
-
1473  n_cycles,
-
1474  w_cycle,
-
1475  aggregation_threshold,
-
1476  constant_modes,
-
1477  smoother_sweeps,
-
1478  smoother_overlap,
-
1479  output_details,
-
1480  smoother_type,
-
1481  coarse_type);
-
1482 
-
1483  Teuchos::ParameterList parameter_ml;
-
1484  std::unique_ptr<Epetra_MultiVector> distributed_constant_modes;
-
1485  preconditionerOptions.set_parameters(parameter_ml,
-
1486  distributed_constant_modes,
-
1487  system_matrix);
-
1488  const double ilu_fill = current_preconditioner_fill_level;
-
1489  const double ilu_atol =
-
1490  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1491  .amg_precond_ilu_atol;
-
1492  const double ilu_rtol =
-
1493  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1494  .amg_precond_ilu_rtol;
-
1495  parameter_ml.set("smoother: ifpack level-of-fill", ilu_fill);
-
1496  parameter_ml.set("smoother: ifpack absolute threshold", ilu_atol);
-
1497  parameter_ml.set("smoother: ifpack relative threshold", ilu_rtol);
-
1498 
-
1499  parameter_ml.set("coarse: ifpack level-of-fill", ilu_fill);
-
1500  parameter_ml.set("coarse: ifpack absolute threshold", ilu_atol);
-
1501  parameter_ml.set("coarse: ifpack relative threshold", ilu_rtol);
-
1502  amg_preconditioner = std::make_shared<TrilinosWrappers::PreconditionAMG>();
-
1503  amg_preconditioner->initialize(system_matrix, parameter_ml);
-
1504 }
-
1505 
-
1506 template <int dim>
-
1507 void
- -
1509  const double absolute_residual,
-
1510  const double relative_residual)
-
1511 {
-
1512  const unsigned int max_iter = 3;
-
1513  unsigned int iter = 0;
-
1514  bool success = false;
+
1322  // Establish the rhs tensor operator
+
1323  for (int i = 0; i < dim; ++i)
+
1324  {
+
1325  const unsigned int component_i =
+
1326  this->fe->system_to_component_index(i).first;
+
1327  rhs_initial_velocity_pressure[i] =
+
1328  initial_velocity[q](component_i);
+
1329  }
+
1330  rhs_initial_pressure = initial_velocity[q](dim);
+
1331 
+
1332  for (unsigned int i = 0; i < dofs_per_cell; ++i)
+
1333  {
+
1334  // Matrix assembly
+
1335  for (unsigned int j = 0; j < dofs_per_cell; ++j)
+
1336  {
+
1337  local_matrix(i, j) +=
+
1338  (phi_u[j] * phi_u[i]) * fe_values.JxW(q);
+
1339  local_matrix(i, j) +=
+
1340  (phi_p[j] * phi_p[i]) * fe_values.JxW(q);
+
1341  }
+
1342  local_rhs(i) += (phi_u[i] * rhs_initial_velocity_pressure +
+
1343  phi_p[i] * rhs_initial_pressure) *
+
1344  fe_values.JxW(q);
+
1345  }
+
1346  }
+
1347 
+
1348  cell->get_dof_indices(local_dof_indices);
+
1349  this->nonzero_constraints.distribute_local_to_global(
+
1350  local_matrix,
+
1351  local_rhs,
+
1352  local_dof_indices,
+
1353  system_matrix,
+
1354  this->system_rhs);
+
1355  }
+
1356  }
+
1357  system_matrix.compress(VectorOperation::add);
+
1358  this->system_rhs.compress(VectorOperation::add);
+
1359 }
+
1360 
+
1361 template <int dim>
+
1362 void
+ +
1364  const bool /* renewed_matrix */)
+
1365 {
+
1366  const double absolute_residual =
+
1367  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1368  .minimum_residual;
+
1369  const double relative_residual =
+
1370  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1371  .relative_residual;
+
1372 
+
1373  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+ +
1375  solve_system_GMRES(initial_step, absolute_residual, relative_residual);
+
1376  else if (this->simulation_parameters.linear_solver
+ + +
1379  solve_system_BiCGStab(initial_step, absolute_residual, relative_residual);
+
1380  else if (this->simulation_parameters.linear_solver
+ + +
1383  solve_system_direct(initial_step, absolute_residual, relative_residual);
+
1384  else
+
1385  AssertThrow(
+
1386  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+ +
1388  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+ +
1390  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+ +
1392  ExcMessage(
+
1393  "This linear solver is not supported. Only <gmres>, <bicgstab> and <direct> linear solvers are supported."));
+
1394 
+
1395  this->rescale_pressure_dofs_in_newton_update();
+
1396 }
+
1397 
+
1398 template <int dim>
+
1399 void
+ +
1401 {
+
1402  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+ +
1404  setup_ILU();
+
1405  else if (this->simulation_parameters.linear_solver
+ +
1407  .preconditioner ==
+ +
1409  setup_AMG();
+
1410  else
+
1411  AssertThrow(
+
1412  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1413  .preconditioner ==
+ +
1415  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1416  .preconditioner ==
+ +
1418  ExcMessage(
+
1419  "This linear solver does not support this preconditioner. Only <ilu> and <amg> preconditioners are supported."));
+
1420 }
+
1421 
+
1422 
+
1423 template <int dim>
+
1424 void
+ +
1426 {
+
1427  TimerOutput::Scope t(this->computing_timer, "Setup ILU");
+
1428 
+
1429  const double ilu_atol =
+
1430  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1431  .ilu_precond_atol;
+
1432  const double ilu_rtol =
+
1433  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1434  .ilu_precond_rtol;
+
1435  TrilinosWrappers::PreconditionILU::AdditionalData preconditionerOptions(
+
1436  current_preconditioner_fill_level, ilu_atol, ilu_rtol, 0);
+
1437 
+
1438  ilu_preconditioner = std::make_shared<TrilinosWrappers::PreconditionILU>();
+
1439 
+
1440  ilu_preconditioner->initialize(system_matrix, preconditionerOptions);
+
1441 }
+
1442 
+
1443 template <int dim>
+
1444 void
+ +
1446 {
+
1447  TimerOutput::Scope t(this->computing_timer, "setup_AMG");
+
1448 
+
1449  // Constant modes for velocity
+
1450  std::vector<std::vector<bool>> constant_modes;
+
1451 
+
1452  // Constant modes include pressure since everything is in the same matrix
+
1453  ComponentMask components(dim + 1, true);
+
1454  DoFTools::extract_constant_modes(this->dof_handler,
+
1455  components,
+
1456  constant_modes);
+
1457 
+
1458  const bool elliptic = false;
+
1459  bool higher_order_elements = false;
+
1460  if (this->velocity_fem_degree > 1)
+
1461  higher_order_elements = true;
+
1462  const unsigned int n_cycles =
+
1463  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1464  .amg_n_cycles;
+
1465  const bool w_cycle =
+
1466  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1467  .amg_w_cycles;
+
1468  const double aggregation_threshold =
+
1469  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1470  .amg_aggregation_threshold;
+
1471  const unsigned int smoother_sweeps =
+
1472  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1473  .amg_smoother_sweeps;
+
1474  const unsigned int smoother_overlap =
+
1475  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1476  .amg_smoother_overlap;
+
1477  const bool output_details = false;
+
1478  const char *smoother_type = "ILU";
+
1479  const char *coarse_type = "ILU";
+
1480  TrilinosWrappers::PreconditionAMG::AdditionalData preconditionerOptions(
+
1481  elliptic,
+
1482  higher_order_elements,
+
1483  n_cycles,
+
1484  w_cycle,
+
1485  aggregation_threshold,
+
1486  constant_modes,
+
1487  smoother_sweeps,
+
1488  smoother_overlap,
+
1489  output_details,
+
1490  smoother_type,
+
1491  coarse_type);
+
1492 
+
1493  Teuchos::ParameterList parameter_ml;
+
1494  std::unique_ptr<Epetra_MultiVector> distributed_constant_modes;
+
1495  preconditionerOptions.set_parameters(parameter_ml,
+
1496  distributed_constant_modes,
+
1497  system_matrix);
+
1498  const double ilu_fill = current_preconditioner_fill_level;
+
1499  const double ilu_atol =
+
1500  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1501  .amg_precond_ilu_atol;
+
1502  const double ilu_rtol =
+
1503  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1504  .amg_precond_ilu_rtol;
+
1505  parameter_ml.set("smoother: ifpack level-of-fill", ilu_fill);
+
1506  parameter_ml.set("smoother: ifpack absolute threshold", ilu_atol);
+
1507  parameter_ml.set("smoother: ifpack relative threshold", ilu_rtol);
+
1508 
+
1509  parameter_ml.set("coarse: ifpack level-of-fill", ilu_fill);
+
1510  parameter_ml.set("coarse: ifpack absolute threshold", ilu_atol);
+
1511  parameter_ml.set("coarse: ifpack relative threshold", ilu_rtol);
+
1512  amg_preconditioner = std::make_shared<TrilinosWrappers::PreconditionAMG>();
+
1513  amg_preconditioner->initialize(system_matrix, parameter_ml);
+
1514 }
1515 
-
1516 
-
1517  auto &system_rhs = this->system_rhs;
-
1518  auto &nonzero_constraints = this->nonzero_constraints;
-
1519 
-
1520  const AffineConstraints<double> &zero_constraints_used =
-
1521  (!this->simulation_parameters.constrain_solid_domain.enable) ?
-
1522  this->zero_constraints :
-
1523  this->dynamic_zero_constraints;
-
1524 
-
1525  const AffineConstraints<double> &constraints_used =
-
1526  initial_step ? nonzero_constraints : zero_constraints_used;
-
1527 
-
1528  const double linear_solver_tolerance =
-
1529  std::max(relative_residual * system_rhs.l2_norm(), absolute_residual);
-
1530 
-
1531  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1532  .verbosity != Parameters::Verbosity::quiet)
-
1533  {
-
1534  this->pcout << " -Tolerance of iterative solver is : "
-
1535  << linear_solver_tolerance << std::endl;
-
1536  }
-
1537  GlobalVectorType completely_distributed_solution(this->locally_owned_dofs,
-
1538  this->mpi_communicator);
-
1539 
-
1540  SolverControl solver_control(this->simulation_parameters.linear_solver
- -
1542  .max_iterations,
-
1543  linear_solver_tolerance,
-
1544  true,
-
1545  true);
-
1546  bool extra_verbose = false;
-
1547  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
- -
1549  extra_verbose = true;
-
1550 
-
1551  TrilinosWrappers::SolverGMRES::AdditionalData solver_parameters(
-
1552  extra_verbose,
-
1553  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1554  .max_krylov_vectors);
-
1555 
-
1556  // The solver starts from the initial fill level for the ILU(n) or the ILU
-
1557  // smoother provided in the parameter file. If for any reason the linear
-
1558  // solver crashes, it will restart with a fill level increased by 1. This
-
1559  // restart happens up to a maximum of 20 times, after which it will let the
-
1560  // solver crash. If a change happened on the fill level, it will go back
-
1561  // to its original value at the end of the restart process.
-
1562  while (success == false and iter < max_iter)
-
1563  {
-
1564  try
-
1565  {
-
1566  if (!ilu_preconditioner && !amg_preconditioner)
-
1567  setup_preconditioner();
-
1568 
-
1569  TrilinosWrappers::SolverGMRES solver(solver_control,
-
1570  solver_parameters);
-
1571 
-
1572  {
-
1573  TimerOutput::Scope t(this->computing_timer, "Solve linear system");
-
1574 
-
1575  if (this->simulation_parameters.linear_solver
- -
1577  .preconditioner ==
- -
1579  solver.solve(system_matrix,
-
1580  completely_distributed_solution,
-
1581  system_rhs,
-
1582  *ilu_preconditioner);
-
1583  else if (this->simulation_parameters.linear_solver
- -
1585  .preconditioner ==
- -
1587  solver.solve(system_matrix,
-
1588  completely_distributed_solution,
-
1589  system_rhs,
-
1590  *amg_preconditioner);
-
1591  else
-
1592  AssertThrow(
-
1593  this->simulation_parameters.linear_solver
- -
1595  .preconditioner ==
- -
1597  this->simulation_parameters.linear_solver
- -
1599  .preconditioner ==
- -
1601  ExcMessage(
-
1602  "This linear solver does not support this preconditioner. Only <ilu> and <amg> preconditioners are supported."));
-
1603 
-
1604  if (this->simulation_parameters.linear_solver
- -
1606  .verbosity != Parameters::Verbosity::quiet)
-
1607  {
-
1608  this->pcout
-
1609  << " -Iterative solver took : " << solver_control.last_step()
-
1610  << " steps to reach a residual norm of "
-
1611  << solver_control.last_value() << std::endl;
-
1612  }
-
1613  }
-
1614 
-
1615  this->computing_timer.enter_subsection(
-
1616  "Distribute constraints after linear solve");
-
1617 
-
1618  constraints_used.distribute(completely_distributed_solution);
-
1619 
-
1620  this->computing_timer.leave_subsection(
-
1621  "Distribute constraints after linear solve");
-
1622 
-
1623  auto &newton_update = this->newton_update;
-
1624  newton_update = completely_distributed_solution;
-
1625  success = true;
-
1626  }
-
1627  catch (std::exception &e)
-
1628  {
-
1629  current_preconditioner_fill_level += 1;
-
1630  this->pcout
-
1631  << " GMRES solver failed! Trying with a higher preconditioner fill level. New fill = "
-
1632  << current_preconditioner_fill_level << std::endl;
-
1633  setup_preconditioner();
-
1634 
-
1635  if (iter == max_iter - 1 && !this->simulation_parameters.linear_solver
- -
1637  .force_linear_solver_continuation)
-
1638  throw e;
-
1639  }
-
1640  iter += 1;
-
1641  }
-
1642  current_preconditioner_fill_level = initial_preconditioner_fill_level;
-
1643 }
+
1516 template <int dim>
+
1517 void
+ +
1519  const double absolute_residual,
+
1520  const double relative_residual)
+
1521 {
+
1522  const unsigned int max_iter = 3;
+
1523  unsigned int iter = 0;
+
1524  bool success = false;
+
1525 
+
1526 
+
1527  auto &system_rhs = this->system_rhs;
+
1528  auto &nonzero_constraints = this->nonzero_constraints;
+
1529 
+
1530  const AffineConstraints<double> &zero_constraints_used =
+
1531  (!this->simulation_parameters.constrain_solid_domain.enable) ?
+
1532  this->zero_constraints :
+
1533  this->dynamic_zero_constraints;
+
1534 
+
1535  const AffineConstraints<double> &constraints_used =
+
1536  initial_step ? nonzero_constraints : zero_constraints_used;
+
1537 
+
1538  const double linear_solver_tolerance =
+
1539  std::max(relative_residual * system_rhs.l2_norm(), absolute_residual);
+
1540 
+
1541  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1542  .verbosity != Parameters::Verbosity::quiet)
+
1543  {
+
1544  this->pcout << " -Tolerance of iterative solver is : "
+
1545  << linear_solver_tolerance << std::endl;
+
1546  }
+
1547  GlobalVectorType completely_distributed_solution(this->locally_owned_dofs,
+
1548  this->mpi_communicator);
+
1549 
+
1550  SolverControl solver_control(this->simulation_parameters.linear_solver
+ +
1552  .max_iterations,
+
1553  linear_solver_tolerance,
+
1554  true,
+
1555  true);
+
1556  bool extra_verbose = false;
+
1557  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+ +
1559  extra_verbose = true;
+
1560 
+
1561  TrilinosWrappers::SolverGMRES::AdditionalData solver_parameters(
+
1562  extra_verbose,
+
1563  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1564  .max_krylov_vectors);
+
1565 
+
1566  // The solver starts from the initial fill level for the ILU(n) or the ILU
+
1567  // smoother provided in the parameter file. If for any reason the linear
+
1568  // solver crashes, it will restart with a fill level increased by 1. This
+
1569  // restart happens up to a maximum of 20 times, after which it will let the
+
1570  // solver crash. If a change happened on the fill level, it will go back
+
1571  // to its original value at the end of the restart process.
+
1572  while (success == false and iter < max_iter)
+
1573  {
+
1574  try
+
1575  {
+
1576  if (!ilu_preconditioner && !amg_preconditioner)
+
1577  setup_preconditioner();
+
1578 
+
1579  TrilinosWrappers::SolverGMRES solver(solver_control,
+
1580  solver_parameters);
+
1581 
+
1582  {
+
1583  TimerOutput::Scope t(this->computing_timer, "Solve linear system");
+
1584 
+
1585  if (this->simulation_parameters.linear_solver
+ +
1587  .preconditioner ==
+ +
1589  solver.solve(system_matrix,
+
1590  completely_distributed_solution,
+
1591  system_rhs,
+
1592  *ilu_preconditioner);
+
1593  else if (this->simulation_parameters.linear_solver
+ +
1595  .preconditioner ==
+ +
1597  solver.solve(system_matrix,
+
1598  completely_distributed_solution,
+
1599  system_rhs,
+
1600  *amg_preconditioner);
+
1601  else
+
1602  AssertThrow(
+
1603  this->simulation_parameters.linear_solver
+ +
1605  .preconditioner ==
+ +
1607  this->simulation_parameters.linear_solver
+ +
1609  .preconditioner ==
+ +
1611  ExcMessage(
+
1612  "This linear solver does not support this preconditioner. Only <ilu> and <amg> preconditioners are supported."));
+
1613 
+
1614  if (this->simulation_parameters.linear_solver
+ +
1616  .verbosity != Parameters::Verbosity::quiet)
+
1617  {
+
1618  this->pcout
+
1619  << " -Iterative solver took : " << solver_control.last_step()
+
1620  << " steps to reach a residual norm of "
+
1621  << solver_control.last_value() << std::endl;
+
1622  }
+
1623  }
+
1624 
+
1625  this->computing_timer.enter_subsection(
+
1626  "Distribute constraints after linear solve");
+
1627 
+
1628  constraints_used.distribute(completely_distributed_solution);
+
1629 
+
1630  this->computing_timer.leave_subsection(
+
1631  "Distribute constraints after linear solve");
+
1632 
+
1633  auto &newton_update = this->newton_update;
+
1634  newton_update = completely_distributed_solution;
+
1635  success = true;
+
1636  }
+
1637  catch (std::exception &e)
+
1638  {
+
1639  current_preconditioner_fill_level += 1;
+
1640  this->pcout
+
1641  << " GMRES solver failed! Trying with a higher preconditioner fill level. New fill = "
+
1642  << current_preconditioner_fill_level << std::endl;
+
1643  setup_preconditioner();
1644 
-
1645 // The solver starts from the initial fill level provided in the parameter file.
-
1646 // If for any reason the linear solver crashes, it will restart with a fill
-
1647 // level increased by 1. This restart happens up to a maximum of 20 times, after
-
1648 // which it will let the solver crash. If a change happened on the fill level,
-
1649 // it will go back to its original value at the end of the restart process.
-
1650 template <int dim>
-
1651 void
- -
1653  const bool initial_step,
-
1654  const double absolute_residual,
-
1655  const double relative_residual)
-
1656 {
-
1657  TimerOutput::Scope t(this->computing_timer, "solve");
-
1658  const unsigned int max_iter = 3;
-
1659  unsigned int iter = 0;
-
1660  bool success = false;
-
1661 
-
1662 
-
1663  auto &system_rhs = this->system_rhs;
-
1664  auto &nonzero_constraints = this->nonzero_constraints;
-
1665 
-
1666  const AffineConstraints<double> &zero_constraints_used =
-
1667  (!this->simulation_parameters.constrain_solid_domain.enable) ?
-
1668  this->zero_constraints :
-
1669  this->dynamic_zero_constraints;
-
1670 
-
1671  const AffineConstraints<double> &constraints_used =
-
1672  initial_step ? nonzero_constraints : zero_constraints_used;
-
1673  const double linear_solver_tolerance =
-
1674  std::max(relative_residual * system_rhs.l2_norm(), absolute_residual);
-
1675  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1676  .verbosity != Parameters::Verbosity::quiet)
-
1677  {
-
1678  this->pcout << " -Tolerance of iterative solver is : "
-
1679  << linear_solver_tolerance << std::endl;
-
1680  }
-
1681  GlobalVectorType completely_distributed_solution(this->locally_owned_dofs,
-
1682  this->mpi_communicator);
-
1683 
-
1684  bool extra_verbose = false;
+
1645  if (iter == max_iter - 1 && !this->simulation_parameters.linear_solver
+ +
1647  .force_linear_solver_continuation)
+
1648  throw e;
+
1649  }
+
1650  iter += 1;
+
1651  }
+
1652  current_preconditioner_fill_level = initial_preconditioner_fill_level;
+
1653 }
+
1654 
+
1655 // The solver starts from the initial fill level provided in the parameter file.
+
1656 // If for any reason the linear solver crashes, it will restart with a fill
+
1657 // level increased by 1. This restart happens up to a maximum of 20 times, after
+
1658 // which it will let the solver crash. If a change happened on the fill level,
+
1659 // it will go back to its original value at the end of the restart process.
+
1660 template <int dim>
+
1661 void
+ +
1663  const bool initial_step,
+
1664  const double absolute_residual,
+
1665  const double relative_residual)
+
1666 {
+
1667  TimerOutput::Scope t(this->computing_timer, "solve");
+
1668  const unsigned int max_iter = 3;
+
1669  unsigned int iter = 0;
+
1670  bool success = false;
+
1671 
+
1672 
+
1673  auto &system_rhs = this->system_rhs;
+
1674  auto &nonzero_constraints = this->nonzero_constraints;
+
1675 
+
1676  const AffineConstraints<double> &zero_constraints_used =
+
1677  (!this->simulation_parameters.constrain_solid_domain.enable) ?
+
1678  this->zero_constraints :
+
1679  this->dynamic_zero_constraints;
+
1680 
+
1681  const AffineConstraints<double> &constraints_used =
+
1682  initial_step ? nonzero_constraints : zero_constraints_used;
+
1683  const double linear_solver_tolerance =
+
1684  std::max(relative_residual * system_rhs.l2_norm(), absolute_residual);
1685  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
- -
1687  extra_verbose = true;
-
1688  TrilinosWrappers::SolverBicgstab::AdditionalData solver_parameters(
-
1689  extra_verbose);
-
1690 
-
1691  SolverControl solver_control(this->simulation_parameters.linear_solver
- -
1693  .max_iterations,
-
1694  linear_solver_tolerance,
-
1695  true,
-
1696  true);
-
1697  TrilinosWrappers::SolverBicgstab solver(solver_control, solver_parameters);
-
1698  while (success == false and iter < max_iter)
-
1699  {
-
1700  try
-
1701  {
-
1702  if (!ilu_preconditioner)
-
1703  setup_preconditioner();
-
1704 
-
1705  {
-
1706  TimerOutput::Scope t(this->computing_timer, "Solve linear system");
-
1707 
-
1708  if (this->simulation_parameters.linear_solver
- -
1710  .preconditioner ==
- -
1712  solver.solve(system_matrix,
-
1713  completely_distributed_solution,
-
1714  system_rhs,
-
1715  *ilu_preconditioner);
-
1716  else
-
1717  AssertThrow(
-
1718  this->simulation_parameters.linear_solver
- -
1720  .preconditioner ==
- -
1722  ExcMessage(
-
1723  "This linear solver does not support this preconditioner. Only <ilu> preconditioner is supported."));
-
1724 
-
1725  if (this->simulation_parameters.linear_solver
- -
1727  .verbosity != Parameters::Verbosity::quiet)
-
1728  {
-
1729  this->pcout
-
1730  << " -Iterative solver took : " << solver_control.last_step()
-
1731  << " steps to reach a residual norm of "
-
1732  << solver_control.last_value() << std::endl;
-
1733  }
-
1734  constraints_used.distribute(completely_distributed_solution);
-
1735  this->newton_update = completely_distributed_solution;
-
1736  }
-
1737  success = true;
-
1738  }
-
1739  catch (std::exception &e)
-
1740  {
-
1741  current_preconditioner_fill_level += 1;
-
1742  this->pcout
-
1743  << " BiCGStab solver failed! Trying with a higher preconditioner fill level. New fill = "
-
1744  << current_preconditioner_fill_level << std::endl;
-
1745  setup_preconditioner();
-
1746 
-
1747  if (iter == max_iter - 1 && !this->simulation_parameters.linear_solver
- -
1749  .force_linear_solver_continuation)
-
1750  throw e;
-
1751  }
-
1752  iter += 1;
-
1753  }
-
1754  current_preconditioner_fill_level = initial_preconditioner_fill_level;
-
1755 }
+
1686  .verbosity != Parameters::Verbosity::quiet)
+
1687  {
+
1688  this->pcout << " -Tolerance of iterative solver is : "
+
1689  << linear_solver_tolerance << std::endl;
+
1690  }
+
1691  GlobalVectorType completely_distributed_solution(this->locally_owned_dofs,
+
1692  this->mpi_communicator);
+
1693 
+
1694  bool extra_verbose = false;
+
1695  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+ +
1697  extra_verbose = true;
+
1698  TrilinosWrappers::SolverBicgstab::AdditionalData solver_parameters(
+
1699  extra_verbose);
+
1700 
+
1701  SolverControl solver_control(this->simulation_parameters.linear_solver
+ +
1703  .max_iterations,
+
1704  linear_solver_tolerance,
+
1705  true,
+
1706  true);
+
1707  TrilinosWrappers::SolverBicgstab solver(solver_control, solver_parameters);
+
1708  while (success == false and iter < max_iter)
+
1709  {
+
1710  try
+
1711  {
+
1712  if (!ilu_preconditioner)
+
1713  setup_preconditioner();
+
1714 
+
1715  {
+
1716  TimerOutput::Scope t(this->computing_timer, "Solve linear system");
+
1717 
+
1718  if (this->simulation_parameters.linear_solver
+ +
1720  .preconditioner ==
+ +
1722  solver.solve(system_matrix,
+
1723  completely_distributed_solution,
+
1724  system_rhs,
+
1725  *ilu_preconditioner);
+
1726  else
+
1727  AssertThrow(
+
1728  this->simulation_parameters.linear_solver
+ +
1730  .preconditioner ==
+ +
1732  ExcMessage(
+
1733  "This linear solver does not support this preconditioner. Only <ilu> preconditioner is supported."));
+
1734 
+
1735  if (this->simulation_parameters.linear_solver
+ +
1737  .verbosity != Parameters::Verbosity::quiet)
+
1738  {
+
1739  this->pcout
+
1740  << " -Iterative solver took : " << solver_control.last_step()
+
1741  << " steps to reach a residual norm of "
+
1742  << solver_control.last_value() << std::endl;
+
1743  }
+
1744  constraints_used.distribute(completely_distributed_solution);
+
1745  this->newton_update = completely_distributed_solution;
+
1746  }
+
1747  success = true;
+
1748  }
+
1749  catch (std::exception &e)
+
1750  {
+
1751  current_preconditioner_fill_level += 1;
+
1752  this->pcout
+
1753  << " BiCGStab solver failed! Trying with a higher preconditioner fill level. New fill = "
+
1754  << current_preconditioner_fill_level << std::endl;
+
1755  setup_preconditioner();
1756 
-
1757 template <int dim>
-
1758 void
- -
1760  const double absolute_residual,
-
1761  const double relative_residual)
-
1762 {
-
1763  auto &system_rhs = this->system_rhs;
-
1764  auto &nonzero_constraints = this->nonzero_constraints;
-
1765 
-
1766  const AffineConstraints<double> &zero_constraints_used =
-
1767  (!this->simulation_parameters.constrain_solid_domain.enable) ?
-
1768  this->zero_constraints :
-
1769  this->dynamic_zero_constraints;
-
1770 
-
1771  const AffineConstraints<double> &constraints_used =
-
1772  initial_step ? nonzero_constraints : zero_constraints_used;
-
1773  const double linear_solver_tolerance =
-
1774  std::max(relative_residual * system_rhs.l2_norm(), absolute_residual);
+
1757  if (iter == max_iter - 1 && !this->simulation_parameters.linear_solver
+ +
1759  .force_linear_solver_continuation)
+
1760  throw e;
+
1761  }
+
1762  iter += 1;
+
1763  }
+
1764  current_preconditioner_fill_level = initial_preconditioner_fill_level;
+
1765 }
+
1766 
+
1767 template <int dim>
+
1768 void
+ +
1770  const double absolute_residual,
+
1771  const double relative_residual)
+
1772 {
+
1773  auto &system_rhs = this->system_rhs;
+
1774  auto &nonzero_constraints = this->nonzero_constraints;
1775 
-
1776  GlobalVectorType completely_distributed_solution(this->locally_owned_dofs,
-
1777  this->mpi_communicator);
-
1778 
-
1779  SolverControl solver_control(this->simulation_parameters.linear_solver
- -
1781  .max_iterations,
-
1782  linear_solver_tolerance,
-
1783  true,
-
1784  true);
-
1785  TrilinosWrappers::SolverDirect solver(solver_control);
-
1786 
-
1787  solver.initialize(system_matrix);
-
1788  solver.solve(completely_distributed_solution, system_rhs);
-
1789  constraints_used.distribute(completely_distributed_solution);
-
1790  auto &newton_update = this->newton_update;
-
1791  newton_update = completely_distributed_solution;
-
1792 }
-
1793 
-
1794 template <int dim>
-
1795 void
- -
1797 {
-
1798  this->computing_timer.enter_subsection("Read mesh and manifolds");
-
1799 
- -
1801  *this->triangulation,
-
1802  this->simulation_parameters.mesh,
-
1803  this->simulation_parameters.manifolds_parameters,
-
1804  this->simulation_parameters.restart_parameters.restart,
-
1805  this->simulation_parameters.boundary_conditions);
-
1806 
-
1807  this->computing_timer.leave_subsection("Read mesh and manifolds");
-
1808 
-
1809  this->setup_dofs();
-
1810  this->enable_dynamic_zero_constraints_fd();
-
1811  this->box_refine_mesh(this->simulation_parameters.restart_parameters.restart);
-
1812  this->set_initial_condition(
-
1813  this->simulation_parameters.initial_condition->type,
-
1814  this->simulation_parameters.restart_parameters.restart);
-
1815  this->update_multiphysics_time_average_solution();
+
1776  const AffineConstraints<double> &zero_constraints_used =
+
1777  (!this->simulation_parameters.constrain_solid_domain.enable) ?
+
1778  this->zero_constraints :
+
1779  this->dynamic_zero_constraints;
+
1780 
+
1781  const AffineConstraints<double> &constraints_used =
+
1782  initial_step ? nonzero_constraints : zero_constraints_used;
+
1783  const double linear_solver_tolerance =
+
1784  std::max(relative_residual * system_rhs.l2_norm(), absolute_residual);
+
1785 
+
1786  GlobalVectorType completely_distributed_solution(this->locally_owned_dofs,
+
1787  this->mpi_communicator);
+
1788 
+
1789  SolverControl solver_control(this->simulation_parameters.linear_solver
+ +
1791  .max_iterations,
+
1792  linear_solver_tolerance,
+
1793  true,
+
1794  true);
+
1795  TrilinosWrappers::SolverDirect solver(solver_control);
+
1796 
+
1797  solver.initialize(system_matrix);
+
1798  solver.solve(completely_distributed_solution, system_rhs);
+
1799  constraints_used.distribute(completely_distributed_solution);
+
1800  auto &newton_update = this->newton_update;
+
1801  newton_update = completely_distributed_solution;
+
1802 }
+
1803 
+
1804 template <int dim>
+
1805 void
+ +
1807 {
+
1808  this->computing_timer.enter_subsection("Read mesh and manifolds");
+
1809 
+ +
1811  *this->triangulation,
+
1812  this->simulation_parameters.mesh,
+
1813  this->simulation_parameters.manifolds_parameters,
+
1814  this->simulation_parameters.restart_parameters.restart,
+
1815  this->simulation_parameters.boundary_conditions);
1816 
-
1817  while (this->simulation_control->integrate())
-
1818  {
-
1819  this->forcing_function->set_time(
-
1820  this->simulation_control->get_current_time());
-
1821 
-
1822  bool refinement_step;
-
1823  if (this->simulation_parameters.mesh_adaptation.refinement_at_frequency)
-
1824  refinement_step =
-
1825  this->simulation_control->get_step_number() %
-
1826  this->simulation_parameters.mesh_adaptation.frequency !=
-
1827  0;
-
1828  else
-
1829  refinement_step = this->simulation_control->get_step_number() == 0;
-
1830  if (refinement_step ||
-
1831  this->simulation_parameters.mesh_adaptation.type ==
- -
1833  this->simulation_control->is_at_start())
-
1834  {
-
1835  // We allow the physics to update their boundary conditions
-
1836  // according to their own parameters
-
1837  this->update_boundary_conditions();
-
1838  this->multiphysics->update_boundary_conditions();
-
1839  }
-
1840 
-
1841  this->simulation_control->print_progression(this->pcout);
-
1842  this->dynamic_flow_control();
-
1843 
-
1844  if (!this->simulation_control->is_at_start())
- -
1846 
-
1847  this->define_dynamic_zero_constraints();
-
1848  this->iterate();
-
1849  this->postprocess(false);
-
1850  this->finish_time_step();
-
1851  }
-
1852 
+
1817  this->computing_timer.leave_subsection("Read mesh and manifolds");
+
1818 
+
1819  this->setup_dofs();
+
1820  this->enable_dynamic_zero_constraints_fd();
+
1821  this->box_refine_mesh(this->simulation_parameters.restart_parameters.restart);
+
1822  this->set_initial_condition(
+
1823  this->simulation_parameters.initial_condition->type,
+
1824  this->simulation_parameters.restart_parameters.restart);
+
1825  this->update_multiphysics_time_average_solution();
+
1826 
+
1827  while (this->simulation_control->integrate())
+
1828  {
+
1829  this->forcing_function->set_time(
+
1830  this->simulation_control->get_current_time());
+
1831 
+
1832  bool refinement_step;
+
1833  if (this->simulation_parameters.mesh_adaptation.refinement_at_frequency)
+
1834  refinement_step =
+
1835  this->simulation_control->get_step_number() %
+
1836  this->simulation_parameters.mesh_adaptation.frequency !=
+
1837  0;
+
1838  else
+
1839  refinement_step = this->simulation_control->get_step_number() == 0;
+
1840  if (refinement_step ||
+
1841  this->simulation_parameters.mesh_adaptation.type ==
+ +
1843  this->simulation_control->is_at_start())
+
1844  {
+
1845  // We allow the physics to update their boundary conditions
+
1846  // according to their own parameters
+
1847  this->update_boundary_conditions();
+
1848  this->multiphysics->update_boundary_conditions();
+
1849  }
+
1850 
+
1851  this->simulation_control->print_progression(this->pcout);
+
1852  this->dynamic_flow_control();
1853 
-
1854  this->finish_simulation();
-
1855 }
+
1854  if (!this->simulation_control->is_at_start())
+
1856 
-
1857 
-
1858 // Pre-compile the 2D and 3D Navier-Stokes solver to ensure that the library is
-
1859 // valid before we actually compile the solver This greatly helps with debugging
-
1860 template class GLSNavierStokesSolver<2>;
-
1861 template class GLSNavierStokesSolver<3>;
+
1857  this->define_dynamic_zero_constraints();
+
1858  this->iterate();
+
1859  this->postprocess(false);
+
1860  this->finish_time_step();
+
1861  }
+
1862 
+
1863 
+
1864  this->finish_simulation();
+
1865 }
+
1866 
+
1867 
+
1868 // Pre-compile the 2D and 3D Navier-Stokes solver to ensure that the library is
+
1869 // valid before we actually compile the solver This greatly helps with debugging
+
1870 template class GLSNavierStokesSolver<2>;
+
1871 template class GLSNavierStokesSolver<3>;
Class that assembles the transient time arising from BDF time integration for the isothermal compress...
Class that assembles the core of the isothermal compressible Navier-Stokes equations....
@@ -1955,28 +1965,28 @@
virtual void setup_dofs_fd() override
setup_dofs_fd Setup the degree of freedom, system matrix and solution vectors Navier-Stokes problem
virtual void copy_local_rhs_to_global_rhs(const StabilizedMethodsTensorCopyData< dim > &copy_data)
Copy local cell rhs information to global rhs.
-
void assemble_L2_projection()
Assembles an L2_projection matrix for the velocity and the pressure. This L2 projection matrix can be...
+
void assemble_L2_projection()
Assembles an L2_projection matrix for the velocity and the pressure. This L2 projection matrix can be...
void update_boundary_conditions()
update non zero constraint if the boundary is time-dependent
-
void solve_system_GMRES(const bool initial_step, const double absolute_residual, const double relative_residual)
GMRES solver with ILU(N) preconditioning or AMG preconditioning.
+
void solve_system_GMRES(const bool initial_step, const double absolute_residual, const double relative_residual)
GMRES solver with ILU(N) preconditioning or AMG preconditioning.
virtual void assemble_system_rhs() override
Assemble the rhs associated with the solver.
-
void solve_linear_system(const bool initial_step, const bool renewed_matrix=true) override
Call for the assembly of the linear system of equation.
+
void solve_linear_system(const bool initial_step, const bool renewed_matrix=true) override
Call for the assembly of the linear system of equation.
void define_dynamic_zero_constraints()
Define the zero constraints used to solved the problem that change with other physics' solutions.
virtual void copy_local_matrix_to_global_matrix(const StabilizedMethodsTensorCopyData< dim > &copy_data)
Copy local cell information to global matrix.
-
void setup_AMG()
Set-up AMG preconditioner.
-
virtual void solve()
solve Solves the Navier-Stokes problem
+
void setup_AMG()
Set-up AMG preconditioner.
+
virtual void solve()
solve Solves the Navier-Stokes problem
void define_non_zero_constraints()
Define the non-zero constraints used to solve the problem.
virtual void assemble_system_matrix() override
Assembles the matrix associated with the solver.
virtual void update_multiphysics_time_average_solution() override
Updates the average velocity field solution in the multiphyscics interface.
virtual void assemble_local_system_matrix(const typename DoFHandler< dim >::active_cell_iterator &cell, NavierStokesScratchData< dim > &scratch_data, StabilizedMethodsTensorCopyData< dim > &copy_data)
Assemble the local matrix for a given cell.
-
void setup_preconditioner() override
Set-up the appropriate preconditioner.
+
void setup_preconditioner() override
Set-up the appropriate preconditioner.
void define_zero_constraints()
Define the zero constraints used to solve the problem.
virtual void setup_assemblers()
sets up the vector of assembler functions
-
void setup_ILU()
Set-up ILU preconditioner.
+
void setup_ILU()
Set-up ILU preconditioner.
virtual void assemble_local_system_rhs(const typename DoFHandler< dim >::active_cell_iterator &cell, NavierStokesScratchData< dim > &scratch_data, StabilizedMethodsTensorCopyData< dim > &copy_data)
Assemble the local rhs for a given cell.
-
void solve_system_direct(const bool initial_step, const double absolute_residual, const double relative_residual)
Direct solver using TrilinosWrappers::SolverDirect The use of this solver should be avoided for 3D pr...
+
void solve_system_direct(const bool initial_step, const double absolute_residual, const double relative_residual)
Direct solver using TrilinosWrappers::SolverDirect The use of this solver should be avoided for 3D pr...
GLSNavierStokesSolver(SimulationParameters< dim > &nsparam)
-
void solve_system_BiCGStab(const bool initial_step, const double absolute_residual, const double relative_residual)
BiCGStab solver with ILU(N) preconditioning.
+
void solve_system_BiCGStab(const bool initial_step, const double absolute_residual, const double relative_residual)
BiCGStab solver with ILU(N) preconditioning.
Assembles the transient time arising from BDF time integration for the Navier-Stokes equation with fr...
Assembles the core of the Navier-Stokes equation with free surface using VOF modeling....
Assembles the Marangoni effect for the Navier-Stokes equations according to the following equation:
@@ -2044,7 +2054,7 @@ - +
Struct containing fluid id, temperature and phase fraction range information, and flag containers for...
diff --git a/doxygen/gls__nitsche__navier__stokes_8cc_source.html b/doxygen/gls__nitsche__navier__stokes_8cc_source.html index c43e753a29..6636e24389 100644 --- a/doxygen/gls__nitsche__navier__stokes_8cc_source.html +++ b/doxygen/gls__nitsche__navier__stokes_8cc_source.html @@ -1182,9 +1182,9 @@
void output_solid_triangulation(const unsigned int i_solid)
Outputs a vtu file for each output frequency of the solid triangulation.
virtual void refine_mesh() override
Allow the refinement of the mesh according to one of the 2 methods proposed. Overrides the regular me...
std::vector< PVDHandler > pvdhandler_solid_triangulation
- + - + diff --git a/doxygen/gls__sharp__navier__stokes_8cc_source.html b/doxygen/gls__sharp__navier__stokes_8cc_source.html index a6fba4257d..33134e23a0 100644 --- a/doxygen/gls__sharp__navier__stokes_8cc_source.html +++ b/doxygen/gls__sharp__navier__stokes_8cc_source.html @@ -5119,13 +5119,13 @@
virtual void refine_mesh()
Allow the refinement of the mesh according to one of the 2 methods proposed.
- +
virtual void finish_time_step()
finish_time_step Finishes the time step of the fluid dynamics Post-processing and time stepping
virtual void iterate()
iterate Do a regular CFD iteration
-
virtual void postprocess_fd(bool first_iteration)
postprocess Post-process fluid dynamics after an iteration
+
virtual void postprocess_fd(bool first_iteration)
postprocess Post-process fluid dynamics after an iteration
std::shared_ptr< Function< dim > > forcing_function
@@ -5139,7 +5139,7 @@
virtual void set_initial_condition(Parameters::InitialConditionType initial_condition_type, bool restart=false)
set_initial_conditions
- +
std::shared_ptr< parallel::DistributedTriangulationBase< dim > > triangulation
This class implements a boundary conditions for the Navier-Stokes equation where the velocity compone...
virtual double value(const Point< dim > &p, const unsigned int component) const override
Calculates the value of a Function-type Navier-Stokes equations.
diff --git a/doxygen/mf__navier__stokes_8cc_source.html b/doxygen/mf__navier__stokes_8cc_source.html index 9169236054..92d6a58141 100644 --- a/doxygen/mf__navier__stokes_8cc_source.html +++ b/doxygen/mf__navier__stokes_8cc_source.html @@ -302,2275 +302,2309 @@
221  , simulation_parameters(simulation_parameters)
222  , dof_handler(dof_handler)
223  , dof_handler_fe_q_iso_q1(dof_handler_fe_q_iso_q1)
-
224  , mg_setup_timer(MPI_COMM_WORLD,
-
225  this->pcout,
-
226  TimerOutput::never,
-
227  TimerOutput::wall_times)
-
228  , mg_vmult_timer(MPI_COMM_WORLD,
-
229  this->pcout,
-
230  TimerOutput::never,
-
231  TimerOutput::wall_times)
-
232 {
-
233  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
- -
235  {
-
236  // Define maximum and minimum level according to triangulation
-
237  const unsigned int n_h_levels =
-
238  this->dof_handler.get_triangulation().n_global_levels();
-
239  this->minlevel = 0;
-
240  this->maxlevel = n_h_levels - 1;
-
241 
-
242  // If multigrid number of levels or minimum number of cells in level are
-
243  // specified, change the min level fnd print levels information
-
244 
-
245  int mg_min_level =
-
246  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
247  .mg_min_level;
-
248 
-
249  AssertThrow(
-
250  mg_min_level <= static_cast<int>(MGTools::max_level_for_coarse_mesh(
-
251  this->dof_handler.get_triangulation())),
-
252  ExcMessage(std::string(
-
253  "The maximum level allowed for the coarse mesh (mg min level) is: " +
-
254  std::to_string(MGTools::max_level_for_coarse_mesh(
-
255  this->dof_handler.get_triangulation())) +
-
256  ".")));
-
257 
-
258  int mg_level_min_cells =
-
259  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
260  .mg_level_min_cells;
-
261 
-
262 
-
263  std::vector<unsigned int> n_cells_on_levels(
-
264  this->dof_handler.get_triangulation().n_global_levels(), 0);
-
265 
-
266  for (unsigned int l = 0;
-
267  l < this->dof_handler.get_triangulation().n_levels();
-
268  ++l)
-
269  for (const auto &cell :
-
270  this->dof_handler.get_triangulation().cell_iterators_on_level(l))
-
271  if (cell->is_locally_owned_on_level())
-
272  n_cells_on_levels[l]++;
-
273 
-
274  Utilities::MPI::sum(n_cells_on_levels,
-
275  this->dof_handler.get_communicator(),
-
276  n_cells_on_levels);
-
277  AssertThrow(
-
278  mg_level_min_cells <= static_cast<int>(n_cells_on_levels[maxlevel]),
-
279  ExcMessage(
-
280  "The mg level min cells specified are larger than the cells of the finest mg level."));
-
281 
-
282 
-
283  if (mg_min_level != -1)
-
284  this->minlevel = mg_min_level;
-
285 
-
286  if (mg_level_min_cells != -1)
-
287  {
-
288  for (unsigned int level = this->minlevel; level <= this->maxlevel;
-
289  ++level)
-
290  if (static_cast<int>(n_cells_on_levels[level]) >=
-
291  mg_level_min_cells)
-
292  {
-
293  this->minlevel = level;
-
294  break;
-
295  }
-
296  }
-
297 
-
298  if (this->simulation_parameters.linear_solver
- -
300  .mg_verbosity != Parameters::Verbosity::quiet)
-
301  {
-
302  this->pcout << std::endl;
-
303  this->pcout << " -Levels of MG preconditioner:" << std::endl;
-
304  for (unsigned int level = this->minlevel; level <= this->maxlevel;
-
305  ++level)
-
306  this->pcout << " Level " << level - this->minlevel << ": "
-
307  << this->dof_handler.n_dofs(level) << " DoFs, "
-
308  << n_cells_on_levels[level] << " cells" << std::endl;
-
309  this->pcout << std::endl;
-
310  }
-
311 
-
312  std::vector<std::shared_ptr<const Utilities::MPI::Partitioner>>
-
313  partitioners(this->dof_handler.get_triangulation().n_global_levels());
+
224  , mg_setup_timer(this->pcout, TimerOutput::never, TimerOutput::wall_times)
+
225  , mg_vmult_timer(this->pcout, TimerOutput::never, TimerOutput::wall_times)
+
226 {
+
227  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+ +
229  {
+
230  // Define maximum and minimum level according to triangulation
+
231  const unsigned int n_h_levels =
+
232  this->dof_handler.get_triangulation().n_global_levels();
+
233  this->minlevel = 0;
+
234  this->maxlevel = n_h_levels - 1;
+
235 
+
236  // If multigrid number of levels or minimum number of cells in level are
+
237  // specified, change the min level fnd print levels information
+
238 
+
239  int mg_min_level =
+
240  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
241  .mg_min_level;
+
242 
+
243  AssertThrow(
+
244  mg_min_level <= static_cast<int>(MGTools::max_level_for_coarse_mesh(
+
245  this->dof_handler.get_triangulation())),
+
246  ExcMessage(std::string(
+
247  "The maximum level allowed for the coarse mesh (mg min level) is: " +
+
248  std::to_string(MGTools::max_level_for_coarse_mesh(
+
249  this->dof_handler.get_triangulation())) +
+
250  ".")));
+
251 
+
252  int mg_level_min_cells =
+
253  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
254  .mg_level_min_cells;
+
255 
+
256 
+
257  std::vector<unsigned int> n_cells_on_levels(
+
258  this->dof_handler.get_triangulation().n_global_levels(), 0);
+
259 
+
260  for (unsigned int l = 0;
+
261  l < this->dof_handler.get_triangulation().n_levels();
+
262  ++l)
+
263  for (const auto &cell :
+
264  this->dof_handler.get_triangulation().cell_iterators_on_level(l))
+
265  if (cell->is_locally_owned_on_level())
+
266  n_cells_on_levels[l]++;
+
267 
+
268  Utilities::MPI::sum(n_cells_on_levels,
+
269  this->dof_handler.get_communicator(),
+
270  n_cells_on_levels);
+
271  AssertThrow(
+
272  mg_level_min_cells <= static_cast<int>(n_cells_on_levels[maxlevel]),
+
273  ExcMessage(
+
274  "The mg level min cells specified are larger than the cells of the finest mg level."));
+
275 
+
276 
+
277  if (mg_min_level != -1)
+
278  this->minlevel = mg_min_level;
+
279 
+
280  if (mg_level_min_cells != -1)
+
281  {
+
282  for (unsigned int level = this->minlevel; level <= this->maxlevel;
+
283  ++level)
+
284  if (static_cast<int>(n_cells_on_levels[level]) >=
+
285  mg_level_min_cells)
+
286  {
+
287  this->minlevel = level;
+
288  break;
+
289  }
+
290  }
+
291 
+
292  if (this->simulation_parameters.linear_solver
+ +
294  .mg_verbosity != Parameters::Verbosity::quiet)
+
295  {
+
296  this->pcout << std::endl;
+
297  this->pcout << " -Levels of MG preconditioner:" << std::endl;
+
298  for (unsigned int level = this->minlevel; level <= this->maxlevel;
+
299  ++level)
+
300  this->pcout << " Level " << level - this->minlevel << ": "
+
301  << this->dof_handler.n_dofs(level) << " DoFs, "
+
302  << n_cells_on_levels[level] << " cells" << std::endl;
+
303  this->pcout << std::endl;
+
304  }
+
305 
+
306  if (this->simulation_parameters.linear_solver
+ +
308  .mg_verbosity == Parameters::Verbosity::extra_verbose)
+
309  {
+
310  this->pcout << " -MG vertical communication efficiency: "
+
311  << MGTools::vertical_communication_efficiency(
+
312  this->dof_handler.get_triangulation())
+
313  << std::endl;
314 
-
315  // Local object for constraints of the different levels
-
316  MGLevelObject<AffineConstraints<double>> level_constraints;
-
317 
-
318  // Resize all multilevel objects according to level
-
319  this->mg_operators.resize(this->minlevel, this->maxlevel);
-
320  level_constraints.resize(this->minlevel, this->maxlevel);
-
321  this->ls_mg_interface_in.resize(this->minlevel, this->maxlevel);
-
322  this->ls_mg_operators.resize(this->minlevel, this->maxlevel);
+
315  this->pcout << " -MG workload imbalance: "
+
316  << MGTools::workload_imbalance(
+
317  this->dof_handler.get_triangulation())
+
318  << std::endl;
+
319  }
+
320 
+
321  std::vector<std::shared_ptr<const Utilities::MPI::Partitioner>>
+
322  partitioners(this->dof_handler.get_triangulation().n_global_levels());
323 
-
324  // Fill the level constraints
-
325  this->mg_setup_timer.enter_subsection("Set boundary conditions");
+
324  // Local object for constraints of the different levels
+
325  MGLevelObject<AffineConstraints<double>> level_constraints;
326 
-
327  this->mg_constrained_dofs.clear();
-
328  this->mg_constrained_dofs.initialize(this->dof_handler);
-
329 
-
330  FEValuesExtractors::Vector velocities(0);
-
331  FEValuesExtractors::Scalar pressure(dim);
+
327  // Resize all multilevel objects according to level
+
328  this->mg_operators.resize(this->minlevel, this->maxlevel);
+
329  level_constraints.resize(this->minlevel, this->maxlevel);
+
330  this->ls_mg_interface_in.resize(this->minlevel, this->maxlevel);
+
331  this->ls_mg_operators.resize(this->minlevel, this->maxlevel);
332 
-
333  for (unsigned int i_bc = 0;
-
334  i_bc < this->simulation_parameters.boundary_conditions.size;
-
335  ++i_bc)
-
336  {
-
337  if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
- -
339  {
-
340  std::set<types::boundary_id> no_normal_flux_boundaries;
-
341  no_normal_flux_boundaries.insert(
-
342  this->simulation_parameters.boundary_conditions.id[i_bc]);
-
343  for (unsigned int level = this->minlevel; level <= this->maxlevel;
-
344  ++level)
-
345  {
-
346  AffineConstraints<double> temp_constraints;
-
347  temp_constraints.clear();
-
348  const IndexSet locally_relevant_level_dofs =
-
349  DoFTools::extract_locally_relevant_level_dofs(
-
350  this->dof_handler, level);
-
351  temp_constraints.reinit(locally_relevant_level_dofs);
-
352  VectorTools::compute_no_normal_flux_constraints_on_level(
-
353  this->dof_handler,
-
354  0,
-
355  no_normal_flux_boundaries,
-
356  temp_constraints,
-
357  *mapping,
-
358  this->mg_constrained_dofs.get_refinement_edge_indices(
-
359  level),
-
360  level);
-
361  temp_constraints.close();
-
362  this->mg_constrained_dofs.add_user_constraints(
-
363  level, temp_constraints);
-
364  }
-
365  }
-
366  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
- -
368  {
-
369  /*already taken into account when mg_constrained_dofs is
-
370  * initialized*/
-
371  }
-
372  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
- -
374  {
-
375  /*do nothing*/
-
376  }
-
377  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
- -
379  {
-
380  /*do nothing*/
-
381  }
-
382  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
- -
384  {
-
385  /*do nothing*/
-
386  }
-
387  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
- -
389  {
-
390  /*do nothing*/
-
391  }
-
392  else
+
333  // Fill the level constraints
+
334  this->mg_setup_timer.enter_subsection("Set boundary conditions");
+
335 
+
336  this->mg_constrained_dofs.clear();
+
337  this->mg_constrained_dofs.initialize(this->dof_handler);
+
338 
+
339  FEValuesExtractors::Vector velocities(0);
+
340  FEValuesExtractors::Scalar pressure(dim);
+
341 
+
342  for (unsigned int i_bc = 0;
+
343  i_bc < this->simulation_parameters.boundary_conditions.size;
+
344  ++i_bc)
+
345  {
+
346  if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
+ +
348  {
+
349  std::set<types::boundary_id> no_normal_flux_boundaries;
+
350  no_normal_flux_boundaries.insert(
+
351  this->simulation_parameters.boundary_conditions.id[i_bc]);
+
352  for (unsigned int level = this->minlevel; level <= this->maxlevel;
+
353  ++level)
+
354  {
+
355  AffineConstraints<double> temp_constraints;
+
356  temp_constraints.clear();
+
357  const IndexSet locally_relevant_level_dofs =
+
358  DoFTools::extract_locally_relevant_level_dofs(
+
359  this->dof_handler, level);
+
360  temp_constraints.reinit(locally_relevant_level_dofs);
+
361  VectorTools::compute_no_normal_flux_constraints_on_level(
+
362  this->dof_handler,
+
363  0,
+
364  no_normal_flux_boundaries,
+
365  temp_constraints,
+
366  *mapping,
+
367  this->mg_constrained_dofs.get_refinement_edge_indices(
+
368  level),
+
369  level);
+
370  temp_constraints.close();
+
371  this->mg_constrained_dofs.add_user_constraints(
+
372  level, temp_constraints);
+
373  }
+
374  }
+
375  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
+ +
377  {
+
378  /*already taken into account when mg_constrained_dofs is
+
379  * initialized*/
+
380  }
+
381  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
+ +
383  {
+
384  /*do nothing*/
+
385  }
+
386  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
+ +
388  {
+
389  /*do nothing*/
+
390  }
+
391  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
+
393  {
-
394  std::set<types::boundary_id> dirichlet_boundary_id = {
-
395  this->simulation_parameters.boundary_conditions.id[i_bc]};
-
396  this->mg_constrained_dofs.make_zero_boundary_constraints(
-
397  this->dof_handler,
-
398  dirichlet_boundary_id,
-
399  fe->component_mask(velocities));
+
394  /*do nothing*/
+
395  }
+
396  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
+ +
398  {
+
399  /*do nothing*/
400  }
-
401  }
-
402 
-
403  this->mg_setup_timer.leave_subsection("Set boundary conditions");
-
404 
-
405  // Create mg operators for each level and additional operators needed only
-
406  // for local smoothing
-
407  for (unsigned int level = this->minlevel; level <= this->maxlevel;
-
408  ++level)
-
409  {
-
410  level_constraints[level].clear();
+
401  else
+
402  {
+
403  std::set<types::boundary_id> dirichlet_boundary_id = {
+
404  this->simulation_parameters.boundary_conditions.id[i_bc]};
+
405  this->mg_constrained_dofs.make_zero_boundary_constraints(
+
406  this->dof_handler,
+
407  dirichlet_boundary_id,
+
408  fe->component_mask(velocities));
+
409  }
+
410  }
411 
-
412  const IndexSet relevant_dofs =
-
413  DoFTools::extract_locally_relevant_level_dofs(this->dof_handler,
-
414  level);
-
415 
-
416  level_constraints[level].reinit(relevant_dofs);
-
417 
-
418 #if DEAL_II_VERSION_GTE(9, 6, 0)
-
419  this->mg_constrained_dofs.merge_constraints(
-
420  level_constraints[level], level, true, false, true, true);
-
421 #else
-
422  AssertThrow(
-
423  false,
-
424  ExcMessage(
-
425  "The constraints for the lsmg preconditioner require a most recent version of deal.II."));
-
426 #endif
-
427 
-
428  if (this->simulation_parameters.boundary_conditions
-
429  .fix_pressure_constant &&
-
430  level == this->minlevel)
-
431  {
-
432  unsigned int min_index = numbers::invalid_unsigned_int;
-
433 
-
434  std::vector<types::global_dof_index> dof_indices;
-
435 
-
436  // Loop over the cells to identify the min index
-
437  for (const auto &cell : this->dof_handler.active_cell_iterators())
-
438  {
-
439  if (cell->is_locally_owned())
-
440  {
-
441  const auto &fe = cell->get_fe();
+
412  this->mg_setup_timer.leave_subsection("Set boundary conditions");
+
413 
+
414  // Create mg operators for each level and additional operators needed only
+
415  // for local smoothing
+
416  for (unsigned int level = this->minlevel; level <= this->maxlevel;
+
417  ++level)
+
418  {
+
419  level_constraints[level].clear();
+
420 
+
421  const IndexSet relevant_dofs =
+
422  DoFTools::extract_locally_relevant_level_dofs(this->dof_handler,
+
423  level);
+
424 
+
425  level_constraints[level].reinit(relevant_dofs);
+
426 
+
427 #if DEAL_II_VERSION_GTE(9, 6, 0)
+
428  this->mg_constrained_dofs.merge_constraints(
+
429  level_constraints[level], level, true, false, true, true);
+
430 #else
+
431  AssertThrow(
+
432  false,
+
433  ExcMessage(
+
434  "The constraints for the lsmg preconditioner require a most recent version of deal.II."));
+
435 #endif
+
436 
+
437  if (this->simulation_parameters.boundary_conditions
+
438  .fix_pressure_constant &&
+
439  level == this->minlevel)
+
440  {
+
441  unsigned int min_index = numbers::invalid_unsigned_int;
442 
-
443  dof_indices.resize(fe.n_dofs_per_cell());
-
444  cell->get_dof_indices(dof_indices);
-
445 
-
446  for (unsigned int i = 0; i < dof_indices.size(); ++i)
-
447  if (fe.system_to_component_index(i).first == dim)
-
448  min_index = std::min(min_index, dof_indices[i]);
-
449  }
-
450  }
+
443  std::vector<types::global_dof_index> dof_indices;
+
444 
+
445  // Loop over the cells to identify the min index
+
446  for (const auto &cell : this->dof_handler.active_cell_iterators())
+
447  {
+
448  if (cell->is_locally_owned())
+
449  {
+
450  const auto &fe = cell->get_fe();
451 
-
452  // Necessary to find the min across all cores.
-
453  min_index =
-
454  Utilities::MPI::min(min_index,
-
455  this->dof_handler.get_communicator());
-
456 
-
457  if (relevant_dofs.is_element(min_index))
-
458  level_constraints[level].add_line(min_index);
-
459  }
+
452  dof_indices.resize(fe.n_dofs_per_cell());
+
453  cell->get_dof_indices(dof_indices);
+
454 
+
455  for (unsigned int i = 0; i < dof_indices.size(); ++i)
+
456  if (fe.system_to_component_index(i).first == dim)
+
457  min_index = std::min(min_index, dof_indices[i]);
+
458  }
+
459  }
460 
-
461  level_constraints[level].close();
-
462 
-
463  this->mg_setup_timer.enter_subsection("Set up operators");
-
464 
-
465  // Provide appropriate quadrature depending on the type of elements of
-
466  // the level
-
467  auto quadrature_mg = *cell_quadrature;
-
468  if (this->simulation_parameters.linear_solver
- -
470  .mg_use_fe_q_iso_q1 &&
-
471  level == this->minlevel)
-
472  {
-
473  const auto points =
-
474  QGaussLobatto<1>(this->dof_handler.get_fe().degree + 1)
-
475  .get_points();
-
476 
-
477  quadrature_mg = QIterated<dim>(QGauss<1>(2), points);
-
478  }
-
479 
-
480  this->mg_operators[level] =
-
481  std::make_shared<NavierStokesStabilizedOperator<dim, double>>();
-
482 
-
483  this->mg_operators[level]->reinit(
-
484  *mapping,
-
485  (this->simulation_parameters.linear_solver
- -
487  .mg_use_fe_q_iso_q1 &&
-
488  level == this->minlevel) ?
- -
490  this->dof_handler,
-
491  level_constraints[level],
-
492  quadrature_mg,
-
493  forcing_function,
-
494  this->simulation_parameters.physical_properties_manager
- -
496  this->simulation_parameters.stabilization.stabilization,
-
497  level,
-
498  simulation_control,
-
499  this->simulation_parameters.linear_solver
- -
501  .mg_enable_hessians_jacobian,
-
502  true);
-
503 
-
504  this->ls_mg_operators[level].initialize(*(this->mg_operators)[level]);
-
505  this->ls_mg_interface_in[level].initialize(
-
506  *(this->mg_operators)[level]);
-
507 
-
508  partitioners[level] =
-
509  this->mg_operators[level]->get_vector_partitioner();
-
510 
-
511  this->mg_setup_timer.leave_subsection("Set up operators");
-
512  }
-
513 
-
514  // Create transfer operators
-
515  this->mg_setup_timer.enter_subsection("Create transfer operator");
+
461  // Necessary to find the min across all cores.
+
462  min_index =
+
463  Utilities::MPI::min(min_index,
+
464  this->dof_handler.get_communicator());
+
465 
+
466  if (relevant_dofs.is_element(min_index))
+
467  level_constraints[level].add_line(min_index);
+
468  }
+
469 
+
470  level_constraints[level].close();
+
471 
+
472  this->mg_setup_timer.enter_subsection("Set up operators");
+
473 
+
474  // Provide appropriate quadrature depending on the type of elements of
+
475  // the level
+
476  auto quadrature_mg = *cell_quadrature;
+
477  if (this->simulation_parameters.linear_solver
+ +
479  .mg_use_fe_q_iso_q1 &&
+
480  level == this->minlevel)
+
481  {
+
482  const auto points =
+
483  QGaussLobatto<1>(this->dof_handler.get_fe().degree + 1)
+
484  .get_points();
+
485 
+
486  quadrature_mg = QIterated<dim>(QGauss<1>(2), points);
+
487  }
+
488 
+
489  this->mg_operators[level] =
+
490  std::make_shared<NavierStokesStabilizedOperator<dim, double>>();
+
491 
+
492  this->mg_operators[level]->reinit(
+
493  *mapping,
+
494  (this->simulation_parameters.linear_solver
+ +
496  .mg_use_fe_q_iso_q1 &&
+
497  level == this->minlevel) ?
+ +
499  this->dof_handler,
+
500  level_constraints[level],
+
501  quadrature_mg,
+
502  forcing_function,
+
503  this->simulation_parameters.physical_properties_manager
+ +
505  this->simulation_parameters.stabilization.stabilization,
+
506  level,
+
507  simulation_control,
+
508  this->simulation_parameters.linear_solver
+ +
510  .mg_enable_hessians_jacobian,
+
511  true);
+
512 
+
513  this->ls_mg_operators[level].initialize(*(this->mg_operators)[level]);
+
514  this->ls_mg_interface_in[level].initialize(
+
515  *(this->mg_operators)[level]);
516 
-
517  this->mg_transfer_ls = std::make_shared<LSTransferType>();
-
518 
-
519  this->mg_transfer_ls->initialize_constraints(this->mg_constrained_dofs);
-
520  this->mg_transfer_ls->build(this->dof_handler, partitioners);
-
521 
-
522  this->mg_setup_timer.leave_subsection("Create transfer operator");
-
523  }
-
524  else if (this->simulation_parameters.linear_solver
- -
526  .preconditioner ==
- -
528  {
-
529  // Create triangulations
-
530  this->mg_setup_timer.enter_subsection("Create level triangulations");
- -
532  MGTransferGlobalCoarseningTools::create_geometric_coarsening_sequence(
-
533  this->dof_handler.get_triangulation());
-
534  this->mg_setup_timer.leave_subsection("Create level triangulations");
-
535 
-
536  // Modify the triangulations if multigrid number of levels or minimum
-
537  // number of cells in level are specified
-
538  std::vector<std::shared_ptr<const Triangulation<dim>>> temp;
-
539 
-
540  int mg_min_level =
-
541  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
542  .mg_min_level;
-
543 
-
544  AssertThrow(
-
545  (mg_min_level + 1) <=
-
546  static_cast<int>(this->coarse_grid_triangulations.size()),
-
547  ExcMessage(
-
548  "The mg min level specified is higher than the finest mg level."));
-
549 
-
550  int mg_level_min_cells =
-
551  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
552  .mg_level_min_cells;
-
553 
-
554  AssertThrow(
-
555  mg_level_min_cells <=
-
556  static_cast<int>(this
- -
558  [this->coarse_grid_triangulations.size() - 1]
-
559  ->n_global_active_cells()),
-
560  ExcMessage(
-
561  "The mg level min cells specified are larger than the cells of the finest mg level."));
+
517  partitioners[level] =
+
518  this->mg_operators[level]->get_vector_partitioner();
+
519 
+
520  this->mg_setup_timer.leave_subsection("Set up operators");
+
521  }
+
522 
+
523  // Create transfer operators
+
524  this->mg_setup_timer.enter_subsection("Create transfer operator");
+
525 
+
526  this->mg_transfer_ls = std::make_shared<LSTransferType>();
+
527 
+
528  this->mg_transfer_ls->initialize_constraints(this->mg_constrained_dofs);
+
529  this->mg_transfer_ls->build(this->dof_handler, partitioners);
+
530 
+
531  this->mg_setup_timer.leave_subsection("Create transfer operator");
+
532  }
+
533  else if (this->simulation_parameters.linear_solver
+ +
535  .preconditioner ==
+ +
537  {
+
538  // Create triangulations
+
539  this->mg_setup_timer.enter_subsection("Create level triangulations");
+ +
541  MGTransferGlobalCoarseningTools::create_geometric_coarsening_sequence(
+
542  this->dof_handler.get_triangulation());
+
543  this->mg_setup_timer.leave_subsection("Create level triangulations");
+
544 
+
545  // Modify the triangulations if multigrid number of levels or minimum
+
546  // number of cells in level are specified
+
547  std::vector<std::shared_ptr<const Triangulation<dim>>> temp;
+
548 
+
549  int mg_min_level =
+
550  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
551  .mg_min_level;
+
552 
+
553  AssertThrow(
+
554  (mg_min_level + 1) <=
+
555  static_cast<int>(this->coarse_grid_triangulations.size()),
+
556  ExcMessage(
+
557  "The mg min level specified is higher than the finest mg level."));
+
558 
+
559  int mg_level_min_cells =
+
560  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
561  .mg_level_min_cells;
562 
-
563  // find first relevant coarse-grid triangulation
-
564  auto ptr = std::find_if(
-
565  this->coarse_grid_triangulations.begin(),
-
566  this->coarse_grid_triangulations.end() - 1,
-
567  [&mg_min_level, &mg_level_min_cells](const auto &tria) {
-
568  if (mg_min_level != -1) // minimum number of levels
-
569  {
-
570  if ((mg_min_level + 1) <=
-
571  static_cast<int>(tria->n_global_levels()))
-
572  return true;
-
573  }
-
574  else if (mg_level_min_cells != -1) // minimum number of cells
-
575  {
-
576  if (static_cast<int>(tria->n_global_active_cells()) >=
-
577  mg_level_min_cells)
-
578  return true;
-
579  }
-
580  else
-
581  {
-
582  return true;
-
583  }
-
584  return false;
-
585  });
-
586 
-
587  // consider all triangulations from that one
-
588  while (ptr != this->coarse_grid_triangulations.end())
-
589  temp.push_back(*(ptr++));
-
590 
-
591  this->coarse_grid_triangulations = temp;
-
592 
-
593  // Define maximum and minimum level according to triangulations
-
594  const unsigned int n_h_levels = this->coarse_grid_triangulations.size();
-
595  this->minlevel = 0;
-
596  this->maxlevel = n_h_levels - 1;
-
597 
-
598  // Local object for constraints of the different levels
-
599  MGLevelObject<AffineConstraints<typename VectorType::value_type>>
-
600  constraints;
+
563  AssertThrow(
+
564  mg_level_min_cells <=
+
565  static_cast<int>(this
+ +
567  [this->coarse_grid_triangulations.size() - 1]
+
568  ->n_global_active_cells()),
+
569  ExcMessage(
+
570  "The mg level min cells specified are larger than the cells of the finest mg level."));
+
571 
+
572  // find first relevant coarse-grid triangulation
+
573  auto ptr = std::find_if(
+
574  this->coarse_grid_triangulations.begin(),
+
575  this->coarse_grid_triangulations.end() - 1,
+
576  [&mg_min_level, &mg_level_min_cells](const auto &tria) {
+
577  if (mg_min_level != -1) // minimum number of levels
+
578  {
+
579  if ((mg_min_level + 1) <=
+
580  static_cast<int>(tria->n_global_levels()))
+
581  return true;
+
582  }
+
583  else if (mg_level_min_cells != -1) // minimum number of cells
+
584  {
+
585  if (static_cast<int>(tria->n_global_active_cells()) >=
+
586  mg_level_min_cells)
+
587  return true;
+
588  }
+
589  else
+
590  {
+
591  return true;
+
592  }
+
593  return false;
+
594  });
+
595 
+
596  // consider all triangulations from that one
+
597  while (ptr != this->coarse_grid_triangulations.end())
+
598  temp.push_back(*(ptr++));
+
599 
+
600  this->coarse_grid_triangulations = temp;
601 
-
602  // Resize all multilevel objects according to level
-
603  this->mg_operators.resize(this->minlevel, this->maxlevel);
-
604  constraints.resize(this->minlevel, this->maxlevel);
-
605  this->transfers.resize(this->minlevel, this->maxlevel);
+
602  // Define maximum and minimum level according to triangulations
+
603  const unsigned int n_h_levels = this->coarse_grid_triangulations.size();
+
604  this->minlevel = 0;
+
605  this->maxlevel = n_h_levels - 1;
606 
-
607  // Distribute DoFs for each level
-
608  this->mg_setup_timer.enter_subsection(
-
609  "Create DoFHandlers and distribute DoFs");
-
610  this->dof_handlers.resize(this->minlevel, this->maxlevel);
-
611 
-
612  for (unsigned int l = this->minlevel; l <= this->maxlevel; ++l)
-
613  {
-
614  this->dof_handlers[l].reinit(*this->coarse_grid_triangulations[l]);
+
607  // Local object for constraints of the different levels
+
608  MGLevelObject<AffineConstraints<typename VectorType::value_type>>
+
609  constraints;
+
610 
+
611  // Resize all multilevel objects according to level
+
612  this->mg_operators.resize(this->minlevel, this->maxlevel);
+
613  constraints.resize(this->minlevel, this->maxlevel);
+
614  this->transfers.resize(this->minlevel, this->maxlevel);
615 
-
616  // To use elements with linear interpolation for coarse-grid we need
-
617  // to create the min level dof handler with the appropriate element
-
618  // type
-
619  if (this->simulation_parameters.linear_solver
- -
621  .mg_use_fe_q_iso_q1 &&
-
622  l == this->minlevel)
-
623  {
-
624  const auto points =
-
625  QGaussLobatto<1>(this->dof_handler.get_fe().degree + 1)
-
626  .get_points();
-
627 
-
628  this->dof_handlers[l].distribute_dofs(
-
629  FESystem<dim>(FE_Q_iso_Q1<dim>(points), dim + 1));
-
630  }
-
631  else
-
632  this->dof_handlers[l].distribute_dofs(this->dof_handler.get_fe());
-
633  }
-
634 
-
635  this->mg_setup_timer.leave_subsection(
-
636  "Create DoFHandlers and distribute DoFs");
-
637 
-
638  if (this->simulation_parameters.linear_solver
- -
640  .mg_verbosity != Parameters::Verbosity::quiet)
-
641  {
-
642  this->pcout << std::endl;
-
643  this->pcout << " -Levels of MG preconditioner:" << std::endl;
-
644  for (unsigned int level = this->minlevel; level <= this->maxlevel;
-
645  ++level)
-
646  this->pcout << " Level " << level << ": "
-
647  << this->dof_handlers[level].n_dofs() << " DoFs, "
-
648  << this->coarse_grid_triangulations[level]
-
649  ->n_global_active_cells()
-
650  << " cells" << std::endl;
+
616  // Distribute DoFs for each level
+
617  this->mg_setup_timer.enter_subsection(
+
618  "Create DoFHandlers and distribute DoFs");
+
619  this->dof_handlers.resize(this->minlevel, this->maxlevel);
+
620 
+
621  for (unsigned int l = this->minlevel; l <= this->maxlevel; ++l)
+
622  {
+
623  this->dof_handlers[l].reinit(*this->coarse_grid_triangulations[l]);
+
624 
+
625  // To use elements with linear interpolation for coarse-grid we need
+
626  // to create the min level dof handler with the appropriate element
+
627  // type
+
628  if (this->simulation_parameters.linear_solver
+ +
630  .mg_use_fe_q_iso_q1 &&
+
631  l == this->minlevel)
+
632  {
+
633  const auto points =
+
634  QGaussLobatto<1>(this->dof_handler.get_fe().degree + 1)
+
635  .get_points();
+
636 
+
637  this->dof_handlers[l].distribute_dofs(
+
638  FESystem<dim>(FE_Q_iso_Q1<dim>(points), dim + 1));
+
639  }
+
640  else
+
641  this->dof_handlers[l].distribute_dofs(this->dof_handler.get_fe());
+
642  }
+
643 
+
644  this->mg_setup_timer.leave_subsection(
+
645  "Create DoFHandlers and distribute DoFs");
+
646 
+
647  if (this->simulation_parameters.linear_solver
+ +
649  .mg_verbosity != Parameters::Verbosity::quiet)
+
650  {
651  this->pcout << std::endl;
-
652  }
-
653 
-
654  // Apply constraints and create mg operators for each level
-
655  for (unsigned int level = this->minlevel; level <= this->maxlevel;
-
656  ++level)
-
657  {
-
658  const auto &level_dof_handler = this->dof_handlers[level];
-
659  auto &level_constraint = constraints[level];
-
660 
-
661  this->mg_setup_timer.enter_subsection("Set boundary conditions");
+
652  this->pcout << " -Levels of MG preconditioner:" << std::endl;
+
653  for (unsigned int level = this->minlevel; level <= this->maxlevel;
+
654  ++level)
+
655  this->pcout << " Level " << level << ": "
+
656  << this->dof_handlers[level].n_dofs() << " DoFs, "
+
657  << this->coarse_grid_triangulations[level]
+
658  ->n_global_active_cells()
+
659  << " cells" << std::endl;
+
660  this->pcout << std::endl;
+
661  }
662 
-
663  level_constraint.clear();
-
664  const IndexSet locally_relevant_dofs =
-
665  DoFTools::extract_locally_relevant_dofs(level_dof_handler);
-
666  level_constraint.reinit(locally_relevant_dofs);
-
667 
-
668  DoFTools::make_hanging_node_constraints(level_dof_handler,
-
669  level_constraint);
-
670 
-
671  FEValuesExtractors::Vector velocities(0);
-
672  FEValuesExtractors::Scalar pressure(dim);
-
673 
-
674  for (unsigned int i_bc = 0;
-
675  i_bc < this->simulation_parameters.boundary_conditions.size;
-
676  ++i_bc)
-
677  {
-
678  if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
- -
680  {
-
681  std::set<types::boundary_id> no_normal_flux_boundaries;
-
682  no_normal_flux_boundaries.insert(
-
683  this->simulation_parameters.boundary_conditions.id[i_bc]);
-
684  VectorTools::compute_no_normal_flux_constraints(
-
685  level_dof_handler,
-
686  0,
-
687  no_normal_flux_boundaries,
-
688  level_constraint,
-
689  *mapping);
-
690  }
-
691  else if (this->simulation_parameters.boundary_conditions
-
692  .type[i_bc] ==
- -
694  {
-
695  DoFTools::make_periodicity_constraints(
-
696  level_dof_handler,
-
697  this->simulation_parameters.boundary_conditions.id[i_bc],
-
698  this->simulation_parameters.boundary_conditions
-
699  .periodic_id[i_bc],
-
700  this->simulation_parameters.boundary_conditions
-
701  .periodic_direction[i_bc],
-
702  level_constraint);
-
703  }
-
704  else if (this->simulation_parameters.boundary_conditions
-
705  .type[i_bc] ==
- -
707  {
-
708  /*do nothing*/
-
709  }
-
710  else if (this->simulation_parameters.boundary_conditions
-
711  .type[i_bc] ==
- -
713  {
-
714  /*do nothing*/
-
715  }
-
716  else if (this->simulation_parameters.boundary_conditions
-
717  .type[i_bc] ==
- -
719  {
-
720  /*do nothing*/
-
721  }
-
722  else if (this->simulation_parameters.boundary_conditions
-
723  .type[i_bc] ==
- -
725  {
-
726  /*do nothing*/
+
663  if (this->simulation_parameters.linear_solver
+ +
665  .mg_verbosity == Parameters::Verbosity::extra_verbose)
+
666  {
+
667  this->pcout << " -MG vertical communication efficiency: "
+
668  << MGTools::vertical_communication_efficiency(
+ +
670  << std::endl;
+
671 
+
672  this->pcout << " -MG workload imbalance: "
+
673  << MGTools::workload_imbalance(
+ +
675  << std::endl;
+
676  }
+
677 
+
678  // Apply constraints and create mg operators for each level
+
679  for (unsigned int level = this->minlevel; level <= this->maxlevel;
+
680  ++level)
+
681  {
+
682  const auto &level_dof_handler = this->dof_handlers[level];
+
683  auto &level_constraint = constraints[level];
+
684 
+
685  this->mg_setup_timer.enter_subsection("Set boundary conditions");
+
686 
+
687  level_constraint.clear();
+
688  const IndexSet locally_relevant_dofs =
+
689  DoFTools::extract_locally_relevant_dofs(level_dof_handler);
+
690  level_constraint.reinit(locally_relevant_dofs);
+
691 
+
692  DoFTools::make_hanging_node_constraints(level_dof_handler,
+
693  level_constraint);
+
694 
+
695  FEValuesExtractors::Vector velocities(0);
+
696  FEValuesExtractors::Scalar pressure(dim);
+
697 
+
698  for (unsigned int i_bc = 0;
+
699  i_bc < this->simulation_parameters.boundary_conditions.size;
+
700  ++i_bc)
+
701  {
+
702  if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
+ +
704  {
+
705  std::set<types::boundary_id> no_normal_flux_boundaries;
+
706  no_normal_flux_boundaries.insert(
+
707  this->simulation_parameters.boundary_conditions.id[i_bc]);
+
708  VectorTools::compute_no_normal_flux_constraints(
+
709  level_dof_handler,
+
710  0,
+
711  no_normal_flux_boundaries,
+
712  level_constraint,
+
713  *mapping);
+
714  }
+
715  else if (this->simulation_parameters.boundary_conditions
+
716  .type[i_bc] ==
+ +
718  {
+
719  DoFTools::make_periodicity_constraints(
+
720  level_dof_handler,
+
721  this->simulation_parameters.boundary_conditions.id[i_bc],
+
722  this->simulation_parameters.boundary_conditions
+
723  .periodic_id[i_bc],
+
724  this->simulation_parameters.boundary_conditions
+
725  .periodic_direction[i_bc],
+
726  level_constraint);
727  }
-
728  else
-
729  {
-
730  VectorTools::interpolate_boundary_values(
-
731  *mapping,
-
732  level_dof_handler,
-
733  this->simulation_parameters.boundary_conditions.id[i_bc],
-
734  dealii::Functions::ZeroFunction<dim>(dim + 1),
-
735  level_constraint,
-
736  fe->component_mask(velocities));
-
737  }
-
738  }
-
739 
-
740  if (this->simulation_parameters.boundary_conditions
-
741  .fix_pressure_constant &&
-
742  level == this->minlevel)
-
743  {
-
744  unsigned int min_index = numbers::invalid_unsigned_int;
-
745 
-
746  std::vector<types::global_dof_index> dof_indices;
-
747 
-
748  // Loop over the cells to identify the min index
-
749  for (const auto &cell : level_dof_handler.active_cell_iterators())
-
750  {
-
751  if (cell->is_locally_owned())
-
752  {
-
753  const auto &fe = cell->get_fe();
-
754 
-
755  dof_indices.resize(fe.n_dofs_per_cell());
-
756  cell->get_dof_indices(dof_indices);
-
757 
-
758  for (unsigned int i = 0; i < dof_indices.size(); ++i)
-
759  if (fe.system_to_component_index(i).first == dim)
-
760  min_index = std::min(min_index, dof_indices[i]);
-
761  }
-
762  }
+
728  else if (this->simulation_parameters.boundary_conditions
+
729  .type[i_bc] ==
+ +
731  {
+
732  /*do nothing*/
+
733  }
+
734  else if (this->simulation_parameters.boundary_conditions
+
735  .type[i_bc] ==
+ +
737  {
+
738  /*do nothing*/
+
739  }
+
740  else if (this->simulation_parameters.boundary_conditions
+
741  .type[i_bc] ==
+ +
743  {
+
744  /*do nothing*/
+
745  }
+
746  else if (this->simulation_parameters.boundary_conditions
+
747  .type[i_bc] ==
+ +
749  {
+
750  /*do nothing*/
+
751  }
+
752  else
+
753  {
+
754  VectorTools::interpolate_boundary_values(
+
755  *mapping,
+
756  level_dof_handler,
+
757  this->simulation_parameters.boundary_conditions.id[i_bc],
+
758  dealii::Functions::ZeroFunction<dim>(dim + 1),
+
759  level_constraint,
+
760  fe->component_mask(velocities));
+
761  }
+
762  }
763 
-
764  // Necessary to find the min across all cores.
-
765  min_index =
-
766  Utilities::MPI::min(min_index,
-
767  this->dof_handler.get_communicator());
-
768 
-
769  if (locally_relevant_dofs.is_element(min_index))
-
770  level_constraint.add_line(min_index);
-
771  }
-
772 
-
773  level_constraint.close();
-
774 
-
775  this->mg_setup_timer.leave_subsection("Set boundary conditions");
-
776 
-
777  this->mg_setup_timer.enter_subsection("Set up operators");
+
764  if (this->simulation_parameters.boundary_conditions
+
765  .fix_pressure_constant &&
+
766  level == this->minlevel)
+
767  {
+
768  unsigned int min_index = numbers::invalid_unsigned_int;
+
769 
+
770  std::vector<types::global_dof_index> dof_indices;
+
771 
+
772  // Loop over the cells to identify the min index
+
773  for (const auto &cell : level_dof_handler.active_cell_iterators())
+
774  {
+
775  if (cell->is_locally_owned())
+
776  {
+
777  const auto &fe = cell->get_fe();
778 
-
779  // Provide appropriate quadrature depending on the type of elements of
-
780  // the level
-
781  auto quadrature_mg = *cell_quadrature;
-
782  if (this->simulation_parameters.linear_solver
- -
784  .mg_use_fe_q_iso_q1 &&
-
785  level == this->minlevel)
-
786  {
-
787  const auto points =
-
788  QGaussLobatto<1>(this->dof_handler.get_fe().degree + 1)
-
789  .get_points();
-
790 
-
791  quadrature_mg = QIterated<dim>(QGauss<1>(2), points);
-
792  }
-
793 
-
794  this->mg_operators[level] =
-
795  std::make_shared<NavierStokesStabilizedOperator<dim, double>>();
+
779  dof_indices.resize(fe.n_dofs_per_cell());
+
780  cell->get_dof_indices(dof_indices);
+
781 
+
782  for (unsigned int i = 0; i < dof_indices.size(); ++i)
+
783  if (fe.system_to_component_index(i).first == dim)
+
784  min_index = std::min(min_index, dof_indices[i]);
+
785  }
+
786  }
+
787 
+
788  // Necessary to find the min across all cores.
+
789  min_index =
+
790  Utilities::MPI::min(min_index,
+
791  this->dof_handler.get_communicator());
+
792 
+
793  if (locally_relevant_dofs.is_element(min_index))
+
794  level_constraint.add_line(min_index);
+
795  }
796 
-
797  this->mg_operators[level]->reinit(
-
798  *mapping,
-
799  level_dof_handler,
-
800  level_constraint,
-
801  quadrature_mg,
-
802  forcing_function,
-
803  this->simulation_parameters.physical_properties_manager
- -
805  this->simulation_parameters.stabilization.stabilization,
-
806  numbers::invalid_unsigned_int,
-
807  simulation_control,
-
808  this->simulation_parameters.linear_solver
- -
810  .mg_enable_hessians_jacobian,
-
811  true);
-
812 
-
813  this->mg_setup_timer.leave_subsection("Set up operators");
-
814  }
-
815 
-
816  // Create transfer operators
-
817  this->mg_setup_timer.enter_subsection("Create transfer operator");
-
818 
-
819  for (unsigned int level = this->minlevel; level < this->maxlevel; ++level)
-
820  this->transfers[level + 1].reinit(this->dof_handlers[level + 1],
-
821  this->dof_handlers[level],
-
822  constraints[level + 1],
-
823  constraints[level]);
-
824 
-
825  this->mg_transfer_gc = std::make_shared<GCTransferType>(
-
826  this->transfers, [&](const auto l, auto &vec) {
-
827  this->mg_operators[l]->initialize_dof_vector(vec);
-
828  });
-
829 
-
830  this->mg_setup_timer.leave_subsection("Create transfer operator");
-
831  }
-
832  else
-
833  AssertThrow(false, ExcNotImplemented());
-
834 }
-
835 
-
836 template <int dim>
-
837 void
- -
839  const std::shared_ptr<SimulationControl> simulation_control,
-
840  FlowControl<dim> &flow_control,
-
841  const VectorType &present_solution,
-
842  const VectorType &time_derivative_previous_solutions)
-
843 {
-
844  // Local objects for the different levels
-
845  MGLevelObject<VectorType> mg_solution(this->minlevel, this->maxlevel);
-
846  MGLevelObject<VectorType> mg_time_derivative_previous_solutions(
-
847  this->minlevel, this->maxlevel);
+
797  level_constraint.close();
+
798 
+
799  this->mg_setup_timer.leave_subsection("Set boundary conditions");
+
800 
+
801  this->mg_setup_timer.enter_subsection("Set up operators");
+
802 
+
803  // Provide appropriate quadrature depending on the type of elements of
+
804  // the level
+
805  auto quadrature_mg = *cell_quadrature;
+
806  if (this->simulation_parameters.linear_solver
+ +
808  .mg_use_fe_q_iso_q1 &&
+
809  level == this->minlevel)
+
810  {
+
811  const auto points =
+
812  QGaussLobatto<1>(this->dof_handler.get_fe().degree + 1)
+
813  .get_points();
+
814 
+
815  quadrature_mg = QIterated<dim>(QGauss<1>(2), points);
+
816  }
+
817 
+
818  this->mg_operators[level] =
+
819  std::make_shared<NavierStokesStabilizedOperator<dim, double>>();
+
820 
+
821  this->mg_operators[level]->reinit(
+
822  *mapping,
+
823  level_dof_handler,
+
824  level_constraint,
+
825  quadrature_mg,
+
826  forcing_function,
+
827  this->simulation_parameters.physical_properties_manager
+ +
829  this->simulation_parameters.stabilization.stabilization,
+
830  numbers::invalid_unsigned_int,
+
831  simulation_control,
+
832  this->simulation_parameters.linear_solver
+ +
834  .mg_enable_hessians_jacobian,
+
835  true);
+
836 
+
837  this->mg_setup_timer.leave_subsection("Set up operators");
+
838  }
+
839 
+
840  // Create transfer operators
+
841  this->mg_setup_timer.enter_subsection("Create transfer operator");
+
842 
+
843  for (unsigned int level = this->minlevel; level < this->maxlevel; ++level)
+
844  this->transfers[level + 1].reinit(this->dof_handlers[level + 1],
+
845  this->dof_handlers[level],
+
846  constraints[level + 1],
+
847  constraints[level]);
848 
-
849  for (unsigned int level = this->minlevel; level <= this->maxlevel; ++level)
-
850  {
-
851  this->mg_operators[level]->initialize_dof_vector(mg_solution[level]);
-
852  if (is_bdf(simulation_control->get_assembly_method()))
-
853  this->mg_operators[level]->initialize_dof_vector(
-
854  mg_time_derivative_previous_solutions[level]);
+
849  this->mg_transfer_gc = std::make_shared<GCTransferType>(
+
850  this->transfers, [&](const auto l, auto &vec) {
+
851  this->mg_operators[l]->initialize_dof_vector(vec);
+
852  });
+
853 
+
854  this->mg_setup_timer.leave_subsection("Create transfer operator");
855  }
-
856 
-
857  this->mg_setup_timer.enter_subsection("Execute relevant transfers");
-
858 
-
859  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
- -
861  {
-
862  // Create transfer operator and transfer solution to mg levels
-
863 
-
864  this->mg_transfer_ls->interpolate_to_mg(this->dof_handler,
-
865  mg_solution,
-
866  present_solution);
-
867 
-
868  if (is_bdf(simulation_control->get_assembly_method()))
-
869  this->mg_transfer_ls->interpolate_to_mg(
-
870  this->dof_handler,
-
871  mg_time_derivative_previous_solutions,
-
872  time_derivative_previous_solutions);
-
873 
-
874  this->mg_matrix =
-
875  std::make_shared<mg::Matrix<VectorType>>(this->ls_mg_operators);
-
876  }
-
877  else if (this->simulation_parameters.linear_solver
- -
879  .preconditioner ==
- -
881  {
-
882  this->mg_transfer_gc->interpolate_to_mg(this->dof_handler,
-
883  mg_solution,
-
884  present_solution);
-
885 
-
886  if (is_bdf(simulation_control->get_assembly_method()))
-
887  this->mg_transfer_gc->interpolate_to_mg(
-
888  this->dof_handler,
-
889  mg_time_derivative_previous_solutions,
-
890  time_derivative_previous_solutions);
+
856  else
+
857  AssertThrow(false, ExcNotImplemented());
+
858 }
+
859 
+
860 template <int dim>
+
861 void
+ +
863  const std::shared_ptr<SimulationControl> simulation_control,
+
864  FlowControl<dim> &flow_control,
+
865  const VectorType &present_solution,
+
866  const VectorType &time_derivative_previous_solutions)
+
867 {
+
868  // Local objects for the different levels
+
869  MGLevelObject<VectorType> mg_solution(this->minlevel, this->maxlevel);
+
870  MGLevelObject<VectorType> mg_time_derivative_previous_solutions(
+
871  this->minlevel, this->maxlevel);
+
872 
+
873  for (unsigned int level = this->minlevel; level <= this->maxlevel; ++level)
+
874  {
+
875  this->mg_operators[level]->initialize_dof_vector(mg_solution[level]);
+
876  if (is_bdf(simulation_control->get_assembly_method()))
+
877  this->mg_operators[level]->initialize_dof_vector(
+
878  mg_time_derivative_previous_solutions[level]);
+
879  }
+
880 
+
881  this->mg_setup_timer.enter_subsection("Execute relevant transfers");
+
882 
+
883  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+ +
885  {
+
886  // Create transfer operator and transfer solution to mg levels
+
887 
+
888  this->mg_transfer_ls->interpolate_to_mg(this->dof_handler,
+
889  mg_solution,
+
890  present_solution);
891 
-
892  this->mg_matrix =
-
893  std::make_shared<mg::Matrix<VectorType>>(this->mg_operators);
-
894  }
-
895 
-
896  this->mg_setup_timer.leave_subsection("Execute relevant transfers");
+
892  if (is_bdf(simulation_control->get_assembly_method()))
+
893  this->mg_transfer_ls->interpolate_to_mg(
+
894  this->dof_handler,
+
895  mg_time_derivative_previous_solutions,
+
896  time_derivative_previous_solutions);
897 
-
898  // Evaluate non linear terms for all mg operators
-
899  for (unsigned int level = this->minlevel; level <= this->maxlevel; ++level)
-
900  {
-
901  mg_solution[level].update_ghost_values();
-
902  this->mg_operators[level]->evaluate_non_linear_term_and_calculate_tau(
-
903  mg_solution[level]);
-
904 
-
905  if (is_bdf(simulation_control->get_assembly_method()))
-
906  {
-
907  mg_time_derivative_previous_solutions[level].update_ghost_values();
-
908  this->mg_operators[level]
-
909  ->evaluate_time_derivative_previous_solutions(
-
910  mg_time_derivative_previous_solutions[level]);
-
911 
-
912  if (this->simulation_parameters.flow_control.enable_flow_control)
-
913  this->mg_operators[level]->update_beta_force(
-
914  flow_control.get_beta());
-
915  }
-
916  }
-
917 
-
918  // Create smoother, fill parameters for each level and intialize it
-
919  this->mg_setup_timer.enter_subsection("Set up and initialize smoother");
-
920 
-
921  this->mg_smoother = std::make_shared<
-
922  MGSmootherPrecondition<OperatorType, SmootherType, VectorType>>();
-
923 
-
924  MGLevelObject<typename SmootherType::AdditionalData> smoother_data(
-
925  this->minlevel, this->maxlevel);
-
926 
-
927  for (unsigned int level = this->minlevel; level <= this->maxlevel; ++level)
-
928  {
-
929  VectorType diagonal_vector;
-
930  this->mg_operators[level]->compute_inverse_diagonal(diagonal_vector);
-
931  smoother_data[level].preconditioner =
-
932  std::make_shared<SmootherPreconditionerType>(diagonal_vector);
-
933  smoother_data[level].n_iterations =
-
934  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
935  .mg_smoother_iterations;
-
936 
-
937  if (this->simulation_parameters.linear_solver
- -
939  .mg_smoother_eig_estimation)
-
940  {
-
941 #if DEAL_II_VERSION_GTE(9, 6, 0)
-
942  // Set relaxation to zero so that eigenvalues are estimated
-
943  // internally
-
944  smoother_data[level].relaxation = 0.0;
-
945  smoother_data[level].smoothing_range =
-
946  this->simulation_parameters.linear_solver
- -
948  .eig_estimation_smoothing_range;
-
949  smoother_data[level].eig_cg_n_iterations =
-
950  this->simulation_parameters.linear_solver
- -
952  .eig_estimation_cg_n_iterations;
-
953  smoother_data[level].eigenvalue_algorithm =
-
954  SmootherType::AdditionalData::EigenvalueAlgorithm::power_iteration;
-
955  smoother_data[level].constraints.copy_from(
-
956  this->mg_operators[level]
-
957  ->get_system_matrix_free()
-
958  .get_affine_constraints());
-
959 #else
-
960  AssertThrow(
-
961  false,
-
962  ExcMessage(
-
963  "The estimation of eigenvalues within LSMG requires a version of deal.II >= 9.6.0"));
-
964 #endif
-
965  }
-
966  else
-
967  smoother_data[level].relaxation =
-
968  this->simulation_parameters.linear_solver
- -
970  .mg_smoother_relaxation;
-
971  }
-
972 
-
973  mg_smoother->initialize(this->mg_operators, smoother_data);
-
974 
-
975 #if DEAL_II_VERSION_GTE(9, 6, 0)
-
976  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
977  .mg_smoother_eig_estimation &&
-
978  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
979  .eig_estimation_verbose != Parameters::Verbosity::quiet)
-
980  {
-
981  // Print eigenvalue estimation for all levels
-
982  for (unsigned int level = this->minlevel; level <= this->maxlevel;
-
983  ++level)
-
984  {
-
985  VectorType vec;
-
986  this->mg_operators[level]->initialize_dof_vector(vec);
-
987  const auto evs =
-
988  mg_smoother->smoothers[level].estimate_eigenvalues(vec);
-
989 
-
990  this->pcout << std::endl;
-
991  this->pcout << " -Eigenvalue estimation level "
-
992  << level - this->minlevel << ":" << std::endl;
-
993  this->pcout << " Relaxation parameter: "
-
994  << mg_smoother->smoothers[level].get_relaxation()
-
995  << std::endl;
-
996  this->pcout << " Minimum eigenvalue: "
-
997  << evs.min_eigenvalue_estimate << std::endl;
-
998  this->pcout << " Maximum eigenvalue: "
-
999  << evs.max_eigenvalue_estimate << std::endl;
-
1000  this->pcout << std::endl;
-
1001  }
-
1002  }
-
1003 #else
-
1004  AssertThrow(
-
1005  false,
-
1006  ExcMessage(
-
1007  "The estimation of eigenvalues within LSMG requires a version of deal.II >= 9.6.0"));
-
1008 #endif
-
1009 
-
1010  this->mg_setup_timer.leave_subsection("Set up and initialize smoother");
-
1011 
-
1012  // Create coarse-grid GMRES solver and AMG preconditioner
-
1013  this->mg_setup_timer.enter_subsection("Create coarse-grid solver");
-
1014 
-
1015  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1016  .mg_coarse_grid_solver ==
- -
1018  {
-
1019  const int max_iterations =
-
1020  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1021  .mg_gmres_max_iterations;
-
1022  const double tolerance =
-
1023  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1024  .mg_gmres_tolerance;
-
1025  const double reduce =
-
1026  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1027  .mg_gmres_reduce;
-
1028  this->coarse_grid_solver_control = std::make_shared<ReductionControl>(
-
1029  max_iterations, tolerance, reduce, false, false);
-
1030  SolverGMRES<VectorType>::AdditionalData solver_parameters;
-
1031  solver_parameters.max_n_tmp_vectors =
-
1032  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1033  .mg_gmres_max_krylov_vectors;
-
1034 
-
1035  this->coarse_grid_solver = std::make_shared<SolverGMRES<VectorType>>(
-
1036  *this->coarse_grid_solver_control, solver_parameters);
-
1037 
-
1038  if (this->simulation_parameters.linear_solver
- -
1040  .mg_gmres_preconditioner ==
- -
1042  {
-
1043  setup_AMG();
-
1044 
-
1045  this->mg_coarse = std::make_shared<
-
1046  MGCoarseGridIterativeSolver<VectorType,
-
1047  SolverGMRES<VectorType>,
-
1048  OperatorType,
-
1049  TrilinosWrappers::PreconditionAMG>>(
-
1050  *this->coarse_grid_solver,
-
1051  *this->mg_operators[this->minlevel],
-
1052  *this->precondition_amg);
-
1053  }
-
1054  else if (this->simulation_parameters.linear_solver
- -
1056  .mg_gmres_preconditioner ==
- -
1058  {
-
1059  setup_ILU();
-
1060 
-
1061  this->mg_coarse = std::make_shared<
-
1062  MGCoarseGridIterativeSolver<VectorType,
-
1063  SolverGMRES<VectorType>,
-
1064  OperatorType,
-
1065  TrilinosWrappers::PreconditionILU>>(
-
1066  *this->coarse_grid_solver,
-
1067  *this->mg_operators[this->minlevel],
-
1068  *this->precondition_ilu);
-
1069  }
-
1070  }
-
1071  else if (this->simulation_parameters.linear_solver
- -
1073  .mg_coarse_grid_solver ==
- -
1075  {
-
1076  setup_AMG();
-
1077 
-
1078  this->mg_coarse = std::make_shared<
- -
1080  TrilinosWrappers::PreconditionAMG>>(
-
1081  *this->precondition_amg);
-
1082  }
-
1083  else if (this->simulation_parameters.linear_solver
- -
1085  .mg_coarse_grid_solver ==
- -
1087  {
-
1088  setup_ILU();
-
1089 
-
1090  this->mg_coarse = std::make_shared<
- -
1092  TrilinosWrappers::PreconditionILU>>(
-
1093  *this->precondition_ilu);
+
898  this->mg_matrix =
+
899  std::make_shared<mg::Matrix<VectorType>>(this->ls_mg_operators);
+
900  }
+
901  else if (this->simulation_parameters.linear_solver
+ +
903  .preconditioner ==
+ +
905  {
+
906  this->mg_transfer_gc->interpolate_to_mg(this->dof_handler,
+
907  mg_solution,
+
908  present_solution);
+
909 
+
910  if (is_bdf(simulation_control->get_assembly_method()))
+
911  this->mg_transfer_gc->interpolate_to_mg(
+
912  this->dof_handler,
+
913  mg_time_derivative_previous_solutions,
+
914  time_derivative_previous_solutions);
+
915 
+
916  this->mg_matrix =
+
917  std::make_shared<mg::Matrix<VectorType>>(this->mg_operators);
+
918  }
+
919 
+
920  this->mg_setup_timer.leave_subsection("Execute relevant transfers");
+
921 
+
922  // Evaluate non linear terms for all mg operators
+
923  for (unsigned int level = this->minlevel; level <= this->maxlevel; ++level)
+
924  {
+
925  mg_solution[level].update_ghost_values();
+
926  this->mg_operators[level]->evaluate_non_linear_term_and_calculate_tau(
+
927  mg_solution[level]);
+
928 
+
929  if (is_bdf(simulation_control->get_assembly_method()))
+
930  {
+
931  mg_time_derivative_previous_solutions[level].update_ghost_values();
+
932  this->mg_operators[level]
+
933  ->evaluate_time_derivative_previous_solutions(
+
934  mg_time_derivative_previous_solutions[level]);
+
935 
+
936  if (this->simulation_parameters.flow_control.enable_flow_control)
+
937  this->mg_operators[level]->update_beta_force(
+
938  flow_control.get_beta());
+
939  }
+
940  }
+
941 
+
942  // Create smoother, fill parameters for each level and intialize it
+
943  this->mg_setup_timer.enter_subsection("Set up and initialize smoother");
+
944 
+
945  this->mg_smoother = std::make_shared<
+
946  MGSmootherPrecondition<OperatorType, SmootherType, VectorType>>();
+
947 
+
948  MGLevelObject<typename SmootherType::AdditionalData> smoother_data(
+
949  this->minlevel, this->maxlevel);
+
950 
+
951  for (unsigned int level = this->minlevel; level <= this->maxlevel; ++level)
+
952  {
+
953  VectorType diagonal_vector;
+
954  this->mg_operators[level]->compute_inverse_diagonal(diagonal_vector);
+
955  smoother_data[level].preconditioner =
+
956  std::make_shared<SmootherPreconditionerType>(diagonal_vector);
+
957  smoother_data[level].n_iterations =
+
958  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
959  .mg_smoother_iterations;
+
960 
+
961  if (this->simulation_parameters.linear_solver
+ +
963  .mg_smoother_eig_estimation)
+
964  {
+
965 #if DEAL_II_VERSION_GTE(9, 6, 0)
+
966  // Set relaxation to zero so that eigenvalues are estimated
+
967  // internally
+
968  smoother_data[level].relaxation = 0.0;
+
969  smoother_data[level].smoothing_range =
+
970  this->simulation_parameters.linear_solver
+ +
972  .eig_estimation_smoothing_range;
+
973  smoother_data[level].eig_cg_n_iterations =
+
974  this->simulation_parameters.linear_solver
+ +
976  .eig_estimation_cg_n_iterations;
+
977  smoother_data[level].eigenvalue_algorithm =
+
978  SmootherType::AdditionalData::EigenvalueAlgorithm::power_iteration;
+
979  smoother_data[level].constraints.copy_from(
+
980  this->mg_operators[level]
+
981  ->get_system_matrix_free()
+
982  .get_affine_constraints());
+
983 #else
+
984  AssertThrow(
+
985  false,
+
986  ExcMessage(
+
987  "The estimation of eigenvalues within LSMG requires a version of deal.II >= 9.6.0"));
+
988 #endif
+
989  }
+
990  else
+
991  smoother_data[level].relaxation =
+
992  this->simulation_parameters.linear_solver
+ +
994  .mg_smoother_relaxation;
+
995  }
+
996 
+
997  mg_smoother->initialize(this->mg_operators, smoother_data);
+
998 
+
999 #if DEAL_II_VERSION_GTE(9, 6, 0)
+
1000  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1001  .mg_smoother_eig_estimation &&
+
1002  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1003  .eig_estimation_verbose != Parameters::Verbosity::quiet)
+
1004  {
+
1005  // Print eigenvalue estimation for all levels
+
1006  for (unsigned int level = this->minlevel; level <= this->maxlevel;
+
1007  ++level)
+
1008  {
+
1009  VectorType vec;
+
1010  this->mg_operators[level]->initialize_dof_vector(vec);
+
1011  const auto evs =
+
1012  mg_smoother->smoothers[level].estimate_eigenvalues(vec);
+
1013 
+
1014  this->pcout << std::endl;
+
1015  this->pcout << " -Eigenvalue estimation level "
+
1016  << level - this->minlevel << ":" << std::endl;
+
1017  this->pcout << " Relaxation parameter: "
+
1018  << mg_smoother->smoothers[level].get_relaxation()
+
1019  << std::endl;
+
1020  this->pcout << " Minimum eigenvalue: "
+
1021  << evs.min_eigenvalue_estimate << std::endl;
+
1022  this->pcout << " Maximum eigenvalue: "
+
1023  << evs.max_eigenvalue_estimate << std::endl;
+
1024  this->pcout << std::endl;
+
1025  }
+
1026  }
+
1027 #else
+
1028  AssertThrow(
+
1029  false,
+
1030  ExcMessage(
+
1031  "The estimation of eigenvalues within LSMG requires a version of deal.II >= 9.6.0"));
+
1032 #endif
+
1033 
+
1034  this->mg_setup_timer.leave_subsection("Set up and initialize smoother");
+
1035 
+
1036  // Create coarse-grid GMRES solver and AMG preconditioner
+
1037  this->mg_setup_timer.enter_subsection("Create coarse-grid solver");
+
1038 
+
1039  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1040  .mg_coarse_grid_solver ==
+ +
1042  {
+
1043  const int max_iterations =
+
1044  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1045  .mg_gmres_max_iterations;
+
1046  const double tolerance =
+
1047  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1048  .mg_gmres_tolerance;
+
1049  const double reduce =
+
1050  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1051  .mg_gmres_reduce;
+
1052  this->coarse_grid_solver_control = std::make_shared<ReductionControl>(
+
1053  max_iterations, tolerance, reduce, false, false);
+
1054  SolverGMRES<VectorType>::AdditionalData solver_parameters;
+
1055  solver_parameters.max_n_tmp_vectors =
+
1056  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1057  .mg_gmres_max_krylov_vectors;
+
1058 
+
1059  this->coarse_grid_solver = std::make_shared<SolverGMRES<VectorType>>(
+
1060  *this->coarse_grid_solver_control, solver_parameters);
+
1061 
+
1062  if (this->simulation_parameters.linear_solver
+ +
1064  .mg_gmres_preconditioner ==
+ +
1066  {
+
1067  setup_AMG();
+
1068 
+
1069  this->mg_coarse = std::make_shared<
+
1070  MGCoarseGridIterativeSolver<VectorType,
+
1071  SolverGMRES<VectorType>,
+
1072  OperatorType,
+
1073  TrilinosWrappers::PreconditionAMG>>(
+
1074  *this->coarse_grid_solver,
+
1075  *this->mg_operators[this->minlevel],
+
1076  *this->precondition_amg);
+
1077  }
+
1078  else if (this->simulation_parameters.linear_solver
+ +
1080  .mg_gmres_preconditioner ==
+ +
1082  {
+
1083  setup_ILU();
+
1084 
+
1085  this->mg_coarse = std::make_shared<
+
1086  MGCoarseGridIterativeSolver<VectorType,
+
1087  SolverGMRES<VectorType>,
+
1088  OperatorType,
+
1089  TrilinosWrappers::PreconditionILU>>(
+
1090  *this->coarse_grid_solver,
+
1091  *this->mg_operators[this->minlevel],
+
1092  *this->precondition_ilu);
+
1093  }
1094  }
1095  else if (this->simulation_parameters.linear_solver
1097  .mg_coarse_grid_solver ==
- +
1099  {
-
1100 #if DEAL_II_VERSION_GTE(9, 6, 0)
-
1101  TrilinosWrappers::SolverDirect::AdditionalData data;
-
1102  this->direct_solver_control =
-
1103  std::make_shared<SolverControl>(100, 1.e-10);
-
1104 
-
1105  this->precondition_direct =
-
1106  std::make_shared<TrilinosWrappers::SolverDirect>(
-
1107  *this->direct_solver_control, data);
-
1108 
-
1109  this->precondition_direct->initialize(
-
1110  this->mg_operators[this->minlevel]->get_system_matrix());
-
1111 
-
1112  this->mg_coarse = std::make_shared<
- -
1114  TrilinosWrappers::SolverDirect>>(
-
1115  *this->precondition_direct);
-
1116 #else
-
1117  AssertThrow(
-
1118  false,
-
1119  ExcMessage(
-
1120  "The usage of a direct solver as coarse grid solver requires a version of deal.II >= 9.6.0"));
-
1121 #endif
-
1122  }
-
1123  else
-
1124  AssertThrow(
-
1125  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1126  .mg_coarse_grid_solver ==
- -
1128  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1129  .mg_coarse_grid_solver ==
- -
1131  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1132  .mg_coarse_grid_solver ==
- -
1134  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1135  .mg_coarse_grid_solver ==
- -
1137  ExcMessage(
-
1138  "This coarse-grid solver is not supported. Supported options are <gmres|amg|ilu|direct>."));
-
1139 
-
1140  this->mg_setup_timer.leave_subsection("Create coarse-grid solver");
-
1141 
-
1142  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
- -
1144  {
-
1145  // Create interface matrices needed for local smoothing in case of
-
1146  // local refinement
-
1147  this->mg_interface_matrix_in =
-
1148  std::make_shared<mg::Matrix<VectorType>>(this->ls_mg_interface_in);
-
1149 
-
1150  // Create main MG object
-
1151  this->mg = std::make_shared<Multigrid<VectorType>>(*this->mg_matrix,
-
1152  *this->mg_coarse,
-
1153  *this->mg_transfer_ls,
-
1154  *this->mg_smoother,
-
1155  *this->mg_smoother,
-
1156  this->minlevel);
-
1157 
-
1158  if (this->dof_handler.get_triangulation().has_hanging_nodes())
-
1159  this->mg->set_edge_in_matrix(*this->mg_interface_matrix_in);
-
1160 
-
1161  // Create MG preconditioner
-
1162  this->ls_multigrid_preconditioner =
-
1163  std::make_shared<PreconditionMG<dim, VectorType, LSTransferType>>(
-
1164  this->dof_handler, *this->mg, *this->mg_transfer_ls);
-
1165  }
-
1166  else if (this->simulation_parameters.linear_solver
- -
1168  .preconditioner ==
- -
1170  {
-
1171  // Create main MG object
-
1172  this->mg = std::make_shared<Multigrid<VectorType>>(*this->mg_matrix,
-
1173  *this->mg_coarse,
-
1174  *this->mg_transfer_gc,
-
1175  *this->mg_smoother,
-
1176  *this->mg_smoother);
-
1177 
-
1178  // Create MG preconditioner
-
1179  this->gc_multigrid_preconditioner =
-
1180  std::make_shared<PreconditionMG<dim, VectorType, GCTransferType>>(
-
1181  this->dof_handler, *this->mg, *this->mg_transfer_gc);
-
1182  }
-
1183 
-
1184  // Print detailed timings of multigrid vmult
-
1185  const auto create_mg_timer_function = [&](const std::string &label) {
-
1186  return [label, this](const bool flag, const unsigned int level) {
-
1187  const std::string label_full =
-
1188  (label == "") ?
-
1189  ("gmg::vmult::level_" + std::to_string(level)) :
-
1190  ("gmg::vmult::level_" + std::to_string(level) + "::" + label);
-
1191 
-
1192  if (flag)
-
1193  this->mg_vmult_timer.enter_subsection(label_full);
-
1194  else
-
1195  this->mg_vmult_timer.leave_subsection(label_full);
-
1196  };
-
1197  };
-
1198 
-
1199  this->mg->connect_pre_smoother_step(
-
1200  create_mg_timer_function("0_pre_smoother_step"));
-
1201  this->mg->connect_residual_step(create_mg_timer_function("1_residual_step"));
-
1202  this->mg->connect_restriction(create_mg_timer_function("2_restriction"));
-
1203  this->mg->connect_coarse_solve(create_mg_timer_function(""));
-
1204  this->mg->connect_prolongation(create_mg_timer_function("3_prolongation"));
-
1205  this->mg->connect_edge_prolongation(
-
1206  create_mg_timer_function("4_edge_prolongation"));
-
1207  this->mg->connect_post_smoother_step(
-
1208  create_mg_timer_function("5_post_smoother_step"));
-
1209 
-
1210 
-
1211  const auto create_mg_precon_timer_function = [&](const std::string &label) {
-
1212  return [label, this](const bool flag) {
-
1213  const std::string label_full = "gmg::vmult::" + label;
-
1214 
-
1215  if (flag)
-
1216  this->mg_vmult_timer.enter_subsection(label_full);
-
1217  else
-
1218  this->mg_vmult_timer.leave_subsection(label_full);
-
1219  };
-
1220  };
-
1221 
-
1222  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
- -
1224  {
-
1225  this->ls_multigrid_preconditioner->connect_transfer_to_mg(
-
1226  create_mg_precon_timer_function("transfer_to_mg"));
-
1227  this->ls_multigrid_preconditioner->connect_transfer_to_global(
-
1228  create_mg_precon_timer_function("transfer_to_global"));
-
1229  }
-
1230  else if (this->simulation_parameters.linear_solver
- -
1232  .preconditioner ==
- -
1234  {
-
1235  this->gc_multigrid_preconditioner->connect_transfer_to_mg(
-
1236  create_mg_precon_timer_function("transfer_to_mg"));
-
1237  this->gc_multigrid_preconditioner->connect_transfer_to_global(
-
1238  create_mg_precon_timer_function("transfer_to_global"));
-
1239  }
-
1240 }
-
1241 
-
1242 template <int dim>
-
1243 void
- -
1245  const VectorType &src) const
-
1246 {
-
1247  if (this->ls_multigrid_preconditioner)
-
1248  this->ls_multigrid_preconditioner->vmult(dst, src);
-
1249  else if (this->gc_multigrid_preconditioner)
-
1250  this->gc_multigrid_preconditioner->vmult(dst, src);
-
1251  else
-
1252  AssertThrow(false, ExcNotImplemented());
-
1253 
-
1254  // Save number of coarse grid iterations needed in one vmult
-
1255  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1256  .mg_coarse_grid_solver ==
- -
1258  this->coarse_grid_iterations.emplace_back(
-
1259  this->coarse_grid_solver_control->last_step());
-
1260 }
-
1261 
-
1262 template <int dim>
-
1263 void
- -
1265 {
-
1266  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1267  .mg_coarse_grid_solver ==
- -
1269  {
-
1270  if (this->coarse_grid_iterations.empty())
-
1271  this->pcout << " -Coarse grid solver took: 0 iterations" << std::endl;
-
1272  else
-
1273  {
-
1274  unsigned int total = this->coarse_grid_iterations[0];
-
1275  this->pcout << " -Coarse grid solver took: "
-
1276  << this->coarse_grid_iterations[0];
-
1277  for (unsigned int i = 1; i < this->coarse_grid_iterations.size(); i++)
-
1278  {
-
1279  this->pcout << " + " << this->coarse_grid_iterations[i];
-
1280  total += this->coarse_grid_iterations[i];
-
1281  }
-
1282  this->pcout << " = " << total << " iterations" << std::endl;
-
1283 
-
1284  this->coarse_grid_iterations.clear();
-
1285  }
-
1286  }
-
1287 }
-
1288 
-
1289 template <int dim>
-
1290 const MGLevelObject<std::shared_ptr<NavierStokesOperatorBase<dim, double>>> &
- -
1292 {
-
1293  return this->mg_operators;
-
1294 }
-
1295 
-
1296 template <int dim>
-
1297 void
- -
1299 {
-
1300  TrilinosWrappers::PreconditionAMG::AdditionalData amg_data;
-
1301 
-
1302  // Extract matrix of the minlevel to avoid building it twice
-
1303  const TrilinosWrappers::SparseMatrix &min_level_matrix =
-
1304  this->mg_operators[this->minlevel]->get_system_matrix();
-
1305 
-
1306  if (!this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1307  .mg_amg_use_default_parameters)
-
1308  {
-
1309  amg_data.elliptic = false;
-
1310  if (this->dof_handler.get_fe().degree > 1)
-
1311  amg_data.higher_order_elements = true;
-
1312  amg_data.n_cycles =
-
1313  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1314  .amg_n_cycles;
-
1315  amg_data.w_cycle =
-
1316  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1317  .amg_w_cycles;
-
1318  amg_data.aggregation_threshold =
-
1319  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1320  .amg_aggregation_threshold;
-
1321  amg_data.smoother_sweeps =
-
1322  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1323  .amg_smoother_sweeps;
-
1324  amg_data.smoother_overlap =
-
1325  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1326  .amg_smoother_overlap;
-
1327  amg_data.output_details = false;
-
1328  amg_data.smoother_type = "ILU";
-
1329  amg_data.coarse_type = "ILU";
-
1330 
-
1331  std::vector<std::vector<bool>> constant_modes;
-
1332  ComponentMask components(dim + 1, true);
-
1333  if (this->simulation_parameters.linear_solver
- -
1335  .preconditioner ==
- -
1337 
-
1338  {
-
1339 #if DEAL_II_VERSION_GTE(9, 6, 0)
-
1340  // Constant modes for velocity and pressure
-
1341  DoFTools::extract_level_constant_modes(this->minlevel,
-
1342  this->dof_handler,
-
1343  components,
-
1344  constant_modes);
-
1345 #else
-
1346  AssertThrow(
-
1347  false,
-
1348  ExcMessage(
-
1349  "The extraction of constant modes for the AMG coarse-grid solver requires a version of deal.II >= 9.6.0"));
-
1350 #endif
-
1351  }
-
1352  else if (this->simulation_parameters.linear_solver
- -
1354  .preconditioner ==
- -
1356  {
-
1357  // Constant modes for velocity and pressure
-
1358  DoFTools::extract_constant_modes(this->dof_handlers[this->minlevel],
-
1359  components,
-
1360  constant_modes);
-
1361  }
-
1362 
-
1363  amg_data.constant_modes = constant_modes;
-
1364 
-
1365  Teuchos::ParameterList parameter_ml;
-
1366  std::unique_ptr<Epetra_MultiVector> distributed_constant_modes;
-
1367  amg_data.set_parameters(parameter_ml,
-
1368  distributed_constant_modes,
-
1369  min_level_matrix);
-
1370 
-
1371  const double ilu_fill =
-
1372  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1373  .amg_precond_ilu_fill;
-
1374  const double ilu_atol =
-
1375  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1376  .amg_precond_ilu_atol;
-
1377  const double ilu_rtol =
-
1378  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1379  .amg_precond_ilu_rtol;
-
1380  parameter_ml.set("smoother: ifpack level-of-fill", ilu_fill);
-
1381  parameter_ml.set("smoother: ifpack absolute threshold", ilu_atol);
-
1382  parameter_ml.set("smoother: ifpack relative threshold", ilu_rtol);
-
1383 
-
1384  parameter_ml.set("coarse: ifpack level-of-fill", ilu_fill);
-
1385  parameter_ml.set("coarse: ifpack absolute threshold", ilu_atol);
-
1386  parameter_ml.set("coarse: ifpack relative threshold", ilu_rtol);
-
1387 
-
1388  this->precondition_amg =
-
1389  std::make_shared<TrilinosWrappers::PreconditionAMG>();
-
1390 
-
1391  this->precondition_amg->initialize(min_level_matrix, parameter_ml);
-
1392  }
-
1393  else
-
1394  {
-
1395  this->precondition_amg =
-
1396  std::make_shared<TrilinosWrappers::PreconditionAMG>();
-
1397 
-
1398  this->precondition_amg->initialize(min_level_matrix, amg_data);
-
1399  }
-
1400 }
-
1401 
-
1402 template <int dim>
-
1403 void
- -
1405 {
-
1406  int current_preconditioner_fill_level =
-
1407  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1408  .ilu_precond_fill;
-
1409  const double ilu_atol =
-
1410  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1411  .ilu_precond_atol;
-
1412  const double ilu_rtol =
-
1413  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1414  .ilu_precond_rtol;
-
1415  TrilinosWrappers::PreconditionILU::AdditionalData preconditionerOptions(
-
1416  current_preconditioner_fill_level, ilu_atol, ilu_rtol, 0);
-
1417 
-
1418  this->precondition_ilu =
-
1419  std::make_shared<TrilinosWrappers::PreconditionILU>();
-
1420 
-
1421  this->precondition_ilu->initialize(
-
1422  this->mg_operators[this->minlevel]->get_system_matrix(),
-
1423  preconditionerOptions);
+
1100  setup_AMG();
+
1101 
+
1102  this->mg_coarse = std::make_shared<
+ +
1104  TrilinosWrappers::PreconditionAMG>>(
+
1105  *this->precondition_amg);
+
1106  }
+
1107  else if (this->simulation_parameters.linear_solver
+ +
1109  .mg_coarse_grid_solver ==
+ +
1111  {
+
1112  setup_ILU();
+
1113 
+
1114  this->mg_coarse = std::make_shared<
+ +
1116  TrilinosWrappers::PreconditionILU>>(
+
1117  *this->precondition_ilu);
+
1118  }
+
1119  else if (this->simulation_parameters.linear_solver
+ +
1121  .mg_coarse_grid_solver ==
+ +
1123  {
+
1124 #if DEAL_II_VERSION_GTE(9, 6, 0)
+
1125  TrilinosWrappers::SolverDirect::AdditionalData data;
+
1126  this->direct_solver_control =
+
1127  std::make_shared<SolverControl>(100, 1.e-10);
+
1128 
+
1129  this->precondition_direct =
+
1130  std::make_shared<TrilinosWrappers::SolverDirect>(
+
1131  *this->direct_solver_control, data);
+
1132 
+
1133  this->precondition_direct->initialize(
+
1134  this->mg_operators[this->minlevel]->get_system_matrix());
+
1135 
+
1136  this->mg_coarse = std::make_shared<
+ +
1138  TrilinosWrappers::SolverDirect>>(
+
1139  *this->precondition_direct);
+
1140 #else
+
1141  AssertThrow(
+
1142  false,
+
1143  ExcMessage(
+
1144  "The usage of a direct solver as coarse grid solver requires a version of deal.II >= 9.6.0"));
+
1145 #endif
+
1146  }
+
1147  else
+
1148  AssertThrow(
+
1149  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1150  .mg_coarse_grid_solver ==
+ +
1152  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1153  .mg_coarse_grid_solver ==
+ +
1155  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1156  .mg_coarse_grid_solver ==
+ +
1158  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1159  .mg_coarse_grid_solver ==
+ +
1161  ExcMessage(
+
1162  "This coarse-grid solver is not supported. Supported options are <gmres|amg|ilu|direct>."));
+
1163 
+
1164  this->mg_setup_timer.leave_subsection("Create coarse-grid solver");
+
1165 
+
1166  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+ +
1168  {
+
1169  // Create interface matrices needed for local smoothing in case of
+
1170  // local refinement
+
1171  this->mg_interface_matrix_in =
+
1172  std::make_shared<mg::Matrix<VectorType>>(this->ls_mg_interface_in);
+
1173 
+
1174  // Create main MG object
+
1175  this->mg = std::make_shared<Multigrid<VectorType>>(*this->mg_matrix,
+
1176  *this->mg_coarse,
+
1177  *this->mg_transfer_ls,
+
1178  *this->mg_smoother,
+
1179  *this->mg_smoother,
+
1180  this->minlevel);
+
1181 
+
1182  if (this->dof_handler.get_triangulation().has_hanging_nodes())
+
1183  this->mg->set_edge_in_matrix(*this->mg_interface_matrix_in);
+
1184 
+
1185  // Create MG preconditioner
+
1186  this->ls_multigrid_preconditioner =
+
1187  std::make_shared<PreconditionMG<dim, VectorType, LSTransferType>>(
+
1188  this->dof_handler, *this->mg, *this->mg_transfer_ls);
+
1189  }
+
1190  else if (this->simulation_parameters.linear_solver
+ +
1192  .preconditioner ==
+ +
1194  {
+
1195  // Create main MG object
+
1196  this->mg = std::make_shared<Multigrid<VectorType>>(*this->mg_matrix,
+
1197  *this->mg_coarse,
+
1198  *this->mg_transfer_gc,
+
1199  *this->mg_smoother,
+
1200  *this->mg_smoother);
+
1201 
+
1202  // Create MG preconditioner
+
1203  this->gc_multigrid_preconditioner =
+
1204  std::make_shared<PreconditionMG<dim, VectorType, GCTransferType>>(
+
1205  this->dof_handler, *this->mg, *this->mg_transfer_gc);
+
1206  }
+
1207 
+
1208  // Print detailed timings of multigrid vmult
+
1209  const auto create_mg_timer_function = [&](const std::string &label) {
+
1210  return [label, this](const bool flag, const unsigned int level) {
+
1211  const std::string label_full =
+
1212  (label == "") ?
+
1213  ("gmg::vmult::level_" + std::to_string(level)) :
+
1214  ("gmg::vmult::level_" + std::to_string(level) + "::" + label);
+
1215 
+
1216  if (flag)
+
1217  this->mg_vmult_timer.enter_subsection(label_full);
+
1218  else
+
1219  this->mg_vmult_timer.leave_subsection(label_full);
+
1220  };
+
1221  };
+
1222 
+
1223  this->mg->connect_pre_smoother_step(
+
1224  create_mg_timer_function("0_pre_smoother_step"));
+
1225  this->mg->connect_residual_step(create_mg_timer_function("1_residual_step"));
+
1226  this->mg->connect_restriction(create_mg_timer_function("2_restriction"));
+
1227  this->mg->connect_coarse_solve(create_mg_timer_function(""));
+
1228  this->mg->connect_prolongation(create_mg_timer_function("3_prolongation"));
+
1229  this->mg->connect_edge_prolongation(
+
1230  create_mg_timer_function("4_edge_prolongation"));
+
1231  this->mg->connect_post_smoother_step(
+
1232  create_mg_timer_function("5_post_smoother_step"));
+
1233 
+
1234 
+
1235  const auto create_mg_precon_timer_function = [&](const std::string &label) {
+
1236  return [label, this](const bool flag) {
+
1237  const std::string label_full = "gmg::vmult::" + label;
+
1238 
+
1239  if (flag)
+
1240  this->mg_vmult_timer.enter_subsection(label_full);
+
1241  else
+
1242  this->mg_vmult_timer.leave_subsection(label_full);
+
1243  };
+
1244  };
+
1245 
+
1246  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+ +
1248  {
+
1249  this->ls_multigrid_preconditioner->connect_transfer_to_mg(
+
1250  create_mg_precon_timer_function("transfer_to_mg"));
+
1251  this->ls_multigrid_preconditioner->connect_transfer_to_global(
+
1252  create_mg_precon_timer_function("transfer_to_global"));
+
1253  }
+
1254  else if (this->simulation_parameters.linear_solver
+ +
1256  .preconditioner ==
+ +
1258  {
+
1259  this->gc_multigrid_preconditioner->connect_transfer_to_mg(
+
1260  create_mg_precon_timer_function("transfer_to_mg"));
+
1261  this->gc_multigrid_preconditioner->connect_transfer_to_global(
+
1262  create_mg_precon_timer_function("transfer_to_global"));
+
1263  }
+
1264 }
+
1265 
+
1266 template <int dim>
+
1267 void
+ +
1269  const VectorType &src) const
+
1270 {
+
1271  if (this->ls_multigrid_preconditioner)
+
1272  this->ls_multigrid_preconditioner->vmult(dst, src);
+
1273  else if (this->gc_multigrid_preconditioner)
+
1274  this->gc_multigrid_preconditioner->vmult(dst, src);
+
1275  else
+
1276  AssertThrow(false, ExcNotImplemented());
+
1277 
+
1278  // Save number of coarse grid iterations needed in one vmult
+
1279  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1280  .mg_coarse_grid_solver ==
+ +
1282  this->coarse_grid_iterations.emplace_back(
+
1283  this->coarse_grid_solver_control->last_step());
+
1284 }
+
1285 
+
1286 template <int dim>
+
1287 void
+ +
1289 {
+
1290  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1291  .mg_coarse_grid_solver ==
+ +
1293  {
+
1294  if (this->coarse_grid_iterations.empty())
+
1295  this->pcout << " -Coarse grid solver took: 0 iterations" << std::endl;
+
1296  else
+
1297  {
+
1298  unsigned int total = this->coarse_grid_iterations[0];
+
1299  this->pcout << " -Coarse grid solver took: "
+
1300  << this->coarse_grid_iterations[0];
+
1301  for (unsigned int i = 1; i < this->coarse_grid_iterations.size(); i++)
+
1302  {
+
1303  this->pcout << " + " << this->coarse_grid_iterations[i];
+
1304  total += this->coarse_grid_iterations[i];
+
1305  }
+
1306  this->pcout << " = " << total << " iterations" << std::endl;
+
1307 
+
1308  this->coarse_grid_iterations.clear();
+
1309  }
+
1310  }
+
1311 }
+
1312 
+
1313 template <int dim>
+
1314 const MGLevelObject<std::shared_ptr<NavierStokesOperatorBase<dim, double>>> &
+ +
1316 {
+
1317  return this->mg_operators;
+
1318 }
+
1319 
+
1320 template <int dim>
+
1321 void
+ +
1323 {
+
1324  TrilinosWrappers::PreconditionAMG::AdditionalData amg_data;
+
1325 
+
1326  // Extract matrix of the minlevel to avoid building it twice
+
1327  const TrilinosWrappers::SparseMatrix &min_level_matrix =
+
1328  this->mg_operators[this->minlevel]->get_system_matrix();
+
1329 
+
1330  if (!this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1331  .mg_amg_use_default_parameters)
+
1332  {
+
1333  amg_data.elliptic = false;
+
1334  if (this->dof_handler.get_fe().degree > 1)
+
1335  amg_data.higher_order_elements = true;
+
1336  amg_data.n_cycles =
+
1337  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1338  .amg_n_cycles;
+
1339  amg_data.w_cycle =
+
1340  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1341  .amg_w_cycles;
+
1342  amg_data.aggregation_threshold =
+
1343  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1344  .amg_aggregation_threshold;
+
1345  amg_data.smoother_sweeps =
+
1346  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1347  .amg_smoother_sweeps;
+
1348  amg_data.smoother_overlap =
+
1349  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1350  .amg_smoother_overlap;
+
1351  amg_data.output_details = false;
+
1352  amg_data.smoother_type = "ILU";
+
1353  amg_data.coarse_type = "ILU";
+
1354 
+
1355  std::vector<std::vector<bool>> constant_modes;
+
1356  ComponentMask components(dim + 1, true);
+
1357  if (this->simulation_parameters.linear_solver
+ +
1359  .preconditioner ==
+ +
1361 
+
1362  {
+
1363 #if DEAL_II_VERSION_GTE(9, 6, 0)
+
1364  // Constant modes for velocity and pressure
+
1365  DoFTools::extract_level_constant_modes(this->minlevel,
+
1366  this->dof_handler,
+
1367  components,
+
1368  constant_modes);
+
1369 #else
+
1370  AssertThrow(
+
1371  false,
+
1372  ExcMessage(
+
1373  "The extraction of constant modes for the AMG coarse-grid solver requires a version of deal.II >= 9.6.0"));
+
1374 #endif
+
1375  }
+
1376  else if (this->simulation_parameters.linear_solver
+ +
1378  .preconditioner ==
+ +
1380  {
+
1381  // Constant modes for velocity and pressure
+
1382  DoFTools::extract_constant_modes(this->dof_handlers[this->minlevel],
+
1383  components,
+
1384  constant_modes);
+
1385  }
+
1386 
+
1387  amg_data.constant_modes = constant_modes;
+
1388 
+
1389  Teuchos::ParameterList parameter_ml;
+
1390  std::unique_ptr<Epetra_MultiVector> distributed_constant_modes;
+
1391  amg_data.set_parameters(parameter_ml,
+
1392  distributed_constant_modes,
+
1393  min_level_matrix);
+
1394 
+
1395  const double ilu_fill =
+
1396  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1397  .amg_precond_ilu_fill;
+
1398  const double ilu_atol =
+
1399  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1400  .amg_precond_ilu_atol;
+
1401  const double ilu_rtol =
+
1402  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1403  .amg_precond_ilu_rtol;
+
1404  parameter_ml.set("smoother: ifpack level-of-fill", ilu_fill);
+
1405  parameter_ml.set("smoother: ifpack absolute threshold", ilu_atol);
+
1406  parameter_ml.set("smoother: ifpack relative threshold", ilu_rtol);
+
1407 
+
1408  parameter_ml.set("coarse: ifpack level-of-fill", ilu_fill);
+
1409  parameter_ml.set("coarse: ifpack absolute threshold", ilu_atol);
+
1410  parameter_ml.set("coarse: ifpack relative threshold", ilu_rtol);
+
1411 
+
1412  this->precondition_amg =
+
1413  std::make_shared<TrilinosWrappers::PreconditionAMG>();
+
1414 
+
1415  this->precondition_amg->initialize(min_level_matrix, parameter_ml);
+
1416  }
+
1417  else
+
1418  {
+
1419  this->precondition_amg =
+
1420  std::make_shared<TrilinosWrappers::PreconditionAMG>();
+
1421 
+
1422  this->precondition_amg->initialize(min_level_matrix, amg_data);
+
1423  }
1424 }
1425 
1426 template <int dim>
- -
1428  SimulationParameters<dim> &nsparam)
-
1429  : NavierStokesBase<dim, VectorType, IndexSet>(nsparam)
-
1430 {
-
1431  AssertThrow(
-
1432  nsparam.fem_parameters.velocity_order ==
- -
1434  dealii::ExcMessage(
-
1435  "Matrix free Navier-Stokes does not support different orders for the velocity and the pressure!"));
-
1436 
-
1437  this->fe = std::make_shared<FESystem<dim>>(
-
1438  FE_Q<dim>(nsparam.fem_parameters.velocity_order), dim + 1);
-
1439 
-
1440  system_operator =
-
1441  std::make_shared<NavierStokesStabilizedOperator<dim, double>>();
-
1442 
-
1443  if (!this->simulation_parameters.source_term.enable)
-
1444  {
-
1445  this->forcing_function.reset();
-
1446  }
-
1447 }
-
1448 
-
1449 template <int dim>
- -
1451 {
-
1452  this->dof_handler.clear();
-
1453 }
-
1454 
-
1455 template <int dim>
-
1456 void
- -
1458 {
-
1459  this->computing_timer.enter_subsection("Read mesh and manifolds");
+
1427 void
+ +
1429 {
+
1430  int current_preconditioner_fill_level =
+
1431  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1432  .ilu_precond_fill;
+
1433  const double ilu_atol =
+
1434  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1435  .ilu_precond_atol;
+
1436  const double ilu_rtol =
+
1437  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1438  .ilu_precond_rtol;
+
1439  TrilinosWrappers::PreconditionILU::AdditionalData preconditionerOptions(
+
1440  current_preconditioner_fill_level, ilu_atol, ilu_rtol, 0);
+
1441 
+
1442  this->precondition_ilu =
+
1443  std::make_shared<TrilinosWrappers::PreconditionILU>();
+
1444 
+
1445  this->precondition_ilu->initialize(
+
1446  this->mg_operators[this->minlevel]->get_system_matrix(),
+
1447  preconditionerOptions);
+
1448 }
+
1449 
+
1450 template <int dim>
+ +
1452  SimulationParameters<dim> &nsparam)
+
1453  : NavierStokesBase<dim, VectorType, IndexSet>(nsparam)
+
1454 {
+
1455  AssertThrow(
+
1456  nsparam.fem_parameters.velocity_order ==
+ +
1458  dealii::ExcMessage(
+
1459  "Matrix free Navier-Stokes does not support different orders for the velocity and the pressure!"));
1460 
- -
1462  *this->triangulation,
-
1463  this->simulation_parameters.mesh,
-
1464  this->simulation_parameters.manifolds_parameters,
-
1465  this->simulation_parameters.restart_parameters.restart,
-
1466  this->simulation_parameters.boundary_conditions);
-
1467 
-
1468  this->computing_timer.leave_subsection("Read mesh and manifolds");
-
1469 
-
1470  this->setup_dofs();
-
1471  this->set_initial_condition(
-
1472  this->simulation_parameters.initial_condition->type,
-
1473  this->simulation_parameters.restart_parameters.restart);
-
1474 
-
1475  // Only needed if other physics apart from fluid dynamics are enabled.
-
1476  if (this->multiphysics->get_active_physics().size() > 1)
-
1477  this->update_multiphysics_time_average_solution();
+
1461  this->fe = std::make_shared<FESystem<dim>>(
+
1462  FE_Q<dim>(nsparam.fem_parameters.velocity_order), dim + 1);
+
1463 
+
1464  system_operator =
+
1465  std::make_shared<NavierStokesStabilizedOperator<dim, double>>();
+
1466 
+
1467  if (!this->simulation_parameters.source_term.enable)
+
1468  {
+
1469  this->forcing_function.reset();
+
1470  }
+
1471 }
+
1472 
+
1473 template <int dim>
+ +
1475 {
+
1476  this->dof_handler.clear();
+
1477 }
1478 
-
1479  while (this->simulation_control->integrate())
-
1480  {
-
1481  if (this->forcing_function)
-
1482  this->forcing_function->set_time(
-
1483  this->simulation_control->get_current_time());
+
1479 template <int dim>
+
1480 void
+ +
1482 {
+
1483  this->computing_timer.enter_subsection("Read mesh and manifolds");
1484 
-
1485  bool refinement_step;
-
1486  if (this->simulation_parameters.mesh_adaptation.refinement_at_frequency)
-
1487  refinement_step =
-
1488  this->simulation_control->get_step_number() %
-
1489  this->simulation_parameters.mesh_adaptation.frequency !=
-
1490  0;
-
1491  else
-
1492  refinement_step = this->simulation_control->get_step_number() == 0;
-
1493  if ((refinement_step ||
-
1494  this->simulation_parameters.mesh_adaptation.type ==
- -
1496  this->simulation_control->is_at_start()) &&
-
1497  this->simulation_parameters.boundary_conditions.time_dependent)
-
1498  {
-
1499  update_boundary_conditions();
-
1500  this->multiphysics->update_boundary_conditions();
-
1501  }
+ +
1486  *this->triangulation,
+
1487  this->simulation_parameters.mesh,
+
1488  this->simulation_parameters.manifolds_parameters,
+
1489  this->simulation_parameters.restart_parameters.restart,
+
1490  this->simulation_parameters.boundary_conditions);
+
1491 
+
1492  this->computing_timer.leave_subsection("Read mesh and manifolds");
+
1493 
+
1494  this->setup_dofs();
+
1495  this->set_initial_condition(
+
1496  this->simulation_parameters.initial_condition->type,
+
1497  this->simulation_parameters.restart_parameters.restart);
+
1498 
+
1499  // Only needed if other physics apart from fluid dynamics are enabled.
+
1500  if (this->multiphysics->get_active_physics().size() > 1)
+
1501  this->update_multiphysics_time_average_solution();
1502 
-
1503  this->simulation_control->print_progression(this->pcout);
-
1504  this->dynamic_flow_control();
-
1505 
-
1506  if (!this->simulation_control->is_at_start())
-
1507  {
- -
1509  }
-
1510 
-
1511  if (is_bdf(this->simulation_control->get_assembly_method()))
-
1512  {
-
1513  this->computing_timer.enter_subsection(
-
1514  "Calculate time derivative previous solutions");
-
1515 
-
1516  calculate_time_derivative_previous_solutions();
-
1517  this->time_derivative_previous_solutions.update_ghost_values();
-
1518  this->system_operator->evaluate_time_derivative_previous_solutions(
-
1519  this->time_derivative_previous_solutions);
-
1520 
-
1521  this->computing_timer.leave_subsection(
-
1522  "Calculate time derivative previous solutions");
-
1523 
-
1524  if (this->simulation_parameters.flow_control.enable_flow_control)
-
1525  this->system_operator->update_beta_force(
-
1526  this->flow_control.get_beta());
-
1527  }
-
1528 
-
1529  // Provide the fluid dynamics dof_handler, present solution and previous
-
1530  // solution to the multiphysics interface only if other physics
-
1531  // apart from fluid dynamics are enabled
-
1532  if (this->multiphysics->get_active_physics().size() > 1)
-
1533  update_solutions_for_multiphysics();
+
1503  while (this->simulation_control->integrate())
+
1504  {
+
1505  if (this->forcing_function)
+
1506  this->forcing_function->set_time(
+
1507  this->simulation_control->get_current_time());
+
1508 
+
1509  bool refinement_step;
+
1510  if (this->simulation_parameters.mesh_adaptation.refinement_at_frequency)
+
1511  refinement_step =
+
1512  this->simulation_control->get_step_number() %
+
1513  this->simulation_parameters.mesh_adaptation.frequency !=
+
1514  0;
+
1515  else
+
1516  refinement_step = this->simulation_control->get_step_number() == 0;
+
1517  if ((refinement_step ||
+
1518  this->simulation_parameters.mesh_adaptation.type ==
+ +
1520  this->simulation_control->is_at_start()) &&
+
1521  this->simulation_parameters.boundary_conditions.time_dependent)
+
1522  {
+
1523  update_boundary_conditions();
+
1524  this->multiphysics->update_boundary_conditions();
+
1525  }
+
1526 
+
1527  this->simulation_control->print_progression(this->pcout);
+
1528  this->dynamic_flow_control();
+
1529 
+
1530  if (!this->simulation_control->is_at_start())
+
1531  {
+ +
1533  }
1534 
-
1535  this->iterate();
-
1536  this->postprocess(false);
-
1537  this->finish_time_step();
-
1538 
-
1539  if (this->simulation_parameters.timer.type ==
- -
1541  print_mg_setup_times();
-
1542  }
-
1543 
-
1544  if (this->simulation_parameters.timer.type == Parameters::Timer::Type::end)
-
1545  print_mg_setup_times();
-
1546 
-
1547  this->finish_simulation();
-
1548 }
-
1549 
-
1550 template <int dim>
-
1551 void
- -
1553 {
-
1554  TimerOutput::Scope t(this->computing_timer, "Setup DoFs");
-
1555 
-
1556  // Clear the preconditioners
-
1557  ilu_preconditioner.reset();
-
1558  gmg_preconditioner.reset();
-
1559 
-
1560  // Clear matrix free operator
-
1561  this->system_operator->clear();
+
1535  if (is_bdf(this->simulation_control->get_assembly_method()))
+
1536  {
+
1537  this->computing_timer.enter_subsection(
+
1538  "Calculate time derivative previous solutions");
+
1539 
+
1540  calculate_time_derivative_previous_solutions();
+
1541  this->time_derivative_previous_solutions.update_ghost_values();
+
1542  this->system_operator->evaluate_time_derivative_previous_solutions(
+
1543  this->time_derivative_previous_solutions);
+
1544 
+
1545  this->computing_timer.leave_subsection(
+
1546  "Calculate time derivative previous solutions");
+
1547 
+
1548  if (this->simulation_parameters.flow_control.enable_flow_control)
+
1549  this->system_operator->update_beta_force(
+
1550  this->flow_control.get_beta());
+
1551  }
+
1552 
+
1553  // Provide the fluid dynamics dof_handler, present solution and previous
+
1554  // solution to the multiphysics interface only if other physics
+
1555  // apart from fluid dynamics are enabled
+
1556  if (this->multiphysics->get_active_physics().size() > 1)
+
1557  update_solutions_for_multiphysics();
+
1558 
+
1559  this->iterate();
+
1560  this->postprocess(false);
+
1561  this->finish_time_step();
1562 
-
1563  // Fill the dof handler and initialize vectors
-
1564  this->dof_handler.distribute_dofs(*this->fe);
-
1565 
-
1566  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
- -
1568  {
-
1569  this->dof_handler.distribute_mg_dofs();
+
1563  if (this->simulation_parameters.timer.type ==
+ +
1565  print_mg_setup_times();
+
1566  }
+
1567 
+
1568  if (this->simulation_parameters.timer.type == Parameters::Timer::Type::end)
+
1569  print_mg_setup_times();
1570 
-
1571  // To use elements with linear interpolation for coarse-grid we need to
-
1572  // have another dof handler with the appropriate element type
-
1573  if (this->simulation_parameters.linear_solver
- -
1575  .mg_use_fe_q_iso_q1)
-
1576  {
-
1577  this->dof_handler_fe_q_iso_q1.reinit(*this->triangulation);
-
1578 
-
1579  const auto points =
-
1580  QGaussLobatto<1>(this->dof_handler.get_fe().degree + 1)
-
1581  .get_points();
-
1582 
-
1583  this->dof_handler_fe_q_iso_q1.distribute_dofs(
-
1584  FESystem<dim>(FE_Q_iso_Q1<dim>(points), dim + 1));
-
1585  this->dof_handler_fe_q_iso_q1.distribute_mg_dofs();
-
1586  }
-
1587  }
-
1588 
-
1589  this->locally_owned_dofs = this->dof_handler.locally_owned_dofs();
-
1590  this->locally_relevant_dofs =
-
1591  DoFTools::extract_locally_relevant_dofs(this->dof_handler);
-
1592 
-
1593  // Non Zero constraints
-
1594  define_non_zero_constraints();
-
1595 
-
1596  // Zero constraints
-
1597  define_zero_constraints();
-
1598 
-
1599  // Initialize matrix-free object
-
1600  unsigned int mg_level = numbers::invalid_unsigned_int;
-
1601  this->system_operator->reinit(
-
1602  *this->mapping,
-
1603  this->dof_handler,
-
1604  this->zero_constraints,
-
1605  *this->cell_quadrature,
-
1606  this->forcing_function,
-
1607  this->simulation_parameters.physical_properties_manager
-
1608  .get_kinematic_viscosity_scale(),
-
1609  this->simulation_parameters.stabilization.stabilization,
-
1610  mg_level,
-
1611  this->simulation_control,
-
1612  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1613  .enable_hessians_jacobian,
-
1614  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
1615  .enable_hessians_residual);
+
1571  this->finish_simulation();
+
1572 }
+
1573 
+
1574 template <int dim>
+
1575 void
+ +
1577 {
+
1578  TimerOutput::Scope t(this->computing_timer, "Setup DoFs");
+
1579 
+
1580  // Clear the preconditioners
+
1581  ilu_preconditioner.reset();
+
1582  gmg_preconditioner.reset();
+
1583 
+
1584  // Clear matrix free operator
+
1585  this->system_operator->clear();
+
1586 
+
1587  // Fill the dof handler and initialize vectors
+
1588  this->dof_handler.distribute_dofs(*this->fe);
+
1589 
+
1590  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+ +
1592  {
+
1593  this->dof_handler.distribute_mg_dofs();
+
1594 
+
1595  // To use elements with linear interpolation for coarse-grid we need to
+
1596  // have another dof handler with the appropriate element type
+
1597  if (this->simulation_parameters.linear_solver
+ +
1599  .mg_use_fe_q_iso_q1)
+
1600  {
+
1601  this->dof_handler_fe_q_iso_q1.reinit(*this->triangulation);
+
1602 
+
1603  const auto points =
+
1604  QGaussLobatto<1>(this->dof_handler.get_fe().degree + 1)
+
1605  .get_points();
+
1606 
+
1607  this->dof_handler_fe_q_iso_q1.distribute_dofs(
+
1608  FESystem<dim>(FE_Q_iso_Q1<dim>(points), dim + 1));
+
1609  this->dof_handler_fe_q_iso_q1.distribute_mg_dofs();
+
1610  }
+
1611  }
+
1612 
+
1613  this->locally_owned_dofs = this->dof_handler.locally_owned_dofs();
+
1614  this->locally_relevant_dofs =
+
1615  DoFTools::extract_locally_relevant_dofs(this->dof_handler);
1616 
-
1617 
-
1618  // Initialize vectors using operator
-
1619  this->system_operator->initialize_dof_vector(this->present_solution);
-
1620  this->system_operator->initialize_dof_vector(this->evaluation_point);
-
1621  this->system_operator->initialize_dof_vector(this->newton_update);
-
1622  this->system_operator->initialize_dof_vector(this->system_rhs);
-
1623  this->system_operator->initialize_dof_vector(this->local_evaluation_point);
-
1624  this->system_operator->initialize_dof_vector(
-
1625  this->time_derivative_previous_solutions);
-
1626 
-
1627  // Initialize vectors of previous solutions
-
1628  for (auto &solution : this->previous_solutions)
-
1629  {
-
1630  this->system_operator->initialize_dof_vector(solution);
-
1631  }
-
1632 
-
1633  if (this->simulation_parameters.post_processing.calculate_average_velocities)
-
1634  {
-
1635  this->average_velocities->initialize_vectors(
-
1636  this->locally_owned_dofs,
-
1637  this->locally_relevant_dofs,
-
1638  this->fe->n_dofs_per_vertex(),
-
1639  this->mpi_communicator);
+
1617  // Non Zero constraints
+
1618  define_non_zero_constraints();
+
1619 
+
1620  // Zero constraints
+
1621  define_zero_constraints();
+
1622 
+
1623  // Initialize matrix-free object
+
1624  unsigned int mg_level = numbers::invalid_unsigned_int;
+
1625  this->system_operator->reinit(
+
1626  *this->mapping,
+
1627  this->dof_handler,
+
1628  this->zero_constraints,
+
1629  *this->cell_quadrature,
+
1630  this->forcing_function,
+
1631  this->simulation_parameters.physical_properties_manager
+
1632  .get_kinematic_viscosity_scale(),
+
1633  this->simulation_parameters.stabilization.stabilization,
+
1634  mg_level,
+
1635  this->simulation_control,
+
1636  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1637  .enable_hessians_jacobian,
+
1638  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
1639  .enable_hessians_residual);
1640 
-
1641  // Intialize Trilinos vectors used to pass average velocities to
-
1642  // multiphysics interface
-
1643  this->multiphysics_average_velocities.reinit(this->locally_owned_dofs,
-
1644  this->locally_relevant_dofs,
-
1645  this->mpi_communicator);
-
1646 
-
1647  if (this->simulation_parameters.restart_parameters.checkpoint)
-
1648  {
-
1649  this->average_velocities->initialize_checkpoint_vectors(
-
1650  this->locally_owned_dofs,
-
1651  this->locally_relevant_dofs,
-
1652  this->mpi_communicator);
-
1653  }
-
1654  }
-
1655 
-
1656  double global_volume =
-
1657  GridTools::volume(*this->triangulation, *this->mapping);
-
1658 
-
1659  this->pcout << " Number of active cells: "
-
1660  << this->triangulation->n_global_active_cells() << std::endl
-
1661  << " Number of degrees of freedom: "
-
1662  << this->dof_handler.n_dofs() << std::endl;
-
1663  this->pcout << " Volume of triangulation: " << global_volume
-
1664  << std::endl;
-
1665 
-
1666  // Initialize Trilinos vectors used to pass solution to multiphysics interface
-
1667  this->multiphysics_present_solution.reinit(this->locally_owned_dofs,
-
1668  this->locally_relevant_dofs,
-
1669  this->mpi_communicator);
+
1641 
+
1642  // Initialize vectors using operator
+
1643  this->system_operator->initialize_dof_vector(this->present_solution);
+
1644  this->system_operator->initialize_dof_vector(this->evaluation_point);
+
1645  this->system_operator->initialize_dof_vector(this->newton_update);
+
1646  this->system_operator->initialize_dof_vector(this->system_rhs);
+
1647  this->system_operator->initialize_dof_vector(this->local_evaluation_point);
+
1648  this->system_operator->initialize_dof_vector(
+
1649  this->time_derivative_previous_solutions);
+
1650 
+
1651  // Initialize vectors of previous solutions
+
1652  for (auto &solution : this->previous_solutions)
+
1653  {
+
1654  this->system_operator->initialize_dof_vector(solution);
+
1655  }
+
1656 
+
1657  if (this->simulation_parameters.post_processing.calculate_average_velocities)
+
1658  {
+
1659  this->average_velocities->initialize_vectors(
+
1660  this->locally_owned_dofs,
+
1661  this->locally_relevant_dofs,
+
1662  this->fe->n_dofs_per_vertex(),
+
1663  this->mpi_communicator);
+
1664 
+
1665  // Intialize Trilinos vectors used to pass average velocities to
+
1666  // multiphysics interface
+
1667  this->multiphysics_average_velocities.reinit(this->locally_owned_dofs,
+
1668  this->locally_relevant_dofs,
+
1669  this->mpi_communicator);
1670 
-
1671  // Pre-allocate memory for the previous solutions using the information
-
1672  // of the BDF schemes
-
1673  this->multiphysics_previous_solutions.resize(
-
1674  this->simulation_control->get_number_of_previous_solution_in_assembly());
-
1675 
-
1676  for (auto &solution : this->multiphysics_previous_solutions)
-
1677  solution.reinit(this->locally_owned_dofs,
-
1678  this->locally_relevant_dofs,
-
1679  this->mpi_communicator);
-
1680 
-
1681  // Provide relevant solution to multiphysics interface only if other physics
-
1682  // apart from fluid dynamics are enabled.
-
1683  if (this->multiphysics->get_active_physics().size() > 1)
-
1684  update_solutions_for_multiphysics();
-
1685 }
-
1686 
-
1687 template <int dim>
-
1688 void
- -
1690 {
-
1691  if (this->simulation_parameters.boundary_conditions.time_dependent)
-
1692  {
-
1693  double time = this->simulation_control->get_current_time();
-
1694  for (unsigned int i_bc = 0;
-
1695  i_bc < this->simulation_parameters.boundary_conditions.size;
-
1696  ++i_bc)
-
1697  {
-
1698  this->simulation_parameters.boundary_conditions.bcFunctions[i_bc]
-
1699  .u.set_time(time);
-
1700  this->simulation_parameters.boundary_conditions.bcFunctions[i_bc]
-
1701  .v.set_time(time);
-
1702  this->simulation_parameters.boundary_conditions.bcFunctions[i_bc]
-
1703  .w.set_time(time);
-
1704  this->simulation_parameters.boundary_conditions
-
1705  .bcPressureFunction[i_bc]
-
1706  .p.set_time(time);
-
1707  }
-
1708  define_non_zero_constraints();
-
1709  // Distribute constraints
-
1710  auto &nonzero_constraints = this->nonzero_constraints;
-
1711  nonzero_constraints.distribute(this->local_evaluation_point);
-
1712  this->present_solution = this->local_evaluation_point;
-
1713  }
-
1714 }
-
1715 
-
1716 template <int dim>
-
1717 void
- -
1719  Parameters::InitialConditionType initial_condition_type,
-
1720  bool restart)
-
1721 {
-
1722  if (this->simulation_parameters.timer.type == Parameters::Timer::Type::end)
-
1723  TimerOutput::Scope t(this->computing_timer, "Set initial conditions");
-
1724 
-
1725  if (restart)
-
1726  {
-
1727  this->pcout << "************************" << std::endl;
-
1728  this->pcout << "---> Simulation Restart " << std::endl;
-
1729  this->pcout << "************************" << std::endl;
-
1730  this->read_checkpoint();
-
1731  }
-
1732  else if (initial_condition_type == Parameters::InitialConditionType::nodal)
-
1733  {
-
1734  this->set_nodal_values();
-
1735  this->present_solution.update_ghost_values();
-
1736  this->finish_time_step();
+
1671  if (this->simulation_parameters.restart_parameters.checkpoint)
+
1672  {
+
1673  this->average_velocities->initialize_checkpoint_vectors(
+
1674  this->locally_owned_dofs,
+
1675  this->locally_relevant_dofs,
+
1676  this->mpi_communicator);
+
1677  }
+
1678  }
+
1679 
+
1680  double global_volume =
+
1681  GridTools::volume(*this->triangulation, *this->mapping);
+
1682 
+
1683  this->pcout << " Number of active cells: "
+
1684  << this->triangulation->n_global_active_cells() << std::endl
+
1685  << " Number of degrees of freedom: "
+
1686  << this->dof_handler.n_dofs() << std::endl;
+
1687  this->pcout << " Volume of triangulation: " << global_volume
+
1688  << std::endl;
+
1689 
+
1690  // Initialize Trilinos vectors used to pass solution to multiphysics interface
+
1691  this->multiphysics_present_solution.reinit(this->locally_owned_dofs,
+
1692  this->locally_relevant_dofs,
+
1693  this->mpi_communicator);
+
1694 
+
1695  // Pre-allocate memory for the previous solutions using the information
+
1696  // of the BDF schemes
+
1697  this->multiphysics_previous_solutions.resize(
+
1698  this->simulation_control->get_number_of_previous_solution_in_assembly());
+
1699 
+
1700  for (auto &solution : this->multiphysics_previous_solutions)
+
1701  solution.reinit(this->locally_owned_dofs,
+
1702  this->locally_relevant_dofs,
+
1703  this->mpi_communicator);
+
1704 
+
1705  // Provide relevant solution to multiphysics interface only if other physics
+
1706  // apart from fluid dynamics are enabled.
+
1707  if (this->multiphysics->get_active_physics().size() > 1)
+
1708  update_solutions_for_multiphysics();
+
1709 }
+
1710 
+
1711 template <int dim>
+
1712 void
+ +
1714 {
+
1715  if (this->simulation_parameters.boundary_conditions.time_dependent)
+
1716  {
+
1717  double time = this->simulation_control->get_current_time();
+
1718  for (unsigned int i_bc = 0;
+
1719  i_bc < this->simulation_parameters.boundary_conditions.size;
+
1720  ++i_bc)
+
1721  {
+
1722  this->simulation_parameters.boundary_conditions.bcFunctions[i_bc]
+
1723  .u.set_time(time);
+
1724  this->simulation_parameters.boundary_conditions.bcFunctions[i_bc]
+
1725  .v.set_time(time);
+
1726  this->simulation_parameters.boundary_conditions.bcFunctions[i_bc]
+
1727  .w.set_time(time);
+
1728  this->simulation_parameters.boundary_conditions
+
1729  .bcPressureFunction[i_bc]
+
1730  .p.set_time(time);
+
1731  }
+
1732  define_non_zero_constraints();
+
1733  // Distribute constraints
+
1734  auto &nonzero_constraints = this->nonzero_constraints;
+
1735  nonzero_constraints.distribute(this->local_evaluation_point);
+
1736  this->present_solution = this->local_evaluation_point;
1737  }
-
1738  else if (initial_condition_type == Parameters::InitialConditionType::viscous)
-
1739  {
-
1740  // Set the nodal values to have an initial condition that is adequate
-
1741  this->set_nodal_values();
-
1742  this->present_solution.update_ghost_values();
-
1743 
-
1744  // Create a pointer to the current viscosity model
-
1745  std::shared_ptr<RheologicalModel> viscosity_model =
-
1746  this->simulation_parameters.physical_properties_manager.get_rheology();
-
1747 
-
1748  // Keep in memory the initial viscosity
-
1749  const double viscosity_end = viscosity_model->get_kinematic_viscosity();
-
1750 
-
1751  // Set it to the initial condition viscosity
-
1752  viscosity_model->set_kinematic_viscosity(
-
1753  this->simulation_parameters.initial_condition->kinematic_viscosity);
-
1754 
-
1755  // Set the kinematic viscosity in the system operator to be the
-
1756  // temporary viscosity
-
1757  this->system_operator->set_kinematic_viscosity(
-
1758  this->simulation_parameters.physical_properties_manager
-
1759  .get_kinematic_viscosity_scale());
-
1760 
-
1761  // Set temporary viscosity in the multigrid operators
-
1762  if ((this->simulation_parameters.linear_solver
- -
1764  .preconditioner ==
- -
1766  (this->simulation_parameters.linear_solver
- -
1768  .preconditioner ==
- -
1770  {
-
1771  // Create the mg operators if they do not exist to be able
-
1772  // to change the viscosity for all of them
-
1773  if (!gmg_preconditioner)
-
1774  gmg_preconditioner =
-
1775  std::make_shared<MFNavierStokesPreconditionGMG<dim>>(
-
1776  this->simulation_parameters,
-
1777  this->dof_handler,
-
1778  this->dof_handler_fe_q_iso_q1,
-
1779  this->mapping,
-
1780  this->cell_quadrature,
-
1781  this->forcing_function,
-
1782  this->simulation_control,
-
1783  this->fe);
-
1784 
-
1785  auto mg_operators = this->gmg_preconditioner->get_mg_operators();
-
1786  for (unsigned int level = mg_operators.min_level();
-
1787  level <= mg_operators.max_level();
-
1788  level++)
-
1789  {
-
1790  mg_operators[level]->set_kinematic_viscosity(
-
1791  this->simulation_parameters.physical_properties_manager
-
1792  .get_kinematic_viscosity_scale());
-
1793  }
-
1794  }
-
1795 
-
1796  // Solve the problem with the temporary viscosity
-
1797  this->simulation_control->set_assembly_method(
- - -
1800  solve_non_linear_system(false);
-
1801  this->finish_time_step();
-
1802 
-
1803  // Set the kinematic viscosity in the system operator to be the original
-
1804  // viscosity
-
1805  viscosity_model->set_kinematic_viscosity(viscosity_end);
-
1806 
-
1807  // Reset kinematic viscosity to simulation parameters
-
1808  viscosity_model->set_kinematic_viscosity(viscosity_end);
-
1809  this->system_operator->set_kinematic_viscosity(viscosity_end);
-
1810 
-
1811  if ((this->simulation_parameters.linear_solver
- -
1813  .preconditioner ==
- -
1815  (this->simulation_parameters.linear_solver
- -
1817  .preconditioner ==
- -
1819  {
-
1820  auto mg_operators = this->gmg_preconditioner->get_mg_operators();
-
1821  for (unsigned int level = mg_operators.min_level();
-
1822  level <= mg_operators.max_level();
-
1823  level++)
-
1824  {
-
1825  mg_operators[level]->set_kinematic_viscosity(viscosity_end);
-
1826  }
-
1827  }
-
1828  }
-
1829  else if (initial_condition_type == Parameters::InitialConditionType::ramp)
-
1830  {
-
1831  this->pcout << "*********************************" << std::endl;
-
1832  this->pcout << " Initial condition using ramp " << std::endl;
-
1833  this->pcout << "*********************************" << std::endl;
-
1834 
-
1835  // Set the nodal values to have an initial condition that is adequate
-
1836  this->set_nodal_values();
-
1837  this->present_solution.update_ghost_values();
-
1838 
-
1839  // Create a pointer to the current viscosity model
-
1840  std::shared_ptr<RheologicalModel> viscosity_model =
-
1841  this->simulation_parameters.physical_properties_manager.get_rheology();
-
1842 
-
1843  // Gather viscosity final parameters
-
1844  const double viscosity_end = viscosity_model->get_kinematic_viscosity();
-
1845 
-
1846  // Kinematic viscosity ramp parameters
-
1847  const int n_iter_viscosity =
-
1848  this->simulation_parameters.initial_condition->ramp.ramp_viscosity
-
1849  .n_iter;
-
1850  double kinematic_viscosity =
-
1851  n_iter_viscosity > 0 ?
-
1852  this->simulation_parameters.initial_condition->ramp.ramp_viscosity
-
1853  .kinematic_viscosity_init :
-
1854  viscosity_end;
-
1855  const double alpha_viscosity =
-
1856  this->simulation_parameters.initial_condition->ramp.ramp_viscosity
-
1857  .alpha;
-
1858 
-
1859  viscosity_model->set_kinematic_viscosity(kinematic_viscosity);
-
1860 
-
1861  // Ramp on kinematic viscosity
-
1862  for (int i = 0; i < n_iter_viscosity; ++i)
-
1863  {
-
1864  this->pcout << std::setprecision(4)
-
1865  << "********* Solution for kinematic viscosity = " +
-
1866  std::to_string(kinematic_viscosity) + " *********"
-
1867  << std::endl;
+
1738 }
+
1739 
+
1740 template <int dim>
+
1741 void
+ +
1743  Parameters::InitialConditionType initial_condition_type,
+
1744  bool restart)
+
1745 {
+
1746  if (restart)
+
1747  {
+
1748  this->pcout << "************************" << std::endl;
+
1749  this->pcout << "---> Simulation Restart " << std::endl;
+
1750  this->pcout << "************************" << std::endl;
+
1751  this->read_checkpoint();
+
1752  }
+
1753  else if (initial_condition_type == Parameters::InitialConditionType::nodal)
+
1754  {
+
1755  this->set_nodal_values();
+
1756  this->present_solution.update_ghost_values();
+
1757  this->finish_time_step();
+
1758  }
+
1759  else if (initial_condition_type == Parameters::InitialConditionType::viscous)
+
1760  {
+
1761  // Set the nodal values to have an initial condition that is adequate
+
1762  this->set_nodal_values();
+
1763  this->present_solution.update_ghost_values();
+
1764 
+
1765  // Create a pointer to the current viscosity model
+
1766  std::shared_ptr<RheologicalModel> viscosity_model =
+
1767  this->simulation_parameters.physical_properties_manager.get_rheology();
+
1768 
+
1769  // Keep in memory the initial viscosity
+
1770  const double viscosity_end = viscosity_model->get_kinematic_viscosity();
+
1771 
+
1772  // Set it to the initial condition viscosity
+
1773  viscosity_model->set_kinematic_viscosity(
+
1774  this->simulation_parameters.initial_condition->kinematic_viscosity);
+
1775 
+
1776  // Set the kinematic viscosity in the system operator to be the
+
1777  // temporary viscosity
+
1778  this->system_operator->set_kinematic_viscosity(
+
1779  this->simulation_parameters.physical_properties_manager
+
1780  .get_kinematic_viscosity_scale());
+
1781 
+
1782  // Set temporary viscosity in the multigrid operators
+
1783  if ((this->simulation_parameters.linear_solver
+ +
1785  .preconditioner ==
+ +
1787  (this->simulation_parameters.linear_solver
+ +
1789  .preconditioner ==
+ +
1791  {
+
1792  // Create the mg operators if they do not exist to be able
+
1793  // to change the viscosity for all of them
+
1794  if (!gmg_preconditioner)
+
1795  gmg_preconditioner =
+
1796  std::make_shared<MFNavierStokesPreconditionGMG<dim>>(
+
1797  this->simulation_parameters,
+
1798  this->dof_handler,
+
1799  this->dof_handler_fe_q_iso_q1,
+
1800  this->mapping,
+
1801  this->cell_quadrature,
+
1802  this->forcing_function,
+
1803  this->simulation_control,
+
1804  this->fe);
+
1805 
+
1806  auto mg_operators = this->gmg_preconditioner->get_mg_operators();
+
1807  for (unsigned int level = mg_operators.min_level();
+
1808  level <= mg_operators.max_level();
+
1809  level++)
+
1810  {
+
1811  mg_operators[level]->set_kinematic_viscosity(
+
1812  this->simulation_parameters.physical_properties_manager
+
1813  .get_kinematic_viscosity_scale());
+
1814  }
+
1815  }
+
1816 
+
1817  // Solve the problem with the temporary viscosity
+
1818  this->simulation_control->set_assembly_method(
+ + +
1821  solve_non_linear_system(false);
+
1822  this->finish_time_step();
+
1823 
+
1824  // Set the kinematic viscosity in the system operator to be the original
+
1825  // viscosity
+
1826  viscosity_model->set_kinematic_viscosity(viscosity_end);
+
1827 
+
1828  // Reset kinematic viscosity to simulation parameters
+
1829  viscosity_model->set_kinematic_viscosity(viscosity_end);
+
1830  this->system_operator->set_kinematic_viscosity(viscosity_end);
+
1831 
+
1832  if ((this->simulation_parameters.linear_solver
+ +
1834  .preconditioner ==
+ +
1836  (this->simulation_parameters.linear_solver
+ +
1838  .preconditioner ==
+ +
1840  {
+
1841  auto mg_operators = this->gmg_preconditioner->get_mg_operators();
+
1842  for (unsigned int level = mg_operators.min_level();
+
1843  level <= mg_operators.max_level();
+
1844  level++)
+
1845  {
+
1846  mg_operators[level]->set_kinematic_viscosity(viscosity_end);
+
1847  }
+
1848  }
+
1849  }
+
1850  else if (initial_condition_type == Parameters::InitialConditionType::ramp)
+
1851  {
+
1852  this->pcout << "*********************************" << std::endl;
+
1853  this->pcout << " Initial condition using ramp " << std::endl;
+
1854  this->pcout << "*********************************" << std::endl;
+
1855 
+
1856  Timer timer(this->mpi_communicator);
+
1857 
+
1858  // Set the nodal values to have an initial condition that is adequate
+
1859  this->set_nodal_values();
+
1860  this->present_solution.update_ghost_values();
+
1861 
+
1862  // Create a pointer to the current viscosity model
+
1863  std::shared_ptr<RheologicalModel> viscosity_model =
+
1864  this->simulation_parameters.physical_properties_manager.get_rheology();
+
1865 
+
1866  // Gather viscosity final parameters
+
1867  const double viscosity_end = viscosity_model->get_kinematic_viscosity();
1868 
-
1869  viscosity_model->set_kinematic_viscosity(kinematic_viscosity);
-
1870 
-
1871  // Set the kinematic viscosity in the system operator to be the
-
1872  // temporary viscosity
-
1873  this->system_operator->set_kinematic_viscosity(
-
1874  this->simulation_parameters.physical_properties_manager
-
1875  .get_kinematic_viscosity_scale());
-
1876 
-
1877  // Set temporary viscosity in the multigrid operators
-
1878  if ((this->simulation_parameters.linear_solver
- -
1880  .preconditioner ==
- -
1882  (this->simulation_parameters.linear_solver
- -
1884  .preconditioner ==
- -
1886  {
-
1887  // Create the mg operators if they do not exist to be able
-
1888  // to change the viscosity for all of them
-
1889  if (!gmg_preconditioner)
-
1890  gmg_preconditioner =
-
1891  std::make_shared<MFNavierStokesPreconditionGMG<dim>>(
-
1892  this->simulation_parameters,
-
1893  this->dof_handler,
-
1894  this->dof_handler_fe_q_iso_q1,
-
1895  this->mapping,
-
1896  this->cell_quadrature,
-
1897  this->forcing_function,
-
1898  this->simulation_control,
-
1899  this->fe);
-
1900 
-
1901  auto mg_operators = this->gmg_preconditioner->get_mg_operators();
-
1902  for (unsigned int level = mg_operators.min_level();
-
1903  level <= mg_operators.max_level();
-
1904  level++)
-
1905  {
-
1906  mg_operators[level]->set_kinematic_viscosity(
-
1907  this->simulation_parameters.physical_properties_manager
-
1908  .get_kinematic_viscosity_scale());
-
1909  }
-
1910  }
-
1911 
-
1912  this->simulation_control->set_assembly_method(
- -
1914  // Solve the problem with the temporary viscosity
- -
1916  solve_non_linear_system(false);
-
1917  this->finish_time_step();
-
1918 
-
1919  kinematic_viscosity +=
-
1920  alpha_viscosity * (viscosity_end - kinematic_viscosity);
-
1921  }
-
1922  // Reset kinematic viscosity to simulation parameters
-
1923  viscosity_model->set_kinematic_viscosity(viscosity_end);
-
1924  this->system_operator->set_kinematic_viscosity(viscosity_end);
-
1925 
-
1926  if ((this->simulation_parameters.linear_solver
- -
1928  .preconditioner ==
- -
1930  (this->simulation_parameters.linear_solver
- -
1932  .preconditioner ==
- -
1934  {
-
1935  auto mg_operators = this->gmg_preconditioner->get_mg_operators();
-
1936  for (unsigned int level = mg_operators.min_level();
-
1937  level <= mg_operators.max_level();
-
1938  level++)
-
1939  {
-
1940  mg_operators[level]->set_kinematic_viscosity(viscosity_end);
-
1941  }
-
1942  }
-
1943  }
-
1944  else
-
1945  {
-
1946  throw std::runtime_error(
-
1947  "Type of initial condition is not supported by MF Navier-Stokes");
-
1948  }
-
1949 }
-
1950 
-
1951 template <int dim>
-
1952 void
- -
1954 {
-
1955  // Required for compilation but not used for matrix free solvers.
-
1956  TimerOutput::Scope t(this->computing_timer, "Assemble matrix");
-
1957 }
-
1958 
-
1959 template <int dim>
-
1960 void
- -
1962 {
-
1963  TimerOutput::Scope t(this->computing_timer, "Assemble RHS");
-
1964 
-
1965  this->system_operator->evaluate_residual(this->system_rhs,
-
1966  this->evaluation_point);
-
1967 
-
1968  this->system_rhs *= -1.0;
-
1969 
-
1970  // Provide residual to simulation control for stopping criterion when using
-
1971  // steady bdf
-
1972  if (this->simulation_control->is_first_assembly())
-
1973  this->simulation_control->provide_residual(this->system_rhs.l2_norm());
-
1974 }
-
1975 
-
1976 template <int dim>
-
1977 void
- -
1979 {
-
1980  TimerOutput::Scope t(this->computing_timer,
-
1981  "Update multiphysics average solution");
-
1982 
-
1983  if (this->simulation_parameters.post_processing.calculate_average_velocities)
-
1984  {
-
1985  TrilinosWrappers::MPI::Vector temp_average_velocities(
-
1986  this->locally_owned_dofs, this->mpi_communicator);
- -
1988  temp_average_velocities,
-
1989  this->average_velocities->get_average_velocities());
-
1990  this->multiphysics_average_velocities = temp_average_velocities;
-
1991 
-
1992  this->multiphysics->set_time_average_solution(
-
1993  PhysicsID::fluid_dynamics, &this->multiphysics_average_velocities);
-
1994  }
-
1995 }
-
1996 
-
1997 template <int dim>
-
1998 void
- -
2000 {
-
2001  this->time_derivative_previous_solutions = 0;
-
2002 
-
2003  // Time stepping information
-
2004  const auto method = this->simulation_control->get_assembly_method();
-
2005  // Vector for the BDF coefficients
-
2006  const Vector<double> &bdf_coefs =
-
2007  this->simulation_control->get_bdf_coefficients();
-
2008 
-
2009  for (unsigned int p = 0; p < number_of_previous_solutions(method); ++p)
-
2010  {
-
2011  this->time_derivative_previous_solutions.add(bdf_coefs[p + 1],
-
2012  this->previous_solutions[p]);
-
2013  }
-
2014 }
-
2015 
-
2016 template <int dim>
-
2017 void
- -
2019 {
-
2020  TimerOutput::Scope t(this->computing_timer, "Setup GMG");
-
2021 
-
2022  if (!gmg_preconditioner)
-
2023  gmg_preconditioner = std::make_shared<MFNavierStokesPreconditionGMG<dim>>(
-
2024  this->simulation_parameters,
-
2025  this->dof_handler,
-
2026  this->dof_handler_fe_q_iso_q1,
-
2027  this->mapping,
-
2028  this->cell_quadrature,
-
2029  this->forcing_function,
-
2030  this->simulation_control,
-
2031  this->fe);
-
2032 
-
2033  gmg_preconditioner->initialize(this->simulation_control,
-
2034  this->flow_control,
-
2035  this->present_solution,
-
2036  this->time_derivative_previous_solutions);
-
2037 }
-
2038 
-
2039 template <int dim>
-
2040 void
- -
2042 {
-
2043  TimerOutput::Scope t(this->computing_timer, "Setup ILU");
-
2044 
-
2045  int current_preconditioner_fill_level =
-
2046  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
2047  .ilu_precond_fill;
-
2048  const double ilu_atol =
-
2049  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
2050  .ilu_precond_atol;
-
2051  const double ilu_rtol =
-
2052  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
2053  .ilu_precond_rtol;
-
2054  TrilinosWrappers::PreconditionILU::AdditionalData preconditionerOptions(
-
2055  current_preconditioner_fill_level, ilu_atol, ilu_rtol, 0);
-
2056 
-
2057  ilu_preconditioner = std::make_shared<TrilinosWrappers::PreconditionILU>();
-
2058 
-
2059  ilu_preconditioner->initialize(system_operator->get_system_matrix(),
-
2060  preconditionerOptions);
-
2061 }
-
2062 
-
2063 
-
2064 template <int dim>
-
2065 void
- -
2067 {
-
2068  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
2069  .mg_verbosity == Parameters::Verbosity::extra_verbose)
-
2070  {
-
2071  announce_string(this->pcout, "Multigrid setup times");
-
2072  this->gmg_preconditioner->mg_setup_timer.print_wall_time_statistics(
-
2073  MPI_COMM_WORLD);
-
2074 
-
2075  announce_string(this->pcout, "Multigrid vmult times");
-
2076  this->gmg_preconditioner->mg_vmult_timer.print_wall_time_statistics(
-
2077  MPI_COMM_WORLD);
+
1869  // Kinematic viscosity ramp parameters
+
1870  const int n_iter_viscosity =
+
1871  this->simulation_parameters.initial_condition->ramp.ramp_viscosity
+
1872  .n_iter;
+
1873  double kinematic_viscosity =
+
1874  n_iter_viscosity > 0 ?
+
1875  this->simulation_parameters.initial_condition->ramp.ramp_viscosity
+
1876  .kinematic_viscosity_init :
+
1877  viscosity_end;
+
1878  const double alpha_viscosity =
+
1879  this->simulation_parameters.initial_condition->ramp.ramp_viscosity
+
1880  .alpha;
+
1881 
+
1882  viscosity_model->set_kinematic_viscosity(kinematic_viscosity);
+
1883 
+
1884  // Ramp on kinematic viscosity
+
1885  for (int i = 0; i < n_iter_viscosity; ++i)
+
1886  {
+
1887  this->pcout << std::setprecision(4)
+
1888  << "********* Solution for kinematic viscosity = " +
+
1889  std::to_string(kinematic_viscosity) + " *********"
+
1890  << std::endl;
+
1891 
+
1892  viscosity_model->set_kinematic_viscosity(kinematic_viscosity);
+
1893 
+
1894  // Set the kinematic viscosity in the system operator to be the
+
1895  // temporary viscosity
+
1896  this->system_operator->set_kinematic_viscosity(
+
1897  this->simulation_parameters.physical_properties_manager
+
1898  .get_kinematic_viscosity_scale());
+
1899 
+
1900  // Set temporary viscosity in the multigrid operators
+
1901  if ((this->simulation_parameters.linear_solver
+ +
1903  .preconditioner ==
+ +
1905  (this->simulation_parameters.linear_solver
+ +
1907  .preconditioner ==
+ +
1909  {
+
1910  // Create the mg operators if they do not exist to be able
+
1911  // to change the viscosity for all of them
+
1912  if (!gmg_preconditioner)
+
1913  gmg_preconditioner =
+
1914  std::make_shared<MFNavierStokesPreconditionGMG<dim>>(
+
1915  this->simulation_parameters,
+
1916  this->dof_handler,
+
1917  this->dof_handler_fe_q_iso_q1,
+
1918  this->mapping,
+
1919  this->cell_quadrature,
+
1920  this->forcing_function,
+
1921  this->simulation_control,
+
1922  this->fe);
+
1923 
+
1924  auto mg_operators = this->gmg_preconditioner->get_mg_operators();
+
1925  for (unsigned int level = mg_operators.min_level();
+
1926  level <= mg_operators.max_level();
+
1927  level++)
+
1928  {
+
1929  mg_operators[level]->set_kinematic_viscosity(
+
1930  this->simulation_parameters.physical_properties_manager
+
1931  .get_kinematic_viscosity_scale());
+
1932  }
+
1933  }
+
1934 
+
1935  this->simulation_control->set_assembly_method(
+ +
1937  // Solve the problem with the temporary viscosity
+ +
1939  solve_non_linear_system(false);
+
1940  this->finish_time_step();
+
1941 
+
1942  kinematic_viscosity +=
+
1943  alpha_viscosity * (viscosity_end - kinematic_viscosity);
+
1944  }
+
1945  // Reset kinematic viscosity to simulation parameters
+
1946  viscosity_model->set_kinematic_viscosity(viscosity_end);
+
1947  this->system_operator->set_kinematic_viscosity(viscosity_end);
+
1948 
+
1949  if ((this->simulation_parameters.linear_solver
+ +
1951  .preconditioner ==
+ +
1953  (this->simulation_parameters.linear_solver
+ +
1955  .preconditioner ==
+ +
1957  {
+
1958  auto mg_operators = this->gmg_preconditioner->get_mg_operators();
+
1959  for (unsigned int level = mg_operators.min_level();
+
1960  level <= mg_operators.max_level();
+
1961  level++)
+
1962  {
+
1963  mg_operators[level]->set_kinematic_viscosity(viscosity_end);
+
1964  }
+
1965  }
+
1966 
+
1967  timer.stop();
+
1968 
+
1969  if (this->simulation_parameters.timer.type !=
+ +
1971  {
+
1972  this->pcout << "*********************************" << std::endl;
+
1973  this->pcout << " Time spent in ramp: " << timer.wall_time() << "s"
+
1974  << std::endl;
+
1975  this->pcout << "*********************************" << std::endl;
+
1976  }
+
1977  }
+
1978  else
+
1979  {
+
1980  throw std::runtime_error(
+
1981  "Type of initial condition is not supported by MF Navier-Stokes");
+
1982  }
+
1983 }
+
1984 
+
1985 template <int dim>
+
1986 void
+ +
1988 {
+
1989  // Required for compilation but not used for matrix free solvers.
+
1990  TimerOutput::Scope t(this->computing_timer, "Assemble matrix");
+
1991 }
+
1992 
+
1993 template <int dim>
+
1994 void
+ +
1996 {
+
1997  TimerOutput::Scope t(this->computing_timer, "Assemble RHS");
+
1998 
+
1999  this->system_operator->evaluate_residual(this->system_rhs,
+
2000  this->evaluation_point);
+
2001 
+
2002  this->system_rhs *= -1.0;
+
2003 
+
2004  // Provide residual to simulation control for stopping criterion when using
+
2005  // steady bdf
+
2006  if (this->simulation_control->is_first_assembly())
+
2007  this->simulation_control->provide_residual(this->system_rhs.l2_norm());
+
2008 }
+
2009 
+
2010 template <int dim>
+
2011 void
+ +
2013 {
+
2014  TimerOutput::Scope t(this->computing_timer,
+
2015  "Update multiphysics average solution");
+
2016 
+
2017  if (this->simulation_parameters.post_processing.calculate_average_velocities)
+
2018  {
+
2019  TrilinosWrappers::MPI::Vector temp_average_velocities(
+
2020  this->locally_owned_dofs, this->mpi_communicator);
+ +
2022  temp_average_velocities,
+
2023  this->average_velocities->get_average_velocities());
+
2024  this->multiphysics_average_velocities = temp_average_velocities;
+
2025 
+
2026  this->multiphysics->set_time_average_solution(
+
2027  PhysicsID::fluid_dynamics, &this->multiphysics_average_velocities);
+
2028  }
+
2029 }
+
2030 
+
2031 template <int dim>
+
2032 void
+ +
2034 {
+
2035  this->time_derivative_previous_solutions = 0;
+
2036 
+
2037  // Time stepping information
+
2038  const auto method = this->simulation_control->get_assembly_method();
+
2039  // Vector for the BDF coefficients
+
2040  const Vector<double> &bdf_coefs =
+
2041  this->simulation_control->get_bdf_coefficients();
+
2042 
+
2043  for (unsigned int p = 0; p < number_of_previous_solutions(method); ++p)
+
2044  {
+
2045  this->time_derivative_previous_solutions.add(bdf_coefs[p + 1],
+
2046  this->previous_solutions[p]);
+
2047  }
+
2048 }
+
2049 
+
2050 template <int dim>
+
2051 void
+ +
2053 {
+
2054  TimerOutput::Scope t(this->computing_timer, "Setup GMG");
+
2055 
+
2056  if (!gmg_preconditioner)
+
2057  gmg_preconditioner = std::make_shared<MFNavierStokesPreconditionGMG<dim>>(
+
2058  this->simulation_parameters,
+
2059  this->dof_handler,
+
2060  this->dof_handler_fe_q_iso_q1,
+
2061  this->mapping,
+
2062  this->cell_quadrature,
+
2063  this->forcing_function,
+
2064  this->simulation_control,
+
2065  this->fe);
+
2066 
+
2067  gmg_preconditioner->initialize(this->simulation_control,
+
2068  this->flow_control,
+
2069  this->present_solution,
+
2070  this->time_derivative_previous_solutions);
+
2071 }
+
2072 
+
2073 template <int dim>
+
2074 void
+ +
2076 {
+
2077  TimerOutput::Scope t(this->computing_timer, "Setup ILU");
2078 
-
2079  announce_string(this->pcout, "System operator times");
-
2080  this->system_operator->timer.print_wall_time_statistics(MPI_COMM_WORLD);
-
2081 
-
2082  auto mg_operators = this->gmg_preconditioner->get_mg_operators();
-
2083  for (unsigned int level = mg_operators.min_level();
-
2084  level <= mg_operators.max_level();
-
2085  level++)
-
2086  {
-
2087  announce_string(this->pcout,
-
2088  "Operator level " + std::to_string(level) + " times");
-
2089  mg_operators[level]->timer.print_wall_time_statistics(MPI_COMM_WORLD);
+
2079  int current_preconditioner_fill_level =
+
2080  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
2081  .ilu_precond_fill;
+
2082  const double ilu_atol =
+
2083  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
2084  .ilu_precond_atol;
+
2085  const double ilu_rtol =
+
2086  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
2087  .ilu_precond_rtol;
+
2088  TrilinosWrappers::PreconditionILU::AdditionalData preconditionerOptions(
+
2089  current_preconditioner_fill_level, ilu_atol, ilu_rtol, 0);
2090 
-
2091  // Reset timer if output is set to every iteration
-
2092  mg_operators[level]->timer.reset();
-
2093  }
-
2094 
-
2095  // Reset timers if output is set to every iteration
-
2096  this->gmg_preconditioner->mg_setup_timer.reset();
-
2097  this->gmg_preconditioner->mg_vmult_timer.reset();
-
2098  }
-
2099 }
-
2100 
-
2101 template <int dim>
-
2102 void
- -
2104 {
-
2105  TimerOutput::Scope t(this->computing_timer,
-
2106  "Update solutions for multiphysics");
-
2107 
-
2108  // Provide the fluid dynamics dof_handler to the multiphysics interface
-
2109  this->multiphysics->set_dof_handler(PhysicsID::fluid_dynamics,
-
2110  &this->dof_handler);
-
2111 
+
2091  ilu_preconditioner = std::make_shared<TrilinosWrappers::PreconditionILU>();
+
2092 
+
2093  ilu_preconditioner->initialize(system_operator->get_system_matrix(),
+
2094  preconditionerOptions);
+
2095 }
+
2096 
+
2097 
+
2098 template <int dim>
+
2099 void
+ +
2101 {
+
2102  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
2103  .mg_verbosity == Parameters::Verbosity::extra_verbose)
+
2104  {
+
2105  announce_string(this->pcout, "Multigrid setup times");
+
2106  this->gmg_preconditioner->mg_setup_timer.print_wall_time_statistics(
+
2107  MPI_COMM_WORLD);
+
2108 
+
2109  announce_string(this->pcout, "Multigrid vmult times");
+
2110  this->gmg_preconditioner->mg_vmult_timer.print_wall_time_statistics(
+
2111  MPI_COMM_WORLD);
2112 
-
2113 
-
2114  // Convert the present solution to multiphysics vector type and provide it to
-
2115  // the multiphysics interface
-
2116  TrilinosWrappers::MPI::Vector temp_solution(this->locally_owned_dofs,
-
2117  this->mpi_communicator);
-
2118 
-
2119  this->present_solution.update_ghost_values();
-
2120  convert_vector_dealii_to_trilinos(temp_solution, this->present_solution);
-
2121  multiphysics_present_solution = temp_solution;
-
2122 
-
2123  this->multiphysics->set_solution(PhysicsID::fluid_dynamics,
-
2124  &this->multiphysics_present_solution);
-
2125 
-
2126  // Convert the previous solutions to multiphysics vector type and provide them
-
2127  // to the multiphysics interface
-
2128  const unsigned int number_of_previous_solutions =
-
2129  this->simulation_control->get_number_of_previous_solution_in_assembly();
-
2130 
-
2131  std::vector<TrilinosWrappers::MPI::Vector> temp_previous_solutions;
-
2132 
-
2133  temp_previous_solutions.resize(number_of_previous_solutions);
-
2134  for (auto &solution : temp_previous_solutions)
-
2135  solution.reinit(this->locally_owned_dofs, this->mpi_communicator);
-
2136 
-
2137  for (unsigned int i = 0; i < number_of_previous_solutions; i++)
-
2138  {
-
2139  this->previous_solutions[i].update_ghost_values();
-
2140  convert_vector_dealii_to_trilinos(temp_previous_solutions[i],
-
2141  this->previous_solutions[i]);
-
2142 
-
2143  this->multiphysics_previous_solutions[i] = temp_previous_solutions[i];
-
2144  }
+
2113  announce_string(this->pcout, "System operator times");
+
2114  this->system_operator->timer.print_wall_time_statistics(MPI_COMM_WORLD);
+
2115 
+
2116  auto mg_operators = this->gmg_preconditioner->get_mg_operators();
+
2117  for (unsigned int level = mg_operators.min_level();
+
2118  level <= mg_operators.max_level();
+
2119  level++)
+
2120  {
+
2121  announce_string(this->pcout,
+
2122  "Operator level " + std::to_string(level) + " times");
+
2123  mg_operators[level]->timer.print_wall_time_statistics(MPI_COMM_WORLD);
+
2124 
+
2125  // Reset timer if output is set to every iteration
+
2126  mg_operators[level]->timer.reset();
+
2127  }
+
2128 
+
2129  // Reset timers if output is set to every iteration
+
2130  this->gmg_preconditioner->mg_setup_timer.reset();
+
2131  this->gmg_preconditioner->mg_vmult_timer.reset();
+
2132  }
+
2133 }
+
2134 
+
2135 template <int dim>
+
2136 void
+ +
2138 {
+
2139  TimerOutput::Scope t(this->computing_timer,
+
2140  "Update solutions for multiphysics");
+
2141 
+
2142  // Provide the fluid dynamics dof_handler to the multiphysics interface
+
2143  this->multiphysics->set_dof_handler(PhysicsID::fluid_dynamics,
+
2144  &this->dof_handler);
2145 
-
2146  this->multiphysics->set_previous_solutions(
-
2147  PhysicsID::fluid_dynamics, &this->multiphysics_previous_solutions);
-
2148 }
-
2149 
-
2150 template <int dim>
-
2151 void
- -
2153 {
-
2154  double time = this->simulation_control->get_current_time();
-
2155  FEValuesExtractors::Vector velocities(0);
-
2156  FEValuesExtractors::Scalar pressure(dim);
-
2157  // Non-zero constraints
-
2158  auto &nonzero_constraints = this->get_nonzero_constraints();
-
2159  {
-
2160  nonzero_constraints.clear();
-
2161  nonzero_constraints.reinit(this->locally_relevant_dofs);
-
2162 
-
2163  DoFTools::make_hanging_node_constraints(this->dof_handler,
-
2164  nonzero_constraints);
-
2165  for (unsigned int i_bc = 0;
-
2166  i_bc < this->simulation_parameters.boundary_conditions.size;
-
2167  ++i_bc)
-
2168  {
-
2169  if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
- -
2171  {
-
2172  VectorTools::interpolate_boundary_values(
-
2173  *this->mapping,
-
2174  this->dof_handler,
-
2175  this->simulation_parameters.boundary_conditions.id[i_bc],
-
2176  dealii::Functions::ZeroFunction<dim>(dim + 1),
-
2177  nonzero_constraints,
-
2178  this->fe->component_mask(velocities));
-
2179  }
-
2180  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
- -
2182  {
-
2183  std::set<types::boundary_id> no_normal_flux_boundaries;
-
2184  no_normal_flux_boundaries.insert(
-
2185  this->simulation_parameters.boundary_conditions.id[i_bc]);
-
2186  VectorTools::compute_no_normal_flux_constraints(
-
2187  this->dof_handler,
-
2188  0,
-
2189  no_normal_flux_boundaries,
-
2190  nonzero_constraints,
-
2191  *this->mapping);
-
2192  }
-
2193  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
- -
2195  {
-
2196  this->simulation_parameters.boundary_conditions.bcFunctions[i_bc]
-
2197  .u.set_time(time);
-
2198  this->simulation_parameters.boundary_conditions.bcFunctions[i_bc]
-
2199  .v.set_time(time);
-
2200  this->simulation_parameters.boundary_conditions.bcFunctions[i_bc]
-
2201  .w.set_time(time);
-
2202  VectorTools::interpolate_boundary_values(
-
2203  *this->mapping,
-
2204  this->dof_handler,
-
2205  this->simulation_parameters.boundary_conditions.id[i_bc],
- -
2207  &this->simulation_parameters.boundary_conditions
-
2208  .bcFunctions[i_bc]
-
2209  .u,
-
2210  &this->simulation_parameters.boundary_conditions
-
2211  .bcFunctions[i_bc]
-
2212  .v,
-
2213  &this->simulation_parameters.boundary_conditions
-
2214  .bcFunctions[i_bc]
-
2215  .w),
-
2216  nonzero_constraints,
-
2217  this->fe->component_mask(velocities));
-
2218  }
-
2219  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
- -
2221  {
-
2222  DoFTools::make_periodicity_constraints(
-
2223  this->dof_handler,
-
2224  this->simulation_parameters.boundary_conditions.id[i_bc],
-
2225  this->simulation_parameters.boundary_conditions.periodic_id[i_bc],
-
2226  this->simulation_parameters.boundary_conditions
-
2227  .periodic_direction[i_bc],
-
2228  nonzero_constraints);
-
2229  }
-
2230  }
-
2231  }
-
2232 
-
2233 
-
2234 
-
2235  this->establish_solid_domain(true);
-
2236 
-
2237  nonzero_constraints.close();
-
2238 }
-
2239 
-
2240 template <int dim>
-
2241 void
- -
2243 {
-
2244  FEValuesExtractors::Vector velocities(0);
-
2245  FEValuesExtractors::Scalar pressure(dim);
-
2246  this->zero_constraints.clear();
-
2247  this->locally_relevant_dofs =
-
2248  DoFTools::extract_locally_relevant_dofs(this->dof_handler);
-
2249  this->zero_constraints.reinit(this->locally_relevant_dofs);
-
2250 
-
2251  DoFTools::make_hanging_node_constraints(this->dof_handler,
-
2252  this->zero_constraints);
-
2253 
-
2254  for (unsigned int i_bc = 0;
-
2255  i_bc < this->simulation_parameters.boundary_conditions.size;
-
2256  ++i_bc)
-
2257  {
-
2258  if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
- -
2260  {
-
2261  std::set<types::boundary_id> no_normal_flux_boundaries;
-
2262  no_normal_flux_boundaries.insert(
-
2263  this->simulation_parameters.boundary_conditions.id[i_bc]);
-
2264  VectorTools::compute_no_normal_flux_constraints(
-
2265  this->dof_handler,
-
2266  0,
-
2267  no_normal_flux_boundaries,
-
2268  this->zero_constraints,
-
2269  *this->mapping);
-
2270  }
-
2271  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
- -
2273  {
-
2274  DoFTools::make_periodicity_constraints(
-
2275  this->dof_handler,
-
2276  this->simulation_parameters.boundary_conditions.id[i_bc],
-
2277  this->simulation_parameters.boundary_conditions.periodic_id[i_bc],
-
2278  this->simulation_parameters.boundary_conditions
-
2279  .periodic_direction[i_bc],
-
2280  this->zero_constraints);
-
2281  }
-
2282  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
- -
2284  {
-
2285  /*do nothing*/
-
2286  }
-
2287  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
- -
2289  {
-
2290  /*do nothing*/
-
2291  }
-
2292  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
- +
2146 
+
2147 
+
2148  // Convert the present solution to multiphysics vector type and provide it to
+
2149  // the multiphysics interface
+
2150  TrilinosWrappers::MPI::Vector temp_solution(this->locally_owned_dofs,
+
2151  this->mpi_communicator);
+
2152 
+
2153  this->present_solution.update_ghost_values();
+
2154  convert_vector_dealii_to_trilinos(temp_solution, this->present_solution);
+
2155  multiphysics_present_solution = temp_solution;
+
2156 
+
2157  this->multiphysics->set_solution(PhysicsID::fluid_dynamics,
+
2158  &this->multiphysics_present_solution);
+
2159 
+
2160  // Convert the previous solutions to multiphysics vector type and provide them
+
2161  // to the multiphysics interface
+
2162  const unsigned int number_of_previous_solutions =
+
2163  this->simulation_control->get_number_of_previous_solution_in_assembly();
+
2164 
+
2165  std::vector<TrilinosWrappers::MPI::Vector> temp_previous_solutions;
+
2166 
+
2167  temp_previous_solutions.resize(number_of_previous_solutions);
+
2168  for (auto &solution : temp_previous_solutions)
+
2169  solution.reinit(this->locally_owned_dofs, this->mpi_communicator);
+
2170 
+
2171  for (unsigned int i = 0; i < number_of_previous_solutions; i++)
+
2172  {
+
2173  this->previous_solutions[i].update_ghost_values();
+
2174  convert_vector_dealii_to_trilinos(temp_previous_solutions[i],
+
2175  this->previous_solutions[i]);
+
2176 
+
2177  this->multiphysics_previous_solutions[i] = temp_previous_solutions[i];
+
2178  }
+
2179 
+
2180  this->multiphysics->set_previous_solutions(
+
2181  PhysicsID::fluid_dynamics, &this->multiphysics_previous_solutions);
+
2182 }
+
2183 
+
2184 template <int dim>
+
2185 void
+ +
2187 {
+
2188  double time = this->simulation_control->get_current_time();
+
2189  FEValuesExtractors::Vector velocities(0);
+
2190  FEValuesExtractors::Scalar pressure(dim);
+
2191  // Non-zero constraints
+
2192  auto &nonzero_constraints = this->get_nonzero_constraints();
+
2193  {
+
2194  nonzero_constraints.clear();
+
2195  nonzero_constraints.reinit(this->locally_relevant_dofs);
+
2196 
+
2197  DoFTools::make_hanging_node_constraints(this->dof_handler,
+
2198  nonzero_constraints);
+
2199  for (unsigned int i_bc = 0;
+
2200  i_bc < this->simulation_parameters.boundary_conditions.size;
+
2201  ++i_bc)
+
2202  {
+
2203  if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
+ +
2205  {
+
2206  VectorTools::interpolate_boundary_values(
+
2207  *this->mapping,
+
2208  this->dof_handler,
+
2209  this->simulation_parameters.boundary_conditions.id[i_bc],
+
2210  dealii::Functions::ZeroFunction<dim>(dim + 1),
+
2211  nonzero_constraints,
+
2212  this->fe->component_mask(velocities));
+
2213  }
+
2214  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
+ +
2216  {
+
2217  std::set<types::boundary_id> no_normal_flux_boundaries;
+
2218  no_normal_flux_boundaries.insert(
+
2219  this->simulation_parameters.boundary_conditions.id[i_bc]);
+
2220  VectorTools::compute_no_normal_flux_constraints(
+
2221  this->dof_handler,
+
2222  0,
+
2223  no_normal_flux_boundaries,
+
2224  nonzero_constraints,
+
2225  *this->mapping);
+
2226  }
+
2227  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
+ +
2229  {
+
2230  this->simulation_parameters.boundary_conditions.bcFunctions[i_bc]
+
2231  .u.set_time(time);
+
2232  this->simulation_parameters.boundary_conditions.bcFunctions[i_bc]
+
2233  .v.set_time(time);
+
2234  this->simulation_parameters.boundary_conditions.bcFunctions[i_bc]
+
2235  .w.set_time(time);
+
2236  VectorTools::interpolate_boundary_values(
+
2237  *this->mapping,
+
2238  this->dof_handler,
+
2239  this->simulation_parameters.boundary_conditions.id[i_bc],
+ +
2241  &this->simulation_parameters.boundary_conditions
+
2242  .bcFunctions[i_bc]
+
2243  .u,
+
2244  &this->simulation_parameters.boundary_conditions
+
2245  .bcFunctions[i_bc]
+
2246  .v,
+
2247  &this->simulation_parameters.boundary_conditions
+
2248  .bcFunctions[i_bc]
+
2249  .w),
+
2250  nonzero_constraints,
+
2251  this->fe->component_mask(velocities));
+
2252  }
+
2253  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
+ +
2255  {
+
2256  DoFTools::make_periodicity_constraints(
+
2257  this->dof_handler,
+
2258  this->simulation_parameters.boundary_conditions.id[i_bc],
+
2259  this->simulation_parameters.boundary_conditions.periodic_id[i_bc],
+
2260  this->simulation_parameters.boundary_conditions
+
2261  .periodic_direction[i_bc],
+
2262  nonzero_constraints);
+
2263  }
+
2264  }
+
2265  }
+
2266 
+
2267 
+
2268 
+
2269  this->establish_solid_domain(true);
+
2270 
+
2271  nonzero_constraints.close();
+
2272 }
+
2273 
+
2274 template <int dim>
+
2275 void
+ +
2277 {
+
2278  FEValuesExtractors::Vector velocities(0);
+
2279  FEValuesExtractors::Scalar pressure(dim);
+
2280  this->zero_constraints.clear();
+
2281  this->locally_relevant_dofs =
+
2282  DoFTools::extract_locally_relevant_dofs(this->dof_handler);
+
2283  this->zero_constraints.reinit(this->locally_relevant_dofs);
+
2284 
+
2285  DoFTools::make_hanging_node_constraints(this->dof_handler,
+
2286  this->zero_constraints);
+
2287 
+
2288  for (unsigned int i_bc = 0;
+
2289  i_bc < this->simulation_parameters.boundary_conditions.size;
+
2290  ++i_bc)
+
2291  {
+
2292  if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
+
2294  {
-
2295  /*do nothing*/
-
2296  }
-
2297  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
- -
2299  {
-
2300  /*do nothing*/
-
2301  }
-
2302  else
-
2303  {
-
2304  VectorTools::interpolate_boundary_values(
-
2305  *this->mapping,
-
2306  this->dof_handler,
-
2307  this->simulation_parameters.boundary_conditions.id[i_bc],
-
2308  dealii::Functions::ZeroFunction<dim>(dim + 1),
-
2309  this->zero_constraints,
-
2310  this->fe->component_mask(velocities));
-
2311  }
-
2312  }
-
2313 
-
2314  this->establish_solid_domain(false);
-
2315 
-
2316  this->zero_constraints.close();
-
2317 }
-
2318 
-
2319 template <int dim>
-
2320 void
- -
2322 {
-
2323  this->present_solution.update_ghost_values();
-
2324 
-
2325  this->computing_timer.enter_subsection("Evaluate non linear term and tau");
-
2326 
-
2327  this->system_operator->evaluate_non_linear_term_and_calculate_tau(
-
2328  this->present_solution);
-
2329 
-
2330  this->computing_timer.leave_subsection("Evaluate non linear term and tau");
-
2331 
-
2332  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
- -
2334  setup_ILU();
-
2335  else if ((this->simulation_parameters.linear_solver
- -
2337  .preconditioner ==
- -
2339  (this->simulation_parameters.linear_solver
- -
2341  .preconditioner ==
- -
2343  setup_GMG();
-
2344  else
-
2345  AssertThrow(
-
2346  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
2347  .preconditioner ==
- -
2349  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
2350  .preconditioner ==
- -
2352  ExcMessage(
-
2353  "This linear solver does not support this preconditioner. Only <ilu|lsmg|gcmg> preconditioners are supported."));
-
2354 }
-
2355 
-
2356 template <int dim>
-
2357 void
- -
2359  const bool /* renewed_matrix */)
-
2360 {
-
2361  const double absolute_residual =
-
2362  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
2363  .minimum_residual;
-
2364  const double relative_residual =
-
2365  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
2366  .relative_residual;
-
2367 
-
2368  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
- -
2370  solve_system_GMRES(initial_step, absolute_residual, relative_residual);
-
2371  else
-
2372  AssertThrow(false, ExcMessage("This solver is not allowed"));
-
2373  this->rescale_pressure_dofs_in_newton_update();
-
2374 }
-
2375 
-
2376 template <int dim>
-
2377 void
- -
2379 {
-
2380  // TODO
-
2381 }
-
2382 
-
2383 template <int dim>
-
2384 void
- -
2386  const double absolute_residual,
-
2387  const double relative_residual)
-
2388 {
-
2389  auto &system_rhs = this->system_rhs;
-
2390  auto &nonzero_constraints = this->nonzero_constraints;
-
2391 
-
2392  const AffineConstraints<double> &constraints_used =
-
2393  initial_step ? nonzero_constraints : this->zero_constraints;
-
2394  const double linear_solver_tolerance =
-
2395  std::max(relative_residual * system_rhs.l2_norm(), absolute_residual);
-
2396 
-
2397  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
2398  .verbosity != Parameters::Verbosity::quiet)
-
2399  {
-
2400  this->pcout << " -Tolerance of iterative solver is : "
-
2401  << linear_solver_tolerance << std::endl;
-
2402  }
-
2403 
-
2404  SolverControl solver_control(this->simulation_parameters.linear_solver
- -
2406  .max_iterations,
-
2407  linear_solver_tolerance,
-
2408  true,
-
2409  true);
-
2410 
-
2411  SolverGMRES<VectorType>::AdditionalData solver_parameters;
-
2412 
-
2413  solver_parameters.max_n_tmp_vectors =
-
2414  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
2415  .max_krylov_vectors;
-
2416  solver_parameters.right_preconditioning = true;
-
2417 
-
2418  SolverGMRES<VectorType> solver(solver_control, solver_parameters);
-
2419 
-
2420  this->newton_update = 0.0;
-
2421 
-
2422  this->computing_timer.enter_subsection("Solve linear system");
-
2423 
-
2424  if ((this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
2425  .preconditioner ==
- -
2427  (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
- -
2429  {
-
2430  solver.solve(*(this->system_operator),
-
2431  this->newton_update,
-
2432  this->system_rhs,
-
2433  *(this->gmg_preconditioner));
-
2434 
-
2435  if (this->simulation_parameters.linear_solver
- -
2437  .mg_verbosity != Parameters::Verbosity::quiet)
-
2438  this->gmg_preconditioner->print_relevant_info();
-
2439  }
-
2440  else if (this->simulation_parameters.linear_solver
- -
2442  .preconditioner ==
- -
2444  solver.solve(*(this->system_operator),
-
2445  this->newton_update,
-
2446  this->system_rhs,
-
2447  *(this->ilu_preconditioner));
-
2448  else
-
2449  AssertThrow(
-
2450  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
2451  .preconditioner ==
- -
2453  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
2454  .preconditioner ==
- -
2456  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
2457  .preconditioner ==
- -
2459  ExcMessage(
-
2460  "This linear solver does not support this preconditioner. Only <ilu|lsmg|gcmg> preconditioners are supported."));
-
2461 
-
2462  this->computing_timer.leave_subsection("Solve linear system");
-
2463 
-
2464  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
-
2465  .verbosity != Parameters::Verbosity::quiet)
-
2466  {
-
2467  this->pcout << " -Iterative solver took : " << solver_control.last_step()
-
2468  << " steps to reach a residual norm of "
-
2469  << solver_control.last_value() << std::endl;
-
2470  }
-
2471 
-
2472  this->computing_timer.enter_subsection(
-
2473  "Distribute constraints after linear solve");
-
2474 
-
2475  constraints_used.distribute(this->newton_update);
-
2476 
-
2477  this->computing_timer.leave_subsection(
-
2478  "Distribute constraints after linear solve");
-
2479 }
-
2480 
-
2481 template class MFNavierStokesSolver<2>;
-
2482 template class MFNavierStokesSolver<3>;
+
2295  std::set<types::boundary_id> no_normal_flux_boundaries;
+
2296  no_normal_flux_boundaries.insert(
+
2297  this->simulation_parameters.boundary_conditions.id[i_bc]);
+
2298  VectorTools::compute_no_normal_flux_constraints(
+
2299  this->dof_handler,
+
2300  0,
+
2301  no_normal_flux_boundaries,
+
2302  this->zero_constraints,
+
2303  *this->mapping);
+
2304  }
+
2305  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
+ +
2307  {
+
2308  DoFTools::make_periodicity_constraints(
+
2309  this->dof_handler,
+
2310  this->simulation_parameters.boundary_conditions.id[i_bc],
+
2311  this->simulation_parameters.boundary_conditions.periodic_id[i_bc],
+
2312  this->simulation_parameters.boundary_conditions
+
2313  .periodic_direction[i_bc],
+
2314  this->zero_constraints);
+
2315  }
+
2316  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
+ +
2318  {
+
2319  /*do nothing*/
+
2320  }
+
2321  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
+ +
2323  {
+
2324  /*do nothing*/
+
2325  }
+
2326  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
+ +
2328  {
+
2329  /*do nothing*/
+
2330  }
+
2331  else if (this->simulation_parameters.boundary_conditions.type[i_bc] ==
+ +
2333  {
+
2334  /*do nothing*/
+
2335  }
+
2336  else
+
2337  {
+
2338  VectorTools::interpolate_boundary_values(
+
2339  *this->mapping,
+
2340  this->dof_handler,
+
2341  this->simulation_parameters.boundary_conditions.id[i_bc],
+
2342  dealii::Functions::ZeroFunction<dim>(dim + 1),
+
2343  this->zero_constraints,
+
2344  this->fe->component_mask(velocities));
+
2345  }
+
2346  }
+
2347 
+
2348  this->establish_solid_domain(false);
+
2349 
+
2350  this->zero_constraints.close();
+
2351 }
+
2352 
+
2353 template <int dim>
+
2354 void
+ +
2356 {
+
2357  this->present_solution.update_ghost_values();
+
2358 
+
2359  this->computing_timer.enter_subsection("Evaluate non linear term and tau");
+
2360 
+
2361  this->system_operator->evaluate_non_linear_term_and_calculate_tau(
+
2362  this->present_solution);
+
2363 
+
2364  this->computing_timer.leave_subsection("Evaluate non linear term and tau");
+
2365 
+
2366  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+ +
2368  setup_ILU();
+
2369  else if ((this->simulation_parameters.linear_solver
+ +
2371  .preconditioner ==
+ +
2373  (this->simulation_parameters.linear_solver
+ +
2375  .preconditioner ==
+ +
2377  setup_GMG();
+
2378  else
+
2379  AssertThrow(
+
2380  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
2381  .preconditioner ==
+ +
2383  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
2384  .preconditioner ==
+ +
2386  ExcMessage(
+
2387  "This linear solver does not support this preconditioner. Only <ilu|lsmg|gcmg> preconditioners are supported."));
+
2388 }
+
2389 
+
2390 template <int dim>
+
2391 void
+ +
2393  const bool /* renewed_matrix */)
+
2394 {
+
2395  const double absolute_residual =
+
2396  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
2397  .minimum_residual;
+
2398  const double relative_residual =
+
2399  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
2400  .relative_residual;
+
2401 
+
2402  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+ +
2404  solve_system_GMRES(initial_step, absolute_residual, relative_residual);
+
2405  else
+
2406  AssertThrow(false, ExcMessage("This solver is not allowed"));
+
2407  this->rescale_pressure_dofs_in_newton_update();
+
2408 }
+
2409 
+
2410 template <int dim>
+
2411 void
+ +
2413 {
+
2414  // TODO
+
2415 }
+
2416 
+
2417 template <int dim>
+
2418 void
+ +
2420  const double absolute_residual,
+
2421  const double relative_residual)
+
2422 {
+
2423  auto &system_rhs = this->system_rhs;
+
2424  auto &nonzero_constraints = this->nonzero_constraints;
+
2425 
+
2426  const AffineConstraints<double> &constraints_used =
+
2427  initial_step ? nonzero_constraints : this->zero_constraints;
+
2428  const double linear_solver_tolerance =
+
2429  std::max(relative_residual * system_rhs.l2_norm(), absolute_residual);
+
2430 
+
2431  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
2432  .verbosity != Parameters::Verbosity::quiet)
+
2433  {
+
2434  this->pcout << " -Tolerance of iterative solver is : "
+
2435  << linear_solver_tolerance << std::endl;
+
2436  }
+
2437 
+
2438  SolverControl solver_control(this->simulation_parameters.linear_solver
+ +
2440  .max_iterations,
+
2441  linear_solver_tolerance,
+
2442  true,
+
2443  true);
+
2444 
+
2445  SolverGMRES<VectorType>::AdditionalData solver_parameters;
+
2446 
+
2447  solver_parameters.max_n_tmp_vectors =
+
2448  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
2449  .max_krylov_vectors;
+
2450  solver_parameters.right_preconditioning = true;
+
2451 
+
2452  SolverGMRES<VectorType> solver(solver_control, solver_parameters);
+
2453 
+
2454  this->newton_update = 0.0;
+
2455 
+
2456  this->computing_timer.enter_subsection("Solve linear system");
+
2457 
+
2458  if ((this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
2459  .preconditioner ==
+ +
2461  (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+ +
2463  {
+
2464  solver.solve(*(this->system_operator),
+
2465  this->newton_update,
+
2466  this->system_rhs,
+
2467  *(this->gmg_preconditioner));
+
2468 
+
2469  if (this->simulation_parameters.linear_solver
+ +
2471  .mg_verbosity != Parameters::Verbosity::quiet)
+
2472  this->gmg_preconditioner->print_relevant_info();
+
2473  }
+
2474  else if (this->simulation_parameters.linear_solver
+ +
2476  .preconditioner ==
+ +
2478  solver.solve(*(this->system_operator),
+
2479  this->newton_update,
+
2480  this->system_rhs,
+
2481  *(this->ilu_preconditioner));
+
2482  else
+
2483  AssertThrow(
+
2484  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
2485  .preconditioner ==
+ +
2487  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
2488  .preconditioner ==
+ +
2490  this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
2491  .preconditioner ==
+ +
2493  ExcMessage(
+
2494  "This linear solver does not support this preconditioner. Only <ilu|lsmg|gcmg> preconditioners are supported."));
+
2495 
+
2496  this->computing_timer.leave_subsection("Solve linear system");
+
2497 
+
2498  if (this->simulation_parameters.linear_solver.at(PhysicsID::fluid_dynamics)
+
2499  .verbosity != Parameters::Verbosity::quiet)
+
2500  {
+
2501  this->pcout << " -Iterative solver took : " << solver_control.last_step()
+
2502  << " steps to reach a residual norm of "
+
2503  << solver_control.last_value() << std::endl;
+
2504  }
+
2505 
+
2506  this->computing_timer.enter_subsection(
+
2507  "Distribute constraints after linear solve");
+
2508 
+
2509  constraints_used.distribute(this->newton_update);
+
2510 
+
2511  this->computing_timer.leave_subsection(
+
2512  "Distribute constraints after linear solve");
+
2513 }
+
2514 
+
2515 template class MFNavierStokesSolver<2>;
+
2516 template class MFNavierStokesSolver<3>;
unsigned int number_of_previous_solutions(Parameters::SimulationControl::TimeSteppingMethod method)
Get the number of previous time steps for a specific BDF scheme.
Definition: bdf.h:115
Class allows to dynamically control the flow with a beta coefficient calculated at each step time.
Definition: flow_control.h:40
Tensor< 1, dim > get_beta()
get_beta. This function gives the beta force of the step time
Definition: flow_control.h:100
TimerOutput mg_setup_timer
Timer for specific geometric multigrid components.
MGLevelObject< MGTwoLevelTransfer< dim, VectorType > > transfers
Transfers for each of the levels of the global coarsening algorithm.
-
const MGLevelObject< std::shared_ptr< OperatorType > > & get_mg_operators() const
Getter function for all level operators.
+
const MGLevelObject< std::shared_ptr< OperatorType > > & get_mg_operators() const
Getter function for all level operators.
std::vector< std::shared_ptr< const Triangulation< dim > > > coarse_grid_triangulations
Triangulations for the global coarsening case.
-
void setup_ILU()
Set the up ILU object needed for coarse-grid solver or preconditioning.
-
void initialize(const std::shared_ptr< SimulationControl > simulation_control, FlowControl< dim > &flow_control, const VectorType &present_solution, const VectorType &time_derivative_previous_solutions)
Initialize smoother, coarse grid solver and multigrid object needed for the geometric multigrid preco...
+
void setup_ILU()
Set the up ILU object needed for coarse-grid solver or preconditioning.
+
void initialize(const std::shared_ptr< SimulationControl > simulation_control, FlowControl< dim > &flow_control, const VectorType &present_solution, const VectorType &time_derivative_previous_solutions)
Initialize smoother, coarse grid solver and multigrid object needed for the geometric multigrid preco...
MGLevelObject< MatrixFreeOperators::MGInterfaceOperator< OperatorType > > ls_mg_operators
LinearAlgebra::distributed::Vector< double > VectorType
std::shared_ptr< GCTransferType > mg_transfer_gc
Transfer operator for global coarsening.
@@ -2578,39 +2612,39 @@
MGConstrainedDoFs mg_constrained_dofs
MGLevelObject< DoFHandler< dim > > dof_handlers
DoF handlers for each of the levels of the global coarsening algorithm.
unsigned int maxlevel
Max level of the multigrid hierarchy.
-
void vmult(VectorType &dst, const VectorType &src) const
Calls the v cycle function of the multigrid object.
+
void vmult(VectorType &dst, const VectorType &src) const
Calls the v cycle function of the multigrid object.
const DoFHandler< dim > & dof_handler_fe_q_iso_q1
Describes the layout of DoFs for FE_Q_iso_Q1 elements.
std::shared_ptr< LSTransferType > mg_transfer_ls
Transfer operator for local smoothing.
MGLevelObject< std::shared_ptr< OperatorType > > mg_operators
Level operators for the geometric multigrid.
MGLevelObject< MatrixFreeOperators::MGInterfaceOperator< OperatorType > > ls_mg_interface_in
-
void setup_AMG()
Set the up AMG object needed for coarse-grid solver or preconditioning.
-
void print_relevant_info() const
Prints relevant multigrid information.
+
void setup_AMG()
Set the up AMG object needed for coarse-grid solver or preconditioning.
+
void print_relevant_info() const
Prints relevant multigrid information.
ConditionalOStream pcout
Conditional Ostream.
MFNavierStokesPreconditionGMG(const SimulationParameters< dim > &simulation_parameters, const DoFHandler< dim > &dof_handler, const DoFHandler< dim > &dof_handler_fe_q_iso_q1, const std::shared_ptr< Mapping< dim >> &mapping, const std::shared_ptr< Quadrature< dim >> &cell_quadrature, const std::shared_ptr< Function< dim >> forcing_function, const std::shared_ptr< SimulationControl > simulation_control, const std::shared_ptr< FESystem< dim >> fe)
Construct a new precondition GMG object. Sets constraints, operators and transfer objects.
unsigned int minlevel
Min level of the multigrid hierarchy.
A solver for the incompressible Navier-Stokes equations implemented in a matrix-free fashion.
-
void solve_system_GMRES(const bool initial_step, const double absolute_residual, const double relative_residual)
GMRES solver with preconditioning.
-
virtual void set_initial_condition_fd(Parameters::InitialConditionType initial_condition_type, bool restart=false) override
Set the initial conditions for the solver. If the simulation is restarted from a checkpoint,...
-
void define_non_zero_constraints()
Define the non-zero constraints used to solve the problem.
-
virtual void assemble_system_matrix() override
Assemble the matrix associated with the solver. Only required for compilation and it is not used for ...
+
void solve_system_GMRES(const bool initial_step, const double absolute_residual, const double relative_residual)
GMRES solver with preconditioning.
+
virtual void set_initial_condition_fd(Parameters::InitialConditionType initial_condition_type, bool restart=false) override
Set the initial conditions for the solver. If the simulation is restarted from a checkpoint,...
+
void define_non_zero_constraints()
Define the non-zero constraints used to solve the problem.
+
virtual void assemble_system_matrix() override
Assemble the matrix associated with the solver. Only required for compilation and it is not used for ...
LinearAlgebra::distributed::Vector< double > VectorType
-
virtual void solve()
Solve the problem defined by simulation parameters by iterating through time or through the mesh refi...
-
void assemble_L2_projection()
Assemble a L2 projection matrix for the velocity and the pressure, which can be used to set the initi...
-
void setup_ILU()
Setup the implicit LU preconditioner and call the solve function of the linear solver....
-
void calculate_time_derivative_previous_solutions()
Calculate and store time derivatives of previous solutions according to time-stepping scheme to use t...
-
void define_zero_constraints()
Define the zero constraints used to solve the problem.
-
virtual void setup_dofs_fd() override
Setup the degrees of freedom, system constraints, system operator and solution vectors.
-
~MFNavierStokesSolver()
Destructor.
-
MFNavierStokesSolver(SimulationParameters< dim > &nsparam)
Constructor that sets the finite element degree and system operator according to simulation parameter...
-
void print_mg_setup_times()
Prints the setup times for the geometric multigrid preconditioner.
-
virtual void assemble_system_rhs() override
Assemble the system right hand side associated with the solver.
-
void update_solutions_for_multiphysics()
Provide present and previous flow solutions to the multiphysics interface. These solutions can be acc...
-
void solve_linear_system(const bool initial_step, const bool renewed_matrix=true) override
Solve the linear system of equations using the method specified in the simulation parameters.
+
virtual void solve()
Solve the problem defined by simulation parameters by iterating through time or through the mesh refi...
+
void assemble_L2_projection()
Assemble a L2 projection matrix for the velocity and the pressure, which can be used to set the initi...
+
void setup_ILU()
Setup the implicit LU preconditioner and call the solve function of the linear solver....
+
void calculate_time_derivative_previous_solutions()
Calculate and store time derivatives of previous solutions according to time-stepping scheme to use t...
+
void define_zero_constraints()
Define the zero constraints used to solve the problem.
+
virtual void setup_dofs_fd() override
Setup the degrees of freedom, system constraints, system operator and solution vectors.
+
~MFNavierStokesSolver()
Destructor.
+
MFNavierStokesSolver(SimulationParameters< dim > &nsparam)
Constructor that sets the finite element degree and system operator according to simulation parameter...
+
void print_mg_setup_times()
Prints the setup times for the geometric multigrid preconditioner.
+
virtual void assemble_system_rhs() override
Assemble the system right hand side associated with the solver.
+
void update_solutions_for_multiphysics()
Provide present and previous flow solutions to the multiphysics interface. These solutions can be acc...
+
void solve_linear_system(const bool initial_step, const bool renewed_matrix=true) override
Solve the linear system of equations using the method specified in the simulation parameters.
std::shared_ptr< NavierStokesOperatorBase< dim, double > > system_operator
Matrix-free operator in used for all the matrix-vector multiplications calls (vmult).
-
void setup_preconditioner() override
Set up appropriate preconditioner.
-
virtual void update_multiphysics_time_average_solution() override
Update the average velocity field solution in the multiphyscics interface.
-
void setup_GMG()
Setup the geometric multigrid preconditioner and call the solve function of the linear solver.
-
void update_boundary_conditions()
Update non zero constraints if the boundary is time dependent.
+
void setup_preconditioner() override
Set up appropriate preconditioner.
+
virtual void update_multiphysics_time_average_solution() override
Update the average velocity field solution in the multiphyscics interface.
+
void setup_GMG()
Setup the geometric multigrid preconditioner and call the solve function of the linear solver.
+
void update_boundary_conditions()
Update non zero constraints if the boundary is time dependent.
virtual void refine_mesh()
Allow the refinement of the mesh according to one of the 2 methods proposed.
@@ -2673,6 +2707,7 @@
enum Parameters::Stabilization::NavierStokesStabilization stabilization
+ diff --git a/doxygen/mf__navier__stokes__operators_8cc_source.html b/doxygen/mf__navier__stokes__operators_8cc_source.html index f46a46800c..6a2774ad67 100644 --- a/doxygen/mf__navier__stokes__operators_8cc_source.html +++ b/doxygen/mf__navier__stokes__operators_8cc_source.html @@ -464,896 +464,917 @@
383  this->matrix_free.cell_loop(
384  &NavierStokesOperatorBase::do_cell_integral_range, this, dst, src, true);
385 
-
386  // set constrained dofs as the sum of current dst value and src value
-
387  for (unsigned int i = 0; i < constrained_indices.size(); ++i)
-
388  dst.local_element(constrained_indices[i]) =
-
389  src.local_element(constrained_indices[i]);
-
390 
-
391  // restoring edge constrained dofs in src and dst
-
392  for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i)
-
393  {
-
394  const_cast<LinearAlgebra::distributed::Vector<number> &>(src)
-
395  .local_element(edge_constrained_indices[i]) =
-
396  edge_constrained_values[i];
-
397  dst.local_element(edge_constrained_indices[i]) =
+
386  // copy constrained dofs from src to dst (corresponding to diagonal
+
387  // entries with value 1.0)
+
388  for (unsigned int i = 0; i < constrained_indices.size(); ++i)
+
389  dst.local_element(constrained_indices[i]) =
+
390  src.local_element(constrained_indices[i]);
+
391 
+
392  // restoring edge constrained dofs in src and copy the values to dst
+
393  // (corresponding to diagonal entries with value 1.0)
+
394  for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i)
+
395  {
+
396  const_cast<LinearAlgebra::distributed::Vector<number> &>(src)
+
397  .local_element(edge_constrained_indices[i]) =
398  edge_constrained_values[i];
-
399  }
-
400 
-
401  this->timer.leave_subsection("operator::vmult");
-
402 }
-
403 
-
404 template <int dim, typename number>
-
405 void
- -
407  const VectorType &src) const
-
408 {
-
409  this->vmult(dst, src);
-
410 }
-
411 
-
412 template <int dim, typename number>
-
413 void
- -
415  VectorType &dst,
-
416  VectorType const &src) const
-
417 {
-
418  this->matrix_free.cell_loop(
-
419  &NavierStokesOperatorBase::do_cell_integral_range, this, dst, src, true);
-
420 
-
421  // set constrained dofs as the sum of current dst value and src value
-
422  for (unsigned int i = 0; i < constrained_indices.size(); ++i)
-
423  dst.local_element(constrained_indices[i]) =
-
424  src.local_element(constrained_indices[i]);
-
425 }
-
426 
-
427 template <int dim, typename number>
-
428 void
- -
430  VectorType &dst,
-
431  VectorType const &src) const
-
432 {
-
433  this->timer.enter_subsection("operator::vmult_interface_up");
-
434 
-
435  if (has_edge_constrained_indices == false)
-
436  {
-
437  dst = number(0.);
-
438  return;
-
439  }
-
440 
-
441  dst = 0.0;
+
399  dst.local_element(edge_constrained_indices[i]) =
+
400  edge_constrained_values[i];
+
401  }
+
402 
+
403  this->timer.leave_subsection("operator::vmult");
+
404 }
+
405 
+
406 template <int dim, typename number>
+
407 void
+ +
409  const VectorType &src) const
+
410 {
+
411  this->vmult(dst, src);
+
412 }
+
413 
+
414 template <int dim, typename number>
+
415 void
+ +
417  VectorType &dst,
+
418  VectorType const &src) const
+
419 {
+
420  this->matrix_free.cell_loop(
+
421  &NavierStokesOperatorBase::do_cell_integral_range, this, dst, src, true);
+
422 
+
423  // set constrained dofs as the sum of current dst value and src value
+
424  for (unsigned int i = 0; i < constrained_indices.size(); ++i)
+
425  dst.local_element(constrained_indices[i]) =
+
426  src.local_element(constrained_indices[i]);
+
427 }
+
428 
+
429 template <int dim, typename number>
+
430 void
+ +
432  VectorType &dst,
+
433  VectorType const &src) const
+
434 {
+
435  this->timer.enter_subsection("operator::vmult_interface_up");
+
436 
+
437  if (has_edge_constrained_indices == false)
+
438  {
+
439  dst = number(0.);
+
440  return;
+
441  }
442 
-
443  // make a copy of src vector and set everything to 0 except edge
-
444  // constrained dofs
-
445  VectorType src_cpy;
-
446  src_cpy.reinit(src, /*omit_zeroing_entries=*/false);
-
447 
-
448  for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i)
-
449  src_cpy.local_element(edge_constrained_indices[i]) =
-
450  src.local_element(edge_constrained_indices[i]);
-
451 
-
452  // do loop with copy of src
-
453  this->matrix_free.cell_loop(&NavierStokesOperatorBase::do_cell_integral_range,
-
454  this,
-
455  dst,
-
456  src_cpy,
-
457  false);
-
458 
-
459  this->timer.leave_subsection("operator::vmult_interface_up");
-
460 }
-
461 
-
462 
-
463 template <int dim, typename number>
-
464 const TrilinosWrappers::SparseMatrix &
- -
466 {
-
467  this->timer.enter_subsection("operator::get_system_matrix");
-
468 
-
469  if (system_matrix.m() == 0 && system_matrix.n() == 0)
-
470  {
-
471  const auto &dof_handler = this->matrix_free.get_dof_handler();
-
472 
-
473  const unsigned int mg_level = this->matrix_free.get_mg_level();
+
443  dst = 0.0;
+
444 
+
445  // make a copy of src vector and set everything to 0 except edge
+
446  // constrained dofs
+
447  VectorType src_cpy;
+
448  src_cpy.reinit(src, /*omit_zeroing_entries=*/false);
+
449 
+
450  for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i)
+
451  src_cpy.local_element(edge_constrained_indices[i]) =
+
452  src.local_element(edge_constrained_indices[i]);
+
453 
+
454  // do loop with copy of src
+
455  this->matrix_free.cell_loop(&NavierStokesOperatorBase::do_cell_integral_range,
+
456  this,
+
457  dst,
+
458  src_cpy,
+
459  false);
+
460 
+
461  this->timer.leave_subsection("operator::vmult_interface_up");
+
462 }
+
463 
+
464 
+
465 template <int dim, typename number>
+
466 const TrilinosWrappers::SparseMatrix &
+ +
468 {
+
469  this->timer.enter_subsection("operator::get_system_matrix");
+
470 
+
471  if (system_matrix.m() == 0 && system_matrix.n() == 0)
+
472  {
+
473  const auto &dof_handler = this->matrix_free.get_dof_handler();
474 
-
475  IndexSet locally_relevant_dofs;
-
476  IndexSet locally_owned_dofs;
-
477 
-
478  if (mg_level != numbers::invalid_unsigned_int)
-
479  {
-
480  locally_relevant_dofs =
-
481  DoFTools::extract_locally_relevant_level_dofs(dof_handler,
-
482  mg_level);
-
483  locally_owned_dofs = dof_handler.locally_owned_mg_dofs(mg_level);
-
484  }
-
485  else
-
486  {
-
487  locally_owned_dofs = dof_handler.locally_owned_dofs();
-
488  locally_relevant_dofs =
-
489  DoFTools::extract_locally_relevant_dofs(dof_handler);
-
490  }
-
491 
-
492  DynamicSparsityPattern dsp(locally_relevant_dofs);
+
475  const unsigned int mg_level = this->matrix_free.get_mg_level();
+
476 
+
477  IndexSet locally_relevant_dofs;
+
478  IndexSet locally_owned_dofs;
+
479 
+
480  if (mg_level != numbers::invalid_unsigned_int)
+
481  {
+
482  locally_relevant_dofs =
+
483  DoFTools::extract_locally_relevant_level_dofs(dof_handler,
+
484  mg_level);
+
485  locally_owned_dofs = dof_handler.locally_owned_mg_dofs(mg_level);
+
486  }
+
487  else
+
488  {
+
489  locally_owned_dofs = dof_handler.locally_owned_dofs();
+
490  locally_relevant_dofs =
+
491  DoFTools::extract_locally_relevant_dofs(dof_handler);
+
492  }
493 
-
494  if (mg_level != numbers::invalid_unsigned_int)
-
495  {
-
496  // the following code does the same as
-
497  // MGTools::make_sparsity_pattern() but also
-
498  // considers bool_dof_mask for FE_Q_iso_Q1
-
499  std::vector<types::global_dof_index> dofs_on_this_cell;
-
500 
-
501  for (const auto &cell : dof_handler.cell_iterators_on_level(mg_level))
-
502  if (cell->is_locally_owned_on_level())
-
503  {
-
504  const unsigned int dofs_per_cell =
-
505  dof_handler.get_fe().n_dofs_per_cell();
-
506  dofs_on_this_cell.resize(dofs_per_cell);
-
507  cell->get_mg_dof_indices(dofs_on_this_cell);
-
508 
-
509  constraints.add_entries_local_to_global(dofs_on_this_cell,
-
510  dsp,
-
511  false,
-
512  bool_dof_mask);
-
513  }
-
514  }
-
515  else
-
516  {
-
517  // the following code does the same as
-
518  // DoFTools::make_sparsity_pattern() but also
-
519  // considers bool_dof_mask for FE_Q_iso_Q1
-
520  std::vector<types::global_dof_index> dofs_on_this_cell;
-
521 
-
522  for (const auto &cell : dof_handler.active_cell_iterators())
-
523  if (cell->is_locally_owned())
-
524  {
-
525  const unsigned int dofs_per_cell =
-
526  cell->get_fe().n_dofs_per_cell();
-
527  dofs_on_this_cell.resize(dofs_per_cell);
-
528  cell->get_dof_indices(dofs_on_this_cell);
-
529 
-
530  constraints.add_entries_local_to_global(dofs_on_this_cell,
-
531  dsp,
-
532  false,
-
533  bool_dof_mask);
-
534  }
-
535  }
-
536 
-
537  SparsityTools::distribute_sparsity_pattern(
-
538  dsp,
-
539  locally_owned_dofs,
-
540  dof_handler.get_triangulation().get_communicator(),
-
541  locally_relevant_dofs);
-
542 
-
543  system_matrix.reinit(locally_owned_dofs,
-
544  locally_owned_dofs,
-
545  dsp,
-
546  dof_handler.get_triangulation().get_communicator());
-
547  }
-
548 
-
549  system_matrix = 0.0;
+
494  DynamicSparsityPattern dsp(locally_relevant_dofs);
+
495 
+
496  if (mg_level != numbers::invalid_unsigned_int)
+
497  {
+
498  // the following code does the same as
+
499  // MGTools::make_sparsity_pattern() but also
+
500  // considers bool_dof_mask for FE_Q_iso_Q1
+
501  std::vector<types::global_dof_index> dofs_on_this_cell;
+
502 
+
503  for (const auto &cell : dof_handler.cell_iterators_on_level(mg_level))
+
504  if (cell->is_locally_owned_on_level())
+
505  {
+
506  const unsigned int dofs_per_cell =
+
507  dof_handler.get_fe().n_dofs_per_cell();
+
508  dofs_on_this_cell.resize(dofs_per_cell);
+
509  cell->get_mg_dof_indices(dofs_on_this_cell);
+
510 
+
511  constraints.add_entries_local_to_global(dofs_on_this_cell,
+
512  dsp,
+
513  false,
+
514  bool_dof_mask);
+
515  }
+
516  }
+
517  else
+
518  {
+
519  // the following code does the same as
+
520  // DoFTools::make_sparsity_pattern() but also
+
521  // considers bool_dof_mask for FE_Q_iso_Q1
+
522  std::vector<types::global_dof_index> dofs_on_this_cell;
+
523 
+
524  for (const auto &cell : dof_handler.active_cell_iterators())
+
525  if (cell->is_locally_owned())
+
526  {
+
527  const unsigned int dofs_per_cell =
+
528  cell->get_fe().n_dofs_per_cell();
+
529  dofs_on_this_cell.resize(dofs_per_cell);
+
530  cell->get_dof_indices(dofs_on_this_cell);
+
531 
+
532  constraints.add_entries_local_to_global(dofs_on_this_cell,
+
533  dsp,
+
534  false,
+
535  bool_dof_mask);
+
536  }
+
537  }
+
538 
+
539  SparsityTools::distribute_sparsity_pattern(
+
540  dsp,
+
541  locally_owned_dofs,
+
542  dof_handler.get_triangulation().get_communicator(),
+
543  locally_relevant_dofs);
+
544 
+
545  system_matrix.reinit(locally_owned_dofs,
+
546  locally_owned_dofs,
+
547  dsp,
+
548  dof_handler.get_triangulation().get_communicator());
+
549  }
550 
-
551  // the following code does the same as
-
552  // MatrixFreeTools::compute_matrix() but with
-
553  // minor corrections for FE_Q_iso_Q1
-
554 
-
555  const auto &lexicographic_numbering =
-
556  matrix_free.get_shape_info().lexicographic_numbering;
-
557 
-
558  unsigned int cell = numbers::invalid_unsigned_int;
-
559  unsigned int column = numbers::invalid_unsigned_int;
-
560 
-
561  MatrixFreeTools::
-
562  compute_matrix<dim, -1, 0, dim + 1, number, VectorizedArray<number>>(
-
563  matrix_free, constraints, system_matrix, [&](auto &integrator) {
-
564  if (cell != integrator.get_current_cell_index())
-
565  {
-
566  cell = integrator.get_current_cell_index();
-
567  column = 0;
-
568  }
-
569 
-
570  do_cell_integral_local(integrator);
+
551  system_matrix = 0.0;
+
552 
+
553  // the following code does the same as
+
554  // MatrixFreeTools::compute_matrix() but with
+
555  // minor corrections for FE_Q_iso_Q1
+
556 
+
557  const auto &lexicographic_numbering =
+
558  matrix_free.get_shape_info().lexicographic_numbering;
+
559 
+
560  unsigned int cell = numbers::invalid_unsigned_int;
+
561  unsigned int column = numbers::invalid_unsigned_int;
+
562 
+
563  MatrixFreeTools::
+
564  compute_matrix<dim, -1, 0, dim + 1, number, VectorizedArray<number>>(
+
565  matrix_free, constraints, system_matrix, [&](auto &integrator) {
+
566  if (cell != integrator.get_current_cell_index())
+
567  {
+
568  cell = integrator.get_current_cell_index();
+
569  column = 0;
+
570  }
571 
-
572  // remove spurious entries for FE_Q_iso_Q1
-
573  for (unsigned int i = 0; i < lexicographic_numbering.size(); ++i)
-
574  if (!bool_dof_mask[lexicographic_numbering[i]]
-
575  [lexicographic_numbering[column]])
-
576  integrator.begin_dof_values()[i] = 0.0;
-
577 
-
578  column++;
-
579  });
-
580 
-
581  this->timer.leave_subsection("operator::get_system_matrix");
+
572  do_cell_integral_local(integrator);
+
573 
+
574  // remove spurious entries for FE_Q_iso_Q1
+
575  for (unsigned int i = 0; i < lexicographic_numbering.size(); ++i)
+
576  if (!bool_dof_mask[lexicographic_numbering[i]]
+
577  [lexicographic_numbering[column]])
+
578  integrator.begin_dof_values()[i] = 0.0;
+
579 
+
580  column++;
+
581  });
582 
-
583  return this->system_matrix;
-
584 }
-
585 
-
586 template <int dim, typename number>
-
587 const MatrixFree<dim, number> &
- -
589 {
-
590  return this->matrix_free;
-
591 }
+
583  // make sure that diagonal entries related to constrained dofs
+
584  // have a value of 1.0 (note this is consistent to vmult() and
+
585  // compute_inverse_diagonal())
+
586  for (const auto &local_row : constrained_indices)
+
587  {
+
588  const auto global_row =
+
589  get_vector_partitioner()->local_to_global(local_row);
+
590  system_matrix.set(global_row, global_row, 1.0);
+
591  }
592 
-
593 template <int dim, typename number>
-
594 const AlignedVector<VectorizedArray<number>>
- -
596 {
-
597  return this->element_size;
-
598 }
+
593  for (const auto &local_row : edge_constrained_indices)
+
594  {
+
595  const auto global_row =
+
596  get_vector_partitioner()->local_to_global(local_row);
+
597  system_matrix.set(global_row, global_row, 1.0);
+
598  }
599 
-
600 template <int dim, typename number>
-
601 void
- - -
604 {
-
605  this->timer.enter_subsection("operator::evaluate_non_linear_term");
+
600  system_matrix.compress(VectorOperation::insert);
+
601 
+
602  this->timer.leave_subsection("operator::get_system_matrix");
+
603 
+
604  return this->system_matrix;
+
605 }
606 
-
607  const unsigned int n_cells = matrix_free.n_cell_batches();
-
608  FECellIntegrator integrator(matrix_free);
-
609 
-
610  // Set appropriate size for tables
-
611  nonlinear_previous_values.reinit(n_cells, integrator.n_q_points);
-
612  nonlinear_previous_gradient.reinit(n_cells, integrator.n_q_points);
-
613  nonlinear_previous_hessian_diagonal.reinit(n_cells, integrator.n_q_points);
-
614  stabilization_parameter.reinit(n_cells, integrator.n_q_points);
-
615  stabilization_parameter_lsic.reinit(n_cells, integrator.n_q_points);
-
616 
-
617  // Define 1/dt if the simulation is transient
-
618  double sdt = 0.0;
-
619 
-
620  bool transient =
-
621  (is_bdf(this->simulation_control->get_assembly_method())) ? true : false;
-
622 
-
623  if (transient)
-
624  {
-
625  const auto time_steps_vector =
-
626  this->simulation_control->get_time_steps_vector();
-
627  const double dt = time_steps_vector[0];
-
628  sdt = 1. / dt;
-
629  }
+
607 template <int dim, typename number>
+
608 const MatrixFree<dim, number> &
+ +
610 {
+
611  return this->matrix_free;
+
612 }
+
613 
+
614 template <int dim, typename number>
+
615 const AlignedVector<VectorizedArray<number>>
+ +
617 {
+
618  return this->element_size;
+
619 }
+
620 
+
621 template <int dim, typename number>
+
622 void
+ + +
625 {
+
626  this->timer.enter_subsection("operator::evaluate_non_linear_term");
+
627 
+
628  const unsigned int n_cells = matrix_free.n_cell_batches();
+
629  FECellIntegrator integrator(matrix_free);
630 
-
631  for (unsigned int cell = 0; cell < n_cells; ++cell)
-
632  {
-
633  integrator.reinit(cell);
-
634  integrator.read_dof_values_plain(newton_step);
-
635 
-
636  if (this->enable_hessians_jacobian)
-
637  integrator.evaluate(EvaluationFlags::values |
-
638  EvaluationFlags::gradients |
-
639  EvaluationFlags::hessians);
-
640  else
-
641  integrator.evaluate(EvaluationFlags::values |
-
642  EvaluationFlags::gradients);
+
631  // Set appropriate size for tables
+
632  nonlinear_previous_values.reinit(n_cells, integrator.n_q_points);
+
633  nonlinear_previous_gradient.reinit(n_cells, integrator.n_q_points);
+
634  nonlinear_previous_hessian_diagonal.reinit(n_cells, integrator.n_q_points);
+
635  stabilization_parameter.reinit(n_cells, integrator.n_q_points);
+
636  stabilization_parameter_lsic.reinit(n_cells, integrator.n_q_points);
+
637 
+
638  // Define 1/dt if the simulation is transient
+
639  double sdt = 0.0;
+
640 
+
641  bool transient =
+
642  (is_bdf(this->simulation_control->get_assembly_method())) ? true : false;
643 
-
644  // Get previously calculated element size needed for tau
-
645  const auto h = integrator.read_cell_data(this->get_element_size());
-
646 
-
647  for (const auto q : integrator.quadrature_point_indices())
-
648  {
-
649  nonlinear_previous_values(cell, q) = integrator.get_value(q);
-
650  nonlinear_previous_gradient(cell, q) = integrator.get_gradient(q);
+
644  if (transient)
+
645  {
+
646  const auto time_steps_vector =
+
647  this->simulation_control->get_time_steps_vector();
+
648  const double dt = time_steps_vector[0];
+
649  sdt = 1. / dt;
+
650  }
651 
-
652  if (this->enable_hessians_jacobian)
-
653  nonlinear_previous_hessian_diagonal(cell, q) =
-
654  integrator.get_hessian_diagonal(q);
-
655 
-
656  // Calculate tau
-
657  VectorizedArray<number> u_mag_squared = 1e-12;
-
658  for (unsigned int k = 0; k < dim; ++k)
-
659  u_mag_squared +=
-
660  Utilities::fixed_power<2>(integrator.get_value(q)[k]);
-
661 
-
662  stabilization_parameter(cell, q) =
-
663  1. / std::sqrt(Utilities::fixed_power<2>(sdt) +
-
664  4. * u_mag_squared / h / h +
-
665  9. * Utilities::fixed_power<2>(
-
666  4. * this->kinematic_viscosity / (h * h)));
+
652  for (unsigned int cell = 0; cell < n_cells; ++cell)
+
653  {
+
654  integrator.reinit(cell);
+
655  integrator.read_dof_values_plain(newton_step);
+
656 
+
657  if (this->enable_hessians_jacobian)
+
658  integrator.evaluate(EvaluationFlags::values |
+
659  EvaluationFlags::gradients |
+
660  EvaluationFlags::hessians);
+
661  else
+
662  integrator.evaluate(EvaluationFlags::values |
+
663  EvaluationFlags::gradients);
+
664 
+
665  // Get previously calculated element size needed for tau
+
666  const auto h = integrator.read_cell_data(this->get_element_size());
667 
-
668  stabilization_parameter_lsic(cell, q) =
-
669  std::sqrt(u_mag_squared) * h * 0.5;
-
670  }
-
671  }
+
668  for (const auto q : integrator.quadrature_point_indices())
+
669  {
+
670  nonlinear_previous_values(cell, q) = integrator.get_value(q);
+
671  nonlinear_previous_gradient(cell, q) = integrator.get_gradient(q);
672 
-
673  this->timer.leave_subsection("operator::evaluate_non_linear_term");
-
674 }
-
675 
-
676 template <int dim, typename number>
-
677 void
- - -
680  const VectorType &time_derivative_previous_solutions)
-
681 {
-
682  this->timer.enter_subsection(
-
683  "operator::evaluate_time_derivative_previous_solutions");
-
684 
-
685  const unsigned int n_cells = matrix_free.n_cell_batches();
-
686  FECellIntegrator integrator(matrix_free);
-
687 
-
688  time_derivatives_previous_solutions.reinit(n_cells, integrator.n_q_points);
-
689 
-
690  for (unsigned int cell = 0; cell < n_cells; ++cell)
-
691  {
-
692  integrator.reinit(cell);
-
693  integrator.read_dof_values_plain(time_derivative_previous_solutions);
-
694  integrator.evaluate(EvaluationFlags::values);
-
695  for (const auto q : integrator.quadrature_point_indices())
-
696  time_derivatives_previous_solutions(cell, q) += integrator.get_value(q);
-
697  }
-
698 
-
699  this->timer.leave_subsection(
-
700  "operator::evaluate_time_derivative_previous_solutions");
-
701 }
-
702 
-
703 template <int dim, typename number>
-
704 void
- -
706  const Tensor<1, dim> &beta_force)
-
707 {
-
708  for (unsigned int v = 0; v < VectorizedArray<number>::size(); ++v)
-
709  {
-
710  for (unsigned int d = 0; d < dim; ++d)
-
711  this->beta_force[d][v] = beta_force[d];
-
712  }
-
713 }
-
714 
-
715 template <int dim, typename number>
-
716 void
- -
718  const VectorType &src)
-
719 {
-
720  this->timer.enter_subsection("operator::evaluate_residual");
-
721 
-
722  this->matrix_free.cell_loop(
- -
724 
-
725  this->timer.leave_subsection("operator::evaluate_residual");
-
726 }
-
727 
-
728 template <int dim, typename number>
-
729 void
- -
731  VectorType &diagonal) const
-
732 {
-
733  this->timer.enter_subsection("operator::compute_inverse_diagonal");
-
734 
-
735  this->matrix_free.initialize_dof_vector(diagonal);
-
736  MatrixFreeTools::compute_diagonal(
-
737  matrix_free,
-
738  diagonal,
- -
740  this);
-
741 
-
742  for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i)
-
743  diagonal.local_element(edge_constrained_indices[i]) = 0.0;
-
744 
-
745  for (auto &i : diagonal)
-
746  i = (std::abs(i) > 1.0e-10) ? (1.0 / i) : 1.0;
-
747 
-
748  this->timer.leave_subsection("operator::compute_inverse_diagonal");
-
749 }
-
750 
-
751 template <int dim, typename number>
-
752 void
- -
754  const MatrixFree<dim, number> &matrix_free,
-
755  VectorType &dst,
-
756  const VectorType &src,
-
757  const std::pair<unsigned int, unsigned int> &range) const
-
758 {
-
759  FECellIntegrator integrator(matrix_free, range);
-
760 
-
761  for (unsigned int cell = range.first; cell < range.second; ++cell)
-
762  {
-
763  integrator.reinit(cell);
-
764 
-
765  integrator.read_dof_values(src);
-
766 
-
767  do_cell_integral_local(integrator);
+
673  if (this->enable_hessians_jacobian)
+
674  nonlinear_previous_hessian_diagonal(cell, q) =
+
675  integrator.get_hessian_diagonal(q);
+
676 
+
677  // Calculate tau
+
678  VectorizedArray<number> u_mag_squared = 1e-12;
+
679  for (unsigned int k = 0; k < dim; ++k)
+
680  u_mag_squared +=
+
681  Utilities::fixed_power<2>(integrator.get_value(q)[k]);
+
682 
+
683  stabilization_parameter(cell, q) =
+
684  1. / std::sqrt(Utilities::fixed_power<2>(sdt) +
+
685  4. * u_mag_squared / h / h +
+
686  9. * Utilities::fixed_power<2>(
+
687  4. * this->kinematic_viscosity / (h * h)));
+
688 
+
689  stabilization_parameter_lsic(cell, q) =
+
690  std::sqrt(u_mag_squared) * h * 0.5;
+
691  }
+
692  }
+
693 
+
694  this->timer.leave_subsection("operator::evaluate_non_linear_term");
+
695 }
+
696 
+
697 template <int dim, typename number>
+
698 void
+ + +
701  const VectorType &time_derivative_previous_solutions)
+
702 {
+
703  this->timer.enter_subsection(
+
704  "operator::evaluate_time_derivative_previous_solutions");
+
705 
+
706  const unsigned int n_cells = matrix_free.n_cell_batches();
+
707  FECellIntegrator integrator(matrix_free);
+
708 
+
709  time_derivatives_previous_solutions.reinit(n_cells, integrator.n_q_points);
+
710 
+
711  for (unsigned int cell = 0; cell < n_cells; ++cell)
+
712  {
+
713  integrator.reinit(cell);
+
714  integrator.read_dof_values_plain(time_derivative_previous_solutions);
+
715  integrator.evaluate(EvaluationFlags::values);
+
716  for (const auto q : integrator.quadrature_point_indices())
+
717  time_derivatives_previous_solutions(cell, q) += integrator.get_value(q);
+
718  }
+
719 
+
720  this->timer.leave_subsection(
+
721  "operator::evaluate_time_derivative_previous_solutions");
+
722 }
+
723 
+
724 template <int dim, typename number>
+
725 void
+ +
727  const Tensor<1, dim> &beta_force)
+
728 {
+
729  for (unsigned int v = 0; v < VectorizedArray<number>::size(); ++v)
+
730  {
+
731  for (unsigned int d = 0; d < dim; ++d)
+
732  this->beta_force[d][v] = beta_force[d];
+
733  }
+
734 }
+
735 
+
736 template <int dim, typename number>
+
737 void
+ +
739  const VectorType &src)
+
740 {
+
741  this->timer.enter_subsection("operator::evaluate_residual");
+
742 
+
743  this->matrix_free.cell_loop(
+ +
745 
+
746  this->timer.leave_subsection("operator::evaluate_residual");
+
747 }
+
748 
+
749 template <int dim, typename number>
+
750 void
+ +
752  VectorType &diagonal) const
+
753 {
+
754  this->timer.enter_subsection("operator::compute_inverse_diagonal");
+
755 
+
756  this->matrix_free.initialize_dof_vector(diagonal);
+
757  MatrixFreeTools::compute_diagonal(
+
758  matrix_free,
+
759  diagonal,
+ +
761  this);
+
762 
+
763  for (unsigned int i = 0; i < edge_constrained_indices.size(); ++i)
+
764  diagonal.local_element(edge_constrained_indices[i]) = 0.0;
+
765 
+
766  for (auto &i : diagonal)
+
767  i = (std::abs(i) > 1.0e-10) ? (1.0 / i) : 1.0;
768 
-
769  integrator.distribute_local_to_global(dst);
-
770  }
-
771 }
-
772 
-
773 template <int dim, typename number>
-
774 IndexSet
- -
776  const MatrixFree<dim, number> &matrix_free)
-
777 {
-
778  const unsigned int level = matrix_free.get_mg_level();
-
779 
-
780  std::vector<IndexSet> refinement_edge_indices;
-
781  refinement_edge_indices.clear();
-
782  const unsigned int nlevels =
-
783  matrix_free.get_dof_handler().get_triangulation().n_global_levels();
-
784  refinement_edge_indices.resize(nlevels);
-
785  for (unsigned int l = 0; l < nlevels; l++)
-
786  refinement_edge_indices[l] =
-
787  IndexSet(matrix_free.get_dof_handler().n_dofs(l));
-
788 
-
789  MGTools::extract_inner_interface_dofs(matrix_free.get_dof_handler(),
-
790  refinement_edge_indices);
-
791  return refinement_edge_indices[level];
+
769  this->timer.leave_subsection("operator::compute_inverse_diagonal");
+
770 }
+
771 
+
772 template <int dim, typename number>
+
773 void
+ +
775  const MatrixFree<dim, number> &matrix_free,
+
776  VectorType &dst,
+
777  const VectorType &src,
+
778  const std::pair<unsigned int, unsigned int> &range) const
+
779 {
+
780  FECellIntegrator integrator(matrix_free, range);
+
781 
+
782  for (unsigned int cell = range.first; cell < range.second; ++cell)
+
783  {
+
784  integrator.reinit(cell);
+
785 
+
786  integrator.read_dof_values(src);
+
787 
+
788  do_cell_integral_local(integrator);
+
789 
+
790  integrator.distribute_local_to_global(dst);
+
791  }
792 }
793 
- - -
796 
-
797 template <int dim, typename number>
- -
799  default;
-
800 
-
801 /**
-
802  * The expressions calculated in this cell integral are:
-
803  * (q,∇δu) + (v,∂t δu) + (v,(u·∇)δu) + (v,(δu·∇)u) - (∇·v,δp) + ν(∇v,∇δu) (Weak
-
804  * form Jacobian),
-
805  * plus three additional terms in the case of SUPG-PSPG stabilization:
-
806  * \+ (∂t δu +(u·∇)δu + (δu·∇)u + ∇δp - ν∆δu)τ·∇q (PSPG Jacobian)
-
807  * \+ (∂t δu +(u·∇)δu + (δu·∇)u + ∇δp - ν∆δu)Ï„u·∇v (SUPG Jacobian Part 1)
-
808  * \+ (∂t u +(u·∇)u + ∇p - ν∆u - f )τδu·∇v (SUPG Jacobian Part 2),
-
809  * plus two additional terms in the case of full gls stabilization:
-
810  * \+ (∂t δu +(u·∇)δu + (δu·∇)u + ∇δp - ν∆δu)Ï„(−ν∆v) (GLS Jacobian)
-
811  * \+ (∇·δu)Ï„'(∇·v) (LSIC Jacobian).
-
812  */
-
813 template <int dim, typename number>
-
814 void
- -
816  FECellIntegrator &integrator) const
-
817 {
-
818  if (this->enable_hessians_jacobian)
-
819  integrator.evaluate(EvaluationFlags::values | EvaluationFlags::gradients |
-
820  EvaluationFlags::hessians);
-
821  else
-
822  integrator.evaluate(EvaluationFlags::values | EvaluationFlags::gradients);
-
823 
-
824  const unsigned int cell = integrator.get_current_cell_index();
-
825 
-
826  // To identify whether the problem is transient or steady
-
827  bool transient =
-
828  (is_bdf(this->simulation_control->get_assembly_method())) ? true : false;
-
829 
-
830  // Vector for BDF coefficients
-
831  const Vector<double> *bdf_coefs;
-
832  if (transient)
-
833  bdf_coefs = &this->simulation_control->get_bdf_coefficients();
-
834 
-
835  for (const auto q : integrator.quadrature_point_indices())
-
836  {
-
837  Tensor<1, dim, VectorizedArray<number>> source_value;
-
838 
-
839  // Evaluate source term function if enabled
-
840  if (this->forcing_function)
-
841  {
-
842  Point<dim, VectorizedArray<number>> point_batch =
-
843  integrator.quadrature_point(q);
-
844  source_value =
-
845  evaluate_function<dim, number, dim>(*(this->forcing_function),
-
846  point_batch);
-
847  }
-
848 
-
849  // Add to source term the dynamic flow control force (zero if not enabled)
-
850  source_value += this->beta_force;
-
851 
-
852  // Gather the original value/gradient
-
853  typename FECellIntegrator::value_type value = integrator.get_value(q);
-
854  typename FECellIntegrator::gradient_type gradient =
-
855  integrator.get_gradient(q);
-
856  typename FECellIntegrator::gradient_type hessian_diagonal;
-
857 
-
858  if (this->enable_hessians_jacobian)
-
859  hessian_diagonal = integrator.get_hessian_diagonal(q);
-
860 
-
861  // Result value/gradient we will use
-
862  typename FECellIntegrator::value_type value_result;
-
863  typename FECellIntegrator::gradient_type gradient_result;
-
864  typename FECellIntegrator::hessian_type hessian_result;
-
865 
-
866  // Gather previous values of the velocity and the pressure
-
867  auto previous_values = this->nonlinear_previous_values(cell, q);
-
868  auto previous_gradient = this->nonlinear_previous_gradient(cell, q);
-
869  auto previous_hessian_diagonal =
-
870  this->nonlinear_previous_hessian_diagonal(cell, q);
-
871 
-
872  Tensor<1, dim + 1, VectorizedArray<number>> previous_time_derivatives;
-
873  if (transient)
-
874  previous_time_derivatives =
-
875  this->time_derivatives_previous_solutions(cell, q);
-
876 
-
877  // Get stabilization parameter
-
878  const auto tau = this->stabilization_parameter[cell][q];
-
879  const auto tau_lsic = this->stabilization_parameter_lsic[cell][q];
-
880 
-
881  // Weak form Jacobian
-
882  for (unsigned int i = 0; i < dim; ++i)
-
883  {
-
884  // ν(∇v,∇δu)
-
885  gradient_result[i] = this->kinematic_viscosity * gradient[i];
-
886  // -(∇·v,δp)
-
887  gradient_result[i][i] += -value[dim];
-
888  // +(q,∇δu)
-
889  value_result[dim] += gradient[i][i];
-
890 
-
891  for (unsigned int k = 0; k < dim; ++k)
-
892  {
-
893  // +(v,(u·∇)δu + (δu·∇)u)
-
894  value_result[i] += gradient[i][k] * previous_values[k] +
-
895  previous_gradient[i][k] * value[k];
-
896  }
-
897  // +(v,∂t δu)
-
898  if (transient)
-
899  value_result[i] += (*bdf_coefs)[0] * value[i];
-
900  }
+
794 template <int dim, typename number>
+
795 IndexSet
+ +
797  const MatrixFree<dim, number> &matrix_free)
+
798 {
+
799  const unsigned int level = matrix_free.get_mg_level();
+
800 
+
801  std::vector<IndexSet> refinement_edge_indices;
+
802  refinement_edge_indices.clear();
+
803  const unsigned int nlevels =
+
804  matrix_free.get_dof_handler().get_triangulation().n_global_levels();
+
805  refinement_edge_indices.resize(nlevels);
+
806  for (unsigned int l = 0; l < nlevels; l++)
+
807  refinement_edge_indices[l] =
+
808  IndexSet(matrix_free.get_dof_handler().n_dofs(l));
+
809 
+
810  MGTools::extract_inner_interface_dofs(matrix_free.get_dof_handler(),
+
811  refinement_edge_indices);
+
812  return refinement_edge_indices[level];
+
813 }
+
814 
+ + +
817 
+
818 template <int dim, typename number>
+ +
820  default;
+
821 
+
822 /**
+
823  * The expressions calculated in this cell integral are:
+
824  * (q,∇δu) + (v,∂t δu) + (v,(u·∇)δu) + (v,(δu·∇)u) - (∇·v,δp) + ν(∇v,∇δu) (Weak
+
825  * form Jacobian),
+
826  * plus three additional terms in the case of SUPG-PSPG stabilization:
+
827  * \+ (∂t δu +(u·∇)δu + (δu·∇)u + ∇δp - ν∆δu)τ·∇q (PSPG Jacobian)
+
828  * \+ (∂t δu +(u·∇)δu + (δu·∇)u + ∇δp - ν∆δu)Ï„u·∇v (SUPG Jacobian Part 1)
+
829  * \+ (∂t u +(u·∇)u + ∇p - ν∆u - f )τδu·∇v (SUPG Jacobian Part 2),
+
830  * plus two additional terms in the case of full gls stabilization:
+
831  * \+ (∂t δu +(u·∇)δu + (δu·∇)u + ∇δp - ν∆δu)Ï„(−ν∆v) (GLS Jacobian)
+
832  * \+ (∇·δu)Ï„'(∇·v) (LSIC Jacobian).
+
833  */
+
834 template <int dim, typename number>
+
835 void
+ +
837  FECellIntegrator &integrator) const
+
838 {
+
839  if (this->enable_hessians_jacobian)
+
840  integrator.evaluate(EvaluationFlags::values | EvaluationFlags::gradients |
+
841  EvaluationFlags::hessians);
+
842  else
+
843  integrator.evaluate(EvaluationFlags::values | EvaluationFlags::gradients);
+
844 
+
845  const unsigned int cell = integrator.get_current_cell_index();
+
846 
+
847  // To identify whether the problem is transient or steady
+
848  bool transient =
+
849  (is_bdf(this->simulation_control->get_assembly_method())) ? true : false;
+
850 
+
851  // Vector for BDF coefficients
+
852  const Vector<double> *bdf_coefs;
+
853  if (transient)
+
854  bdf_coefs = &this->simulation_control->get_bdf_coefficients();
+
855 
+
856  for (const auto q : integrator.quadrature_point_indices())
+
857  {
+
858  Tensor<1, dim, VectorizedArray<number>> source_value;
+
859 
+
860  // Evaluate source term function if enabled
+
861  if (this->forcing_function)
+
862  {
+
863  Point<dim, VectorizedArray<number>> point_batch =
+
864  integrator.quadrature_point(q);
+
865  source_value =
+
866  evaluate_function<dim, number, dim>(*(this->forcing_function),
+
867  point_batch);
+
868  }
+
869 
+
870  // Add to source term the dynamic flow control force (zero if not enabled)
+
871  source_value += this->beta_force;
+
872 
+
873  // Gather the original value/gradient
+
874  typename FECellIntegrator::value_type value = integrator.get_value(q);
+
875  typename FECellIntegrator::gradient_type gradient =
+
876  integrator.get_gradient(q);
+
877  typename FECellIntegrator::gradient_type hessian_diagonal;
+
878 
+
879  if (this->enable_hessians_jacobian)
+
880  hessian_diagonal = integrator.get_hessian_diagonal(q);
+
881 
+
882  // Result value/gradient we will use
+
883  typename FECellIntegrator::value_type value_result;
+
884  typename FECellIntegrator::gradient_type gradient_result;
+
885  typename FECellIntegrator::hessian_type hessian_result;
+
886 
+
887  // Gather previous values of the velocity and the pressure
+
888  auto previous_values = this->nonlinear_previous_values(cell, q);
+
889  auto previous_gradient = this->nonlinear_previous_gradient(cell, q);
+
890  auto previous_hessian_diagonal =
+
891  this->nonlinear_previous_hessian_diagonal(cell, q);
+
892 
+
893  Tensor<1, dim + 1, VectorizedArray<number>> previous_time_derivatives;
+
894  if (transient)
+
895  previous_time_derivatives =
+
896  this->time_derivatives_previous_solutions(cell, q);
+
897 
+
898  // Get stabilization parameter
+
899  const auto tau = this->stabilization_parameter[cell][q];
+
900  const auto tau_lsic = this->stabilization_parameter_lsic[cell][q];
901 
-
902  // PSPG Jacobian
+
902  // Weak form Jacobian
903  for (unsigned int i = 0; i < dim; ++i)
904  {
-
905  for (unsigned int k = 0; k < dim; ++k)
-
906  {
-
907  // (-ν∆δu + (u·∇)δu + (δu·∇)u)·τ∇q
-
908  gradient_result[dim][i] +=
-
909  tau * (-this->kinematic_viscosity * hessian_diagonal[i][k] +
-
910  gradient[i][k] * previous_values[k] +
-
911  previous_gradient[i][k] * value[k]);
-
912  }
-
913  // +(∂t δu)·τ∇q
-
914  if (transient)
-
915  gradient_result[dim][i] += tau * (*bdf_coefs)[0] * value[i];
-
916  }
-
917  // (∇δp)τ·∇q
-
918  gradient_result[dim] += tau * gradient[dim];
-
919 
-
920  // SUPG Jacobian
-
921  for (unsigned int i = 0; i < dim; ++i)
-
922  {
-
923  for (unsigned int k = 0; k < dim; ++k)
-
924  {
-
925  // Part 1
-
926  for (unsigned int l = 0; l < dim; ++l)
-
927  {
-
928  // +((u·∇)δu + (δu·∇)u - ν∆δu)Ï„(u·∇)v
-
929  gradient_result[i][k] +=
-
930  tau * previous_values[k] *
-
931  (gradient[i][l] * previous_values[l] +
-
932  previous_gradient[i][l] * value[l] -
-
933  this->kinematic_viscosity * hessian_diagonal[i][l]);
-
934  }
-
935  // +(∇δp)Ï„(u·∇)v
-
936  gradient_result[i][k] +=
-
937  tau * previous_values[k] * (gradient[dim][i]);
-
938 
-
939  // +(∂t δu)Ï„(u·∇)v
-
940  if (transient)
-
941  gradient_result[i][k] +=
-
942  tau * previous_values[k] * ((*bdf_coefs)[0] * value[i]);
-
943 
-
944 
-
945  // Part 2
-
946  for (unsigned int l = 0; l < dim; ++l)
-
947  {
-
948  // +((u·∇)u - ν∆u)Ï„(δu·∇)v
-
949  gradient_result[i][k] +=
-
950  tau * value[k] *
-
951  (previous_gradient[i][l] * previous_values[l] -
-
952  this->kinematic_viscosity *
-
953  previous_hessian_diagonal[i][l]);
-
954  }
-
955  // +(∇p - f)Ï„(δu·∇)v
-
956  gradient_result[i][k] +=
-
957  tau * value[k] * (previous_gradient[dim][i] - source_value[i]);
-
958 
-
959  // +(∂t u)Ï„(δu·∇)v
-
960  if (transient)
-
961  gradient_result[i][k] += tau * value[k] *
-
962  ((*bdf_coefs)[0] * previous_values[i] +
-
963  previous_time_derivatives[i]);
-
964  }
-
965  }
-
966 
-
967  if (this->stabilization ==
- -
969  {
-
970  // GLS Jacobian
-
971  for (unsigned int i = 0; i < dim; ++i)
-
972  {
-
973  for (unsigned int k = 0; k < dim; ++k)
-
974  {
-
975  if (this->enable_hessians_jacobian)
-
976  {
-
977  for (unsigned int l = 0; l < dim; ++l)
-
978  {
-
979  // +((u·∇)δu + (δu·∇)u - ν∆δu)Ï„(−ν∆v)
-
980  hessian_result[i][k][k] +=
-
981  tau * -this->kinematic_viscosity *
-
982  (gradient[i][l] * previous_values[l] +
-
983  previous_gradient[i][l] * value[l] -
-
984  this->kinematic_viscosity *
-
985  hessian_diagonal[i][l]);
-
986  }
+
905  // ν(∇v,∇δu)
+
906  gradient_result[i] = this->kinematic_viscosity * gradient[i];
+
907  // -(∇·v,δp)
+
908  gradient_result[i][i] += -value[dim];
+
909  // +(q,∇δu)
+
910  value_result[dim] += gradient[i][i];
+
911 
+
912  for (unsigned int k = 0; k < dim; ++k)
+
913  {
+
914  // +(v,(u·∇)δu + (δu·∇)u)
+
915  value_result[i] += gradient[i][k] * previous_values[k] +
+
916  previous_gradient[i][k] * value[k];
+
917  }
+
918  // +(v,∂t δu)
+
919  if (transient)
+
920  value_result[i] += (*bdf_coefs)[0] * value[i];
+
921  }
+
922 
+
923  // PSPG Jacobian
+
924  for (unsigned int i = 0; i < dim; ++i)
+
925  {
+
926  for (unsigned int k = 0; k < dim; ++k)
+
927  {
+
928  // (-ν∆δu + (u·∇)δu + (δu·∇)u)·τ∇q
+
929  gradient_result[dim][i] +=
+
930  tau * (-this->kinematic_viscosity * hessian_diagonal[i][k] +
+
931  gradient[i][k] * previous_values[k] +
+
932  previous_gradient[i][k] * value[k]);
+
933  }
+
934  // +(∂t δu)·τ∇q
+
935  if (transient)
+
936  gradient_result[dim][i] += tau * (*bdf_coefs)[0] * value[i];
+
937  }
+
938  // (∇δp)τ·∇q
+
939  gradient_result[dim] += tau * gradient[dim];
+
940 
+
941  // SUPG Jacobian
+
942  for (unsigned int i = 0; i < dim; ++i)
+
943  {
+
944  for (unsigned int k = 0; k < dim; ++k)
+
945  {
+
946  // Part 1
+
947  for (unsigned int l = 0; l < dim; ++l)
+
948  {
+
949  // +((u·∇)δu + (δu·∇)u - ν∆δu)Ï„(u·∇)v
+
950  gradient_result[i][k] +=
+
951  tau * previous_values[k] *
+
952  (gradient[i][l] * previous_values[l] +
+
953  previous_gradient[i][l] * value[l] -
+
954  this->kinematic_viscosity * hessian_diagonal[i][l]);
+
955  }
+
956  // +(∇δp)Ï„(u·∇)v
+
957  gradient_result[i][k] +=
+
958  tau * previous_values[k] * (gradient[dim][i]);
+
959 
+
960  // +(∂t δu)Ï„(u·∇)v
+
961  if (transient)
+
962  gradient_result[i][k] +=
+
963  tau * previous_values[k] * ((*bdf_coefs)[0] * value[i]);
+
964 
+
965 
+
966  // Part 2
+
967  for (unsigned int l = 0; l < dim; ++l)
+
968  {
+
969  // +((u·∇)u - ν∆u)Ï„(δu·∇)v
+
970  gradient_result[i][k] +=
+
971  tau * value[k] *
+
972  (previous_gradient[i][l] * previous_values[l] -
+
973  this->kinematic_viscosity *
+
974  previous_hessian_diagonal[i][l]);
+
975  }
+
976  // +(∇p - f)Ï„(δu·∇)v
+
977  gradient_result[i][k] +=
+
978  tau * value[k] * (previous_gradient[dim][i] - source_value[i]);
+
979 
+
980  // +(∂t u)Ï„(δu·∇)v
+
981  if (transient)
+
982  gradient_result[i][k] += tau * value[k] *
+
983  ((*bdf_coefs)[0] * previous_values[i] +
+
984  previous_time_derivatives[i]);
+
985  }
+
986  }
987 
-
988  // +(∇δp)Ï„(−ν∆v)
-
989  hessian_result[i][k][k] +=
-
990  tau * -this->kinematic_viscosity * (gradient[dim][i]);
-
991 
-
992  // +(∂t δu)Ï„(−ν∆v)
-
993  if (transient)
-
994  hessian_result[i][k][k] += tau *
-
995  -this->kinematic_viscosity *
-
996  ((*bdf_coefs)[0] * value[i]);
-
997  }
-
998 
-
999  // LSIC term
-
1000  // (∇·δu)Ï„'(∇·v)
-
1001  gradient_result[i][i] += tau_lsic * gradient[k][k];
-
1002  }
-
1003  }
-
1004  }
-
1005 
-
1006  integrator.submit_gradient(gradient_result, q);
-
1007  integrator.submit_value(value_result, q);
+
988  if (this->stabilization ==
+ +
990  {
+
991  // GLS Jacobian
+
992  for (unsigned int i = 0; i < dim; ++i)
+
993  {
+
994  for (unsigned int k = 0; k < dim; ++k)
+
995  {
+
996  if (this->enable_hessians_jacobian)
+
997  {
+
998  for (unsigned int l = 0; l < dim; ++l)
+
999  {
+
1000  // +((u·∇)δu + (δu·∇)u - ν∆δu)Ï„(−ν∆v)
+
1001  hessian_result[i][k][k] +=
+
1002  tau * -this->kinematic_viscosity *
+
1003  (gradient[i][l] * previous_values[l] +
+
1004  previous_gradient[i][l] * value[l] -
+
1005  this->kinematic_viscosity *
+
1006  hessian_diagonal[i][l]);
+
1007  }
1008 
-
1009  if (this->enable_hessians_jacobian)
-
1010  integrator.submit_hessian(hessian_result, q);
-
1011  }
+
1009  // +(∇δp)Ï„(−ν∆v)
+
1010  hessian_result[i][k][k] +=
+
1011  tau * -this->kinematic_viscosity * (gradient[dim][i]);
1012 
-
1013  if (this->enable_hessians_jacobian)
-
1014  integrator.integrate(EvaluationFlags::values | EvaluationFlags::gradients |
-
1015  EvaluationFlags::hessians);
-
1016  else
-
1017  integrator.integrate(EvaluationFlags::values | EvaluationFlags::gradients);
-
1018 }
-
1019 
-
1020 /**
-
1021  * The expressions calculated in this cell integral are:
-
1022  * (q, ∇·u) + (v,∂t u) + (v,(u·∇)u) - (∇·v,p) + ν(∇v,∇u) - (v,f) (Weak form),
-
1023  * plus two additional terms in the case of SUPG-PSPG stabilization:
-
1024  * \+ (∂t u +(u·∇)u + ∇p - ν∆u - f)τ∇·q (PSPG term)
-
1025  * \+ (∂t u +(u·∇)u + ∇p - ν∆u - f)Ï„u·∇v (SUPG term),
-
1026  * plus two additional terms in the case of full gls stabilization:
-
1027  * \+ (∂t u +(u·∇)u + ∇p - ν∆u - f)Ï„(−ν∆v) (GLS term)
-
1028  * \+ (∇·u)Ï„'(∇·v) (LSIC term).
-
1029  */
-
1030 template <int dim, typename number>
-
1031 void
- -
1033  const MatrixFree<dim, number> &matrix_free,
-
1034  VectorType &dst,
-
1035  const VectorType &src,
-
1036  const std::pair<unsigned int, unsigned int> &range) const
-
1037 {
-
1038  FECellIntegrator integrator(matrix_free);
-
1039 
-
1040  for (unsigned int cell = range.first; cell < range.second; ++cell)
-
1041  {
-
1042  integrator.reinit(cell);
-
1043  integrator.read_dof_values_plain(src);
-
1044 
-
1045  if (this->enable_hessians_residual)
-
1046  integrator.evaluate(EvaluationFlags::values |
-
1047  EvaluationFlags::gradients |
-
1048  EvaluationFlags::hessians);
-
1049  else
-
1050  integrator.evaluate(EvaluationFlags::values |
-
1051  EvaluationFlags::gradients);
-
1052 
-
1053  // To identify whether the problem is transient or steady
-
1054  bool transient =
-
1055  (is_bdf(this->simulation_control->get_assembly_method())) ? true :
-
1056  false;
-
1057 
-
1058  // Vector for BDF coefficients
-
1059  const Vector<double> *bdf_coefs;
-
1060  if (transient)
-
1061  bdf_coefs = &this->simulation_control->get_bdf_coefficients();
-
1062 
-
1063  for (const auto q : integrator.quadrature_point_indices())
-
1064  {
-
1065  Tensor<1, dim, VectorizedArray<number>> source_value;
-
1066 
-
1067  // Evaluate source term function if enabled
-
1068  if (this->forcing_function)
-
1069  {
-
1070  Point<dim, VectorizedArray<number>> point_batch =
-
1071  integrator.quadrature_point(q);
-
1072  source_value =
-
1073  evaluate_function<dim, number, dim>(*(this->forcing_function),
-
1074  point_batch);
-
1075  }
-
1076 
-
1077  // Add to source term the dynamic flow control force (zero if not
-
1078  // enabled)
-
1079  source_value += this->beta_force;
-
1080 
-
1081  // Gather the original value/gradient
-
1082  typename FECellIntegrator::value_type value = integrator.get_value(q);
-
1083  typename FECellIntegrator::gradient_type gradient =
-
1084  integrator.get_gradient(q);
-
1085  typename FECellIntegrator::gradient_type hessian_diagonal;
-
1086 
-
1087  if (this->enable_hessians_residual)
-
1088  hessian_diagonal = integrator.get_hessian_diagonal(q);
-
1089 
-
1090  // Time derivatives of previous solutions
-
1091  Tensor<1, dim + 1, VectorizedArray<number>> previous_time_derivatives;
-
1092  if (transient)
-
1093  previous_time_derivatives =
-
1094  this->time_derivatives_previous_solutions(cell, q);
-
1095 
-
1096  // Get stabilization parameter
-
1097  const auto tau = this->stabilization_parameter[cell][q];
-
1098  const auto tau_lsic = this->stabilization_parameter_lsic[cell][q];
-
1099 
-
1100  // Result value/gradient we will use
-
1101  typename FECellIntegrator::value_type value_result;
-
1102  typename FECellIntegrator::gradient_type gradient_result;
-
1103  typename FECellIntegrator::hessian_type hessian_result;
-
1104 
-
1105  // Weak form
-
1106  for (unsigned int i = 0; i < dim; ++i)
-
1107  {
-
1108  // ν(∇v,∇u)
-
1109  gradient_result[i] = this->kinematic_viscosity * gradient[i];
-
1110  // -(∇·v,p)
-
1111  gradient_result[i][i] += -value[dim];
-
1112  // +(v,-f)
-
1113  value_result[i] = -source_value[i];
-
1114 
-
1115  // +(v,∂t u)
-
1116  if (transient)
-
1117  value_result[i] +=
-
1118  (*bdf_coefs)[0] * value[i] + previous_time_derivatives[i];
-
1119 
+
1013  // +(∂t δu)Ï„(−ν∆v)
+
1014  if (transient)
+
1015  hessian_result[i][k][k] += tau *
+
1016  -this->kinematic_viscosity *
+
1017  ((*bdf_coefs)[0] * value[i]);
+
1018  }
+
1019 
+
1020  // LSIC term
+
1021  // (∇·δu)Ï„'(∇·v)
+
1022  gradient_result[i][i] += tau_lsic * gradient[k][k];
+
1023  }
+
1024  }
+
1025  }
+
1026 
+
1027  integrator.submit_gradient(gradient_result, q);
+
1028  integrator.submit_value(value_result, q);
+
1029 
+
1030  if (this->enable_hessians_jacobian)
+
1031  integrator.submit_hessian(hessian_result, q);
+
1032  }
+
1033 
+
1034  if (this->enable_hessians_jacobian)
+
1035  integrator.integrate(EvaluationFlags::values | EvaluationFlags::gradients |
+
1036  EvaluationFlags::hessians);
+
1037  else
+
1038  integrator.integrate(EvaluationFlags::values | EvaluationFlags::gradients);
+
1039 }
+
1040 
+
1041 /**
+
1042  * The expressions calculated in this cell integral are:
+
1043  * (q, ∇·u) + (v,∂t u) + (v,(u·∇)u) - (∇·v,p) + ν(∇v,∇u) - (v,f) (Weak form),
+
1044  * plus two additional terms in the case of SUPG-PSPG stabilization:
+
1045  * \+ (∂t u +(u·∇)u + ∇p - ν∆u - f)τ∇·q (PSPG term)
+
1046  * \+ (∂t u +(u·∇)u + ∇p - ν∆u - f)Ï„u·∇v (SUPG term),
+
1047  * plus two additional terms in the case of full gls stabilization:
+
1048  * \+ (∂t u +(u·∇)u + ∇p - ν∆u - f)Ï„(−ν∆v) (GLS term)
+
1049  * \+ (∇·u)Ï„'(∇·v) (LSIC term).
+
1050  */
+
1051 template <int dim, typename number>
+
1052 void
+ +
1054  const MatrixFree<dim, number> &matrix_free,
+
1055  VectorType &dst,
+
1056  const VectorType &src,
+
1057  const std::pair<unsigned int, unsigned int> &range) const
+
1058 {
+
1059  FECellIntegrator integrator(matrix_free);
+
1060 
+
1061  for (unsigned int cell = range.first; cell < range.second; ++cell)
+
1062  {
+
1063  integrator.reinit(cell);
+
1064  integrator.read_dof_values_plain(src);
+
1065 
+
1066  if (this->enable_hessians_residual)
+
1067  integrator.evaluate(EvaluationFlags::values |
+
1068  EvaluationFlags::gradients |
+
1069  EvaluationFlags::hessians);
+
1070  else
+
1071  integrator.evaluate(EvaluationFlags::values |
+
1072  EvaluationFlags::gradients);
+
1073 
+
1074  // To identify whether the problem is transient or steady
+
1075  bool transient =
+
1076  (is_bdf(this->simulation_control->get_assembly_method())) ? true :
+
1077  false;
+
1078 
+
1079  // Vector for BDF coefficients
+
1080  const Vector<double> *bdf_coefs;
+
1081  if (transient)
+
1082  bdf_coefs = &this->simulation_control->get_bdf_coefficients();
+
1083 
+
1084  for (const auto q : integrator.quadrature_point_indices())
+
1085  {
+
1086  Tensor<1, dim, VectorizedArray<number>> source_value;
+
1087 
+
1088  // Evaluate source term function if enabled
+
1089  if (this->forcing_function)
+
1090  {
+
1091  Point<dim, VectorizedArray<number>> point_batch =
+
1092  integrator.quadrature_point(q);
+
1093  source_value =
+
1094  evaluate_function<dim, number, dim>(*(this->forcing_function),
+
1095  point_batch);
+
1096  }
+
1097 
+
1098  // Add to source term the dynamic flow control force (zero if not
+
1099  // enabled)
+
1100  source_value += this->beta_force;
+
1101 
+
1102  // Gather the original value/gradient
+
1103  typename FECellIntegrator::value_type value = integrator.get_value(q);
+
1104  typename FECellIntegrator::gradient_type gradient =
+
1105  integrator.get_gradient(q);
+
1106  typename FECellIntegrator::gradient_type hessian_diagonal;
+
1107 
+
1108  if (this->enable_hessians_residual)
+
1109  hessian_diagonal = integrator.get_hessian_diagonal(q);
+
1110 
+
1111  // Time derivatives of previous solutions
+
1112  Tensor<1, dim + 1, VectorizedArray<number>> previous_time_derivatives;
+
1113  if (transient)
+
1114  previous_time_derivatives =
+
1115  this->time_derivatives_previous_solutions(cell, q);
+
1116 
+
1117  // Get stabilization parameter
+
1118  const auto tau = this->stabilization_parameter[cell][q];
+
1119  const auto tau_lsic = this->stabilization_parameter_lsic[cell][q];
1120 
-
1121  // +(q,∇·u)
-
1122  value_result[dim] += gradient[i][i];
-
1123 
-
1124  for (unsigned int k = 0; k < dim; ++k)
-
1125  {
-
1126  // +(v,(u·∇)u)
-
1127  value_result[i] += gradient[i][k] * value[k];
-
1128  }
-
1129  }
-
1130 
-
1131  // PSPG term
-
1132  for (unsigned int i = 0; i < dim; ++i)
-
1133  {
-
1134  for (unsigned int k = 0; k < dim; ++k)
-
1135  {
-
1136  // (-ν∆u + (u·∇)u)·τ∇q
-
1137  gradient_result[dim][i] +=
-
1138  tau * (-this->kinematic_viscosity * hessian_diagonal[i][k] +
-
1139  gradient[i][k] * value[k]);
-
1140  }
-
1141  // +(-f)·τ∇q
-
1142  gradient_result[dim][i] += tau * (-source_value[i]);
-
1143 
-
1144  // +(∂t u)·τ∇q
-
1145  if (transient)
-
1146  gradient_result[dim][i] += tau * ((*bdf_coefs)[0] * value[i] +
-
1147  previous_time_derivatives[i]);
-
1148  }
-
1149  // +(∇p)τ∇·q
-
1150  gradient_result[dim] += tau * gradient[dim];
+
1121  // Result value/gradient we will use
+
1122  typename FECellIntegrator::value_type value_result;
+
1123  typename FECellIntegrator::gradient_type gradient_result;
+
1124  typename FECellIntegrator::hessian_type hessian_result;
+
1125 
+
1126  // Weak form
+
1127  for (unsigned int i = 0; i < dim; ++i)
+
1128  {
+
1129  // ν(∇v,∇u)
+
1130  gradient_result[i] = this->kinematic_viscosity * gradient[i];
+
1131  // -(∇·v,p)
+
1132  gradient_result[i][i] += -value[dim];
+
1133  // +(v,-f)
+
1134  value_result[i] = -source_value[i];
+
1135 
+
1136  // +(v,∂t u)
+
1137  if (transient)
+
1138  value_result[i] +=
+
1139  (*bdf_coefs)[0] * value[i] + previous_time_derivatives[i];
+
1140 
+
1141 
+
1142  // +(q,∇·u)
+
1143  value_result[dim] += gradient[i][i];
+
1144 
+
1145  for (unsigned int k = 0; k < dim; ++k)
+
1146  {
+
1147  // +(v,(u·∇)u)
+
1148  value_result[i] += gradient[i][k] * value[k];
+
1149  }
+
1150  }
1151 
-
1152  // SUPG term
+
1152  // PSPG term
1153  for (unsigned int i = 0; i < dim; ++i)
1154  {
1155  for (unsigned int k = 0; k < dim; ++k)
1156  {
-
1157  for (unsigned int l = 0; l < dim; ++l)
-
1158  {
-
1159  // (-ν∆u)Ï„(u·∇)v
-
1160  gradient_result[i][k] +=
-
1161  -tau * this->kinematic_viscosity * value[k] *
-
1162  hessian_diagonal[i][l];
-
1163 
-
1164  // + ((u·∇)u)Ï„(u·∇)v
-
1165  gradient_result[i][k] +=
-
1166  tau * value[k] * gradient[i][l] * value[l];
-
1167  }
-
1168  // + (∇p - f)Ï„(u·∇)v
-
1169  gradient_result[i][k] +=
-
1170  tau * value[k] * (gradient[dim][i] - source_value[i]);
-
1171 
-
1172  // + (∂t u)Ï„(u·∇)v
-
1173  if (transient)
-
1174  gradient_result[i][k] += tau * value[k] *
-
1175  ((*bdf_coefs)[0] * value[i] +
-
1176  previous_time_derivatives[i]);
-
1177  }
-
1178  }
-
1179 
-
1180  if (this->stabilization ==
- -
1182  {
-
1183  // GLS term
-
1184  for (unsigned int i = 0; i < dim; ++i)
-
1185  {
-
1186  for (unsigned int k = 0; k < dim; ++k)
-
1187  {
-
1188  if (this->enable_hessians_residual)
-
1189  {
-
1190  for (unsigned int l = 0; l < dim; ++l)
-
1191  {
-
1192  // (-ν∆u + (u·∇)u)Ï„(−ν∆v)
-
1193  hessian_result[i][k][k] +=
-
1194  tau * -this->kinematic_viscosity *
-
1195  (-this->kinematic_viscosity *
-
1196  hessian_diagonal[i][l] +
-
1197  gradient[i][l] * value[l]);
-
1198  }
-
1199  // + (∇p - f)Ï„(−ν∆v)
-
1200  hessian_result[i][k][k] +=
-
1201  tau * -this->kinematic_viscosity *
-
1202  (gradient[dim][i] - source_value[i]);
-
1203 
-
1204  // + (∂t u)Ï„(−ν∆v)
-
1205  if (transient)
-
1206  hessian_result[i][k][k] +=
-
1207  tau * -this->kinematic_viscosity *
-
1208  ((*bdf_coefs)[0] * value[i] +
-
1209  previous_time_derivatives[i]);
-
1210  }
-
1211 
-
1212  // LSIC term
-
1213  // (∇·u)Ï„'(∇·v)
-
1214  gradient_result[i][i] += tau_lsic * gradient[k][k];
-
1215  }
-
1216  }
-
1217  }
-
1218 
-
1219  integrator.submit_gradient(gradient_result, q);
-
1220  integrator.submit_value(value_result, q);
-
1221  if (this->enable_hessians_residual)
-
1222  integrator.submit_hessian(hessian_result, q);
-
1223  }
+
1157  // (-ν∆u + (u·∇)u)·τ∇q
+
1158  gradient_result[dim][i] +=
+
1159  tau * (-this->kinematic_viscosity * hessian_diagonal[i][k] +
+
1160  gradient[i][k] * value[k]);
+
1161  }
+
1162  // +(-f)·τ∇q
+
1163  gradient_result[dim][i] += tau * (-source_value[i]);
+
1164 
+
1165  // +(∂t u)·τ∇q
+
1166  if (transient)
+
1167  gradient_result[dim][i] += tau * ((*bdf_coefs)[0] * value[i] +
+
1168  previous_time_derivatives[i]);
+
1169  }
+
1170  // +(∇p)τ∇·q
+
1171  gradient_result[dim] += tau * gradient[dim];
+
1172 
+
1173  // SUPG term
+
1174  for (unsigned int i = 0; i < dim; ++i)
+
1175  {
+
1176  for (unsigned int k = 0; k < dim; ++k)
+
1177  {
+
1178  for (unsigned int l = 0; l < dim; ++l)
+
1179  {
+
1180  // (-ν∆u)Ï„(u·∇)v
+
1181  gradient_result[i][k] +=
+
1182  -tau * this->kinematic_viscosity * value[k] *
+
1183  hessian_diagonal[i][l];
+
1184 
+
1185  // + ((u·∇)u)Ï„(u·∇)v
+
1186  gradient_result[i][k] +=
+
1187  tau * value[k] * gradient[i][l] * value[l];
+
1188  }
+
1189  // + (∇p - f)Ï„(u·∇)v
+
1190  gradient_result[i][k] +=
+
1191  tau * value[k] * (gradient[dim][i] - source_value[i]);
+
1192 
+
1193  // + (∂t u)Ï„(u·∇)v
+
1194  if (transient)
+
1195  gradient_result[i][k] += tau * value[k] *
+
1196  ((*bdf_coefs)[0] * value[i] +
+
1197  previous_time_derivatives[i]);
+
1198  }
+
1199  }
+
1200 
+
1201  if (this->stabilization ==
+ +
1203  {
+
1204  // GLS term
+
1205  for (unsigned int i = 0; i < dim; ++i)
+
1206  {
+
1207  for (unsigned int k = 0; k < dim; ++k)
+
1208  {
+
1209  if (this->enable_hessians_residual)
+
1210  {
+
1211  for (unsigned int l = 0; l < dim; ++l)
+
1212  {
+
1213  // (-ν∆u + (u·∇)u)Ï„(−ν∆v)
+
1214  hessian_result[i][k][k] +=
+
1215  tau * -this->kinematic_viscosity *
+
1216  (-this->kinematic_viscosity *
+
1217  hessian_diagonal[i][l] +
+
1218  gradient[i][l] * value[l]);
+
1219  }
+
1220  // + (∇p - f)Ï„(−ν∆v)
+
1221  hessian_result[i][k][k] +=
+
1222  tau * -this->kinematic_viscosity *
+
1223  (gradient[dim][i] - source_value[i]);
1224 
-
1225  if (this->enable_hessians_residual)
-
1226  integrator.integrate_scatter(EvaluationFlags::values |
-
1227  EvaluationFlags::gradients |
-
1228  EvaluationFlags::hessians,
-
1229  dst);
-
1230  else
-
1231  integrator.integrate_scatter(EvaluationFlags::values |
-
1232  EvaluationFlags::gradients,
-
1233  dst);
-
1234  }
-
1235 }
-
1236 
- - +
1225  // + (∂t u)Ï„(−ν∆v)
+
1226  if (transient)
+
1227  hessian_result[i][k][k] +=
+
1228  tau * -this->kinematic_viscosity *
+
1229  ((*bdf_coefs)[0] * value[i] +
+
1230  previous_time_derivatives[i]);
+
1231  }
+
1232 
+
1233  // LSIC term
+
1234  // (∇·u)Ï„'(∇·v)
+
1235  gradient_result[i][i] += tau_lsic * gradient[k][k];
+
1236  }
+
1237  }
+
1238  }
+
1239 
+
1240  integrator.submit_gradient(gradient_result, q);
+
1241  integrator.submit_value(value_result, q);
+
1242  if (this->enable_hessians_residual)
+
1243  integrator.submit_hessian(hessian_result, q);
+
1244  }
+
1245 
+
1246  if (this->enable_hessians_residual)
+
1247  integrator.integrate_scatter(EvaluationFlags::values |
+
1248  EvaluationFlags::gradients |
+
1249  EvaluationFlags::hessians,
+
1250  dst);
+
1251  else
+
1252  integrator.integrate_scatter(EvaluationFlags::values |
+
1253  EvaluationFlags::gradients,
+
1254  dst);
+
1255  }
+
1256 }
+
1257 
+ +
A class that serves as base for all the matrix-free Navier-Stokes operators.
number el(unsigned int, unsigned int) const
Access a particular element in the matrix. Only required for compilation and it is not used.
virtual void local_evaluate_residual(const MatrixFree< dim, number > &matrix_free, VectorType &dst, const VectorType &src, const std::pair< unsigned int, unsigned int > &range) const =0
Interface to function in charge of computing the residual using a cell integral in a cell batch with ...
-
void evaluate_non_linear_term_and_calculate_tau(const VectorType &newton_step)
Store relevant values of the vector of the last newton step to use it in the Jacobian and pre-calcula...
-
void update_beta_force(const Tensor< 1, dim > &beta_force)
Store the values of the source term calculated if dynamic control is enabled in the appropriate struc...
+
void evaluate_non_linear_term_and_calculate_tau(const VectorType &newton_step)
Store relevant values of the vector of the last newton step to use it in the Jacobian and pre-calcula...
+
void update_beta_force(const Tensor< 1, dim > &beta_force)
Store the values of the source term calculated if dynamic control is enabled in the appropriate struc...
bool enable_hessians_jacobian
Flag to turn hessian terms from jacobian on or off.
AffineConstraints< number > constraints
Object that stores constraints for the matrix free implementation.
bool enable_hessians_residual
Flag to turn hessian terms from residual on or off.
void clear()
Clear the matrix-free object.
-
void vmult_interface_down(VectorType &dst, VectorType const &src) const
Vmult operator for an interface. Required only if local smoothing multigrid is used and for meshes wi...
+
void vmult_interface_down(VectorType &dst, VectorType const &src) const
Vmult operator for an interface. Required only if local smoothing multigrid is used and for meshes wi...
void vmult(VectorType &dst, const VectorType &src) const
Perform an operator evaluation dst = A*src by looping with the help of the MatrixFree object over all...
const std::shared_ptr< const Utilities::MPI::Partitioner > & get_vector_partitioner() const
Get the vector partitioner object required for local smoothing multigrid preconditioner.
void compute_element_size()
Compute the element size h of the cells required to calculate stabilization parameters.
types::global_dof_index m() const
Get the total number of DoFs.
std::shared_ptr< Function< dim > > forcing_function
Force function or source function for the Navier-Stokes equations.
void reinit(const Mapping< dim > &mapping, const DoFHandler< dim > &dof_handler, const AffineConstraints< number > &constraints, const Quadrature< dim > &quadrature, const std::shared_ptr< Function< dim >> forcing_function, const double kinematic_viscosity, const StabilizationType stabilization, const unsigned int mg_level, std::shared_ptr< SimulationControl > simulation_control, const bool &enable_hessians_jacobian, const bool &enable_hessians_residual)
Initialize the main matrix free object that contains all data and is needed to perform loops over cel...
-
void evaluate_residual(VectorType &dst, const VectorType &src)
Evaluate right hand side using the matrix-free operator.
-
void evaluate_time_derivative_previous_solutions(const VectorType &time_derivative_previous_solutions)
Store the values of the vector containing the time derivatives of previous solutions to use them in t...
-
void do_cell_integral_range(const MatrixFree< dim, number > &matrix_free, VectorType &dst, const VectorType &src, const std::pair< unsigned int, unsigned int > &range) const
Loop over all cell batches within certain range and perform a cell integral with access to global vec...
+
void evaluate_residual(VectorType &dst, const VectorType &src)
Evaluate right hand side using the matrix-free operator.
+
void evaluate_time_derivative_previous_solutions(const VectorType &time_derivative_previous_solutions)
Store the values of the vector containing the time derivatives of previous solutions to use them in t...
+
void do_cell_integral_range(const MatrixFree< dim, number > &matrix_free, VectorType &dst, const VectorType &src, const std::pair< unsigned int, unsigned int > &range) const
Loop over all cell batches within certain range and perform a cell integral with access to global vec...
FEEvaluation< dim, -1, 0, dim+1, number > FECellIntegrator
-
void compute_inverse_diagonal(VectorType &diagonal) const
Compute the diagonal of the operator using an optimized MatrixFree function. Needed for preconditione...
+
void compute_inverse_diagonal(VectorType &diagonal) const
Compute the diagonal of the operator using an optimized MatrixFree function. Needed for preconditione...
virtual void do_cell_integral_local(FECellIntegrator &integrator) const =0
Interface to function that performs a cell integral in a cell batch without gathering and scattering ...
double kinematic_viscosity
Kinematic viscosity needed for the operator.
-
static IndexSet get_refinement_edges(const MatrixFree< dim, number > &matrix_free)
Get the refinement edges. Only needed if the local smoothing multigrid approach is used.
+
static IndexSet get_refinement_edges(const MatrixFree< dim, number > &matrix_free)
Get the refinement edges. Only needed if the local smoothing multigrid approach is used.
StabilizationType stabilization
Stabilization type needed to add or remove terms from operator.
std::shared_ptr< SimulationControl > simulation_control
Object storing the information regarding the time stepping method.
NavierStokesOperatorBase()
Default constructor.
-
const AlignedVector< VectorizedArray< number > > get_element_size() const
Get the element size object.
+
const AlignedVector< VectorizedArray< number > > get_element_size() const
Get the element size object.
void initialize_dof_vector(VectorType &vec) const
Initialize a given vector by delegating it to the MatrixFree function in charge of this task.
-
const MatrixFree< dim, number > & get_system_matrix_free() const
Get the system matrix free object.
-
void Tvmult(VectorType &dst, const VectorType &src) const
Perform the transposed operator evaluation.
-
void vmult_interface_up(VectorType &dst, VectorType const &src) const
Vmult operator for an interface. Required only if local smoothing multigrid is used and for meshes wi...
+
const MatrixFree< dim, number > & get_system_matrix_free() const
Get the system matrix free object.
+
void Tvmult(VectorType &dst, const VectorType &src) const
Perform the transposed operator evaluation.
+
void vmult_interface_up(VectorType &dst, VectorType const &src) const
Vmult operator for an interface. Required only if local smoothing multigrid is used and for meshes wi...
LinearAlgebra::distributed::Vector< number > VectorType
-
const TrilinosWrappers::SparseMatrix & get_system_matrix() const
Calculate matrix if needed, e.g., by coarse-grid solver when a multigrid algorithm is used.
+
const TrilinosWrappers::SparseMatrix & get_system_matrix() const
Calculate matrix if needed, e.g., by coarse-grid solver when a multigrid algorithm is used.
Implements the matrix-free operator to solve steady/transient Navier-Stokes equations using stabiliza...
-
void local_evaluate_residual(const MatrixFree< dim, number > &matrix_free, VectorType &dst, const VectorType &src, const std::pair< unsigned int, unsigned int > &range) const override
Perform cell integral on a cell batch with gathering and scattering the values, and according to the ...
-
void do_cell_integral_local(FECellIntegrator &integrator) const override
Perform cell integral on a cell batch without gathering and scattering the values,...
+
void local_evaluate_residual(const MatrixFree< dim, number > &matrix_free, VectorType &dst, const VectorType &src, const std::pair< unsigned int, unsigned int > &range) const override
Perform cell integral on a cell batch with gathering and scattering the values, and according to the ...
+
void do_cell_integral_local(FECellIntegrator &integrator) const override
Perform cell integral on a cell batch without gathering and scattering the values,...
const Table< 2, bool > create_bool_dof_mask(const FiniteElement< dim, spacedim > &fe, const Quadrature< dim > &quadrature)
Creates and fills a table that works as bool dof mask object needed for the sparsity pattern and comp...
VectorizedArray< Number > evaluate_function(const Function< dim > &function, const Point< dim, VectorizedArray< Number >> &p_vectorized)
Matrix free helper function.
diff --git a/doxygen/navier__stokes__base_8cc_source.html b/doxygen/navier__stokes__base_8cc_source.html index 3dc9e67e69..cb1d48e300 100644 --- a/doxygen/navier__stokes__base_8cc_source.html +++ b/doxygen/navier__stokes__base_8cc_source.html @@ -1203,1639 +1203,1643 @@
1122  if (this->simulation_parameters.post_processing.calculate_average_velocities)
1123  average_velocities->post_mesh_adaptation();
1124 
-
1125  this->update_multiphysics_time_average_solution();
-
1126 }
-
1127 
-
1128 template <int dim, typename VectorType, typename DofsType>
-
1129 void
- -
1131 {
-
1132  TimerOutput::Scope t(this->computing_timer, "Refine");
-
1133 
-
1134  // Solution transfer objects for all the solutions
-
1135  parallel::distributed::SolutionTransfer<dim, VectorType> solution_transfer(
-
1136  this->dof_handler);
-
1137  parallel::distributed::SolutionTransfer<dim, VectorType> solution_transfer_m2(
+
1125  // Only needed if other physics apart from fluid dynamics are enabled.
+
1126  if (this->multiphysics->get_active_physics().size() > 1)
+
1127  this->update_multiphysics_time_average_solution();
+
1128 }
+
1129 
+
1130 template <int dim, typename VectorType, typename DofsType>
+
1131 void
+ +
1133 {
+
1134  TimerOutput::Scope t(this->computing_timer, "Refine");
+
1135 
+
1136  // Solution transfer objects for all the solutions
+
1137  parallel::distributed::SolutionTransfer<dim, VectorType> solution_transfer(
1138  this->dof_handler);
-
1139  parallel::distributed::SolutionTransfer<dim, VectorType> solution_transfer_m3(
+
1139  parallel::distributed::SolutionTransfer<dim, VectorType> solution_transfer_m2(
1140  this->dof_handler);
-
1141 
-
1142  if constexpr (std::is_same_v<VectorType,
-
1143  LinearAlgebra::distributed::Vector<double>>)
-
1144  present_solution.update_ghost_values();
-
1145 
-
1146  solution_transfer.prepare_for_coarsening_and_refinement(
-
1147  this->present_solution);
-
1148 
-
1149  std::vector<parallel::distributed::SolutionTransfer<dim, VectorType>>
-
1150  previous_solutions_transfer;
-
1151  // Important to reserve to prevent pointer dangling
-
1152  previous_solutions_transfer.reserve(previous_solutions.size());
-
1153 
-
1154  for (unsigned int i = 0; i < previous_solutions.size(); ++i)
-
1155  {
-
1156  previous_solutions_transfer.emplace_back(
-
1157  parallel::distributed::SolutionTransfer<dim, VectorType>(
-
1158  this->dof_handler));
-
1159 
-
1160  if constexpr (std::is_same_v<VectorType,
-
1161  LinearAlgebra::distributed::Vector<double>>)
-
1162  previous_solutions[i].update_ghost_values();
-
1163 
-
1164  previous_solutions_transfer[i].prepare_for_coarsening_and_refinement(
-
1165  previous_solutions[i]);
-
1166  }
-
1167 
-
1168  multiphysics->prepare_for_mesh_adaptation();
+
1141  parallel::distributed::SolutionTransfer<dim, VectorType> solution_transfer_m3(
+
1142  this->dof_handler);
+
1143 
+
1144  if constexpr (std::is_same_v<VectorType,
+
1145  LinearAlgebra::distributed::Vector<double>>)
+
1146  present_solution.update_ghost_values();
+
1147 
+
1148  solution_transfer.prepare_for_coarsening_and_refinement(
+
1149  this->present_solution);
+
1150 
+
1151  std::vector<parallel::distributed::SolutionTransfer<dim, VectorType>>
+
1152  previous_solutions_transfer;
+
1153  // Important to reserve to prevent pointer dangling
+
1154  previous_solutions_transfer.reserve(previous_solutions.size());
+
1155 
+
1156  for (unsigned int i = 0; i < previous_solutions.size(); ++i)
+
1157  {
+
1158  previous_solutions_transfer.emplace_back(
+
1159  parallel::distributed::SolutionTransfer<dim, VectorType>(
+
1160  this->dof_handler));
+
1161 
+
1162  if constexpr (std::is_same_v<VectorType,
+
1163  LinearAlgebra::distributed::Vector<double>>)
+
1164  previous_solutions[i].update_ghost_values();
+
1165 
+
1166  previous_solutions_transfer[i].prepare_for_coarsening_and_refinement(
+
1167  previous_solutions[i]);
+
1168  }
1169 
-
1170  // Refine
-
1171  this->triangulation->refine_global(1);
-
1172 
-
1173  setup_dofs();
+
1170  multiphysics->prepare_for_mesh_adaptation();
+
1171 
+
1172  // Refine
+
1173  this->triangulation->refine_global(1);
1174 
-
1175  // Set up the vectors for the transfer
-
1176  VectorType tmp = init_temporary_vector();
-
1177 
-
1178  // Interpolate the solution at time and previous time
-
1179  solution_transfer.interpolate(tmp);
-
1180 
-
1181  // Distribute constraints
-
1182  auto &nonzero_constraints = this->nonzero_constraints;
-
1183  nonzero_constraints.distribute(tmp);
-
1184 
-
1185  // Fix on the new mesh
-
1186  present_solution = tmp;
-
1187 
-
1188  // Set up the vectors for the transfer
-
1189  for (unsigned int i = 0; i < previous_solutions.size(); ++i)
-
1190  {
-
1191  VectorType tmp_previous_solution = init_temporary_vector();
-
1192  previous_solutions_transfer[i].interpolate(tmp_previous_solution);
-
1193  nonzero_constraints.distribute(tmp_previous_solution);
-
1194  previous_solutions[i] = tmp_previous_solution;
-
1195  }
-
1196 
-
1197  multiphysics->post_mesh_adaptation();
-
1198  if (this->simulation_parameters.post_processing.calculate_average_velocities)
-
1199  average_velocities->post_mesh_adaptation();
-
1200 
-
1201  this->update_multiphysics_time_average_solution();
-
1202 }
-
1203 
-
1204 template <int dim, typename VectorType, typename DofsType>
-
1205 void
- -
1207 {
-
1208  auto &present_solution = this->present_solution;
-
1209 
-
1210  // Enstrophy
-
1211  if (this->simulation_parameters.post_processing.calculate_enstrophy)
-
1212  {
-
1213  TimerOutput::Scope t(this->computing_timer, "Calculate enstrophy");
-
1214 
-
1215  double enstrophy = calculate_enstrophy(this->dof_handler,
-
1216  present_solution,
-
1217  *this->cell_quadrature,
-
1218  *this->mapping);
-
1219 
-
1220  this->enstrophy_table.add_value("time",
-
1221  simulation_control->get_current_time());
-
1222  this->enstrophy_table.add_value("enstrophy", enstrophy);
+
1175  setup_dofs();
+
1176 
+
1177  // Set up the vectors for the transfer
+
1178  VectorType tmp = init_temporary_vector();
+
1179 
+
1180  // Interpolate the solution at time and previous time
+
1181  solution_transfer.interpolate(tmp);
+
1182 
+
1183  // Distribute constraints
+
1184  auto &nonzero_constraints = this->nonzero_constraints;
+
1185  nonzero_constraints.distribute(tmp);
+
1186 
+
1187  // Fix on the new mesh
+
1188  present_solution = tmp;
+
1189 
+
1190  // Set up the vectors for the transfer
+
1191  for (unsigned int i = 0; i < previous_solutions.size(); ++i)
+
1192  {
+
1193  VectorType tmp_previous_solution = init_temporary_vector();
+
1194  previous_solutions_transfer[i].interpolate(tmp_previous_solution);
+
1195  nonzero_constraints.distribute(tmp_previous_solution);
+
1196  previous_solutions[i] = tmp_previous_solution;
+
1197  }
+
1198 
+
1199  multiphysics->post_mesh_adaptation();
+
1200  if (this->simulation_parameters.post_processing.calculate_average_velocities)
+
1201  average_velocities->post_mesh_adaptation();
+
1202 
+
1203  // Only needed if other physics apart from fluid dynamics are enabled.
+
1204  if (this->multiphysics->get_active_physics().size() > 1)
+
1205  this->update_multiphysics_time_average_solution();
+
1206 }
+
1207 
+
1208 template <int dim, typename VectorType, typename DofsType>
+
1209 void
+ +
1211 {
+
1212  auto &present_solution = this->present_solution;
+
1213 
+
1214  // Enstrophy
+
1215  if (this->simulation_parameters.post_processing.calculate_enstrophy)
+
1216  {
+
1217  TimerOutput::Scope t(this->computing_timer, "Calculate enstrophy");
+
1218 
+
1219  double enstrophy = calculate_enstrophy(this->dof_handler,
+
1220  present_solution,
+
1221  *this->cell_quadrature,
+
1222  *this->mapping);
1223 
-
1224  // Display Enstrophy to screen if verbosity is enabled
-
1225  if (this->simulation_parameters.post_processing.verbosity ==
- -
1227  {
-
1228  this->pcout << "Enstrophy : " << enstrophy << std::endl;
-
1229  }
-
1230 
-
1231  // Output Enstrophy to a text file from processor 0
-
1232  if (simulation_control->get_step_number() %
-
1233  this->simulation_parameters.post_processing.output_frequency ==
-
1234  0 &&
-
1235  this->this_mpi_process == 0)
-
1236  {
-
1237  std::string filename =
-
1238  simulation_parameters.simulation_control.output_folder +
-
1239  simulation_parameters.post_processing.enstrophy_output_name +
-
1240  ".dat";
-
1241  std::ofstream output(filename.c_str());
-
1242  enstrophy_table.set_precision("time", 12);
-
1243  enstrophy_table.set_precision("enstrophy", 12);
-
1244  this->enstrophy_table.write_text(output);
-
1245  }
-
1246  }
-
1247 
-
1248  // Pressure power
-
1249  if (this->simulation_parameters.post_processing.calculate_pressure_power)
-
1250  {
-
1251  TimerOutput::Scope t(this->computing_timer, "Calculate pressure power");
-
1252 
-
1253  const double pressure_power =
-
1254  calculate_pressure_power(this->dof_handler,
-
1255  present_solution,
-
1256  *this->cell_quadrature,
-
1257  *this->mapping);
-
1258 
-
1259  this->pressure_power_table.add_value(
-
1260  "time", simulation_control->get_current_time());
-
1261  this->pressure_power_table.add_value("pressure_power", pressure_power);
+
1224  this->enstrophy_table.add_value("time",
+
1225  simulation_control->get_current_time());
+
1226  this->enstrophy_table.add_value("enstrophy", enstrophy);
+
1227 
+
1228  // Display Enstrophy to screen if verbosity is enabled
+
1229  if (this->simulation_parameters.post_processing.verbosity ==
+ +
1231  {
+
1232  this->pcout << "Enstrophy : " << enstrophy << std::endl;
+
1233  }
+
1234 
+
1235  // Output Enstrophy to a text file from processor 0
+
1236  if (simulation_control->get_step_number() %
+
1237  this->simulation_parameters.post_processing.output_frequency ==
+
1238  0 &&
+
1239  this->this_mpi_process == 0)
+
1240  {
+
1241  std::string filename =
+
1242  simulation_parameters.simulation_control.output_folder +
+
1243  simulation_parameters.post_processing.enstrophy_output_name +
+
1244  ".dat";
+
1245  std::ofstream output(filename.c_str());
+
1246  enstrophy_table.set_precision("time", 12);
+
1247  enstrophy_table.set_precision("enstrophy", 12);
+
1248  this->enstrophy_table.write_text(output);
+
1249  }
+
1250  }
+
1251 
+
1252  // Pressure power
+
1253  if (this->simulation_parameters.post_processing.calculate_pressure_power)
+
1254  {
+
1255  TimerOutput::Scope t(this->computing_timer, "Calculate pressure power");
+
1256 
+
1257  const double pressure_power =
+
1258  calculate_pressure_power(this->dof_handler,
+
1259  present_solution,
+
1260  *this->cell_quadrature,
+
1261  *this->mapping);
1262 
-
1263  // Display pressure power to screen if verbosity is enabled
-
1264  if (this->simulation_parameters.post_processing.verbosity ==
- -
1266  {
-
1267  this->pcout << "Pressure power : " << pressure_power << std::endl;
-
1268  }
-
1269 
-
1270  // Output pressure power to a text file from processor 0
-
1271  if (simulation_control->get_step_number() %
-
1272  this->simulation_parameters.post_processing.output_frequency ==
-
1273  0 &&
-
1274  this->this_mpi_process == 0)
-
1275  {
-
1276  std::string filename =
-
1277  simulation_parameters.simulation_control.output_folder +
-
1278  simulation_parameters.post_processing.pressure_power_output_name +
-
1279  ".dat";
-
1280  std::ofstream output(filename.c_str());
-
1281  pressure_power_table.set_precision("time", 12);
-
1282  pressure_power_table.set_precision("pressure_power", 12);
-
1283  this->pressure_power_table.write_text(output);
-
1284  }
-
1285  }
-
1286 
-
1287 
-
1288  // Viscous dissipation
-
1289  if (this->simulation_parameters.post_processing.calculate_viscous_dissipation)
-
1290  {
-
1291  TimerOutput::Scope t(this->computing_timer,
-
1292  "Calculate viscous dissipation");
-
1293 
-
1294  const double viscous_dissipation = calculate_viscous_dissipation(
-
1295  this->dof_handler,
-
1296  present_solution,
-
1297  *this->cell_quadrature,
-
1298  *this->mapping,
-
1299  simulation_parameters.physical_properties_manager);
-
1300 
-
1301  this->viscous_dissipation_table.add_value(
-
1302  "time", simulation_control->get_current_time());
-
1303  this->viscous_dissipation_table.add_value("viscous_dissipation",
-
1304  viscous_dissipation);
-
1305 
-
1306  // Display pressure power to screen if verbosity is enabled
-
1307  if (this->simulation_parameters.post_processing.verbosity ==
- -
1309  {
-
1310  this->pcout << "Viscous dissipation : " << viscous_dissipation
-
1311  << std::endl;
-
1312  }
-
1313 
-
1314  // Output pressure power to a text file from processor 0
-
1315  if (simulation_control->get_step_number() %
-
1316  this->simulation_parameters.post_processing.output_frequency ==
-
1317  0 &&
-
1318  this->this_mpi_process == 0)
-
1319  {
-
1320  std::string filename =
-
1321  simulation_parameters.simulation_control.output_folder +
-
1322  simulation_parameters.post_processing
-
1323  .viscous_dissipation_output_name +
-
1324  ".dat";
-
1325  std::ofstream output(filename.c_str());
-
1326  viscous_dissipation_table.set_precision("time", 12);
-
1327  viscous_dissipation_table.set_precision("viscous_dissipation", 12);
-
1328  this->viscous_dissipation_table.write_text(output);
-
1329  }
-
1330  }
-
1331 
-
1332  // The average velocities and reynolds stresses are calculated when the
-
1333  // time reaches the initial time. (time >= initial time) with 1e-6 as
-
1334  // tolerance.
-
1335  if (this->simulation_parameters.post_processing.calculate_average_velocities)
-
1336  {
-
1337  TimerOutput::Scope t(this->computing_timer,
-
1338  "Calculate average velocities");
-
1339 
-
1340  // Calculate average velocities when the time reaches the initial time.
-
1341  // time >= initial time with the epsilon as tolerance.
-
1342  const double dt = simulation_control->get_time_step();
-
1343  if (simulation_control->get_current_time() >
-
1344  (simulation_parameters.post_processing.initial_time - 1e-6 * dt))
-
1345  {
-
1346  this->average_velocities->calculate_average_velocities(
-
1347  this->local_evaluation_point,
-
1348  simulation_parameters.post_processing,
-
1349  simulation_control->get_current_time(),
-
1350  dt);
-
1351  }
-
1352  }
-
1353 
-
1354  if (this->simulation_parameters.post_processing.calculate_kinetic_energy)
-
1355  {
-
1356  TimerOutput::Scope t(this->computing_timer, "Calculate kinetic energy");
+
1263  this->pressure_power_table.add_value(
+
1264  "time", simulation_control->get_current_time());
+
1265  this->pressure_power_table.add_value("pressure_power", pressure_power);
+
1266 
+
1267  // Display pressure power to screen if verbosity is enabled
+
1268  if (this->simulation_parameters.post_processing.verbosity ==
+ +
1270  {
+
1271  this->pcout << "Pressure power : " << pressure_power << std::endl;
+
1272  }
+
1273 
+
1274  // Output pressure power to a text file from processor 0
+
1275  if (simulation_control->get_step_number() %
+
1276  this->simulation_parameters.post_processing.output_frequency ==
+
1277  0 &&
+
1278  this->this_mpi_process == 0)
+
1279  {
+
1280  std::string filename =
+
1281  simulation_parameters.simulation_control.output_folder +
+
1282  simulation_parameters.post_processing.pressure_power_output_name +
+
1283  ".dat";
+
1284  std::ofstream output(filename.c_str());
+
1285  pressure_power_table.set_precision("time", 12);
+
1286  pressure_power_table.set_precision("pressure_power", 12);
+
1287  this->pressure_power_table.write_text(output);
+
1288  }
+
1289  }
+
1290 
+
1291 
+
1292  // Viscous dissipation
+
1293  if (this->simulation_parameters.post_processing.calculate_viscous_dissipation)
+
1294  {
+
1295  TimerOutput::Scope t(this->computing_timer,
+
1296  "Calculate viscous dissipation");
+
1297 
+
1298  const double viscous_dissipation = calculate_viscous_dissipation(
+
1299  this->dof_handler,
+
1300  present_solution,
+
1301  *this->cell_quadrature,
+
1302  *this->mapping,
+
1303  simulation_parameters.physical_properties_manager);
+
1304 
+
1305  this->viscous_dissipation_table.add_value(
+
1306  "time", simulation_control->get_current_time());
+
1307  this->viscous_dissipation_table.add_value("viscous_dissipation",
+
1308  viscous_dissipation);
+
1309 
+
1310  // Display pressure power to screen if verbosity is enabled
+
1311  if (this->simulation_parameters.post_processing.verbosity ==
+ +
1313  {
+
1314  this->pcout << "Viscous dissipation : " << viscous_dissipation
+
1315  << std::endl;
+
1316  }
+
1317 
+
1318  // Output pressure power to a text file from processor 0
+
1319  if (simulation_control->get_step_number() %
+
1320  this->simulation_parameters.post_processing.output_frequency ==
+
1321  0 &&
+
1322  this->this_mpi_process == 0)
+
1323  {
+
1324  std::string filename =
+
1325  simulation_parameters.simulation_control.output_folder +
+
1326  simulation_parameters.post_processing
+
1327  .viscous_dissipation_output_name +
+
1328  ".dat";
+
1329  std::ofstream output(filename.c_str());
+
1330  viscous_dissipation_table.set_precision("time", 12);
+
1331  viscous_dissipation_table.set_precision("viscous_dissipation", 12);
+
1332  this->viscous_dissipation_table.write_text(output);
+
1333  }
+
1334  }
+
1335 
+
1336  // The average velocities and reynolds stresses are calculated when the
+
1337  // time reaches the initial time. (time >= initial time) with 1e-6 as
+
1338  // tolerance.
+
1339  if (this->simulation_parameters.post_processing.calculate_average_velocities)
+
1340  {
+
1341  TimerOutput::Scope t(this->computing_timer,
+
1342  "Calculate average velocities");
+
1343 
+
1344  // Calculate average velocities when the time reaches the initial time.
+
1345  // time >= initial time with the epsilon as tolerance.
+
1346  const double dt = simulation_control->get_time_step();
+
1347  if (simulation_control->get_current_time() >
+
1348  (simulation_parameters.post_processing.initial_time - 1e-6 * dt))
+
1349  {
+
1350  this->average_velocities->calculate_average_velocities(
+
1351  this->local_evaluation_point,
+
1352  simulation_parameters.post_processing,
+
1353  simulation_control->get_current_time(),
+
1354  dt);
+
1355  }
+
1356  }
1357 
-
1358  double kE = calculate_kinetic_energy(this->dof_handler,
-
1359  present_solution,
-
1360  *this->cell_quadrature,
-
1361  *this->mapping);
-
1362  this->kinetic_energy_table.add_value(
-
1363  "time", simulation_control->get_current_time());
-
1364  this->kinetic_energy_table.add_value("kinetic-energy", kE);
-
1365  if (this->simulation_parameters.post_processing.verbosity ==
- -
1367  {
-
1368  this->pcout << "Kinetic energy : " << kE << std::endl;
-
1369  }
-
1370 
-
1371  // Output Kinetic Energy to a text file from processor 0
-
1372  if ((simulation_control->get_step_number() %
-
1373  this->simulation_parameters.post_processing.output_frequency ==
-
1374  0) &&
-
1375  this->this_mpi_process == 0)
-
1376  {
-
1377  std::string filename =
-
1378  simulation_parameters.simulation_control.output_folder +
-
1379  simulation_parameters.post_processing.kinetic_energy_output_name +
-
1380  ".dat";
-
1381  std::ofstream output(filename.c_str());
-
1382  kinetic_energy_table.set_precision("time", 12);
-
1383  kinetic_energy_table.set_precision("kinetic-energy", 12);
-
1384  this->kinetic_energy_table.write_text(output);
-
1385  }
-
1386  }
-
1387 
-
1388  // Calculate apparent viscosity
-
1389  if (this->simulation_parameters.post_processing.calculate_apparent_viscosity)
-
1390  {
-
1391  TimerOutput::Scope t(this->computing_timer,
-
1392  "Calculate apparent viscosity");
-
1393 
-
1394  double apparent_viscosity = calculate_apparent_viscosity(
-
1395  this->dof_handler,
-
1396  this->present_solution,
-
1397  *this->cell_quadrature,
-
1398  *this->mapping,
-
1399  this->simulation_parameters.physical_properties_manager);
-
1400 
-
1401  this->apparent_viscosity_table.add_value(
-
1402  "time", simulation_control->get_current_time());
-
1403  this->apparent_viscosity_table.add_value("apparent_viscosity",
-
1404  apparent_viscosity);
-
1405  if (this->simulation_parameters.post_processing.verbosity ==
- -
1407  {
-
1408  this->pcout << "Apparent viscosity: " << apparent_viscosity
-
1409  << " m^2/s" << std::endl;
-
1410  }
-
1411 
-
1412  // Output apparent viscosity to a text file from processor 0
-
1413  if (simulation_control->get_step_number() %
-
1414  this->simulation_parameters.post_processing.output_frequency ==
-
1415  0 &&
-
1416  this->this_mpi_process == 0)
-
1417  {
-
1418  std::string filename =
-
1419  simulation_parameters.simulation_control.output_folder +
-
1420  simulation_parameters.post_processing
-
1421  .apparent_viscosity_output_name +
-
1422  ".dat";
-
1423  std::ofstream output(filename.c_str());
-
1424  apparent_viscosity_table.set_precision("time", 12);
-
1425  apparent_viscosity_table.set_precision("apparent_viscosity", 12);
-
1426  this->apparent_viscosity_table.write_text(output);
-
1427  }
-
1428  }
-
1429 
-
1430  // Calculate pressure drop between two boundaries
-
1431  if (this->simulation_parameters.post_processing.calculate_pressure_drop)
-
1432  {
-
1433  TimerOutput::Scope t(this->computing_timer, "Calculate pressure drop");
-
1434 
-
1435  double pressure_drop, total_pressure_drop;
-
1436  std::tie(pressure_drop, total_pressure_drop) = calculate_pressure_drop(
-
1437  this->dof_handler,
-
1438  *this->mapping,
-
1439  this->evaluation_point,
-
1440  *this->cell_quadrature,
-
1441  *this->face_quadrature,
-
1442  this->simulation_parameters.post_processing.inlet_boundary_id,
-
1443  this->simulation_parameters.post_processing.outlet_boundary_id);
-
1444  this->pressure_drop_table.add_value(
-
1445  "time", simulation_control->get_current_time());
-
1446  this->pressure_drop_table.add_value("pressure-drop", pressure_drop);
-
1447  this->pressure_drop_table.add_value("total-pressure-drop",
-
1448  total_pressure_drop);
-
1449  if (this->simulation_parameters.post_processing.verbosity ==
- -
1451  {
-
1452  this->pcout << "Pressure drop: "
-
1453  << std::setprecision(
-
1454  simulation_control->get_log_precision())
-
1455  << this->simulation_parameters.physical_properties_manager
-
1456  .get_density_scale() *
-
1457  pressure_drop
-
1458  << " Pa" << std::endl;
-
1459  this->pcout << "Total pressure drop: "
-
1460  << std::setprecision(
-
1461  simulation_control->get_log_precision())
-
1462  << this->simulation_parameters.physical_properties_manager
-
1463  .get_density_scale() *
-
1464  total_pressure_drop
-
1465  << " Pa" << std::endl;
-
1466  }
-
1467 
-
1468  // Output pressure drop to a text file from processor 0
-
1469  if ((simulation_control->get_step_number() %
-
1470  this->simulation_parameters.post_processing.output_frequency ==
-
1471  0) &&
-
1472  this->this_mpi_process == 0)
-
1473  {
-
1474  std::string filename =
-
1475  simulation_parameters.simulation_control.output_folder +
-
1476  simulation_parameters.post_processing.pressure_drop_output_name +
-
1477  ".dat";
-
1478  std::ofstream output(filename.c_str());
-
1479  pressure_drop_table.set_precision("time", 12);
-
1480  pressure_drop_table.set_precision("pressure-drop", 12);
-
1481  pressure_drop_table.set_precision("total-pressure-drop", 12);
-
1482  this->pressure_drop_table.write_text(output);
-
1483  }
-
1484  }
-
1485 
-
1486  // Calculate flow rate at every boundary
-
1487  if (this->simulation_parameters.post_processing.calculate_flow_rate)
-
1488  {
-
1489  TimerOutput::Scope t(this->computing_timer, "Calculate flow rate");
-
1490 
-
1491  this->flow_rate_table.add_value("time",
-
1492  simulation_control->get_current_time());
-
1493  this->flow_rate_table.set_scientific("time", true);
+
1358  if (this->simulation_parameters.post_processing.calculate_kinetic_energy)
+
1359  {
+
1360  TimerOutput::Scope t(this->computing_timer, "Calculate kinetic energy");
+
1361 
+
1362  double kE = calculate_kinetic_energy(this->dof_handler,
+
1363  present_solution,
+
1364  *this->cell_quadrature,
+
1365  *this->mapping);
+
1366  this->kinetic_energy_table.add_value(
+
1367  "time", simulation_control->get_current_time());
+
1368  this->kinetic_energy_table.add_value("kinetic-energy", kE);
+
1369  if (this->simulation_parameters.post_processing.verbosity ==
+ +
1371  {
+
1372  this->pcout << "Kinetic energy : " << kE << std::endl;
+
1373  }
+
1374 
+
1375  // Output Kinetic Energy to a text file from processor 0
+
1376  if ((simulation_control->get_step_number() %
+
1377  this->simulation_parameters.post_processing.output_frequency ==
+
1378  0) &&
+
1379  this->this_mpi_process == 0)
+
1380  {
+
1381  std::string filename =
+
1382  simulation_parameters.simulation_control.output_folder +
+
1383  simulation_parameters.post_processing.kinetic_energy_output_name +
+
1384  ".dat";
+
1385  std::ofstream output(filename.c_str());
+
1386  kinetic_energy_table.set_precision("time", 12);
+
1387  kinetic_energy_table.set_precision("kinetic-energy", 12);
+
1388  this->kinetic_energy_table.write_text(output);
+
1389  }
+
1390  }
+
1391 
+
1392  // Calculate apparent viscosity
+
1393  if (this->simulation_parameters.post_processing.calculate_apparent_viscosity)
+
1394  {
+
1395  TimerOutput::Scope t(this->computing_timer,
+
1396  "Calculate apparent viscosity");
+
1397 
+
1398  double apparent_viscosity = calculate_apparent_viscosity(
+
1399  this->dof_handler,
+
1400  this->present_solution,
+
1401  *this->cell_quadrature,
+
1402  *this->mapping,
+
1403  this->simulation_parameters.physical_properties_manager);
+
1404 
+
1405  this->apparent_viscosity_table.add_value(
+
1406  "time", simulation_control->get_current_time());
+
1407  this->apparent_viscosity_table.add_value("apparent_viscosity",
+
1408  apparent_viscosity);
+
1409  if (this->simulation_parameters.post_processing.verbosity ==
+ +
1411  {
+
1412  this->pcout << "Apparent viscosity: " << apparent_viscosity
+
1413  << " m^2/s" << std::endl;
+
1414  }
+
1415 
+
1416  // Output apparent viscosity to a text file from processor 0
+
1417  if (simulation_control->get_step_number() %
+
1418  this->simulation_parameters.post_processing.output_frequency ==
+
1419  0 &&
+
1420  this->this_mpi_process == 0)
+
1421  {
+
1422  std::string filename =
+
1423  simulation_parameters.simulation_control.output_folder +
+
1424  simulation_parameters.post_processing
+
1425  .apparent_viscosity_output_name +
+
1426  ".dat";
+
1427  std::ofstream output(filename.c_str());
+
1428  apparent_viscosity_table.set_precision("time", 12);
+
1429  apparent_viscosity_table.set_precision("apparent_viscosity", 12);
+
1430  this->apparent_viscosity_table.write_text(output);
+
1431  }
+
1432  }
+
1433 
+
1434  // Calculate pressure drop between two boundaries
+
1435  if (this->simulation_parameters.post_processing.calculate_pressure_drop)
+
1436  {
+
1437  TimerOutput::Scope t(this->computing_timer, "Calculate pressure drop");
+
1438 
+
1439  double pressure_drop, total_pressure_drop;
+
1440  std::tie(pressure_drop, total_pressure_drop) = calculate_pressure_drop(
+
1441  this->dof_handler,
+
1442  *this->mapping,
+
1443  this->evaluation_point,
+
1444  *this->cell_quadrature,
+
1445  *this->face_quadrature,
+
1446  this->simulation_parameters.post_processing.inlet_boundary_id,
+
1447  this->simulation_parameters.post_processing.outlet_boundary_id);
+
1448  this->pressure_drop_table.add_value(
+
1449  "time", simulation_control->get_current_time());
+
1450  this->pressure_drop_table.add_value("pressure-drop", pressure_drop);
+
1451  this->pressure_drop_table.add_value("total-pressure-drop",
+
1452  total_pressure_drop);
+
1453  if (this->simulation_parameters.post_processing.verbosity ==
+ +
1455  {
+
1456  this->pcout << "Pressure drop: "
+
1457  << std::setprecision(
+
1458  simulation_control->get_log_precision())
+
1459  << this->simulation_parameters.physical_properties_manager
+
1460  .get_density_scale() *
+
1461  pressure_drop
+
1462  << " Pa" << std::endl;
+
1463  this->pcout << "Total pressure drop: "
+
1464  << std::setprecision(
+
1465  simulation_control->get_log_precision())
+
1466  << this->simulation_parameters.physical_properties_manager
+
1467  .get_density_scale() *
+
1468  total_pressure_drop
+
1469  << " Pa" << std::endl;
+
1470  }
+
1471 
+
1472  // Output pressure drop to a text file from processor 0
+
1473  if ((simulation_control->get_step_number() %
+
1474  this->simulation_parameters.post_processing.output_frequency ==
+
1475  0) &&
+
1476  this->this_mpi_process == 0)
+
1477  {
+
1478  std::string filename =
+
1479  simulation_parameters.simulation_control.output_folder +
+
1480  simulation_parameters.post_processing.pressure_drop_output_name +
+
1481  ".dat";
+
1482  std::ofstream output(filename.c_str());
+
1483  pressure_drop_table.set_precision("time", 12);
+
1484  pressure_drop_table.set_precision("pressure-drop", 12);
+
1485  pressure_drop_table.set_precision("total-pressure-drop", 12);
+
1486  this->pressure_drop_table.write_text(output);
+
1487  }
+
1488  }
+
1489 
+
1490  // Calculate flow rate at every boundary
+
1491  if (this->simulation_parameters.post_processing.calculate_flow_rate)
+
1492  {
+
1493  TimerOutput::Scope t(this->computing_timer, "Calculate flow rate");
1494 
-
1495  if (this->simulation_parameters.post_processing.verbosity ==
- -
1497  {
-
1498  announce_string(this->pcout, "Flow rates");
-
1499  }
-
1500 
-
1501  for (unsigned int boundary_id = 0;
-
1502  boundary_id < simulation_parameters.boundary_conditions.size;
-
1503  ++boundary_id)
-
1504  {
-
1505  std::pair<double, double> boundary_flow_rate =
-
1506  calculate_flow_rate(this->dof_handler,
-
1507  this->present_solution,
-
1508  boundary_id,
-
1509  *this->face_quadrature,
-
1510  *this->mapping);
-
1511 
-
1512  this->flow_rate_table.add_value(
-
1513  "flow-rate-" + Utilities::int_to_string(boundary_id, 2),
-
1514  boundary_flow_rate.first);
-
1515  this->flow_rate_table.set_scientific(
-
1516  "flow-rate-" + Utilities::int_to_string(boundary_id, 2), true);
-
1517  if (this->simulation_parameters.post_processing.verbosity ==
- -
1519  {
-
1520  this->pcout << "Flow rate at boundary " +
-
1521  std::to_string(boundary_id) + ": "
-
1522  << std::setprecision(
-
1523  simulation_control->get_log_precision())
-
1524  << boundary_flow_rate.first << " m^3/s" << std::endl;
-
1525  }
-
1526  }
-
1527 
-
1528  // Output flow rate to a text file from processor 0
-
1529  if ((simulation_control->get_step_number() %
-
1530  this->simulation_parameters.post_processing.output_frequency ==
-
1531  0) &&
-
1532  this->this_mpi_process == 0)
-
1533  {
-
1534  std::string filename =
-
1535  simulation_parameters.simulation_control.output_folder +
-
1536  simulation_parameters.post_processing.flow_rate_output_name +
-
1537  ".dat";
-
1538  std::ofstream output(filename.c_str());
-
1539  flow_rate_table.set_precision("time", 12);
-
1540  for (unsigned int boundary_id = 0;
-
1541  boundary_id < simulation_parameters.boundary_conditions.size;
-
1542  ++boundary_id)
-
1543  flow_rate_table.set_precision(
-
1544  "flow-rate-" + Utilities::int_to_string(boundary_id, 2), 12);
-
1545  this->flow_rate_table.write_text(output);
-
1546  }
-
1547  }
-
1548 
-
1549  // this->computing_timer.leave_subsection("Postprocessing");
-
1550 
-
1551  if (!firstIter)
-
1552  {
-
1553  // Calculate forces on the boundary conditions
-
1554  if (this->simulation_parameters.forces_parameters.calculate_force)
-
1555  {
-
1556  if (simulation_control->get_step_number() %
-
1557  this->simulation_parameters.forces_parameters
-
1558  .calculation_frequency ==
-
1559  0)
-
1560  this->postprocessing_forces(present_solution);
-
1561  if (simulation_control->get_step_number() %
-
1562  this->simulation_parameters.forces_parameters
-
1563  .output_frequency ==
-
1564  0)
-
1565  this->write_output_forces();
-
1566  }
-
1567 
-
1568  // Calculate torques on the boundary conditions
-
1569  if (this->simulation_parameters.forces_parameters.calculate_torque)
-
1570  {
-
1571  if (simulation_control->get_step_number() %
-
1572  this->simulation_parameters.forces_parameters
-
1573  .calculation_frequency ==
-
1574  0)
-
1575  this->postprocessing_torques(present_solution);
-
1576  if (simulation_control->get_step_number() %
-
1577  this->simulation_parameters.forces_parameters
-
1578  .output_frequency ==
-
1579  0)
-
1580  this->write_output_torques();
-
1581  }
-
1582 
-
1583  // Calculate error with respect to analytical solution
-
1584  if (this->simulation_parameters.analytical_solution->calculate_error())
-
1585  {
-
1586  TimerOutput::Scope t(this->computing_timer,
-
1587  "Calculate error w.r.t. analytical solution");
-
1588 
-
1589  // Update the time of the exact solution to the actual time
-
1590  this->exact_solution->set_time(
-
1591  simulation_control->get_current_time());
+
1495  this->flow_rate_table.add_value("time",
+
1496  simulation_control->get_current_time());
+
1497  this->flow_rate_table.set_scientific("time", true);
+
1498 
+
1499  if (this->simulation_parameters.post_processing.verbosity ==
+ +
1501  {
+
1502  announce_string(this->pcout, "Flow rates");
+
1503  }
+
1504 
+
1505  for (unsigned int boundary_id = 0;
+
1506  boundary_id < simulation_parameters.boundary_conditions.size;
+
1507  ++boundary_id)
+
1508  {
+
1509  std::pair<double, double> boundary_flow_rate =
+
1510  calculate_flow_rate(this->dof_handler,
+
1511  this->present_solution,
+
1512  boundary_id,
+
1513  *this->face_quadrature,
+
1514  *this->mapping);
+
1515 
+
1516  this->flow_rate_table.add_value(
+
1517  "flow-rate-" + Utilities::int_to_string(boundary_id, 2),
+
1518  boundary_flow_rate.first);
+
1519  this->flow_rate_table.set_scientific(
+
1520  "flow-rate-" + Utilities::int_to_string(boundary_id, 2), true);
+
1521  if (this->simulation_parameters.post_processing.verbosity ==
+ +
1523  {
+
1524  this->pcout << "Flow rate at boundary " +
+
1525  std::to_string(boundary_id) + ": "
+
1526  << std::setprecision(
+
1527  simulation_control->get_log_precision())
+
1528  << boundary_flow_rate.first << " m^3/s" << std::endl;
+
1529  }
+
1530  }
+
1531 
+
1532  // Output flow rate to a text file from processor 0
+
1533  if ((simulation_control->get_step_number() %
+
1534  this->simulation_parameters.post_processing.output_frequency ==
+
1535  0) &&
+
1536  this->this_mpi_process == 0)
+
1537  {
+
1538  std::string filename =
+
1539  simulation_parameters.simulation_control.output_folder +
+
1540  simulation_parameters.post_processing.flow_rate_output_name +
+
1541  ".dat";
+
1542  std::ofstream output(filename.c_str());
+
1543  flow_rate_table.set_precision("time", 12);
+
1544  for (unsigned int boundary_id = 0;
+
1545  boundary_id < simulation_parameters.boundary_conditions.size;
+
1546  ++boundary_id)
+
1547  flow_rate_table.set_precision(
+
1548  "flow-rate-" + Utilities::int_to_string(boundary_id, 2), 12);
+
1549  this->flow_rate_table.write_text(output);
+
1550  }
+
1551  }
+
1552 
+
1553  // this->computing_timer.leave_subsection("Postprocessing");
+
1554 
+
1555  if (!firstIter)
+
1556  {
+
1557  // Calculate forces on the boundary conditions
+
1558  if (this->simulation_parameters.forces_parameters.calculate_force)
+
1559  {
+
1560  if (simulation_control->get_step_number() %
+
1561  this->simulation_parameters.forces_parameters
+
1562  .calculation_frequency ==
+
1563  0)
+
1564  this->postprocessing_forces(present_solution);
+
1565  if (simulation_control->get_step_number() %
+
1566  this->simulation_parameters.forces_parameters
+
1567  .output_frequency ==
+
1568  0)
+
1569  this->write_output_forces();
+
1570  }
+
1571 
+
1572  // Calculate torques on the boundary conditions
+
1573  if (this->simulation_parameters.forces_parameters.calculate_torque)
+
1574  {
+
1575  if (simulation_control->get_step_number() %
+
1576  this->simulation_parameters.forces_parameters
+
1577  .calculation_frequency ==
+
1578  0)
+
1579  this->postprocessing_torques(present_solution);
+
1580  if (simulation_control->get_step_number() %
+
1581  this->simulation_parameters.forces_parameters
+
1582  .output_frequency ==
+
1583  0)
+
1584  this->write_output_torques();
+
1585  }
+
1586 
+
1587  // Calculate error with respect to analytical solution
+
1588  if (this->simulation_parameters.analytical_solution->calculate_error())
+
1589  {
+
1590  TimerOutput::Scope t(this->computing_timer,
+
1591  "Calculate error w.r.t. analytical solution");
1592 
-
1593  present_solution.update_ghost_values();
-
1594 
-
1595  const std::pair<double, double> errors =
-
1596  calculate_L2_error(dof_handler,
-
1597  present_solution,
-
1598  exact_solution,
-
1599  *this->cell_quadrature,
-
1600  *this->mapping);
-
1601  const double error_velocity = errors.first;
-
1602  const double error_pressure = errors.second;
-
1603  if (simulation_parameters.simulation_control.method ==
- -
1605  {
-
1606  this->error_table.add_value(
-
1607  "cells", this->triangulation->n_global_active_cells());
-
1608  this->error_table.add_value("error_velocity", error_velocity);
-
1609  this->error_table.add_value("error_pressure", error_pressure);
-
1610  auto summary = computing_timer.get_summary_data(
-
1611  computing_timer.total_wall_time);
-
1612  double total_time = 0;
-
1613  for (auto it = summary.begin(); it != summary.end(); ++it)
-
1614  {
-
1615  total_time += summary[it->first];
-
1616  }
-
1617 
-
1618  this->error_table.add_value("total_time", total_time);
-
1619  }
-
1620  else
-
1621  {
-
1622  this->error_table.add_value(
-
1623  "time", simulation_control->get_current_time());
-
1624  this->error_table.add_value("error_velocity", error_velocity);
-
1625 
-
1626  if (this->simulation_parameters.timer.write_time_in_error_table)
-
1627  {
-
1628  auto summary = computing_timer.get_summary_data(
-
1629  computing_timer.total_wall_time);
-
1630  double total_time = 0;
-
1631  for (auto it = summary.begin(); it != summary.end(); ++it)
-
1632  {
-
1633  total_time += summary[it->first];
-
1634  }
-
1635  this->error_table.add_value("total_time", total_time);
-
1636  }
-
1637 
-
1638  // Calculate error on pressure for VOF or Cahn-Hilliard
-
1639  // simulations
-
1640  if (this->simulation_parameters.multiphysics.VOF ||
-
1641  this->simulation_parameters.multiphysics.cahn_hilliard)
-
1642  this->error_table.add_value("error_pressure", error_pressure);
-
1643  }
-
1644  if (this->simulation_parameters.analytical_solution->verbosity ==
- -
1646  {
-
1647  this->pcout << "L2 error velocity : "
-
1648  << std::setprecision(
-
1649  simulation_control->get_log_precision())
-
1650  << error_velocity << std::endl;
-
1651  if (this->simulation_parameters.multiphysics.cahn_hilliard)
-
1652  {
-
1653  this->pcout << "L2 error pressure : "
-
1654  << std::setprecision(
-
1655  simulation_control->get_log_precision())
-
1656  << error_pressure << std::endl;
-
1657  }
-
1658  }
-
1659  }
-
1660  }
-
1661  if (this->simulation_control->is_output_iteration())
-
1662  {
-
1663  this->write_output_results(present_solution);
+
1593  // Update the time of the exact solution to the actual time
+
1594  this->exact_solution->set_time(
+
1595  simulation_control->get_current_time());
+
1596 
+
1597  present_solution.update_ghost_values();
+
1598 
+
1599  const std::pair<double, double> errors =
+
1600  calculate_L2_error(dof_handler,
+
1601  present_solution,
+
1602  exact_solution,
+
1603  *this->cell_quadrature,
+
1604  *this->mapping);
+
1605  const double error_velocity = errors.first;
+
1606  const double error_pressure = errors.second;
+
1607  if (simulation_parameters.simulation_control.method ==
+ +
1609  {
+
1610  this->error_table.add_value(
+
1611  "cells", this->triangulation->n_global_active_cells());
+
1612  this->error_table.add_value("error_velocity", error_velocity);
+
1613  this->error_table.add_value("error_pressure", error_pressure);
+
1614  auto summary = computing_timer.get_summary_data(
+
1615  computing_timer.total_wall_time);
+
1616  double total_time = 0;
+
1617  for (auto it = summary.begin(); it != summary.end(); ++it)
+
1618  {
+
1619  total_time += summary[it->first];
+
1620  }
+
1621 
+
1622  this->error_table.add_value("total_time", total_time);
+
1623  }
+
1624  else
+
1625  {
+
1626  this->error_table.add_value(
+
1627  "time", simulation_control->get_current_time());
+
1628  this->error_table.add_value("error_velocity", error_velocity);
+
1629 
+
1630  if (this->simulation_parameters.timer.write_time_in_error_table)
+
1631  {
+
1632  auto summary = computing_timer.get_summary_data(
+
1633  computing_timer.total_wall_time);
+
1634  double total_time = 0;
+
1635  for (auto it = summary.begin(); it != summary.end(); ++it)
+
1636  {
+
1637  total_time += summary[it->first];
+
1638  }
+
1639  this->error_table.add_value("total_time", total_time);
+
1640  }
+
1641 
+
1642  // Calculate error on pressure for VOF or Cahn-Hilliard
+
1643  // simulations
+
1644  if (this->simulation_parameters.multiphysics.VOF ||
+
1645  this->simulation_parameters.multiphysics.cahn_hilliard)
+
1646  this->error_table.add_value("error_pressure", error_pressure);
+
1647  }
+
1648  if (this->simulation_parameters.analytical_solution->verbosity ==
+ +
1650  {
+
1651  this->pcout << "L2 error velocity : "
+
1652  << std::setprecision(
+
1653  simulation_control->get_log_precision())
+
1654  << error_velocity << std::endl;
+
1655  if (this->simulation_parameters.multiphysics.cahn_hilliard)
+
1656  {
+
1657  this->pcout << "L2 error pressure : "
+
1658  << std::setprecision(
+
1659  simulation_control->get_log_precision())
+
1660  << error_pressure << std::endl;
+
1661  }
+
1662  }
+
1663  }
1664  }
-
1665 }
-
1666 
-
1667 template <int dim, typename VectorType, typename DofsType>
-
1668 void
- -
1670 {
-
1671  const FEValuesExtractors::Vector velocities(0);
-
1672  const FEValuesExtractors::Scalar pressure(dim);
-
1673  VectorTools::interpolate(*this->mapping,
-
1674  this->dof_handler,
-
1675  this->simulation_parameters.initial_condition->uvwp,
-
1676  this->newton_update,
-
1677  this->fe->component_mask(velocities));
-
1678  VectorTools::interpolate(*this->mapping,
-
1679  this->dof_handler,
-
1680  this->simulation_parameters.initial_condition->uvwp,
-
1681  this->newton_update,
-
1682  this->fe->component_mask(pressure));
-
1683  this->nonzero_constraints.distribute(this->newton_update);
-
1684  this->present_solution = this->newton_update;
-
1685  if (this->simulation_parameters.simulation_control.bdf_startup_method ==
- -
1687  {
-
1688  for (unsigned int i = 1; i < this->previous_solutions.size(); ++i)
-
1689  {
-
1690  double previous_solution_time =
-
1691  -this->simulation_parameters.simulation_control.dt * i;
-
1692  this->simulation_parameters.initial_condition->uvwp.set_time(
-
1693  previous_solution_time);
-
1694  const FEValuesExtractors::Vector velocities(0);
-
1695  const FEValuesExtractors::Scalar pressure(dim);
-
1696  VectorTools::interpolate(
-
1697  *this->mapping,
-
1698  this->dof_handler,
-
1699  this->simulation_parameters.initial_condition->uvwp,
-
1700  this->newton_update,
-
1701  this->fe->component_mask(velocities));
-
1702  VectorTools::interpolate(
-
1703  *this->mapping,
-
1704  this->dof_handler,
-
1705  this->simulation_parameters.initial_condition->uvwp,
-
1706  this->newton_update,
-
1707  this->fe->component_mask(pressure));
-
1708  this->previous_solutions[i - 1] = this->newton_update;
-
1709  }
-
1710  }
-
1711 }
-
1712 
-
1713 
-
1714 template <int dim, typename VectorType, typename DofsType>
-
1715 void
- -
1717 {
-
1718  TimerOutput::Scope timer(this->computing_timer, "Read checkpoint");
-
1719  std::string prefix =
-
1720  this->simulation_parameters.simulation_control.output_folder +
-
1721  this->simulation_parameters.restart_parameters.filename;
-
1722  this->simulation_control->read(prefix);
-
1723  this->pvdhandler.read(prefix);
-
1724 
-
1725  const std::string filename = prefix + ".triangulation";
-
1726  std::ifstream in(filename.c_str());
-
1727  if (!in)
-
1728  AssertThrow(false,
-
1729  ExcMessage(
-
1730  std::string(
-
1731  "You are trying to restart a previous computation, "
-
1732  "but the restart file <") +
-
1733  filename + "> does not appear to exist!"));
-
1734 
-
1735  try
-
1736  {
-
1737  if (auto tria = dynamic_cast<parallel::distributed::Triangulation<dim> *>(
-
1738  this->triangulation.get()))
-
1739  tria->load(filename.c_str());
-
1740  }
-
1741  catch (...)
-
1742  {
-
1743  AssertThrow(false,
-
1744  ExcMessage("Cannot open snapshot mesh file or read the "
-
1745  "triangulation stored there."));
-
1746  }
-
1747  setup_dofs();
-
1748  enable_dynamic_zero_constraints_fd();
-
1749 
-
1750  // BB note: There is an issue right now that will prevent this code from
-
1751  // running in debug mode with Trilinos vectors Deal.II vectors require that
-
1752  // the vectors used in the checkpointing mechanism have their relevant dofs
-
1753  // whereas Trilinos vectors do not allow for this. Right now this code works
-
1754  // well in release mode for both vector types, but will not work in debug mode
-
1755  // for Trilinos vectors because of an assertion. A workaround will be
-
1756  // implemented in a near future
-
1757 
-
1758  std::vector<VectorType *> x_system(1 + previous_solutions.size());
-
1759 
-
1760  VectorType distributed_system(locally_owned_dofs,
-
1761  this->locally_relevant_dofs,
-
1762  this->mpi_communicator);
-
1763  x_system[0] = &(distributed_system);
-
1764 
-
1765  std::vector<VectorType> distributed_previous_solutions;
-
1766  distributed_previous_solutions.reserve(previous_solutions.size());
-
1767  for (unsigned int i = 0; i < previous_solutions.size(); ++i)
-
1768  {
-
1769  distributed_previous_solutions.emplace_back(
-
1770  VectorType(locally_owned_dofs,
-
1771  this->locally_relevant_dofs,
-
1772  this->mpi_communicator));
-
1773  x_system[i + 1] = &distributed_previous_solutions[i];
-
1774  }
-
1775  parallel::distributed::SolutionTransfer<dim, VectorType> system_trans_vectors(
-
1776  this->dof_handler);
-
1777 
-
1778  if (simulation_parameters.post_processing.calculate_average_velocities)
-
1779  {
-
1780  std::vector<VectorType *> sum_vectors =
-
1781  this->average_velocities->read(prefix);
-
1782 
-
1783  x_system.insert(x_system.end(), sum_vectors.begin(), sum_vectors.end());
-
1784  }
-
1785 
-
1786  system_trans_vectors.deserialize(x_system);
-
1787  this->present_solution = distributed_system;
-
1788  for (unsigned int i = 0; i < previous_solutions.size(); ++i)
-
1789  {
-
1790  previous_solutions[i] = distributed_previous_solutions[i];
-
1791  }
-
1792 
-
1793  if (simulation_parameters.post_processing.calculate_average_velocities)
-
1794  {
-
1795  this->average_velocities->calculate_average_velocities(
-
1796  this->local_evaluation_point,
-
1797  simulation_parameters.post_processing,
-
1798  simulation_control->get_current_time(),
-
1799  simulation_control->get_time_step());
-
1800  }
-
1801 
-
1802  if (simulation_parameters.flow_control.enable_flow_control)
-
1803  {
-
1804  this->flow_control.read(prefix);
-
1805  }
-
1806 
-
1807  multiphysics->read_checkpoint();
-
1808 
-
1809  // Deserialize all post-processing tables that are currently used
-
1810  {
-
1811  const Parameters::PostProcessing post_processing =
-
1812  this->simulation_parameters.post_processing;
-
1813  std::string prefix =
-
1814  this->simulation_parameters.simulation_control.output_folder;
-
1815  std::string suffix = ".checkpoint";
-
1816  if (post_processing.calculate_enstrophy)
-
1817  deserialize_table(this->enstrophy_table,
-
1818  prefix + post_processing.enstrophy_output_name +
-
1819  suffix);
-
1820  if (post_processing.calculate_pressure_power)
-
1821  deserialize_table(this->pressure_power_table,
-
1822  prefix + post_processing.pressure_power_output_name +
+
1665  if (this->simulation_control->is_output_iteration())
+
1666  {
+
1667  this->write_output_results(present_solution);
+
1668  }
+
1669 }
+
1670 
+
1671 template <int dim, typename VectorType, typename DofsType>
+
1672 void
+ +
1674 {
+
1675  const FEValuesExtractors::Vector velocities(0);
+
1676  const FEValuesExtractors::Scalar pressure(dim);
+
1677  VectorTools::interpolate(*this->mapping,
+
1678  this->dof_handler,
+
1679  this->simulation_parameters.initial_condition->uvwp,
+
1680  this->newton_update,
+
1681  this->fe->component_mask(velocities));
+
1682  VectorTools::interpolate(*this->mapping,
+
1683  this->dof_handler,
+
1684  this->simulation_parameters.initial_condition->uvwp,
+
1685  this->newton_update,
+
1686  this->fe->component_mask(pressure));
+
1687  this->nonzero_constraints.distribute(this->newton_update);
+
1688  this->present_solution = this->newton_update;
+
1689  if (this->simulation_parameters.simulation_control.bdf_startup_method ==
+ +
1691  {
+
1692  for (unsigned int i = 1; i < this->previous_solutions.size(); ++i)
+
1693  {
+
1694  double previous_solution_time =
+
1695  -this->simulation_parameters.simulation_control.dt * i;
+
1696  this->simulation_parameters.initial_condition->uvwp.set_time(
+
1697  previous_solution_time);
+
1698  const FEValuesExtractors::Vector velocities(0);
+
1699  const FEValuesExtractors::Scalar pressure(dim);
+
1700  VectorTools::interpolate(
+
1701  *this->mapping,
+
1702  this->dof_handler,
+
1703  this->simulation_parameters.initial_condition->uvwp,
+
1704  this->newton_update,
+
1705  this->fe->component_mask(velocities));
+
1706  VectorTools::interpolate(
+
1707  *this->mapping,
+
1708  this->dof_handler,
+
1709  this->simulation_parameters.initial_condition->uvwp,
+
1710  this->newton_update,
+
1711  this->fe->component_mask(pressure));
+
1712  this->previous_solutions[i - 1] = this->newton_update;
+
1713  }
+
1714  }
+
1715 }
+
1716 
+
1717 
+
1718 template <int dim, typename VectorType, typename DofsType>
+
1719 void
+ +
1721 {
+
1722  TimerOutput::Scope timer(this->computing_timer, "Read checkpoint");
+
1723  std::string prefix =
+
1724  this->simulation_parameters.simulation_control.output_folder +
+
1725  this->simulation_parameters.restart_parameters.filename;
+
1726  this->simulation_control->read(prefix);
+
1727  this->pvdhandler.read(prefix);
+
1728 
+
1729  const std::string filename = prefix + ".triangulation";
+
1730  std::ifstream in(filename.c_str());
+
1731  if (!in)
+
1732  AssertThrow(false,
+
1733  ExcMessage(
+
1734  std::string(
+
1735  "You are trying to restart a previous computation, "
+
1736  "but the restart file <") +
+
1737  filename + "> does not appear to exist!"));
+
1738 
+
1739  try
+
1740  {
+
1741  if (auto tria = dynamic_cast<parallel::distributed::Triangulation<dim> *>(
+
1742  this->triangulation.get()))
+
1743  tria->load(filename.c_str());
+
1744  }
+
1745  catch (...)
+
1746  {
+
1747  AssertThrow(false,
+
1748  ExcMessage("Cannot open snapshot mesh file or read the "
+
1749  "triangulation stored there."));
+
1750  }
+
1751  setup_dofs();
+
1752  enable_dynamic_zero_constraints_fd();
+
1753 
+
1754  // BB note: There is an issue right now that will prevent this code from
+
1755  // running in debug mode with Trilinos vectors Deal.II vectors require that
+
1756  // the vectors used in the checkpointing mechanism have their relevant dofs
+
1757  // whereas Trilinos vectors do not allow for this. Right now this code works
+
1758  // well in release mode for both vector types, but will not work in debug mode
+
1759  // for Trilinos vectors because of an assertion. A workaround will be
+
1760  // implemented in a near future
+
1761 
+
1762  std::vector<VectorType *> x_system(1 + previous_solutions.size());
+
1763 
+
1764  VectorType distributed_system(locally_owned_dofs,
+
1765  this->locally_relevant_dofs,
+
1766  this->mpi_communicator);
+
1767  x_system[0] = &(distributed_system);
+
1768 
+
1769  std::vector<VectorType> distributed_previous_solutions;
+
1770  distributed_previous_solutions.reserve(previous_solutions.size());
+
1771  for (unsigned int i = 0; i < previous_solutions.size(); ++i)
+
1772  {
+
1773  distributed_previous_solutions.emplace_back(
+
1774  VectorType(locally_owned_dofs,
+
1775  this->locally_relevant_dofs,
+
1776  this->mpi_communicator));
+
1777  x_system[i + 1] = &distributed_previous_solutions[i];
+
1778  }
+
1779  parallel::distributed::SolutionTransfer<dim, VectorType> system_trans_vectors(
+
1780  this->dof_handler);
+
1781 
+
1782  if (simulation_parameters.post_processing.calculate_average_velocities)
+
1783  {
+
1784  std::vector<VectorType *> sum_vectors =
+
1785  this->average_velocities->read(prefix);
+
1786 
+
1787  x_system.insert(x_system.end(), sum_vectors.begin(), sum_vectors.end());
+
1788  }
+
1789 
+
1790  system_trans_vectors.deserialize(x_system);
+
1791  this->present_solution = distributed_system;
+
1792  for (unsigned int i = 0; i < previous_solutions.size(); ++i)
+
1793  {
+
1794  previous_solutions[i] = distributed_previous_solutions[i];
+
1795  }
+
1796 
+
1797  if (simulation_parameters.post_processing.calculate_average_velocities)
+
1798  {
+
1799  this->average_velocities->calculate_average_velocities(
+
1800  this->local_evaluation_point,
+
1801  simulation_parameters.post_processing,
+
1802  simulation_control->get_current_time(),
+
1803  simulation_control->get_time_step());
+
1804  }
+
1805 
+
1806  if (simulation_parameters.flow_control.enable_flow_control)
+
1807  {
+
1808  this->flow_control.read(prefix);
+
1809  }
+
1810 
+
1811  multiphysics->read_checkpoint();
+
1812 
+
1813  // Deserialize all post-processing tables that are currently used
+
1814  {
+
1815  const Parameters::PostProcessing post_processing =
+
1816  this->simulation_parameters.post_processing;
+
1817  std::string prefix =
+
1818  this->simulation_parameters.simulation_control.output_folder;
+
1819  std::string suffix = ".checkpoint";
+
1820  if (post_processing.calculate_enstrophy)
+
1821  deserialize_table(this->enstrophy_table,
+
1822  prefix + post_processing.enstrophy_output_name +
1823  suffix);
-
1824  if (post_processing.calculate_viscous_dissipation)
-
1825  deserialize_table(this->viscous_dissipation_table,
-
1826  prefix +
-
1827  post_processing.viscous_dissipation_output_name +
-
1828  suffix);
-
1829  if (post_processing.calculate_kinetic_energy)
-
1830  deserialize_table(this->kinetic_energy_table,
-
1831  prefix + post_processing.kinetic_energy_output_name +
+
1824  if (post_processing.calculate_pressure_power)
+
1825  deserialize_table(this->pressure_power_table,
+
1826  prefix + post_processing.pressure_power_output_name +
+
1827  suffix);
+
1828  if (post_processing.calculate_viscous_dissipation)
+
1829  deserialize_table(this->viscous_dissipation_table,
+
1830  prefix +
+
1831  post_processing.viscous_dissipation_output_name +
1832  suffix);
-
1833  if (post_processing.calculate_apparent_viscosity)
-
1834  deserialize_table(this->apparent_viscosity_table,
-
1835  prefix +
-
1836  post_processing.apparent_viscosity_output_name +
-
1837  suffix);
-
1838  if (post_processing.calculate_flow_rate)
-
1839  deserialize_table(this->flow_rate_table,
-
1840  prefix + post_processing.flow_rate_output_name +
+
1833  if (post_processing.calculate_kinetic_energy)
+
1834  deserialize_table(this->kinetic_energy_table,
+
1835  prefix + post_processing.kinetic_energy_output_name +
+
1836  suffix);
+
1837  if (post_processing.calculate_apparent_viscosity)
+
1838  deserialize_table(this->apparent_viscosity_table,
+
1839  prefix +
+
1840  post_processing.apparent_viscosity_output_name +
1841  suffix);
-
1842  if (post_processing.calculate_pressure_drop)
-
1843  deserialize_table(this->pressure_drop_table,
-
1844  prefix + post_processing.pressure_drop_output_name +
+
1842  if (post_processing.calculate_flow_rate)
+
1843  deserialize_table(this->flow_rate_table,
+
1844  prefix + post_processing.flow_rate_output_name +
1845  suffix);
-
1846  if (this->simulation_parameters.forces_parameters.calculate_force)
-
1847  for (unsigned int boundary_id = 0;
-
1848  boundary_id < this->simulation_parameters.boundary_conditions.size;
-
1849  ++boundary_id)
-
1850  {
- -
1852  this->forces_tables[boundary_id],
-
1853  prefix +
-
1854  this->simulation_parameters.forces_parameters.force_output_name +
-
1855  "_" + Utilities::int_to_string(boundary_id, 2) + suffix);
-
1856  }
-
1857  if (this->simulation_parameters.forces_parameters.calculate_torque)
-
1858  for (unsigned int boundary_id = 0;
-
1859  boundary_id < this->simulation_parameters.boundary_conditions.size;
-
1860  ++boundary_id)
-
1861  {
- -
1863  this->torques_tables[boundary_id],
-
1864  prefix +
-
1865  this->simulation_parameters.forces_parameters.torque_output_name +
-
1866  "_" + Utilities::int_to_string(boundary_id, 2) + suffix);
-
1867  }
-
1868  if (this->simulation_parameters.analytical_solution->calculate_error())
- -
1870  this->error_table,
-
1871  prefix +
-
1872  this->simulation_parameters.analytical_solution->get_filename() +
-
1873  "_FD" + suffix);
-
1874  }
-
1875 }
-
1876 
-
1877 template <int dim, typename VectorType, typename DofsType>
-
1878 void
- -
1880  const bool non_zero_constraints)
-
1881 {
-
1882  // If there are no solid regions, there is no work to be done and we can
-
1883  // return
-
1884  if (simulation_parameters.physical_properties_manager
-
1885  .get_number_of_solids() == 0)
-
1886  return;
-
1887 
-
1888  const unsigned int dofs_per_cell = this->fe->dofs_per_cell;
-
1889  std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
-
1890 
-
1891  // We will need to identify which pressure degrees of freedom are connected to
-
1892  // fluid region. For these, we won't establish a zero pressure constraint.
-
1893  std::unordered_set<types::global_dof_index> dofs_are_connected_to_fluid;
+
1846  if (post_processing.calculate_pressure_drop)
+
1847  deserialize_table(this->pressure_drop_table,
+
1848  prefix + post_processing.pressure_drop_output_name +
+
1849  suffix);
+
1850  if (this->simulation_parameters.forces_parameters.calculate_force)
+
1851  for (unsigned int boundary_id = 0;
+
1852  boundary_id < this->simulation_parameters.boundary_conditions.size;
+
1853  ++boundary_id)
+
1854  {
+ +
1856  this->forces_tables[boundary_id],
+
1857  prefix +
+
1858  this->simulation_parameters.forces_parameters.force_output_name +
+
1859  "_" + Utilities::int_to_string(boundary_id, 2) + suffix);
+
1860  }
+
1861  if (this->simulation_parameters.forces_parameters.calculate_torque)
+
1862  for (unsigned int boundary_id = 0;
+
1863  boundary_id < this->simulation_parameters.boundary_conditions.size;
+
1864  ++boundary_id)
+
1865  {
+ +
1867  this->torques_tables[boundary_id],
+
1868  prefix +
+
1869  this->simulation_parameters.forces_parameters.torque_output_name +
+
1870  "_" + Utilities::int_to_string(boundary_id, 2) + suffix);
+
1871  }
+
1872  if (this->simulation_parameters.analytical_solution->calculate_error())
+ +
1874  this->error_table,
+
1875  prefix +
+
1876  this->simulation_parameters.analytical_solution->get_filename() +
+
1877  "_FD" + suffix);
+
1878  }
+
1879 }
+
1880 
+
1881 template <int dim, typename VectorType, typename DofsType>
+
1882 void
+ +
1884  const bool non_zero_constraints)
+
1885 {
+
1886  // If there are no solid regions, there is no work to be done and we can
+
1887  // return
+
1888  if (simulation_parameters.physical_properties_manager
+
1889  .get_number_of_solids() == 0)
+
1890  return;
+
1891 
+
1892  const unsigned int dofs_per_cell = this->fe->dofs_per_cell;
+
1893  std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
1894 
-
1895  // Loop through all cells to identify which cells are solid. This first step
-
1896  // is used to 1) constraint the velocity degree of freedom to be zero in the
-
1897  // solid region and 2) to identify which pressure degrees of freedom are
-
1898  // connected to fluid cells
-
1899  for (const auto &cell : dof_handler.active_cell_iterators())
-
1900  {
-
1901  if (cell->is_locally_owned() || cell->is_ghost())
-
1902  {
-
1903  cell->get_dof_indices(local_dof_indices);
-
1904  // If the material_id is higher than 0, the region is a solid region.
-
1905  // Constrain the velocity DOFs to be zero.
-
1906  if (cell->material_id() > 0)
-
1907  {
-
1908  constrain_solid_cell_velocity_dofs(non_zero_constraints,
-
1909  local_dof_indices,
-
1910  this->zero_constraints);
-
1911  }
-
1912  else
-
1913  {
-
1914  // Cell is a fluid cell and as such all the pressure DOFs of that
-
1915  // cell are connected to the fluid. This will be used later on to
-
1916  // identify which pressure cells to constrain.
-
1917  flag_dofs_connected_to_fluid(local_dof_indices,
-
1918  dofs_are_connected_to_fluid);
-
1919  }
-
1920  }
-
1921  }
-
1922 
-
1923  // All pressure DOFs that are not connected to a fluid cell are constrained
-
1924  // to ensure that the system matrix has adequate conditioning.
-
1925  for (const auto &cell : dof_handler.active_cell_iterators())
-
1926  {
-
1927  if (cell->is_locally_owned() || cell->is_ghost())
-
1928  {
-
1929  cell->get_dof_indices(local_dof_indices);
-
1930  // If the material_id is > 0, the region is a solid region
-
1931  if (cell->material_id() > 0)
-
1932  {
-
1933  // First check if the cell is connected to a fluid cell by
-
1934  // checking if one of the DOF of the cell is connected to a fluid
-
1935  // cell.
-
1936  bool connected_to_fluid =
-
1937  check_cell_is_connected_to_fluid(dofs_are_connected_to_fluid,
-
1938  local_dof_indices);
-
1939 
-
1940  // All the pressure DOFs with the cell are not connected to the
-
1941  // fluid. Consequently, we fix a constraint on these pressure
-
1942  // DOFs.
-
1943  if (!connected_to_fluid)
-
1944  {
-
1945  constrain_pressure(non_zero_constraints,
-
1946  local_dof_indices,
-
1947  this->zero_constraints);
-
1948  }
-
1949  }
-
1950  }
-
1951  }
-
1952 }
-
1953 
-
1954 template <int dim, typename VectorType, typename DofsType>
-
1955 void
- -
1957  const DoFHandler<dim> *dof_handler_ht)
-
1958 {
-
1959  const unsigned int dofs_per_cell = this->fe->dofs_per_cell;
-
1960  std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
-
1961 
-
1962  // Get struct containing temperature range information and flag
-
1963  // containers for DOFs.
-
1964  StasisConstraintWithTemperature &stasis_constraint_struct =
-
1965  this->stasis_constraint_structs[0];
-
1966 
-
1967  // Get temperature solution
-
1968  const auto temperature_solution =
-
1969  *this->multiphysics->get_solution(PhysicsID::heat_transfer);
-
1970  std::vector<double> local_temperature_values(this->cell_quadrature->size());
-
1971 
-
1972  for (const auto &cell : dof_handler.active_cell_iterators())
-
1973  {
-
1974  if (cell->is_locally_owned() || cell->is_ghost())
-
1975  {
-
1976  cell->get_dof_indices(local_dof_indices);
-
1977  get_cell_temperature_values(cell,
-
1978  dof_handler_ht,
-
1979  temperature_solution,
-
1980  local_temperature_values);
-
1981  add_flags_and_constrain_velocity(local_dof_indices,
-
1982  local_temperature_values,
-
1983  stasis_constraint_struct);
-
1984  }
-
1985  }
-
1986  check_and_constrain_pressure(stasis_constraint_struct, local_dof_indices);
-
1987 }
-
1988 
-
1989 template <int dim, typename VectorType, typename DofsType>
-
1990 void
- -
1992  constrain_stasis_with_temperature_vof(const DoFHandler<dim> *dof_handler_vof,
-
1993  const DoFHandler<dim> *dof_handler_ht)
-
1994 {
-
1995  const unsigned int dofs_per_cell = this->fe->dofs_per_cell;
-
1996  std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
-
1997 
-
1998  // Get filtered phase fraction solution
-
1999  const auto filtered_phase_fraction_solution =
-
2000  *this->multiphysics->get_filtered_solution(PhysicsID::VOF);
-
2001  std::vector<double> local_filtered_phase_fraction_values(
-
2002  this->cell_quadrature->size());
-
2003 
-
2004  // Get temperature solution
-
2005  const auto temperature_solution =
-
2006  *this->multiphysics->get_solution(PhysicsID::heat_transfer);
-
2007  std::vector<double> local_temperature_values(this->cell_quadrature->size());
-
2008 
-
2009  // Loop over structs containing fluid id, temperature and phase fraction range
-
2010  // information, and flag containers for DOFs.
-
2011  for (StasisConstraintWithTemperature &stasis_constraint_struct :
-
2012  this->stasis_constraint_structs)
-
2013  {
-
2014  for (const auto &cell : dof_handler.active_cell_iterators())
-
2015  {
-
2016  if (cell->is_locally_owned() || cell->is_ghost())
-
2017  {
-
2018  cell->get_dof_indices(local_dof_indices);
-
2019  bool cell_is_in_right_fluid = true;
-
2020 
-
2021  get_cell_filtered_phase_fraction_values(
-
2022  cell,
-
2023  dof_handler_vof,
-
2024  filtered_phase_fraction_solution,
-
2025  local_filtered_phase_fraction_values);
-
2026 
-
2027  // Check if cell is only in the fluid of interest. As soon as one
-
2028  // filtered phase fraction value is outside the tolerated range,
-
2029  // the cell is perceived as being in the wrong fluid.
-
2030  for (const double &filtered_phase_fraction :
-
2031  local_filtered_phase_fraction_values)
-
2032  {
-
2033  if (abs(stasis_constraint_struct.fluid_id -
-
2034  filtered_phase_fraction) >=
-
2035  stasis_constraint_struct
-
2036  .filtered_phase_fraction_tolerance)
-
2037  {
-
2038  cell_is_in_right_fluid = false;
-
2039  break;
-
2040  }
-
2041  }
-
2042 
-
2043  // If the cell is not in the right fluid, no solid constraint will
-
2044  // be applied on the cell's DOFs. We flag the current cell's DOFs
-
2045  // as "connected to fluid" and we skip to the next cell.
-
2046  if (!cell_is_in_right_fluid)
-
2047  {
-
2048  flag_dofs_connected_to_fluid(
-
2049  local_dof_indices,
-
2050  stasis_constraint_struct.dofs_are_connected_to_fluid);
-
2051  continue;
-
2052  }
-
2053 
-
2054  get_cell_temperature_values(cell,
-
2055  dof_handler_ht,
-
2056  temperature_solution,
-
2057  local_temperature_values);
-
2058  add_flags_and_constrain_velocity(local_dof_indices,
-
2059  local_temperature_values,
-
2060  stasis_constraint_struct);
-
2061  }
-
2062  }
-
2063  check_and_constrain_pressure(stasis_constraint_struct, local_dof_indices);
-
2064  }
-
2065 }
-
2066 
-
2067 template <int dim, typename VectorType, typename DofsType>
-
2068 void
- -
2070  const std::vector<types::global_dof_index> &local_dof_indices,
-
2071  const std::vector<double> &local_temperature_values,
-
2072  StasisConstraintWithTemperature &stasis_constraint_struct)
-
2073 {
-
2074  for (const double &temperature : local_temperature_values)
-
2075  {
-
2076  // Flag non-solid cell DOFs to identify which pressure DOFs should not
-
2077  // be constrained.
-
2078  if (temperature < stasis_constraint_struct.min_solid_temperature ||
-
2079  temperature > stasis_constraint_struct.max_solid_temperature)
-
2080  {
-
2081  flag_dofs_connected_to_fluid(
-
2082  local_dof_indices,
-
2083  stasis_constraint_struct.dofs_are_connected_to_fluid);
-
2084  return;
-
2085  }
-
2086 
-
2087  // If the cell is solid, flag it as solid and constrain its velocity DOFs
-
2088  flag_dofs_in_solid(local_dof_indices,
-
2089  stasis_constraint_struct.dofs_are_in_solid);
-
2090  constrain_solid_cell_velocity_dofs(false,
-
2091  local_dof_indices,
-
2092  this->dynamic_zero_constraints);
-
2093  }
-
2094 }
-
2095 
-
2096 template <int dim, typename VectorType, typename DofsType>
-
2097 void
- -
2099  const StasisConstraintWithTemperature &stasis_constraint_struct,
-
2100  std::vector<types::global_dof_index> &local_dof_indices)
-
2101 {
-
2102  for (const auto &cell : dof_handler.active_cell_iterators())
-
2103  {
-
2104  if (cell->is_locally_owned() || cell->is_ghost())
-
2105  {
-
2106  cell->get_dof_indices(local_dof_indices);
-
2107  bool cell_is_solid =
-
2108  check_cell_is_in_solid(stasis_constraint_struct.dofs_are_in_solid,
-
2109  local_dof_indices);
-
2110  if (cell_is_solid)
-
2111  {
-
2112  bool connected_to_fluid = check_cell_is_connected_to_fluid(
-
2113  stasis_constraint_struct.dofs_are_connected_to_fluid,
-
2114  local_dof_indices);
-
2115  if (!connected_to_fluid)
-
2116  {
-
2117  // Set homogeneous constraints to pressure DOFs that are not
-
2118  // connected to a fluid.
-
2119  constrain_pressure(false,
-
2120  local_dof_indices,
-
2121  this->dynamic_zero_constraints);
-
2122  }
-
2123  }
-
2124  }
-
2125  }
-
2126 }
-
2127 
-
2128 template <int dim, typename VectorType, typename DofsType>
-
2129 void
- -
2131  DataOut<dim> & /*data_out*/)
-
2132 {}
-
2133 
-
2134 template <int dim, typename VectorType, typename DofsType>
-
2135 void
- -
2137  const VectorType &solution)
-
2138 {
-
2139  TimerOutput::Scope t(this->computing_timer, "Output VTU");
-
2140 
-
2141  const std::string folder = simulation_control->get_output_path();
-
2142  const std::string solution_name = simulation_control->get_output_name();
-
2143  const unsigned int iter = simulation_control->get_step_number();
-
2144  const double time = simulation_control->get_current_time();
-
2145  const unsigned int subdivision = simulation_control->get_number_subdivision();
-
2146  const unsigned int group_files = simulation_control->get_group_files();
-
2147 
-
2148  // Add the interpretation of the solution. The dim first components are the
-
2149  // velocity vectors and the following one is the pressure.
-
2150  std::vector<std::string> solution_names(dim, "velocity");
-
2151  solution_names.push_back("pressure");
-
2152  std::vector<DataComponentInterpretation::DataComponentInterpretation>
-
2153  data_component_interpretation(
-
2154  dim, DataComponentInterpretation::component_is_part_of_vector);
-
2155  data_component_interpretation.push_back(
-
2156  DataComponentInterpretation::component_is_scalar);
-
2157 
-
2158  DataOut<dim> data_out;
-
2159 
-
2160  // Additional flag to enable the output of high-order elements
-
2161  DataOutBase::VtkFlags flags;
-
2162  if (this->velocity_fem_degree > 1)
-
2163  flags.write_higher_order_cells = true;
-
2164  data_out.set_flags(flags);
-
2165 
-
2166  // Attach the solution data to data_out object
-
2167  data_out.attach_dof_handler(this->dof_handler);
-
2168  data_out.add_data_vector(solution,
-
2169  solution_names,
-
2170  DataOut<dim>::type_dof_data,
-
2171  data_component_interpretation);
-
2172 
-
2173  if (this->simulation_parameters.post_processing.calculate_average_velocities)
-
2174  {
-
2175  // Add the interpretation of the average solution. The dim first
-
2176  // components are the average velocity vectors and the following one is
-
2177  // the average pressure. (<u>, <v>, <w>, <p>)
-
2178  std::vector<std::string> average_solution_names(dim, "average_velocity");
-
2179  average_solution_names.push_back("average_pressure");
-
2180 
-
2181  std::vector<DataComponentInterpretation::DataComponentInterpretation>
-
2182  average_data_component_interpretation(
-
2183  dim, DataComponentInterpretation::component_is_part_of_vector);
-
2184  average_data_component_interpretation.push_back(
-
2185  DataComponentInterpretation::component_is_scalar);
-
2186 
-
2187  data_out.add_data_vector(
-
2188  this->average_velocities->get_average_velocities(),
-
2189  average_solution_names,
-
2190  DataOut<dim>::type_dof_data,
-
2191  average_data_component_interpretation);
-
2192 
-
2193  // Add the interpretation of the reynolds stresses of solution.
-
2194  // The dim first components are the normal reynolds stress vectors and
-
2195  // the following ones are others resolved reynolds stresses.
-
2196  std::vector<std::string> reynolds_normal_stress_names(
-
2197  dim, "reynolds_normal_stress");
-
2198  reynolds_normal_stress_names.push_back("turbulent_kinetic_energy");
-
2199  std::vector<DataComponentInterpretation::DataComponentInterpretation>
-
2200  reynolds_normal_stress_data_component_interpretation(
-
2201  dim, DataComponentInterpretation::component_is_part_of_vector);
-
2202  reynolds_normal_stress_data_component_interpretation.push_back(
-
2203  DataComponentInterpretation::component_is_scalar);
-
2204 
-
2205 
-
2206  std::vector<std::string> reynolds_shear_stress_names = {
-
2207  "reynolds_shear_stress_uv"};
-
2208  if (dim == 2)
-
2209  {
-
2210  reynolds_shear_stress_names.push_back("dummy_rss_2d");
-
2211  }
-
2212  if (dim == 3)
+
1895  // We will need to identify which pressure degrees of freedom are connected to
+
1896  // fluid region. For these, we won't establish a zero pressure constraint.
+
1897  std::unordered_set<types::global_dof_index> dofs_are_connected_to_fluid;
+
1898 
+
1899  // Loop through all cells to identify which cells are solid. This first step
+
1900  // is used to 1) constraint the velocity degree of freedom to be zero in the
+
1901  // solid region and 2) to identify which pressure degrees of freedom are
+
1902  // connected to fluid cells
+
1903  for (const auto &cell : dof_handler.active_cell_iterators())
+
1904  {
+
1905  if (cell->is_locally_owned() || cell->is_ghost())
+
1906  {
+
1907  cell->get_dof_indices(local_dof_indices);
+
1908  // If the material_id is higher than 0, the region is a solid region.
+
1909  // Constrain the velocity DOFs to be zero.
+
1910  if (cell->material_id() > 0)
+
1911  {
+
1912  constrain_solid_cell_velocity_dofs(non_zero_constraints,
+
1913  local_dof_indices,
+
1914  this->zero_constraints);
+
1915  }
+
1916  else
+
1917  {
+
1918  // Cell is a fluid cell and as such all the pressure DOFs of that
+
1919  // cell are connected to the fluid. This will be used later on to
+
1920  // identify which pressure cells to constrain.
+
1921  flag_dofs_connected_to_fluid(local_dof_indices,
+
1922  dofs_are_connected_to_fluid);
+
1923  }
+
1924  }
+
1925  }
+
1926 
+
1927  // All pressure DOFs that are not connected to a fluid cell are constrained
+
1928  // to ensure that the system matrix has adequate conditioning.
+
1929  for (const auto &cell : dof_handler.active_cell_iterators())
+
1930  {
+
1931  if (cell->is_locally_owned() || cell->is_ghost())
+
1932  {
+
1933  cell->get_dof_indices(local_dof_indices);
+
1934  // If the material_id is > 0, the region is a solid region
+
1935  if (cell->material_id() > 0)
+
1936  {
+
1937  // First check if the cell is connected to a fluid cell by
+
1938  // checking if one of the DOF of the cell is connected to a fluid
+
1939  // cell.
+
1940  bool connected_to_fluid =
+
1941  check_cell_is_connected_to_fluid(dofs_are_connected_to_fluid,
+
1942  local_dof_indices);
+
1943 
+
1944  // All the pressure DOFs with the cell are not connected to the
+
1945  // fluid. Consequently, we fix a constraint on these pressure
+
1946  // DOFs.
+
1947  if (!connected_to_fluid)
+
1948  {
+
1949  constrain_pressure(non_zero_constraints,
+
1950  local_dof_indices,
+
1951  this->zero_constraints);
+
1952  }
+
1953  }
+
1954  }
+
1955  }
+
1956 }
+
1957 
+
1958 template <int dim, typename VectorType, typename DofsType>
+
1959 void
+ +
1961  const DoFHandler<dim> *dof_handler_ht)
+
1962 {
+
1963  const unsigned int dofs_per_cell = this->fe->dofs_per_cell;
+
1964  std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
+
1965 
+
1966  // Get struct containing temperature range information and flag
+
1967  // containers for DOFs.
+
1968  StasisConstraintWithTemperature &stasis_constraint_struct =
+
1969  this->stasis_constraint_structs[0];
+
1970 
+
1971  // Get temperature solution
+
1972  const auto temperature_solution =
+
1973  *this->multiphysics->get_solution(PhysicsID::heat_transfer);
+
1974  std::vector<double> local_temperature_values(this->cell_quadrature->size());
+
1975 
+
1976  for (const auto &cell : dof_handler.active_cell_iterators())
+
1977  {
+
1978  if (cell->is_locally_owned() || cell->is_ghost())
+
1979  {
+
1980  cell->get_dof_indices(local_dof_indices);
+
1981  get_cell_temperature_values(cell,
+
1982  dof_handler_ht,
+
1983  temperature_solution,
+
1984  local_temperature_values);
+
1985  add_flags_and_constrain_velocity(local_dof_indices,
+
1986  local_temperature_values,
+
1987  stasis_constraint_struct);
+
1988  }
+
1989  }
+
1990  check_and_constrain_pressure(stasis_constraint_struct, local_dof_indices);
+
1991 }
+
1992 
+
1993 template <int dim, typename VectorType, typename DofsType>
+
1994 void
+ +
1996  constrain_stasis_with_temperature_vof(const DoFHandler<dim> *dof_handler_vof,
+
1997  const DoFHandler<dim> *dof_handler_ht)
+
1998 {
+
1999  const unsigned int dofs_per_cell = this->fe->dofs_per_cell;
+
2000  std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
+
2001 
+
2002  // Get filtered phase fraction solution
+
2003  const auto filtered_phase_fraction_solution =
+
2004  *this->multiphysics->get_filtered_solution(PhysicsID::VOF);
+
2005  std::vector<double> local_filtered_phase_fraction_values(
+
2006  this->cell_quadrature->size());
+
2007 
+
2008  // Get temperature solution
+
2009  const auto temperature_solution =
+
2010  *this->multiphysics->get_solution(PhysicsID::heat_transfer);
+
2011  std::vector<double> local_temperature_values(this->cell_quadrature->size());
+
2012 
+
2013  // Loop over structs containing fluid id, temperature and phase fraction range
+
2014  // information, and flag containers for DOFs.
+
2015  for (StasisConstraintWithTemperature &stasis_constraint_struct :
+
2016  this->stasis_constraint_structs)
+
2017  {
+
2018  for (const auto &cell : dof_handler.active_cell_iterators())
+
2019  {
+
2020  if (cell->is_locally_owned() || cell->is_ghost())
+
2021  {
+
2022  cell->get_dof_indices(local_dof_indices);
+
2023  bool cell_is_in_right_fluid = true;
+
2024 
+
2025  get_cell_filtered_phase_fraction_values(
+
2026  cell,
+
2027  dof_handler_vof,
+
2028  filtered_phase_fraction_solution,
+
2029  local_filtered_phase_fraction_values);
+
2030 
+
2031  // Check if cell is only in the fluid of interest. As soon as one
+
2032  // filtered phase fraction value is outside the tolerated range,
+
2033  // the cell is perceived as being in the wrong fluid.
+
2034  for (const double &filtered_phase_fraction :
+
2035  local_filtered_phase_fraction_values)
+
2036  {
+
2037  if (abs(stasis_constraint_struct.fluid_id -
+
2038  filtered_phase_fraction) >=
+
2039  stasis_constraint_struct
+
2040  .filtered_phase_fraction_tolerance)
+
2041  {
+
2042  cell_is_in_right_fluid = false;
+
2043  break;
+
2044  }
+
2045  }
+
2046 
+
2047  // If the cell is not in the right fluid, no solid constraint will
+
2048  // be applied on the cell's DOFs. We flag the current cell's DOFs
+
2049  // as "connected to fluid" and we skip to the next cell.
+
2050  if (!cell_is_in_right_fluid)
+
2051  {
+
2052  flag_dofs_connected_to_fluid(
+
2053  local_dof_indices,
+
2054  stasis_constraint_struct.dofs_are_connected_to_fluid);
+
2055  continue;
+
2056  }
+
2057 
+
2058  get_cell_temperature_values(cell,
+
2059  dof_handler_ht,
+
2060  temperature_solution,
+
2061  local_temperature_values);
+
2062  add_flags_and_constrain_velocity(local_dof_indices,
+
2063  local_temperature_values,
+
2064  stasis_constraint_struct);
+
2065  }
+
2066  }
+
2067  check_and_constrain_pressure(stasis_constraint_struct, local_dof_indices);
+
2068  }
+
2069 }
+
2070 
+
2071 template <int dim, typename VectorType, typename DofsType>
+
2072 void
+ +
2074  const std::vector<types::global_dof_index> &local_dof_indices,
+
2075  const std::vector<double> &local_temperature_values,
+
2076  StasisConstraintWithTemperature &stasis_constraint_struct)
+
2077 {
+
2078  for (const double &temperature : local_temperature_values)
+
2079  {
+
2080  // Flag non-solid cell DOFs to identify which pressure DOFs should not
+
2081  // be constrained.
+
2082  if (temperature < stasis_constraint_struct.min_solid_temperature ||
+
2083  temperature > stasis_constraint_struct.max_solid_temperature)
+
2084  {
+
2085  flag_dofs_connected_to_fluid(
+
2086  local_dof_indices,
+
2087  stasis_constraint_struct.dofs_are_connected_to_fluid);
+
2088  return;
+
2089  }
+
2090 
+
2091  // If the cell is solid, flag it as solid and constrain its velocity DOFs
+
2092  flag_dofs_in_solid(local_dof_indices,
+
2093  stasis_constraint_struct.dofs_are_in_solid);
+
2094  constrain_solid_cell_velocity_dofs(false,
+
2095  local_dof_indices,
+
2096  this->dynamic_zero_constraints);
+
2097  }
+
2098 }
+
2099 
+
2100 template <int dim, typename VectorType, typename DofsType>
+
2101 void
+ +
2103  const StasisConstraintWithTemperature &stasis_constraint_struct,
+
2104  std::vector<types::global_dof_index> &local_dof_indices)
+
2105 {
+
2106  for (const auto &cell : dof_handler.active_cell_iterators())
+
2107  {
+
2108  if (cell->is_locally_owned() || cell->is_ghost())
+
2109  {
+
2110  cell->get_dof_indices(local_dof_indices);
+
2111  bool cell_is_solid =
+
2112  check_cell_is_in_solid(stasis_constraint_struct.dofs_are_in_solid,
+
2113  local_dof_indices);
+
2114  if (cell_is_solid)
+
2115  {
+
2116  bool connected_to_fluid = check_cell_is_connected_to_fluid(
+
2117  stasis_constraint_struct.dofs_are_connected_to_fluid,
+
2118  local_dof_indices);
+
2119  if (!connected_to_fluid)
+
2120  {
+
2121  // Set homogeneous constraints to pressure DOFs that are not
+
2122  // connected to a fluid.
+
2123  constrain_pressure(false,
+
2124  local_dof_indices,
+
2125  this->dynamic_zero_constraints);
+
2126  }
+
2127  }
+
2128  }
+
2129  }
+
2130 }
+
2131 
+
2132 template <int dim, typename VectorType, typename DofsType>
+
2133 void
+ +
2135  DataOut<dim> & /*data_out*/)
+
2136 {}
+
2137 
+
2138 template <int dim, typename VectorType, typename DofsType>
+
2139 void
+ +
2141  const VectorType &solution)
+
2142 {
+
2143  TimerOutput::Scope t(this->computing_timer, "Output VTU");
+
2144 
+
2145  const std::string folder = simulation_control->get_output_path();
+
2146  const std::string solution_name = simulation_control->get_output_name();
+
2147  const unsigned int iter = simulation_control->get_step_number();
+
2148  const double time = simulation_control->get_current_time();
+
2149  const unsigned int subdivision = simulation_control->get_number_subdivision();
+
2150  const unsigned int group_files = simulation_control->get_group_files();
+
2151 
+
2152  // Add the interpretation of the solution. The dim first components are the
+
2153  // velocity vectors and the following one is the pressure.
+
2154  std::vector<std::string> solution_names(dim, "velocity");
+
2155  solution_names.push_back("pressure");
+
2156  std::vector<DataComponentInterpretation::DataComponentInterpretation>
+
2157  data_component_interpretation(
+
2158  dim, DataComponentInterpretation::component_is_part_of_vector);
+
2159  data_component_interpretation.push_back(
+
2160  DataComponentInterpretation::component_is_scalar);
+
2161 
+
2162  DataOut<dim> data_out;
+
2163 
+
2164  // Additional flag to enable the output of high-order elements
+
2165  DataOutBase::VtkFlags flags;
+
2166  if (this->velocity_fem_degree > 1)
+
2167  flags.write_higher_order_cells = true;
+
2168  data_out.set_flags(flags);
+
2169 
+
2170  // Attach the solution data to data_out object
+
2171  data_out.attach_dof_handler(this->dof_handler);
+
2172  data_out.add_data_vector(solution,
+
2173  solution_names,
+
2174  DataOut<dim>::type_dof_data,
+
2175  data_component_interpretation);
+
2176 
+
2177  if (this->simulation_parameters.post_processing.calculate_average_velocities)
+
2178  {
+
2179  // Add the interpretation of the average solution. The dim first
+
2180  // components are the average velocity vectors and the following one is
+
2181  // the average pressure. (<u>, <v>, <w>, <p>)
+
2182  std::vector<std::string> average_solution_names(dim, "average_velocity");
+
2183  average_solution_names.push_back("average_pressure");
+
2184 
+
2185  std::vector<DataComponentInterpretation::DataComponentInterpretation>
+
2186  average_data_component_interpretation(
+
2187  dim, DataComponentInterpretation::component_is_part_of_vector);
+
2188  average_data_component_interpretation.push_back(
+
2189  DataComponentInterpretation::component_is_scalar);
+
2190 
+
2191  data_out.add_data_vector(
+
2192  this->average_velocities->get_average_velocities(),
+
2193  average_solution_names,
+
2194  DataOut<dim>::type_dof_data,
+
2195  average_data_component_interpretation);
+
2196 
+
2197  // Add the interpretation of the reynolds stresses of solution.
+
2198  // The dim first components are the normal reynolds stress vectors and
+
2199  // the following ones are others resolved reynolds stresses.
+
2200  std::vector<std::string> reynolds_normal_stress_names(
+
2201  dim, "reynolds_normal_stress");
+
2202  reynolds_normal_stress_names.push_back("turbulent_kinetic_energy");
+
2203  std::vector<DataComponentInterpretation::DataComponentInterpretation>
+
2204  reynolds_normal_stress_data_component_interpretation(
+
2205  dim, DataComponentInterpretation::component_is_part_of_vector);
+
2206  reynolds_normal_stress_data_component_interpretation.push_back(
+
2207  DataComponentInterpretation::component_is_scalar);
+
2208 
+
2209 
+
2210  std::vector<std::string> reynolds_shear_stress_names = {
+
2211  "reynolds_shear_stress_uv"};
+
2212  if (dim == 2)
2213  {
-
2214  reynolds_shear_stress_names.push_back("reynolds_shear_stress_vw");
-
2215  reynolds_shear_stress_names.push_back("reynolds_shear_stress_uw");
-
2216  }
-
2217  reynolds_shear_stress_names.push_back("dummy_rss");
-
2218 
-
2219  std::vector<DataComponentInterpretation::DataComponentInterpretation>
-
2220  reynolds_shear_stress_data_component_interpretation(
-
2221  dim, DataComponentInterpretation::component_is_scalar);
-
2222  reynolds_shear_stress_data_component_interpretation.push_back(
-
2223  DataComponentInterpretation::component_is_scalar);
-
2224 
-
2225  data_out.add_data_vector(
-
2226  this->average_velocities->get_reynolds_normal_stresses(),
-
2227  reynolds_normal_stress_names,
-
2228  DataOut<dim>::type_dof_data,
-
2229  reynolds_normal_stress_data_component_interpretation);
-
2230 
-
2231  data_out.add_data_vector(
-
2232  this->average_velocities->get_reynolds_shear_stresses(),
-
2233  reynolds_shear_stress_names,
-
2234  DataOut<dim>::type_dof_data,
-
2235  reynolds_shear_stress_data_component_interpretation);
-
2236  }
-
2237 
-
2238  Vector<float> subdomain(this->triangulation->n_active_cells());
-
2239  for (unsigned int i = 0; i < subdomain.size(); ++i)
-
2240  subdomain(i) = this->triangulation->locally_owned_subdomain();
-
2241  data_out.add_data_vector(subdomain, "subdomain");
-
2242 
-
2243 
-
2244  // Create the post-processors to have derived information about the velocity
-
2245  // They are generated outside the if condition for smoothing to ensure
-
2246  // that the objects still exist when the write output of DataOut is called
-
2247  // Regular discontinuous postprocessors
-
2248  QCriterionPostprocessor<dim> qcriterion;
-
2249  DivergencePostprocessor<dim> divergence;
-
2250  VorticityPostprocessor<dim> vorticity;
-
2251  data_out.add_data_vector(solution, vorticity);
-
2252 
-
2253  // Get physical properties models
-
2254  std::vector<std::shared_ptr<DensityModel>> density_models =
-
2255  this->simulation_parameters.physical_properties_manager
-
2256  .get_density_vector();
-
2257  std::vector<std::shared_ptr<RheologicalModel>> rheological_models =
-
2258  this->simulation_parameters.physical_properties_manager
-
2259  .get_rheology_vector();
-
2260 
-
2261  const double n_fluids = this->simulation_parameters
-
2262  .physical_properties_manager.get_number_of_fluids();
-
2263 
-
2264  std::vector<DensityPostprocessor<dim>> density_postprocessors;
-
2265  density_postprocessors.reserve(n_fluids);
-
2266  std::vector<KinematicViscosityPostprocessor<dim>>
-
2267  kinematic_viscosity_postprocessors;
-
2268  kinematic_viscosity_postprocessors.reserve(n_fluids);
-
2269  std::vector<DynamicViscosityPostprocessor<dim>>
-
2270  dynamic_viscosity_postprocessors;
-
2271  dynamic_viscosity_postprocessors.reserve(n_fluids);
-
2272 
-
2273  for (unsigned int f_id = 0; f_id < n_fluids; ++f_id)
-
2274  {
-
2275  density_postprocessors.push_back(
-
2276  DensityPostprocessor<dim>(density_models[f_id], f_id));
-
2277  kinematic_viscosity_postprocessors.push_back(
-
2278  KinematicViscosityPostprocessor<dim>(rheological_models[f_id], f_id));
-
2279  dynamic_viscosity_postprocessors.push_back(
- -
2281  rheological_models[f_id],
-
2282  density_models[f_id]->get_density_ref(),
-
2283  f_id));
-
2284 
-
2285  // Only output when density is not constant or if it is a multiphase
-
2286  // flow
-
2287  if (!density_models[f_id]->is_constant_density_model() ||
-
2288  this->simulation_parameters.multiphysics.VOF ||
-
2289  this->simulation_parameters.multiphysics.cahn_hilliard)
-
2290  data_out.add_data_vector(solution, density_postprocessors[f_id]);
-
2291 
-
2292  // Only output the kinematic viscosity for non-newtonian rheology
-
2293  if (rheological_models[f_id]->is_non_newtonian_rheological_model())
-
2294  {
-
2295  data_out.add_data_vector(solution,
-
2296  kinematic_viscosity_postprocessors[f_id]);
-
2297 
-
2298  // Only output the dynamic viscosity for multiphase flows
-
2299  if (this->simulation_parameters.multiphysics.VOF ||
-
2300  this->simulation_parameters.multiphysics.cahn_hilliard)
-
2301  data_out.add_data_vector(solution,
-
2302  dynamic_viscosity_postprocessors[f_id]);
-
2303  }
-
2304  }
-
2305 
-
2306  ShearRatePostprocessor<dim> shear_rate_processor;
-
2307  if (this->simulation_parameters.physical_properties_manager
-
2308  .is_non_newtonian())
-
2309  data_out.add_data_vector(solution, shear_rate_processor);
-
2310 
-
2311  // Trilinos vector for the smoothed output fields
- -
2313  *this->triangulation,
-
2314  this->simulation_parameters,
-
2315  number_quadrature_points);
-
2316 
- -
2318  *this->triangulation,
-
2319  this->simulation_parameters,
-
2320  number_quadrature_points);
-
2321 
-
2322  // TODO: generalize this to VectorType
-
2323  GlobalVectorType qcriterion_field;
-
2324  GlobalVectorType continuity_field;
+
2214  reynolds_shear_stress_names.push_back("dummy_rss_2d");
+
2215  }
+
2216  if (dim == 3)
+
2217  {
+
2218  reynolds_shear_stress_names.push_back("reynolds_shear_stress_vw");
+
2219  reynolds_shear_stress_names.push_back("reynolds_shear_stress_uw");
+
2220  }
+
2221  reynolds_shear_stress_names.push_back("dummy_rss");
+
2222 
+
2223  std::vector<DataComponentInterpretation::DataComponentInterpretation>
+
2224  reynolds_shear_stress_data_component_interpretation(
+
2225  dim, DataComponentInterpretation::component_is_scalar);
+
2226  reynolds_shear_stress_data_component_interpretation.push_back(
+
2227  DataComponentInterpretation::component_is_scalar);
+
2228 
+
2229  data_out.add_data_vector(
+
2230  this->average_velocities->get_reynolds_normal_stresses(),
+
2231  reynolds_normal_stress_names,
+
2232  DataOut<dim>::type_dof_data,
+
2233  reynolds_normal_stress_data_component_interpretation);
+
2234 
+
2235  data_out.add_data_vector(
+
2236  this->average_velocities->get_reynolds_shear_stresses(),
+
2237  reynolds_shear_stress_names,
+
2238  DataOut<dim>::type_dof_data,
+
2239  reynolds_shear_stress_data_component_interpretation);
+
2240  }
+
2241 
+
2242  Vector<float> subdomain(this->triangulation->n_active_cells());
+
2243  for (unsigned int i = 0; i < subdomain.size(); ++i)
+
2244  subdomain(i) = this->triangulation->locally_owned_subdomain();
+
2245  data_out.add_data_vector(subdomain, "subdomain");
+
2246 
+
2247 
+
2248  // Create the post-processors to have derived information about the velocity
+
2249  // They are generated outside the if condition for smoothing to ensure
+
2250  // that the objects still exist when the write output of DataOut is called
+
2251  // Regular discontinuous postprocessors
+
2252  QCriterionPostprocessor<dim> qcriterion;
+
2253  DivergencePostprocessor<dim> divergence;
+
2254  VorticityPostprocessor<dim> vorticity;
+
2255  data_out.add_data_vector(solution, vorticity);
+
2256 
+
2257  // Get physical properties models
+
2258  std::vector<std::shared_ptr<DensityModel>> density_models =
+
2259  this->simulation_parameters.physical_properties_manager
+
2260  .get_density_vector();
+
2261  std::vector<std::shared_ptr<RheologicalModel>> rheological_models =
+
2262  this->simulation_parameters.physical_properties_manager
+
2263  .get_rheology_vector();
+
2264 
+
2265  const double n_fluids = this->simulation_parameters
+
2266  .physical_properties_manager.get_number_of_fluids();
+
2267 
+
2268  std::vector<DensityPostprocessor<dim>> density_postprocessors;
+
2269  density_postprocessors.reserve(n_fluids);
+
2270  std::vector<KinematicViscosityPostprocessor<dim>>
+
2271  kinematic_viscosity_postprocessors;
+
2272  kinematic_viscosity_postprocessors.reserve(n_fluids);
+
2273  std::vector<DynamicViscosityPostprocessor<dim>>
+
2274  dynamic_viscosity_postprocessors;
+
2275  dynamic_viscosity_postprocessors.reserve(n_fluids);
+
2276 
+
2277  for (unsigned int f_id = 0; f_id < n_fluids; ++f_id)
+
2278  {
+
2279  density_postprocessors.push_back(
+
2280  DensityPostprocessor<dim>(density_models[f_id], f_id));
+
2281  kinematic_viscosity_postprocessors.push_back(
+
2282  KinematicViscosityPostprocessor<dim>(rheological_models[f_id], f_id));
+
2283  dynamic_viscosity_postprocessors.push_back(
+ +
2285  rheological_models[f_id],
+
2286  density_models[f_id]->get_density_ref(),
+
2287  f_id));
+
2288 
+
2289  // Only output when density is not constant or if it is a multiphase
+
2290  // flow
+
2291  if (!density_models[f_id]->is_constant_density_model() ||
+
2292  this->simulation_parameters.multiphysics.VOF ||
+
2293  this->simulation_parameters.multiphysics.cahn_hilliard)
+
2294  data_out.add_data_vector(solution, density_postprocessors[f_id]);
+
2295 
+
2296  // Only output the kinematic viscosity for non-newtonian rheology
+
2297  if (rheological_models[f_id]->is_non_newtonian_rheological_model())
+
2298  {
+
2299  data_out.add_data_vector(solution,
+
2300  kinematic_viscosity_postprocessors[f_id]);
+
2301 
+
2302  // Only output the dynamic viscosity for multiphase flows
+
2303  if (this->simulation_parameters.multiphysics.VOF ||
+
2304  this->simulation_parameters.multiphysics.cahn_hilliard)
+
2305  data_out.add_data_vector(solution,
+
2306  dynamic_viscosity_postprocessors[f_id]);
+
2307  }
+
2308  }
+
2309 
+
2310  ShearRatePostprocessor<dim> shear_rate_processor;
+
2311  if (this->simulation_parameters.physical_properties_manager
+
2312  .is_non_newtonian())
+
2313  data_out.add_data_vector(solution, shear_rate_processor);
+
2314 
+
2315  // Trilinos vector for the smoothed output fields
+ +
2317  *this->triangulation,
+
2318  this->simulation_parameters,
+
2319  number_quadrature_points);
+
2320 
+ +
2322  *this->triangulation,
+
2323  this->simulation_parameters,
+
2324  number_quadrature_points);
2325 
-
2326  if (this->simulation_parameters.post_processing.smoothed_output_fields)
-
2327  {
-
2328  // Qcriterion smoothing
-
2329  {
-
2330  qcriterion_field =
-
2331  qcriterion_smoothing.calculate_smoothed_field(solution,
-
2332  this->dof_handler,
-
2333  this->mapping);
-
2334 
-
2335  std::vector<DataComponentInterpretation::DataComponentInterpretation>
-
2336  data_component_interpretation(
-
2337  1, DataComponentInterpretation::component_is_scalar);
+
2326  // TODO: generalize this to VectorType
+
2327  GlobalVectorType qcriterion_field;
+
2328  GlobalVectorType continuity_field;
+
2329 
+
2330  if (this->simulation_parameters.post_processing.smoothed_output_fields)
+
2331  {
+
2332  // Qcriterion smoothing
+
2333  {
+
2334  qcriterion_field =
+
2335  qcriterion_smoothing.calculate_smoothed_field(solution,
+
2336  this->dof_handler,
+
2337  this->mapping);
2338 
-
2339  std::vector<std::string> qcriterion_name = {"qcriterion"};
-
2340  const DoFHandler<dim> &dof_handler_qcriterion =
-
2341  qcriterion_smoothing.get_dof_handler();
-
2342  data_out.add_data_vector(dof_handler_qcriterion,
-
2343  qcriterion_field,
-
2344  qcriterion_name,
-
2345  data_component_interpretation);
-
2346  }
-
2347  // Continuity smoothing
-
2348  {
-
2349  continuity_field =
-
2350  continuity_smoothing.calculate_smoothed_field(solution,
-
2351  this->dof_handler,
-
2352  this->mapping);
-
2353 
-
2354  std::vector<DataComponentInterpretation::DataComponentInterpretation>
-
2355  data_component_interpretation(
-
2356  1, DataComponentInterpretation::component_is_scalar);
+
2339  std::vector<DataComponentInterpretation::DataComponentInterpretation>
+
2340  data_component_interpretation(
+
2341  1, DataComponentInterpretation::component_is_scalar);
+
2342 
+
2343  std::vector<std::string> qcriterion_name = {"qcriterion"};
+
2344  const DoFHandler<dim> &dof_handler_qcriterion =
+
2345  qcriterion_smoothing.get_dof_handler();
+
2346  data_out.add_data_vector(dof_handler_qcriterion,
+
2347  qcriterion_field,
+
2348  qcriterion_name,
+
2349  data_component_interpretation);
+
2350  }
+
2351  // Continuity smoothing
+
2352  {
+
2353  continuity_field =
+
2354  continuity_smoothing.calculate_smoothed_field(solution,
+
2355  this->dof_handler,
+
2356  this->mapping);
2357 
-
2358  std::vector<std::string> continuity_name = {"velocity_divergence"};
-
2359  const DoFHandler<dim> &dof_handler_qcriterion =
-
2360  continuity_smoothing.get_dof_handler();
-
2361  data_out.add_data_vector(dof_handler_qcriterion,
-
2362  continuity_field,
-
2363  continuity_name,
-
2364  data_component_interpretation);
-
2365  }
-
2366  }
-
2367  else
-
2368  {
-
2369  // Use the non-smoothed version of the post-processors
-
2370  data_out.add_data_vector(solution, divergence);
-
2371  data_out.add_data_vector(solution, qcriterion);
-
2372  }
-
2373 
-
2374 
-
2375  SRFPostprocessor<dim> srf(simulation_parameters.velocity_sources.omega_x,
-
2376  simulation_parameters.velocity_sources.omega_y,
-
2377  simulation_parameters.velocity_sources.omega_z);
+
2358  std::vector<DataComponentInterpretation::DataComponentInterpretation>
+
2359  data_component_interpretation(
+
2360  1, DataComponentInterpretation::component_is_scalar);
+
2361 
+
2362  std::vector<std::string> continuity_name = {"velocity_divergence"};
+
2363  const DoFHandler<dim> &dof_handler_qcriterion =
+
2364  continuity_smoothing.get_dof_handler();
+
2365  data_out.add_data_vector(dof_handler_qcriterion,
+
2366  continuity_field,
+
2367  continuity_name,
+
2368  data_component_interpretation);
+
2369  }
+
2370  }
+
2371  else
+
2372  {
+
2373  // Use the non-smoothed version of the post-processors
+
2374  data_out.add_data_vector(solution, divergence);
+
2375  data_out.add_data_vector(solution, qcriterion);
+
2376  }
+
2377 
2378 
-
2379  if (simulation_parameters.velocity_sources.rotating_frame_type ==
- -
2381  data_out.add_data_vector(solution, srf);
+
2379  SRFPostprocessor<dim> srf(simulation_parameters.velocity_sources.omega_x,
+
2380  simulation_parameters.velocity_sources.omega_y,
+
2381  simulation_parameters.velocity_sources.omega_z);
2382 
-
2383  output_field_hook(data_out);
-
2384 
-
2385  multiphysics->attach_solution_to_output(data_out);
+
2383  if (simulation_parameters.velocity_sources.rotating_frame_type ==
+ +
2385  data_out.add_data_vector(solution, srf);
2386 
-
2387  // Build the patches and write the output
+
2387  output_field_hook(data_out);
2388 
-
2389  data_out.build_patches(*this->mapping,
-
2390  subdivision,
-
2391  DataOut<dim>::curved_inner_cells);
+
2389  multiphysics->attach_solution_to_output(data_out);
+
2390 
+
2391  // Build the patches and write the output
2392 
-
2393  write_vtu_and_pvd<dim>(this->pvdhandler,
-
2394  data_out,
-
2395  folder,
-
2396  solution_name,
-
2397  time,
-
2398  iter,
-
2399  group_files,
-
2400  this->mpi_communicator);
-
2401 
-
2402  if (simulation_control->get_output_boundaries() &&
-
2403  simulation_control->get_step_number() == 0)
-
2404  {
-
2405  DataOutFaces<dim> data_out_faces;
-
2406 
-
2407  // Add the additional flag to enable high-order cells output when the
-
2408  // velocity interpolation order is larger than 1
-
2409  DataOutBase::VtkFlags flags;
-
2410  if (this->velocity_fem_degree > 1)
-
2411  flags.write_higher_order_cells = true;
-
2412  data_out_faces.set_flags(flags);
-
2413 
-
2414  BoundaryPostprocessor<dim> boundary_id;
-
2415  data_out_faces.attach_dof_handler(this->dof_handler);
-
2416  data_out_faces.add_data_vector(solution, boundary_id);
-
2417  data_out_faces.build_patches(*this->mapping, subdivision);
-
2418 
-
2419  write_boundaries_vtu<dim>(
-
2420  data_out_faces, folder, time, iter, this->mpi_communicator);
-
2421  }
-
2422 }
-
2423 
-
2424 template <int dim, typename VectorType, typename DofsType>
-
2425 void
- -
2427 {
-
2428  TimerOutput::Scope t(this->computing_timer, "Output forces");
-
2429  if (this->this_mpi_process == 0)
-
2430  {
-
2431  for (unsigned int boundary_id = 0;
-
2432  boundary_id < simulation_parameters.boundary_conditions.size;
-
2433  ++boundary_id)
-
2434  {
-
2435  std::string filename =
-
2436  simulation_parameters.simulation_control.output_folder +
-
2437  simulation_parameters.forces_parameters.force_output_name + "." +
-
2438  Utilities::int_to_string(boundary_id, 2) + ".dat";
-
2439  std::ofstream output(filename.c_str());
-
2440 
-
2441  forces_tables[boundary_id].write_text(output);
-
2442  }
-
2443  }
-
2444 }
-
2445 
-
2446 template <int dim, typename VectorType, typename DofsType>
-
2447 void
- -
2449 {
-
2450  TimerOutput::Scope t(this->computing_timer, "Output torques");
-
2451  if (this->this_mpi_process == 0)
-
2452  {
-
2453  for (unsigned int boundary_id = 0;
-
2454  boundary_id < simulation_parameters.boundary_conditions.size;
-
2455  ++boundary_id)
-
2456  {
-
2457  std::string filename =
-
2458  simulation_parameters.simulation_control.output_folder +
-
2459  simulation_parameters.forces_parameters.torque_output_name + "." +
-
2460  Utilities::int_to_string(boundary_id, 2) + ".dat";
-
2461  std::ofstream output(filename.c_str());
-
2462 
-
2463  this->torques_tables[boundary_id].write_text(output);
-
2464  }
-
2465  }
-
2466 }
-
2467 
-
2468 template <int dim, typename VectorType, typename DofsType>
-
2469 void
- -
2471 {
-
2472  TimerOutput::Scope timer(this->computing_timer, "Write checkpoint");
-
2473  std::string prefix =
-
2474  this->simulation_parameters.simulation_control.output_folder +
-
2475  this->simulation_parameters.restart_parameters.filename;
-
2476  if (Utilities::MPI::this_mpi_process(this->mpi_communicator) == 0)
-
2477  {
-
2478  simulation_control->save(prefix);
-
2479  this->pvdhandler.save(prefix);
-
2480 
-
2481  if (simulation_parameters.flow_control.enable_flow_control)
-
2482  this->flow_control.save(prefix);
-
2483  }
+
2393  data_out.build_patches(*this->mapping,
+
2394  subdivision,
+
2395  DataOut<dim>::curved_inner_cells);
+
2396 
+
2397  write_vtu_and_pvd<dim>(this->pvdhandler,
+
2398  data_out,
+
2399  folder,
+
2400  solution_name,
+
2401  time,
+
2402  iter,
+
2403  group_files,
+
2404  this->mpi_communicator);
+
2405 
+
2406  if (simulation_control->get_output_boundaries() &&
+
2407  simulation_control->get_step_number() == 0)
+
2408  {
+
2409  DataOutFaces<dim> data_out_faces;
+
2410 
+
2411  // Add the additional flag to enable high-order cells output when the
+
2412  // velocity interpolation order is larger than 1
+
2413  DataOutBase::VtkFlags flags;
+
2414  if (this->velocity_fem_degree > 1)
+
2415  flags.write_higher_order_cells = true;
+
2416  data_out_faces.set_flags(flags);
+
2417 
+
2418  BoundaryPostprocessor<dim> boundary_id;
+
2419  data_out_faces.attach_dof_handler(this->dof_handler);
+
2420  data_out_faces.add_data_vector(solution, boundary_id);
+
2421  data_out_faces.build_patches(*this->mapping, subdivision);
+
2422 
+
2423  write_boundaries_vtu<dim>(
+
2424  data_out_faces, folder, time, iter, this->mpi_communicator);
+
2425  }
+
2426 }
+
2427 
+
2428 template <int dim, typename VectorType, typename DofsType>
+
2429 void
+ +
2431 {
+
2432  TimerOutput::Scope t(this->computing_timer, "Output forces");
+
2433  if (this->this_mpi_process == 0)
+
2434  {
+
2435  for (unsigned int boundary_id = 0;
+
2436  boundary_id < simulation_parameters.boundary_conditions.size;
+
2437  ++boundary_id)
+
2438  {
+
2439  std::string filename =
+
2440  simulation_parameters.simulation_control.output_folder +
+
2441  simulation_parameters.forces_parameters.force_output_name + "." +
+
2442  Utilities::int_to_string(boundary_id, 2) + ".dat";
+
2443  std::ofstream output(filename.c_str());
+
2444 
+
2445  forces_tables[boundary_id].write_text(output);
+
2446  }
+
2447  }
+
2448 }
+
2449 
+
2450 template <int dim, typename VectorType, typename DofsType>
+
2451 void
+ +
2453 {
+
2454  TimerOutput::Scope t(this->computing_timer, "Output torques");
+
2455  if (this->this_mpi_process == 0)
+
2456  {
+
2457  for (unsigned int boundary_id = 0;
+
2458  boundary_id < simulation_parameters.boundary_conditions.size;
+
2459  ++boundary_id)
+
2460  {
+
2461  std::string filename =
+
2462  simulation_parameters.simulation_control.output_folder +
+
2463  simulation_parameters.forces_parameters.torque_output_name + "." +
+
2464  Utilities::int_to_string(boundary_id, 2) + ".dat";
+
2465  std::ofstream output(filename.c_str());
+
2466 
+
2467  this->torques_tables[boundary_id].write_text(output);
+
2468  }
+
2469  }
+
2470 }
+
2471 
+
2472 template <int dim, typename VectorType, typename DofsType>
+
2473 void
+ +
2475 {
+
2476  TimerOutput::Scope timer(this->computing_timer, "Write checkpoint");
+
2477  std::string prefix =
+
2478  this->simulation_parameters.simulation_control.output_folder +
+
2479  this->simulation_parameters.restart_parameters.filename;
+
2480  if (Utilities::MPI::this_mpi_process(this->mpi_communicator) == 0)
+
2481  {
+
2482  simulation_control->save(prefix);
+
2483  this->pvdhandler.save(prefix);
2484 
-
2485  std::vector<const VectorType *> sol_set_transfer;
-
2486  sol_set_transfer.push_back(&this->present_solution);
-
2487  for (unsigned int i = 0; i < previous_solutions.size(); ++i)
-
2488  {
-
2489  sol_set_transfer.push_back(&previous_solutions[i]);
-
2490  }
-
2491 
-
2492  if (simulation_parameters.post_processing.calculate_average_velocities)
-
2493  {
-
2494  std::vector<const VectorType *> av_set_transfer =
-
2495  this->average_velocities->save(prefix);
-
2496 
-
2497  // Insert average velocities vectors into the set transfer vector
-
2498  sol_set_transfer.insert(sol_set_transfer.end(),
-
2499  av_set_transfer.begin(),
-
2500  av_set_transfer.end());
-
2501  }
-
2502 
-
2503  parallel::distributed::SolutionTransfer<dim, VectorType> system_trans_vectors(
-
2504  this->dof_handler);
-
2505  system_trans_vectors.prepare_for_serialization(sol_set_transfer);
+
2485  if (simulation_parameters.flow_control.enable_flow_control)
+
2486  this->flow_control.save(prefix);
+
2487  }
+
2488 
+
2489  std::vector<const VectorType *> sol_set_transfer;
+
2490  sol_set_transfer.push_back(&this->present_solution);
+
2491  for (unsigned int i = 0; i < previous_solutions.size(); ++i)
+
2492  {
+
2493  sol_set_transfer.push_back(&previous_solutions[i]);
+
2494  }
+
2495 
+
2496  if (simulation_parameters.post_processing.calculate_average_velocities)
+
2497  {
+
2498  std::vector<const VectorType *> av_set_transfer =
+
2499  this->average_velocities->save(prefix);
+
2500 
+
2501  // Insert average velocities vectors into the set transfer vector
+
2502  sol_set_transfer.insert(sol_set_transfer.end(),
+
2503  av_set_transfer.begin(),
+
2504  av_set_transfer.end());
+
2505  }
2506 
-
2507  multiphysics->write_checkpoint();
-
2508 
-
2509  if (auto tria = dynamic_cast<parallel::distributed::Triangulation<dim> *>(
-
2510  this->triangulation.get()))
-
2511  {
-
2512  std::string triangulationName = prefix + ".triangulation";
-
2513  tria->save(prefix + ".triangulation");
-
2514  }
-
2515 
-
2516  // Serialize all post-processing tables that are currently used
-
2517  {
-
2518  const Parameters::PostProcessing post_processing =
-
2519  this->simulation_parameters.post_processing;
-
2520  std::string prefix =
-
2521  this->simulation_parameters.simulation_control.output_folder;
-
2522  std::string suffix = ".checkpoint";
-
2523  if (post_processing.calculate_enstrophy)
-
2524  serialize_table(this->enstrophy_table,
-
2525  prefix + post_processing.enstrophy_output_name + suffix);
-
2526  if (post_processing.calculate_kinetic_energy)
-
2527  serialize_table(this->kinetic_energy_table,
-
2528  prefix + post_processing.kinetic_energy_output_name +
-
2529  suffix);
-
2530  if (post_processing.calculate_pressure_power)
-
2531  serialize_table(this->pressure_power_table,
-
2532  prefix + post_processing.pressure_power_output_name +
+
2507  parallel::distributed::SolutionTransfer<dim, VectorType> system_trans_vectors(
+
2508  this->dof_handler);
+
2509  system_trans_vectors.prepare_for_serialization(sol_set_transfer);
+
2510 
+
2511  multiphysics->write_checkpoint();
+
2512 
+
2513  if (auto tria = dynamic_cast<parallel::distributed::Triangulation<dim> *>(
+
2514  this->triangulation.get()))
+
2515  {
+
2516  std::string triangulationName = prefix + ".triangulation";
+
2517  tria->save(prefix + ".triangulation");
+
2518  }
+
2519 
+
2520  // Serialize all post-processing tables that are currently used
+
2521  {
+
2522  const Parameters::PostProcessing post_processing =
+
2523  this->simulation_parameters.post_processing;
+
2524  std::string prefix =
+
2525  this->simulation_parameters.simulation_control.output_folder;
+
2526  std::string suffix = ".checkpoint";
+
2527  if (post_processing.calculate_enstrophy)
+
2528  serialize_table(this->enstrophy_table,
+
2529  prefix + post_processing.enstrophy_output_name + suffix);
+
2530  if (post_processing.calculate_kinetic_energy)
+
2531  serialize_table(this->kinetic_energy_table,
+
2532  prefix + post_processing.kinetic_energy_output_name +
2533  suffix);
-
2534  if (post_processing.calculate_viscous_dissipation)
-
2535  serialize_table(this->viscous_dissipation_table,
-
2536  prefix + post_processing.viscous_dissipation_output_name +
+
2534  if (post_processing.calculate_pressure_power)
+
2535  serialize_table(this->pressure_power_table,
+
2536  prefix + post_processing.pressure_power_output_name +
2537  suffix);
-
2538  if (post_processing.calculate_apparent_viscosity)
-
2539  serialize_table(this->apparent_viscosity_table,
-
2540  prefix + post_processing.apparent_viscosity_output_name +
+
2538  if (post_processing.calculate_viscous_dissipation)
+
2539  serialize_table(this->viscous_dissipation_table,
+
2540  prefix + post_processing.viscous_dissipation_output_name +
2541  suffix);
-
2542  if (post_processing.calculate_flow_rate)
-
2543  serialize_table(this->flow_rate_table,
-
2544  prefix + post_processing.flow_rate_output_name + suffix);
-
2545  if (post_processing.calculate_pressure_drop)
-
2546  serialize_table(this->pressure_drop_table,
-
2547  prefix + post_processing.pressure_drop_output_name +
-
2548  suffix);
-
2549  if (this->simulation_parameters.forces_parameters.calculate_force)
-
2550  for (unsigned int boundary_id = 0;
-
2551  boundary_id < this->simulation_parameters.boundary_conditions.size;
-
2552  ++boundary_id)
-
2553  {
- -
2555  this->forces_tables[boundary_id],
-
2556  prefix +
-
2557  this->simulation_parameters.forces_parameters.force_output_name +
-
2558  "_" + Utilities::int_to_string(boundary_id, 2) + suffix);
-
2559  }
-
2560  if (this->simulation_parameters.forces_parameters.calculate_torque)
-
2561  for (unsigned int boundary_id = 0;
-
2562  boundary_id < this->simulation_parameters.boundary_conditions.size;
-
2563  ++boundary_id)
-
2564  {
- -
2566  this->torques_tables[boundary_id],
-
2567  prefix +
-
2568  this->simulation_parameters.forces_parameters.torque_output_name +
-
2569  "_" + Utilities::int_to_string(boundary_id, 2) + suffix);
-
2570  }
-
2571  if (this->simulation_parameters.analytical_solution->calculate_error())
- -
2573  this->error_table,
-
2574  prefix +
-
2575  this->simulation_parameters.analytical_solution->get_filename() +
-
2576  "_FD" + suffix);
-
2577  }
-
2578 }
-
2579 
-
2580 template <int dim, typename VectorType, typename DofsType>
-
2581 void
- - -
2584 {
-
2585  const double pressure_scaling_factor =
-
2586  simulation_parameters.stabilization.pressure_scaling_factor;
-
2587 
-
2588  // We skip the function if the factor has a value of 1
-
2589  if (abs(pressure_scaling_factor - 1) < 1e-8)
-
2590  return;
+
2542  if (post_processing.calculate_apparent_viscosity)
+
2543  serialize_table(this->apparent_viscosity_table,
+
2544  prefix + post_processing.apparent_viscosity_output_name +
+
2545  suffix);
+
2546  if (post_processing.calculate_flow_rate)
+
2547  serialize_table(this->flow_rate_table,
+
2548  prefix + post_processing.flow_rate_output_name + suffix);
+
2549  if (post_processing.calculate_pressure_drop)
+
2550  serialize_table(this->pressure_drop_table,
+
2551  prefix + post_processing.pressure_drop_output_name +
+
2552  suffix);
+
2553  if (this->simulation_parameters.forces_parameters.calculate_force)
+
2554  for (unsigned int boundary_id = 0;
+
2555  boundary_id < this->simulation_parameters.boundary_conditions.size;
+
2556  ++boundary_id)
+
2557  {
+ +
2559  this->forces_tables[boundary_id],
+
2560  prefix +
+
2561  this->simulation_parameters.forces_parameters.force_output_name +
+
2562  "_" + Utilities::int_to_string(boundary_id, 2) + suffix);
+
2563  }
+
2564  if (this->simulation_parameters.forces_parameters.calculate_torque)
+
2565  for (unsigned int boundary_id = 0;
+
2566  boundary_id < this->simulation_parameters.boundary_conditions.size;
+
2567  ++boundary_id)
+
2568  {
+ +
2570  this->torques_tables[boundary_id],
+
2571  prefix +
+
2572  this->simulation_parameters.forces_parameters.torque_output_name +
+
2573  "_" + Utilities::int_to_string(boundary_id, 2) + suffix);
+
2574  }
+
2575  if (this->simulation_parameters.analytical_solution->calculate_error())
+ +
2577  this->error_table,
+
2578  prefix +
+
2579  this->simulation_parameters.analytical_solution->get_filename() +
+
2580  "_FD" + suffix);
+
2581  }
+
2582 }
+
2583 
+
2584 template <int dim, typename VectorType, typename DofsType>
+
2585 void
+ + +
2588 {
+
2589  const double pressure_scaling_factor =
+
2590  simulation_parameters.stabilization.pressure_scaling_factor;
2591 
-
2592  TimerOutput::Scope t(this->computing_timer, "rescale_pressure");
-
2593 
-
2594  const unsigned int dofs_per_cell = this->fe->dofs_per_cell;
-
2595  std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
-
2596  // Map used to keep track of which DOFs have been looped over
-
2597  std::unordered_set<unsigned int> rescaled_dofs_set;
-
2598  rescaled_dofs_set.clear();
-
2599  for (const auto &cell : dof_handler.active_cell_iterators())
-
2600  {
-
2601  if (cell->is_locally_owned() || cell->is_ghost())
-
2602  {
-
2603  cell->get_dof_indices(local_dof_indices);
-
2604  for (unsigned int j = 0; j < local_dof_indices.size(); ++j)
-
2605  {
-
2606  const unsigned int global_id = local_dof_indices[j];
-
2607  // We check if we have already checked this DOF
-
2608  auto iterator = rescaled_dofs_set.find(global_id);
-
2609  if (iterator == rescaled_dofs_set.end())
-
2610  {
-
2611  const unsigned int component_index =
-
2612  this->fe->system_to_component_index(j).first;
-
2613  if (this->dof_handler.locally_owned_dofs().is_element(
-
2614  global_id) &&
-
2615  component_index == dim)
-
2616  {
-
2617  this->newton_update(global_id) =
-
2618  this->newton_update(global_id) *
-
2619  pressure_scaling_factor;
-
2620  }
-
2621  rescaled_dofs_set.insert(global_id);
-
2622  }
-
2623  }
-
2624  }
-
2625  }
-
2626 }
-
2627 
-
2628 template <int dim, typename VectorType, typename DofsType>
-
2629 void
- -
2631  const unsigned int display_precision)
-
2632 {
-
2633  TimerOutput::Scope t(this->computing_timer,
-
2634  "Calculate and output norms after Newton its");
-
2635 
-
2636  if constexpr (std::is_same_v<VectorType, GlobalVectorType> ||
-
2637  std::is_same_v<VectorType,
-
2638  LinearAlgebra::distributed::Vector<double>>)
-
2639  {
-
2640  FEValuesExtractors::Vector velocities(0);
-
2641  FEValuesExtractors::Scalar pressure(dim);
-
2642 
-
2643  ComponentMask velocity_mask = fe->component_mask(velocities);
-
2644  ComponentMask pressure_mask = fe->component_mask(pressure);
-
2645 
-
2646  const std::vector<IndexSet> index_set_velocity =
-
2647  DoFTools::locally_owned_dofs_per_component(dof_handler, velocity_mask);
-
2648  const std::vector<IndexSet> index_set_pressure =
-
2649  DoFTools::locally_owned_dofs_per_component(dof_handler, pressure_mask);
-
2650 
-
2651  double local_sum = 0.0;
-
2652  double local_max = std::numeric_limits<double>::lowest();
-
2653 
-
2654  for (unsigned int d = 0; d < dim; ++d)
-
2655  {
-
2656  for (auto j = index_set_velocity[d].begin();
-
2657  j != index_set_velocity[d].end();
-
2658  j++)
-
2659  {
-
2660  double dof_newton_update = newton_update[*j];
-
2661 
-
2662  local_sum += dof_newton_update * dof_newton_update;
-
2663 
-
2664  local_max = std::max(local_max, std::abs(dof_newton_update));
-
2665  }
-
2666  }
+
2592  // We skip the function if the factor has a value of 1
+
2593  if (abs(pressure_scaling_factor - 1) < 1e-8)
+
2594  return;
+
2595 
+
2596  TimerOutput::Scope t(this->computing_timer, "rescale_pressure");
+
2597 
+
2598  const unsigned int dofs_per_cell = this->fe->dofs_per_cell;
+
2599  std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
+
2600  // Map used to keep track of which DOFs have been looped over
+
2601  std::unordered_set<unsigned int> rescaled_dofs_set;
+
2602  rescaled_dofs_set.clear();
+
2603  for (const auto &cell : dof_handler.active_cell_iterators())
+
2604  {
+
2605  if (cell->is_locally_owned() || cell->is_ghost())
+
2606  {
+
2607  cell->get_dof_indices(local_dof_indices);
+
2608  for (unsigned int j = 0; j < local_dof_indices.size(); ++j)
+
2609  {
+
2610  const unsigned int global_id = local_dof_indices[j];
+
2611  // We check if we have already checked this DOF
+
2612  auto iterator = rescaled_dofs_set.find(global_id);
+
2613  if (iterator == rescaled_dofs_set.end())
+
2614  {
+
2615  const unsigned int component_index =
+
2616  this->fe->system_to_component_index(j).first;
+
2617  if (this->dof_handler.locally_owned_dofs().is_element(
+
2618  global_id) &&
+
2619  component_index == dim)
+
2620  {
+
2621  this->newton_update(global_id) =
+
2622  this->newton_update(global_id) *
+
2623  pressure_scaling_factor;
+
2624  }
+
2625  rescaled_dofs_set.insert(global_id);
+
2626  }
+
2627  }
+
2628  }
+
2629  }
+
2630 }
+
2631 
+
2632 template <int dim, typename VectorType, typename DofsType>
+
2633 void
+ +
2635  const unsigned int display_precision)
+
2636 {
+
2637  TimerOutput::Scope t(this->computing_timer,
+
2638  "Calculate and output norms after Newton its");
+
2639 
+
2640  if constexpr (std::is_same_v<VectorType, GlobalVectorType> ||
+
2641  std::is_same_v<VectorType,
+
2642  LinearAlgebra::distributed::Vector<double>>)
+
2643  {
+
2644  FEValuesExtractors::Vector velocities(0);
+
2645  FEValuesExtractors::Scalar pressure(dim);
+
2646 
+
2647  ComponentMask velocity_mask = fe->component_mask(velocities);
+
2648  ComponentMask pressure_mask = fe->component_mask(pressure);
+
2649 
+
2650  const std::vector<IndexSet> index_set_velocity =
+
2651  DoFTools::locally_owned_dofs_per_component(dof_handler, velocity_mask);
+
2652  const std::vector<IndexSet> index_set_pressure =
+
2653  DoFTools::locally_owned_dofs_per_component(dof_handler, pressure_mask);
+
2654 
+
2655  double local_sum = 0.0;
+
2656  double local_max = std::numeric_limits<double>::lowest();
+
2657 
+
2658  for (unsigned int d = 0; d < dim; ++d)
+
2659  {
+
2660  for (auto j = index_set_velocity[d].begin();
+
2661  j != index_set_velocity[d].end();
+
2662  j++)
+
2663  {
+
2664  double dof_newton_update = newton_update[*j];
+
2665 
+
2666  local_sum += dof_newton_update * dof_newton_update;
2667 
-
2668  double global_velocity_l2_norm =
-
2669  std::sqrt(Utilities::MPI::sum(local_sum, this->mpi_communicator));
-
2670  double global_velocity_linfty_norm =
-
2671  Utilities::MPI::max(local_max, this->mpi_communicator);
-
2672 
-
2673  local_sum = 0.0;
-
2674  local_max = std::numeric_limits<double>::lowest();
-
2675 
-
2676  for (auto j = index_set_pressure[dim].begin();
-
2677  j != index_set_pressure[dim].end();
-
2678  j++)
-
2679  {
-
2680  double dof_newton_update = newton_update[*j];
-
2681 
-
2682  local_sum += dof_newton_update * dof_newton_update;
-
2683 
-
2684  local_max = std::max(local_max, std::abs(dof_newton_update));
-
2685  }
-
2686 
-
2687  double global_pressure_l2_norm =
-
2688  std::sqrt(Utilities::MPI::sum(local_sum, this->mpi_communicator));
-
2689  double global_pressure_linfty_norm =
-
2690  Utilities::MPI::max(local_max, this->mpi_communicator);
-
2691 
-
2692  this->pcout << std::setprecision(display_precision)
-
2693  << "\n\t||du||_L2 = " << std::setw(6)
-
2694  << global_velocity_l2_norm << std::setw(6)
-
2695  << "\t||du||_Linfty = "
-
2696  << std::setprecision(display_precision)
-
2697  << global_velocity_linfty_norm << std::endl;
-
2698  this->pcout << std::setprecision(display_precision)
-
2699  << "\t||dp||_L2 = " << std::setw(6) << global_pressure_l2_norm
-
2700  << std::setw(6) << "\t||dp||_Linfty = "
-
2701  << std::setprecision(display_precision)
-
2702  << global_pressure_linfty_norm << std::endl;
-
2703  }
-
2704  if constexpr (std::is_same_v<VectorType, GlobalBlockVectorType>)
-
2705  {
-
2706  this->pcout << std::setprecision(display_precision)
-
2707  << "\t||du||_L2 = " << std::setw(6)
-
2708  << newton_update.block(0).l2_norm() << std::setw(6)
-
2709  << "\t||du||_Linfty = "
-
2710  << std::setprecision(display_precision)
-
2711  << newton_update.block(0).linfty_norm() << std::endl;
-
2712  this->pcout << std::setprecision(display_precision)
-
2713  << "\t||dp||_L2 = " << std::setw(6)
-
2714  << newton_update.block(1).l2_norm() << std::setw(6)
-
2715  << "\t||dp||_Linfty = "
-
2716  << std::setprecision(display_precision)
-
2717  << newton_update.block(1).linfty_norm() << std::endl;
-
2718  }
-
2719 }
-
2720 
-
2721 template <int dim, typename VectorType, typename DofsType>
-
2722 inline VectorType
- -
2724 {
-
2725  VectorType tmp;
-
2726 
-
2727  if constexpr (std::is_same_v<VectorType, GlobalVectorType> ||
-
2728  std::is_same_v<VectorType, GlobalBlockVectorType>)
-
2729  tmp.reinit(locally_owned_dofs, this->mpi_communicator);
+
2668  local_max = std::max(local_max, std::abs(dof_newton_update));
+
2669  }
+
2670  }
+
2671 
+
2672  double global_velocity_l2_norm =
+
2673  std::sqrt(Utilities::MPI::sum(local_sum, this->mpi_communicator));
+
2674  double global_velocity_linfty_norm =
+
2675  Utilities::MPI::max(local_max, this->mpi_communicator);
+
2676 
+
2677  local_sum = 0.0;
+
2678  local_max = std::numeric_limits<double>::lowest();
+
2679 
+
2680  for (auto j = index_set_pressure[dim].begin();
+
2681  j != index_set_pressure[dim].end();
+
2682  j++)
+
2683  {
+
2684  double dof_newton_update = newton_update[*j];
+
2685 
+
2686  local_sum += dof_newton_update * dof_newton_update;
+
2687 
+
2688  local_max = std::max(local_max, std::abs(dof_newton_update));
+
2689  }
+
2690 
+
2691  double global_pressure_l2_norm =
+
2692  std::sqrt(Utilities::MPI::sum(local_sum, this->mpi_communicator));
+
2693  double global_pressure_linfty_norm =
+
2694  Utilities::MPI::max(local_max, this->mpi_communicator);
+
2695 
+
2696  this->pcout << std::setprecision(display_precision)
+
2697  << "\n\t||du||_L2 = " << std::setw(6)
+
2698  << global_velocity_l2_norm << std::setw(6)
+
2699  << "\t||du||_Linfty = "
+
2700  << std::setprecision(display_precision)
+
2701  << global_velocity_linfty_norm << std::endl;
+
2702  this->pcout << std::setprecision(display_precision)
+
2703  << "\t||dp||_L2 = " << std::setw(6) << global_pressure_l2_norm
+
2704  << std::setw(6) << "\t||dp||_Linfty = "
+
2705  << std::setprecision(display_precision)
+
2706  << global_pressure_linfty_norm << std::endl;
+
2707  }
+
2708  if constexpr (std::is_same_v<VectorType, GlobalBlockVectorType>)
+
2709  {
+
2710  this->pcout << std::setprecision(display_precision)
+
2711  << "\t||du||_L2 = " << std::setw(6)
+
2712  << newton_update.block(0).l2_norm() << std::setw(6)
+
2713  << "\t||du||_Linfty = "
+
2714  << std::setprecision(display_precision)
+
2715  << newton_update.block(0).linfty_norm() << std::endl;
+
2716  this->pcout << std::setprecision(display_precision)
+
2717  << "\t||dp||_L2 = " << std::setw(6)
+
2718  << newton_update.block(1).l2_norm() << std::setw(6)
+
2719  << "\t||dp||_Linfty = "
+
2720  << std::setprecision(display_precision)
+
2721  << newton_update.block(1).linfty_norm() << std::endl;
+
2722  }
+
2723 }
+
2724 
+
2725 template <int dim, typename VectorType, typename DofsType>
+
2726 inline VectorType
+ +
2728 {
+
2729  VectorType tmp;
2730 
-
2731  else if constexpr (std::is_same_v<VectorType,
-
2732  LinearAlgebra::distributed::Vector<double>>)
-
2733  tmp.reinit(locally_owned_dofs,
-
2734  locally_relevant_dofs,
-
2735  this->mpi_communicator);
-
2736 
-
2737  return tmp;
-
2738 }
-
2739 
-
2740 // Pre-compile the 2D and 3D version with the types that can occur
- - -
2743 template class NavierStokesBase<2,
- -
2745  std::vector<IndexSet>>;
-
2746 template class NavierStokesBase<3,
- -
2748  std::vector<IndexSet>>;
-
2749 
-
2750 #ifndef LETHE_USE_LDV
-
2751 template class NavierStokesBase<2,
-
2752  LinearAlgebra::distributed::Vector<double>,
-
2753  IndexSet>;
-
2754 template class NavierStokesBase<3,
-
2755  LinearAlgebra::distributed::Vector<double>,
-
2756  IndexSet>;
-
2757 #endif
+
2731  if constexpr (std::is_same_v<VectorType, GlobalVectorType> ||
+
2732  std::is_same_v<VectorType, GlobalBlockVectorType>)
+
2733  tmp.reinit(locally_owned_dofs, this->mpi_communicator);
+
2734 
+
2735  else if constexpr (std::is_same_v<VectorType,
+
2736  LinearAlgebra::distributed::Vector<double>>)
+
2737  tmp.reinit(locally_owned_dofs,
+
2738  locally_relevant_dofs,
+
2739  this->mpi_communicator);
+
2740 
+
2741  return tmp;
+
2742 }
+
2743 
+
2744 // Pre-compile the 2D and 3D version with the types that can occur
+ + +
2747 template class NavierStokesBase<2,
+ +
2749  std::vector<IndexSet>>;
+
2750 template class NavierStokesBase<3,
+ +
2752  std::vector<IndexSet>>;
+
2753 
+
2754 #ifndef LETHE_USE_LDV
+
2755 template class NavierStokesBase<2,
+
2756  LinearAlgebra::distributed::Vector<double>,
+
2757  IndexSet>;
+
2758 template class NavierStokesBase<3,
+
2759  LinearAlgebra::distributed::Vector<double>,
+
2760  IndexSet>;
+
2761 #endif
unsigned int maximum_number_of_previous_solutions()
Get the maximum number of previous time steps supposed by the BDF schemes implemented in Lethe.
Definition: bdf.h:102
BoundaryPostprocessor Post-processor class used to attach the boundary id to the faces when outputtin...
Definition: manifolds.h:88
@@ -2845,26 +2849,26 @@
Compute the dynamic viscosity scalar field of a fluid within a domain.
Compute the kinematic viscosity scalar field of a fluid within a domain.
-
void constrain_stasis_with_temperature(const DoFHandler< dim > *dof_handler_ht)
Constrain a fluid's subdomains according to the temperature field to null velocity and pressure field...
+
void constrain_stasis_with_temperature(const DoFHandler< dim > *dof_handler_ht)
Constrain a fluid's subdomains according to the temperature field to null velocity and pressure field...
void box_refine_mesh(const bool restart)
Allow the initial refinement of all cells of the principal mesh that are partially contained in one o...
void refine_mesh_kelly()
Allow the refinement of the mesh based on the Kelly error estimator. See : https://www....
std::shared_ptr< FESystem< dim > > fe
Function< dim > * exact_solution
bool check_existance_of_bc(BoundaryConditions::BoundaryType bc)
Check if a specifique boundary condition exist.
std::shared_ptr< Quadrature< dim > > cell_quadrature
-
void write_output_results(const VectorType &solution)
write_output_results Post-processing as parallel VTU files
+
void write_output_results(const VectorType &solution)
write_output_results Post-processing as parallel VTU files
-
void add_flags_and_constrain_velocity(const std::vector< types::global_dof_index > &local_dof_indices, const std::vector< double > &local_temperature_values, StasisConstraintWithTemperature &stasis_constraint_struct)
Flag cell DOFs (either "solid" or "connected to fluid") and constrain velocity DOFs with homogeneous ...
+
void add_flags_and_constrain_velocity(const std::vector< types::global_dof_index > &local_dof_indices, const std::vector< double > &local_temperature_values, StasisConstraintWithTemperature &stasis_constraint_struct)
Flag cell DOFs (either "solid" or "connected to fluid") and constrain velocity DOFs with homogeneous ...
NavierStokesBase(SimulationParameters< dim > &nsparam)
unsigned int number_quadrature_points
-
void rescale_pressure_dofs_in_newton_update()
rescale_pressure_dofs_in_newton_update This function is used to rescale pressure DOFs in the newton c...
-
void constrain_stasis_with_temperature_vof(const DoFHandler< dim > *dof_handler_vof, const DoFHandler< dim > *dof_handler_ht)
Constrain fluids' subdomains according to the temperature field to null velocity and pressure fields ...
-
void write_output_torques()
write_output_torques Writes the torques per boundary condition to a text file output
+
void rescale_pressure_dofs_in_newton_update()
rescale_pressure_dofs_in_newton_update This function is used to rescale pressure DOFs in the newton c...
+
void constrain_stasis_with_temperature_vof(const DoFHandler< dim > *dof_handler_vof, const DoFHandler< dim > *dof_handler_ht)
Constrain fluids' subdomains according to the temperature field to null velocity and pressure fields ...
+
void write_output_torques()
write_output_torques Writes the torques per boundary condition to a text file output
std::shared_ptr< Quadrature< dim - 1 > > face_quadrature
-
void write_output_forces()
write_output_forces Writes the forces per boundary condition to a text file output
+
void write_output_forces()
write_output_forces Writes the forces per boundary condition to a text file output
DoFHandler< dim > dof_handler
virtual void refine_mesh()
Allow the refinement of the mesh according to one of the 2 methods proposed.
-
virtual void read_checkpoint()
read_checkpoint
+
virtual void read_checkpoint()
read_checkpoint
std::vector< std::vector< Tensor< 1, dim > > > forces_on_boundaries
virtual void enable_dynamic_zero_constraints_fd()
Enable the use of dynamic zero constraints by initializing required FEValues objects.
void postprocessing_torques(const VectorType &evaluation_point)
postprocessing_torques Post-processing function Outputs the torque acting on each boundary condition
@@ -2872,28 +2876,28 @@
std::vector< TableHandler > forces_tables
virtual void dynamic_flow_control()
dynamic_flow_control If set to enable, dynamic_flow_control allows to control the flow by executing s...
SimulationParameters< dim > simulation_parameters
-
void check_and_constrain_pressure(const StasisConstraintWithTemperature &stasis_constraint_struct, std::vector< types::global_dof_index > &local_dof_indices)
Check if solid cells are connected to fluid ones and constrain null pressure DOFs if they are not.
-
virtual void output_field_hook(DataOut< dim > &)
output_field_hook This function is to be redefined in specialized classes to adapt the output to each...
+
void check_and_constrain_pressure(const StasisConstraintWithTemperature &stasis_constraint_struct, std::vector< types::global_dof_index > &local_dof_indices)
Check if solid cells are connected to fluid ones and constrain null pressure DOFs if they are not.
+
virtual void output_field_hook(DataOut< dim > &)
output_field_hook This function is to be redefined in specialized classes to adapt the output to each...
virtual void iterate()
iterate Do a regular CFD iteration
void finish_simulation_fd()
finish_simulation Finishes the simulation for fluid dynamics by calling the post-processing elements ...
-
virtual void postprocess_fd(bool first_iteration)
postprocess Post-process fluid dynamics after an iteration
+
virtual void postprocess_fd(bool first_iteration)
postprocess Post-process fluid dynamics after an iteration
TimerOutput computing_timer
-
void establish_solid_domain(const bool non_zero_constraints)
Turn regions of the mesh where the material_id>0 into a solid block by injecting velocity and pressur...
+
void establish_solid_domain(const bool non_zero_constraints)
Turn regions of the mesh where the material_id>0 into a solid block by injecting velocity and pressur...
std::shared_ptr< Function< dim > > forcing_function
std::vector< VectorType > previous_solutions
-
VectorType init_temporary_vector()
init_temporary_vector This function initializes correctly a temporary vector depending on the vector ...
+
VectorType init_temporary_vector()
init_temporary_vector This function initializes correctly a temporary vector depending on the vector ...
std::shared_ptr< SimulationControl > simulation_control
std::vector< TableHandler > torques_tables
-
void refine_mesh_uniform()
Allow the uniform refinement of all the mesh.
+
void refine_mesh_uniform()
Allow the uniform refinement of all the mesh.
std::shared_ptr< MultiphysicsInterface< dim > > multiphysics
std::vector< Tensor< 1, 3 > > torques_on_boundaries
virtual void percolate_time_vectors_fd()
finish_time_step Finishes the time step of the fluid dynamics Post-processing and time stepping
std::shared_ptr< AverageVelocities< dim, VectorType, DofsType > > average_velocities
std::shared_ptr< Mapping< dim > > mapping
-
virtual void output_newton_update_norms(const unsigned int display_precision) override
Output the L2 and Linfty norms of the correction vector.
+
virtual void output_newton_update_norms(const unsigned int display_precision) override
Output the L2 and Linfty norms of the correction vector.
void postprocessing_forces(const VectorType &evaluation_point)
postprocessing_forces Post-processing function Outputs the forces acting on each boundary condition
-
void set_nodal_values()
set_nodal_values Set the nodal values of velocity and pressure
-
virtual void write_checkpoint()
write_checkpoint
+
void set_nodal_values()
set_nodal_values Set the nodal values of velocity and pressure
+
virtual void write_checkpoint()
write_checkpoint
std::shared_ptr< parallel::DistributedTriangulationBase< dim > > triangulation
const unsigned int velocity_fem_degree
Class that has all the common elements of a physics solver. It creates the nonlinear solver as specif...