@@ -53,11 +53,48 @@ template <typename VectorType>
53
53
class PreconditionBase
54
54
{
55
55
public:
56
+ /* *
57
+ * @brief Constructor.
58
+ */
59
+ PreconditionBase ()
60
+ : comm(MPI_COMM_WORLD)
61
+ , pcout(std::cout, Utilities::MPI::this_mpi_process(comm) == 0 )
62
+ , timer(pcout, TimerOutput::never, TimerOutput::wall_times)
63
+ {}
64
+
56
65
/* *
57
66
* @brief Apply preconditioner.
58
67
*/
59
68
virtual void
60
69
vmult (VectorType &dst, const VectorType &src) const = 0 ;
70
+
71
+ /* *
72
+ * @brief Print timers.
73
+ */
74
+ void
75
+ timer_print () const
76
+ {
77
+ timer.print_wall_time_statistics (comm);
78
+ }
79
+
80
+ /* *
81
+ * @brief Reset timers.
82
+ */
83
+ void
84
+ timer_reset () const
85
+ {
86
+ timer.reset ();
87
+ }
88
+
89
+ protected:
90
+ // / Communicator used for timer output.
91
+ const MPI_Comm comm;
92
+
93
+ // / Stream used for timer output.
94
+ ConditionalOStream pcout;
95
+
96
+ // / Timer.
97
+ mutable TimerOutput timer;
61
98
};
62
99
63
100
/* *
@@ -152,6 +189,8 @@ class PreconditionASM : public PreconditionBase<VectorType>
152
189
const AffineConstraints<Number> &constraints,
153
190
const std::shared_ptr<const Utilities::MPI::Partitioner> &partitioner)
154
191
{
192
+ this ->timer .enter_subsection (" asm::inidices" );
193
+
155
194
std::vector<std::vector<types::global_dof_index>> patches;
156
195
157
196
const auto add_indices = [&](const auto &local_dof_indices) {
@@ -195,13 +234,30 @@ class PreconditionASM : public PreconditionBase<VectorType>
195
234
dst_internal.reinit (partition);
196
235
}
197
236
237
+ // convert indices to local ones
238
+ this ->patches .resize (patches.size ());
239
+ for (unsigned int c = 0 ; c < patches.size (); ++c)
240
+ {
241
+ this ->patches [c].resize (0 );
242
+ this ->patches [c].reserve (patches[c].size ());
243
+
244
+ for (const auto &i : patches[c])
245
+ this ->patches [c].emplace_back (partition->global_to_local (i));
246
+ }
247
+
248
+ this ->timer .leave_subsection (" asm::inidices" );
249
+ this ->timer .enter_subsection (" asm::restrict" );
250
+
198
251
std::vector<FullMatrix<Number>> blocks;
199
252
200
253
SparseMatrixTools::restrict_to_full_matrices (global_sparse_matrix,
201
254
global_sparsity_pattern,
202
255
patches,
203
256
blocks);
204
257
258
+ this ->timer .leave_subsection (" asm::restrict" );
259
+ this ->timer .enter_subsection (" asm::invert" );
260
+
205
261
this ->blocks .resize (blocks.size ());
206
262
207
263
for (unsigned int b = 0 ; b < blocks.size (); ++b)
@@ -212,8 +268,11 @@ class PreconditionASM : public PreconditionBase<VectorType>
212
268
this ->blocks [b].compute_lu_factorization ();
213
269
}
214
270
271
+ this ->timer .leave_subsection (" asm::invert" );
272
+
215
273
if (weighting_type != WeightingType::none)
216
274
{
275
+ this ->timer .enter_subsection (" asm::weight" );
217
276
Vector<double > vector_weights;
218
277
weights.reinit (partition);
219
278
@@ -234,17 +293,8 @@ class PreconditionASM : public PreconditionBase<VectorType>
234
293
i = (weighting_type == WeightingType::symm) ? std::sqrt (1.0 / i) :
235
294
(1.0 / i);
236
295
weights.update_ghost_values ();
237
- }
238
296
239
- // convert indices to local ones
240
- this ->patches .resize (patches.size ());
241
- for (unsigned int c = 0 ; c < patches.size (); ++c)
242
- {
243
- this ->patches [c].resize (0 );
244
- this ->patches [c].reserve (patches[c].size ());
245
-
246
- for (const auto &i : patches[c])
247
- this ->patches [c].emplace_back (partition->global_to_local (i));
297
+ this ->timer .leave_subsection (" asm::weight" );
248
298
}
249
299
}
250
300
@@ -254,6 +304,8 @@ class PreconditionASM : public PreconditionBase<VectorType>
254
304
void
255
305
vmult (VectorType &dst, const VectorType &src) const override
256
306
{
307
+ this ->timer .enter_subsection (" asm::vmult" );
308
+
257
309
const auto &src_ptr = (src_internal.size () != 0 ) ? src_internal : src;
258
310
auto &dst_ptr = (dst_internal.size () != 0 ) ? dst_internal : dst;
259
311
@@ -302,6 +354,8 @@ class PreconditionASM : public PreconditionBase<VectorType>
302
354
303
355
if (dst_internal.size () != 0 )
304
356
dst.copy_locally_owned_data_from (dst_internal);
357
+
358
+ this ->timer .leave_subsection (" asm::vmult" );
305
359
}
306
360
307
361
private:
@@ -1769,6 +1823,14 @@ MFNavierStokesPreconditionGMG<dim>::get_mg_operators() const
1769
1823
return this ->mg_operators ;
1770
1824
}
1771
1825
1826
+ template <int dim>
1827
+ const MGLevelObject<std::shared_ptr<
1828
+ PreconditionBase<typename MFNavierStokesPreconditionGMG<dim>::VectorType>>> &
1829
+ MFNavierStokesPreconditionGMG<dim>::get_mg_smoother_preconditioners() const
1830
+ {
1831
+ return this ->mg_smoother_preconditioners ;
1832
+ }
1833
+
1772
1834
template <int dim>
1773
1835
void
1774
1836
MFNavierStokesPreconditionGMG<dim>::setup_AMG()
@@ -2569,6 +2631,21 @@ FluidDynamicsMatrixFree<dim>::print_mg_setup_times()
2569
2631
mg_operators[level]->timer .reset ();
2570
2632
}
2571
2633
2634
+ auto mg_smoother_preconditioners =
2635
+ this ->gmg_preconditioner ->get_mg_smoother_preconditioners ();
2636
+ for (unsigned int level = mg_operators.min_level ();
2637
+ level <= mg_operators.max_level ();
2638
+ level++)
2639
+ {
2640
+ announce_string (this ->pcout ,
2641
+ " Preconditioner level " + std::to_string (level) +
2642
+ " times" );
2643
+ mg_smoother_preconditioners[level]->timer_print ();
2644
+
2645
+ // Reset timer if output is set to every iteration
2646
+ mg_smoother_preconditioners[level]->timer_reset ();
2647
+ }
2648
+
2572
2649
// Reset timers if output is set to every iteration
2573
2650
this ->gmg_preconditioner ->mg_setup_timer .reset ();
2574
2651
this ->gmg_preconditioner ->mg_vmult_timer .reset ();
0 commit comments