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