1 #ifndef __CS_SLES_PC_H__
2 #define __CS_SLES_PC_H__
3 
4 /*============================================================================
5  * Sparse Linear Equation Solver Preconditioner driver
6  *============================================================================*/
7 
8 /*
9   This file is part of Code_Saturne, a general-purpose CFD tool.
10 
11   Copyright (C) 1998-2021 EDF S.A.
12 
13   This program is free software; you can redistribute it and/or modify it under
14   the terms of the GNU General Public License as published by the Free Software
15   Foundation; either version 2 of the License, or (at your option) any later
16   version.
17 
18   This program is distributed in the hope that it will be useful, but WITHOUT
19   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
21   details.
22 
23   You should have received a copy of the GNU General Public License along with
24   this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
25   Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 */
27 
28 /*----------------------------------------------------------------------------*/
29 
30 /*----------------------------------------------------------------------------
31  *  Local headers
32  *----------------------------------------------------------------------------*/
33 
34 #include "cs_base.h"
35 #include "cs_log.h"
36 #include "cs_halo_perio.h"
37 #include "cs_matrix.h"
38 
39 /*----------------------------------------------------------------------------*/
40 
41 BEGIN_C_DECLS
42 
43 /*============================================================================
44  * Macro definitions
45  *============================================================================*/
46 
47 /*============================================================================
48  * Type definitions
49  *============================================================================*/
50 
51 /*----------------------------------------------------------------------------
52  * Convergence status
53  *----------------------------------------------------------------------------*/
54 
55 typedef enum {
56 
57   CS_SLES_PC_DIVERGED = -2,
58   CS_SLES_PC_BREAKDOWN = -1,
59   CS_SLES_PC_MAX_ITERATION = 0,
60   CS_SLES_PC_CONVERGED = 1
61 
62 } cs_sles_pc_state_t;
63 
64 /* General linear solver context (opaque) */
65 
66 typedef struct _cs_sles_pc_t  cs_sles_pc_t;
67 
68 /*----------------------------------------------------------------------------
69  * Function pointer returning the type name of a preconditioner context.
70  *
71  * The context structure depends on the type of preconditioner used,
72  * which may in turn be determined by the string returned by
73  * cs_sles_pc_get_type() and cs_sles_pc_get_type_name().
74  * If may be used by appropriate functions specific to that type.
75  *
76  * parameters:
77  *   context   <-- pointer to preconditioner-specific context
78  *   logging   <-- if true, a name appropritate to logging
79  *                 (possibly translated) is returned; if false,
80  *                 a canonical name is returned.
81  *----------------------------------------------------------------------------*/
82 
83 typedef const char *
84 (cs_sles_pc_get_type_t) (const void  *context,
85                          bool         logging);
86 
87 /*----------------------------------------------------------------------------
88  * Function pointer for pre-resolution setup of a preconditioner context.
89  *
90  * This setup may include building a multigrid hierarchy, for example.
91  *
92  * parameters:
93  *   context   <-> pointer to preconditioner context
94  *   name      <-- pointer to name of associated linear system
95  *   a         <-- matrix
96  *   verbosity <-- associated verbosity
97  *----------------------------------------------------------------------------*/
98 
99 typedef void
100 (cs_sles_pc_setup_t) (void               *context,
101                       const char         *name,
102                       const cs_matrix_t  *a,
103                       int                 verbosity);
104 
105 /*----------------------------------------------------------------------------
106  * Function pointer for setting of the required tolerance for preconditioners
107  * involving an iterative solver.
108  *
109  * This will usually not be relevant to non-iterative preconditioners,
110  * for which this type of function does not need to be defined.
111  *
112  * The preconditioner is considered to have converged when
113  * residue/r_norm <= precision, residue being the L2 norm of a.vx-rhs.
114  *
115  * parameters:
116  *   context       <-> pointer to preconditioner context
117  *   precision     <-- preconditioner precision
118  *   r_norm        <-- residue normalization
119  *----------------------------------------------------------------------------*/
120 
121 typedef void
122 (cs_sles_pc_tolerance_t) (void    *context,
123                           double   precision,
124                           double   r_norm);
125 
126 /*----------------------------------------------------------------------------
127  * Function pointer for application of a preconditioner.
128  *
129  * In cases where it is desired that the preconditioner modify a vector
130  * "in place", x_in should be set to NULL, and x_out contain the vector to
131  * be modified (\f$x_{out} \leftarrow M^{-1}x_{out})\f$).
132  *
133  * parameters:
134  *   context       <-> pointer to preconditioner context
135  *   x_in          <-- input vector
136  *   x_out         <-> input/output vector
137  *
138  * returns:
139  *   preconditioner application status
140  *----------------------------------------------------------------------------*/
141 
142 typedef cs_sles_pc_state_t
143 (cs_sles_pc_apply_t) (void                *context,
144                       const cs_real_t     *x_in,
145                       cs_real_t           *x_out);
146 
147 /*----------------------------------------------------------------------------
148  * Function pointer for freeing of a preconditioner's context data.
149  *
150  * Note that this function should free resolution-related data, such as
151  * multigrid hierarchy and any other temporary arrays or
152  * objects required for application, but should not free the whole context,
153  * as info used for logging (especially performance data) should be
154  * maintained.
155  *
156  * parameters:
157  *   context <-> pointer to preconditioner context
158  *----------------------------------------------------------------------------*/
159 
160 typedef void
161 (cs_sles_pc_free_t) (void  *context);
162 
163 /*----------------------------------------------------------------------------
164  * Function pointer for logging of linear preconditioner setup,
165  * history and performance data.
166  *
167  * This function will indirectly  be called for each preconditioner when
168  * cs_sles_finalize() is called.
169  *
170  * parameters:
171  *   context  <-- pointer to preconditioner context
172  *   log_type <-- log type
173  *----------------------------------------------------------------------------*/
174 
175 typedef void
176 (cs_sles_pc_log_t) (const void  *context,
177                     cs_log_t     log_type);
178 
179 /*----------------------------------------------------------------------------
180  * Function pointer for creation of a preconditioner context based on the
181  * copy of another.
182  *
183  * The new context copies the settings of the copied context, but not
184  * its setup data and logged info, such as performance data.
185  *
186  * This type of function is optional, but enables associating different
187  * preconditioners to related systems (to differentiate logging) while using
188  * the same settings by default.
189  *
190  * parameters:
191  *   context  <-- context to clone
192  *
193  * returns:
194  *   pointer to newly created context
195  *----------------------------------------------------------------------------*/
196 
197 typedef void *
198 (cs_sles_pc_clone_t) (const void  *context);
199 
200 /*----------------------------------------------------------------------------
201  * Function pointer for destruction of a preconditioner context.
202  *
203  * This function should free all context data.
204  *
205  * parameters:
206  *   context <-> pointer to preconditioner context
207  *----------------------------------------------------------------------------*/
208 
209 typedef void
210 (cs_sles_pc_destroy_t) (void  **context);
211 
212 /*============================================================================
213  *  Global variables
214  *============================================================================*/
215 
216 /*=============================================================================
217  * Public function prototypes for Fortran API
218  *============================================================================*/
219 
220 /*=============================================================================
221  * Public function prototypes
222  *============================================================================*/
223 
224 /*----------------------------------------------------------------------------*/
225 /*!
226  * \brief Log preconditioner setup, history and performance data.
227  *
228  * This function frees resolution-related data, such as multigrid hierarchy,
229  * preconditioning, and any other temporary arrays or objects required for
230  * resolution, but maintains context information such as that used for
231  * logging (especially performance data).
232  *
233  * \param[in, out]  pc        pointer to preconditioner object
234  * \param[in]       log_type  log type
235  */
236 /*----------------------------------------------------------------------------*/
237 
238 void
239 cs_sles_pc_log(cs_sles_pc_t  *pc,
240                cs_log_t       log_type);
241 
242 /*----------------------------------------------------------------------------*/
243 /*!
244  * \brief Define sparse linear equation preconditioner.
245  *
246  * The context pointer is used to point to a structure adapted to the function
247  * pointers given here, and combined with those functions, allows using
248  * both built-in, external, or user-defined preconditioners.
249  *
250  * \param[in, out]  context         pointer to preconditioner context structure
251  *                                  (cs_sles_pc subsystem becomes owner)
252  * \param[in]       get_type_func   pointer to function returning type name
253  * \param[in]       setup_func      pointer to preconditioner setup function
254  * \param[in]       tolerance_func  pointer to tolerance setting functio
255  * \param[in]       apply_func      pointer to preconditioner application
256  *                                  function (also calls setup_func if not done
257  *                                  yet or free_func called since last apply)
258  * \param[in]       free_func       pointer function freeing system setup
259  * \param[in]       log_func        pointer to system info logging function
260                                     (optional, but recommended)
261  * \param[in]       clone_func      pointer to settings clone function
262  * \param[in]       destroy_func    pointer to function destroying
263  *                                  preconditioner context
264  *
265  * \return  pointer to associated preconditioner object
266  */
267 /*----------------------------------------------------------------------------*/
268 
269 cs_sles_pc_t *
270 cs_sles_pc_define(void                    *context,
271                   cs_sles_pc_get_type_t   *get_type_func,
272                   cs_sles_pc_setup_t      *setup_func,
273                   cs_sles_pc_tolerance_t  *tolerance_func,
274                   cs_sles_pc_apply_t      *apply_func,
275                   cs_sles_pc_free_t       *free_func,
276                   cs_sles_pc_log_t        *log_func,
277                   cs_sles_pc_clone_t      *clone_func,
278                   cs_sles_pc_destroy_t    *destroy_func);
279 
280 /*----------------------------------------------------------------------------*/
281 /*!
282  * \brief Destroy a sparse linear equation preconditioner.
283  *
284  *
285  * \param[in, out]  pc   pointer to preconditioner context structure
286  */
287 /*----------------------------------------------------------------------------*/
288 
289 void
290 cs_sles_pc_destroy(cs_sles_pc_t **pc);
291 
292 /*----------------------------------------------------------------------------*/
293 /*!
294  * \brief Create a new preconditioner context based on the copy of another.
295  *
296  * The intended use of this function is to allow associating different
297  * preconditioners to related systems, so as to allow simultaneous setups
298  * and differentiate logging, while using the same settings by default.
299  *
300  * If no preconditioner (i.e. NULL) is passed, it will return NULL.
301  *
302  * \param[in]       src   pointer to source preconditioner object
303  *
304  * \return  pointer to new preconditioner object, or NULL
305  */
306 /*----------------------------------------------------------------------------*/
307 
308 cs_sles_pc_t *
309 cs_sles_pc_clone(const cs_sles_pc_t  *src);
310 
311 /*----------------------------------------------------------------------------*/
312 /*!
313  * \brief Return type name of preconditioner context.
314  *
315  * The returned string is intended to help determine which type is associated
316  * with the void * pointer returned by \ref cs_sles_pc_get_context for a given
317  * preconditioner definition, so as to be able to call additional specific
318  * functions beyond the generic functions assigned to a cs_sles_pc_t object.
319  *
320  * \param[in]  pc  pointer to preconditioner object
321  *
322  * \return  pointer to linear system preconditioner specific type name
323  */
324 /*----------------------------------------------------------------------------*/
325 
326 const char *
327 cs_sles_pc_get_type(cs_sles_pc_t  *pc);
328 
329 /*----------------------------------------------------------------------------*/
330 /*!
331  * \brief Return type name of preconditioner context.
332  *
333  * The returned string is intended mainly for logging.
334  *
335  * \param[in]  pc  pointer to preconditioner object
336  */
337 /*----------------------------------------------------------------------------*/
338 
339 const char *
340 cs_sles_pc_get_type_name(cs_sles_pc_t  *pc);
341 
342 /*----------------------------------------------------------------------------*/
343 /*!
344  * \brief Return pointer to preconditioner context structure pointer.
345  *
346  * The context structure depends on the type of preconditioner used, which may
347  * in turn be determined by the string returned by cs_sles_pc_get_type().
348  * If may be used by appropriate functions specific to that type.
349  *
350  * \param[in]  pc  pointer to preconditioner object
351  *
352  * \return  pointer to preconditioner-specific info and context
353  */
354 /*----------------------------------------------------------------------------*/
355 
356 void *
357 cs_sles_pc_get_context(cs_sles_pc_t  *pc);
358 
359 /*----------------------------------------------------------------------------*/
360 /*!
361  * \brief Return a pointer to the function used to apply a preconditioner.
362  *
363  * This allows calling the preconditioner with one less level of indirection.
364  *
365  * \param[in]  pc  pointer to preconditioner object
366  *
367  * \return  preconditioner apply function
368  */
369 /*----------------------------------------------------------------------------*/
370 
371 cs_sles_pc_apply_t *
372 cs_sles_pc_get_apply_func(const cs_sles_pc_t *pc);
373 
374 /*----------------------------------------------------------------------------*/
375 /*!
376  * \brief Set the required tolerance for preconditioners involving an
377  *        iterative solver.
378  *
379  * This will usually not be relevant to non-iterative preconditioners,
380  * in which case this is a no-op.
381  *
382  * If no options were previously provided for the matching system,
383  * default options will be used.
384  *
385  * The system is considered to have converged when
386  * residue/r_norm <= precision, residue being the L2 norm of a.vx-rhs.
387  *
388  * \param[in, out]  pc             pointer to preconditioner object
389  * \param[in]       precision      preconditioner precision
390  * \param[in]       r_norm         residue normalization
391  */
392 /*----------------------------------------------------------------------------*/
393 
394 void
395 cs_sles_pc_set_tolerance(cs_sles_pc_t  *pc,
396                          double         precision,
397                          double         r_norm);
398 
399 /*----------------------------------------------------------------------------*/
400 /*!
401  * \brief Setup sparse linear equation preconditioner.
402  *
403  * Use of this function is optional: if a \ref cs_sles_solve is called
404  * for the same system before this function is called, the latter will be
405  * called automatically.
406  *
407  * If no options were previously provided for the matching system,
408  * default options will be used.
409  *
410  * \param[in, out]  pc         pointer to preconditioner object
411  * \param[in]       name       linear system name
412  * \param[in]       a          matrix
413  * \param[in]       verbosity  verbosity level
414  */
415 /*----------------------------------------------------------------------------*/
416 
417 void
418 cs_sles_pc_setup(cs_sles_pc_t       *pc,
419                  const char         *name,
420                  const cs_matrix_t  *a,
421                  int                 verbosity);
422 
423 /*----------------------------------------------------------------------------*/
424 /*!
425  * \brief Apply a preconditioner.
426  *
427  * If no options were previously provided for the matching system,
428  * default options will be used.
429  *
430  * In cases where it is desired that the preconditioner modify a vector
431  * "in place", x_in should be set to NULL, and x_out contain the vector to
432  * be modified (\f$x_{out} \leftarrow M^{-1}x_{out})\f$).
433  *
434  * \param[in, out]  pc             pointer to preconditioner object
435  * \param[in]       x_in           input vector
436  * \param[in, out]  x_out          input/output vector
437  *
438  * \return  preconditioner application status
439  */
440 /*----------------------------------------------------------------------------*/
441 
442 cs_sles_pc_state_t
443 cs_sles_pc_apply(cs_sles_pc_t        *pc,
444                  cs_real_t           *x_in,
445                  cs_real_t           *x_out);
446 
447 /*----------------------------------------------------------------------------*/
448 /*!
449  * \brief Free preconditioner setup.
450  *
451  * This function frees resolution-related data, such as multigrid hierarchy,
452  * preconditioning, and any other temporary arrays or objects required for
453  * resolution, but maintains context information such as that used for
454  * logging (especially performance data).
455  *
456  * \param[in, out]  pc  pointer to preconditioner object
457  */
458 /*----------------------------------------------------------------------------*/
459 
460 void
461 cs_sles_pc_free(cs_sles_pc_t  *pc);
462 
463 /*----------------------------------------------------------------------------*/
464 /*!
465  * \brief Create an "identity" (or null) preconditioner.
466  *
467  * \return  pointer to newly created preconditioner object.
468  */
469 /*----------------------------------------------------------------------------*/
470 
471 cs_sles_pc_t *
472 cs_sles_pc_none_create(void);
473 
474 /*----------------------------------------------------------------------------*/
475 /*!
476  * \brief Create a Jacobi preconditioner.
477  *
478  * \return  pointer to newly created preconditioner object.
479  */
480 /*----------------------------------------------------------------------------*/
481 
482 cs_sles_pc_t *
483 cs_sles_pc_jacobi_create(void);
484 
485 /*----------------------------------------------------------------------------*/
486 /*!
487  * \brief Create a polynomial preconditioner of degree 1.
488  *
489  * \return  pointer to newly created preconditioner object.
490  */
491 /*----------------------------------------------------------------------------*/
492 
493 cs_sles_pc_t *
494 cs_sles_pc_poly_1_create(void);
495 
496 /*----------------------------------------------------------------------------*/
497 /*!
498  * \brief Create a polynomial preconditioner of degree 2.
499  *
500  * \return  pointer to newly created preconditioner object.
501  */
502 /*----------------------------------------------------------------------------*/
503 
504 cs_sles_pc_t *
505 cs_sles_pc_poly_2_create(void);
506 
507 /*----------------------------------------------------------------------------*/
508 
509 END_C_DECLS
510 
511 #endif /* __CS_SLES_PC_H__ */
512