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