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>
38class NonlinearOperatorCoupled
39{
40private:
41 typedef dealii::LinearAlgebra::distributed::Vector<Number> VectorType;
42 typedef dealii::LinearAlgebra::distributed::BlockVector<Number> BlockVectorType;
43
44 typedef OperatorCoupled<dim, Number> PDEOperator;
45
46public:
47 NonlinearOperatorCoupled()
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
90 typedef OperatorCoupled<dim, Number> PDEOperator;
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>
129class BlockPreconditioner
130{
131private:
132 typedef dealii::LinearAlgebra::distributed::BlockVector<Number> BlockVectorType;
133
134 typedef OperatorCoupled<dim, Number> PDEOperator;
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:
191 typedef SpatialOperatorBase<dim, Number> Base;
192 typedef OperatorCoupled<dim, Number> This;
193
194 typedef typename Base::MultigridPoisson MultigridPoisson;
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_problem(BlockVectorType & dst,
263 BlockVectorType const & src,
264 VectorType const & transport_velocity,
265 bool const & update_preconditioner,
266 double const & scaling_factor_mass = 1.0);
267
268 /*
269 * Convective term treated implicitly: solve non-linear system of equations
270 */
271
272 /*
273 * This function solves the nonlinear problem.
274 */
275 std::tuple<unsigned int, unsigned int>
276 solve_nonlinear_problem(BlockVectorType & dst,
277 VectorType const & rhs_vector,
278 bool const & update_preconditioner,
279 double const & time = 0.0,
280 double const & scaling_factor_mass = 1.0);
281
282
283 /*
284 * This function evaluates the nonlinear residual.
285 */
286 void
287 evaluate_nonlinear_residual(BlockVectorType & dst,
288 BlockVectorType const & src,
289 VectorType const * rhs_vector,
290 double const & time,
291 double const & scaling_factor_mass) const;
292
293 /*
294 * This function evaluates the nonlinear residual of the steady Navier-Stokes equations.
295 * This function has to be implemented separately (for example, the convective term will be
296 * evaluated in case of the Navier-Stokes equations and the time-derivative term is never
297 * evaluated).
298 */
299 void
300 evaluate_nonlinear_residual_steady(BlockVectorType & dst,
301 BlockVectorType const & src,
302 double const & time) const;
303
304 /*
305 * This function calculates the matrix-vector product for the linear(ized) problem.
306 */
307 void
308 apply_linearized_problem(BlockVectorType & dst, BlockVectorType const & src) const;
309
310 /*
311 * This function calculates the right-hand side of the steady Stokes problem, or unsteady Stokes
312 * problem, or unsteady Navier-Stokes problem with explicit treatment of the convective term. The
313 * parameter 'time' has to be specified for unsteady problems and can be omitted for steady
314 * problems.
315 */
316 void
317 rhs_linear_problem(BlockVectorType & dst,
318 VectorType const & transport_velocity,
319 double const & time = 0.0) const;
320
321 /*
322 * Block preconditioner
323 */
324 void
325 update_block_preconditioner();
326
327 void
328 apply_block_preconditioner(BlockVectorType & dst, BlockVectorType const & src) const;
329
330private:
331 void
332 setup_solver_coupled();
333
334 /*
335 * Block preconditioner
336 */
337 void
338 setup_block_preconditioner();
339
340 void
341 initialize_vectors();
342
343 void
344 initialize_preconditioner_velocity_block();
345
346 void
347 setup_multigrid_preconditioner_momentum();
348
349 void
350 setup_iterative_solver_momentum();
351
352 void
353 initialize_preconditioner_pressure_block();
354
355 void
356 setup_multigrid_preconditioner_schur_complement();
357
358 void
359 setup_iterative_solver_schur_complement();
360
361 void
362 setup_pressure_convection_diffusion_operator();
363
364 void
365 apply_preconditioner_velocity_block(VectorType & dst, VectorType const & src) const;
366
367 void
368 apply_preconditioner_pressure_block(VectorType & dst, VectorType const & src) const;
369
370 void
371 apply_inverse_negative_laplace_operator(VectorType & dst, VectorType const & src) const;
372
373 /*
374 * Newton-Krylov solver for (non-)linear problem
375 */
376
377 // temporary vector needed to evaluate both the nonlinear residual and the linearized operator
378 VectorType mutable temp_vector;
379
380 double scaling_factor_continuity;
381
382 // Nonlinear operator
383 NonlinearOperatorCoupled<dim, Number> nonlinear_operator;
384
385 // Newton solver
386 std::shared_ptr<Newton::Solver<BlockVectorType,
390 newton_solver;
391
392 // Linear operator
394
395 // Linear solver
396 std::shared_ptr<Krylov::SolverBase<BlockVectorType>> linear_solver;
397
398 /*
399 * Block preconditioner for linear(ized) problem
400 */
401 typedef BlockPreconditioner<dim, Number> Preconditioner;
402 Preconditioner block_preconditioner;
403
404 // preconditioner velocity/momentum block
405 std::shared_ptr<PreconditionerBase<Number>> preconditioner_momentum;
406
407 std::shared_ptr<Krylov::SolverBase<VectorType>> solver_velocity_block;
408
409 // preconditioner pressure/Schur-complement block
410 std::shared_ptr<PreconditionerBase<Number>> multigrid_preconditioner_schur_complement;
411 std::shared_ptr<PreconditionerBase<Number>> inverse_mass_preconditioner_schur_complement;
412
413 std::shared_ptr<ConvDiff::CombinedOperator<dim, Number>> pressure_conv_diff_operator;
414
415 std::shared_ptr<Poisson::LaplaceOperator<dim, Number, 1>> laplace_operator;
416
417 std::shared_ptr<Krylov::SolverBase<VectorType>> solver_pressure_block;
418
419 // temporary vectors that are necessary when using preconditioners of block-triangular type
420 VectorType mutable vec_tmp_pressure;
421 VectorType mutable vec_tmp_velocity, vec_tmp_velocity_2;
422
423 // temporary vectors that are necessary when applying the Schur-complement preconditioner (scp)
424 VectorType mutable tmp_scp_pressure;
425 VectorType mutable tmp_scp_velocity, tmp_scp_velocity_2;
426};
427
428} // namespace IncNS
429} // namespace ExaDG
430
431#endif /* INCLUDE_EXADG_INCOMPRESSIBLE_NAVIER_STOKES_SPATIAL_DISCRETIZATION_OPERATOR_COUPLED_H_ \
432 */
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 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