1 /*============================================================================
2 * Définitions des fonctions de base
3 * associées à la structure `ecs_maillage_t' décrivant un maillage.
4 *============================================================================*/
5
6 /*
7 This file is part of Code_Saturne, a general-purpose CFD tool.
8
9 Copyright (C) 1998-2021 EDF S.A.
10
11 This program is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free Software
13 Foundation; either version 2 of the License, or (at your option) any later
14 version.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19 details.
20
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
23 Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 */
25
26 /*----------------------------------------------------------------------------*/
27
28
29 /*============================================================================
30 * Visibilité
31 *============================================================================*/
32
33 #include "cs_config.h"
34
35
36 /*----------------------------------------------------------------------------
37 * Fichiers `include' librairie standard C
38 *----------------------------------------------------------------------------*/
39
40 #include <assert.h>
41
42
43 /*----------------------------------------------------------------------------
44 * Fichiers `include' système
45 *----------------------------------------------------------------------------*/
46
47 #include <stdlib.h>
48 #include <string.h>
49
50
51 /*----------------------------------------------------------------------------
52 * Fichiers `include' visibles du paquetage global "Utilitaire"
53 *----------------------------------------------------------------------------*/
54
55 #include "ecs_def.h"
56 #include "ecs_fic.h"
57 #include "ecs_file.h"
58 #include "ecs_mem.h"
59 #include "ecs_tab.h"
60
61
62 /*----------------------------------------------------------------------------
63 * Fichiers `include' publics du paquetage global "Post-Traitement"
64 *----------------------------------------------------------------------------*/
65
66 #include "ecs_post.h"
67
68
69 /*----------------------------------------------------------------------------
70 * Fichiers `include' visibles des paquetages visibles
71 *----------------------------------------------------------------------------*/
72
73 #include "ecs_famille_chaine.h"
74 #include "ecs_post.h"
75
76
77 /*----------------------------------------------------------------------------
78 * Fichiers `include' visibles du paquetage courant
79 *----------------------------------------------------------------------------*/
80
81 #include "ecs_table.h"
82 #include "ecs_table_def.h"
83 #include "ecs_table_att.h"
84 #include "ecs_table_post.h"
85 #include "ecs_maillage_post.h"
86
87
88 /*----------------------------------------------------------------------------
89 * Fichier `include' du paquetage courant associé au fichier courant
90 *----------------------------------------------------------------------------*/
91
92 #include "ecs_maillage.h"
93
94
95 /*----------------------------------------------------------------------------
96 * Fichiers `include' privés du paquetage courant
97 *----------------------------------------------------------------------------*/
98
99 #include "ecs_maillage_priv.h"
100
101
102 /*============================================================================
103 * Fonctions privées
104 *============================================================================*/
105
106 /*----------------------------------------------------------------------------
107 * Fonction d'impression d'une table avec position réglée en ASCII
108 *----------------------------------------------------------------------------*/
109
110 static void
_imprime_coords(FILE * f,size_t nbr,const ecs_coord_t val[],size_t nbr_imp)111 _imprime_coords(FILE *f,
112 size_t nbr,
113 const ecs_coord_t val[],
114 size_t nbr_imp)
115 {
116 /* Variables locales */
117
118 size_t ient;
119
120 size_t ind_ent_1 = 0;
121 size_t ind_ent_2;
122
123 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
124
125 assert(val != NULL);
126
127 ind_ent_2 = ECS_MIN(nbr, nbr_imp);
128
129 /* Impression des valeurs */
130 /*========================*/
131
132 while (1) {
133
134 for (ient = ind_ent_1; ient < ind_ent_2; ient++)
135 fprintf(f, "%24s %12lu %#12.5E %#12.5E %#12.5E\n",
136 " ", (unsigned long)(ient + 1), (double)val[3*ient],
137 (double)val[3*ient + 1], (double)val[3*ient + 2]);
138
139 if (ind_ent_2 == nbr)
140 break;
141
142 ind_ent_1 = ECS_MAX(nbr - nbr_imp, nbr_imp);
143
144 if (ind_ent_1 > ind_ent_2)
145
146 fprintf(f,
147 "%77s", "........... ........... ...........\n");
148
149 ind_ent_2 = nbr;
150
151 }
152 }
153
154 /*----------------------------------------------------------------------------
155 * Fonction d'impression des familles des éléments
156 *----------------------------------------------------------------------------*/
157
158 static void
_dump_elt_fam(FILE * f,size_t n_elts,const int elt_fam[],size_t nbr_imp)159 _dump_elt_fam(FILE *f,
160 size_t n_elts,
161 const int elt_fam[],
162 size_t nbr_imp)
163 {
164 /* Variables locales */
165
166 size_t i;
167
168 size_t i1 = 0;
169 size_t i2;
170
171 /* Instructions */
172
173 assert(elt_fam != NULL);
174
175 i2 = ECS_MIN(n_elts, nbr_imp);
176
177 /* Print values */
178 /*==============*/
179
180 while (1) {
181
182 for (i = i1; i < i2; i++)
183 fprintf(f, "%54s %10lu %10d\n", " ", (unsigned long)(i+1), elt_fam[i]);
184
185 if (i2 == n_elts)
186 break;
187
188 i1 = ECS_MAX(n_elts - nbr_imp, nbr_imp);
189
190 if (i1 > i2)
191 fprintf(f,
192 "%77s", "..........\n");
193
194 i2 = n_elts;
195
196 }
197 }
198
199 /*----------------------------------------------------------------------------
200 * Fonction d'impression des connectivités supplémentaires
201 *----------------------------------------------------------------------------*/
202
203 static void
_dump_connect_couples(FILE * f,size_t n_connect_couples,const ecs_int_t connect_couples[],size_t nbr_imp)204 _dump_connect_couples(FILE *f,
205 size_t n_connect_couples,
206 const ecs_int_t connect_couples[],
207 size_t nbr_imp)
208 {
209 /* Variables locales */
210
211 size_t i;
212
213 size_t i1 = 0;
214 size_t i2;
215
216 /* Instructions */
217
218 assert(connect_couples != NULL);
219
220 i2 = ECS_MIN(n_connect_couples, nbr_imp);
221
222 /* Print values */
223 /*==============*/
224
225 while (1) {
226
227 for (i = i1; i < i2; i++)
228 fprintf(f, "%50s %12ld %12ld\n", " ",
229 (long)connect_couples[i*2],
230 (long)connect_couples[i*2+1]);
231
232 if (i2 == n_connect_couples)
233 break;
234
235 i1 = ECS_MAX(n_connect_couples - nbr_imp, nbr_imp);
236
237 if (i1 > i2)
238 fprintf(f,
239 "%77s", "............\n");
240
241 i2 = n_connect_couples;
242
243 }
244 }
245
246 /*----------------------------------------------------------------------------
247 * Fonction qui selectionne tous les elements ou ceux appartenant a une liste
248 * Seules sont concernees les entites de type `entmail_sel'
249 *----------------------------------------------------------------------------*/
250
251 static bool *
_maillage__selectionne_lst(ecs_maillage_t * maillage,ecs_entmail_t entmail_sel,const ecs_tab_int_t * liste_filtre)252 _maillage__selectionne_lst(ecs_maillage_t *maillage,
253 ecs_entmail_t entmail_sel,
254 const ecs_tab_int_t *liste_filtre)
255 {
256 size_t nbr_elt;
257 size_t ielt;
258
259 bool *elt_select = NULL;
260
261 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
262
263 if (maillage->table_def[entmail_sel] != NULL) {
264
265 nbr_elt = ecs_table__ret_elt_nbr(maillage->table_def[entmail_sel]);
266
267 ECS_MALLOC(elt_select, nbr_elt, bool);
268
269 for (ielt = 0; ielt < nbr_elt; ielt++)
270 elt_select[ielt] = false;
271
272 }
273
274 if (liste_filtre == NULL) {
275
276 nbr_elt = ecs_table__ret_elt_nbr(maillage->table_def[entmail_sel]);
277
278 for (ielt = 0; ielt < nbr_elt; ielt++)
279 elt_select[ielt] = true;
280
281 }
282 else {
283
284 for (ielt = 0; ielt < liste_filtre->nbr; ielt++)
285 elt_select[liste_filtre->val[ielt]] = true;
286
287 }
288
289 return elt_select;
290 }
291
292 /*----------------------------------------------------------------------------
293 * Fonction qui détermine une nouveau table à partir d'une table de référence
294 * en extrayant de ce dernier les éléments sélectionnés
295 * par le tableau de booléens
296 *
297 * Cette fonction renvoie le tableau qui définit les anciens éléments
298 * du table de référence en fonction des nouveaux éléments du table renvoyé
299 *----------------------------------------------------------------------------*/
300
301 static ecs_tab_int_t
_maillage__extrait_coords(ecs_maillage_t * maillage_new,const ecs_maillage_t * maillage_ref,const bool elt_select[])302 _maillage__extrait_coords(ecs_maillage_t *maillage_new,
303 const ecs_maillage_t *maillage_ref,
304 const bool elt_select[])
305 {
306 size_t cpt_elt_new;
307 size_t cpt_val_new;
308 size_t nbr_elt_ref;
309 size_t nbr_val_ref;
310 size_t pos_ref_inf;
311 size_t pos_ref_sup;
312
313 size_t ielt_ref;
314 size_t ipos_ref;
315
316 ecs_tab_int_t tab_old_new;
317
318 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
319
320 nbr_elt_ref = maillage_ref->n_vertices;
321 nbr_val_ref = maillage_ref->n_vertices * 3;
322
323 maillage_new->n_vertices = maillage_ref->n_vertices;
324 ECS_MALLOC(maillage_new->vertex_coords, nbr_val_ref, ecs_coord_t);
325
326 tab_old_new.nbr = nbr_elt_ref;
327 ECS_MALLOC(tab_old_new.val, tab_old_new.nbr, ecs_int_t);
328
329 cpt_elt_new = 0;
330 cpt_val_new = 0;
331
332 for (ielt_ref = 0; ielt_ref < nbr_elt_ref; ielt_ref++) {
333
334 if (elt_select[ielt_ref] == true) {
335
336 /* L'élément est à extraire */
337
338 pos_ref_inf = 3 * ielt_ref;
339 pos_ref_sup = 3 * (ielt_ref + 1);
340
341 for (ipos_ref = pos_ref_inf; ipos_ref < pos_ref_sup; ipos_ref++)
342 maillage_new->vertex_coords[cpt_val_new++]
343 = maillage_ref->vertex_coords[ipos_ref];
344
345 tab_old_new.val[ielt_ref] = cpt_elt_new + 1;
346
347 cpt_elt_new++;
348
349 }
350 else {
351
352 tab_old_new.val[ielt_ref] = 0;
353
354 }
355 }
356
357 maillage_new->n_vertices = cpt_elt_new * 3;
358 ECS_REALLOC(maillage_new->vertex_coords,
359 maillage_new->n_vertices*3,
360 ecs_coord_t);
361
362 return tab_old_new;
363 }
364
365 /*----------------------------------------------------------------------------
366 * Fonction qui definit de nouvelles entites de maillage principales
367 * par extraction d'une partie des elements
368 * d'une entite de maillage principale donnee
369 * Les elements a extraire sont ceux qui ont un booleen a `true'
370 *----------------------------------------------------------------------------*/
371
372 static ecs_maillage_t *
_maillage__extrait(ecs_maillage_t * maillage,ecs_entmail_t entmail,bool elt_select[])373 _maillage__extrait(ecs_maillage_t *maillage,
374 ecs_entmail_t entmail,
375 bool elt_select[])
376 {
377 size_t isom;
378 ecs_tab_int_t tab_som_old_new;
379
380 bool *som_select = NULL;
381
382 ecs_maillage_t *maillage_new;
383
384 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
385
386 assert(maillage != NULL);
387
388 /* Initialisations */
389 /*-----------------*/
390
391 tab_som_old_new.nbr = 0;
392 tab_som_old_new.val = NULL;
393
394 maillage_new = ecs_maillage__cree_nodal();
395
396 /* Construction de la connectivité du nouveau maillage extrait */
397 /*-------------------------------------------------------------*/
398
399 /* Extraction des elements sélectionnés de l'entite de maillage
400 (qui sont renumerotés à partir de 1 mais qui sont toujours
401 définis par les sous-éléments non renumérotés)
402 Creation d'une table donnant pour chaque ancien numero de l'élément
403 avant extraction le nouveau numéro de l'élément selectionné et
404 renumeroté a partir de 1 */
405
406 maillage_new->table_def[entmail]
407 = ecs_table__extrait(maillage->table_def[entmail],
408 elt_select);
409
410 /* Traitement des sommets */
411 /*------------------------*/
412
413 /* Construction de la liste de selection des sommets a extraire */
414
415 ECS_MALLOC(som_select, maillage->n_vertices, bool);
416
417 for (isom = 0; isom < maillage->n_vertices; isom++)
418 som_select[isom] = false;
419
420 ecs_table_def__cree_masque(som_select,
421 maillage_new->table_def[entmail]);
422
423 /* Extraction des sommets selectionnés
424 Création d'une table donnant
425 pour chaque ancien numéro du sommet avant extraction
426 le nouveau numéro du sommet selectionné et renumeroté à partir de 1 */
427
428 tab_som_old_new = _maillage__extrait_coords(maillage_new,
429 maillage,
430 som_select);
431
432 ECS_FREE(som_select);
433
434 /* Remplacement des anciens numéros des sommets
435 par les nouveaux numéros (numérotés à partir de 1)
436 dans la définition des éléments */
437
438 ecs_table_def__remplace_ref(maillage_new->table_def[entmail],
439 &tab_som_old_new);
440
441 tab_som_old_new.nbr = 0;
442 ECS_FREE(tab_som_old_new.val);
443
444 /* On renvoie le maillage extrait */
445 /*--------------------------------*/
446
447 return maillage_new;
448 }
449
450 /*----------------------------------------------------------------------------
451 * Concaténation de deux ensembles de sommets.
452 *----------------------------------------------------------------------------*/
453
454 static void
_maillage__concat_vtx(ecs_maillage_t * maillage,ecs_maillage_t * maillage_concat)455 _maillage__concat_vtx(ecs_maillage_t *maillage,
456 ecs_maillage_t *maillage_concat)
457 {
458 size_t n_vertices_ini;
459
460 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
461
462 assert(maillage != NULL);
463 assert(maillage_concat != NULL);
464
465 n_vertices_ini = maillage->n_vertices;
466
467 maillage->n_vertices += maillage_concat->n_vertices;
468 ECS_REALLOC(maillage->vertex_coords,
469 maillage->n_vertices * 3,
470 ecs_coord_t);
471
472 memcpy(maillage->vertex_coords + (n_vertices_ini*3),
473 maillage_concat->vertex_coords,
474 maillage_concat->n_vertices * 3 * sizeof(ecs_coord_t));
475
476 /* Remove corresponding data from appended mesh */
477
478 maillage_concat->n_vertices = 0;
479 ECS_FREE(maillage_concat->vertex_coords);
480 }
481
482 /*----------------------------------------------------------------------------
483 * Concaténation de deux ensembles de connectivités.
484 *----------------------------------------------------------------------------*/
485
486 static void
_maillage__concat_connect(ecs_maillage_t * maillage,ecs_maillage_t * maillage_concat,ecs_entmail_t entmail)487 _maillage__concat_connect(ecs_maillage_t *maillage,
488 ecs_maillage_t *maillage_concat,
489 ecs_entmail_t entmail)
490 {
491 size_t n_couples_concat;
492
493 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
494
495 assert(maillage != NULL);
496 assert(maillage_concat != NULL);
497
498 n_couples_concat = maillage_concat->n_connect_couples[entmail];
499
500 if (n_couples_concat > 0) {
501
502 size_t i;
503 size_t n_couples = maillage->n_connect_couples[entmail];
504 size_t concat_shift = ecs_table__ret_elt_nbr(maillage->table_def[entmail]);
505 ecs_int_t *dest = NULL;
506 const ecs_int_t *src = maillage_concat->connect_couples[entmail];
507
508 /* Update receiving mesh */
509
510 maillage->n_connect_couples[entmail] += n_couples_concat;
511 ECS_REALLOC(maillage->connect_couples[entmail],
512 maillage->n_connect_couples[entmail]*2,
513 ecs_int_t);
514
515 dest = maillage->connect_couples[entmail] + (n_couples*2);
516
517 for (i = 0; i < n_couples_concat*2; i++)
518 dest[i] = src[i] + concat_shift;
519
520 /* Remove corresponding data from appended mesh */
521
522 maillage_concat->n_connect_couples[entmail] = 0;
523 ECS_FREE(maillage_concat->connect_couples[entmail]);
524 }
525 }
526
527 /*----------------------------------------------------------------------------
528 * Fonction réalisant transformation des familles
529 * en fusionnant les familles des éléments qui sont identiquement
530 * transformés par le vecteur de transformation donné.
531 *
532 * Cette fonction inclut le prolongement du tableau des familles
533 * d'une liste d'éléments initiale vers une liste à compacter,
534 * ainsi que le compactage en question. Ceci permet de rendre ce
535 * prolongement implicite, et réduire la taille de tableau intermédiaire.
536 *
537 * Par construction préalable, on fait l'hypothèse qu'un seul un de chaque
538 * ensemble d'éléments fusionnés porte une famille.
539 *----------------------------------------------------------------------------*/
540
541 static void
_maillage_elt_fam_fusionne(int ** elt_fam,size_t nbr_elt_old,size_t nbr_elt_new,const ecs_tab_int_t vect_transf)542 _maillage_elt_fam_fusionne(int **elt_fam,
543 size_t nbr_elt_old,
544 size_t nbr_elt_new,
545 const ecs_tab_int_t vect_transf)
546 {
547 ecs_int_t ind_elt_transf;
548 int val_ref;
549
550 size_t ielt;
551 size_t ielt_ref;
552
553 int *elt_fam_new = NULL;
554
555 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
556
557 if (elt_fam == NULL)
558 return;
559
560 if (*elt_fam == NULL)
561 return;
562
563 ECS_MALLOC(elt_fam_new, nbr_elt_new, int);
564 for (ielt = 0; ielt < nbr_elt_new; ielt++)
565 elt_fam_new[ielt] = 0;
566
567 for (ielt_ref = 0; ielt_ref < nbr_elt_old; ielt_ref++) {
568
569 ind_elt_transf = vect_transf.val[ielt_ref];
570 assert(ind_elt_transf > -1);
571
572 val_ref = (*elt_fam)[ielt_ref];
573
574 if (val_ref != 0 && elt_fam_new[ind_elt_transf] == 0)
575 elt_fam_new[ind_elt_transf] = val_ref;
576
577 }
578
579 ECS_FREE(*elt_fam);
580 *elt_fam = elt_fam_new;
581 }
582
583 /*----------------------------------------------------------------------------
584 * Update element family numbers when elements are renumbered. Each
585 * initial element has at most one matching element.
586 *----------------------------------------------------------------------------*/
587
588 static void
_maillage_elt_fam_compacte(int ** elt_fam,ecs_tab_int_t * tab_old_new)589 _maillage_elt_fam_compacte(int **elt_fam,
590 ecs_tab_int_t *tab_old_new)
591 {
592 size_t ielt;
593 ecs_int_t num_elt_new;
594
595 ecs_int_t cpt_elt = 0;
596 int *_elt_fam = NULL;
597
598 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
599
600 if (elt_fam == NULL)
601 return;
602
603 if (*elt_fam == NULL)
604 return;
605
606 /* Compact numbering */
607
608 _elt_fam = *elt_fam;
609
610 for (ielt = 0; ielt < tab_old_new->nbr; ielt++) {
611
612 num_elt_new = tab_old_new->val[ielt];
613
614 if (num_elt_new != 0) {
615 assert(num_elt_new == cpt_elt + 1);
616 _elt_fam[num_elt_new - 1] = _elt_fam[ielt];
617 cpt_elt += 1;
618 }
619
620 }
621
622 /* Update definitions */
623
624 ECS_REALLOC(_elt_fam, cpt_elt, int);
625
626 *elt_fam = _elt_fam;
627 }
628
629 /*----------------------------------------------------------------------------
630 * Suppression des éléments dégénérés
631 *----------------------------------------------------------------------------*/
632
633 static void
_maillage__nettoie_descend(ecs_maillage_t * maillage)634 _maillage__nettoie_descend(ecs_maillage_t *maillage)
635 {
636 ecs_tab_int_t tab_fac_old_new;
637
638 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
639
640 assert(maillage != NULL);
641
642 if (maillage->table_def[ECS_ENTMAIL_FAC] == NULL)
643 return;
644
645 /* Faces */
646 /*-------*/
647
648 tab_fac_old_new
649 = ecs_table_def__nettoie_fac(maillage->table_def[ECS_ENTMAIL_FAC]);
650
651 if (tab_fac_old_new.nbr != 0) {
652
653 /* Inherit "family" fields */
654
655 assert(maillage->table_att[ECS_ENTMAIL_FAC] == NULL);
656
657 _maillage_elt_fam_compacte(&(maillage->elt_fam[ECS_ENTMAIL_FAC]),
658 &tab_fac_old_new);
659
660 /* Replace references in face definitions */
661
662 if (maillage->table_def[ECS_ENTMAIL_CEL] != NULL)
663 ecs_table_def__remplace_ref(maillage->table_def[ECS_ENTMAIL_CEL],
664 &tab_fac_old_new);
665
666 tab_fac_old_new.nbr = 0;
667 ECS_FREE(tab_fac_old_new.val);
668 }
669 }
670
671 /*----------------------------------------------------------------------------
672 * Fonction qui construit la liste des faces avec erreur de connectivité
673 * (i.e. qui appartiennent à 2 cellules ou plus vu d'un même côté, ou qui
674 * sont à la fois entrante et sortante pour une cellule).
675 *
676 * Un tableau indiquant le type associé à chaque face (0 pour face isolée,
677 * 1 ou 2 pour face de bord, 3 pour face interne, et 4 pour tous les autres
678 * cas (faces voyant au moins deux cellules sur un même côté, d'ou erreur
679 * de connectivité) doit être fourni en entrée.
680 *----------------------------------------------------------------------------*/
681
682 static void
_maillage__liste_fac_err(const ecs_tab_int_t * typ_fac,ecs_tab_int_t * liste_fac_erreur)683 _maillage__liste_fac_err(const ecs_tab_int_t *typ_fac,
684 ecs_tab_int_t *liste_fac_erreur)
685 {
686 size_t cpt_fac_erreur;
687 size_t ifac;
688
689 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
690
691 assert(typ_fac != NULL);
692 assert(liste_fac_erreur != NULL);
693
694 /* Initialisations */
695
696 cpt_fac_erreur = 0;
697
698 /* Première boucle sur les faces : comptage */
699 /*------------------------------------------*/
700
701 for (ifac = 0; ifac < typ_fac->nbr; ifac++) {
702 if (typ_fac->val[ifac] >= 4)
703 cpt_fac_erreur++;
704 }
705
706 /* Initialisation et allocation de la liste */
707
708 liste_fac_erreur->nbr = cpt_fac_erreur;
709 ECS_MALLOC(liste_fac_erreur->val, liste_fac_erreur->nbr, ecs_int_t);
710
711 /* Seconde boucle sur les faces : remplissage des listes */
712 /*-------------------------------------------------------*/
713
714 cpt_fac_erreur = 0;
715
716 for (ifac = 0; ifac < typ_fac->nbr; ifac++) {
717 if (typ_fac->val[ifac] >= 4)
718 liste_fac_erreur->val[cpt_fac_erreur++] = ifac;
719 }
720 }
721
722 /*----------------------------------------------------------------------------
723 * Fonction qui compte le nombre de faces internes et de bord, ainsi que
724 * le nombre de faces avec erreur de connectivité (i.e. qui appartiennent
725 * à 2 cellules ou plus vu d'un même côté, ou qui sont à la fois entrante
726 * et sortante pour une cellule) et de faces isolées.
727 *
728 * Un tableau indiquant le type associé à chaque face (0 pour face isolée,
729 * 1 ou 2 pour face de bord, 3 pour face interne, et >= 4 pour tous les autres
730 * cas (faces voyant au moins deux cellules sur un même côté, d'ou erreur
731 * de connectivité) doit être fourni en entrée.
732 *----------------------------------------------------------------------------*/
733
734 static void
_maillage__compte_typ_fac(const ecs_tab_int_t * typ_fac,size_t * nbr_fac_erreur,size_t * nbr_fac_interne,size_t * nbr_fac_de_bord,size_t * nbr_fac_isolee)735 _maillage__compte_typ_fac(const ecs_tab_int_t *typ_fac,
736 size_t *nbr_fac_erreur,
737 size_t *nbr_fac_interne,
738 size_t *nbr_fac_de_bord,
739 size_t *nbr_fac_isolee)
740 {
741 size_t ifac;
742
743 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
744
745 assert(typ_fac != NULL);
746
747 /* Initialisations */
748
749 *nbr_fac_erreur = 0;
750 *nbr_fac_interne = 0;
751 *nbr_fac_de_bord = 0;
752 *nbr_fac_isolee = 0;
753
754 /* Boucle sur les faces : comptage */
755 /*---------------------------------*/
756
757 for (ifac = 0; ifac < typ_fac->nbr; ifac++) {
758
759 switch(typ_fac->val[ifac]) {
760
761 case 0:
762 *nbr_fac_isolee += 1;
763 break;
764
765 case 1:
766 case 2:
767 *nbr_fac_de_bord += 1;
768 break;
769
770 case 3:
771 *nbr_fac_interne += 1;
772 break;
773
774 default:
775 *nbr_fac_erreur += 1;
776
777 }
778 }
779
780 if (*nbr_fac_erreur != 0) {
781 ecs_warn();
782 printf(_("There are %lu faces of which one same side belongs\n"
783 "to at least 2 cells --> bad connectivity."),
784 (unsigned long)(*nbr_fac_erreur));
785 }
786
787 if (*nbr_fac_isolee != 0) {
788 ecs_warn();
789 printf(_("There is/are %lu isolated face(s)\n"),
790 (unsigned long)(*nbr_fac_isolee));
791 }
792 }
793
794 /*----------------------------------------------------------------------------
795 * Fonction réalisant la transformation d'un vecteur indexé
796 * en appliquant directement le vecteur de transformation donné
797 * sur les valeurs associées à ses éléments
798 *----------------------------------------------------------------------------*/
799
800 static void
_maillage_renum_connect(ecs_maillage_t * maillage,ecs_entmail_t entmail,const ecs_tab_int_t vect_transf)801 _maillage_renum_connect(ecs_maillage_t *maillage,
802 ecs_entmail_t entmail,
803 const ecs_tab_int_t vect_transf)
804 {
805 size_t n_couples, i, j;
806 ecs_int_t c1, c2;
807 ecs_int_t *connect;
808
809 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
810
811 assert(maillage != NULL);
812
813 if (maillage->connect_couples[entmail] == NULL)
814 return;
815
816 n_couples = maillage->n_connect_couples[entmail];
817 connect = maillage->connect_couples[entmail];
818
819 for (i = 0, j = 0; i < n_couples; i++) {
820 assert(connect[i*2] > 0 && connect[i*2 + 1] > 0);
821 c1 = ECS_ABS(vect_transf.val[connect[i*2] - 1]);
822 c2 = ECS_ABS(vect_transf.val[connect[i*2 + 1] - 1]);
823 if (c1 != c2 && c1 > 0 && c2 > 0) {
824 connect[j++] = c1;
825 connect[j++] = c2;
826 }
827 }
828
829 if (j < n_couples*2) {
830 maillage->n_connect_couples[entmail] = j/2;
831 ECS_REALLOC(maillage->connect_couples[entmail], j, ecs_int_t);
832 }
833 }
834
835 /*============================================================================
836 * Fonctions publiques
837 *============================================================================*/
838
839 /*----------------------------------------------------------------------------
840 * Define a new empty mesh structure with nodal connectivity.
841 *----------------------------------------------------------------------------*/
842
843 ecs_maillage_t *
ecs_maillage__cree_nodal(void)844 ecs_maillage__cree_nodal(void)
845 {
846 int ient;
847 ecs_maillage_t *maillage = NULL;
848
849 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
850
851 /* Structure globale du maillage */
852 /*-------------------------------*/
853
854 /* Allocation de la structure globale du maillage */
855
856 ECS_MALLOC(maillage, 1, ecs_maillage_t);
857
858 /* Initialisation du type de connectivité par défaut */
859
860 maillage->typ_connect = ECS_MAILLAGE_CONNECT_NODALE;
861
862 /* Entités de maillage */
863 /*---------------------*/
864
865 maillage->vertex_coords = NULL;
866
867 for (ient = 0; ient < 2; ient++) {
868 maillage->table_def[ient] = NULL;
869 maillage->table_att[ient] = NULL;
870 maillage->elt_fam[ient] = NULL;
871 maillage->n_connect_couples[ient] = 0;
872 maillage->connect_couples[ient] = NULL;
873 maillage->famille[ient] = NULL;
874 }
875
876 return maillage;
877 }
878
879 /*----------------------------------------------------------------------------
880 * Free a mesh structure.
881 *----------------------------------------------------------------------------*/
882
883 void
ecs_maillage__detruit(ecs_maillage_t ** maillage)884 ecs_maillage__detruit(ecs_maillage_t **maillage)
885 {
886 int ient;
887 ecs_maillage_t *m = *maillage;
888
889 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
890
891 /* Structures des entités de maillage */
892 /*====================================*/
893
894 if (m->vertex_coords != NULL)
895 ECS_FREE(m->vertex_coords);
896
897 for (ient = 0; ient < 2; ient++) {
898 if (m->table_def[ient] != NULL)
899 ecs_table__detruit(&m->table_def[ient]);
900 if (m->table_att[ient] != NULL)
901 ecs_table__detruit(&m->table_att[ient]);
902 if (m->elt_fam[ient] != NULL)
903 ECS_FREE(m->elt_fam[ient]);
904 if (m->connect_couples[ient] != NULL)
905 ECS_FREE(m->connect_couples[ient]);
906 if (m->famille[ient] != NULL)
907 ecs_famille_chaine__detruit(&(m->famille[ient]));
908 }
909
910 ECS_FREE(*maillage);
911 }
912
913 /*----------------------------------------------------------------------------
914 * Fonction imprimant le contenu d'une structure `ecs_maillage_t' donnée
915 * dans le fichier preprocessor_dump.txt
916 *----------------------------------------------------------------------------*/
917
918 void
ecs_maillage__imprime(const ecs_maillage_t * maillage,const ecs_int_t nbr_imp)919 ecs_maillage__imprime(const ecs_maillage_t *maillage,
920 const ecs_int_t nbr_imp)
921 {
922 const char *nom_typ_c[2] = {
923 "ECS_MAILLAGE_CONNECT_NODALE",
924 "ECS_MAILLAGE_CONNECT_DESCENDANTE"
925 };
926
927 const char *nom_table_def[2] = {
928 "FACE_DEFS",
929 "CELL_DEFS"
930 };
931
932 const char *nom_table_att[2] = {
933 "FACE_GROUPS",
934 "CELL_GROUPS"
935 };
936
937 const char *nom_elt_fam[2] = {
938 "FACE_FAMILIES",
939 "CELL_FAMILIES"
940 };
941
942 const char *nom_connect[2] = {
943 "FACE_CONNECTIVITY",
944 "CELL_CONNECTIVITY"
945 };
946
947 const char *nom_fam[2] = {
948 "FACE_FAMILIES",
949 "CELL_FAMILIES"
950 };
951
952 FILE *f;
953 ecs_int_t imp_col;
954 ecs_int_t ient;
955
956 #define ECS_FCT_IMP_MAILLAGE_FAMILLE "famille"
957
958 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
959
960 assert(maillage != NULL);
961
962 imp_col = 0;
963
964 /* Ouverture du fichier d'impression */
965 /*===================================*/
966
967 f = fopen("preprocessor_dump.txt", "w");
968
969 /* Message sur la sortie standard */
970 /*================================*/
971
972 printf("\n\nMesh structure after reading input\n\n");
973
974 /* Connectivity type */
975 /*-------------------*/
976
977 ecs_fic__imprime_val(f, imp_col, "typ_connect",
978 ECS_TYPE_char, nom_typ_c[maillage->typ_connect]);
979
980 /* Vertices */
981 /*----------*/
982
983 ecs_fic__imprime_val(f, imp_col, "n_vertices",
984 ECS_TYPE_size_t,
985 &(maillage->n_vertices));
986
987 ecs_fic__imprime_ptr(f, imp_col,
988 "VERTEX_COORDS",
989 maillage->vertex_coords);
990
991 if (maillage->vertex_coords != NULL)
992 _imprime_coords(f,
993 maillage->n_vertices,
994 maillage->vertex_coords,
995 nbr_imp);
996
997 /* Element definitions and attributes */
998 /*------------------------------------*/
999
1000 for (ient = 0; ient < ECS_N_ENTMAIL; ient++) {
1001
1002 /* Main definitions */
1003
1004 ecs_fic__imprime_ptr(f, imp_col,
1005 nom_table_def[ient],
1006 maillage->table_def[ient]);
1007
1008 if (maillage->table_def[ient] != NULL)
1009 ecs_table__imprime(maillage->table_def[ient],
1010 imp_col+1,
1011 nbr_imp,
1012 f);
1013
1014 /* Groups */
1015
1016 ecs_fic__imprime_ptr(f, imp_col,
1017 nom_table_att[ient],
1018 maillage->table_att[ient]);
1019
1020 if (maillage->table_att[ient] != NULL)
1021 ecs_table__imprime(maillage->table_att[ient],
1022 imp_col+1,
1023 nbr_imp,
1024 f);
1025
1026 /* Entity families */
1027
1028 ecs_fic__imprime_ptr(f, imp_col,
1029 nom_elt_fam[ient],
1030 maillage->elt_fam[ient]);
1031
1032 if (maillage->elt_fam[ient] != NULL)
1033 _dump_elt_fam(f,
1034 ecs_table__ret_elt_nbr(maillage->table_def[ient]),
1035 maillage->elt_fam[ient],
1036 nbr_imp);
1037
1038 /* Additional connectivity */
1039
1040 ecs_fic__imprime_val(f, imp_col, "n_connect_couples",
1041 ECS_TYPE_size_t,
1042 &(maillage->n_connect_couples[ient]));
1043
1044 ecs_fic__imprime_ptr(f, imp_col,
1045 nom_connect[ient],
1046 maillage->connect_couples[ient]);
1047
1048 if (maillage->n_connect_couples[ient] != 0)
1049 _dump_connect_couples(f,
1050 maillage->n_connect_couples[ient],
1051 maillage->connect_couples[ient],
1052 nbr_imp);
1053
1054 }
1055
1056 /* Family definitions */
1057 /*--------------------*/
1058
1059 for (ient = 0; ient < ECS_N_ENTMAIL; ient++) {
1060
1061 /* Impression du pointeur sur une entité principale */
1062
1063 ecs_fic__imprime_ptr(f, imp_col,
1064 nom_fam[ient],
1065 (void *)maillage->famille[ient]);
1066
1067 if (maillage->famille[ient] != NULL)
1068 ecs_famille_chaine__imprime(maillage->famille[ient],
1069 imp_col + 1,
1070 f);
1071 }
1072
1073 /* Close dump file */
1074 /*-----------------*/
1075
1076 fclose(f);
1077 }
1078
1079 /*----------------------------------------------------------------------------
1080 * Fonction qui retourne le type d'entité de plus grande dimension
1081 * contenue dans une structure `ecs_maillage_t'
1082 *----------------------------------------------------------------------------*/
1083
1084 ecs_entmail_t
ecs_maillage__ret_entmail_max(const ecs_maillage_t * maillage)1085 ecs_maillage__ret_entmail_max(const ecs_maillage_t *maillage)
1086 {
1087 ecs_entmail_t entmail_max = ECS_ENTMAIL_NONE;
1088 ecs_int_t ient;
1089
1090 for (ient = 0; ient < ECS_N_ENTMAIL; ient++) {
1091 if (maillage->table_def[ient] != NULL) {
1092 if (ecs_table__ret_elt_nbr(maillage->table_def[ient]) > 0)
1093 entmail_max = (ecs_entmail_t) ient;
1094 }
1095 }
1096
1097 return entmail_max;
1098 }
1099
1100 /*----------------------------------------------------------------------------
1101 * Fonction qui renvoie la taille en octets d'une structure `ecs_maillage_t'.
1102 *----------------------------------------------------------------------------*/
1103
1104 float
ecs_maillage__ret_taille(const ecs_maillage_t * maillage)1105 ecs_maillage__ret_taille(const ecs_maillage_t *maillage)
1106 {
1107 size_t taille;
1108 ecs_int_t ient;
1109
1110 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1111
1112 assert(maillage != NULL);
1113
1114 taille = sizeof(*maillage);
1115
1116 for (ient = 0; ient < ECS_N_ENTMAIL; ient++) {
1117
1118 if (maillage->table_def[ient] != NULL)
1119 taille += ecs_table__ret_taille(maillage->table_def[ient]);
1120
1121 if (maillage->table_att[ient] != NULL)
1122 taille += ecs_table__ret_taille(maillage->table_att[ient]);
1123
1124 if (maillage->elt_fam[ient] != NULL)
1125 taille += ( ecs_table__ret_elt_nbr(maillage->table_def[ient])
1126 * sizeof(int));
1127
1128 if (maillage->n_connect_couples[ient] != 0)
1129 taille += maillage->n_connect_couples[ient] * sizeof(ecs_int_t);
1130
1131 if (maillage->famille[ient] != NULL)
1132 taille += ecs_famille_chaine__ret_taille(maillage->famille[ient]);
1133 }
1134
1135 return (float)taille;
1136 }
1137
1138 /*----------------------------------------------------------------------------
1139 * Suppression des sommets ne participant pas à la connectivité
1140 * et fusion des éléments surfaciques confondus éventuels
1141 *----------------------------------------------------------------------------*/
1142
1143 void
ecs_maillage__nettoie_nodal(ecs_maillage_t * maillage)1144 ecs_maillage__nettoie_nodal(ecs_maillage_t *maillage)
1145 {
1146 size_t nbr_elt_new;
1147 ecs_tab_int_t vect_transf;
1148 ecs_tab_int_t signe_elt;
1149
1150 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1151
1152 /* Suppression des sommets inutiles */
1153
1154 if (maillage->vertex_coords != NULL)
1155 ecs_table_def__nettoie_nodal(&(maillage->n_vertices),
1156 &(maillage->vertex_coords),
1157 maillage->table_def[ECS_ENTMAIL_FAC],
1158 maillage->table_def[ECS_ENTMAIL_CEL]);
1159
1160 /*
1161 Fusion d'éléments surfaciques confondus éventuels (issus par exemple,
1162 de l'utilisation conjointe de references de faces et faces de bord
1163 sous Simail, double `surface coating' sous I-DEAS, ...)
1164 */
1165
1166 /*--------------------------------------------------------------------------*/
1167 /* Tri et compactage des definitions des elements */
1168 /* */
1169 /* Determination du vecteur de transformation permettant de passer */
1170 /* de la liste initiale des elements */
1171 /* a une liste ordonnee et compactee des elements */
1172 /*--------------------------------------------------------------------------*/
1173
1174 nbr_elt_new = 0;
1175
1176 signe_elt.nbr = 0;
1177 signe_elt.val = NULL;
1178
1179 if (maillage->table_def[ECS_ENTMAIL_FAC] == NULL)
1180 return;
1181
1182 vect_transf = ecs_table_def__fusionne(maillage->table_def[ECS_ENTMAIL_FAC],
1183 &nbr_elt_new,
1184 &signe_elt);
1185
1186 /* Tables de type attribut ou famille */
1187 /*------------------------------------*/
1188
1189 ecs_table_att__fusionne(maillage->table_att[ECS_ENTMAIL_FAC],
1190 nbr_elt_new,
1191 vect_transf);
1192
1193 assert(maillage->elt_fam[ECS_ENTMAIL_FAC] == NULL);
1194
1195 /* Table de type connectivité supplémentaire. */
1196 /*--------------------------------------------*/
1197
1198 if (maillage->n_connect_couples[ECS_ENTMAIL_FAC] != 0)
1199 _maillage_renum_connect(maillage,
1200 ECS_ENTMAIL_FAC,
1201 vect_transf);
1202
1203 ECS_FREE(signe_elt.val);
1204 ECS_FREE(vect_transf.val);
1205 }
1206
1207 /*----------------------------------------------------------------------------
1208 * Correction si nécessaire de l'orientation des éléments en
1209 * connectivité nodale.
1210 *
1211 * La liste de cellules avec erreur est optionnelle.
1212 *----------------------------------------------------------------------------*/
1213
1214 void
ecs_maillage__orient_nodal(ecs_maillage_t * maillage,ecs_tab_int_t * liste_cel_err,bool correc_orient)1215 ecs_maillage__orient_nodal(ecs_maillage_t *maillage,
1216 ecs_tab_int_t *liste_cel_err,
1217 bool correc_orient)
1218 {
1219 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1220
1221 if (maillage->vertex_coords == NULL)
1222 return;
1223
1224 ecs_table_def__orient_nodal(maillage->vertex_coords,
1225 maillage->table_def[ECS_ENTMAIL_FAC],
1226 maillage->table_def[ECS_ENTMAIL_CEL],
1227 liste_cel_err,
1228 correc_orient);
1229 }
1230
1231 /*----------------------------------------------------------------------------
1232 * Fonction qui assigne la tête de la liste chaînée des familles donnée
1233 * à la structure de maillage donnée
1234 *----------------------------------------------------------------------------*/
1235
1236 void
ecs_maillage__definit_famille(ecs_maillage_t * maillage,ecs_famille_t * vect_famille[2])1237 ecs_maillage__definit_famille(ecs_maillage_t *maillage,
1238 ecs_famille_t *vect_famille[2])
1239 {
1240 int ient;
1241
1242 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1243
1244 assert(maillage != NULL);
1245
1246 for (ient = 0; ient < ECS_N_ENTMAIL; ient++)
1247 maillage->famille[ient] = vect_famille[ient];
1248 }
1249
1250 /*----------------------------------------------------------------------------
1251 * Fonction réalisant, à partir d'une connectivité de maillage donnée,
1252 * la connectivité descendante du maillage
1253 *----------------------------------------------------------------------------*/
1254
1255 void
ecs_maillage__connect_descend(ecs_maillage_t * maillage)1256 ecs_maillage__connect_descend(ecs_maillage_t * maillage)
1257 {
1258 size_t nbr_elt_new;
1259 ecs_tab_int_t vect_transf;
1260 ecs_tab_int_t signe_elt;
1261
1262 ecs_size_t nbr_fac_old = 0;
1263
1264 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1265
1266 assert(maillage != NULL);
1267 assert(maillage->typ_connect == ECS_MAILLAGE_CONNECT_NODALE);
1268
1269 maillage->typ_connect = ECS_MAILLAGE_CONNECT_DESCENDANTE;
1270
1271 if (maillage->table_def[ECS_ENTMAIL_CEL] == NULL)
1272 return;
1273
1274 /* Decompose cells into faces */
1275 /*----------------------------*/
1276
1277 if (maillage->table_def[ECS_ENTMAIL_FAC] != NULL)
1278 nbr_fac_old = ecs_table__ret_elt_nbr(maillage->table_def[ECS_ENTMAIL_FAC]);
1279
1280 ecs_table_def__decompose_cel(&maillage->table_def[ECS_ENTMAIL_FAC],
1281 maillage->table_def[ECS_ENTMAIL_CEL]);
1282
1283 assert(maillage->table_att[ECS_ENTMAIL_FAC] == NULL);
1284
1285 /* Merge coincident vertices (update face connectivity ) */
1286 /*-------------------------------------------------------*/
1287
1288 ecs_table_def__nettoie_som_fac(&(maillage->n_vertices),
1289 &(maillage->vertex_coords),
1290 maillage->table_def[ECS_ENTMAIL_FAC]);
1291
1292 /* Merge faces with the same definition */
1293 /*--------------------------------------*/
1294
1295 nbr_elt_new = 0;
1296
1297 signe_elt.nbr = 0;
1298 signe_elt.val = NULL;
1299
1300 vect_transf = ecs_table_def__fusionne(maillage->table_def[ECS_ENTMAIL_FAC],
1301 &nbr_elt_new,
1302 &signe_elt);
1303
1304 /* Application du vecteur de transformation sur les autres tables */
1305 /*----------------------------------------------------------------*/
1306
1307 assert(maillage->table_att[ECS_ENTMAIL_FAC] == NULL);
1308
1309 _maillage_elt_fam_fusionne(&(maillage->elt_fam[ECS_ENTMAIL_FAC]),
1310 nbr_fac_old,
1311 nbr_elt_new,
1312 vect_transf);
1313
1314 _maillage_renum_connect(maillage,
1315 ECS_ENTMAIL_FAC,
1316 vect_transf);
1317
1318 /* Application du vecteur de transformation et du signe des elements
1319 sur la definition des cellules */
1320
1321 ecs_table__renumerote(maillage->table_def[ECS_ENTMAIL_CEL],
1322 vect_transf,
1323 signe_elt);
1324
1325 ECS_FREE(signe_elt.val);
1326 ECS_FREE(vect_transf.val);
1327
1328 /* Remove degenerate (empty) faces if present */
1329
1330 _maillage__nettoie_descend(maillage);
1331 }
1332
1333 /*----------------------------------------------------------------------------
1334 * Fonction réalisant le tri des éléments suivant leur type géométrique
1335 * La fonction affiche le nombre d'éléments par type géométrique
1336 *----------------------------------------------------------------------------*/
1337
1338 void
ecs_maillage__trie_typ_geo(ecs_maillage_t * maillage)1339 ecs_maillage__trie_typ_geo(ecs_maillage_t *maillage)
1340 {
1341 int ient;
1342 int dim_elt[2] = {2, 3};
1343 ecs_tab_int_t vect_renum;
1344
1345 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1346
1347 assert(maillage != NULL);
1348
1349 for (ient = 0; ient < ECS_N_ENTMAIL; ient++) {
1350
1351 /* Tri des types géometriques des éléments (si nécessaire) */
1352 /*---------------------------------------------------------*/
1353
1354 vect_renum.nbr = 0;
1355 vect_renum.val = NULL;
1356
1357 if (maillage->table_def[ient] != NULL)
1358
1359 vect_renum = ecs_table_def__trie_typ(maillage->table_def[ient],
1360 dim_elt[ient]);
1361
1362 /* Application du vecteur de renumerotation sur les autres tables */
1363 /*----------------------------------------------------------------*/
1364
1365 if (vect_renum.val != NULL) {
1366
1367 /* Inversion du tableau de renumerotation */
1368
1369 ecs_tab_int__inverse(&vect_renum);
1370
1371 /* Traitement de la table representant les définitions */
1372
1373 ecs_table__transforme_pos(maillage->table_def[ient],
1374 vect_renum.nbr,
1375 vect_renum);
1376
1377 /* Traitement des tables "attribut" */
1378
1379 ecs_table__transforme_pos(maillage->table_att[ient],
1380 vect_renum.nbr,
1381 vect_renum);
1382
1383 assert(maillage->elt_fam[ient] == NULL);
1384
1385 /* Traitement des connectivités supplémentaires */
1386
1387 _maillage_renum_connect(maillage,
1388 ient,
1389 vect_renum);
1390
1391 ECS_FREE(vect_renum.val);
1392
1393 } /* Fin : si le vecteur de renumerotation n'est pas NULL */
1394 }
1395 }
1396
1397 /*----------------------------------------------------------------------------
1398 * Fonction qui définit un nouveau maillage
1399 * par extraction d'une partie du maillage donné
1400 *
1401 * Les éléments à extraire doivent être tous de même dimension :
1402 * cellules ou faces ou arêtes ou sommets
1403 *----------------------------------------------------------------------------*/
1404
1405 ecs_maillage_t *
ecs_maillage__extrait(ecs_maillage_t * maillage,ecs_entmail_t entmail_sel,const ecs_tab_int_t * liste_filtre)1406 ecs_maillage__extrait(ecs_maillage_t *maillage,
1407 ecs_entmail_t entmail_sel,
1408 const ecs_tab_int_t *liste_filtre)
1409 {
1410 bool *elt_select = NULL;
1411 ecs_maillage_t *maillage_new = NULL;
1412
1413 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1414
1415 assert(maillage != NULL);
1416
1417 assert( maillage->typ_connect == ECS_MAILLAGE_CONNECT_NODALE
1418 || entmail_sel == ECS_ENTMAIL_FAC);
1419
1420 /* Construction de la liste des éléments du maillage d'origine à extraire */
1421 /*------------------------------------------------------------------------*/
1422
1423 elt_select = _maillage__selectionne_lst(maillage,
1424 entmail_sel,
1425 liste_filtre);
1426
1427 /* Extraction des éléments sélectionnés du maillage d'origine */
1428 /* pour l'ensemble des entités de maillage */
1429 /*------------------------------------------------------------*/
1430
1431 maillage_new = _maillage__extrait(maillage,
1432 entmail_sel,
1433 elt_select);
1434
1435 if (elt_select != NULL)
1436 ECS_FREE(elt_select);
1437
1438 return maillage_new;
1439 }
1440
1441 /*----------------------------------------------------------------------------
1442 * Fonction qui concatène dans un maillage récepteur donné,
1443 * un maillage à concaténer donné.
1444 *
1445 * Le maillage à concaténer est détruit.
1446 *----------------------------------------------------------------------------*/
1447
1448 void
ecs_maillage__concatene_nodal(ecs_maillage_t * maillage_recept,ecs_maillage_t * maillage_concat)1449 ecs_maillage__concatene_nodal(ecs_maillage_t *maillage_recept,
1450 ecs_maillage_t *maillage_concat)
1451 {
1452 ecs_int_t ient;
1453 ecs_int_t nbr_elt_concat = 0;
1454 ecs_int_t nbr_elt_recept = 0;
1455 ecs_int_t nbr_som_recept = 0;
1456
1457 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1458
1459 assert(maillage_recept != NULL);
1460 assert(maillage_concat != NULL);
1461
1462 assert(maillage_recept->typ_connect == ECS_MAILLAGE_CONNECT_NODALE);
1463 assert(maillage_concat->typ_connect == ECS_MAILLAGE_CONNECT_NODALE);
1464
1465 nbr_som_recept = maillage_recept->n_vertices;
1466
1467 /* Concaténation des sommets */
1468 /*----------------------------*/
1469
1470 _maillage__concat_vtx(maillage_recept,
1471 maillage_concat);
1472
1473 /* On doit avoir des attributs et non des familles à ce stade */
1474
1475 /* Concaténation des éléments */
1476 /*----------------------------*/
1477
1478 for (ient = 0; ient < ECS_N_ENTMAIL; ient++) {
1479
1480 assert( maillage_recept->elt_fam[ient] == NULL
1481 && maillage_concat->elt_fam[ient] == NULL);
1482
1483 /* Décalage des références des sommets */
1484
1485 if (maillage_concat->table_def[ient] != NULL) {
1486
1487 ecs_table__incremente_val(maillage_concat->table_def[ient],
1488 nbr_som_recept);
1489
1490 nbr_elt_recept = ecs_table__ret_elt_nbr(maillage_recept->table_def[ient]);
1491 nbr_elt_concat = ecs_table__ret_elt_nbr(maillage_concat->table_def[ient]);
1492
1493 if (nbr_elt_recept != 0) {
1494
1495 /* Définitions */
1496
1497 ecs_table__concatene(&maillage_recept->table_def[ient],
1498 &maillage_concat->table_def[ient],
1499 nbr_elt_recept,
1500 nbr_elt_concat);
1501
1502 ecs_table__detruit(&maillage_concat->table_def[ient]);
1503
1504 /* Groupes */
1505
1506 ecs_table__concatene(&maillage_recept->table_att[ient],
1507 &maillage_concat->table_att[ient],
1508 nbr_elt_recept,
1509 nbr_elt_concat);
1510
1511 ecs_table__detruit(&maillage_concat->table_att[ient]);
1512
1513 }
1514 else {
1515
1516 maillage_recept->table_def[ient] = maillage_concat->table_def[ient];
1517 maillage_recept->table_att[ient] = maillage_concat->table_att[ient];
1518 maillage_recept->elt_fam[ient] = maillage_concat->elt_fam[ient];
1519
1520 maillage_concat->table_def[ient] = NULL;
1521 maillage_concat->table_att[ient] = NULL;
1522 maillage_concat->elt_fam[ient] = NULL;
1523
1524 }
1525
1526 /* Connectivités supplémentaires */
1527
1528 _maillage__concat_connect(maillage_recept,
1529 maillage_concat,
1530 ient);
1531
1532 } /* else : rien à faire */
1533
1534 } /* Fin : boucle sur `ient' */
1535
1536 ecs_maillage__detruit(&maillage_concat);
1537 }
1538
1539 /*----------------------------------------------------------------------------
1540 * Fonction qui construit la liste des cellules attachées à une liste
1541 * de faces fournie en argument.
1542 *----------------------------------------------------------------------------*/
1543
1544 ecs_tab_int_t
ecs_maillage__liste_cel_fac(ecs_maillage_t * maillage,const ecs_tab_int_t liste_fac)1545 ecs_maillage__liste_cel_fac(ecs_maillage_t *maillage,
1546 const ecs_tab_int_t liste_fac)
1547 {
1548 size_t nbr_fac = 0;
1549
1550 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1551
1552 assert(maillage != NULL);
1553 assert(maillage->table_def[ECS_ENTMAIL_CEL] != NULL);
1554 assert(maillage->table_def[ECS_ENTMAIL_FAC] != NULL);
1555
1556 nbr_fac = ecs_table__ret_elt_nbr
1557 (maillage->table_def[ECS_ENTMAIL_FAC]);
1558
1559 return ecs_table_def__liste_cel_fac(nbr_fac,
1560 maillage->table_def[ECS_ENTMAIL_CEL],
1561 liste_fac);
1562 }
1563
1564 /*----------------------------------------------------------------------------
1565 * Fonction qui calcule les coordonnées min et max du domaine
1566 *----------------------------------------------------------------------------*/
1567
1568 void
ecs_maillage__calc_coo_ext(ecs_maillage_t * maillage)1569 ecs_maillage__calc_coo_ext(ecs_maillage_t *maillage)
1570 {
1571 size_t icoo, ipos, isom, nbr;
1572
1573 ecs_coord_t coo_min[3], coo_max[3];
1574
1575 const ecs_coord_t *vertex_coords = NULL;
1576
1577 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1578
1579 assert(maillage != NULL);
1580
1581 nbr = maillage->n_vertices;
1582 vertex_coords = maillage->vertex_coords;
1583
1584 if (nbr < 1)
1585 return;
1586
1587 assert(maillage->vertex_coords != NULL);
1588
1589 ipos = 0;
1590
1591 for (icoo = 0; icoo < 3; icoo++) {
1592 coo_min[icoo] = vertex_coords[ipos + icoo];
1593 coo_max[icoo] = vertex_coords[ipos + icoo];
1594 }
1595
1596 for (isom = 1; isom < nbr; isom++) {
1597
1598 ipos = 3 * isom;
1599
1600 for (icoo = 0; icoo < 3; icoo++) {
1601 if (vertex_coords[ipos + icoo] < coo_min[icoo])
1602 coo_min[icoo] = vertex_coords[ipos + icoo];
1603 else if (vertex_coords[ipos + icoo] > coo_max[icoo])
1604 coo_max[icoo] = vertex_coords[ipos + icoo];
1605 }
1606
1607 }
1608
1609 printf(_("\n Domain coordinate extents:\n\n"));
1610
1611 printf(" [% 10.5e, % 10.5e, % 10.5e]\n",
1612 coo_min[0], coo_min[1], coo_min[2]);
1613 printf(" [% 10.5e, % 10.5e, % 10.5e]\n",
1614 coo_max[0], coo_max[1], coo_max[2]);
1615 }
1616
1617 /*----------------------------------------------------------------------------
1618 * Fonction qui transforme les attributs en familles
1619 *----------------------------------------------------------------------------*/
1620
1621 void
ecs_maillage__cree_famille(ecs_maillage_t * maillage)1622 ecs_maillage__cree_famille(ecs_maillage_t *maillage)
1623 {
1624 int ient;
1625 ecs_int_t num_fam_deb;
1626 ecs_int_t ifam_ent;
1627
1628 ecs_table_t *table_att = NULL;
1629
1630 ecs_famille_t *vect_famille[2] = {NULL, NULL};
1631 int nbr_fam_ent[2] = {0, 0};
1632
1633 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1634
1635 /* Conctruction des familles */
1636
1637 num_fam_deb = 1;
1638
1639 /*------------------------*/
1640 /* Boucle sur les entites */
1641 /*------------------------*/
1642
1643 for (ient = ECS_ENTMAIL_CEL; ient >= ECS_ENTMAIL_FAC; ient--) {
1644
1645 /* Recuperation de l'adresse de la table des groupes */
1646
1647 table_att = maillage->table_att[ient];
1648
1649 if (table_att != NULL) {
1650
1651 maillage->table_att[ient] = NULL;
1652
1653 /*------------------------------------*/
1654 /* Construction des familles à partir */
1655 /* des tables "attribut" de l'entité */
1656 /*------------------------------------*/
1657
1658 maillage->elt_fam[ient]
1659 = ecs_table_att__construit_fam(&table_att,
1660 &(vect_famille[ient]),
1661 num_fam_deb,
1662 &(nbr_fam_ent[ient]));
1663
1664 num_fam_deb += nbr_fam_ent[ient];
1665
1666 } /* Fin : si il y a des tables "attribut" pour cette entité */
1667
1668 } /* Fin : boucle sur les entités de maillage */
1669
1670 /* Récupération des valeurs */
1671
1672 for (ifam_ent = 0; ifam_ent < ECS_N_ENTMAIL; ifam_ent++)
1673 maillage->famille[ifam_ent] = vect_famille[ifam_ent];
1674 }
1675
1676 /*----------------------------------------------------------------------------
1677 * Fonction qui détruit les familles
1678 *----------------------------------------------------------------------------*/
1679
1680 void
ecs_maillage__detruit_famille(ecs_maillage_t * maillage)1681 ecs_maillage__detruit_famille(ecs_maillage_t *maillage)
1682 {
1683 int ient;
1684
1685 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1686
1687 /* Destruction des tables "famille" et des familles */
1688 /*-------------------------------------------------*/
1689
1690 for (ient = 0; ient < ECS_N_ENTMAIL; ient++) {
1691
1692 ECS_FREE(maillage->elt_fam[ient]);
1693
1694 ecs_famille_chaine__detruit(&maillage->famille[ient]);
1695 }
1696 }
1697
1698 /*----------------------------------------------------------------------------
1699 * Fonction qui construit les attributs "groupe" à partir des familles
1700 *----------------------------------------------------------------------------*/
1701
1702 void
ecs_maillage__cree_attributs(ecs_maillage_t * maillage)1703 ecs_maillage__cree_attributs(ecs_maillage_t *maillage)
1704 {
1705 int ient;
1706
1707 ecs_famille_t *famille = NULL;
1708
1709 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1710
1711 /* Concaténation des familles des différentes entités */
1712
1713 famille = NULL;
1714
1715 for (ient = ECS_ENTMAIL_CEL; ient >= ECS_ENTMAIL_FAC; ient--) {
1716
1717 if (maillage->famille[ient] != NULL) {
1718
1719 ecs_famille_chaine__ajoute(&famille, maillage->famille[ient]);
1720
1721 maillage->famille[ient] = NULL;
1722
1723 }
1724 }
1725
1726 if (famille != NULL) {
1727
1728 for (ient = ECS_ENTMAIL_CEL; ient >= ECS_ENTMAIL_FAC; ient--) {
1729
1730 if (maillage->elt_fam[ient] != NULL ) {
1731
1732 assert(maillage->table_att[ient] == NULL);
1733
1734 /* Création de la table "groupe" */
1735
1736 maillage->table_att[ient]
1737 = ecs_table_att__cree_att_fam
1738 (ecs_table__ret_elt_nbr(maillage->table_def[ient]),
1739 maillage->elt_fam[ient],
1740 famille);
1741
1742 /* Libération des tableaux de familles */
1743
1744 ECS_FREE(maillage->elt_fam[ient]);
1745
1746 }
1747 }
1748 }
1749
1750 ecs_famille_chaine__detruit(&famille);
1751 }
1752
1753 /*----------------------------------------------------------------------------
1754 * Fonction qui supprime les attributs "groupe"
1755 *----------------------------------------------------------------------------*/
1756
1757 void
ecs_maillage__supprime_attributs(ecs_maillage_t * maillage)1758 ecs_maillage__supprime_attributs(ecs_maillage_t *maillage)
1759 {
1760 int ient;
1761
1762 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1763
1764 for (ient = 0; ient < ECS_N_ENTMAIL; ient++) {
1765
1766 if (maillage->table_att[ient] != NULL)
1767 ecs_table__detruit(&(maillage->table_att[ient]));
1768 }
1769 }
1770
1771 /*----------------------------------------------------------------------------
1772 * Vérification d'un maillage
1773 *----------------------------------------------------------------------------*/
1774
1775 bool
ecs_maillage__verif(ecs_maillage_t * maillage,ecs_post_t * cas_post)1776 ecs_maillage__verif(ecs_maillage_t *maillage,
1777 ecs_post_t *cas_post)
1778 {
1779 size_t nbr_cel, nbr_som;
1780 size_t nbr_fac_erreur, nbr_fac_interne, nbr_fac_de_bord, nbr_fac_isolee;
1781
1782 ecs_tab_int_t typ_fac_cel;
1783 ecs_tab_int_t liste_fac_erreur;
1784
1785 bool bool_coherent;
1786
1787 /*xxxxxxxxxxxxxxxxxxxxxxxxxxx Instructions xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
1788
1789 assert(maillage != NULL);
1790
1791 bool_coherent = true;
1792
1793 /* On vérifie qu'on est bien en connectivité descendante */
1794
1795 assert(maillage->typ_connect == ECS_MAILLAGE_CONNECT_DESCENDANTE);
1796
1797 assert(maillage->vertex_coords != NULL);
1798 assert(maillage->table_def[ECS_ENTMAIL_FAC] != NULL);
1799
1800 if (maillage->table_def[ECS_ENTMAIL_CEL] == NULL)
1801 return false;
1802
1803 /* Détermination du nombre de cellules et de faces */
1804
1805 nbr_cel = ecs_table__ret_elt_nbr(maillage->table_def[ECS_ENTMAIL_CEL]);
1806 nbr_som = maillage->n_vertices;
1807
1808 /* Determination du type de connectivité associé à chaque face */
1809
1810 typ_fac_cel
1811 = ecs_table_def__typ_fac_cel(maillage->table_def[ECS_ENTMAIL_CEL],
1812 maillage->table_def[ECS_ENTMAIL_FAC]);
1813
1814 _maillage__compte_typ_fac(&typ_fac_cel,
1815 &nbr_fac_erreur,
1816 &nbr_fac_interne,
1817 &nbr_fac_de_bord,
1818 &nbr_fac_isolee);
1819
1820 if (nbr_fac_erreur > 0)
1821 bool_coherent = false;
1822
1823 /* Affichage des infos sur les maillage */
1824 /*--------------------------------------*/
1825
1826 printf(_("\n\nMain mesh properties\n"
1827 "--------------------\n\n"));
1828
1829 printf(_(" Number of cells: %10d\n"
1830 " Number of internal faces: %10d\n"),
1831 (int)nbr_cel,
1832 (int)nbr_fac_interne);
1833
1834
1835 printf(_(" Number of boundary faces: %10d\n"),
1836 (int)nbr_fac_de_bord);
1837
1838
1839 if (nbr_som != 0)
1840 printf(_(" Number of vertices: %10d\n"),
1841 (int)nbr_som);
1842
1843 /* Construction des listes de faces en cas de post-traitement */
1844
1845 _maillage__liste_fac_err(&typ_fac_cel,
1846 &liste_fac_erreur);
1847
1848 typ_fac_cel.nbr = 0;
1849 ECS_FREE(typ_fac_cel.val);
1850
1851 /* Affichage des faces avec connectivité excessive */
1852
1853 if (liste_fac_erreur.nbr > 0) {
1854
1855 /* En case de faces avec erreur de connectivité,
1856 on effectue un post traitement pour analyse de problème */
1857
1858 ecs_maillage_post__ecr_fac_liste(_("Connectivity Error Faces"),
1859 maillage,
1860 liste_fac_erreur,
1861 ECS_POST_TYPE_ERREUR,
1862 cas_post);
1863
1864 ECS_FREE(liste_fac_erreur.val);
1865 liste_fac_erreur.nbr = 0;
1866
1867 }
1868
1869 return bool_coherent;
1870 }
1871
1872 /*----------------------------------------------------------------------------*/
1873
1874
1875