1 /*============================================================================
2 * Management of post-processing for joining operation
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 <assert.h>
34 #include <stdio.h>
35 #include <string.h>
36
37 /*----------------------------------------------------------------------------
38 * Local headers
39 *---------------------------------------------------------------------------*/
40
41 #include "bft_error.h"
42 #include "bft_mem.h"
43
44 #include "fvm_nodal.h"
45 #include "fvm_nodal_order.h"
46 #include "fvm_nodal_from_desc.h"
47 #include "fvm_writer.h"
48
49 #include "cs_file.h"
50 #include "cs_mesh_connect.h"
51 #include "cs_post.h"
52 #include "cs_timer_stats.h"
53
54 /*----------------------------------------------------------------------------
55 * Header for the current file
56 *---------------------------------------------------------------------------*/
57
58 #include "cs_join_post.h"
59
60 /*---------------------------------------------------------------------------*/
61
62 BEGIN_C_DECLS
63
64 /*! \cond DOXYGEN_SHOULD_SKIP_THIS */
65
66 /*============================================================================
67 * Macro and type definitions
68 *===========================================================================*/
69
70 typedef struct {
71
72 int writer_num; /* identifier for the related writer */
73 fvm_writer_t *writer; /* writer used for post-processing */
74
75 } cs_join_post_t;
76
77 /* Directory name separator
78 (historically, '/' for Unix/Linux, '\' for Windows, ':' for Mac
79 but '/' should work for all on modern systems) */
80
81 #define DIR_SEPARATOR '/'
82
83 /*============================================================================
84 * Static global variables
85 *===========================================================================*/
86
87 static cs_join_post_t _cs_join_post_param;
88
89 static bool _cs_join_post_initialized = false;
90 static int _post_stage_stat_id = -1;
91
92 /*============================================================================
93 * Private function definitions
94 *===========================================================================*/
95
96 /*----------------------------------------------------------------------------
97 * Initialize post-processing writer with same format and associated
98 * options as default writer, but no time dependency, intended to
99 * post elements implied in the joining operations.
100 *
101 * returns:
102 * id of associated writer (< 0, or 0 in case of failure)
103 *----------------------------------------------------------------------------*/
104
105 static int
_init_join_writer(void)106 _init_join_writer(void)
107 {
108 int writer_id = cs_post_get_free_writer_id();
109
110 /* Special case for Catalyst: if matching co-processing script is
111 not available, revert to EnSight Gold format */
112
113 int default_format_id
114 = fvm_writer_get_format_id(cs_post_get_default_format());
115
116 if (default_format_id == fvm_writer_get_format_id("Catalyst")) {
117 if (! cs_file_isreg("error.py"))
118 return 0;
119 }
120
121 cs_post_define_writer(writer_id,
122 "joining",
123 "postprocessing",
124 fvm_writer_format_name(default_format_id),
125 cs_post_get_default_format_options(),
126 FVM_WRITER_FIXED_MESH,
127 false,
128 false,
129 -1,
130 -1.0);
131
132 return writer_id;
133 }
134
135 /*----------------------------------------------------------------------------
136 * Write a field of "double" on the vertices of the selected mesh.
137 * Variable is interlaced.
138 *
139 * parameters:
140 * mesh <-- mesh on which we want to write the current field.
141 * varname <-- name of the field.
142 * dim <-- dimension of the field to export.
143 * field <-- variable to write.
144 *---------------------------------------------------------------------------*/
145
146 static void
_post_vtx_dfield(fvm_nodal_t * mesh,const char * varname,int dim,const double * field)147 _post_vtx_dfield(fvm_nodal_t *mesh,
148 const char *varname,
149 int dim,
150 const double *field)
151 {
152 fvm_writer_t *writer = _cs_join_post_param.writer;
153
154 cs_lnum_t parent_num_shift[2] = {0, 0};
155
156 const double *var_ptr[9] = {NULL, NULL, NULL,
157 NULL, NULL, NULL,
158 NULL, NULL, NULL};
159
160 assert(writer != NULL);
161 assert(sizeof(double) == 8);
162
163 var_ptr[0] = field;
164
165 fvm_writer_export_field(writer,
166 mesh,
167 varname,
168 FVM_WRITER_PER_NODE,
169 dim,
170 CS_INTERLACE,
171 0,
172 parent_num_shift,
173 CS_DOUBLE,
174 -1,
175 0.,
176 (const void **)var_ptr);
177 }
178
179 /*----------------------------------------------------------------------------
180 * Write an integer field on the elements of the selected mesh.
181 * Variable is interlaced.
182 *
183 * parameters:
184 * mesh <-- mesh on which we want to write the current field.
185 * varname <-- name of the field.
186 * dim <-- dimension of the field to export.
187 * field <-- variable to write.
188 *---------------------------------------------------------------------------*/
189
190 static void
_post_elt_ifield(fvm_nodal_t * mesh,const char * varname,int dim,const int * field)191 _post_elt_ifield(fvm_nodal_t *mesh,
192 const char *varname,
193 int dim,
194 const int *field)
195 {
196 fvm_writer_t *writer = _cs_join_post_param.writer;
197
198 cs_lnum_t parent_num_shift[2] = {0, 0};
199 cs_datatype_t datatype = CS_DATATYPE_NULL;
200
201 const int *var_ptr[9] = {NULL, NULL, NULL,
202 NULL, NULL, NULL,
203 NULL, NULL, NULL};
204
205 assert(writer != NULL);
206 assert(sizeof(cs_lnum_t) == sizeof(int));
207
208 if (sizeof(int) == 4)
209 datatype = CS_INT32;
210 else if (sizeof(int) == 8)
211 datatype = CS_INT64;
212 else
213 bft_error(__FILE__, __LINE__, 0,
214 _(" Size of \"int\" is not 4 or 8 bytes.\n"
215 " Check the datatype of the field to export.\n"));
216
217 var_ptr[0] = field;
218
219 fvm_writer_export_field(writer,
220 mesh,
221 varname,
222 FVM_WRITER_PER_ELEMENT,
223 dim,
224 CS_INTERLACE,
225 0,
226 parent_num_shift,
227 datatype,
228 -1,
229 0.,
230 (const void **)var_ptr);
231 }
232
233 /*! (DOXYGEN_SHOULD_SKIP_THIS) \endcond */
234
235 /*============================================================================
236 * Public function definitions
237 *===========================================================================*/
238
239 /*----------------------------------------------------------------------------
240 * Create a writer to output post-processing files for a joining operation.
241 *---------------------------------------------------------------------------*/
242
243 void
cs_join_post_init(void)244 cs_join_post_init(void)
245 {
246 if (_cs_join_post_initialized == true)
247 return;
248
249 _post_stage_stat_id = cs_timer_stats_id_by_name("postprocessing_stage");
250
251 int writer_num = _init_join_writer();
252
253 if (writer_num != 0) {
254
255 _cs_join_post_initialized = true;
256
257 cs_post_activate_writer(writer_num, 1);
258
259 _cs_join_post_param.writer = cs_post_get_writer(writer_num);
260 _cs_join_post_param.writer_num = writer_num;
261
262 }
263 }
264
265 /*----------------------------------------------------------------------------
266 * Post-treatment of a cs_join_mesh_t structure.
267 *
268 * parameters:
269 * mesh_name <-- name of the mesh for the post-processing
270 * mesh <-- pointer to a cs_join_mesh_t structure to post-process
271 *---------------------------------------------------------------------------*/
272
273 void
cs_join_post_mesh(const char * mesh_name,const cs_join_mesh_t * join_mesh)274 cs_join_post_mesh(const char *mesh_name,
275 const cs_join_mesh_t *join_mesh)
276 {
277 if (_cs_join_post_initialized == true)
278 return;
279
280 int t_top_id = cs_timer_stats_switch(_post_stage_stat_id);
281
282 int i, j;
283 cs_lnum_t n_vertices;
284
285 const char *name = NULL;
286 int *ifield = NULL;
287 double *dfield = NULL;
288 cs_gnum_t *vertex_gnum = NULL;
289 cs_real_t *vertex_coord = NULL;
290 cs_lnum_t *parent_vtx_num = NULL;
291 fvm_nodal_t *post_mesh = NULL;
292 fvm_writer_t *writer = _cs_join_post_param.writer;
293
294 const int local_rank = CS_MAX(cs_glob_rank_id, 0);
295 const cs_lnum_t face_list_shift[2] = {0, join_mesh->n_faces};
296 const cs_lnum_t *face_vertex_idx[1] = {join_mesh->face_vtx_idx};
297 const cs_lnum_t *face_vertex_lst[1] = {join_mesh->face_vtx_lst};
298
299 /* Define an fvm_nodal_mesh_t structure from a cs_join_mesh_t structure */
300
301 /* Create an empty fvm_nodal_t structure. */
302
303 if (mesh_name == NULL)
304 name = join_mesh->name;
305 else
306 name = mesh_name;
307
308 post_mesh = fvm_nodal_create(name, 3);
309
310 /* Define fvm_nodal_t structure */
311
312 fvm_nodal_from_desc_add_faces(post_mesh,
313 -1,
314 join_mesh->n_faces,
315 NULL,
316 1,
317 face_list_shift,
318 face_vertex_idx,
319 face_vertex_lst,
320 NULL,
321 NULL);
322
323 /* Define vertex_coord for fvm_nodal_set_shared_vertices() */
324
325 BFT_MALLOC(vertex_coord, 3*join_mesh->n_vertices, cs_real_t);
326
327 for (i = 0; i < join_mesh->n_vertices; i++)
328 for (j = 0; j < 3; j++)
329 vertex_coord[3*i+j] = (join_mesh->vertices[i]).coord[j];
330
331 fvm_nodal_set_shared_vertices(post_mesh, vertex_coord);
332
333 /* Order faces by increasing global number */
334
335 fvm_nodal_order_faces(post_mesh, join_mesh->face_gnum);
336 fvm_nodal_init_io_num(post_mesh, join_mesh->face_gnum, 2);
337
338 /* Order vertices by increasing global number */
339
340 BFT_MALLOC(vertex_gnum, join_mesh->n_vertices, cs_gnum_t);
341
342 for (i = 0; i < join_mesh->n_vertices; i++)
343 vertex_gnum[i] = (join_mesh->vertices[i]).gnum;
344
345 fvm_nodal_order_vertices(post_mesh, vertex_gnum);
346 fvm_nodal_init_io_num(post_mesh, vertex_gnum, 0);
347
348 /* Write current mesh */
349
350 fvm_writer_export_nodal(writer, post_mesh);
351
352 BFT_FREE(vertex_gnum);
353 BFT_FREE(vertex_coord);
354
355 /* Write rank associated to each face */
356
357 BFT_MALLOC(ifield, join_mesh->n_faces, int);
358
359 for (i = 0; i < join_mesh->n_faces; i++)
360 ifield[i] = local_rank;
361
362 _post_elt_ifield(post_mesh, _("Rank"), 1, ifield);
363
364 BFT_FREE(ifield);
365
366 /* Write vertex tolerance */
367
368 n_vertices = fvm_nodal_get_n_entities(post_mesh, 0);
369
370 BFT_MALLOC(parent_vtx_num, n_vertices, cs_lnum_t);
371 BFT_MALLOC(dfield, n_vertices, double);
372
373 fvm_nodal_get_parent_num(post_mesh, 0, parent_vtx_num);
374
375 for (i = 0; i < n_vertices; i++) {
376
377 cs_join_vertex_t data = join_mesh->vertices[parent_vtx_num[i]-1];
378
379 dfield[i] = data.tolerance;
380 }
381
382 _post_vtx_dfield(post_mesh, _("VtxTolerance"), 1, dfield);
383
384 BFT_FREE(parent_vtx_num);
385 BFT_FREE(dfield);
386
387 post_mesh = fvm_nodal_destroy(post_mesh);
388
389 cs_timer_stats_switch(t_top_id);
390 }
391
392 /*----------------------------------------------------------------------------
393 * Post-process a subset of faces of a cs_join_mesh_t structure.
394 *
395 * parameters:
396 * mesh_name <-- name of the sub-set mesh
397 * mesh <-- pointer to the parent cs_join_mesh_t structure
398 * n_selected_faces <-- number of selected faces (size of the sub-set)
399 * selected_faces <-- list of local number in parent mesh
400 *---------------------------------------------------------------------------*/
401
402 void
cs_join_post_faces_subset(const char * mesh_name,const cs_join_mesh_t * parent_mesh,cs_lnum_t n_select_faces,const cs_lnum_t selected_faces[])403 cs_join_post_faces_subset(const char *mesh_name,
404 const cs_join_mesh_t *parent_mesh,
405 cs_lnum_t n_select_faces,
406 const cs_lnum_t selected_faces[])
407 {
408 if (_cs_join_post_initialized == true)
409 return;
410
411 int t_top_id = cs_timer_stats_switch(_post_stage_stat_id);
412
413 cs_join_mesh_t *subset_mesh = NULL;
414
415 assert(parent_mesh != NULL);
416
417 subset_mesh = cs_join_mesh_create_from_subset(mesh_name,
418 n_select_faces,
419 selected_faces,
420 parent_mesh);
421
422 cs_join_post_mesh(subset_mesh->name, subset_mesh);
423
424 cs_join_mesh_destroy(&subset_mesh);
425
426 cs_timer_stats_switch(t_top_id);
427 }
428
429 /*----------------------------------------------------------------------------
430 * Post-process mesh after the update following the merge operation.
431 *
432 * parameters:
433 * join_param <-- set of parameters for the joining operation
434 * join_select <-- list of participating entities in the joining operation
435 *---------------------------------------------------------------------------*/
436
437 void
cs_join_post_after_merge(cs_join_param_t join_param,const cs_join_select_t * join_select)438 cs_join_post_after_merge(cs_join_param_t join_param,
439 const cs_join_select_t *join_select)
440 {
441 if (_cs_join_post_initialized == true)
442 return;
443
444 int t_top_id = cs_timer_stats_switch(_post_stage_stat_id);
445
446 int adj_mesh_id, sel_mesh_id;
447
448 int writer_ids[] = {_cs_join_post_param.writer_num};
449 char *mesh_name = NULL;
450 fvm_nodal_t *adj_mesh = NULL, *sel_mesh = NULL;
451
452 adj_mesh_id = cs_post_get_free_mesh_id();
453
454 BFT_MALLOC(mesh_name, strlen("AdjacentJoinFaces_j") + 2 + 1, char);
455 sprintf(mesh_name,"%s%02d", "AdjacentJoinFaces_j", join_param.num);
456
457 adj_mesh = cs_mesh_connect_faces_to_nodal(cs_glob_mesh,
458 mesh_name,
459 false, /* include families */
460 join_select->n_i_adj_faces,
461 join_select->n_b_adj_faces,
462 join_select->i_adj_faces,
463 join_select->b_adj_faces);
464
465 cs_post_define_existing_mesh(adj_mesh_id,
466 adj_mesh,
467 0, /* dim_shift */
468 true, /* transfer ownership */
469 false,
470 1,
471 writer_ids);
472
473 sel_mesh_id = cs_post_get_free_mesh_id();
474
475 BFT_REALLOC(mesh_name, strlen("JoinFacesAfterMerge_j") + 2 + 1, char);
476 sprintf(mesh_name,"%s%02d", "JoinFacesAfterMerge_j", join_param.num);
477
478 sel_mesh = cs_mesh_connect_faces_to_nodal(cs_glob_mesh,
479 mesh_name,
480 false, /* include families */
481 0,
482 join_select->n_faces,
483 NULL,
484 join_select->faces);
485
486 cs_post_define_existing_mesh(sel_mesh_id,
487 sel_mesh,
488 0, /* dim_shift */
489 true, /* transfer ownership */
490 false,
491 1,
492 writer_ids);
493
494 /* Post */
495
496 cs_post_activate_writer(_cs_join_post_param.writer_num, 1);
497 cs_post_write_meshes(NULL);
498
499 cs_post_free_mesh(sel_mesh_id);
500 cs_post_free_mesh(adj_mesh_id);
501
502 BFT_FREE(mesh_name);
503
504 cs_timer_stats_switch(t_top_id);
505 }
506
507 /*----------------------------------------------------------------------------
508 * Post-process mesh after the update following the split operation.
509 *
510 * parameters:
511 * n_old_i_faces <-- initial number of interior faces
512 * n_old_b_faces <-- initial number of border faces
513 * n_g_new_b_faces <-- global number of new border faces
514 * n_select_faces <-- number of selected faces
515 * mesh <-- pointer to a cs_mesh_t structure
516 * join_param <-- set of parameters for the joining operation
517 *---------------------------------------------------------------------------*/
518
519 void
cs_join_post_after_split(cs_lnum_t n_old_i_faces,cs_lnum_t n_old_b_faces,cs_gnum_t n_g_new_b_faces,cs_lnum_t n_select_faces,const cs_mesh_t * mesh,cs_join_param_t join_param)520 cs_join_post_after_split(cs_lnum_t n_old_i_faces,
521 cs_lnum_t n_old_b_faces,
522 cs_gnum_t n_g_new_b_faces,
523 cs_lnum_t n_select_faces,
524 const cs_mesh_t *mesh,
525 cs_join_param_t join_param)
526 {
527 if (join_param.visualization < 1 || _cs_join_post_initialized == false)
528 return;
529
530 int t_top_id = cs_timer_stats_switch(_post_stage_stat_id);
531
532 cs_lnum_t i, j;
533
534 int writer_ids[] = {_cs_join_post_param.writer_num};
535 char *mesh_name = NULL;
536 cs_lnum_t *post_i_faces = NULL, *post_b_faces = NULL;
537 fvm_nodal_t *post_i_mesh = NULL;
538 int post_i_mesh_id = cs_post_get_free_mesh_id();
539 int post_b_mesh_id = 0;
540
541 const int n_new_i_faces = mesh->n_i_faces - n_old_i_faces;
542 const int n_new_b_faces = mesh->n_b_faces - n_old_b_faces + n_select_faces;
543
544 /* Define list of faces to post-treat */
545
546 BFT_MALLOC(post_i_faces, n_new_i_faces, cs_lnum_t);
547 BFT_MALLOC(post_b_faces, n_new_b_faces, cs_lnum_t);
548
549 for (i = n_old_i_faces, j = 0; i < mesh->n_i_faces; i++, j++)
550 post_i_faces[j] = i + 1;
551
552 for (i = n_old_b_faces-n_select_faces, j = 0; i < mesh->n_b_faces; i++, j++)
553 post_b_faces[j] = i + 1;
554
555 BFT_MALLOC(mesh_name, strlen("InteriorJoinedFaces_j") + 2 + 1, char);
556 sprintf(mesh_name,"%s%02d", "InteriorJoinedFaces_j", join_param.num);
557
558 post_i_mesh = cs_mesh_connect_faces_to_nodal(cs_glob_mesh,
559 mesh_name,
560 false, /* include families */
561 n_new_i_faces,
562 0,
563 post_i_faces,
564 NULL);
565
566 cs_post_define_existing_mesh(post_i_mesh_id,
567 post_i_mesh,
568 0, /* dim_shift */
569 true, /* transfer ownership */
570 false,
571 1,
572 writer_ids);
573
574 if (join_param.visualization > 1 && n_g_new_b_faces > 0) {
575
576 fvm_nodal_t *post_b_mesh = NULL;
577 post_b_mesh_id = cs_post_get_free_mesh_id();
578
579 BFT_REALLOC(mesh_name, strlen("BoundaryJoinedFaces_j") + 2 + 1, char);
580 sprintf(mesh_name,"%s%02d", "BoundaryJoinedFaces_j", join_param.num);
581
582 post_b_mesh = cs_mesh_connect_faces_to_nodal(cs_glob_mesh,
583 mesh_name,
584 false, /* include families */
585 0,
586 n_new_b_faces,
587 NULL,
588 post_b_faces);
589
590 cs_post_define_existing_mesh(post_b_mesh_id,
591 post_b_mesh,
592 0, /* dim_shift */
593 true, /* transfer ownership */
594 false,
595 1,
596 writer_ids);
597
598 }
599
600 /* Post */
601
602 cs_post_activate_writer(_cs_join_post_param.writer_num, 1);
603 cs_post_write_meshes(NULL);
604
605 if (post_b_mesh_id != 0)
606 cs_post_free_mesh(post_b_mesh_id);
607 cs_post_free_mesh(post_i_mesh_id);
608
609 BFT_FREE(post_i_faces);
610 BFT_FREE(post_b_faces);
611 BFT_FREE(mesh_name);
612
613 cs_timer_stats_switch(t_top_id);
614 }
615
616 /*----------------------------------------------------------------------------
617 * Post-process mesh after the update following the split operation.
618 *
619 * parameters:
620 * n_i_clean_faces <-- number of interior faces cleaned
621 * i_clean_faces <-> list of interior face numbers (ordered on exit)
622 * n_b_clean_faces <-- number of border faces cleaned
623 * b_clean_faces <-> list of border face numbers (ordered on exit)
624 * param <-- set of parameters for the joining operation
625 *---------------------------------------------------------------------------*/
626
627 void
cs_join_post_cleaned_faces(cs_lnum_t n_i_clean_faces,cs_lnum_t i_clean_faces[],cs_lnum_t n_b_clean_faces,cs_lnum_t b_clean_faces[],cs_join_param_t param)628 cs_join_post_cleaned_faces(cs_lnum_t n_i_clean_faces,
629 cs_lnum_t i_clean_faces[],
630 cs_lnum_t n_b_clean_faces,
631 cs_lnum_t b_clean_faces[],
632 cs_join_param_t param)
633 {
634 if (_cs_join_post_initialized == false)
635 return;
636
637 int t_top_id = cs_timer_stats_switch(_post_stage_stat_id);
638
639 int writer_ids[] = {_cs_join_post_param.writer_num};
640 int post_mesh_id = cs_post_get_free_mesh_id();
641 char *name = NULL;
642 fvm_nodal_t *export_mesh = NULL;
643
644 BFT_MALLOC(name, strlen("CleanFaces_j") + 2 + 1, char);
645 sprintf(name,"%s%02d", "CleanFaces_j", param.num);
646
647 export_mesh = cs_mesh_connect_faces_to_nodal(cs_glob_mesh,
648 name,
649 false, /* include families */
650 n_i_clean_faces,
651 n_b_clean_faces,
652 i_clean_faces,
653 b_clean_faces);
654
655 cs_post_define_existing_mesh(post_mesh_id,
656 export_mesh,
657 0, /* dim_shift */
658 true, /* transfer ownership */
659 false,
660 1,
661 writer_ids);
662
663 /* Output post-processing data */
664
665 cs_post_activate_writer(_cs_join_post_param.writer_num, 1);
666 cs_post_write_meshes(NULL);
667
668 cs_post_free_mesh(post_mesh_id);
669
670 BFT_FREE(name);
671
672 cs_timer_stats_switch(t_top_id);
673 }
674
675 /*----------------------------------------------------------------------------
676 * Output processor-specific post-processing data for a cs_join_mesh_t
677 * structure according to the visualization level.
678 *
679 * parameters:
680 * basename <-- generic name for the mesh to post
681 * mesh <-- fvm_join_mesh_t structure to post-process
682 * param <-- fvm_join_param_t structure
683 *---------------------------------------------------------------------------*/
684
685 void
cs_join_post_dump_mesh(const char * basename,const cs_join_mesh_t * mesh,cs_join_param_t param)686 cs_join_post_dump_mesh(const char *basename,
687 const cs_join_mesh_t *mesh,
688 cs_join_param_t param)
689 {
690 int rank, len;
691
692 cs_join_mesh_t *tmp = NULL;
693 char *fullname = NULL;
694
695 const int n_ranks = cs_glob_n_ranks;
696 const int rank_id = CS_MAX(cs_glob_rank_id, 0);
697
698 /* Define a specific name for the output */
699
700 len = strlen("log/JoinDBG_.dat") + strlen(basename) + 4 + 2 + 1;
701 BFT_MALLOC(fullname, len, char);
702 sprintf(fullname, "log%cJoin%02dDBG_%s%04d.dat", DIR_SEPARATOR,
703 param.num, basename, rank_id);
704
705 #if 0 && defined(DEBUG) && !defined(NDEBUG) /* Dump mesh structure */
706 if (param.verbosity > 3) {
707 FILE *dbg_file = NULL;
708 dbg_file = fopen(fullname, "w");
709 cs_join_mesh_dump_file(dbg_file, mesh);
710 fflush(dbg_file);
711 fclose(dbg_file);
712 }
713 #endif
714
715 if (_cs_join_post_initialized == true && param.visualization > 3) {
716
717 if (n_ranks == 1)
718 cs_join_post_mesh(fullname, mesh);
719
720 else { /* Parallel */
721
722 for (rank = 0; rank < n_ranks; rank++) {
723
724 char *mesh_name = NULL;
725
726 BFT_MALLOC(mesh_name, strlen(basename) + 2 + 2 + 5 + 1, char);
727 sprintf(mesh_name,"%s%02d%s%05d", basename, param.num, "_n", rank);
728
729 if (rank_id == rank)
730 cs_join_post_mesh(mesh_name, mesh);
731
732 else { /* Pieces empty on other ranks */
733 tmp = cs_join_mesh_create(mesh_name);
734 cs_join_post_mesh(mesh_name, tmp);
735 cs_join_mesh_destroy(&tmp);
736 }
737
738 BFT_FREE(mesh_name);
739
740 } /* End of loop on ranks */
741 } /* End of parallel treatment */
742 }
743
744 BFT_FREE(fullname);
745
746 #if defined(HAVE_MPI)
747 if (n_ranks > 1)
748 MPI_Barrier(cs_glob_mpi_comm);
749 #endif
750 }
751
752 /*---------------------------------------------------------------------------*/
753
754 END_C_DECLS
755