ExaDG
Loading...
Searching...
No Matches
operator_coupled.h
1/* ______________________________________________________________________
2 *
3 * ExaDG - High-Order Discontinuous Galerkin for the Exa-Scale
4 *
5 * Copyright (C) 2021 by the ExaDG authors
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * ______________________________________________________________________
20 */
21
22#ifndef EXADG_INCOMPRESSIBLE_NAVIER_STOKES_SPATIAL_DISCRETIZATION_OPERATOR_COUPLED_H_
23#define EXADG_INCOMPRESSIBLE_NAVIER_STOKES_SPATIAL_DISCRETIZATION_OPERATOR_COUPLED_H_
24
25// ExaDG
26#include <exadg/convection_diffusion/spatial_discretization/operators/combined_operator.h>
27#include <exadg/incompressible_navier_stokes/spatial_discretization/spatial_operator_base.h>
28#include <exadg/solvers_and_preconditioners/newton/newton_solver.h>
29
30namespace ExaDG
31{
32namespace IncNS
33{
34// forward declaration
35template<int dim, typename Number>
36class OperatorCoupled;
37
38template<int dim, typename Number>
39class NonlinearOperatorCoupled
40{
41private:
42 typedef dealii::LinearAlgebra::distributed::Vector<Number> VectorType;
43 typedef dealii::LinearAlgebra::distributed::BlockVector<Number> BlockVectorType;
44
45 typedef OperatorCoupled<dim, Number> PDEOperator;
46
47public:
48 NonlinearOperatorCoupled()
49 : pde_operator(nullptr), rhs_vector(nullptr), time(0.0), scaling_factor_mass(1.0)
50 {
51 }
52
53 void
54 initialize(PDEOperator const & pde_operator)
55 {
56 this->pde_operator = &pde_operator;
57 }
58
59 void
60 update(VectorType const & rhs_vector, double const & time, double const & scaling_factor)
61 {
62 this->rhs_vector = &rhs_vector;
63 this->time = time;
64 this->scaling_factor_mass = scaling_factor;
65 }
66
67 /*
68 * The implementation of the Newton solver requires a function called
69 * 'evaluate_residual'.
70 */
71 void
72 evaluate_residual(BlockVectorType & dst, BlockVectorType const & src) const
73 {
74 pde_operator->evaluate_nonlinear_residual(dst, src, rhs_vector, time, scaling_factor_mass);
75 }
76
77private:
78 PDEOperator const * pde_operator;
79
80 VectorType const * rhs_vector;
81 double time;
82 double scaling_factor_mass;
83};
84
85template<int dim, typename Number>
86class LinearOperatorCoupled : public dealii::EnableObserverPointer
87{
88private:
89 typedef dealii::LinearAlgebra::distributed::BlockVector<Number> BlockVectorType;
90
91 typedef OperatorCoupled<dim, Number> PDEOperator;
92
93public:
94 LinearOperatorCoupled() : dealii::EnableObserverPointer(), pde_operator(nullptr)
95 {
96 }
97
98 void
99 initialize(PDEOperator const & pde_operator)
100 {
101 this->pde_operator = &pde_operator;
102 }
103
104 /*
105 * The implementation of the Newton solver requires a function called
106 * 'set_solution_linearization'.
107 */
108 void
109 set_solution_linearization(BlockVectorType const & solution_linearization) const
110 {
111 pde_operator->set_velocity_ptr(solution_linearization.block(0));
112 }
113
114
115 /*
116 * The implementation of linear solvers in deal.ii requires that a function called 'vmult' is
117 * provided.
118 */
119 void
120 vmult(BlockVectorType & dst, BlockVectorType const & src) const
121 {
122 pde_operator->apply_linearized_problem(dst, src);
123 }
124
125private:
126 PDEOperator const * pde_operator;
127};
128
129template<int dim, typename Number>
130class BlockPreconditioner
131{
132private:
133 typedef dealii::LinearAlgebra::distributed::BlockVector<Number> BlockVectorType;
134
135 typedef OperatorCoupled<dim, Number> PDEOperator;
136
137public:
138 BlockPreconditioner() : update_needed(true), pde_operator(nullptr)
139 {
140 }
141
142 void
143 initialize(PDEOperator * pde_operator_in)
144 {
145 pde_operator = pde_operator_in;
146 }
147
148 void
149 update()
150 {
151 pde_operator->update_block_preconditioner();
152
153 this->update_needed = false;
154 }
155
156 bool
157 needs_update() const
158 {
159 return update_needed;
160 }
161
162 void
163 vmult(BlockVectorType & dst, BlockVectorType const & src) const
164 {
165 AssertThrow(this->update_needed == false,
166 dealii::ExcMessage(
167 "BlockPreconditioner can not be applied because it is not up-to-date."));
168
169 pde_operator->apply_block_preconditioner(dst, src);
170 }
171
172 std::shared_ptr<TimerTree>
173 get_timings() const
174 {
175 AssertThrow(false,
176 dealii::ExcMessage(
177 "Function get_timings() is not implemented for BlockPreconditioner."));
178
179 return std::make_shared<TimerTree>();
180 }
181
182private:
183 bool update_needed;
184
185 PDEOperator * pde_operator;
186};
187
188template<int dim, typename Number = double>
189class OperatorCoupled : public SpatialOperatorBase<dim, Number>
190{
191private:
192 typedef SpatialOperatorBase<dim, Number> Base;
193 typedef OperatorCoupled<dim, Number> This;
194
195 typedef typename Base::MultigridPoisson MultigridPoisson;
196
197 typedef typename Base::VectorType VectorType;
198
199 typedef typename Base::BlockVectorType BlockVectorType;
200
201public:
202 /*
203 * Constructor.
204 */
205 OperatorCoupled(std::shared_ptr<Grid<dim> const> grid,
206 std::shared_ptr<dealii::Mapping<dim> const> mapping,
207 std::shared_ptr<MultigridMappings<dim, Number>> const multigrid_mappings,
208 std::shared_ptr<BoundaryDescriptor<dim> const> boundary_descriptor,
209 std::shared_ptr<FieldFunctions<dim> const> field_functions,
210 Parameters const & parameters,
211 std::string const & field,
212 MPI_Comm const & mpi_comm);
213
214 /*
215 * Destructor.
216 */
217 virtual ~OperatorCoupled();
218
219private:
220 void
221 setup_derived() final;
222
223 void
224 setup_preconditioners_and_solvers() final;
225
226public:
227 /*
228 * Update divergence penalty operator by recalculating the penalty parameter
229 * which depends on the current velocity field
230 */
231 void
232 update_divergence_penalty_operator(VectorType const & velocity);
233
234 /*
235 * Update continuity penalty operator by recalculating the penalty parameter
236 * which depends on the current velocity field
237 */
238 void
239 update_continuity_penalty_operator(VectorType const & velocity);
240
241 /*
242 * Setters and getters.
243 */
244
245 /*
246 * This function sets the variable scaling_factor_continuity, and also the related scaling factor
247 * for the pressure gradient operator.
248 */
249 void
250 set_scaling_factor_continuity(double const scaling_factor);
251
252 /*
253 * Stokes equations or convective term treated explicitly: solve linear system of equations
254 */
255
256 /*
257 * This function solves the linear Stokes problem (Stokes equations or Navier-Stokes
258 * equations with an explicit treatment of the convective term). The parameter
259 * scaling_factor_mass has to be specified for unsteady problem and
260 * can be omitted for steady problems.
261 */
262 unsigned int
263 solve_linear_problem(BlockVectorType & dst,
264 BlockVectorType const & src,
265 VectorType const & transport_velocity,
266 bool const & update_preconditioner,
267 double const & scaling_factor_mass = 1.0);
268
269 /*
270 * Convective term treated implicitly: solve non-linear system of equations
271 */
272
273 /*
274 * This function solves the nonlinear problem.
275 */
276 std::tuple<unsigned int, unsigned int>
277 solve_nonlinear_problem(BlockVectorType & dst,
278 VectorType const & rhs_vector,
279 bool const & update_preconditioner,
280 double const & time = 0.0,
281 double const & scaling_factor_mass = 1.0);
282
283
284 /*
285 * This function evaluates the nonlinear residual.
286 */
287 void
288 evaluate_nonlinear_residual(BlockVectorType & dst,
289 BlockVectorType const & src,
290 VectorType const * rhs_vector,
291 double const & time,
292 double const & scaling_factor_mass) const;
293
294 /*
295 * This function evaluates the nonlinear residual of the steady Navier-Stokes equations.
296 * This function has to be implemented separately (for example, the convective term will be
297 * evaluated in case of the Navier-Stokes equations and the time-derivative term is never
298 * evaluated).
299 */
300 void
301 evaluate_nonlinear_residual_steady(BlockVectorType & dst,
302 BlockVectorType const & src,
303 double const & time) const;
304
305 /*
306 * This function calculates the matrix-vector product for the linear(ized) problem.
307 */
308 void
309 apply_linearized_problem(BlockVectorType & dst, BlockVectorType const & src) const;
310
311 /*
312 * This function calculates the right-hand side of the steady Stokes problem, or unsteady Stokes
313 * problem, or unsteady Navier-Stokes problem with explicit treatment of the convective term. The
314 * parameter 'time' has to be specified for unsteady problems and can be omitted for steady
315 * problems.
316 */
317 void
318 rhs_linear_problem(BlockVectorType & dst,
319 VectorType const & transport_velocity,
320 double const & time = 0.0) const;
321
322 /*
323 * Block preconditioner
324 */
325 void
326 update_block_preconditioner();
327
328 void
329 apply_block_preconditioner(BlockVectorType & dst, BlockVectorType const & src) const;
330
331private:
332 void
333 setup_solver_coupled();
334
335 /*
336 * Block preconditioner
337 */
338 void
339 setup_block_preconditioner();
340
341 void
342 initialize_vectors();
343
344 void
345 initialize_preconditioner_velocity_block();
346
347 void
348 setup_multigrid_preconditioner_momentum();
349
350 void
351 setup_iterative_solver_momentum();
352
353 void
354 initialize_preconditioner_pressure_block();
355
356 void
357 setup_multigrid_preconditioner_schur_complement();
358
359 void
360 setup_iterative_solver_schur_complement();
361
362 void
363 setup_pressure_convection_diffusion_operator();
364
365 void
366 apply_preconditioner_velocity_block(VectorType & dst, VectorType const & src) const;
367
368 void
369 apply_preconditioner_pressure_block(VectorType & dst, VectorType const & src) const;
370
371 void
372 apply_inverse_negative_laplace_operator(VectorType & dst, VectorType const & src) const;
373
374 /*
375 * Newton-Krylov solver for (non-)linear problem
376 */
377
378 // temporary vector needed to evaluate both the nonlinear residual and the linearized operator
379 VectorType mutable temp_vector;
380
381 double scaling_factor_continuity;
382
383 // Nonlinear operator
384 NonlinearOperatorCoupled<dim, Number> nonlinear_operator;
385
386 // Newton solver
387 std::shared_ptr<Newton::Solver<BlockVectorType,
391 newton_solver;
392
393 // Linear operator
395
396 // Linear solver
397 std::shared_ptr<Krylov::SolverBase<BlockVectorType>> linear_solver;
398
399 /*
400 * Block preconditioner for linear(ized) problem
401 */
402 typedef BlockPreconditioner<dim, Number> Preconditioner;
403 Preconditioner block_preconditioner;
404
405 // preconditioner velocity/momentum block
406 std::shared_ptr<PreconditionerBase<Number>> preconditioner_momentum;
407
408 std::shared_ptr<Krylov::SolverBase<VectorType>> solver_velocity_block;
409
410 // preconditioner pressure/Schur-complement block
411 std::shared_ptr<PreconditionerBase<Number>> multigrid_preconditioner_schur_complement;
412 std::shared_ptr<PreconditionerBase<Number>> inverse_mass_preconditioner_schur_complement;
413
414 std::shared_ptr<ConvDiff::CombinedOperator<dim, Number>> pressure_conv_diff_operator;
415
416 std::shared_ptr<Poisson::LaplaceOperator<dim, Number, 1>> laplace_operator;
417
418 std::shared_ptr<Krylov::SolverBase<VectorType>> solver_pressure_block;
419
420 // temporary vectors that are necessary when using preconditioners of block-triangular type
421 VectorType mutable vec_tmp_pressure;
422 VectorType mutable vec_tmp_velocity, vec_tmp_velocity_2;
423
424 // temporary vectors that are necessary when applying the Schur-complement preconditioner (scp)
425 VectorType mutable tmp_scp_pressure;
426 VectorType mutable tmp_scp_velocity, tmp_scp_velocity_2;
427};
428
429} // namespace IncNS
430} // namespace ExaDG
431
432#endif /* EXADG_INCOMPRESSIBLE_NAVIER_STOKES_SPATIAL_DISCRETIZATION_OPERATOR_COUPLED_H_ \
433 */
Definition grid.h:40
Definition operator_coupled.h:131
Definition operator_coupled.h:87
Definition operator_coupled.h:40
Definition operator_coupled.h:190
Definition parameters.h:46
Definition iterative_solvers_dealii_wrapper.h:40
Definition grid.h:84
Definition newton_solver.h:40
Definition driver.cpp:33
Definition boundary_descriptor.h:240
Definition field_functions.h:31