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