1 #ifndef __CS_INTERNAL_COUPLING_H__ 2 #define __CS_INTERNAL_COUPLING_H__ 3 4 /*============================================================================ 5 * Internal coupling: coupling for one instance of Code_Saturne 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 * PLE library headers 32 *----------------------------------------------------------------------------*/ 33 34 #include <ple_locator.h> 35 36 /*---------------------------------------------------------------------------- 37 * Local headers 38 *----------------------------------------------------------------------------*/ 39 40 #include "cs_defs.h" 41 42 #include "cs_base.h" 43 #include "cs_matrix_assembler.h" 44 #include "cs_mesh.h" 45 #include "cs_mesh_quantities.h" 46 #include "cs_parameters.h" 47 48 /*----------------------------------------------------------------------------*/ 49 50 BEGIN_C_DECLS 51 52 /*============================================================================= 53 * Macro definitions 54 *============================================================================*/ 55 56 /*============================================================================ 57 * Type definitions 58 *============================================================================*/ 59 60 61 /* Internal coupling structure definition */ 62 63 typedef struct { 64 65 /* Id */ 66 int id; 67 68 /* Locator + tag for exchanging variables */ 69 ple_locator_t *locator; 70 int *c_tag; 71 72 /* Selection criteria for coupled domains */ 73 char *cells_criteria; 74 char *faces_criteria; 75 76 char *interior_faces_group_name; 77 char *exterior_faces_group_name; 78 79 /* Associated zone ids */ 80 81 int n_volume_zones; 82 int *volume_zone_ids; 83 84 cs_lnum_t n_local; /* Number of faces */ 85 cs_lnum_t *faces_local; /* Coupling boundary faces, numbered 0..n-1 */ 86 87 cs_lnum_t n_distant; /* Number of faces in faces_distant */ 88 cs_lnum_t *faces_distant; /* Distant boundary faces associated with locator */ 89 90 /* face i is coupled in this entity if coupled_faces[i] = true */ 91 bool *coupled_faces; 92 93 /* Geometrical weights around coupling interface */ 94 cs_real_t *g_weight; 95 96 /* IJ vectors */ 97 cs_real_3_t *ci_cj_vect; 98 99 /* OF vectors */ 100 cs_real_3_t *offset_vect; 101 102 } cs_internal_coupling_t; 103 104 /*============================================================================ 105 * Public function prototypes 106 *============================================================================*/ 107 108 /*----------------------------------------------------------------------------*/ 109 /*! 110 * \brief Return number of defined internal couplings. 111 * 112 * \return number of internal couplings 113 */ 114 /*----------------------------------------------------------------------------*/ 115 116 int 117 cs_internal_coupling_n_couplings(void); 118 119 /*----------------------------------------------------------------------------*/ 120 /*! 121 * \brief Define coupling volume using given selection criteria. 122 * 123 * Then, this volume must be separated from the rest of the domain with a wall. 124 * 125 * \param[in] criteria_cells criteria for the first group of cells 126 * \param[in] criteria_faces criteria for faces to be joined 127 */ 128 /*----------------------------------------------------------------------------*/ 129 130 void 131 cs_internal_coupling_add(const char criteria_cells[], 132 const char criteria_faces[]); 133 134 /*----------------------------------------------------------------------------*/ 135 /*! 136 * \brief Define coupling volume using given criteria. Then, this volume will 137 * be separated from the rest of the domain with thin walls. 138 * 139 * \param[in] criteria_cells criteria for the first group of cells 140 */ 141 /*----------------------------------------------------------------------------*/ 142 143 void 144 cs_internal_coupling_add_volume(const char criteria_cells[]); 145 146 /*----------------------------------------------------------------------------*/ 147 /*! 148 * \brief Define coupling volume using a cs_zone_t. Then, this volume will 149 * be separated from the rest of the domain with thin walls. 150 * 151 * \param[in] z pointer to cs_volume_zone_t 152 */ 153 /*----------------------------------------------------------------------------*/ 154 155 void 156 cs_internal_coupling_add_volume_zone(const cs_zone_t *z); 157 158 /*----------------------------------------------------------------------------*/ 159 /*! 160 * \brief Define coupling volume using given cs_zone_t. Then, this volume will 161 * be separated from the rest of the domain with thin walls. 162 * 163 * \param[in] n_zones number of associated volume zones 164 * \param[in] zone_ids ids of associated volume zones 165 */ 166 /*----------------------------------------------------------------------------*/ 167 168 void 169 cs_internal_coupling_add_volume_zones(int n_zones, 170 const int zone_ids[]); 171 172 /*----------------------------------------------------------------------------*/ 173 /*! 174 * \brief Define internal coupling volume boundary group names. 175 * 176 * This is used only for internal couplings based on a separation of volumes 177 * (cs_internal_coupling_add_volume, cs_internal_coupling_add_volume_zone, 178 * cs_internal_coupling_add_volume_zones). 179 * 180 * The interior name is used for faces adjacent to the main volume, and 181 * the exterio name for faces adjacent to the selected (exterior) volume. 182 * 183 * This allows filtering faces on each side of the boundary in a simpler manner. 184 * 185 * \param[in, out] cpl pointer to mesh structure to modify 186 * \param[in] criteria_cells criteria for the first group of cells 187 */ 188 /*----------------------------------------------------------------------------*/ 189 190 void 191 cs_internal_coupling_add_boundary_groups(cs_internal_coupling_t *cpl, 192 const char *interior_name, 193 const char *exterior_name); 194 195 /*----------------------------------------------------------------------------*/ 196 /*! 197 * \brief Impose wall BCs to internal coupled faces if not yet defined. 198 * 199 * \param[in, out] bc_type face boundary condition type 200 */ 201 /*----------------------------------------------------------------------------*/ 202 203 void 204 cs_internal_coupling_bcs(int bc_type[]); 205 206 /*----------------------------------------------------------------------------*/ 207 /*! 208 * \brief Destruction of all internal coupling related structures. 209 */ 210 /*----------------------------------------------------------------------------*/ 211 212 void 213 cs_internal_coupling_finalize(void); 214 215 /*----------------------------------------------------------------------------*/ 216 /*! 217 * \brief Return the coupling associated with a given coupling_id. 218 * 219 * \param[in] coupling_id associated with a coupling entity 220 * 221 * \return pointer to associated coupling structure 222 */ 223 /*----------------------------------------------------------------------------*/ 224 225 cs_internal_coupling_t * 226 cs_internal_coupling_by_id(int coupling_id); 227 228 /*----------------------------------------------------------------------------*/ 229 /*! 230 * \brief Exchange quantities from distant to local 231 * (update local using distant). 232 * 233 * \param[in] cpl pointer to coupling entity 234 * \param[in] stride stride (e.g. 1 for double, 3 for interleaved coordinates) 235 * \param[in] distant distant values, size coupling->n_distant 236 * \param[out] local local values, size coupling->n_local 237 */ 238 /*----------------------------------------------------------------------------*/ 239 240 void 241 cs_internal_coupling_exchange_var(const cs_internal_coupling_t *cpl, 242 int stride, 243 cs_real_t distant[], 244 cs_real_t local[]); 245 246 /*----------------------------------------------------------------------------*/ 247 /*! 248 * \brief Exchange variable between groups using cell id. 249 * 250 * \param[in] cpl pointer to coupling entity 251 * \param[in] stride number of values (non interlaced) by entity 252 * \param[in] tab variable exchanged 253 * \param[out] local local data 254 */ 255 /*----------------------------------------------------------------------------*/ 256 257 void 258 cs_internal_coupling_exchange_by_cell_id(const cs_internal_coupling_t *cpl, 259 int stride, 260 const cs_real_t tab[], 261 cs_real_t local[]); 262 263 /*----------------------------------------------------------------------------*/ 264 /*! 265 * \brief Exchange variable between groups using face id. 266 * 267 * \param[in] cpl pointer to coupling entity 268 * \param[in] stride number of values (non interlaced) by entity 269 * \param[in] tab variable exchanged 270 * \param[out] local local data 271 */ 272 /*----------------------------------------------------------------------------*/ 273 274 void 275 cs_internal_coupling_exchange_by_face_id(const cs_internal_coupling_t *cpl, 276 int stride, 277 const cs_real_t tab[], 278 cs_real_t local[]); 279 280 /*---------------------------------------------------------------------------- 281 * Modify LSQ COCG matrix to include internal coupling 282 * 283 * parameters: 284 * cpl <-- pointer to coupling entity 285 * cocg <-> cocg matrix modified 286 *----------------------------------------------------------------------------*/ 287 288 void 289 cs_internal_coupling_lsq_cocg_contribution(const cs_internal_coupling_t *cpl, 290 cs_real_6_t cocg[]); 291 292 /*---------------------------------------------------------------------------- 293 * Modify LSQ COCG matrix to include internal coupling 294 * when diffusivity is a tensor 295 * 296 * parameters: 297 * cpl <-- pointer to coupling entity 298 * c_weight <-- weigthing coefficients 299 * cocg <-> cocg matrix modified 300 *----------------------------------------------------------------------------*/ 301 302 void 303 cs_internal_coupling_lsq_cocg_weighted(const cs_internal_coupling_t *cpl, 304 const cs_real_t *c_weight, 305 cs_real_6_t cocg[]); 306 307 /*---------------------------------------------------------------------------- 308 * Modify iterative COCG matrix to include internal coupling 309 * 310 * parameters: 311 * cpl <-- pointer to coupling entity 312 * cocg <-> cocg matrix modified 313 *----------------------------------------------------------------------------*/ 314 315 void 316 cs_internal_coupling_it_cocg_contribution(const cs_internal_coupling_t *cpl, 317 cs_real_33_t cocg[]); 318 319 /*----------------------------------------------------------------------------*/ 320 /*! 321 * \brief Setup internal coupling related parameters. 322 */ 323 /*----------------------------------------------------------------------------*/ 324 325 void 326 cs_internal_coupling_setup(void); 327 328 /*----------------------------------------------------------------------------*/ 329 /*! 330 * \brief Initialize internal coupling related structures. 331 */ 332 /*----------------------------------------------------------------------------*/ 333 334 void 335 cs_internal_coupling_initialize(void); 336 337 /*----------------------------------------------------------------------------*/ 338 /*! 339 * \brief Add internal coupling rhs contribution for LSQ gradient calculation 340 * 341 * \param[in] cpl pointer to coupling entity 342 * \param[in] c_weight weighted gradient coefficient variable, or NULL 343 * \param[in] w_stride stride of weighting coefficient 344 * \param[in, out] rhsv pointer to rhs contribution 345 */ 346 /*----------------------------------------------------------------------------*/ 347 348 void 349 cs_internal_coupling_lsq_scalar_gradient( 350 const cs_internal_coupling_t *cpl, 351 const cs_real_t c_weight[], 352 const int w_stride, 353 cs_real_4_t rhsv[]); 354 355 /*----------------------------------------------------------------------------*/ 356 /*! 357 * \brief Add internal coupling rhs contribution for LSQ gradient calculation 358 * 359 * \param[in] cpl pointer to coupling entity 360 * \param[in] c_weight weighted gradient coefficient variable, or NULL 361 * \param[in] w_stride stride of weighting coefficient 362 * \param[in] pvar pointer to variable 363 * \param[in, out] rhs pointer to rhs contribution 364 */ 365 /*----------------------------------------------------------------------------*/ 366 367 void 368 cs_internal_coupling_lsq_vector_gradient( 369 const cs_internal_coupling_t *cpl, 370 const cs_real_t c_weight[], 371 const int w_stride, 372 const cs_real_3_t pvar[], 373 cs_real_33_t rhs[]); 374 375 /*----------------------------------------------------------------------------*/ 376 /*! 377 * \brief Add internal coupling rhs contribution for LSQ gradient calculation 378 * 379 * \param[in] cpl pointer to coupling entity 380 * \param[in] c_weight weighted gradient coefficient variable, or NULL 381 * \param[in] w_stride stride of weighting coefficient 382 * \param[in] pvar pointer to variable 383 * \param[in, out] rhs pointer to rhs contribution 384 */ 385 /*----------------------------------------------------------------------------*/ 386 387 void 388 cs_internal_coupling_lsq_tensor_gradient( 389 const cs_internal_coupling_t *cpl, 390 const cs_real_t c_weight[], 391 const int w_stride, 392 const cs_real_6_t pvar[], 393 cs_real_63_t rhs[]); 394 395 /*----------------------------------------------------------------------------*/ 396 /*! 397 * \brief Add internal coupling rhs contribution for iterative gradient 398 * calculation 399 * 400 * \param[in] cpl pointer to coupling entity 401 * \param[in] c_weight weighted gradient coefficient variable, or NULL 402 * \param[in] grad pointer to gradient 403 * \param[in] pvar pointer to variable 404 * \param[in, out] rhs pointer to rhs contribution 405 */ 406 /*----------------------------------------------------------------------------*/ 407 408 void 409 cs_internal_coupling_iterative_scalar_gradient( 410 const cs_internal_coupling_t *cpl, 411 const cs_real_t c_weight[], 412 cs_real_3_t *restrict grad, 413 const cs_real_t pvar[], 414 cs_real_3_t rhs[]); 415 416 /*----------------------------------------------------------------------------*/ 417 /*! 418 * \brief Add internal coupling rhs contribution for iterative vector gradient 419 * calculation 420 * 421 * \param[in] cpl pointer to coupling entity 422 * \param[in] c_weight weighted gradient coefficient variable, or NULL 423 * \param[in] grad pointer to gradient 424 * \param[in] pvar pointer to variable 425 * \param[in, out] rhs pointer to rhs contribution 426 */ 427 /*----------------------------------------------------------------------------*/ 428 429 void 430 cs_internal_coupling_iterative_vector_gradient( 431 const cs_internal_coupling_t *cpl, 432 const cs_real_t c_weight[], 433 cs_real_33_t *restrict grad, 434 const cs_real_3_t pvar[], 435 cs_real_33_t rhs[]); 436 437 /*----------------------------------------------------------------------------*/ 438 /*! 439 * \brief Add internal coupling rhs contribution for iterative tensor gradient 440 * calculation 441 * 442 * \param[in] cpl pointer to coupling entity 443 * \param[in] c_weight weighted gradient coefficient variable, or NULL 444 * \param[in] grad pointer to gradient 445 * \param[in] pvar pointer to variable 446 * \param[in, out] rhs pointer to rhs contribution 447 */ 448 /*----------------------------------------------------------------------------*/ 449 450 void 451 cs_internal_coupling_iterative_tensor_gradient( 452 const cs_internal_coupling_t *cpl, 453 const cs_real_t c_weight[], 454 cs_real_63_t *restrict grad, 455 const cs_real_6_t pvar[], 456 cs_real_63_t rhs[]); 457 458 /*----------------------------------------------------------------------------*/ 459 /*! 460 * \brief Add internal coupling contribution for reconstruction of the 461 * gradient of a scalar. 462 * 463 * \param[in] cpl pointer to coupling entity 464 * \param[in] r_grad pointer to reconstruction gradient 465 * \param[in, out] grad pointer to gradient to be reconstructed var 466 */ 467 /*----------------------------------------------------------------------------*/ 468 469 void 470 cs_internal_coupling_reconstruct_scalar_gradient( 471 const cs_internal_coupling_t *cpl, 472 cs_real_3_t *restrict r_grad, 473 cs_real_3_t grad[]); 474 475 /*----------------------------------------------------------------------------*/ 476 /*! 477 * \brief Add internal coupling contribution for reconstruction of the 478 * gradient of a vector. 479 * 480 * \param[in] cpl pointer to coupling entity 481 * \param[in] r_grad pointer to reconstruction gradient 482 * \param[in, out] grad pointer to gradient to be reconstructed var 483 */ 484 /*----------------------------------------------------------------------------*/ 485 486 void 487 cs_internal_coupling_reconstruct_vector_gradient( 488 const cs_internal_coupling_t *cpl, 489 cs_real_33_t *restrict r_grad, 490 cs_real_33_t grad[]); 491 492 /*----------------------------------------------------------------------------*/ 493 /*! 494 * \brief Add internal coupling contribution for reconstruction of the 495 * gradient of a symmetric tensor. 496 * 497 * \param[in] cpl pointer to coupling entity 498 * \param[in] r_grad pointer to reconstruction gradient 499 * \param[in, out] grad pointer to gradient to be reconstructed var 500 */ 501 /*----------------------------------------------------------------------------*/ 502 503 void 504 cs_internal_coupling_reconstruct_tensor_gradient( 505 const cs_internal_coupling_t *cpl, 506 cs_real_63_t *restrict r_grad, 507 cs_real_63_t grad[]); 508 509 /*---------------------------------------------------------------------------- 510 * Addition to matrix-vector product in case of internal coupling. 511 * 512 * parameters: 513 * exclude_diag <-- extra diagonal flag 514 * f <-- associated field pointer 515 * x <-- vector x in m * x = y 516 * y <-> vector y in m * x = y 517 *----------------------------------------------------------------------------*/ 518 519 void 520 cs_internal_coupling_spmv_contribution(bool exclude_diag, 521 const cs_field_t *f, 522 const cs_real_t *restrict x, 523 cs_real_t *restrict y); 524 525 /*---------------------------------------------------------------------------- 526 * Add coupling term coordinates to matrix assembler. 527 * 528 * parameters: 529 * coupling_id 530 * r_g_id <-- global row ids (per cell) 531 * ma <-> matrix assembler 532 *----------------------------------------------------------------------------*/ 533 534 void 535 cs_internal_coupling_matrix_add_ids(int coupling_id, 536 const cs_gnum_t *r_g_id, 537 cs_matrix_assembler_t *ma); 538 539 /*---------------------------------------------------------------------------- 540 * Add coupling terms to matrix values assembly. 541 * 542 * parameters: 543 * f <-- associated field 544 * db_size <-- diagonal block size 545 * eb_size <-- extra-diagonal block size 546 * r_g_id <-- global row ids (per cell) 547 * mav <-> matrix values assembler 548 *----------------------------------------------------------------------------*/ 549 550 void 551 cs_internal_coupling_matrix_add_values(const cs_field_t *f, 552 cs_lnum_t db_size, 553 cs_lnum_t eb_size, 554 const cs_gnum_t r_g_id[], 555 cs_matrix_assembler_values_t *mav); 556 557 /*---------------------------------------------------------------------------- 558 * Return pointers to coupling components 559 * 560 * parameters: 561 * cpl <-- pointer to coupling entity 562 * n_local --> NULL or pointer to component n_local 563 * faces_local --> NULL or pointer to component faces_local 564 * n_distant --> NULL or pointer to component n_distant 565 * faces_distant --> NULL or pointer to component faces_distant 566 *----------------------------------------------------------------------------*/ 567 568 void 569 cs_internal_coupling_coupled_faces(const cs_internal_coupling_t *cpl, 570 cs_lnum_t *n_local, 571 const cs_lnum_t *faces_local[], 572 cs_lnum_t *n_distant, 573 const cs_lnum_t *faces_distant[]); 574 575 /*---------------------------------------------------------------------------- 576 * Log information about a given internal coupling entity 577 * 578 * parameters: 579 * cpl <-- pointer to coupling entity 580 *----------------------------------------------------------------------------*/ 581 582 void 583 cs_internal_coupling_log(const cs_internal_coupling_t *cpl); 584 585 /*---------------------------------------------------------------------------- 586 * Print informations about all coupling entities 587 * 588 * parameters: 589 * cpl <-- pointer to coupling entity 590 *----------------------------------------------------------------------------*/ 591 592 void 593 cs_internal_coupling_dump(void); 594 595 /*---------------------------------------------------------------------------- 596 * Add preprocessing operations required by coupling volume using given 597 * criteria. 598 * 599 * The volume is separated from the rest of the domain with inserted 600 * boundaries. 601 * 602 * parameters: 603 * mesh <-> pointer to mesh structure to modify 604 *----------------------------------------------------------------------------*/ 605 606 void 607 cs_internal_coupling_preprocess(cs_mesh_t *mesh); 608 609 /*---------------------------------------------------------------------------- 610 * Define face to face mappings for internal couplings. 611 * 612 * parameters: 613 * mesh <-> pointer to mesh structure to modify 614 *----------------------------------------------------------------------------*/ 615 616 void 617 cs_internal_coupling_map(cs_mesh_t *mesh); 618 619 /*---------------------------------------------------------------------------- 620 * Define coupling entity using given criteria. 621 * 622 * parameters: 623 * f_id <-- id of the field 624 *----------------------------------------------------------------------------*/ 625 626 void 627 cs_internal_coupling_add_entity(int f_id); 628 629 /*----------------------------------------------------------------------------*/ 630 /*! 631 * \brief Add contribution from coupled faces (internal coupling) to 632 * initialisation for iterative scalar gradient calculation. 633 * 634 * \param[in] cpl pointer to coupling entity 635 * \param[in] c_weight weighted gradient coefficient variable, or NULL 636 * \param[in] pvar variable 637 * \param[in, out] grad gradient 638 */ 639 /*----------------------------------------------------------------------------*/ 640 641 void 642 cs_internal_coupling_initialize_scalar_gradient( 643 const cs_internal_coupling_t *cpl, 644 const cs_real_t c_weight[], 645 const cs_real_t pvar[], 646 cs_real_3_t *restrict grad); 647 648 /*----------------------------------------------------------------------------*/ 649 /*! 650 * \brief Add contribution from coupled faces (internal coupling) to 651 * initialisation for iterative vector gradient calculation 652 * 653 * \param[in] cpl pointer to coupling entity 654 * \param[in] c_weight weighted gradient coefficient variable, or NULL 655 * \param[in] pvar variable 656 * \param[in, out] grad gradient 657 */ 658 /*----------------------------------------------------------------------------*/ 659 660 void 661 cs_internal_coupling_initialize_vector_gradient( 662 const cs_internal_coupling_t *cpl, 663 const cs_real_t c_weight[], 664 const cs_real_3_t pvar[], 665 cs_real_33_t *restrict grad); 666 667 668 /*----------------------------------------------------------------------------*/ 669 /*! 670 * \brief Add contribution from coupled faces (internal coupling) to 671 * initialisation for iterative symmetric tensor gradient calculation 672 * 673 * \param[in] cpl pointer to coupling entity 674 * \param[in] c_weight weighted gradient coefficient variable, or NULL 675 * \param[in, out] pvar variable 676 * \param[in, out] grad gradient 677 */ 678 /*----------------------------------------------------------------------------*/ 679 680 void 681 cs_internal_coupling_initialize_tensor_gradient( 682 const cs_internal_coupling_t *cpl, 683 const cs_real_t c_weight[], 684 const cs_real_6_t pvar[], 685 cs_real_63_t *restrict grad); 686 687 /*----------------------------------------------------------------------------*/ 688 /*! 689 * \brief Update internal coupling coefficients of the field of the 690 * given id using given boundary exchange coefficients passed by face id. 691 * 692 * \param[in] field_id field id 693 * \param[in] hbnd boundary exchange coefficients passed by face id 694 */ 695 /*----------------------------------------------------------------------------*/ 696 697 void 698 cs_ic_field_set_exchcoeff(const int field_id, 699 const cs_real_t *hbnd); 700 701 /*----------------------------------------------------------------------------*/ 702 /*! 703 * \brief Get distant data using face id at all coupling faces for a given 704 * field id. 705 * 706 * \param[in] field_id field id 707 * \param[in] stride number of values (interlaced) by entity 708 * \param[in] tab_distant exchanged data by face id 709 * \param[out] tab_local local data by face id 710 */ 711 /*----------------------------------------------------------------------------*/ 712 713 void 714 cs_ic_field_dist_data_by_face_id(const int field_id, 715 int stride, 716 const cs_real_t tab_distant[], 717 cs_real_t tab_local[]); 718 719 /*----------------------------------------------------------------------------*/ 720 721 END_C_DECLS 722 723 #endif /* __CS_INTERNAL_COUPLING_H__ */ 724