1 /*============================================================================
2  * Usage of MEDCoupling base components.
3  *============================================================================*/
4 
5 /*
6   This file is part of Code_Saturne, a general-purpose CFD tool.
7 
8   Copyright (C) 1998-2021 EDF S.A.
9 
10   This program is free software; you can redistribute it and/or modify it under
11   the terms of the GNU General Public License as published by the Free Software
12   Foundation; either version 2 of the License, or (at your option) any later
13   version.
14 
15   This program is distributed in the hope that it will be useful, but WITHOUT
16   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17   FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
18   details.
19 
20   You should have received a copy of the GNU General Public License along with
21   this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
22   Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 */
24 
25 /*----------------------------------------------------------------------------*/
26 
27 #include "cs_defs.h"
28 
29 /*----------------------------------------------------------------------------
30  * Standard C library headers
31  *----------------------------------------------------------------------------*/
32 
33 #include <stdarg.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <assert.h>
38 #include <math.h>
39 
40 #if defined(HAVE_MPI)
41 #include <mpi.h>
42 #endif
43 
44 /*----------------------------------------------------------------------------
45  *  Local headers
46  *----------------------------------------------------------------------------*/
47 
48 #include "bft_error.h"
49 #include "bft_mem.h"
50 #include "bft_printf.h"
51 
52 #include "cs_mesh.h"
53 #include "cs_mesh_connect.h"
54 #include "cs_parall.h"
55 #include "cs_prototypes.h"
56 #include "cs_selector.h"
57 #include "cs_timer.h"
58 
59 #include "fvm_defs.h"
60 #include "fvm_nodal_from_desc.h"
61 
62 /*----------------------------------------------------------------------------
63  *  Header for the current file
64  *----------------------------------------------------------------------------*/
65 
66 /*----------------------------------------------------------------------------
67  * MEDCOUPLING library headers
68  *----------------------------------------------------------------------------*/
69 
70 #include "cs_medcoupling_utils.hxx"
71 
72 #if defined(HAVE_MEDCOUPLING)
73 #include <MEDCoupling_version.h>
74 
75 #include <MEDCouplingUMesh.hxx>
76 #include <MEDCouplingField.hxx>
77 #include <MEDCouplingFieldDouble.hxx>
78 #include "MEDCouplingRemapper.hxx"
79 
80 using namespace MEDCoupling;
81 
82 #endif
83 
84 /*----------------------------------------------------------------------------*/
85 
86 BEGIN_C_DECLS
87 
88 /*! \cond DOXYGEN_SHOULD_SKIP_THIS */
89 
90 /*============================================================================
91  * Static global variables
92  *============================================================================*/
93 
94 static const cs_lnum_t _perm_tri[3]  = {0, 2, 1};
95 static const cs_lnum_t _perm_quad[4] = {0, 3, 2, 1};
96 static const cs_lnum_t _perm_pent[5] = {0, 4, 3, 2, 1};
97 
98 /*============================================================================
99  * Private function definitions
100  *============================================================================*/
101 
102 /*----------------------------------------------------------------------------*/
103 /*!
104  * \brief Get permutation array for a face given its number of vertices.
105  *
106  * \param[in] n_face_vertices number of vertices of the face
107  *
108  * \return    pointer to the permutation array
109  */
110 /*----------------------------------------------------------------------------*/
111 
112 static inline const cs_lnum_t *
_get_face_vertices_permutation(cs_lnum_t n_face_vertices)113 _get_face_vertices_permutation(cs_lnum_t  n_face_vertices)
114 {
115   const cs_lnum_t *perm = NULL;
116 
117   switch (n_face_vertices) {
118     case 3:
119       perm = _perm_tri;
120       break;
121     case 4:
122       perm = _perm_quad;
123       break;
124     case 5:
125       perm = _perm_pent;
126       break;
127     default:
128       perm = NULL;
129       break;
130   }
131 
132   return perm;
133 }
134 
135 #if defined(HAVE_MEDCOUPLING)
136 
137 /*----------------------------------------------------------------------------*/
138 /*!
139  * \brief   Assign vertex coordinates to a MEDCoupling mesh structure
140  *
141  * \param[in] mesh      pointer to cs_mesh_t structure from which data is copied
142  * \param[in] n_vtx     number of vertices to assign
143  * \param[in] vtx_id    pointer to vertices id's used for assigning
144  * \param[in] med_mesh  pointer to MEDCouplingUMesh to which we copy the
145  *                      coordinates
146  */
147 /*----------------------------------------------------------------------------*/
148 
149 static void
_assign_vertex_coords(const cs_mesh_t * mesh,cs_lnum_t n_vtx,const cs_lnum_t * vtx_id,MEDCouplingUMesh * med_mesh)150 _assign_vertex_coords(const cs_mesh_t    *mesh,
151                       cs_lnum_t           n_vtx,
152                       const cs_lnum_t    *vtx_id,
153                       MEDCouplingUMesh   *med_mesh)
154 {
155   const cs_lnum_t  dim = mesh->dim;
156   const cs_coord_t  *vertex_coords = mesh->vtx_coord;
157 
158   assert(med_mesh != NULL);
159 
160   /* Assign all coordinates */
161   /*------------------------*/
162 
163   DataArrayDouble *med_coords = DataArrayDouble::New();
164   med_coords->alloc(n_vtx, dim);
165 
166   if (vtx_id != NULL) {
167     for (cs_lnum_t i = 0; i < mesh->n_vertices; i++) {
168       if (vtx_id[i] > -1) {
169         for (cs_lnum_t j = 0; j < dim; j++) {
170           med_coords->setIJ(vtx_id[i], j, vertex_coords[i*dim + j]);
171         }
172       }
173     }
174   }
175   else {
176     for (cs_lnum_t i = 0; i < mesh->n_vertices; i++) {
177       for (cs_lnum_t j = 0; j < dim; j++)
178         med_coords->setIJ(i, j, vertex_coords[i*dim + j]);
179     }
180   }
181 
182   med_mesh->setCoords(med_coords);
183   med_coords->decrRef();
184 }
185 
186 /*----------------------------------------------------------------------------*/
187 /*!
188  * \brief   Assign boundary faces to a MEDCoupling mesh structure
189  *
190  * \param[in] mesh      pointer to cs_mesh_t structure from which data is copie
191  * \param[in] n_elts    number of faces to copy
192  * \param[in] elts_list list of faces to copy
193  * \param[in] med_mesh  pointer to MEDCouplingUMesh to which we copy the faces
194  */
195 /*----------------------------------------------------------------------------*/
196 
197 static void
_assign_face_mesh(const cs_mesh_t * mesh,cs_lnum_t n_elts,const cs_lnum_t * elts_list,MEDCouplingUMesh * med_mesh,cs_lnum_t new_to_old[])198 _assign_face_mesh(const cs_mesh_t   *mesh,
199                   cs_lnum_t          n_elts,
200                   const cs_lnum_t   *elts_list,
201                   MEDCouplingUMesh  *med_mesh,
202                   cs_lnum_t          new_to_old[])
203 {
204   INTERP_KERNEL::NormalizedCellType type;
205 
206   cs_lnum_t vtx_count = -1;
207   cs_lnum_t elt_buf_size = 4;
208   cs_lnum_t *vtx_id = NULL;
209 
210   /* Build old->new face id indirection */
211 
212   cs_lnum_t *face_id = NULL;
213   cs_lnum_t face_count = 0;
214   BFT_MALLOC(face_id, mesh->n_b_faces, cs_lnum_t);
215   for (cs_lnum_t i = 0; i < mesh->n_b_faces; i++)
216     face_id[i] = -1;
217 
218   for (cs_lnum_t i = 0; i < n_elts; i++) {
219     face_id[elts_list[i]] = face_count++;
220   }
221 
222   for (cs_lnum_t ii = 0; ii < n_elts; ii++) {
223     new_to_old[face_id[elts_list[ii]]] = elts_list[ii];
224   }
225   BFT_FREE(face_id);
226 
227   /* Mark and renumber vertices */
228 
229   BFT_MALLOC(vtx_id, mesh->n_vertices, cs_lnum_t);
230 
231   /* Initialize the value of vtx_id */
232   for (cs_lnum_t i = 0; i < mesh->n_vertices; i++)
233     vtx_id[i] = -1;
234 
235   /* Case with filter list */
236 
237   if (elts_list != NULL) {
238 
239     for (cs_lnum_t i = 0; i < n_elts; i++) {
240       cs_lnum_t eid = elts_list[i];
241       for (cs_lnum_t j = mesh->b_face_vtx_idx[eid];
242            j < mesh->b_face_vtx_idx[eid+1];
243            j++) {
244         cs_lnum_t vid = mesh->b_face_vtx_lst[j];
245         if (vtx_id[vid] < 0)
246           vtx_id[vid] = vtx_count++;
247       }
248     }
249 
250   }
251   else {
252 
253     for (cs_lnum_t i = 0; i < n_elts; i++) {
254       for (cs_lnum_t j = mesh->b_face_vtx_idx[i];
255            j < mesh->b_face_vtx_idx[i+1];
256            j++) {
257         cs_lnum_t vid = mesh->b_face_vtx_lst[j];
258         if (vtx_id[vid] < 0)
259           vtx_id[vid] = vtx_count++;
260       }
261     }
262 
263   }
264 
265   /* Assign coordinates */
266 
267   _assign_vertex_coords(mesh, vtx_count, vtx_id, med_mesh);
268 
269   /* Assign faces */
270 
271   mcIdType *elt_buf = NULL;
272   BFT_MALLOC(elt_buf, elt_buf_size, mcIdType);
273   med_mesh->allocateCells(n_elts);
274 
275   for (cs_lnum_t i = 0; i < n_elts; i++) {
276 
277     cs_lnum_t eid = (elts_list != NULL) ? elts_list[i] : i;
278 
279     assert(eid >= 0 && eid < mesh->n_b_faces);
280 
281     mcIdType n_vtx = mesh->b_face_vtx_idx[eid+1] - mesh->b_face_vtx_idx[eid];
282 
283     cs_lnum_t connect_start = mesh->b_face_vtx_idx[eid];
284 
285     if (n_vtx > elt_buf_size) { /* reallocate buffer if required */
286       elt_buf_size *= 2;
287       BFT_REALLOC(elt_buf, elt_buf_size, mcIdType);
288     }
289 
290     const cs_lnum_t *_perm_face = _get_face_vertices_permutation(n_vtx);
291     if (_perm_face != NULL) {
292       for (cs_lnum_t j = 0; j < n_vtx; j++)
293         elt_buf[j] = vtx_id[mesh->b_face_vtx_lst[connect_start + _perm_face[j]]];
294     }
295     else {
296       for (cs_lnum_t j = 0; j < n_vtx; j++)
297         elt_buf[j] = vtx_id[mesh->b_face_vtx_lst[connect_start + n_vtx - 1 - j]];
298     }
299     switch(n_vtx) {
300     case 3:
301       type = INTERP_KERNEL::NORM_TRI3;
302       break;
303     case 4:
304       type = INTERP_KERNEL::NORM_QUAD4;
305       break;
306     default:
307       type = INTERP_KERNEL::NORM_POLYGON;
308       break;
309     }
310 
311     med_mesh->insertNextCell(type, n_vtx, elt_buf);
312 
313   }
314 
315   med_mesh->finishInsertingCells();
316 
317   BFT_FREE(elt_buf);
318   BFT_FREE(vtx_id);
319 }
320 
321 /*----------------------------------------------------------------------------*/
322 /*!
323  * \brief   Assign cells to a MEDCoupling mesh structure
324  *
325  * \param[in] mesh        pointer to cs_mesh_t structure from which data is copied
326  * \param[in] n_elts      number of cells to assign
327  * \param[in] elts_list   list of cells to assign
328  * \param[in] med_mesh    pointer to MEDCouplingUMesh to which we copy the cells
329  * \param[in] new_to_old  indirection array between local mesh connectivity
330  *                        and MEDCouplingUMesh connectivity
331  */
332 /*----------------------------------------------------------------------------*/
333 
334 static void
_assign_cell_mesh(const cs_mesh_t * mesh,cs_lnum_t n_elts,const cs_lnum_t elts_list[],MEDCouplingUMesh * med_mesh,cs_lnum_t new_to_old[])335 _assign_cell_mesh(const cs_mesh_t   *mesh,
336                   cs_lnum_t          n_elts,
337                   const cs_lnum_t    elts_list[],
338                   MEDCouplingUMesh  *med_mesh,
339                   cs_lnum_t          new_to_old[])
340 {
341   INTERP_KERNEL::NormalizedCellType type;
342 
343   cs_lnum_t vtx_count = 0, cell_count = 0;
344 
345   cs_lnum_t  elt_buf_size = 8;
346   cs_lnum_t *vtx_id = NULL;
347   cs_lnum_t *cell_id = NULL;
348   cs_lnum_t *cell_faces_idx = NULL, *cell_faces_num = NULL;
349 
350   /* Build old->new cell id indirection */
351 
352   BFT_MALLOC(cell_id, mesh->n_cells, cs_lnum_t);
353   for (cs_lnum_t i = 0; i < mesh->n_cells; i++)
354     cell_id[i] = -1;
355 
356   for (cs_lnum_t i = 0; i < n_elts; i++) {
357     cell_id[elts_list[i]] = cell_count++;
358   }
359 
360   for (cs_lnum_t ii = 0; ii < n_elts; ii++) {
361     new_to_old[cell_id[elts_list[ii]]] = elts_list[ii];
362   }
363 
364   /* Mark and renumber vertices */
365 
366   BFT_MALLOC(vtx_id, mesh->n_vertices, cs_lnum_t);
367   for (cs_lnum_t vid = 0; vid < mesh->n_vertices; vid++) {
368     vtx_id[vid] = -1;
369   }
370 
371   for (cs_lnum_t face_id = 0; face_id < mesh->n_b_faces; face_id++) {
372     cs_lnum_t c_id = cell_id[mesh->b_face_cells[face_id]];
373     if (c_id > -1) {
374       for (cs_lnum_t j = mesh->b_face_vtx_idx[face_id];
375            j < mesh->b_face_vtx_idx[face_id+1];
376            j++) {
377         cs_lnum_t vid = mesh->b_face_vtx_lst[j];
378         if (vtx_id[vid] < 0)
379           vtx_id[vid] = vtx_count++;
380       }
381     }
382   }
383 
384   for (cs_lnum_t face_id = 0; face_id < mesh->n_i_faces; face_id++) {
385     cs_lnum_t c_id1 = mesh->i_face_cells[face_id][0];
386     cs_lnum_t c_id2 = mesh->i_face_cells[face_id][1];
387     c_id1 = (c_id1 < mesh->n_cells) ? cell_id[c_id1] : -1;
388     c_id2 = (c_id2 < mesh->n_cells) ? cell_id[c_id2] : -1;
389     if (c_id1 > -1 || c_id2 > -1) {
390       for (cs_lnum_t j = mesh->i_face_vtx_idx[face_id];
391            j < mesh->i_face_vtx_idx[face_id+1];
392            j++) {
393         cs_lnum_t vid = mesh->i_face_vtx_lst[j];
394         if (vtx_id[vid] < 0)
395           vtx_id[vid] = vtx_count++;
396       }
397     }
398   }
399 
400   /* Assign coordinates */
401 
402   _assign_vertex_coords(mesh, vtx_count, vtx_id, med_mesh);
403 
404   /* Build temporary descending connectivity */
405 
406   cs_mesh_connect_get_cell_faces(mesh,
407                                  mesh->n_cells, /* TODO test using n_elts */
408                                  cell_id,
409                                  &cell_faces_idx,
410                                  &cell_faces_num);
411 
412   BFT_FREE(cell_id);
413 
414   /* Now loop on cells */
415 
416   const cs_lnum_t  face_num_shift[2] = {0, mesh->n_b_faces};
417 
418   const cs_lnum_t  *face_vertices_idx[2] = {mesh->b_face_vtx_idx,
419                                             mesh->i_face_vtx_idx};
420   const cs_lnum_t  *face_vertices_num[2] = {mesh->b_face_vtx_lst,
421                                             mesh->i_face_vtx_lst};
422 
423   mcIdType *elt_buf = NULL;
424   BFT_MALLOC(elt_buf, elt_buf_size, mcIdType);
425   for (cs_lnum_t  ii = 0; ii < elt_buf_size; ii++)
426     elt_buf[ii] = -1;
427 
428   /* Allocate the cells array */
429   med_mesh->allocateCells(n_elts);
430 
431   for (cs_lnum_t ic = 0; ic < n_elts; ic++) {
432 
433     mcIdType  n_vtx;
434     cs_lnum_t cell_vtx[8];
435 
436     cs_lnum_t i = ic;
437 
438     fvm_element_t fvm_type = fvm_nodal_from_desc_cell(i,
439                                                       2,
440                                                       face_num_shift,
441                                                       face_vertices_idx,
442                                                       face_vertices_num,
443                                                       cell_faces_idx,
444                                                       cell_faces_num,
445                                                       cell_vtx);
446 
447     switch(fvm_type) {
448 
449     case FVM_CELL_TETRA:
450       type = INTERP_KERNEL::NORM_TETRA4;
451       n_vtx = 4;
452       elt_buf[0] = vtx_id[cell_vtx[0]-1];
453       elt_buf[1] = vtx_id[cell_vtx[2]-1];
454       elt_buf[2] = vtx_id[cell_vtx[1]-1];
455       elt_buf[3] = vtx_id[cell_vtx[3]-1];
456       break;
457 
458     case FVM_CELL_PYRAM:
459       type = INTERP_KERNEL::NORM_PYRA5;
460       n_vtx = 5;
461       elt_buf[0] = vtx_id[cell_vtx[0]-1];
462       elt_buf[1] = vtx_id[cell_vtx[3]-1];
463       elt_buf[2] = vtx_id[cell_vtx[2]-1];
464       elt_buf[3] = vtx_id[cell_vtx[1]-1];
465       elt_buf[4] = vtx_id[cell_vtx[4]-1];
466       break;
467 
468     case FVM_CELL_PRISM:
469       type = INTERP_KERNEL::NORM_PENTA6;
470       n_vtx = 6;
471       elt_buf[0] = vtx_id[cell_vtx[0]-1];
472       elt_buf[1] = vtx_id[cell_vtx[2]-1];
473       elt_buf[2] = vtx_id[cell_vtx[1]-1];
474       elt_buf[3] = vtx_id[cell_vtx[3]-1];
475       elt_buf[4] = vtx_id[cell_vtx[5]-1];
476       elt_buf[5] = vtx_id[cell_vtx[4]-1];
477       break;
478 
479     case FVM_CELL_HEXA:
480       type = INTERP_KERNEL::NORM_HEXA8;
481       n_vtx = 8;
482       elt_buf[0] = vtx_id[cell_vtx[0]-1];
483       elt_buf[1] = vtx_id[cell_vtx[3]-1];
484       elt_buf[2] = vtx_id[cell_vtx[2]-1];
485       elt_buf[3] = vtx_id[cell_vtx[1]-1];
486       elt_buf[4] = vtx_id[cell_vtx[4]-1];
487       elt_buf[5] = vtx_id[cell_vtx[7]-1];
488       elt_buf[6] = vtx_id[cell_vtx[6]-1];
489       elt_buf[7] = vtx_id[cell_vtx[5]-1];
490       break;
491 
492     default:
493       type = INTERP_KERNEL::NORM_POLYHED;
494 
495       n_vtx = 0;
496 
497       cs_lnum_t s_id = cell_faces_idx[i] - 1;
498       cs_lnum_t e_id = cell_faces_idx[i+1] -1;
499 
500       for (cs_lnum_t j = s_id; j < e_id; j++) {
501         int face_sgn = 0;
502         cs_lnum_t face_id;
503         if (cell_faces_num[j] > 0) {
504           face_id  = cell_faces_num[j] - 1;
505           face_sgn = 1;
506         }
507         else {
508           face_id  = -cell_faces_num[j] - 1;
509           face_sgn = -1;
510         }
511 
512         int fl = 1;
513         if (face_id < face_num_shift[fl])
514           fl = 0;
515         face_id -= face_num_shift[fl];
516 
517         cs_lnum_t v_id_start = face_vertices_idx[fl][face_id];
518         cs_lnum_t v_id_end   = face_vertices_idx[fl][face_id + 1];
519         cs_lnum_t n_face_vertices  = v_id_end - v_id_start;
520 
521         while (n_vtx + n_face_vertices + 1 > elt_buf_size) {
522           elt_buf_size *= 2;
523           BFT_REALLOC(elt_buf, elt_buf_size, mcIdType);
524         }
525 
526         /* Add separator after first face */
527         if (j > s_id)
528           elt_buf[n_vtx++] = -1;
529 
530         const cs_lnum_t *_face_perm = NULL;
531         _get_face_vertices_permutation(n_face_vertices);
532         if (_face_perm != NULL) {
533           for (cs_lnum_t  ik = 0; ik < n_face_vertices; ik++) {
534             cs_lnum_t iik = _face_perm[ik];
535             cs_lnum_t l =   v_id_start
536                           + (  n_face_vertices
537                              + (iik*face_sgn))%n_face_vertices;
538             cs_lnum_t vid = face_vertices_num[fl][l];
539             elt_buf[n_vtx++] = vtx_id[vid];
540           }
541         }
542         else {
543           for (cs_lnum_t ik = 0; ik < n_face_vertices; ik++) {
544             cs_lnum_t l =   v_id_start
545                           + (  n_face_vertices
546                              + (ik*face_sgn))%n_face_vertices;
547             cs_lnum_t vid = face_vertices_num[fl][l];
548             elt_buf[n_vtx++] = vtx_id[vid];
549           }
550         }
551       } /* Loop on j (cell faces) */
552     } /* switch on cell_type */
553 
554     med_mesh->insertNextCell(type, n_vtx, elt_buf);
555   } /* Loop on cells */
556 
557   med_mesh->finishInsertingCells();
558 
559   BFT_FREE(elt_buf);
560   BFT_FREE(cell_faces_num);;
561   BFT_FREE(cell_faces_idx);
562   BFT_FREE(vtx_id);
563 }
564 
565 #endif /* HAVE_MEDCOUPLING - BEGINNING OF PRIVATE FUNCTIONS */
566 
567 /*! (DOXYGEN_SHOULD_SKIP_THIS) \endcond */
568 
569 /*=============================================================================
570  * Public functions
571  *============================================================================*/
572 
573 /*----------------------------------------------------------------------------*/
574 /*!
575  * \brief   create a new cs_medcoupling_mesh_t instance
576  *
577  * \param[in] name                name of the mesh
578  * \param[in] selection_criteria  selection criteria (entire mesh or part of it)
579  * \param[in] elt_dim             dimension of elements.
580  *                                2: faces
581  *                                3: cells
582  *
583  * \return  pointer to the newly created cs_medcoupling_mesh_t struct
584  */
585 /*----------------------------------------------------------------------------*/
586 
587 cs_medcoupling_mesh_t *
cs_medcoupling_mesh_create(const char * name,const char * selection_criteria,int elt_dim)588 cs_medcoupling_mesh_create(const char  *name,
589                            const char  *selection_criteria,
590                            int          elt_dim)
591 {
592   cs_medcoupling_mesh_t *m = NULL;
593 
594 #if !defined(HAVE_MEDCOUPLING)
595   bft_error(__FILE__, __LINE__, 0,
596             _("Error: cs_medcoupling_mesh cannot be created without "
597               "MEDCoupling support\n"));
598 #else
599 
600   BFT_MALLOC(m, 1, cs_medcoupling_mesh_t);
601 
602   if (selection_criteria != NULL) {
603     BFT_MALLOC(m->sel_criteria, strlen(selection_criteria)+1, char);
604     strcpy(m->sel_criteria, selection_criteria);
605   } else {
606     BFT_MALLOC(m->sel_criteria, strlen("all[]")+1, char);
607     strcpy(m->sel_criteria, "all[]");
608   }
609   m->elt_dim  = elt_dim;
610   m->n_elts   = 0;
611   m->elt_list = NULL;
612 
613   m->med_mesh = MEDCouplingUMesh::New();
614   m->med_mesh->setName(name);
615   m->med_mesh->setTimeUnit("s");
616   m->med_mesh->setMeshDimension(elt_dim);
617 
618   m->bbox = NULL;
619 
620   m->new_to_old = NULL;
621 #endif
622 
623   return m;
624 }
625 
626 /*----------------------------------------------------------------------------*/
627 /*!
628  * \brief copy a cs_mesh_t into a cs_medcoupling_mesh_t
629  *
630  * \param[in] csmesh    pointer to the cs_mesh_t struct to copy data from
631  * \param[in] pmmesh    pointer to the cs_medcoupling_mesh_t for copy
632  * \param[in] use_bbox  flag indicating if a reduced bounding is used. Usefull
633  *                      for interpolation to reduce the matrix sice.
634  *                      0: Do not use a reduced bbox
635  *                      1: Use a reduced bbox
636  */
637 /*----------------------------------------------------------------------------*/
638 
639 void
cs_medcoupling_mesh_copy_from_base(cs_mesh_t * csmesh,cs_medcoupling_mesh_t * pmmesh,int use_bbox)640 cs_medcoupling_mesh_copy_from_base(cs_mesh_t              *csmesh,
641                                    cs_medcoupling_mesh_t  *pmmesh,
642                                    int                     use_bbox)
643 {
644 #if !defined(HAVE_MEDCOUPLING)
645   bft_error(__FILE__, __LINE__, 0,
646             _("Error: this funnction cannot be called without "
647               "MEDCoupling support\n"));
648 #else
649   if (pmmesh->elt_dim == 3) {
650 
651     /* Creation of a new nodal mesh from selected cells */
652 
653     BFT_MALLOC(pmmesh->elt_list, csmesh->n_cells, cs_lnum_t);
654 
655     cs_selector_get_cell_list(pmmesh->sel_criteria,
656                               &(pmmesh->n_elts),
657                               pmmesh->elt_list);
658 
659     BFT_REALLOC(pmmesh->elt_list, pmmesh->n_elts, cs_lnum_t);
660 
661     BFT_MALLOC(pmmesh->new_to_old, pmmesh->n_elts, cs_lnum_t);
662 
663     _assign_cell_mesh(csmesh,
664                       pmmesh->n_elts,
665                       pmmesh->elt_list,
666                       pmmesh->med_mesh,
667                       pmmesh->new_to_old);
668 
669     // BBOX
670     if (use_bbox) {
671       if (pmmesh->bbox == NULL) {
672         BFT_MALLOC(pmmesh->bbox, 6, cs_real_t);
673       }
674       pmmesh->med_mesh->getBoundingBox(pmmesh->bbox);
675     }
676 
677   } else if (pmmesh->elt_dim == 2) {
678 
679     /* Creation of a new nodal mesh from selected border faces */
680 
681     BFT_MALLOC(pmmesh->elt_list, csmesh->n_b_faces, cs_lnum_t);
682 
683     cs_selector_get_b_face_list(pmmesh->sel_criteria,
684                                 &(pmmesh->n_elts),
685                                 pmmesh->elt_list);
686 
687     BFT_REALLOC(pmmesh->elt_list, pmmesh->n_elts, cs_lnum_t);
688 
689     BFT_MALLOC(pmmesh->new_to_old, pmmesh->n_elts, cs_lnum_t);
690 
691     _assign_face_mesh(csmesh,
692                       pmmesh->n_elts,
693                       pmmesh->elt_list,
694                       pmmesh->med_mesh,
695                       pmmesh->new_to_old);
696 
697   }
698 #endif
699 }
700 
701 /*----------------------------------------------------------------------------*/
702 /*!
703  * \brief Destroy a cs_medcoupling_mesh_t
704  *
705  * \param[in] mesh  cs_medcoupling_mesh_t pointer
706  */
707 /*----------------------------------------------------------------------------*/
708 
709 void
cs_medcoupling_mesh_destroy(cs_medcoupling_mesh_t * mesh)710 cs_medcoupling_mesh_destroy(cs_medcoupling_mesh_t  *mesh)
711 {
712   BFT_FREE(mesh->sel_criteria);
713   BFT_FREE(mesh->elt_list);
714   BFT_FREE(mesh->new_to_old);
715   BFT_FREE(mesh->bbox);
716 
717 #if defined(HAVE_MEDCOUPLING)
718   BFT_FREE(mesh->med_mesh);
719 #endif
720 
721   BFT_FREE(mesh);
722 }
723 
724 /*----------------------------------------------------------------------------*/
725 /*!
726  * \brief Return a cs_medcoupling_mesh_t structure's spatial dimension
727  *
728  * \param[in] mesh  cs_medcoupling_mesh_t pointer
729  *
730  * \return associated spatial dimension
731  */
732 /*----------------------------------------------------------------------------*/
733 
734 int
cs_medcoupling_mesh_get_dim(cs_medcoupling_mesh_t * m)735 cs_medcoupling_mesh_get_dim(cs_medcoupling_mesh_t  *m)
736 {
737   int retval = -1;
738   if (m != NULL)
739     retval = m->elt_dim;
740 
741   return retval;
742 }
743 
744 /*----------------------------------------------------------------------------*/
745 /*!
746  * \brief Return a cs_medcoupling_mesh_t structure's number of elements
747  *
748  * \param[in] mesh  cs_medcoupling_mesh_t pointer
749  *
750  * \return associated number of elements
751  */
752 /*----------------------------------------------------------------------------*/
753 
754 cs_lnum_t
cs_medcoupling_mesh_get_n_elts(cs_medcoupling_mesh_t * m)755 cs_medcoupling_mesh_get_n_elts(cs_medcoupling_mesh_t  *m)
756 {
757   cs_lnum_t retval = 0;
758   if (m != NULL)
759     retval = m->n_elts;
760 
761   return retval;
762 }
763 
764 /*----------------------------------------------------------------------------*/
765 /*!
766  * \brief Return a cs_medcoupling_mesh_t structure's (parent) elements list
767  *
768  * \param[in] mesh  cs_medcoupling_mesh_t pointer
769  *
770  * \return ids of associated elements, or NULL
771  */
772 /*----------------------------------------------------------------------------*/
773 
774 const cs_lnum_t *
cs_medcoupling_mesh_get_elt_list(cs_medcoupling_mesh_t * m)775 cs_medcoupling_mesh_get_elt_list(cs_medcoupling_mesh_t  *m)
776 {
777   const cs_lnum_t *retval = NULL;
778 
779   if (m != NULL)
780     retval = m->elt_list;
781 
782   return retval;
783 }
784 
785 /*----------------------------------------------------------------------------*/
786 /*!
787  * \brief Return a cs_medcoupling_mesh_t structure's (parent) elements list
788  *
789  * \param[in] mesh  cs_medcoupling_mesh_t pointer
790  *
791  * \return ids of associated elements, or NULL
792  */
793 /*----------------------------------------------------------------------------*/
794 
795 const cs_lnum_t *
cs_medcoupling_mesh_get_connectivity(cs_medcoupling_mesh_t * m)796 cs_medcoupling_mesh_get_connectivity(cs_medcoupling_mesh_t  *m)
797 {
798   const cs_lnum_t *retval = NULL;
799 
800   if (m != NULL)
801     retval = m->new_to_old;
802 
803   return retval;
804 }
805 
806 /*----------------------------------------------------------------------------*/
807 
808 END_C_DECLS
809