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