~ubuntu-branches/ubuntu/precise/code-saturne/precise

« back to all changes in this revision

Viewing changes to src/base/cs_post.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2011-11-24 00:00:08 UTC
  • mfrom: (6.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20111124000008-2vo99e38267942q5
Tags: 2.1.0-3
Install a missing file

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*============================================================================
2
 
 *
3
 
 *     This file is part of the Code_Saturne Kernel, element of the
4
 
 *     Code_Saturne CFD tool.
5
 
 *
6
 
 *     Copyright (C) 1998-2009 EDF S.A., France
7
 
 *
8
 
 *     contact: saturne-support@edf.fr
9
 
 *
10
 
 *     The Code_Saturne Kernel is free software; you can redistribute it
11
 
 *     and/or modify it under the terms of the GNU General Public License
12
 
 *     as published by the Free Software Foundation; either version 2 of
13
 
 *     the License, or (at your option) any later version.
14
 
 *
15
 
 *     The Code_Saturne Kernel is distributed in the hope that it will be
16
 
 *     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
17
 
 *     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
 *     GNU General Public License for more details.
19
 
 *
20
 
 *     You should have received a copy of the GNU General Public License
21
 
 *     along with the Code_Saturne Kernel; if not, write to the
22
 
 *     Free Software Foundation, Inc.,
23
 
 *     51 Franklin St, Fifth Floor,
24
 
 *     Boston, MA  02110-1301  USA
25
 
 *
26
 
 *============================================================================*/
27
 
 
28
 
/*============================================================================
29
2
 * Management of the post-processing
30
3
 *============================================================================*/
31
4
 
 
5
/*
 
6
  This file is part of Code_Saturne, a general-purpose CFD tool.
 
7
 
 
8
  Copyright (C) 1998-2011 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
 
32
27
#if defined(HAVE_CONFIG_H)
33
28
#include "cs_config.h"
34
29
#endif
47
42
 * BFT library headers
48
43
 *----------------------------------------------------------------------------*/
49
44
 
50
 
#include <bft_config.h>
51
45
#include <bft_mem.h>
52
46
#include <bft_printf.h>
53
47
 
56
50
 *----------------------------------------------------------------------------*/
57
51
 
58
52
#include <fvm_nodal.h>
 
53
#include <fvm_parall.h>
59
54
#include <fvm_writer.h>
60
55
 
61
56
/*----------------------------------------------------------------------------
66
61
#include "cs_mesh.h"
67
62
#include "cs_mesh_connect.h"
68
63
#include "cs_prototypes.h"
 
64
#include "cs_selector.h"
69
65
 
70
66
/*----------------------------------------------------------------------------
71
67
 * Header for the current file
81
77
 * Local types and structures
82
78
 *============================================================================*/
83
79
 
 
80
/* FVM writer structure definition parameters */
 
81
/*--------------------------------------------*/
 
82
 
 
83
typedef struct {
 
84
 
 
85
  fvm_writer_time_dep_t   time_dep;     /* Time dependency */
 
86
  int                     fmt_id;       /* format id */
 
87
  char                   *case_name;    /* Case (writer) name */
 
88
  char                   *dir_name;     /* Associated directory name */
 
89
  char                   *fmt_opts;     /* Format options */
 
90
 
 
91
} cs_post_writer_def_t;
 
92
 
84
93
/* Mesh location type */
85
94
/*--------------------*/
86
95
 
104
113
 
105
114
  int            id;           /* Identifier (< 0 for "reservable" writer,
106
115
                                * > 0 for user writer */
107
 
  int            frequency;    /* Default output frequency */
108
 
  cs_bool_t      write_displ;  /* Write displacement field if true */
 
116
  int            output_end;   /* Output at end of calculation if nonzero */
 
117
  int            frequency_n;  /* Default output frequency in time-steps */
 
118
  double         frequency_t;  /* Default output frequency in seconds */
109
119
 
110
120
  int            active;       /* 0 if no output at current time step,
111
121
                                  1 in case of output */
 
122
  int            n_last;       /* Time step number for the last
 
123
                                  activation (-1 before first output) */
 
124
  double         t_last;       /* Time value number for the last
 
125
                                  activation (0.0 before first output) */
 
126
 
 
127
  cs_post_writer_def_t  *wd;   /* Associated writer definition */
112
128
 
113
129
  fvm_writer_t  *writer;       /* Associated FVM writer */
114
130
 
125
141
  int                     id;            /* Identifier (< 0 for "reservable"
126
142
                                            mesh, > 0 for user mesh */
127
143
 
 
144
  char                   *name;          /* Mesh name */
 
145
  char                   *criteria[3];   /* Base selection criteria for
 
146
                                            cells, interior faces, and
 
147
                                            boundary faces respectively */
128
148
  int                     ent_flag[3];   /* Presence of cells (ent_flag[0],
129
149
                                            interior faces (ent_flag[1]),
130
150
                                            or boundary faces (ent_flag[2])
131
151
                                            on one processor at least */
132
152
 
133
 
  int                     cat_id;        /* Optional category id for
134
 
                                            as regards variables output
135
 
                                            (-1 as base volume mesh, -2 as
136
 
                                            base boundary mesh, identical
137
 
                                            to id by default) */
 
153
  int                     cat_id;        /* Optional category id as regards
 
154
                                            variables output (-1 as base
 
155
                                            volume mesh, -2 as base boundary
 
156
                                            mesh, 0 by default) */
138
157
 
139
158
  int                     alias;         /* If > -1, index in array of
140
159
                                            post-processing meshes of the
141
160
                                            first mesh sharing the same
142
161
                                            exportable mesh */
143
162
 
 
163
  cs_bool_t               add_groups;    /* Add group information if present */
 
164
 
144
165
  int                     n_writers;     /* Number of associated writers */
145
166
  int                    *writer_id;     /* Array of associated writer ids */
146
167
  int                     nt_last;       /* Time step number for the last
147
 
                                            output (-1 before first output) */
 
168
                                            output (-2 before first output,
 
169
                                            -1 for time-indepedent output) */
148
170
 
149
 
  cs_int_t                n_i_faces;     /* N. associated interior faces */
150
 
  cs_int_t                n_b_faces;     /* N. associated boundary faces */
 
171
  fvm_lnum_t              n_i_faces;     /* N. associated interior faces */
 
172
  fvm_lnum_t              n_b_faces;     /* N. associated boundary faces */
151
173
 
152
174
  const fvm_nodal_t      *exp_mesh;      /* Associated exportable mesh */
153
 
  fvm_nodal_t            *_exp_mesh;     /* Associated exportble mesh,
 
175
  fvm_nodal_t            *_exp_mesh;     /* Associated exportable mesh,
154
176
                                            if owner */
155
177
 
156
178
  fvm_writer_time_dep_t   mod_flag_min;  /* Minimum mesh time dependency */
162
184
 * Static global variables
163
185
 *============================================================================*/
164
186
 
 
187
/* Default output format and options */
 
188
 
 
189
static int _cs_post_default_format_id = 0;
 
190
static char *_cs_post_default_format_options = NULL;
 
191
 
165
192
/* Backup of initial vertex coordinates */
166
193
 
167
194
static cs_bool_t   _cs_post_deformable = false;
195
222
static cs_post_time_dep_var_t **_cs_post_f_var_tp = NULL;
196
223
static int                     *_cs_post_i_var_tp = NULL;
197
224
 
 
225
/* Default directory name */
 
226
 
 
227
static const char  _cs_post_dirname[] = "postprocessing";
 
228
 
198
229
/*============================================================================
199
230
 * Private function definitions
200
231
 *============================================================================*/
201
232
 
202
233
/*----------------------------------------------------------------------------
 
234
 * Clear temporary writer definition information.
 
235
 *
 
236
 * parameters:
 
237
 *   writer <-> pointer to writer structure
 
238
 *----------------------------------------------------------------------------*/
 
239
 
 
240
static void
 
241
_destroy_writer_def(cs_post_writer_t  *writer)
 
242
{
 
243
  assert(writer != NULL);
 
244
  if (writer->wd != NULL) {
 
245
    cs_post_writer_def_t  *wd = writer->wd;
 
246
    BFT_FREE(wd->case_name);
 
247
    BFT_FREE(wd->dir_name);
 
248
    BFT_FREE(wd->fmt_opts);
 
249
    BFT_FREE(writer->wd);
 
250
  }
 
251
}
 
252
 
 
253
/*----------------------------------------------------------------------------
 
254
 * Print writer information to log file
 
255
 *----------------------------------------------------------------------------*/
 
256
 
 
257
static void
 
258
_writer_info(void)
 
259
{
 
260
  if (cs_glob_rank_id < 1) {
 
261
 
 
262
    int i;
 
263
 
 
264
    bft_printf(_("\n"
 
265
                 "Postprocessing output writers:\n"
 
266
                 "------------------------------\n\n"));
 
267
 
 
268
    for (i = 0; i < _cs_post_n_writers; i++) {
 
269
 
 
270
      int fmt_id = 0, n_fmt_str = 0;
 
271
      fvm_writer_time_dep_t   time_dep;
 
272
      const char  *fmt_name, *fmt_opts;
 
273
      const char  *case_name, *dir_name;
 
274
      const char empty[] = "";
 
275
      char frequency_s[80] = "";
 
276
 
 
277
      const cs_post_writer_t  *writer = _cs_post_writers + i;
 
278
 
 
279
      if (writer->wd != NULL) {
 
280
        const cs_post_writer_def_t *wd = writer->wd;
 
281
        fmt_id = wd->fmt_id;
 
282
        time_dep = wd->time_dep;
 
283
        fmt_opts = wd->fmt_opts;
 
284
        case_name = wd->case_name;
 
285
        dir_name = wd->dir_name;
 
286
      }
 
287
      else if (writer->writer != NULL) {
 
288
        const fvm_writer_t *w = writer->writer;
 
289
        fmt_id = fvm_writer_get_format_id(fvm_writer_get_format(w));
 
290
        time_dep = fvm_writer_get_time_dep(w);
 
291
        case_name = fvm_writer_get_name(w);
 
292
        fmt_opts = fvm_writer_get_options(w);
 
293
        dir_name = fvm_writer_get_path(w);
 
294
      }
 
295
      if (fmt_opts == NULL)
 
296
        fmt_opts = empty;
 
297
 
 
298
      n_fmt_str = fvm_writer_n_version_strings(fmt_id);
 
299
      if (n_fmt_str == 0)
 
300
        fmt_name = fvm_writer_format_name(fmt_id);
 
301
      else
 
302
        fmt_name = fvm_writer_version_string(fmt_id, 0, 0);
 
303
 
 
304
      if (writer->output_end != 0) {
 
305
        if (writer->frequency_t > 0)
 
306
          snprintf(frequency_s, 79,
 
307
                   _("every %12.5e s and at calculation end"),
 
308
                   writer->frequency_t);
 
309
        else if (writer->frequency_n >= 0)
 
310
          snprintf(frequency_s, 79,
 
311
                   _("every %d time steps and at calculation end"),
 
312
                   writer->frequency_n);
 
313
        else
 
314
          snprintf(frequency_s, 79, _("at calculation end"));
 
315
      }
 
316
      else {
 
317
        if (writer->frequency_t > 0)
 
318
          snprintf(frequency_s, 79, _("every %12.5e s"),
 
319
                   writer->frequency_t);
 
320
        else if (writer->frequency_n >= 0)
 
321
          snprintf(frequency_s, 79, _("every %d time steps"),
 
322
                   writer->frequency_n);
 
323
      }
 
324
      frequency_s[79] = '\0';
 
325
 
 
326
      bft_printf(_("  %2d: name: %s\n"
 
327
                   "      directory: %s\n"
 
328
                   "      format: %s\n"
 
329
                   "      options: %s\n"
 
330
                   "      time dependency: %s\n"
 
331
                   "      output: %s\n\n"),
 
332
                 writer->id, case_name, dir_name, fmt_name, fmt_opts,
 
333
                 _(fvm_writer_time_dep_name[time_dep]), frequency_s);
 
334
    }
 
335
  }
 
336
}
 
337
 
 
338
/*----------------------------------------------------------------------------
 
339
 * Initialize a writer; this creates the FVM writer structure, and
 
340
 * clears the temporary writer definition information.
 
341
 *
 
342
 * parameters:
 
343
 *   writer <-> pointer to writer structure
 
344
 *----------------------------------------------------------------------------*/
 
345
 
 
346
static void
 
347
_init_writer(cs_post_writer_t  *writer)
 
348
{
 
349
  assert(writer != NULL);
 
350
 
 
351
  if (writer->writer == NULL) {
 
352
    cs_post_writer_def_t  *wd = writer->wd;
 
353
    assert(writer->wd != NULL);
 
354
    writer->writer = fvm_writer_init(wd->case_name,
 
355
                                     wd->dir_name,
 
356
                                     fvm_writer_format_name(wd->fmt_id),
 
357
                                     wd->fmt_opts,
 
358
                                     wd->time_dep);
 
359
    _destroy_writer_def(writer);
 
360
  }
 
361
}
 
362
 
 
363
/*----------------------------------------------------------------------------
203
364
 * Convert cs_post_type_t datatype to fvm_datatype_t.
204
365
 *
205
366
 * parameters:
316
477
}
317
478
 
318
479
/*----------------------------------------------------------------------------
319
 
 * Add a post-processing mesh, do basic initialization, and return a pointer
320
 
 * to the associated structure
321
 
 *
322
 
 * parameters:
323
 
 *   mesh_id <-- requested mesh id
 
480
 * Search for position in the array of meshes of a mesh with a given id,
 
481
 * allowing the id not to be present
 
482
 *
 
483
 * parameters:
 
484
 *   mesh_id <-- id of mesh
 
485
 *
 
486
 * returns:
 
487
 *   position in the array of meshes, or -1
 
488
 *----------------------------------------------------------------------------*/
 
489
 
 
490
static int
 
491
_cs_post_mesh_id_try(int  mesh_id)
 
492
{
 
493
  int id;
 
494
  cs_post_mesh_t  *post_mesh = NULL;
 
495
 
 
496
  /* Search for requested mesh */
 
497
 
 
498
  for (id = 0; id < _cs_post_n_meshes; id++) {
 
499
    post_mesh = _cs_post_meshes + id;
 
500
    if (post_mesh->id == mesh_id)
 
501
      break;
 
502
  }
 
503
  if (id >= _cs_post_n_meshes)
 
504
    id = -1;
 
505
 
 
506
  return id;
 
507
}
 
508
 
 
509
/*----------------------------------------------------------------------------
 
510
 * Add or select a post-processing mesh, do basic initialization, and return
 
511
 * a pointer to the associated structure
 
512
 *
 
513
 * parameters:
 
514
 *   mesh_id    <-- requested mesh id
 
515
 *   n_writers  <-- number of associated writers
 
516
 *   writer_ids <-- ids of associated writers
324
517
 *
325
518
 * returns:
326
519
 *   pointer to associated structure
327
520
 *----------------------------------------------------------------------------*/
328
521
 
329
522
static cs_post_mesh_t *
330
 
_cs_post_add_mesh(int  mesh_id)
 
523
_predefine_mesh(int        mesh_id,
 
524
                int        n_writers,
 
525
                const int  writer_ids[])
331
526
{
332
527
  /* local variables */
333
528
 
334
 
  int    i, j;
 
529
  int  i, j;
335
530
 
336
531
  cs_post_mesh_t  *post_mesh = NULL;
337
532
 
343
538
                  "must be < 0 (reserved) or > 0 (user).\n"));
344
539
 
345
540
  for (i = 0; i < _cs_post_n_meshes; i++) {
346
 
    if ((_cs_post_meshes + i)->id == mesh_id)
347
 
      bft_error(__FILE__, __LINE__, 0,
348
 
                _("The requested post-processing mesh number\n"
349
 
                  "(%d) has already been assigned.\n"), (int)mesh_id);
350
 
  }
351
 
 
352
 
  /* Resize global array of exportable meshes */
353
 
 
354
 
  if (_cs_post_n_meshes == _cs_post_n_meshes_max) {
355
 
 
356
 
    if (_cs_post_n_meshes_max == 0)
357
 
      _cs_post_n_meshes_max = 8;
358
 
    else
359
 
      _cs_post_n_meshes_max *= 2;
360
 
 
361
 
    BFT_REALLOC(_cs_post_meshes,
362
 
                _cs_post_n_meshes_max,
363
 
                cs_post_mesh_t);
364
 
 
365
 
  }
366
 
 
367
 
  _cs_post_n_meshes += 1;
 
541
    if ((_cs_post_meshes + i)->id == mesh_id) {
 
542
 
 
543
      post_mesh = _cs_post_meshes + i;
 
544
 
 
545
      BFT_FREE(post_mesh->name);
 
546
      for (j = 0; j < 3; j++)
 
547
        BFT_FREE(post_mesh->criteria[j]);
 
548
      BFT_FREE(post_mesh->writer_id);
 
549
 
 
550
      post_mesh->exp_mesh = NULL;
 
551
      if (post_mesh->_exp_mesh != NULL)
 
552
        post_mesh->_exp_mesh = fvm_nodal_destroy(post_mesh->_exp_mesh);
 
553
 
 
554
      break;
 
555
 
 
556
    }
 
557
  }
 
558
 
 
559
  if (i == _cs_post_n_meshes) {
 
560
 
 
561
    /* Resize global array of exportable meshes */
 
562
 
 
563
    if (_cs_post_n_meshes == _cs_post_n_meshes_max) {
 
564
      if (_cs_post_n_meshes_max == 0)
 
565
        _cs_post_n_meshes_max = 8;
 
566
      else
 
567
        _cs_post_n_meshes_max *= 2;
 
568
      BFT_REALLOC(_cs_post_meshes,
 
569
                  _cs_post_n_meshes_max,
 
570
                  cs_post_mesh_t);
 
571
    }
 
572
 
 
573
    post_mesh = _cs_post_meshes + i;
 
574
 
 
575
    _cs_post_n_meshes += 1;
 
576
  }
368
577
 
369
578
  if (mesh_id < _cs_post_min_mesh_id)
370
579
    _cs_post_min_mesh_id = mesh_id;
371
580
 
372
581
  /* Assign newly created mesh to the structure */
373
582
 
374
 
  post_mesh = _cs_post_meshes + _cs_post_n_meshes - 1;
375
 
 
376
583
  post_mesh->id = mesh_id;
 
584
  post_mesh->name = NULL;
377
585
  post_mesh->cat_id = mesh_id;
378
586
  post_mesh->alias = -1;
379
587
 
380
588
  post_mesh->n_writers = 0;
381
589
  post_mesh->writer_id = NULL;
382
590
 
383
 
  post_mesh->nt_last = -1;
384
 
 
385
 
  for (j = 0; j < 3; j++)
 
591
  post_mesh->nt_last = -2;
 
592
 
 
593
  post_mesh->add_groups = false;
 
594
 
 
595
  for (j = 0; j < 3; j++) {
 
596
    post_mesh->criteria[j] = NULL;
386
597
    post_mesh->ent_flag[j] = 0;
 
598
  }
387
599
 
388
600
  post_mesh->n_i_faces = 0;
389
601
  post_mesh->n_b_faces = 0;
397
609
  post_mesh->mod_flag_min = FVM_WRITER_TRANSIENT_CONNECT;
398
610
  post_mesh->mod_flag_max = FVM_WRITER_FIXED_MESH;
399
611
 
 
612
  /* Associate mesh with writers */
 
613
 
 
614
  post_mesh->n_writers = n_writers;
 
615
  BFT_MALLOC(post_mesh->writer_id, n_writers, int);
 
616
 
 
617
  for (i = 0; i < n_writers; i++) {
 
618
 
 
619
    fvm_writer_time_dep_t mod_flag;
 
620
    int _writer_id = _cs_post_writer_id(writer_ids[i]);
 
621
    cs_post_writer_t  *writer = _cs_post_writers + _writer_id;
 
622
 
 
623
    post_mesh->writer_id[i] = _writer_id;
 
624
 
 
625
    if (writer->wd != NULL)
 
626
      mod_flag = writer->wd->time_dep;
 
627
    else
 
628
      mod_flag = fvm_writer_get_time_dep(writer->writer);
 
629
 
 
630
    if (mod_flag < post_mesh->mod_flag_min)
 
631
      post_mesh->mod_flag_min = mod_flag;
 
632
    if (mod_flag > post_mesh->mod_flag_max)
 
633
      post_mesh->mod_flag_max = mod_flag;
 
634
 
 
635
  }
 
636
 
400
637
  return post_mesh;
401
638
}
402
639
 
403
640
/*----------------------------------------------------------------------------
 
641
 * Free a postprocessing mesh's data.
 
642
 *
 
643
 * parameters:
 
644
 *   _mesh_id <-- local id of mesh to remove
 
645
 *----------------------------------------------------------------------------*/
 
646
 
 
647
static void
 
648
_free_mesh(int _mesh_id)
 
649
{
 
650
  int i;
 
651
  cs_post_mesh_t  *post_mesh = _cs_post_meshes + _mesh_id;
 
652
 
 
653
  if (post_mesh->_exp_mesh != NULL)
 
654
    post_mesh->_exp_mesh = fvm_nodal_destroy(post_mesh->_exp_mesh);
 
655
 
 
656
  BFT_FREE(post_mesh->writer_id);
 
657
  post_mesh->n_writers = 0;
 
658
 
 
659
  for (i = 0; i < 3; i++)
 
660
    BFT_FREE(post_mesh->criteria[i]);
 
661
 
 
662
  BFT_FREE(post_mesh->name);
 
663
 
 
664
  /* Shift remaining meshes */
 
665
 
 
666
  for (i = _mesh_id + 1; i < _cs_post_n_meshes; i++) {
 
667
    post_mesh = _cs_post_meshes + i;
 
668
    if (post_mesh->alias > -1 && post_mesh->alias > _mesh_id)
 
669
      post_mesh->alias -= 1;
 
670
    _cs_post_meshes[i-1] = _cs_post_meshes[i];
 
671
  }
 
672
  _cs_post_n_meshes -= 1;
 
673
}
 
674
 
 
675
/*----------------------------------------------------------------------------
 
676
 * Check and possibly fix postprocessing mesh category id once we have
 
677
 * knowledge of entity counts.
 
678
 *
 
679
 * parameters:
 
680
 *   post_mesh <-> pointer to partially initialized post-processing mesh
 
681
 *----------------------------------------------------------------------------*/
 
682
 
 
683
static void
 
684
_check_mesh_cat_id(cs_post_mesh_t  *post_mesh)
 
685
{
 
686
  if (post_mesh->cat_id == -1 || post_mesh->cat_id == -1) {
 
687
    const int *ef = post_mesh->ent_flag;
 
688
    if (ef[0] == 1 && ef[1] == 0 && ef[2] == 0)
 
689
      post_mesh->cat_id = -1;
 
690
    else if (ef[0] == 0 && ef[1] == 0 && ef[2] == 1)
 
691
      post_mesh->cat_id = -2;
 
692
  }
 
693
}
 
694
 
 
695
/*----------------------------------------------------------------------------
404
696
 * Create a post-processing mesh; lists of cells or faces to extract are
405
697
 * sorted upon exit, whether they were sorted upon calling or not.
406
698
 *
411
703
 * Lists of faces are ignored if the number of extracted cells is nonzero;
412
704
 * otherwise, if the number of boundary faces to extract is equal to the
413
705
 * number of boundary faces in the computational mesh, and the number of
414
 
 * interior faces to extract is zero, than we extrac by default the boundary
 
706
 * interior faces to extract is zero, then we extract by default the boundary
415
707
 * mesh, and the list of associated boundary faces is thus not necessary.
416
708
 *
417
709
 * parameters:
418
710
 *   post_mesh   <-> pointer to partially initialized post-processing mesh
419
 
 *   mesh_name   <-- associated mesh name
420
711
 *   n_cells     <-- number of associated cells
421
712
 *   n_i_faces   <-- number of associated interior faces
422
713
 *   n_b_faces   <-- number of associated boundary faces
426
717
 *----------------------------------------------------------------------------*/
427
718
 
428
719
static void
429
 
_cs_post_define_mesh(cs_post_mesh_t  *post_mesh,
430
 
                     const char      *mesh_name,
431
 
                     cs_int_t         n_cells,
432
 
                     cs_int_t         n_i_faces,
433
 
                     cs_int_t         n_b_faces,
434
 
                     cs_int_t         cell_list[],
435
 
                     cs_int_t         i_face_list[],
436
 
                     cs_int_t         b_face_list[])
 
720
_define_export_mesh(cs_post_mesh_t  *post_mesh,
 
721
                    fvm_lnum_t       n_cells,
 
722
                    fvm_lnum_t       n_i_faces,
 
723
                    fvm_lnum_t       n_b_faces,
 
724
                    fvm_lnum_t       cell_list[],
 
725
                    fvm_lnum_t       i_face_list[],
 
726
                    fvm_lnum_t       b_face_list[])
437
727
{
438
728
  /* local variables */
439
729
 
490
780
 
491
781
    if (glob_flag[3] == 1)
492
782
      exp_mesh = cs_mesh_connect_cells_to_nodal(cs_glob_mesh,
493
 
                                                mesh_name,
 
783
                                                post_mesh->name,
 
784
                                                post_mesh->add_groups,
494
785
                                                cs_glob_mesh->n_cells,
495
786
                                                NULL);
496
787
    else
497
788
      exp_mesh = cs_mesh_connect_cells_to_nodal(cs_glob_mesh,
498
 
                                                mesh_name,
 
789
                                                post_mesh->name,
 
790
                                                post_mesh->add_groups,
499
791
                                                n_cells,
500
792
                                                cell_list);
501
793
 
504
796
 
505
797
    if (glob_flag[4] == 1)
506
798
      exp_mesh = cs_mesh_connect_faces_to_nodal(cs_glob_mesh,
507
 
                                                mesh_name,
 
799
                                                post_mesh->name,
 
800
                                                post_mesh->add_groups,
508
801
                                                0,
509
802
                                                cs_glob_mesh->n_b_faces,
510
803
                                                NULL,
511
804
                                                NULL);
512
805
    else
513
806
      exp_mesh = cs_mesh_connect_faces_to_nodal(cs_glob_mesh,
514
 
                                                mesh_name,
 
807
                                                post_mesh->name,
 
808
                                                post_mesh->add_groups,
515
809
                                                n_i_faces,
516
810
                                                n_b_faces,
517
811
                                                i_face_list,
547
841
 
548
842
  post_mesh->exp_mesh = exp_mesh;
549
843
  post_mesh->_exp_mesh = exp_mesh;
550
 
}
551
 
 
552
 
/*----------------------------------------------------------------------------
553
 
 * Update mesh time dependency flags in case of an alias based on the
554
 
 * associated writer properties:
 
844
 
 
845
  /* Fix category id now that we have knowledge of entity counts */
 
846
 
 
847
  _check_mesh_cat_id(post_mesh);
 
848
}
 
849
 
 
850
/*----------------------------------------------------------------------------
 
851
 * Initialize a post-processing mesh based on its definition.
 
852
 *
 
853
 * parameters:
 
854
 *   post_mesh <-> pointer to partially initialized post-processing mesh
 
855
 *----------------------------------------------------------------------------*/
 
856
 
 
857
static void
 
858
_define_mesh_from_criteria(cs_post_mesh_t *post_mesh)
 
859
{
 
860
  fvm_lnum_t n_cells = 0, n_i_faces = 0, n_b_faces = 0;
 
861
  fvm_lnum_t *cell_list = NULL, *i_face_list = NULL, *b_face_list = NULL;
 
862
 
 
863
  const cs_mesh_t *mesh = cs_glob_mesh;
 
864
 
 
865
  assert(post_mesh != NULL);
 
866
 
 
867
  /* Define element lists based on selection criteria */
 
868
 
 
869
  if (post_mesh->criteria[0] != NULL) {
 
870
    const char *criteria = post_mesh->criteria[0];
 
871
    if (!strcmp(criteria, "all[]"))
 
872
      n_cells = mesh->n_cells;
 
873
    else {
 
874
      BFT_MALLOC(cell_list, mesh->n_cells, fvm_lnum_t);
 
875
      cs_selector_get_cell_list(criteria, &n_cells, cell_list);
 
876
    }
 
877
  }
 
878
 
 
879
  if (post_mesh->criteria[1] != NULL) {
 
880
    const char *criteria = post_mesh->criteria[1];
 
881
    if (!strcmp(criteria, "all[]"))
 
882
      n_i_faces = mesh->n_i_faces;
 
883
    else {
 
884
      BFT_MALLOC(i_face_list, mesh->n_i_faces, fvm_lnum_t);
 
885
      cs_selector_get_i_face_list(criteria, &n_i_faces, i_face_list);
 
886
    }
 
887
  }
 
888
 
 
889
  if (post_mesh->criteria[2] != NULL) {
 
890
    const char *criteria = post_mesh->criteria[2];
 
891
    if (!strcmp(criteria, "all[]"))
 
892
      n_b_faces = mesh->n_b_faces;
 
893
    else {
 
894
      BFT_MALLOC(b_face_list, mesh->n_b_faces, fvm_lnum_t);
 
895
      cs_selector_get_b_face_list(criteria, &n_b_faces, b_face_list);
 
896
    }
 
897
  }
 
898
 
 
899
  /* Define mesh based on current arguments */
 
900
 
 
901
  _define_export_mesh(post_mesh,
 
902
                      n_cells,
 
903
                      n_i_faces,
 
904
                      n_b_faces,
 
905
                      cell_list,
 
906
                      i_face_list,
 
907
                      b_face_list);
 
908
 
 
909
  BFT_FREE(cell_list);
 
910
  BFT_FREE(i_face_list);
 
911
  BFT_FREE(b_face_list);
 
912
}
 
913
 
 
914
/*----------------------------------------------------------------------------
 
915
 * Remove meshes which are associated with no writer and are not aliased.
 
916
 *----------------------------------------------------------------------------*/
 
917
 
 
918
static void
 
919
_clear_unused_meshes(void)
 
920
{
 
921
  int  i;
 
922
  int *discard = NULL;
 
923
 
 
924
  cs_post_mesh_t  *post_mesh;
 
925
 
 
926
  /* Mark used meshes, not forgetting aliases */
 
927
 
 
928
  BFT_MALLOC(discard, _cs_post_n_meshes, int);
 
929
 
 
930
  for (i = 0; i < _cs_post_n_meshes; i++) {
 
931
    post_mesh = _cs_post_meshes + i;
 
932
    if (post_mesh->n_writers == 0)
 
933
      discard[i] = 1;
 
934
    else
 
935
      discard[i] = 0;
 
936
  }
 
937
 
 
938
  for (i = 0; i < _cs_post_n_meshes; i++) {
 
939
    post_mesh = _cs_post_meshes + i;
 
940
    if (post_mesh->alias > -1) {
 
941
      if (post_mesh->n_writers > 0)
 
942
        discard[post_mesh->alias] = 0;
 
943
    }
 
944
  }
 
945
 
 
946
  /* Discard meshes not required, compacting array */
 
947
 
 
948
  for (i = _cs_post_n_meshes - 1; i >= 0; i--) {
 
949
    if (discard[i] == 1)
 
950
      _free_mesh(i);  /* shifts other meshes and reduces _cs_post_n_meshes */
 
951
  }
 
952
 
 
953
  BFT_FREE(discard);
 
954
}
 
955
 
 
956
/*----------------------------------------------------------------------------
 
957
 * Update mesh metadata in case of an alias based on the associated writer
 
958
 * and mesh properties:
555
959
 *
556
960
 * A mesh's definition may not be modified if the minimum time dependency
557
961
 * flag is too low (i.e. if one of the associated writers does not allow
560
964
 * Vertex coordinates and connectivity can be freed from memory if the
561
965
 * maximum time dependency flag is low enough (i.e. if none of the associated
562
966
 * writers allows modification of the mesh, and thus its future output).
563
 
 *
564
 
 * parameters:
565
 
 *   mesh_id <-- associated mesh (alias) id
566
967
 *----------------------------------------------------------------------------*/
567
968
 
568
969
static void
569
 
_cs_post_mod_flag_alias(int  mesh_id)
 
970
_update_alias_metadata(void)
570
971
{
571
 
  int  i;
572
 
 
573
 
  cs_post_mesh_t  *post_mesh = NULL;
574
 
  cs_post_mesh_t  *ref_mesh = NULL;
575
 
 
576
 
  /* Update reference */
577
 
 
578
 
  post_mesh = _cs_post_meshes + mesh_id;
579
 
 
580
 
  if (post_mesh->alias > -1) {
581
 
 
582
 
    ref_mesh = _cs_post_meshes + post_mesh->alias;
583
 
 
584
 
    if (post_mesh->mod_flag_min < ref_mesh->mod_flag_min)
585
 
      ref_mesh->mod_flag_min = post_mesh->mod_flag_min;
586
 
 
587
 
    if (post_mesh->mod_flag_max < ref_mesh->mod_flag_max)
588
 
      ref_mesh->mod_flag_max = post_mesh->mod_flag_max;
 
972
  int  i, j;
 
973
  cs_post_mesh_t  *post_mesh, *ref_mesh;
 
974
 
 
975
  /* First pass on aliases */
 
976
 
 
977
  for (i = 0; i < _cs_post_n_meshes; i++) {
 
978
 
 
979
    post_mesh = _cs_post_meshes + i;
 
980
 
 
981
    if (post_mesh->alias > -1) {
 
982
 
 
983
      ref_mesh = _cs_post_meshes + post_mesh->alias;
 
984
 
 
985
      for (j = 0; j < 3; j++)
 
986
        post_mesh->ent_flag[j] = ref_mesh->ent_flag[j];
 
987
 
 
988
      post_mesh->n_i_faces = ref_mesh->n_i_faces;
 
989
      post_mesh->n_b_faces = ref_mesh->n_b_faces;
 
990
 
 
991
      post_mesh->exp_mesh = ref_mesh->exp_mesh;
 
992
 
 
993
      /* Update reference mesh modification flags */
 
994
 
 
995
      if (ref_mesh->mod_flag_min > post_mesh->mod_flag_min)
 
996
        ref_mesh->mod_flag_min = post_mesh->mod_flag_min;
 
997
 
 
998
      if (ref_mesh->mod_flag_max < post_mesh->mod_flag_max)
 
999
        ref_mesh->mod_flag_max = post_mesh->mod_flag_max;
 
1000
 
 
1001
    }
589
1002
 
590
1003
  }
591
1004
 
592
 
  /* Update alias */
 
1005
  /* Second pass on aliases to update their mesh modification flags */
593
1006
 
594
1007
  for (i = 0; i < _cs_post_n_meshes; i++) {
595
1008
 
602
1015
      if (post_mesh->mod_flag_min > ref_mesh->mod_flag_min)
603
1016
        post_mesh->mod_flag_min = ref_mesh->mod_flag_min;
604
1017
 
605
 
      if (post_mesh->mod_flag_max > ref_mesh->mod_flag_max)
 
1018
      if (post_mesh->mod_flag_max < ref_mesh->mod_flag_max)
606
1019
        post_mesh->mod_flag_max = ref_mesh->mod_flag_max;
607
1020
    }
608
1021
 
609
1022
  }
610
 
 
611
1023
}
612
1024
 
613
1025
/*----------------------------------------------------------------------------
619
1031
 *----------------------------------------------------------------------------*/
620
1032
 
621
1033
static void
622
 
_cs_post_divide_poly(cs_post_mesh_t          *post_mesh,
623
 
                     const cs_post_writer_t  *writer)
624
 
{
625
 
  /* Divide polygons or polyhedra into simple elements */
626
 
 
627
 
  if (fvm_writer_needs_tesselation(writer->writer,
628
 
                                   post_mesh->exp_mesh,
629
 
                                   FVM_CELL_POLY) > 0)
630
 
    fvm_nodal_tesselate(post_mesh->_exp_mesh,
631
 
                        FVM_CELL_POLY,
632
 
                        NULL);
633
 
 
634
 
  if (fvm_writer_needs_tesselation(writer->writer,
635
 
                                   post_mesh->exp_mesh,
636
 
                                   FVM_FACE_POLY) > 0)
637
 
    fvm_nodal_tesselate(post_mesh->_exp_mesh,
638
 
                        FVM_FACE_POLY,
639
 
                        NULL);
640
 
}
641
 
 
642
 
/*----------------------------------------------------------------------------
643
 
 * Assemble variable values defined on a mix of interior and boundary
644
 
 * faces (with no indirection) into an array defined on a single faces set.
645
 
 *
646
 
 * The resulting variable is not interlaced.
647
 
 *
648
 
 * parameters:
649
 
 *   exp_mesh    <-- exportable mesh
650
 
 *   n_i_faces   <-- number of interior faces
651
 
 *   n_b_faces   <-- number of boundary faces
652
 
 *   var_dim     <-- varible dimension
653
 
 *   interlace   <-- for vector, interlace if 1, no interlace if 0
654
 
 *   i_face_vals <-- values at interior faces
655
 
 *   b_face_vals <-- values at boundary faces
656
 
 *   var_tmp[]   --> assembled values
657
 
 *----------------------------------------------------------------------------*/
658
 
 
659
 
static void
660
 
_cs_post_assmb_var_faces(const fvm_nodal_t  *exp_mesh,
661
 
                         cs_int_t            n_i_faces,
662
 
                         cs_int_t            n_b_faces,
663
 
                         int                 var_dim,
664
 
                         fvm_interlace_t     interlace,
665
 
                         const cs_real_t     i_face_vals[],
666
 
                         const cs_real_t     b_face_vals[],
667
 
                         cs_real_t           var_tmp[])
668
 
{
669
 
  cs_int_t  i, j, stride_1, stride_2;
670
 
 
671
 
  cs_int_t  n_elts = n_i_faces + n_b_faces;
672
 
 
673
 
  assert(exp_mesh != NULL);
674
 
 
675
 
  /* The variable is defined on interior and boundary faces of the
676
 
     post-processing mesh, and has been built using values
677
 
     at the corresponding interior and boundary faces */
678
 
 
679
 
  /* Boundary faces contribution */
680
 
 
681
 
  if (interlace == FVM_INTERLACE) {
682
 
    stride_1 = var_dim;
683
 
    stride_2 = 1;
684
 
  }
685
 
  else {
686
 
    stride_1 = 1;
687
 
    stride_2 = n_b_faces;
688
 
  }
689
 
 
690
 
  for (i = 0; i < n_b_faces; i++) {
691
 
    for (j = 0; j < var_dim; j++)
692
 
      var_tmp[i + j*n_elts] = b_face_vals[i*stride_1 + j*stride_2];
693
 
  }
694
 
 
695
 
  /* Interior faces contribution */
696
 
 
697
 
  if (interlace == FVM_INTERLACE) {
698
 
    stride_1 = var_dim;
699
 
    stride_2 = 1;
700
 
  }
701
 
  else {
702
 
    stride_1 = 1;
703
 
    stride_2 = n_i_faces;
704
 
  }
705
 
 
706
 
  for (i = 0; i < n_i_faces; i++) {
707
 
    for (j = 0; j < var_dim; j++)
708
 
      var_tmp[i + n_b_faces + j*n_elts] = i_face_vals[i*stride_1 + j*stride_2];
709
 
  }
710
 
 
 
1034
_divide_poly(cs_post_mesh_t    *post_mesh,
 
1035
             cs_post_writer_t  *writer)
 
1036
{
 
1037
  if (fvm_writer_needs_tesselation(writer->writer,
 
1038
                                   post_mesh->exp_mesh,
 
1039
                                   FVM_CELL_POLY) > 0) {
 
1040
 
 
1041
    fvm_nodal_t *exp_mesh = post_mesh->_exp_mesh;
 
1042
    if (post_mesh->alias > -1)
 
1043
      exp_mesh = (_cs_post_meshes + post_mesh->alias)->_exp_mesh;
 
1044
 
 
1045
    fvm_nodal_tesselate(exp_mesh, FVM_CELL_POLY, NULL);
 
1046
 
 
1047
  }
 
1048
 
 
1049
  if (fvm_writer_needs_tesselation(writer->writer,
 
1050
                                   post_mesh->exp_mesh,
 
1051
                                   FVM_FACE_POLY) > 0) {
 
1052
 
 
1053
    fvm_nodal_t *exp_mesh = post_mesh->_exp_mesh;
 
1054
    if (post_mesh->alias > -1)
 
1055
      exp_mesh = (_cs_post_meshes + post_mesh->alias)->_exp_mesh;
 
1056
 
 
1057
    fvm_nodal_tesselate(exp_mesh, FVM_FACE_POLY, NULL);
 
1058
  }
711
1059
}
712
1060
 
713
1061
/*----------------------------------------------------------------------------
798
1146
                    double           t_cur_abs)
799
1147
{
800
1148
  int  j;
801
 
  cs_bool_t  write_mesh;
802
1149
  fvm_writer_time_dep_t  time_dep;
 
1150
  cs_bool_t  write_mesh = false;
803
1151
 
804
1152
  cs_post_writer_t *writer = NULL;
805
1153
 
809
1157
 
810
1158
    writer = _cs_post_writers + post_mesh->writer_id[j];
811
1159
 
812
 
    time_dep = fvm_writer_get_time_dep(writer->writer);
 
1160
    if (writer->wd != NULL)
 
1161
      time_dep = writer->wd->time_dep;
 
1162
    else
 
1163
      time_dep = fvm_writer_get_time_dep(writer->writer);
813
1164
 
814
1165
    write_mesh = false;
815
1166
 
816
1167
    if (time_dep == FVM_WRITER_FIXED_MESH) {
817
 
      if (post_mesh->nt_last < 0)
 
1168
      if (post_mesh->nt_last < -1)
818
1169
        write_mesh = true;
819
1170
    }
820
1171
    else {
822
1173
        write_mesh = true;
823
1174
    }
824
1175
 
825
 
    /* Mesh has already been output when associated with writers
826
 
       allowing only fixed meshes; for other writers, output it */
827
 
 
828
 
    if (write_mesh == true && time_dep != FVM_WRITER_FIXED_MESH) {
 
1176
    if (write_mesh == true) {
 
1177
 
 
1178
      if (writer->writer == NULL)
 
1179
        _init_writer(writer);
 
1180
 
 
1181
      _divide_poly(post_mesh, writer);
 
1182
 
829
1183
      fvm_writer_set_mesh_time(writer->writer, nt_cur_abs, t_cur_abs);
830
1184
      fvm_writer_export_nodal(writer->writer, post_mesh->exp_mesh);
 
1185
 
 
1186
      if (nt_cur_abs >= 0) {
 
1187
        writer->n_last = nt_cur_abs;
 
1188
        writer->t_last = t_cur_abs;
 
1189
      }
 
1190
 
831
1191
    }
832
1192
 
833
 
    if (write_mesh == true && post_mesh->id == -1)
 
1193
    if (write_mesh == true && (post_mesh->id == -1 || post_mesh->id == -2)) {
 
1194
 
834
1195
      _cs_post_write_domain(writer->writer,
835
1196
                            post_mesh->exp_mesh,
836
1197
                            nt_cur_abs,
837
1198
                            t_cur_abs);
838
1199
 
 
1200
      if (nt_cur_abs >= 0) {
 
1201
        writer->n_last = nt_cur_abs;
 
1202
        writer->t_last = t_cur_abs;
 
1203
      }
 
1204
 
 
1205
    }
 
1206
 
839
1207
  }
840
1208
 
841
1209
  if (write_mesh == true)
847
1215
}
848
1216
 
849
1217
/*----------------------------------------------------------------------------
 
1218
 * Assemble variable values defined on a mix of interior and boundary
 
1219
 * faces (with no indirection) into an array defined on a single faces set.
 
1220
 *
 
1221
 * The resulting variable is not interlaced.
 
1222
 *
 
1223
 * parameters:
 
1224
 *   exp_mesh    <-- exportable mesh
 
1225
 *   n_i_faces   <-- number of interior faces
 
1226
 *   n_b_faces   <-- number of boundary faces
 
1227
 *   var_dim     <-- varible dimension
 
1228
 *   interlace   <-- for vector, interlace if 1, no interlace if 0
 
1229
 *   i_face_vals <-- values at interior faces
 
1230
 *   b_face_vals <-- values at boundary faces
 
1231
 *   var_tmp[]   --> assembled values
 
1232
 *----------------------------------------------------------------------------*/
 
1233
 
 
1234
static void
 
1235
_cs_post_assmb_var_faces(const fvm_nodal_t  *exp_mesh,
 
1236
                         cs_int_t            n_i_faces,
 
1237
                         cs_int_t            n_b_faces,
 
1238
                         int                 var_dim,
 
1239
                         fvm_interlace_t     interlace,
 
1240
                         const cs_real_t     i_face_vals[],
 
1241
                         const cs_real_t     b_face_vals[],
 
1242
                         cs_real_t           var_tmp[])
 
1243
{
 
1244
  cs_int_t  i, j, stride_1, stride_2;
 
1245
 
 
1246
  cs_int_t  n_elts = n_i_faces + n_b_faces;
 
1247
 
 
1248
  assert(exp_mesh != NULL);
 
1249
 
 
1250
  /* The variable is defined on interior and boundary faces of the
 
1251
     post-processing mesh, and has been built using values
 
1252
     at the corresponding interior and boundary faces */
 
1253
 
 
1254
  /* Boundary faces contribution */
 
1255
 
 
1256
  if (interlace == FVM_INTERLACE) {
 
1257
    stride_1 = var_dim;
 
1258
    stride_2 = 1;
 
1259
  }
 
1260
  else {
 
1261
    stride_1 = 1;
 
1262
    stride_2 = n_b_faces;
 
1263
  }
 
1264
 
 
1265
  for (i = 0; i < n_b_faces; i++) {
 
1266
    for (j = 0; j < var_dim; j++)
 
1267
      var_tmp[i + j*n_elts] = b_face_vals[i*stride_1 + j*stride_2];
 
1268
  }
 
1269
 
 
1270
  /* Interior faces contribution */
 
1271
 
 
1272
  if (interlace == FVM_INTERLACE) {
 
1273
    stride_1 = var_dim;
 
1274
    stride_2 = 1;
 
1275
  }
 
1276
  else {
 
1277
    stride_1 = 1;
 
1278
    stride_2 = n_i_faces;
 
1279
  }
 
1280
 
 
1281
  for (i = 0; i < n_i_faces; i++) {
 
1282
    for (j = 0; j < var_dim; j++)
 
1283
      var_tmp[i + n_b_faces + j*n_elts] = i_face_vals[i*stride_1 + j*stride_2];
 
1284
  }
 
1285
 
 
1286
}
 
1287
 
 
1288
/*----------------------------------------------------------------------------
850
1289
 * Transform an array of flags (markers) to a list
851
1290
 *
852
1291
 * parameters:
905
1344
 
906
1345
  for (j = 0; j < _cs_post_n_writers; j++) {
907
1346
    writer = _cs_post_writers + j;
908
 
    if (writer->active == 1 && writer->write_displ == true)
 
1347
    if (writer->active == 1)
909
1348
      break;
910
1349
  }
911
1350
  if (j == _cs_post_n_writers)
944
1383
 
945
1384
      writer = _cs_post_writers + post_mesh->writer_id[j];
946
1385
 
947
 
      if (writer->active == 1 && writer->write_displ == true) {
 
1386
      if (writer->active == 1) {
948
1387
 
949
1388
        fvm_writer_export_field(writer->writer,
950
1389
                                post_mesh->exp_mesh,
959
1398
                                (double)t_cur_abs,
960
1399
                                (const void * *)var_ptr);
961
1400
 
 
1401
        if (nt_cur_abs >= 0) {
 
1402
          writer->n_last = nt_cur_abs;
 
1403
          writer->t_last = t_cur_abs;
 
1404
        }
 
1405
 
962
1406
      }
963
1407
 
964
1408
    }
970
1414
  BFT_FREE(deplacements);
971
1415
}
972
1416
 
 
1417
/*----------------------------------------------------------------------------
 
1418
 * Generate global group flags array from local family flags
 
1419
 *
 
1420
 * The caller should free the returned array once it is no longer needed.
 
1421
 *
 
1422
 * parameters:
 
1423
 *   mesh     <-- pointer to mesh structure
 
1424
 *   fam_flag <-- flag values (size: mesh->n_families + 1)
 
1425
 *
 
1426
 * returns:
 
1427
 *   group flag (size: mesh->n_groups)
 
1428
 *----------------------------------------------------------------------------*/
 
1429
 
 
1430
static char *
 
1431
_build_group_flag(const cs_mesh_t  *mesh,
 
1432
                  int              *fam_flag)
 
1433
{
 
1434
  int i, j;
 
1435
 
 
1436
  char *group_flag = NULL;
 
1437
 
 
1438
  BFT_MALLOC(group_flag, mesh->n_groups, char);
 
1439
  memset(group_flag, 0, mesh->n_groups);
 
1440
 
 
1441
#if defined(HAVE_MPI)
 
1442
  if (cs_glob_n_ranks > 1) {
 
1443
    int *_fam_flag = NULL;
 
1444
    BFT_MALLOC(_fam_flag, mesh->n_families + 1, int);
 
1445
    MPI_Allreduce(fam_flag, _fam_flag, mesh->n_families + 1,
 
1446
                  MPI_INT, MPI_MAX, cs_glob_mpi_comm);
 
1447
    memcpy(fam_flag, _fam_flag, (mesh->n_families + 1)*sizeof(int));
 
1448
    BFT_FREE(_fam_flag);
 
1449
  }
 
1450
#endif /* defined(HAVE_MPI) */
 
1451
 
 
1452
  for (i = 0; i < mesh->n_families; i++) {
 
1453
    if (fam_flag[(i+1)] != 0) {
 
1454
      char mask = fam_flag[i+1];
 
1455
      for (j = 0; j < mesh->n_max_family_items; j++) {
 
1456
        int g_id = - mesh->family_item[mesh->n_families*j + i] - 1;
 
1457
        if (g_id >= 0)
 
1458
          group_flag[g_id] = group_flag[g_id] | mask;
 
1459
      }
 
1460
    }
 
1461
  }
 
1462
 
 
1463
  return group_flag;
 
1464
}
 
1465
 
 
1466
/*----------------------------------------------------------------------------
 
1467
 * Set a family flags array to 1 for families containg a given group,
 
1468
 * and to 0 for others.
 
1469
 *
 
1470
 * parameters:
 
1471
 *   mesh     <-- pointer to mesh structure
 
1472
 *   g_id     <-- group id
 
1473
 *   fam_flag --> flag values (size: mesh->n_families)
 
1474
 *----------------------------------------------------------------------------*/
 
1475
 
 
1476
static void
 
1477
_set_fam_flags(const cs_mesh_t  *mesh,
 
1478
               int               g_id,
 
1479
               int              *fam_flag)
 
1480
{
 
1481
  int j, k;
 
1482
  memset(fam_flag, 0, mesh->n_families*sizeof(int));
 
1483
  for (j = 0; j < mesh->n_families; j++) {
 
1484
    for (k = 0; k < mesh->n_max_family_items; k++) {
 
1485
      int _g_id = - mesh->family_item[mesh->n_families*k + j] - 1;
 
1486
      if (_g_id == g_id)
 
1487
        fam_flag[j] = 1;
 
1488
    }
 
1489
  }
 
1490
}
 
1491
 
 
1492
/*----------------------------------------------------------------------------
 
1493
 * Output volume sub-meshes by group
 
1494
 *
 
1495
 * parameters:
 
1496
 *   mesh      <-- base mesh
 
1497
 *   fmt_name  <-- format name
 
1498
 *   fmt_opts  <-- format options
 
1499
 *---------------------------------------------------------------------------*/
 
1500
 
 
1501
static void
 
1502
_vol_submeshes_by_group(const cs_mesh_t  *mesh,
 
1503
                        const char       *fmt_name,
 
1504
                        const char       *fmt_opts)
 
1505
{
 
1506
  fvm_lnum_t  i, j;
 
1507
  fvm_lnum_t n_cells, n_i_faces, n_b_faces;
 
1508
  char part_name[81];
 
1509
  int max_null_family = 0;
 
1510
  int *fam_flag = NULL;
 
1511
  char *group_flag = NULL;
 
1512
  fvm_lnum_t *cell_list = NULL, *i_face_list = NULL, *b_face_list = NULL;
 
1513
  fvm_writer_t *writer = NULL;
 
1514
  fvm_nodal_t *exp_mesh = NULL;
 
1515
 
 
1516
  if (mesh->n_families == 0)
 
1517
    return;
 
1518
 
 
1519
  /* Families should be sorted, so if a nonzero family is empty,
 
1520
     it is family 1 */
 
1521
 
 
1522
  if (mesh->family_item[0] == 0)
 
1523
    max_null_family = 1;
 
1524
 
 
1525
  if (mesh->n_families <= max_null_family)
 
1526
    return;
 
1527
 
 
1528
  /* Get writer info */
 
1529
 
 
1530
  /* Default values */
 
1531
 
 
1532
  /* Create default writer */
 
1533
 
 
1534
  writer = fvm_writer_init("mesh_groups",
 
1535
                           _cs_post_dirname,
 
1536
                           fmt_name,
 
1537
                           fmt_opts,
 
1538
                           FVM_WRITER_FIXED_MESH);
 
1539
 
 
1540
  /* Now detect which groups may be referenced */
 
1541
 
 
1542
  BFT_MALLOC(fam_flag, (mesh->n_families + 1), int);
 
1543
  memset(fam_flag, 0, (mesh->n_families + 1) * sizeof(int));
 
1544
 
 
1545
  if (mesh->cell_family != NULL) {
 
1546
    for (i = 0; i < mesh->n_cells; i++)
 
1547
      fam_flag[mesh->cell_family[i]]
 
1548
        = fam_flag[mesh->cell_family[i]] | 1;
 
1549
  }
 
1550
  if (mesh->i_face_family != NULL) {
 
1551
    for (i = 0; i < mesh->n_i_faces; i++)
 
1552
      fam_flag[mesh->i_face_family[i]]
 
1553
        = fam_flag[mesh->i_face_family[i]] | 2;
 
1554
  }
 
1555
  if (mesh->b_face_family != NULL) {
 
1556
    for (i = 0; i < mesh->n_b_faces; i++)
 
1557
      fam_flag[mesh->b_face_family[i]]
 
1558
        = fam_flag[mesh->b_face_family[i]] | 4;
 
1559
  }
 
1560
 
 
1561
  group_flag = _build_group_flag(mesh, fam_flag);
 
1562
 
 
1563
  /* Now extract volume elements by groups.
 
1564
     Note that selector structures may not have been initialized yet,
 
1565
     so to avoid issue, we use a direct selection here. */
 
1566
 
 
1567
  BFT_REALLOC(fam_flag, mesh->n_families, int);
 
1568
 
 
1569
  BFT_MALLOC(cell_list, mesh->n_cells, fvm_lnum_t);
 
1570
 
 
1571
  for (i = 0; i < mesh->n_groups; i++) {
 
1572
 
 
1573
    if (group_flag[i] & '\1') {
 
1574
 
 
1575
      const char *g_name = mesh->group_lst + mesh->group_idx[i] - 1;
 
1576
 
 
1577
      _set_fam_flags(mesh, i, fam_flag);
 
1578
 
 
1579
      for (j = 0, n_cells = 0; j < mesh->n_cells; j++) {
 
1580
        int f_id = mesh->cell_family[j];
 
1581
        if (f_id > 0 && fam_flag[f_id - 1])
 
1582
          cell_list[n_cells++] = j + 1;
 
1583
      }
 
1584
      strcpy(part_name, "vol: ");
 
1585
      strncat(part_name, g_name, 80 - strlen(part_name));
 
1586
      exp_mesh = cs_mesh_connect_cells_to_nodal(mesh,
 
1587
                                                part_name,
 
1588
                                                false,
 
1589
                                                n_cells,
 
1590
                                                cell_list);
 
1591
 
 
1592
      if (fvm_writer_needs_tesselation(writer, exp_mesh, FVM_CELL_POLY) > 0)
 
1593
        fvm_nodal_tesselate(exp_mesh, FVM_CELL_POLY, NULL);
 
1594
 
 
1595
      fvm_writer_set_mesh_time(writer, -1, 0);
 
1596
      fvm_writer_export_nodal(writer, exp_mesh);
 
1597
 
 
1598
      exp_mesh = fvm_nodal_destroy(exp_mesh);
 
1599
    }
 
1600
 
 
1601
  }
 
1602
 
 
1603
  /* Now export cells with no groups */
 
1604
 
 
1605
  if (mesh->cell_family != NULL) {
 
1606
    for (j = 0, n_cells = 0; j < mesh->n_cells; j++) {
 
1607
      if (mesh->cell_family[j] <= max_null_family)
 
1608
        cell_list[n_cells++] = j + 1;
 
1609
    }
 
1610
  }
 
1611
  else {
 
1612
    for (j = 0, n_cells = 0; j < mesh->n_cells; j++)
 
1613
      cell_list[n_cells++] = j + 1;
 
1614
  }
 
1615
 
 
1616
  i = n_cells;
 
1617
  fvm_parall_counter_max(&i, 1);
 
1618
 
 
1619
  if (i > 0) {
 
1620
    exp_mesh = cs_mesh_connect_cells_to_nodal(mesh,
 
1621
                                              "vol: no_group",
 
1622
                                              false,
 
1623
                                              n_cells,
 
1624
                                              cell_list);
 
1625
 
 
1626
    if (fvm_writer_needs_tesselation(writer, exp_mesh, FVM_CELL_POLY) > 0)
 
1627
      fvm_nodal_tesselate(exp_mesh, FVM_CELL_POLY, NULL);
 
1628
 
 
1629
    fvm_writer_set_mesh_time(writer, -1, 0);
 
1630
    fvm_writer_export_nodal(writer, exp_mesh);
 
1631
 
 
1632
    exp_mesh = fvm_nodal_destroy(exp_mesh);
 
1633
  }
 
1634
 
 
1635
  BFT_FREE(cell_list);
 
1636
 
 
1637
  /* Now extract faces by groups */
 
1638
 
 
1639
  BFT_MALLOC(i_face_list, mesh->n_i_faces, fvm_lnum_t);
 
1640
  BFT_MALLOC(b_face_list, mesh->n_b_faces, fvm_lnum_t);
 
1641
 
 
1642
  for (i = 0; i < mesh->n_groups; i++) {
 
1643
 
 
1644
    if ((group_flag[i] & '\2') || (group_flag[i] & '\4')) {
 
1645
 
 
1646
      const char *g_name = mesh->group_lst + mesh->group_idx[i] - 1;
 
1647
 
 
1648
      _set_fam_flags(mesh, i, fam_flag);
 
1649
 
 
1650
      n_i_faces = 0;
 
1651
      if (mesh->i_face_family != NULL) {
 
1652
        for (j = 0; j < mesh->n_i_faces; j++) {
 
1653
          int f_id = mesh->i_face_family[j];
 
1654
          if (f_id > 0 && fam_flag[f_id - 1])
 
1655
            i_face_list[n_i_faces++] = j + 1;
 
1656
        }
 
1657
      }
 
1658
      n_b_faces = 0;
 
1659
      if (mesh->b_face_family != NULL) {
 
1660
        for (j = 0; j < mesh->n_b_faces; j++) {
 
1661
          int f_id = mesh->b_face_family[j];
 
1662
          if (f_id > 0 && fam_flag[f_id - 1])
 
1663
            b_face_list[n_b_faces++] = j + 1;
 
1664
        }
 
1665
      }
 
1666
 
 
1667
      strcpy(part_name, "surf: ");
 
1668
      strncat(part_name, g_name, 80 - strlen(part_name));
 
1669
      exp_mesh = cs_mesh_connect_faces_to_nodal(cs_glob_mesh,
 
1670
                                                part_name,
 
1671
                                                false,
 
1672
                                                n_i_faces,
 
1673
                                                n_b_faces,
 
1674
                                                i_face_list,
 
1675
                                                b_face_list);
 
1676
 
 
1677
      if (fvm_writer_needs_tesselation(writer, exp_mesh, FVM_FACE_POLY) > 0)
 
1678
        fvm_nodal_tesselate(exp_mesh, FVM_FACE_POLY, NULL);
 
1679
 
 
1680
      fvm_writer_set_mesh_time(writer, -1, 0);
 
1681
      fvm_writer_export_nodal(writer, exp_mesh);
 
1682
 
 
1683
      exp_mesh = fvm_nodal_destroy(exp_mesh);
 
1684
    }
 
1685
 
 
1686
  }
 
1687
 
 
1688
  writer = fvm_writer_finalize(writer);
 
1689
 
 
1690
  BFT_FREE(b_face_list);
 
1691
  BFT_FREE(i_face_list);
 
1692
 
 
1693
  BFT_FREE(fam_flag);
 
1694
  BFT_FREE(group_flag);
 
1695
}
 
1696
 
 
1697
/*----------------------------------------------------------------------------
 
1698
 * Output boundary sub-meshes by group, if it contains multiple groups.
 
1699
 *
 
1700
 * parameters:
 
1701
 *   mesh        <-- base mesh
 
1702
 *   fmt_name    <-- format name
 
1703
 *   fmt_opts    <-- format options
 
1704
 *---------------------------------------------------------------------------*/
 
1705
 
 
1706
static void
 
1707
_boundary_submeshes_by_group(const cs_mesh_t   *mesh,
 
1708
                             const char        *fmt_name,
 
1709
                             const char        *fmt_opts)
 
1710
{
 
1711
  fvm_lnum_t i, j;
 
1712
  fvm_lnum_t n_b_faces;
 
1713
  fvm_gnum_t n_no_group = 0;
 
1714
  int max_null_family = 0;
 
1715
  int *fam_flag = NULL;
 
1716
  char *group_flag = NULL;
 
1717
  fvm_lnum_t *b_face_list = NULL;
 
1718
  fvm_writer_t *writer = NULL;
 
1719
  fvm_nodal_t *exp_mesh = NULL;
 
1720
 
 
1721
  if (mesh->n_families == 0)
 
1722
    return;
 
1723
 
 
1724
  /* Families should be sorted, so if a nonzero family is empty,
 
1725
     it is family 1 */
 
1726
 
 
1727
  if (mesh->family_item[0] == 0)
 
1728
    max_null_family = 1;
 
1729
 
 
1730
  if (mesh->n_families <= max_null_family)
 
1731
    return;
 
1732
 
 
1733
  /* Check how many boundary faces belong to no group */
 
1734
 
 
1735
  if (mesh->b_face_family != NULL) {
 
1736
    for (j = 0, n_b_faces = 0; j < mesh->n_b_faces; j++) {
 
1737
      if (mesh->b_face_family[j] <= max_null_family)
 
1738
        n_no_group += 1;
 
1739
    }
 
1740
  }
 
1741
  else
 
1742
    n_no_group = mesh->n_b_faces;
 
1743
 
 
1744
  fvm_parall_counter(&n_no_group, 1);
 
1745
 
 
1746
  if (n_no_group == mesh->n_g_b_faces)
 
1747
    return;
 
1748
 
 
1749
  /* Get writer info */
 
1750
 
 
1751
  /* Default values */
 
1752
 
 
1753
  /* Create default writer */
 
1754
 
 
1755
  writer = fvm_writer_init("boundary_groups",
 
1756
                           _cs_post_dirname,
 
1757
                           fmt_name,
 
1758
                           fmt_opts,
 
1759
                           FVM_WRITER_FIXED_MESH);
 
1760
 
 
1761
  /* Now detect which groups may be referenced */
 
1762
 
 
1763
  BFT_MALLOC(fam_flag, mesh->n_families + 1, int);
 
1764
  memset(fam_flag, 0, (mesh->n_families + 1)*sizeof(int));
 
1765
 
 
1766
  if (mesh->b_face_family != NULL) {
 
1767
    for (i = 0; i < mesh->n_b_faces; i++)
 
1768
      fam_flag[mesh->b_face_family[i]] = 1;
 
1769
  }
 
1770
 
 
1771
  group_flag = _build_group_flag(mesh, fam_flag);
 
1772
 
 
1773
  /* Now extract boundary faces by groups.
 
1774
     Note that selector structures may not have been initialized yet,
 
1775
     so to avoid issue, we use a direct selection here. */
 
1776
 
 
1777
  BFT_REALLOC(fam_flag, mesh->n_families, int);
 
1778
 
 
1779
  BFT_MALLOC(b_face_list, mesh->n_b_faces, fvm_lnum_t);
 
1780
 
 
1781
  for (i = 0; i < mesh->n_groups; i++) {
 
1782
 
 
1783
    if (group_flag[i] != 0) {
 
1784
 
 
1785
      const char *g_name = mesh->group_lst + mesh->group_idx[i] - 1;
 
1786
 
 
1787
      _set_fam_flags(mesh, i, fam_flag);
 
1788
 
 
1789
      n_b_faces = 0;
 
1790
      if (mesh->b_face_family != NULL) {
 
1791
        for (j = 0; j < mesh->n_b_faces; j++) {
 
1792
          int f_id = mesh->b_face_family[j];
 
1793
          if (f_id > 0 && fam_flag[f_id - 1])
 
1794
            b_face_list[n_b_faces++] = j + 1;
 
1795
        }
 
1796
      }
 
1797
 
 
1798
      exp_mesh = cs_mesh_connect_faces_to_nodal(cs_glob_mesh,
 
1799
                                                g_name,
 
1800
                                                false,
 
1801
                                                0,
 
1802
                                                n_b_faces,
 
1803
                                                NULL,
 
1804
                                                b_face_list);
 
1805
 
 
1806
      if (fvm_writer_needs_tesselation(writer, exp_mesh, FVM_FACE_POLY) > 0)
 
1807
        fvm_nodal_tesselate(exp_mesh, FVM_FACE_POLY, NULL);
 
1808
 
 
1809
      fvm_writer_set_mesh_time(writer, -1, 0);
 
1810
      fvm_writer_export_nodal(writer, exp_mesh);
 
1811
 
 
1812
      exp_mesh = fvm_nodal_destroy(exp_mesh);
 
1813
    }
 
1814
 
 
1815
  }
 
1816
 
 
1817
  /* Output boundary faces belonging to no group */
 
1818
 
 
1819
  if (n_no_group > 0) {
 
1820
 
 
1821
    if (mesh->b_face_family != NULL) {
 
1822
      for (j = 0, n_b_faces = 0; j < mesh->n_b_faces; j++) {
 
1823
        if (mesh->b_face_family[j] <= max_null_family)
 
1824
          b_face_list[n_b_faces++] = j + 1;
 
1825
      }
 
1826
    }
 
1827
    else {
 
1828
      for (j = 0, n_b_faces = 0; j < mesh->n_b_faces; j++)
 
1829
        b_face_list[n_b_faces++] = j + 1;
 
1830
    }
 
1831
 
 
1832
    exp_mesh = cs_mesh_connect_faces_to_nodal(cs_glob_mesh,
 
1833
                                              "no_group",
 
1834
                                              false,
 
1835
                                              0,
 
1836
                                              n_b_faces,
 
1837
                                              NULL,
 
1838
                                              b_face_list);
 
1839
 
 
1840
    if (fvm_writer_needs_tesselation(writer, exp_mesh, FVM_FACE_POLY) > 0)
 
1841
      fvm_nodal_tesselate(exp_mesh, FVM_FACE_POLY, NULL);
 
1842
 
 
1843
    fvm_writer_set_mesh_time(writer, -1, 0);
 
1844
    fvm_writer_export_nodal(writer, exp_mesh);
 
1845
 
 
1846
    exp_mesh = fvm_nodal_destroy(exp_mesh);
 
1847
  }
 
1848
 
 
1849
  BFT_FREE(b_face_list);
 
1850
 
 
1851
  writer = fvm_writer_finalize(writer);
 
1852
 
 
1853
  BFT_FREE(fam_flag);
 
1854
  BFT_FREE(group_flag);
 
1855
}
 
1856
 
973
1857
/*============================================================================
974
1858
 * Public Fortran function definitions
975
1859
 *============================================================================*/
976
1860
 
977
1861
/*----------------------------------------------------------------------------
978
 
 * Create a writer based on Fortran data; this object is based on a choice
979
 
 * of a case, directory, and format, as well as indicator for associated
980
 
 * mesh's time dependency, and the default output frequency for associated
981
 
 * variables.
982
 
 *
983
 
 * Fortran Interface: use PSTCWR (see cs_post_util.F)
984
 
 *
985
 
 * SUBROUTINE PSTCW1 (NUMGEP, NOMCAS, NOMREP, NOMFMT, OPTFMT,
986
 
 * *****************
987
 
 *                    LNMCAS, LNMFMT, LNMREP, LOPFMT,
988
 
 *                    INDMOD, NTCHR)
989
 
 *
990
 
 * INTEGER          NUMWRI      : --> : Number of writer to create (< 0 for
991
 
 *                              :     : standard writer, > 0 for user writer)
992
 
 * CHARACTER        NOMCAS      : --> : Name of associated case
993
 
 * CHARACTER        NOMREP      : --> : Name of associated directory
994
 
 * INTEGER          NOMFMT      : --> : Name of associated format
995
 
 * INTEGER          OPTFMT      : --> : Additional format options
996
 
 * INTEGER          LNMCAS      : --> : Case name length
997
 
 * INTEGER          LNMREP      : --> : Directory name length
998
 
 * INTEGER          LNMFMT      : --> : Format name length
999
 
 * INTEGER          LOPFMT      : --> : Format options string length
1000
 
 * INTEGER          INDMOD      : --> : 0 if fixed, 1 if deformable,
1001
 
 *                              :     : 2 if topology changes
1002
 
 * INTEGER          NTCHR       : --> : Default output frequency
1003
 
 *----------------------------------------------------------------------------*/
1004
 
 
1005
 
void CS_PROCF (pstcw1, PSTCW1)
1006
 
(
1007
 
 const cs_int_t  *numwri,
1008
 
 const char      *nomcas,
1009
 
 const char      *nomrep,
1010
 
 const char      *nomfmt,
1011
 
 const char      *optfmt,
1012
 
 const cs_int_t  *lnmcas,
1013
 
 const cs_int_t  *lnmrep,
1014
 
 const cs_int_t  *lnmfmt,
1015
 
 const cs_int_t  *lopfmt,
1016
 
 const cs_int_t  *indmod,
1017
 
 const cs_int_t  *ntchr
1018
 
 CS_ARGF_SUPP_CHAINE              /*     (possible 'length' arguments added
1019
 
                                         by many Fortran compilers) */
1020
 
)
1021
 
{
1022
 
  /* local variables */
1023
 
 
1024
 
  char  *case_name;
1025
 
  char  *dir_name;
1026
 
  char  *nom_format;
1027
 
  char  *opt_format;
1028
 
 
1029
 
  /* Copy Fortran strings to C strings */
1030
 
 
1031
 
  case_name    = cs_base_string_f_to_c_create(nomcas, *lnmcas);
1032
 
  dir_name    = cs_base_string_f_to_c_create(nomrep, *lnmrep);
1033
 
  nom_format = cs_base_string_f_to_c_create(nomfmt, *lnmfmt);
1034
 
  opt_format = cs_base_string_f_to_c_create(optfmt, *lopfmt);
1035
 
 
1036
 
  /* Main processing */
1037
 
 
1038
 
  cs_post_add_writer(*numwri,
1039
 
                     case_name,
1040
 
                     dir_name,
1041
 
                     nom_format,
1042
 
                     opt_format,
1043
 
                     *indmod,
1044
 
                     *ntchr);
1045
 
 
1046
 
  /* Free temporary C strings */
1047
 
 
1048
 
  cs_base_string_f_to_c_free(&case_name);
1049
 
  cs_base_string_f_to_c_free(&dir_name);
1050
 
  cs_base_string_f_to_c_free(&nom_format);
1051
 
  cs_base_string_f_to_c_free(&opt_format);
1052
 
}
1053
 
 
1054
 
 
1055
 
/*----------------------------------------------------------------------------
1056
 
 * Create a post-processing mesh; lists of cells or faces to extract are
1057
 
 * sorted upon exit, whether they were sorted upon calling or not.
1058
 
 *
1059
 
 * The list of associated cells is only necessary if the number of cells
1060
 
 * to extract is strictly greater than 0 and less than the number of cells
1061
 
 * of the computational mesh.
1062
 
 *
1063
 
 * Lists of faces are ignored if the number of extracted cells is nonzero;
1064
 
 * otherwise, if the number of boundary faces to extract is equal to the
1065
 
 * number of boundary faces in the computational mesh, and the number of
1066
 
 * interior faces to extract is zero, than we extrac by default the boundary
1067
 
 * mesh, and the list of associated boundary faces is thus not necessary.
1068
 
 *
1069
 
 * Fortran interface: use PSTCMA (see cs_post_util.F)
1070
 
 *
1071
 
 * SUBROUTINE PSTCM1 (NUMMAI, NOMMAI, LNMMAI,
1072
 
 * *****************
1073
 
 *                    NBRCEL, NBRFAC, NBRFBR, LSTCEL, LSTFAC, LSTFBR)
1074
 
 *
1075
 
 * INTEGER          NUMMAI      : <-- : Number of output mesh to create
1076
 
 *                              :     : (< 0 for standard mesh,
1077
 
 *                              :     : > 0 for user mesh)
1078
 
 * CHARACTER        NOMMAI      : <-- : Name of associated output mesh
1079
 
 * INTEGER          LNMMAI      : <-- : Mesh name length
1080
 
 * INTEGER          NBRCEL      : <-- : Number of associated cells
1081
 
 * INTEGER          NBRFAC      : <-- : Number of associated interior faces
1082
 
 * INTEGER          NBRFBR      : <-- : Nulber of associated boundary faces
1083
 
 * INTEGER          LSTCEL      : <-- : List of associated cells
1084
 
 * INTEGER          LSTFAC      : <-- : List of associated interior faces
1085
 
 * INTEGER          LSTFBR      : <-- : List of associated boundary faces
1086
 
 *----------------------------------------------------------------------------*/
1087
 
 
1088
 
void CS_PROCF (pstcm1, PSTCM1)
1089
 
(
1090
 
 const cs_int_t  *nummai,
1091
 
 const char      *nommai,
1092
 
 const cs_int_t  *lnmmai,
1093
 
 const cs_int_t  *nbrcel,
1094
 
 const cs_int_t  *nbrfac,
1095
 
 const cs_int_t  *nbrfbr,
1096
 
       cs_int_t   lstcel[],
1097
 
       cs_int_t   lstfac[],
1098
 
       cs_int_t   lstfbr[]
1099
 
 CS_ARGF_SUPP_CHAINE              /*     (possible 'length' arguments added
1100
 
                                         by many Fortran compilers) */
1101
 
)
1102
 
{
1103
 
  /* local variables */
1104
 
 
1105
 
  char  *mesh_name = NULL;
1106
 
 
1107
 
  /* Copy Fortran strings to C strings */
1108
 
 
1109
 
  mesh_name = cs_base_string_f_to_c_create(nommai, *lnmmai);
1110
 
 
1111
 
  /* Main processing */
1112
 
 
1113
 
  cs_post_add_mesh(*nummai,
1114
 
                   mesh_name,
1115
 
                   *nbrcel,
1116
 
                   *nbrfac,
1117
 
                   *nbrfbr,
1118
 
                   lstcel,
1119
 
                   lstfac,
1120
 
                   lstfbr);
1121
 
 
1122
 
  /* Free temporary C strings */
1123
 
 
1124
 
  cs_base_string_f_to_c_free(&mesh_name);
1125
 
}
1126
 
 
1127
 
/*----------------------------------------------------------------------------
1128
 
 * Create a mesh based upon the extraction of edges from an existing mesh.
1129
 
 *
1130
 
 * The newly created edges have no link to their parent elements, so
1131
 
 * no variable referencing parent elements may be output to this mesh,
1132
 
 * whose main use is to visualize "true" face edges when polygonal faces
1133
 
 * are subdivided by the writer. In this way, even highly non-convex
1134
 
 * faces may be visualized correctly if their edges are overlaid on
1135
 
 * the surface mesh with subdivided polygons.
1136
 
 *
1137
 
 * Fortran interface:
1138
 
 *
1139
 
 * SUBROUTINE PSTEDG (NUMMAI, NUMREF)
1140
 
 * *****************
1141
 
 *
1142
 
 * INTEGER          NUMMAI      : <-- : Number of the edges mesh to create
1143
 
 * INTEGER          NUMREF      : <-- : Number of the existing mesh
1144
 
 *----------------------------------------------------------------------------*/
1145
 
 
1146
 
void CS_PROCF (pstedg, PSTEDG)
1147
 
(
1148
 
 const cs_int_t  *nummai,
1149
 
 const cs_int_t  *numref
1150
 
)
1151
 
{
1152
 
  cs_post_add_mesh_edges(*nummai, *numref);
1153
 
}
1154
 
 
1155
 
/*----------------------------------------------------------------------------
1156
 
 * Assign a category to a post-processing mesh.
1157
 
 *
1158
 
 * By default, each mesh is assigned a category id identical to its id.
1159
 
 * The automatic variables output associated with the main volume and
1160
 
 * boundary meshes will also be applied to meshes of the same categories
1161
 
 * (i.e. -1 and -2 respectively, whether meshes -1 and -2 are actually
1162
 
 * defined or not), so setting a user mesh's category to one of these
1163
 
 * values will automatically provide the same automatic variable output to
1164
 
 * the user mesh.
1165
 
 *
1166
 
 * Fortran interface:
1167
 
 *
1168
 
 * SUBROUTINE PSTCAT (NUMMAI, NUMCAT)
1169
 
 * *****************
1170
 
 *
1171
 
 * INTEGER          NUMMAI      : <-- : Number of the alias to create
1172
 
 * INTEGER          NUMCAT      : <-- : Number of the assigned category
1173
 
 *                                      (-1: as volume, -2: as boundary)
1174
 
 *----------------------------------------------------------------------------*/
1175
 
 
1176
 
void CS_PROCF (pstcat, PSTCAT)
1177
 
(
1178
 
 const cs_int_t  *nummai,
1179
 
 const cs_int_t  *numcat
1180
 
)
1181
 
{
1182
 
  cs_post_set_mesh_category(*nummai, *numcat);
1183
 
}
1184
 
 
1185
 
/*----------------------------------------------------------------------------
1186
 
 * Create an alias to a post-processing mesh.
1187
 
 *
1188
 
 * Fortran interface:
1189
 
 *
1190
 
 * SUBROUTINE PSTALM (NUMMAI, NUMREF)
1191
 
 * *****************
1192
 
 *
1193
 
 * INTEGER          NUMMAI      : <-- : Number of the alias to create
1194
 
 * INTEGER          NUMREF      : <-- : Number of the associated output mesh
1195
 
 *----------------------------------------------------------------------------*/
1196
 
 
1197
 
void CS_PROCF (pstalm, PSTALM)
1198
 
(
1199
 
 const cs_int_t  *nummai,
1200
 
 const cs_int_t  *numref
1201
 
)
1202
 
{
1203
 
  cs_post_alias_mesh(*nummai, *numref);
1204
 
}
1205
 
 
1206
 
/*----------------------------------------------------------------------------
1207
 
 * Associate a writer to a post-processing mesh.
1208
 
 *
1209
 
 * Fortran interface:
1210
 
 *
1211
 
 * SUBROUTINE PSTASS (NUMMAI, NUMWRI)
1212
 
 * *****************
1213
 
 *
1214
 
 * INTEGER          NUMMAI      : <-- : Number of the associated output mesh
1215
 
 * INTEGER          NUMWRI      : <-- : Number of the writer to associate
1216
 
 *----------------------------------------------------------------------------*/
1217
 
 
1218
 
void CS_PROCF (pstass, PSTASS)
1219
 
(
1220
 
 const cs_int_t  *nummai,
1221
 
 const cs_int_t  *numwri
1222
 
)
1223
 
{
1224
 
  cs_post_associate(*nummai, *numwri);
 
1862
 * Configure the post-processing output so that a mesh displacement field
 
1863
 * may be output automatically for meshes based on the global volume mesh/
 
1864
 *
 
1865
 * Fortran interface:
 
1866
 *
 
1867
 * subroutine pstdfm
 
1868
 * *****************
 
1869
 *----------------------------------------------------------------------------*/
 
1870
 
 
1871
void CS_PROCF (pstdfm, PSTDFM)
 
1872
(
 
1873
 void
 
1874
)
 
1875
{
 
1876
  cs_post_set_deformable();
1225
1877
}
1226
1878
 
1227
1879
/*----------------------------------------------------------------------------
1230
1882
 *
1231
1883
 * Fortran interface:
1232
1884
 *
1233
 
 * SUBROUTINE PSTNTC (NTCABS)
 
1885
 * subroutine pstntc (ntmabs, ntcabs, ttcabs)
1234
1886
 * *****************
1235
1887
 *
1236
 
 * INTEGER          NTCABS      : <-- : Current time step number
 
1888
 * integer          ntmabs      : <-- : maximum time step number
 
1889
 * integer          ntcabs      : <-- : current time step number
 
1890
 * double precision ttcabs      : <-- : absolute time at the current time step
1237
1891
 *----------------------------------------------------------------------------*/
1238
1892
 
1239
1893
void CS_PROCF (pstntc, PSTNTC)
1240
1894
(
1241
 
 const cs_int_t  *ntcabs
 
1895
 const cs_int_t  *ntmabs,
 
1896
 const cs_int_t  *ntcabs,
 
1897
 const cs_real_t *ttcabs
1242
1898
)
1243
1899
{
1244
 
  cs_post_activate_if_default(*ntcabs);
 
1900
  cs_post_activate_if_default(*ntmabs, *ntcabs, *ttcabs);
1245
1901
}
1246
1902
 
1247
1903
/*----------------------------------------------------------------------------
1250
1906
 *
1251
1907
 * Fortran interface:
1252
1908
 *
1253
 
 * SUBROUTINE PSTNTC (NUMWRI, INDACT)
 
1909
 * subroutine pstact (numwri, indact)
1254
1910
 * *****************
1255
1911
 *
1256
 
 * INTEGER          NUMWRI      : <-- : Writer number, or 0 for all writers
1257
 
 * INTEGER          INDACT      : <-- : 0 to deactivate, 1 to activate
 
1912
 * integer          numwri      : <-- : writer number, or 0 for all writers
 
1913
 * integer          indact      : <-- : 0 to deactivate, 1 to activate
1258
1914
 *----------------------------------------------------------------------------*/
1259
1915
 
1260
1916
void CS_PROCF (pstact, PSTACT)
1263
1919
 const cs_int_t  *indact
1264
1920
)
1265
1921
{
1266
 
  cs_post_activate_writer(*numwri, *indact);
 
1922
  cs_bool_t flag = (*indact != 0) ? true : false;
 
1923
  cs_post_activate_writer(*numwri, flag);
1267
1924
}
1268
1925
 
1269
1926
/*----------------------------------------------------------------------------
1271
1928
 *
1272
1929
 * Fortran interface:
1273
1930
 *
1274
 
 * SUBROUTINE PSTEMA (NTCABS, TTCABS)
 
1931
 * subroutine pstema (ntcabs, ttcabs)
1275
1932
 * *****************
1276
1933
 *
1277
 
 * INTEGER          NTCABS      : <-- : Current time step number
1278
 
 * DOUBLE PRECISION TTCABS      : <-- : Current physical time
 
1934
 * integer          ntcabs      : <-- : current time step number
 
1935
 * double precision ttcabs      : <-- : current physical time
1279
1936
 *----------------------------------------------------------------------------*/
1280
1937
 
1281
1938
void CS_PROCF (pstema, PSTEMA)
1292
1949
 *
1293
1950
 * Fortran interface:
1294
1951
 *
1295
 
 * SUBROUTINE PSTVAR (IDBIA0, IDBRA0,
 
1952
 * subroutine pstvar
1296
1953
 * *****************
1297
 
 *                    NDIM,   NTCABS, NCELET, NCEL,   NFAC,   NFABOR,
1298
 
 *                    NFML,   NPRFML, NNOD,   LNDFAC, LNDFBR, NCELBR,
1299
 
 *                    NVAR,   NSCAL,  NPHAS,  NVLSTA, NVISBR,
1300
 
 *                    NIDEVE, NRDEVE, NITUSE, NRTUSE,
1301
 
 *                    IFACEL, IFABOR, IFMFBR, IFMCEL, IPRFML,
1302
 
 *                    IPNFAC, NODFAC, IPNFBR, NODFBR,
1303
 
 *                    IDEVEL, ITUSER, IA,
1304
 
 *                    TTCABS, XYZCEN, SURFAC, SURFBO, CDGFAC, CDGFBO,
1305
 
 *                    XYZNOD, VOLUME,
1306
 
 *                    DT,     RTPA,   RTP,    PROPCE, PROPFA, PROPFB,
1307
 
 *                    COEFA,  COEFB,
1308
 
 *                    STATCE, STATIV, STATFB,
1309
 
 *                    RDEVEL, RTUSER, RA)
1310
 
 *
1311
 
 * INTEGER          IDBIA0      : <-- : Number of first free position in IA
1312
 
 * INTEGER          IDBRA0      : <-- : Number of first free position in RA
1313
 
 * INTEGER          NDIM        : <-- : Spatial dimension
1314
 
 * INTEGER          NTCABS      : --> : Current time step number
1315
 
 * INTEGER          NCELET      : <-- : Number of extended (real + ghost) cells
1316
 
 * INTEGER          NFAC        : <-- : Number of interior faces
1317
 
 * INTEGER          NFABOR      : <-- : Number of boundary faces
1318
 
 * INTEGER          NFML        : <-- : Number of families (group classes)
1319
 
 * INTEGER          NPRFML      : <-- : Number of family properties
1320
 
 * INTEGER          NNOD        : <-- : Number of vertices
1321
 
 * INTEGER          LNDFAC      : <-- : Size of nodfac
1322
 
 * INTEGER          LNDFBR      : <-- : Size of nodfbr
1323
 
 * INTEGER          NCELBR      : <-- : Number of cells on boundary
1324
 
 * INTEGER          NVAR        : <-- : Number of variables
1325
 
 * INTEGER          NSCAL       : <-- : Number of scalars
1326
 
 * INTEGER          NPHAS       : <-- : Number of phases
1327
 
 * INTEGER          NVLSTA      : <-- : Number of statistical variables (lagr)
1328
 
 * INTEGER          NVISBR      : <-- : Number of boundary stat. variables (lagr)
1329
 
 * INTEGER          NIDEVE      : <-- : Size of IDEVEL integer array
1330
 
 * INTEGER          NRDEVE      : <-- : Size of RDEVEL floating-point array
1331
 
 * INTEGER          NITUSE      : <-- : Size of ITUSER integer array
1332
 
 * INTEGER          NRTUSE      : <-- : Size of RTUSER floating-point array
1333
 
 * INTEGER          IFACEL      : <-- : Interior faces -> cells connectivity
1334
 
 * INTEGER          IFABOR      : <-- : Boundary faces -> cell connectivity
1335
 
 * INTEGER          IFMFBR      : <-- : Boundary face families
1336
 
 * INTEGER          IFMCEL      : <-- : Cell families
1337
 
 * INTEGER          IPRFML      : <-- : List of family properties
1338
 
 * INTEGER          IPNFAC      : <-- : Interior faces -> vertices connect. idx.
1339
 
 * INTEGER          NODFAC      : <-- : Interior faces -> vertices connectivity
1340
 
 * INTEGER          IPNFBR      : <-- : Boundary faces -> vertices connect. idx.
1341
 
 * INTEGER          NODFBR      : <-- : Boundary faces -> vertices connectivity
1342
 
 * INTEGER          IDEVEL      : <-- : IDEVEL integer array
1343
 
 * INTEGER          ITUSER      : <-- : ITUSER integer array
1344
 
 * INTEGER          IA          : <-- : IA integer array
1345
 
 * DOUBLE PRECISION TTCABS      : <-- : Current physical time
1346
 
 * DOUBLE PRECISION XYZCEN      : <-- : Points associated with cell centers
1347
 
 * DOUBLE PRECISION SURFAC      : <-- : Interior face surface vectors
1348
 
 * DOUBLE PRECISION SURFBO      : <-- : Boundary face surface vectors
1349
 
 * DOUBLE PRECISION CDGFAC      : <-- : Interior face centers
1350
 
 * DOUBLE PRECISION CDGFBO      : <-- : Boundary face vectors
1351
 
 * DOUBLE PRECISION XYZNOD      : <-- : Vertex coordinates (optional)
1352
 
 * DOUBLE PRECISION VOLUME      : <-- : Cell volumes
1353
 
 * DOUBLE PRECISION DT          : <-- : Local time step
1354
 
 * DOUBLE PRECISION RTPA        : <-- : Cell variables at previous time step
1355
 
 * DOUBLE PRECISION RTP         : <-- : Cell variables
1356
 
 * DOUBLE PRECISION PROPCE      : <-- : Cell physical properties
1357
 
 * DOUBLE PRECISION PROPFA      : <-- : Interior face physical properties
1358
 
 * DOUBLE PRECISION PROPFB      : <-- : Boundary face physical properties
1359
 
 * DOUBLE PRECISION COEFA       : <-- : Boundary conditions array
1360
 
 * DOUBLE PRECISION COEFB       : <-- : Boundary conditions array
1361
 
 * DOUBLE PRECISION STATCE      : <-- : Cell statistics (Lagrangian)
1362
 
 * DOUBLE PRECISION STATIV      : <-- : Cell variance statistics (Lagrangian)
1363
 
 * DOUBLE PRECISION STATFB      : <-- : Boundary face statistics (Lagrangian)
1364
 
 * DOUBLE PRECISION RDEVEL      : <-- : RDEVEL floating-point array
1365
 
 * DOUBLE PRECISION RTUSER      : <-- : RTUSER floating-point array
1366
 
 * DOUBLE PRECISION RA          : <-- : RA floating-point array
1367
 
 *
 
1954
 *                  ( ntcabs,
 
1955
 *                    nvar,   nscal,  nvlsta, nvisbr,
 
1956
 *                    ttcabs,
 
1957
 *                    dt,     rtpa,   rtp,    propce, propfa, propfb,
 
1958
 *                    coefa,  coefb,
 
1959
 *                    statce, stativ, statfb,
 
1960
 *                    ra)
 
1961
 *
 
1962
 * integer          ntcabs      : --> : current time step number
 
1963
 * integer          nvar        : <-- : number of variables
 
1964
 * integer          nscal       : <-- : number of scalars
 
1965
 * integer          nvlsta      : <-- : number of statistical variables (lagr)
 
1966
 * integer          nvisbr      : <-- : number of boundary stat. variables (lagr)
 
1967
 * double precision ttcabs      : <-- : current physical time
 
1968
 * double precision dt          : <-- : local time step
 
1969
 * double precision rtpa        : <-- : cell variables at previous time step
 
1970
 * double precision rtp         : <-- : cell variables
 
1971
 * double precision propce      : <-- : cell physical properties
 
1972
 * double precision propfa      : <-- : interior face physical properties
 
1973
 * double precision propfb      : <-- : boundary face physical properties
 
1974
 * double precision coefa       : <-- : boundary conditions array
 
1975
 * double precision coefb       : <-- : boundary conditions array
 
1976
 * double precision statce      : <-- : cell statistics (lagrangian)
 
1977
 * double precision stativ      : <-- : cell variance statistics (lagrangian)
 
1978
 * double precision statfb      : <-- : boundary face statistics (lagrangian)
 
1979
 * double precision ra          : <-- : ra floating-point array
1368
1980
 *----------------------------------------------------------------------------*/
1369
1981
 
1370
1982
void CS_PROCF (pstvar, PSTVAR)
1371
1983
(
1372
 
 const cs_int_t   *idbia0,
1373
 
 const cs_int_t   *idbra0,
1374
 
 const cs_int_t   *ndim,
1375
1984
 const cs_int_t   *ntcabs,
1376
 
 const cs_int_t   *ncelet,
1377
 
 const cs_int_t   *ncel,
1378
 
 const cs_int_t   *nfac,
1379
 
 const cs_int_t   *nfabor,
1380
 
 const cs_int_t   *nfml,
1381
 
 const cs_int_t   *nprfml,
1382
 
 const cs_int_t   *nnod,
1383
 
 const cs_int_t   *lndfac,
1384
 
 const cs_int_t   *lndfbr,
1385
 
 const cs_int_t   *ncelbr,
1386
1985
 const cs_int_t   *nvar,
1387
1986
 const cs_int_t   *nscal,
1388
 
 const cs_int_t   *nphas,
1389
1987
 const cs_int_t   *nvlsta,
1390
1988
 const cs_int_t   *nvisbr,
1391
 
 const cs_int_t   *nideve,
1392
 
 const cs_int_t   *nrdeve,
1393
 
 const cs_int_t   *nituse,
1394
 
 const cs_int_t   *nrtuse,
1395
 
 const cs_int_t    ifacel[],
1396
 
 const cs_int_t    ifabor[],
1397
 
 const cs_int_t    ifmfbr[],
1398
 
 const cs_int_t    ifmcel[],
1399
 
 const cs_int_t    iprfml[],
1400
 
 const cs_int_t    ipnfac[],
1401
 
 const cs_int_t    nodfac[],
1402
 
 const cs_int_t    ipnfbr[],
1403
 
 const cs_int_t    nodfbr[],
1404
 
 const cs_int_t    idevel[],
1405
 
       cs_int_t    ituser[],
1406
 
       cs_int_t    ia[],
1407
1989
 const cs_real_t  *ttcabs,
1408
 
 const cs_real_t   xyzcen[],
1409
 
 const cs_real_t   surfac[],
1410
 
 const cs_real_t   surfbo[],
1411
 
 const cs_real_t   cdgfac[],
1412
 
 const cs_real_t   cdgfbo[],
1413
 
 const cs_real_t   xyznod[],
1414
 
 const cs_real_t   volume[],
1415
1990
 const cs_real_t   dt[],
1416
1991
 const cs_real_t   rtpa[],
1417
1992
 const cs_real_t   rtp[],
1423
1998
 const cs_real_t   statce[],
1424
1999
 const cs_real_t   stativ[],
1425
2000
 const cs_real_t   statfb[],
1426
 
 const cs_real_t   rdevel[],
1427
 
       cs_real_t   rtuser[],
1428
2001
       cs_real_t   ra[]
1429
2002
)
1430
2003
{
1567
2140
 
1568
2141
      imodif = 0;
1569
2142
 
1570
 
      CS_PROCF(usmpst, USMPST) (idbia0, idbra0, &nummai,
1571
 
                                ndim, ncelet, ncel, nfac, nfabor, nfml, nprfml,
1572
 
                                nnod, lndfac, lndfbr, ncelbr,
1573
 
                                nvar, nscal, nphas, nvlsta,
 
2143
      CS_PROCF(usmpst, USMPST) (&nummai,
 
2144
                                nvar, nscal, nvlsta,
1574
2145
                                &n_cells, &n_i_faces, &n_b_faces,
1575
 
                                nideve, nrdeve, nituse, nrtuse, &imodif,
1576
 
                                itypps, ifacel, ifabor, ifmfbr, ifmcel, iprfml,
1577
 
                                ipnfac, nodfac, ipnfbr, nodfbr,
 
2146
                                &imodif,
 
2147
                                itypps,
1578
2148
                                cell_list, i_face_list, b_face_list,
1579
 
                                idevel, ituser, ia,
1580
 
                                xyzcen, surfac, surfbo, cdgfac, cdgfbo, xyznod,
1581
 
                                volume, dt, rtpa, rtp, propce, propfa, propfb,
 
2149
                                dt, rtpa, rtp, propce, propfa, propfb,
1582
2150
                                coefa, coefb, statce,
1583
 
                                cel_vals, i_face_vals, b_face_vals,
1584
 
                                rdevel, rtuser, ra);
 
2151
                                cel_vals, i_face_vals, b_face_vals);
1585
2152
 
1586
2153
      if (imodif > 0)
1587
2154
        cs_post_modify_mesh(post_mesh->id,
1776
2343
      /* Standard post-processing */
1777
2344
 
1778
2345
      if (numtyp < 0)
1779
 
        CS_PROCF(dvvpst, DVVPST) (idbia0, idbra0, &nummai, &numtyp,
1780
 
                                  ndim, ncelet, ncel, nfac, nfabor, nfml, nprfml,
1781
 
                                  nnod, lndfac, lndfbr, ncelbr,
1782
 
                                  nvar, nscal, nphas, nvlsta, nvisbr,
 
2346
        CS_PROCF(dvvpst, DVVPST) (&nummai, &numtyp,
 
2347
                                  nvar, nscal, nvlsta, nvisbr,
1783
2348
                                  &n_cells, &n_i_faces, &n_b_faces,
1784
 
                                  nideve, nrdeve, nituse, nrtuse,
1785
 
                                  itypps, ifacel, ifabor, ifmfbr, ifmcel, iprfml,
1786
 
                                  ipnfac, nodfac, ipnfbr, nodfbr,
 
2349
                                  itypps,
1787
2350
                                  cell_list, i_face_list, b_face_list,
1788
 
                                  idevel, ituser, ia,
1789
 
                                  xyzcen, surfac, surfbo, cdgfac, cdgfbo, xyznod,
1790
 
                                  volume, dt, rtpa, rtp, propce, propfa, propfb,
 
2351
                                  dt, rtpa, rtp, propce, propfa, propfb,
1791
2352
                                  coefa, coefb, statce, stativ , statfb ,
1792
2353
                                  cel_vals, i_face_vals, b_face_vals,
1793
 
                                  rdevel, rtuser, ra);
 
2354
                                  ra);
1794
2355
 
1795
2356
      /* Call to user subroutine for additional post-processing */
1796
2357
 
1797
 
      CS_PROCF(usvpst, USVPST) (idbia0, idbra0, &nummai,
1798
 
                                ndim, ncelet, ncel, nfac, nfabor, nfml, nprfml,
1799
 
                                nnod, lndfac, lndfbr, ncelbr,
1800
 
                                nvar, nscal, nphas, nvlsta,
 
2358
      CS_PROCF(usvpst, USVPST) (&nummai,
 
2359
                                nvar, nscal, nvlsta,
1801
2360
                                &n_cells, &n_i_faces, &n_b_faces,
1802
 
                                nideve, nrdeve, nituse, nrtuse,
1803
 
                                itypps, ifacel, ifabor, ifmfbr, ifmcel, iprfml,
1804
 
                                ipnfac, nodfac, ipnfbr, nodfbr,
 
2361
                                itypps,
1805
2362
                                cell_list, i_face_list, b_face_list,
1806
 
                                idevel, ituser, ia,
1807
 
                                xyzcen, surfac, surfbo, cdgfac, cdgfbo, xyznod,
1808
 
                                volume, dt, rtpa, rtp, propce, propfa, propfb,
 
2363
                                dt, rtpa, rtp, propce, propfa, propfb,
1809
2364
                                coefa, coefb, statce,
1810
 
                                cel_vals, i_face_vals, b_face_vals,
1811
 
                                rdevel, rtuser, ra);
 
2365
                                cel_vals, i_face_vals, b_face_vals);
1812
2366
 
1813
2367
      /* In case of mixed interior and boundary faces, free
1814
2368
         additional arrays */
1832
2386
 * Post-processing output of a variable defined on cells or faces of a mesh
1833
2387
 * using associated writers.
1834
2388
 *
1835
 
 * Fortran interface; use PSTEVA (see cs_post_util.F)
 
2389
 * fortran interface; use psteva (see cs_post_f2c.f90)
1836
2390
 *
1837
 
 * SUBROUTINE PSTEV1 (NUMMAI, NOMVAR, LNMVAR, IDIMT,  IENTLA, IVARPR,
 
2391
 * subroutine pstev1 (nummai, nomvar, lnmvar, idimt,  ientla, ivarpr,
1838
2392
 * *****************
1839
 
 *                    NTCABS, TTCABS, VARCEL, VARFAC, VARFBR)
 
2393
 *                    ntcabs, ttcabs, varcel, varfac, varfbr)
1840
2394
 *
1841
 
 * INTEGER          NUMMAI      : <-- : Number of associated output mesh
1842
 
 * CHARACTER        NOMVAR      : <-- : Name of associated variable
1843
 
 * INTEGER          LNMVAR      : <-- : Variable name length
1844
 
 * INTEGER          IDIMT       : <-- : 1 for scalar, 3 for vector
1845
 
 * INTEGER          IENTLA      : <-- : If a vector, 1 for interlaced values
 
2395
 * integer          nummai      : <-- : number of associated output mesh
 
2396
 * character        nomvar      : <-- : name of associated variable
 
2397
 * integer          lnmvar      : <-- : variable name length
 
2398
 * integer          idimt       : <-- : 1 for scalar, 3 for vector
 
2399
 * integer          ientla      : <-- : if a vector, 1 for interlaced values
1846
2400
 *                              :     : (x1, y1, z1, x2, y2, ..., yn, zn),
1847
2401
 *                              :     : 0 otherwise (x1, x2, ...xn, y1, y2, ...)
1848
 
 * INTEGER          IVARPR      : <-- : 1 if variable is defined on "parent"
 
2402
 * integer          ivarpr      : <-- : 1 if variable is defined on "parent"
1849
2403
 *                              :     : mesh, 2 if defined on output mesh
1850
 
 * INTEGER          NTCABS      : <-- : Current time step number
1851
 
 * DOUBLE PRECISION TTCABS      : <-- : Current physical time
1852
 
 * DOUBLE PRECISION VARCEL(*)   : <-- : Cell values
1853
 
 * DOUBLE PRECISION VARFAC(*)   : <-- : Interior face values
1854
 
 * DOUBLE PRECISION VARFBO(*)   : <-- : Boundary face values
 
2404
 * integer          ntcabs      : <-- : current time step number
 
2405
 * double precision ttcabs      : <-- : current physical time
 
2406
 * double precision varcel(*)   : <-- : cell values
 
2407
 * double precision varfac(*)   : <-- : interior face values
 
2408
 * double precision varfbo(*)   : <-- : boundary face values
1855
2409
 *----------------------------------------------------------------------------*/
1856
2410
 
1857
2411
void CS_PROCF (pstev1, PSTEV1)
1923
2477
 *============================================================================*/
1924
2478
 
1925
2479
/*----------------------------------------------------------------------------
1926
 
 * Create a writer; this objects manages a case's name, directory, and format,
 
2480
 * Define a writer; this objects manages a case's name, directory, and format,
1927
2481
 * as well as associated mesh's time dependency, and the default output
1928
2482
 * frequency for associated variables.
1929
2483
 *
 
2484
 * This function must be called before the time loop. If a writer with a
 
2485
 * given id is defined multiple times, the last definition supercedes the
 
2486
 * previous ones.
 
2487
 *
1930
2488
 * parameters:
1931
 
 *   writer_id <-- number of writer to create (< 0 reserved, > 0 for user)
1932
 
 *   case_name <-- associated case name
1933
 
 *   dir_name  <-- associated directory name
1934
 
 *   fmt_name  <-- associated format name
1935
 
 *   fmt_opts  <-- associated format options
1936
 
 *   mod_flag  <-- 0 if fixed, 1 if deformable, 2 if topolygy changes,
1937
 
 *                 +10 add a displacement field
1938
 
 *   frequency <-- default output frequency
 
2489
 *   writer_id     <-- number of writer to create (< 0 reserved, > 0 for user)
 
2490
 *   case_name     <-- associated case name
 
2491
 *   dir_name      <-- associated directory name
 
2492
 *   fmt_name      <-- associated format name
 
2493
 *   fmt_opts      <-- associated format options string
 
2494
 *   time_dep      <-- FVM_WRITER_FIXED_MESH if mesh definitions are fixed,
 
2495
 *                     FVM_WRITER_TRANSIENT_COORDS if coordinates change,
 
2496
 *                     FVM_WRITER_TRANSIENT_CONNECT if connectivity changes
 
2497
 *   output_at_end <-- force output at calculation end if not 0
 
2498
 *   frequency_n   <-- default output frequency in time-steps, or < 0
 
2499
 *   frequency_t   <-- default output frequency in seconds, or < 0
 
2500
 *                     (has priority over frequency_n)
1939
2501
 *----------------------------------------------------------------------------*/
1940
2502
 
1941
2503
void
1942
 
cs_post_add_writer(int          writer_id,
1943
 
                   const char  *case_name,
1944
 
                   const char  *dir_name,
1945
 
                   const char  *fmt_name,
1946
 
                   const char  *fmt_opts,
1947
 
                   cs_int_t     mod_flag,
1948
 
                   cs_int_t     frequency)
 
2504
cs_post_define_writer(int                     writer_id,
 
2505
                      const char             *case_name,
 
2506
                      const char             *dir_name,
 
2507
                      const char             *fmt_name,
 
2508
                      const char             *fmt_opts,
 
2509
                      fvm_writer_time_dep_t   time_dep,
 
2510
                      cs_bool_t               output_at_end,
 
2511
                      cs_int_t                frequency_n,
 
2512
                      cs_real_t               frequency_t)
1949
2513
{
1950
2514
  /* local variables */
1951
2515
 
1952
2516
  int    i;
1953
2517
 
1954
 
  cs_post_writer_t  *writer = NULL;
1955
 
  fvm_writer_time_dep_t  time_dep = FVM_WRITER_FIXED_MESH;
 
2518
  cs_post_writer_t  *w = NULL;
 
2519
  cs_post_writer_def_t  *wd = NULL;
1956
2520
 
1957
 
  /* Check that the required mesh is available */
 
2521
  /* Check if the required writer already exists */
1958
2522
 
1959
2523
  if (writer_id == 0)
1960
2524
    bft_error(__FILE__, __LINE__, 0,
1962
2526
                "must be < 0 (reserved) or > 0 (user).\n"));
1963
2527
 
1964
2528
  for (i = 0; i < _cs_post_n_writers; i++) {
1965
 
    if ((_cs_post_writers + i)->id == writer_id)
1966
 
      bft_error(__FILE__, __LINE__, 0,
1967
 
                _("The requested post-processing writer number\n"
1968
 
                  "(%d) has already been assigned.\n"), (int)writer_id);
1969
 
  }
1970
 
 
1971
 
  /* Resize global writers array */
1972
 
 
1973
 
  if (_cs_post_n_writers == _cs_post_n_writers_max) {
1974
 
 
1975
 
    if (_cs_post_n_writers_max == 0)
1976
 
      _cs_post_n_writers_max = 4;
 
2529
    if ((_cs_post_writers + i)->id == writer_id) {
 
2530
      w = _cs_post_writers + i;
 
2531
      wd = w->wd;
 
2532
      assert(wd != NULL);
 
2533
      BFT_FREE(wd->case_name);
 
2534
      BFT_FREE(wd->dir_name);
 
2535
      BFT_FREE(wd->fmt_opts);
 
2536
      break;
 
2537
    }
 
2538
  }
 
2539
 
 
2540
  if (i == _cs_post_n_writers) { /* New definition */
 
2541
 
 
2542
    /* Resize global writers array */
 
2543
 
 
2544
    if (_cs_post_n_writers == _cs_post_n_writers_max) {
 
2545
      if (_cs_post_n_writers_max == 0)
 
2546
        _cs_post_n_writers_max = 4;
 
2547
      else
 
2548
        _cs_post_n_writers_max *= 2;
 
2549
      BFT_REALLOC(_cs_post_writers,
 
2550
                  _cs_post_n_writers_max,
 
2551
                  cs_post_writer_t);
 
2552
    }
 
2553
 
 
2554
    if (writer_id < _cs_post_min_writer_id)
 
2555
      _cs_post_min_writer_id = writer_id;
 
2556
    _cs_post_n_writers += 1;
 
2557
 
 
2558
    w = _cs_post_writers + i;
 
2559
    BFT_MALLOC(w->wd, 1, cs_post_writer_def_t);
 
2560
    wd = w->wd;
 
2561
 
 
2562
  }
 
2563
 
 
2564
  /* Assign writer definition to the structure */
 
2565
 
 
2566
  w->id = writer_id;
 
2567
  w->output_end = output_at_end;
 
2568
  w->frequency_n = frequency_n;
 
2569
  w->frequency_t = frequency_t;
 
2570
  w->active = 0;
 
2571
  w->n_last = -2;
 
2572
  w->t_last = 0.0;
 
2573
 
 
2574
  wd->time_dep = time_dep;
 
2575
 
 
2576
  BFT_MALLOC(wd->case_name, strlen(case_name) + 1, char);
 
2577
  strcpy(wd->case_name, case_name);
 
2578
 
 
2579
  BFT_MALLOC(wd->dir_name, strlen(dir_name) + 1, char);
 
2580
  strcpy(wd->dir_name, dir_name);
 
2581
 
 
2582
  wd->fmt_id = fvm_writer_get_format_id(fmt_name);
 
2583
 
 
2584
  if (fmt_opts != NULL) {
 
2585
    BFT_MALLOC(wd->fmt_opts, strlen(fmt_opts) + 1, char);
 
2586
    strcpy(wd->fmt_opts, fmt_opts);
 
2587
  }
 
2588
  else {
 
2589
    BFT_MALLOC(wd->fmt_opts, 1, char);
 
2590
    wd->fmt_opts[0] = '\0';
 
2591
  }
 
2592
 
 
2593
  w->writer = NULL;
 
2594
 
 
2595
  /* If writer is the default writer (id -1), update defaults */
 
2596
 
 
2597
  if (writer_id == -1) {
 
2598
    _cs_post_default_format_id = wd->fmt_id;
 
2599
    if (wd->fmt_opts != NULL) {
 
2600
      BFT_REALLOC(_cs_post_default_format_options,
 
2601
                  strlen(wd->fmt_opts)+ 1,
 
2602
                  char);
 
2603
      strcpy(_cs_post_default_format_options, wd->fmt_opts);
 
2604
    }
1977
2605
    else
1978
 
      _cs_post_n_writers_max *= 2;
1979
 
 
1980
 
    BFT_REALLOC(_cs_post_writers,
1981
 
                _cs_post_n_writers_max,
1982
 
                cs_post_writer_t);
1983
 
 
1984
 
  }
1985
 
 
1986
 
  if (writer_id < _cs_post_min_writer_id)
1987
 
    _cs_post_min_writer_id = writer_id;
1988
 
 
1989
 
  _cs_post_n_writers += 1;
1990
 
 
1991
 
  /* Assign newly created writer to the structure */
1992
 
 
1993
 
  writer = _cs_post_writers + _cs_post_n_writers - 1;
1994
 
 
1995
 
  writer->id = writer_id;
1996
 
  writer->frequency = frequency;
1997
 
  writer->write_displ = false;
1998
 
  writer->active = 0;
1999
 
 
2000
 
  if (mod_flag >= 10) {
2001
 
    writer->write_displ = true;
2002
 
    mod_flag -= 10;
2003
 
  }
2004
 
 
2005
 
  if (mod_flag == 1)
2006
 
    time_dep = FVM_WRITER_TRANSIENT_COORDS;
2007
 
  else if (mod_flag >= 2)
2008
 
    time_dep = FVM_WRITER_TRANSIENT_CONNECT;
2009
 
 
2010
 
  writer->writer = fvm_writer_init(case_name,
2011
 
                                   dir_name,
2012
 
                                   fmt_name,
2013
 
                                   fmt_opts,
2014
 
                                   time_dep);
2015
 
}
2016
 
 
2017
 
/*----------------------------------------------------------------------------
2018
 
 * Create a post-processing mesh; lists of cells or faces to extract are
2019
 
 * sorted upon exit, whether they were sorted upon calling or not.
2020
 
 *
2021
 
 * The list of associated cells is only necessary if the number of cells
2022
 
 * to extract is strictly greater than 0 and less than the number of cells
2023
 
 * of the computational mesh.
2024
 
 *
2025
 
 * Lists of faces are ignored if the number of extracted cells is nonzero;
2026
 
 * otherwise, if the number of boundary faces to extract is equal to the
2027
 
 * number of boundary faces in the computational mesh, and the number of
2028
 
 * interior faces to extract is zero, than we extrac by default the boundary
2029
 
 * mesh, and the list of associated boundary faces is thus not necessary.
2030
 
 *
2031
 
 * parameters:
2032
 
 *   mesh_id     <-- number of mesh to create (< 0 reserved, > 0 for user)
2033
 
 *   mesh_name   <-- associated mesh name
2034
 
 *   n_cells     <-- number of associated cells
2035
 
 *   n_i_faces   <-- number of associated interior faces
2036
 
 *   n_b_faces   <-- number of associated boundary faces
2037
 
 *   cell_list   <-- list of associated cells
2038
 
 *   i_face_list <-- list of associated interior faces
2039
 
 *   b_face_list <-- list of associated boundary faces
2040
 
 *----------------------------------------------------------------------------*/
2041
 
 
2042
 
void
2043
 
cs_post_add_mesh(int          mesh_id,
2044
 
                 const char  *mesh_name,
2045
 
                 cs_int_t     n_cells,
2046
 
                 cs_int_t     n_i_faces,
2047
 
                 cs_int_t     n_b_faces,
2048
 
                 cs_int_t     cell_list[],
2049
 
                 cs_int_t     i_face_list[],
2050
 
                 cs_int_t     b_face_list[])
2051
 
{
2052
 
  /* local variables */
2053
 
 
2054
 
  cs_post_mesh_t  *post_mesh = NULL;
2055
 
 
2056
 
  /* Add and initialize base structure */
2057
 
 
2058
 
  post_mesh = _cs_post_add_mesh(mesh_id);
2059
 
 
2060
 
  /* Create mesh and assign to structure */
2061
 
 
2062
 
  _cs_post_define_mesh(post_mesh,
2063
 
                       mesh_name,
2064
 
                       n_cells,
2065
 
                       n_i_faces,
2066
 
                       n_b_faces,
2067
 
                       cell_list,
2068
 
                       i_face_list,
2069
 
                       b_face_list);
 
2606
      BFT_FREE(_cs_post_default_format_options);
 
2607
  }
 
2608
}
 
2609
 
 
2610
/*----------------------------------------------------------------------------
 
2611
 * Define a volume post-processing mesh.
 
2612
 *
 
2613
 * parameters:
 
2614
 *   mesh_id        <-- id of mesh to define (< 0 reserved, > 0 for user)
 
2615
 *   mesh_name      <-- associated mesh name
 
2616
 *   cell_criteria  <-- selection criteria for cells
 
2617
 *   add_groups     <-- if true, add group information if present
 
2618
 *   auto_variables <-- if true, automatic output of main variables
 
2619
 *   n_writers      <-- number of associated writers
 
2620
 *   writer_ids     <-- ids of associated writers
 
2621
 *----------------------------------------------------------------------------*/
 
2622
 
 
2623
void
 
2624
cs_post_define_volume_mesh(int          mesh_id,
 
2625
                           const char  *mesh_name,
 
2626
                           const char  *cell_criteria,
 
2627
                           cs_bool_t    add_groups,
 
2628
                           cs_bool_t    auto_variables,
 
2629
                           int          n_writers,
 
2630
                           const int    writer_ids[])
 
2631
{
 
2632
  /* Call common initialization */
 
2633
 
 
2634
  cs_post_mesh_t *post_mesh = NULL;
 
2635
 
 
2636
  post_mesh = _predefine_mesh(mesh_id, n_writers, writer_ids);
 
2637
 
 
2638
  /* Define mesh based on current arguments */
 
2639
 
 
2640
  BFT_MALLOC(post_mesh->name, strlen(mesh_name) + 1, char);
 
2641
  strcpy(post_mesh->name, mesh_name);
 
2642
 
 
2643
  if (cell_criteria != NULL) {
 
2644
    BFT_MALLOC(post_mesh->criteria[0], strlen(cell_criteria) + 1, char);
 
2645
    strcpy(post_mesh->criteria[0], cell_criteria);
 
2646
  }
 
2647
 
 
2648
  post_mesh->add_groups = (add_groups) ? true : false;
 
2649
  if (auto_variables)
 
2650
    post_mesh->cat_id = -1;
 
2651
}
 
2652
 
 
2653
/*----------------------------------------------------------------------------
 
2654
 * Define a volume post-processing mesh using a cell list.
 
2655
 
 
2656
 * The list of cells to extract is sorted upon exit, whether it was sorted
 
2657
 * upon calling or not.
 
2658
 *
 
2659
 * parameters:
 
2660
 *   mesh_id        <-- id of mesh to define (< 0 reserved, > 0 for user)
 
2661
 *   mesh_name      <-- associated mesh name
 
2662
 *   n_cells        <-- number of selected cells
 
2663
 *   cell_list      <-> list of selected cells (1 to n numbering)
 
2664
 *   add_groups     <-- if true, add group information if present
 
2665
 *   auto_variables <-- if true, automatic output of main variables
 
2666
 *   n_writers      <-- number of associated writers
 
2667
 *   writer_ids     <-- ids of associated writers
 
2668
 *----------------------------------------------------------------------------*/
 
2669
 
 
2670
void
 
2671
cs_post_define_volume_mesh_by_list(int          mesh_id,
 
2672
                                   const char  *mesh_name,
 
2673
                                   fvm_lnum_t   n_cells,
 
2674
                                   fvm_lnum_t   cell_list[],
 
2675
                                   cs_bool_t    add_groups,
 
2676
                                   cs_bool_t    auto_variables,
 
2677
                                   int          n_writers,
 
2678
                                   const int    writer_ids[])
 
2679
{
 
2680
  /* Call common initialization */
 
2681
 
 
2682
  cs_post_mesh_t *post_mesh = NULL;
 
2683
 
 
2684
  post_mesh = _predefine_mesh(mesh_id, n_writers, writer_ids);
 
2685
 
 
2686
  BFT_MALLOC(post_mesh->name, strlen(mesh_name) + 1, char);
 
2687
  strcpy(post_mesh->name, mesh_name);
 
2688
 
 
2689
  post_mesh->add_groups = (add_groups != 0) ? true : false;
 
2690
  if (auto_variables)
 
2691
    post_mesh->cat_id = -1;
 
2692
 
 
2693
  _define_export_mesh(post_mesh,
 
2694
                      n_cells,
 
2695
                      0,
 
2696
                      0,
 
2697
                      cell_list,
 
2698
                      NULL,
 
2699
                      NULL);
 
2700
}
 
2701
 
 
2702
/*----------------------------------------------------------------------------
 
2703
 * Define a surface post-processing mesh.
 
2704
 *
 
2705
 * parameters:
 
2706
 *   mesh_id         <-- id of mesh to define (< 0 reserved, > 0 for user)
 
2707
 *   mesh_name       <-- associated mesh name
 
2708
 *   i_face_criteria <-- selection criteria for interior faces
 
2709
 *   b_face_criteria <-- selection criteria for boundary faces
 
2710
 *   add_groups      <-- if true, add group information if present
 
2711
 *   auto_variables  <-- if true, automatic output of main variables
 
2712
 *   n_writers       <-- number of associated writers
 
2713
 *   writer_ids      <-- ids of associated writers
 
2714
 *----------------------------------------------------------------------------*/
 
2715
 
 
2716
void
 
2717
cs_post_define_surface_mesh(int          mesh_id,
 
2718
                            const char  *mesh_name,
 
2719
                            const char  *i_face_criteria,
 
2720
                            const char  *b_face_criteria,
 
2721
                            cs_bool_t    add_groups,
 
2722
                            cs_bool_t    auto_variables,
 
2723
                            int          n_writers,
 
2724
                            const int    writer_ids[])
 
2725
{
 
2726
  /* Call common initialization */
 
2727
 
 
2728
  cs_post_mesh_t *post_mesh = NULL;
 
2729
 
 
2730
  post_mesh = _predefine_mesh(mesh_id, n_writers, writer_ids);
 
2731
 
 
2732
  /* Define mesh based on current arguments */
 
2733
 
 
2734
  BFT_MALLOC(post_mesh->name, strlen(mesh_name) + 1, char);
 
2735
  strcpy(post_mesh->name, mesh_name);
 
2736
 
 
2737
  if (i_face_criteria != NULL) {
 
2738
    BFT_MALLOC(post_mesh->criteria[1], strlen(i_face_criteria) + 1, char);
 
2739
    strcpy(post_mesh->criteria[1], i_face_criteria);
 
2740
  }
 
2741
 
 
2742
  if (b_face_criteria != NULL) {
 
2743
    BFT_MALLOC(post_mesh->criteria[2], strlen(b_face_criteria) + 1, char);
 
2744
    strcpy(post_mesh->criteria[2], b_face_criteria);
 
2745
  }
 
2746
 
 
2747
  post_mesh->add_groups = (add_groups != 0) ? true : false;
 
2748
  if (auto_variables)
 
2749
    post_mesh->cat_id = -2;
 
2750
}
 
2751
 
 
2752
/*----------------------------------------------------------------------------
 
2753
 * Define a surface post-processing mesh using a face list.
 
2754
 *
 
2755
 * Lists of cells or faces to extract are sorted upon exit, whether they
 
2756
 * were sorted upon calling or not.
 
2757
 *
 
2758
 * parameters:
 
2759
 *   mesh_id        <-- id of mesh to define (< 0 reserved, > 0 for user)
 
2760
 *   mesh_name      <-- associated mesh name
 
2761
 *   n_i_faces      <-- number of associated interior faces
 
2762
 *   n_b_faces      <-- number of associated boundary faces
 
2763
 *   i_face_list    <-> list of associated interior faces (1 to n numbering)
 
2764
 *   b_face_list    <-> list of associated boundary faces (1 to n numbering)
 
2765
 *   add_groups     <-- if true, add group information if present
 
2766
 *   auto_variables <-- if true, automatic output of main variables
 
2767
 *   n_writers      <-- number of associated writers
 
2768
 *   writer_ids     <-- ids of associated writers
 
2769
 *----------------------------------------------------------------------------*/
 
2770
 
 
2771
void
 
2772
cs_post_define_surface_mesh_by_list(int          mesh_id,
 
2773
                                    const char  *mesh_name,
 
2774
                                    fvm_lnum_t   n_i_faces,
 
2775
                                    fvm_lnum_t   n_b_faces,
 
2776
                                    fvm_lnum_t   i_face_list[],
 
2777
                                    fvm_lnum_t   b_face_list[],
 
2778
                                    cs_bool_t    add_groups,
 
2779
                                    cs_bool_t    auto_variables,
 
2780
                                    int          n_writers,
 
2781
                                    const int    writer_ids[])
 
2782
{
 
2783
  /* Call common initialization */
 
2784
 
 
2785
  cs_post_mesh_t *post_mesh = NULL;
 
2786
 
 
2787
  post_mesh = _predefine_mesh(mesh_id, n_writers, writer_ids);
 
2788
 
 
2789
  /* Define mesh based on current arguments */
 
2790
 
 
2791
  BFT_MALLOC(post_mesh->name, strlen(mesh_name) + 1, char);
 
2792
  strcpy(post_mesh->name, mesh_name);
 
2793
 
 
2794
  post_mesh->add_groups = (add_groups != 0) ? true : false;
 
2795
  if (auto_variables)
 
2796
    post_mesh->cat_id = -2;
 
2797
 
 
2798
  _define_export_mesh(post_mesh,
 
2799
                      0,
 
2800
                      n_i_faces,
 
2801
                      n_b_faces,
 
2802
                      NULL,
 
2803
                      i_face_list,
 
2804
                      b_face_list);
 
2805
}
 
2806
 
 
2807
/*----------------------------------------------------------------------------
 
2808
 * Create an alias to a post-processing mesh.
 
2809
 *
 
2810
 * An alias allows association of an extra identifier (id) to an
 
2811
 * existing post-processing mesh, and thus to associate different writers
 
2812
 * than those associated with the existing mesh. For example, this allows
 
2813
 * outputting a set of main variables every n1 time steps with one writer,
 
2814
 * and outputting a specific set of variables every n2 time time steps to
 
2815
 * another post-processing set using another writer, without the overhead
 
2816
 * that would be incurred by duplication of the post-processing mesh.
 
2817
 *
 
2818
 * An alias is thus treated in all points like its associated mesh;
 
2819
 * if the definition of either one is modified, that of the other is
 
2820
 * modified also.
 
2821
 *
 
2822
 * It is forbidden to associate an alias to another alias (as there is no
 
2823
 * identified use for this, and it would make consistency checking more
 
2824
 * difficult), but multiple aliases may be associated with a given mesh.
 
2825
 *
 
2826
 * parameters:
 
2827
 *   mesh_id         <-- id of mesh to define (< 0 reserved, > 0 for user)
 
2828
 *   aliased_mesh_id <-- id of aliased mesh
 
2829
 *   auto_variables  <-- if true, automatic output of main variables
 
2830
 *   n_writers       <-- number of associated writers
 
2831
 *   writer_ids      <-- ids of associated writers
 
2832
 *----------------------------------------------------------------------------*/
 
2833
 
 
2834
void
 
2835
cs_post_define_alias_mesh(int        mesh_id,
 
2836
                          int        aliased_mesh_id,
 
2837
                          cs_bool_t  auto_variables,
 
2838
                          int        n_writers,
 
2839
                          const int  writer_ids[])
 
2840
{
 
2841
  int _alias_id = 0;
 
2842
 
 
2843
  cs_post_mesh_t *post_mesh = NULL;
 
2844
  cs_post_mesh_t  *ref_mesh = NULL;
 
2845
 
 
2846
  /* Initial checks */
 
2847
 
 
2848
  _alias_id = _cs_post_mesh_id(aliased_mesh_id);
 
2849
  ref_mesh = _cs_post_meshes + _alias_id;
 
2850
 
 
2851
  if (ref_mesh->alias > -1)
 
2852
    bft_error(__FILE__, __LINE__, 0,
 
2853
              _("The mesh %d cannot be an alias of mesh %d,\n"
 
2854
                "which is itself an alias of mesh %d.\n"),
 
2855
              mesh_id, aliased_mesh_id,
 
2856
              (int)((_cs_post_meshes + ref_mesh->alias)->id));
 
2857
 
 
2858
  /* Call common initialization */
 
2859
 
 
2860
  post_mesh = _predefine_mesh(mesh_id, n_writers, writer_ids);
 
2861
 
 
2862
  /* Define mesh based on current arguments */
 
2863
 
 
2864
  post_mesh->alias = _alias_id;
 
2865
 
 
2866
  post_mesh->cat_id = (auto_variables) ? -1 : mesh_id;
 
2867
  /* may be fixed once the contents of the reference mesh are known */
2070
2868
}
2071
2869
 
2072
2870
/*----------------------------------------------------------------------------
2088
2886
 * This is important when variables values are exported.
2089
2887
 *
2090
2888
 * parameters:
2091
 
 *   mesh_id   <-- number of mesh to create (< 0 reserved, > 0 for user)
2092
 
 *   exp_mesh  <-- mesh in exportable representation (i.e. fvm_nodal_t)
2093
 
 *   dim_shift <-- nonzero if exp_mesh has been projected
2094
 
 *   transfer  <-- if true, ownership of exp_mesh is transferred to the
2095
 
 *                 post-processing mesh
 
2889
 *   mesh_id        <-- number of mesh to create (< 0 reserved, > 0 for user)
 
2890
 *   exp_mesh       <-- mesh in exportable representation (i.e. fvm_nodal_t)
 
2891
 *   dim_shift      <-- nonzero if exp_mesh has been projected
 
2892
 *   transfer       <-- if true, ownership of exp_mesh is transferred to
 
2893
 *                      the post-processing mesh
 
2894
 *   auto_variables <-- if true, automatic output of main variables
 
2895
 *   n_writers      <-- number of associated writers
 
2896
 *   writer_ids     <-- ids of associated writers
2096
2897
 *----------------------------------------------------------------------------*/
2097
2898
 
2098
2899
void
2099
 
cs_post_add_existing_mesh(int           mesh_id,
2100
 
                          fvm_nodal_t  *exp_mesh,
2101
 
                          int           dim_shift,
2102
 
                          cs_bool_t     transfer)
 
2900
cs_post_define_existing_mesh(int           mesh_id,
 
2901
                             fvm_nodal_t  *exp_mesh,
 
2902
                             int           dim_shift,
 
2903
                             cs_bool_t     transfer,
 
2904
                             cs_bool_t     auto_variables,
 
2905
                             int           n_writers,
 
2906
                             const int     writer_ids[])
2103
2907
{
2104
2908
  /* local variables */
2105
2909
 
2113
2917
                                      MPI_Allreduce(..., MPI_MIN, ...) */
2114
2918
 
2115
2919
  int         dim_ent = 0;
 
2920
  int         dim_ext_ent = 0;
2116
2921
  cs_bool_t   maj_ent_flag = false;
2117
2922
  fvm_lnum_t  n_elts = 0;
2118
2923
 
2121
2926
 
2122
2927
  /* Initialization of base structure */
2123
2928
 
2124
 
  post_mesh = _cs_post_add_mesh(mesh_id);
 
2929
  post_mesh = _predefine_mesh(mesh_id, n_writers, writer_ids);
2125
2930
 
2126
2931
  /* Assign mesh to structure */
2127
2932
 
2132
2937
 
2133
2938
  /* Compute number of cells and/or faces */
2134
2939
 
2135
 
  dim_ent = fvm_nodal_get_max_entity_dim(exp_mesh) + dim_shift;
2136
 
  n_elts = fvm_nodal_get_n_entities(exp_mesh, dim_ent);
 
2940
  dim_ext_ent = fvm_nodal_get_max_entity_dim(exp_mesh);
 
2941
  dim_ent = dim_ext_ent + dim_shift;
 
2942
  n_elts = fvm_nodal_get_n_entities(exp_mesh, dim_ext_ent);
2137
2943
 
2138
2944
  if (dim_ent == 3 && n_elts > 0)
2139
2945
    loc_flag[0] = 0;
2142
2948
 
2143
2949
    BFT_MALLOC(num_ent_parent, n_elts, cs_int_t);
2144
2950
 
2145
 
    fvm_nodal_get_parent_num(exp_mesh, dim_ent, num_ent_parent);
 
2951
    fvm_nodal_get_parent_num(exp_mesh, dim_ext_ent, num_ent_parent);
2146
2952
 
2147
2953
    dec_num_fbr = cs_glob_mesh->n_b_faces;
2148
2954
    for (ind_fac = 0; ind_fac < n_elts; ind_fac++) {
2173
2979
  /* Global indicators of mesh entity type presence;
2174
2980
     updated only if the mesh is not totally empty (for time-depending
2175
2981
     meshes, empty at certain times, we want to know the last type
2176
 
     of entity used in USMPST) */
 
2982
     of entity used in usmpst) */
2177
2983
 
2178
2984
  for (i = 0; i < 3; i++) {
2179
2985
    if (glob_flag[i] == 0)
2188
2994
        post_mesh->ent_flag[i] = 0;
2189
2995
    }
2190
2996
  }
 
2997
 
 
2998
  if (auto_variables) {
 
2999
    post_mesh->cat_id = -1;
 
3000
    _check_mesh_cat_id(post_mesh);
 
3001
  }
2191
3002
}
2192
3003
 
2193
3004
/*----------------------------------------------------------------------------
2201
3012
 * the surface mesh with subdivided polygons.
2202
3013
 *
2203
3014
 * parameters:
2204
 
 *   edges_id <-- id of edges mesh to create (< 0 reserved, > 0 for user)
2205
 
 *   base_id  <-- id of existing mesh (< 0 reserved, > 0 for user)
 
3015
 *   mesh_id <-- id of edges mesh to create (< 0 reserved, > 0 for user)
 
3016
 *   base_mesh_id   <-- id of existing mesh (< 0 reserved, > 0 for user)
 
3017
 *   n_writers  <-- number of associated writers
 
3018
 *   writer_ids <-- ids of associated writers
2206
3019
 *----------------------------------------------------------------------------*/
2207
3020
 
2208
3021
void
2209
 
cs_post_add_mesh_edges(int  edges_id,
2210
 
                       int  base_id)
 
3022
cs_post_define_edges_mesh(int        mesh_id,
 
3023
                          int        base_mesh_id,
 
3024
                          int        n_writers,
 
3025
                          const int  writer_ids[])
2211
3026
{
2212
3027
  /* local variables */
2213
3028
 
2214
 
  char *edges_name = NULL;
2215
 
  cs_post_mesh_t *post_edges = NULL;
 
3029
  cs_post_mesh_t *post_mesh = NULL;
2216
3030
  fvm_nodal_t *exp_edges = NULL;
2217
 
 
2218
 
  const cs_post_mesh_t *post_base = _cs_post_meshes +_cs_post_mesh_id(base_id);
2219
 
  const fvm_nodal_t *exp_mesh = post_base->exp_mesh;
2220
 
  const char *exp_name = fvm_nodal_get_name(exp_mesh);
 
3031
  const fvm_nodal_t *exp_mesh = NULL;
 
3032
  const char *exp_name = NULL;
 
3033
 
 
3034
  cs_post_mesh_t *post_base
 
3035
    = _cs_post_meshes + _cs_post_mesh_id(base_mesh_id);
 
3036
 
 
3037
  /* if base mesh structure is not built yet, force its build now */
 
3038
 
 
3039
  if (exp_mesh == NULL)
 
3040
    _define_mesh_from_criteria(post_base);
 
3041
 
 
3042
  exp_mesh = post_base->exp_mesh;
 
3043
  exp_name = fvm_nodal_get_name(exp_mesh);
2221
3044
 
2222
3045
  /* Add and initialize base structure */
2223
3046
 
2224
 
  post_edges = _cs_post_add_mesh(edges_id);
 
3047
  post_mesh = _predefine_mesh(mesh_id, n_writers, writer_ids);
 
3048
 
 
3049
  BFT_MALLOC(post_mesh->name, strlen(exp_name) + strlen(_(" edges")) + 1, char);
 
3050
  strcpy(post_mesh->name, exp_name);
 
3051
  strcat(post_mesh->name, _(" edges"));
2225
3052
 
2226
3053
  /* Copy mesh edges to new mesh structure */
2227
3054
 
2228
 
  BFT_MALLOC(edges_name, strlen(exp_name) + strlen(_(" edges")) + 1, char);
2229
 
 
2230
 
  strcpy(edges_name, exp_name);
2231
 
  strcat(edges_name, _(" edges"));
2232
 
 
2233
 
  exp_edges = fvm_nodal_copy_edges(edges_name, exp_mesh);
2234
 
 
2235
 
  BFT_FREE(edges_name);
 
3055
  exp_edges = fvm_nodal_copy_edges(post_mesh->name, exp_mesh);
2236
3056
 
2237
3057
  /* Create mesh and assign to structure */
2238
3058
 
2239
 
  post_edges->exp_mesh = exp_edges;
2240
 
  post_edges->_exp_mesh = exp_edges;
 
3059
  post_mesh->exp_mesh = exp_edges;
 
3060
  post_mesh->_exp_mesh = exp_edges;
2241
3061
}
2242
3062
 
2243
3063
/*----------------------------------------------------------------------------
2244
 
 * Assign a category to a post-processing mesh.
2245
 
 *
2246
 
 * By default, each mesh is assigned a category id identical to its id.
2247
 
 * The automatic variables output associated with the main volume and
2248
 
 * boundary meshes will also be applied to meshes of the same categories
2249
 
 * (i.e. -1 and -2 respectively, whether meshes -1 and -2 are actually
2250
 
 * defined or not), so setting a user mesh's category to one of these
2251
 
 * values will automatically provide the same automatic variable output to
2252
 
 * the user mesh.
 
3064
 * Remove a post-processing mesh.
 
3065
 *
 
3066
 * No further post-processing output will be allowed on this mesh,
 
3067
 * so the associated structures may be freed.
 
3068
 *
 
3069
 * A post-processing mesh that has been associated with a time-varying
 
3070
 * writer or that is referenced by an alias may not be removed.
2253
3071
 *
2254
3072
 * parameters:
2255
 
 *   mesh_id     <-- id of associated mesh
2256
 
 *   category_id <-- id of mesh category (-1: as volume, -2: as boundary)
 
3073
 *   mesh_id <-- id of mesh to remove
2257
3074
 *----------------------------------------------------------------------------*/
2258
3075
 
2259
3076
void
2260
 
cs_post_set_mesh_category(int  mesh_id,
2261
 
                          int  category_id)
 
3077
cs_post_free_mesh(int  mesh_id)
2262
3078
{
2263
 
  /* local variables */
2264
 
 
2265
 
  int _mesh_id;
 
3079
  int i;
2266
3080
  cs_post_mesh_t  *post_mesh = NULL;
2267
3081
 
2268
 
  /* Get base structure (return if we do not own the mesh) */
2269
 
 
2270
 
  _mesh_id = _cs_post_mesh_id(mesh_id);
 
3082
  /* Search for requested mesh */
 
3083
 
 
3084
  int _mesh_id = _cs_post_mesh_id(mesh_id);
 
3085
 
 
3086
  /* Check if mesh was aliased */
 
3087
 
 
3088
  for (i = 0; i < _cs_post_n_meshes; i++) {
 
3089
 
 
3090
    post_mesh = _cs_post_meshes + i;
 
3091
    if (post_mesh->alias == _mesh_id)
 
3092
      bft_error(__FILE__, __LINE__, 0,
 
3093
                _("Post-processing mesh number %d has been aliased\n"
 
3094
                  "by mesh %d, so it may not be freed.\n"),
 
3095
                mesh_id, post_mesh->id);
 
3096
  }
 
3097
 
 
3098
  /* Now set pointer to mesh and check for time dependency */
 
3099
 
2271
3100
  post_mesh = _cs_post_meshes + _mesh_id;
2272
3101
 
2273
 
  /* Set category */
2274
 
 
2275
 
  post_mesh->cat_id = category_id;
2276
 
}
2277
 
 
2278
 
/*----------------------------------------------------------------------------
2279
 
 * Create an alias to a post-processing mesh.
2280
 
 *
2281
 
 * An alias allows association of an extra identifier (number) to an
2282
 
 * existing post-processing mesh, and thus to associate different writers
2283
 
 * than those associated with the existing mesh. For example, this allows
2284
 
 * outputting a set of main variables every n1 time steps with one writer,
2285
 
 * and outputting a specific set of variables every n2 time time steps to
2286
 
 * another post-processing set using another writer, without the overhead
2287
 
 * that would be incurred by duplication of the post-processing mesh.
2288
 
 *
2289
 
 * An alias is thus treated in all points like its associated mesh;
2290
 
 * if the definition of either one is modified, that of the other is
2291
 
 * modified also.
2292
 
 *
2293
 
 * It is forbidden to associate an alias to another alias (as there is no
2294
 
 * identified use for this, and it would make consistency checking more
2295
 
 * difficult), but multiple aliases may be associated with a given mesh.
2296
 
 *
2297
 
 * parameters:
2298
 
 *   alias_id <-- number of alias to create (< 0 reserved, > 0 for user)
2299
 
 *   mesh_id  <-- id of associated mesh
2300
 
 *----------------------------------------------------------------------------*/
2301
 
 
2302
 
void
2303
 
cs_post_alias_mesh(int  alias_id,
2304
 
                   int  mesh_id)
2305
 
{
2306
 
  /* local variables */
2307
 
 
2308
 
  int    indref, j;
2309
 
 
2310
 
  cs_post_mesh_t  *post_mesh = NULL;
2311
 
  cs_post_mesh_t  *ref_mesh = NULL;
2312
 
 
2313
 
  /* Initial checks */
2314
 
 
2315
 
  indref = _cs_post_mesh_id(mesh_id);
2316
 
  ref_mesh = _cs_post_meshes + indref;
2317
 
 
2318
 
  if (ref_mesh->alias > -1)
2319
 
    bft_error(__FILE__, __LINE__, 0,
2320
 
              _("The mesh %d cannot be an alias of mesh %d,\n"
2321
 
                "which is itself an alias of mesh %d.\n"),
2322
 
              (int)alias_id, (int)mesh_id,
2323
 
              (int)((_cs_post_meshes + ref_mesh->alias)->id));
2324
 
 
2325
 
  /* Initialize base structure */
2326
 
 
2327
 
  post_mesh = _cs_post_add_mesh(alias_id);
2328
 
 
2329
 
  /* Update ref_mesh, as the adress of _cs_post_meshes may
2330
 
     have been changed by reallocation */
2331
 
 
2332
 
  ref_mesh = _cs_post_meshes + indref;
2333
 
 
2334
 
  /* Links to the reference mesh */
2335
 
 
2336
 
  post_mesh->alias = indref;
2337
 
 
2338
 
  post_mesh->exp_mesh = ref_mesh->exp_mesh;
2339
 
 
2340
 
  post_mesh->mod_flag_min = ref_mesh->mod_flag_min;
2341
 
  post_mesh->mod_flag_max = ref_mesh->mod_flag_max;
2342
 
 
2343
 
  for (j = 0; j < 3; j++)
2344
 
    post_mesh->ent_flag[j] = ref_mesh->ent_flag[j];
2345
 
 
2346
 
  post_mesh->n_i_faces = ref_mesh->n_i_faces;
2347
 
  post_mesh->n_b_faces = ref_mesh->n_b_faces;
 
3102
  for (i = 0; i < post_mesh->n_writers; i++) {
 
3103
 
 
3104
    cs_post_writer_t *writer = _cs_post_writers + post_mesh->writer_id[i];
 
3105
 
 
3106
    fvm_writer_time_dep_t time_dep = fvm_writer_get_time_dep(writer->writer);
 
3107
 
 
3108
    if (post_mesh->nt_last > -2 && time_dep != FVM_WRITER_FIXED_MESH)
 
3109
      bft_error(__FILE__, __LINE__, 0,
 
3110
                _("Post-processing mesh number %d has been associated\n"
 
3111
                  "to writer %d which allows time-varying meshes, so\n"
 
3112
                  "it may not be freed.\n"),
 
3113
                mesh_id, writer->id);
 
3114
  }
 
3115
 
 
3116
  /* Finally, remove mesh if allowed */
 
3117
 
 
3118
  _free_mesh(_mesh_id);
2348
3119
}
2349
3120
 
2350
3121
/*----------------------------------------------------------------------------
2434
3205
  /* local variables */
2435
3206
 
2436
3207
  int i, _mesh_id;
2437
 
  char  *mesh_name = NULL;
2438
3208
  cs_post_mesh_t  *post_mesh = NULL;
2439
 
  cs_post_writer_t    *writer = NULL;
2440
3209
 
2441
3210
  /* Get base structure (return if we do not own the mesh) */
2442
3211
 
2446
3215
  if (post_mesh->_exp_mesh == NULL)
2447
3216
    return;
2448
3217
 
2449
 
  /* Remplace base structure */
2450
 
 
2451
 
  BFT_MALLOC(mesh_name,
2452
 
             strlen(fvm_nodal_get_name(post_mesh->exp_mesh)) + 1,
2453
 
             char);
2454
 
  strcpy(mesh_name, fvm_nodal_get_name(post_mesh->exp_mesh));
 
3218
  /* Replace base structure */
2455
3219
 
2456
3220
  fvm_nodal_destroy(post_mesh->_exp_mesh);
2457
3221
  post_mesh->exp_mesh = NULL;
2458
3222
 
2459
 
  _cs_post_define_mesh(post_mesh,
2460
 
                       mesh_name,
2461
 
                       n_cells,
2462
 
                       n_i_faces,
2463
 
                       n_b_faces,
2464
 
                       cell_list,
2465
 
                       i_face_list,
2466
 
                       b_face_list);
2467
 
 
2468
 
  BFT_FREE(mesh_name);
 
3223
  _define_export_mesh(post_mesh,
 
3224
                      n_cells,
 
3225
                      n_i_faces,
 
3226
                      n_b_faces,
 
3227
                      cell_list,
 
3228
                      i_face_list,
 
3229
                      b_face_list);
2469
3230
 
2470
3231
  /* Update possible aliases */
2471
3232
 
2472
3233
  for (i = 0; i < _cs_post_n_meshes; i++) {
2473
3234
    if ((_cs_post_meshes + i)->alias == _mesh_id)
2474
 
      (_cs_post_meshes + i)->exp_mesh
2475
 
        = post_mesh->exp_mesh;
2476
 
  }
2477
 
 
2478
 
  /* Divide polygons or polyhedra into simple elements */
2479
 
 
2480
 
  for (i = 0; i < post_mesh->n_writers; i++) {
2481
 
 
2482
 
    writer = _cs_post_writers + post_mesh->writer_id[i];
2483
 
    _cs_post_divide_poly(post_mesh, writer);
2484
 
 
2485
 
  }
 
3235
      (_cs_post_meshes + i)->exp_mesh = post_mesh->exp_mesh;
 
3236
  }
 
3237
}
 
3238
 
 
3239
/*----------------------------------------------------------------------------
 
3240
 * Return the default writer format name
 
3241
 *
 
3242
 * Returns:
 
3243
 *   name of the default writer format
 
3244
 *----------------------------------------------------------------------------*/
 
3245
 
 
3246
const char *
 
3247
cs_post_get_default_format(void)
 
3248
{
 
3249
  return (fvm_writer_format_name(_cs_post_default_format_id));
 
3250
}
 
3251
 
 
3252
/*----------------------------------------------------------------------------
 
3253
 * Return the default writer format options
 
3254
 *
 
3255
 * Returns:
 
3256
 *   default writer format options string
 
3257
 *----------------------------------------------------------------------------*/
 
3258
 
 
3259
const char *
 
3260
cs_post_get_default_format_options(void)
 
3261
{
 
3262
  return (_cs_post_default_format_options);
2486
3263
}
2487
3264
 
2488
3265
/*----------------------------------------------------------------------------
2512
3289
}
2513
3290
 
2514
3291
/*----------------------------------------------------------------------------
2515
 
 * Associate a writer with a post-processing mesh.
2516
 
 *
2517
 
 * If the writer only allows fixed (i.e. time-independent) meshes, the
2518
 
 * mesh is exported immediately. Otherwise, output is delayed until
2519
 
 * cs_post_write_meshes() is called for an active time step.
2520
 
 *
2521
 
 * parameters:
2522
 
 *   mesh_id   <-- id of associated mesh
2523
 
 *   writer_id <-- id of associated writer
2524
 
 *----------------------------------------------------------------------------*/
2525
 
 
2526
 
void
2527
 
cs_post_associate(int  mesh_id,
2528
 
                  int  writer_id)
2529
 
{
2530
 
  int  i;
2531
 
  int  _mesh_id, _writer_id;
2532
 
  fvm_writer_time_dep_t mod_flag;
2533
 
 
2534
 
  cs_post_mesh_t  *post_mesh = NULL;
2535
 
  cs_post_writer_t  *writer = NULL;
2536
 
 
2537
 
  /* Search for requested mesh and writer */
2538
 
 
2539
 
  _mesh_id = _cs_post_mesh_id(mesh_id);
2540
 
  _writer_id = _cs_post_writer_id(writer_id);
2541
 
 
2542
 
  post_mesh = _cs_post_meshes + _mesh_id;
2543
 
 
2544
 
  /* Check that the writer is not already associated */
2545
 
 
2546
 
  for (i = 0; i < post_mesh->n_writers; i++) {
2547
 
    if (post_mesh->writer_id[i] == _writer_id)
2548
 
      break;
2549
 
  }
2550
 
 
2551
 
  /* If the writer is not already associated, associate it */
2552
 
 
2553
 
  if (i >= post_mesh->n_writers) {
2554
 
 
2555
 
    post_mesh->n_writers += 1;
2556
 
    BFT_REALLOC(post_mesh->writer_id,
2557
 
                post_mesh->n_writers,
2558
 
                cs_int_t);
2559
 
 
2560
 
    post_mesh->writer_id[post_mesh->n_writers - 1] = _writer_id;
2561
 
    post_mesh->nt_last = - 1;
2562
 
 
2563
 
    /* Update structure */
2564
 
 
2565
 
    writer = _cs_post_writers + _writer_id;
2566
 
    mod_flag = fvm_writer_get_time_dep(writer->writer);
2567
 
 
2568
 
    if (mod_flag < post_mesh->mod_flag_min)
2569
 
      post_mesh->mod_flag_min = mod_flag;
2570
 
    if (mod_flag > post_mesh->mod_flag_max)
2571
 
      post_mesh->mod_flag_max = mod_flag;
2572
 
 
2573
 
    _cs_post_mod_flag_alias(_mesh_id);
2574
 
 
2575
 
    /* If we must compute the vertices displacement field, we need
2576
 
       to save the initial vertex coordinates */
2577
 
 
2578
 
    if (   _cs_post_deformable == false
2579
 
        && _cs_post_ini_vtx_coo == NULL
2580
 
        && writer->write_displ == true) {
2581
 
 
2582
 
      cs_mesh_t *maillage = cs_glob_mesh;
2583
 
 
2584
 
      if (maillage->n_vertices > 0) {
2585
 
        BFT_MALLOC(_cs_post_ini_vtx_coo,
2586
 
                   maillage->n_vertices * 3,
2587
 
                   cs_real_t);
2588
 
        memcpy(_cs_post_ini_vtx_coo,
2589
 
               maillage->vtx_coord,
2590
 
               maillage->n_vertices * 3 * sizeof(cs_real_t));
2591
 
      }
2592
 
 
2593
 
      _cs_post_deformable = true;
2594
 
 
2595
 
    }
2596
 
 
2597
 
    /* Divide polygons or polyhedra into simple elements */
2598
 
 
2599
 
    _cs_post_divide_poly(post_mesh, writer);
2600
 
 
2601
 
    /* If the writer only allows fixed (i.e. time-independent) meshes,
2602
 
       output mesh immediately */
2603
 
 
2604
 
    if (mod_flag == FVM_WRITER_FIXED_MESH) {
2605
 
      fvm_writer_set_mesh_time(writer->writer, 0, 0.0);
2606
 
      fvm_writer_export_nodal(writer->writer, post_mesh->exp_mesh);
2607
 
    }
2608
 
  }
2609
 
 
2610
 
}
2611
 
 
2612
 
/*----------------------------------------------------------------------------
2613
3292
 * Update "active" or "inactive" flag of writers whose output frequency
2614
3293
 * is a divisor of the current time step number.
2615
3294
 *
2616
3295
 * parameters:
 
3296
 *   nt_max_abs <-- maximum time step number
2617
3297
 *   nt_cur_abs <-- current time step number
 
3298
 *   t_cur_abs  <-- absolute time at the current time step
2618
3299
 *----------------------------------------------------------------------------*/
2619
3300
 
2620
3301
void
2621
 
cs_post_activate_if_default(int  nt_cur_abs)
 
3302
cs_post_activate_if_default(int     nt_max_abs,
 
3303
                            int     nt_cur_abs,
 
3304
                            double  t_cur_abs)
2622
3305
{
2623
3306
  int  i;
2624
3307
  cs_post_writer_t  *writer;
2627
3310
 
2628
3311
    writer = _cs_post_writers + i;
2629
3312
 
2630
 
    if (writer->frequency > 0) {
2631
 
      if (nt_cur_abs % (writer->frequency) == 0)
 
3313
    /* In case of previous calls for a given time step,
 
3314
       a writer's status may not be changed */
 
3315
 
 
3316
    if (writer->n_last == nt_cur_abs) {
 
3317
      writer->active = 1;
 
3318
      continue;
 
3319
    }
 
3320
 
 
3321
    if (writer->frequency_t > 0) {
 
3322
      double  delta_t = t_cur_abs - writer->t_last;
 
3323
      if (delta_t >= writer->frequency_t*(1-1e-6))
 
3324
        writer->active = 1;
 
3325
      else
 
3326
        writer->active = 0;
 
3327
    }
 
3328
    else if (writer->frequency_n > 0) {
 
3329
      if (nt_cur_abs % (writer->frequency_n) == 0)
2632
3330
        writer->active = 1;
2633
3331
      else
2634
3332
        writer->active = 0;
2636
3334
    else
2637
3335
      writer->active = 0;
2638
3336
 
 
3337
    if (nt_cur_abs == nt_max_abs && writer->output_end)
 
3338
      writer->active = 1;
 
3339
 
 
3340
    /* Do not activate transient writers for time-independent stages */
 
3341
 
 
3342
    if (nt_cur_abs < 0) {
 
3343
      fvm_writer_time_dep_t  time_dep;
 
3344
      if (writer->writer)
 
3345
        time_dep = fvm_writer_get_time_dep(writer->writer);
 
3346
      else
 
3347
        time_dep = writer->wd->time_dep;
 
3348
      if (time_dep != FVM_WRITER_FIXED_MESH)
 
3349
        writer->active = 0;
 
3350
    }
 
3351
 
2639
3352
  }
2640
3353
}
2641
3354
 
2645
3358
 *
2646
3359
 * parameters:
2647
3360
 *   writer_id <-- writer id, or 0 for all writers
2648
 
 *   activate  <-- 0 to deactivate, 1 to activate
 
3361
 *   activate  <-- false to deactivate, true to activate
2649
3362
 *----------------------------------------------------------------------------*/
2650
3363
 
2651
3364
void
2652
 
cs_post_activate_writer(int  writer_id,
2653
 
                        int  activate)
 
3365
cs_post_activate_writer(int        writer_id,
 
3366
                        cs_bool_t  activate)
2654
3367
{
2655
3368
  int i;
2656
3369
  cs_post_writer_t  *writer;
2658
3371
  if (writer_id != 0) {
2659
3372
    i = _cs_post_writer_id(writer_id);
2660
3373
    writer = _cs_post_writers + i;
2661
 
    writer->active = (activate > 0) ? 1 : 0;
 
3374
    writer->active = (activate) ? 1 : 0;
2662
3375
  }
2663
3376
  else {
2664
3377
    for (i = 0; i < _cs_post_n_writers; i++) {
2665
3378
      writer = _cs_post_writers + i;
2666
 
      writer->active = (activate > 0) ? 1 : 0;
 
3379
      writer->active = (activate) ? 1 : 0;
2667
3380
    }
2668
3381
  }
2669
3382
}
2687
3400
  id = _cs_post_writer_id(writer_id);
2688
3401
  writer = _cs_post_writers + id;
2689
3402
 
 
3403
  if (writer->writer == NULL)
 
3404
    _init_writer(writer);
 
3405
 
2690
3406
  return writer->writer;
2691
3407
}
2692
3408
 
2774
3490
 
2775
3491
  /* Initializations */
2776
3492
 
2777
 
  _mesh_id = _cs_post_mesh_id(mesh_id);
 
3493
  _mesh_id = _cs_post_mesh_id_try(mesh_id);
 
3494
 
 
3495
  if (_mesh_id < 0)
 
3496
    return;
 
3497
 
2778
3498
  post_mesh = _cs_post_meshes + _mesh_id;
2779
3499
 
2780
3500
  if (interlace == true)
2924
3644
 
2925
3645
    writer = _cs_post_writers + post_mesh->writer_id[i];
2926
3646
 
2927
 
    if (writer->active == 1)
 
3647
    if (writer->active == 1) {
 
3648
 
2928
3649
      fvm_writer_export_field(writer->writer,
2929
3650
                              post_mesh->exp_mesh,
2930
3651
                              var_name,
2938
3659
                              (double)t_cur_abs,
2939
3660
                              (const void * *)var_ptr);
2940
3661
 
 
3662
      if (nt_cur_abs >= 0) {
 
3663
        writer->n_last = nt_cur_abs;
 
3664
        writer->t_last = t_cur_abs;
 
3665
      }
 
3666
 
 
3667
    }
 
3668
 
2941
3669
  }
2942
3670
 
2943
3671
  /* Free memory (if both interior and boundary faces present) */
2977
3705
  cs_int_t  i;
2978
3706
  int       _mesh_id;
2979
3707
 
2980
 
 
2981
3708
  cs_post_mesh_t  *post_mesh;
2982
3709
  cs_post_writer_t    *writer;
2983
3710
  fvm_interlace_t      _interlace;
2993
3720
 
2994
3721
  /* Initializations */
2995
3722
 
2996
 
  _mesh_id = _cs_post_mesh_id(mesh_id);
 
3723
  _mesh_id = _cs_post_mesh_id_try(mesh_id);
 
3724
 
 
3725
  if (_mesh_id < 0)
 
3726
    return;
 
3727
 
2997
3728
  post_mesh = _cs_post_meshes + _mesh_id;
2998
3729
 
2999
3730
  if (interlace == true)
3031
3762
 
3032
3763
    writer = _cs_post_writers + post_mesh->writer_id[i];
3033
3764
 
3034
 
    if (writer->active == 1)
 
3765
    if (writer->active == 1) {
 
3766
 
3035
3767
      fvm_writer_export_field(writer->writer,
3036
3768
                              post_mesh->exp_mesh,
3037
3769
                              var_name,
3045
3777
                              (double)t_cur_abs,
3046
3778
                              (const void * *)var_ptr);
3047
3779
 
 
3780
      if (nt_cur_abs >= 0) {
 
3781
        writer->n_last = nt_cur_abs;
 
3782
        writer->t_last = t_cur_abs;
 
3783
      }
 
3784
 
 
3785
    }
 
3786
 
3048
3787
  }
3049
3788
 
3050
3789
}
3221
3960
}
3222
3961
 
3223
3962
/*----------------------------------------------------------------------------
 
3963
 * Configure the post-processing output so that a mesh displacement field
 
3964
 * may be output automatically for meshes based on the global volume mesh/
 
3965
 *----------------------------------------------------------------------------*/
 
3966
 
 
3967
void
 
3968
cs_post_set_deformable(void)
 
3969
{
 
3970
  _cs_post_deformable = true;
 
3971
}
 
3972
 
 
3973
/*----------------------------------------------------------------------------
 
3974
 * Initialize post-processing writers
 
3975
 *----------------------------------------------------------------------------*/
 
3976
 
 
3977
void
 
3978
cs_post_init_writers(void)
 
3979
{
 
3980
  /* Ensure default is defined */
 
3981
 
 
3982
  if (!cs_post_writer_exists(-1))
 
3983
    cs_post_define_writer(-1,               /* writer_id */
 
3984
                          "results",        /* writer name */
 
3985
                          _cs_post_dirname,
 
3986
                          "EnSight Gold",   /* format name */
 
3987
                          "",               /* format options */
 
3988
                          FVM_WRITER_FIXED_MESH,
 
3989
                          true,             /* output at end */
 
3990
                          -1,               /* time step output frequency */
 
3991
                          -1.0);            /* time value output frequency */
 
3992
 
 
3993
  /* Print info on writers */
 
3994
 
 
3995
  _writer_info();
 
3996
}
 
3997
 
 
3998
/*----------------------------------------------------------------------------
 
3999
 * Initialize main post-processing meshes
 
4000
 *
 
4001
 * The check_flag variable is a mask, used for additionnal post-processing:
 
4002
 *
 
4003
 *  - If (check_flag & 1), volume submeshes are output by groups if more
 
4004
 *    than one group is present and the default writer uses the EnSight format.
 
4005
 *
 
4006
 *  - If (check_flag & 2), boundary submeshes are output by groups if more
 
4007
 *    than one group is present and the default writer uses the EnSight format.
 
4008
 *
 
4009
 * Note that all alias-type post-processing meshes and the meshes they
 
4010
 * relate to should have been defined before calling this function, so it is
 
4011
 * recommended that user-defined post-processing meshes be defined before
 
4012
 * calling this function, though specific "automatic" meshes (for example
 
4013
 * those related to couplings) may be defined between this call and a
 
4014
 * time loop.
 
4015
 *
 
4016
 * parameters:
 
4017
 *   check_flag <-- mask used for additional output
 
4018
 *----------------------------------------------------------------------------*/
 
4019
 
 
4020
void
 
4021
cs_post_init_meshes(int check_mask)
 
4022
{
 
4023
  int i;
 
4024
  const int writer_ids[] = {-1}; /* Default (main) writer id */
 
4025
 
 
4026
  /* Definition of default post-processing meshes if this has not been
 
4027
     done yet */
 
4028
 
 
4029
  if (!cs_post_mesh_exists(-1))
 
4030
    cs_post_define_volume_mesh(-1,
 
4031
                               _("Fluid domain"),
 
4032
                               "all[]",
 
4033
                               true,
 
4034
                               true,
 
4035
                               1,
 
4036
                               writer_ids);
 
4037
 
 
4038
  if (!cs_post_mesh_exists(-2))
 
4039
    cs_post_define_surface_mesh(-2,
 
4040
                                _("Boundary"),
 
4041
                                NULL,
 
4042
                                "all[]",
 
4043
                                true,
 
4044
                                true,
 
4045
                                1,
 
4046
                                writer_ids);
 
4047
 
 
4048
  /* Remove meshes which are associated with no writer and not aliased */
 
4049
 
 
4050
  _clear_unused_meshes();
 
4051
 
 
4052
  /* Now that all main meshes are defined, update aliases if present */
 
4053
 
 
4054
  _update_alias_metadata();
 
4055
 
 
4056
  /* Add group parts if necessary (EnSight format) */
 
4057
 
 
4058
  if (check_mask & 1) {
 
4059
    const char *fmt_name = fvm_writer_format_name(_cs_post_default_format_id);
 
4060
    if (!strcmp(fmt_name, "EnSight Gold")) {
 
4061
      _vol_submeshes_by_group(cs_glob_mesh,
 
4062
                              fmt_name,
 
4063
                              _cs_post_default_format_options);
 
4064
      _boundary_submeshes_by_group(cs_glob_mesh,
 
4065
                                   fmt_name,
 
4066
                                   _cs_post_default_format_options);
 
4067
    }
 
4068
  }
 
4069
 
 
4070
  /* Compute connectivity if not already done for delayed definitions */
 
4071
 
 
4072
  for (i = 0; i < _cs_post_n_meshes; i++) {
 
4073
    cs_post_mesh_t  *post_mesh = _cs_post_meshes + i;
 
4074
    if (post_mesh->exp_mesh == NULL)
 
4075
      _define_mesh_from_criteria(post_mesh);
 
4076
  }
 
4077
 
 
4078
  /* If we must compute the vertices displacement field, we need
 
4079
     to save the initial vertex coordinates */
 
4080
 
 
4081
  if (_cs_post_deformable && _cs_post_ini_vtx_coo == NULL) {
 
4082
    cs_mesh_t *mesh = cs_glob_mesh;
 
4083
    if (mesh->n_vertices > 0) {
 
4084
      BFT_MALLOC(_cs_post_ini_vtx_coo,
 
4085
                 mesh->n_vertices * 3,
 
4086
                 cs_real_t);
 
4087
      memcpy(_cs_post_ini_vtx_coo,
 
4088
             mesh->vtx_coord,
 
4089
             mesh->n_vertices * 3 * sizeof(cs_real_t));
 
4090
    }
 
4091
  }
 
4092
 
 
4093
  /* Initial output */
 
4094
 
 
4095
  for (i = 0; i < _cs_post_n_meshes; i++) {
 
4096
    cs_post_mesh_t  *post_mesh = _cs_post_meshes + i;
 
4097
    _cs_post_write_mesh(post_mesh, -1, 0.0);
 
4098
  }
 
4099
}
 
4100
 
 
4101
/*----------------------------------------------------------------------------
3224
4102
 * Destroy all structures associated with post-processing
3225
4103
 *----------------------------------------------------------------------------*/
3226
4104
 
3227
4105
void
3228
4106
cs_post_finalize(void)
3229
4107
{
3230
 
  int i;
 
4108
  int i, j;
3231
4109
  cs_post_mesh_t  *post_mesh = NULL;
3232
4110
 
3233
4111
  /* Timings */
3234
4112
 
3235
4113
  for (i = 0; i < _cs_post_n_writers; i++) {
3236
4114
    double m_wtime = 0.0, m_cpu_time = 0.0, c_wtime = 0.0, c_cpu_time = 0.;
3237
 
    fvm_writer_get_times((_cs_post_writers + i)->writer,
3238
 
                         &m_wtime, &m_cpu_time, &c_wtime, &c_cpu_time);
3239
 
    bft_printf(_("\n"
3240
 
                 "Writing of \"%s\" (%s) summary:\n"
3241
 
                 "\n"
3242
 
                 "  CPU time for meshes:              %12.3f\n"
3243
 
                 "  CPU time for variables:           %12.3f\n"
3244
 
                 "\n"
 
4115
    fvm_writer_t *writer = (_cs_post_writers + i)->writer;
 
4116
    if (writer != NULL) {
 
4117
      fvm_writer_get_times(writer,
 
4118
                           &m_wtime, &m_cpu_time, &c_wtime, &c_cpu_time);
 
4119
      bft_printf(_("\n"
 
4120
                   "Writing of \"%s\" (%s) summary:\n"
 
4121
                   "\n"
 
4122
                   "  CPU time for meshes:              %12.3f\n"
 
4123
                   "  CPU time for variables:           %12.3f\n"
 
4124
                   "\n"
3245
4125
                 "  Elapsed time for meshes:          %12.3f\n"
3246
 
                 "  Elapsed time for variables:       %12.3f\n"),
3247
 
               fvm_writer_get_name((_cs_post_writers + i)->writer),
3248
 
               fvm_writer_get_format((_cs_post_writers + i)->writer),
3249
 
               m_cpu_time, c_cpu_time, m_wtime, c_wtime);
 
4126
                   "  Elapsed time for variables:       %12.3f\n"),
 
4127
                 fvm_writer_get_name(writer),
 
4128
                 fvm_writer_get_format(writer),
 
4129
                 m_cpu_time, c_cpu_time, m_wtime, c_wtime);
 
4130
    }
3250
4131
  }
3251
4132
 
3252
4133
  /* Initial coordinates (if mesh is deformable) */
3260
4141
    post_mesh = _cs_post_meshes + i;
3261
4142
    if (post_mesh->_exp_mesh != NULL)
3262
4143
      fvm_nodal_destroy(post_mesh->_exp_mesh);
 
4144
    BFT_FREE(post_mesh->name);
 
4145
    for (j = 0; j < 3; j++)
 
4146
      BFT_FREE(post_mesh->criteria[j]);
3263
4147
    BFT_FREE(post_mesh->writer_id);
3264
4148
  }
3265
4149
 
3271
4155
 
3272
4156
  /* Writers */
3273
4157
 
3274
 
  for (i = 0; i < _cs_post_n_writers; i++)
3275
 
    fvm_writer_finalize((_cs_post_writers + i)->writer);
 
4158
  for (i = 0; i < _cs_post_n_writers; i++) {
 
4159
    cs_post_writer_t  *writer = _cs_post_writers + i;
 
4160
    if (writer->wd != NULL)
 
4161
      _destroy_writer_def(writer);
 
4162
    if (writer->writer != NULL)
 
4163
      fvm_writer_finalize((_cs_post_writers + i)->writer);
 
4164
  }
3276
4165
 
3277
4166
  BFT_FREE(_cs_post_writers);
3278
4167
 
3285
4174
    BFT_FREE(_cs_post_f_var_tp);
3286
4175
    BFT_FREE(_cs_post_i_var_tp);
3287
4176
  }
 
4177
 
 
4178
  /* Options */
 
4179
 
 
4180
  BFT_FREE(_cs_post_default_format_options);
3288
4181
}
3289
4182
 
3290
4183
/*----------------------------------------------------------------------------
3291
 
 * Initialize main post-processing writer
 
4184
 * Postprocess free (isolated) faces of the current global mesh
3292
4185
 *----------------------------------------------------------------------------*/
3293
4186
 
3294
4187
void
3295
 
cs_post_init_main_writer(void)
 
4188
cs_post_add_free_faces(void)
3296
4189
{
3297
 
  /* Default values */
3298
 
 
3299
 
  cs_int_t  indic_vol = -1, indic_brd = -1, indic_syr = -1, indic_ze = -1;
3300
 
  cs_int_t  indic_mod = -1;
3301
 
  char  fmtchr[32 + 1] = "";
3302
 
  char  optchr[96 + 1] = "";
3303
 
  cs_int_t  ntchr = -1;
3304
 
 
3305
 
  const char  nomcas[] = "chr";
3306
 
  const char  nomrep_ens[] = "chr.ensight";
3307
 
  const char  nomrep_def[] = ".";
3308
 
  const char *nomrep = NULL;
3309
 
 
3310
 
  const cs_int_t  writer_id = -1; /* Default (main) writer id */
3311
 
 
3312
 
  /* Get parameters from Fortran COMMON blocks */
3313
 
 
3314
 
  CS_PROCF(inipst, INIPST)(&indic_vol,
3315
 
                           &indic_brd,
3316
 
                           &indic_syr,
3317
 
                           &indic_ze,
3318
 
                           &indic_mod,
3319
 
                           &ntchr,
3320
 
                           fmtchr,
3321
 
                           optchr);
3322
 
 
3323
 
  fmtchr[32] = '\0';
3324
 
  optchr[96] = '\0';
3325
 
 
3326
 
  if (indic_vol == 0 && indic_brd == 0 && indic_syr == 0)
 
4190
  fvm_lnum_t i, j;
 
4191
  fvm_lnum_t n_f_faces = 0;
 
4192
  fvm_gnum_t n_no_group = 0;
 
4193
  int max_null_family = 0;
 
4194
  fvm_lnum_t *f_face_list = NULL;
 
4195
 
 
4196
  fvm_writer_t *writer = NULL;
 
4197
  fvm_nodal_t *exp_mesh = NULL;
 
4198
 
 
4199
  cs_bool_t  generate_submeshes = false;
 
4200
  cs_mesh_t *mesh = cs_glob_mesh;
 
4201
  const char *fmt_name = fvm_writer_format_name(_cs_post_default_format_id);
 
4202
 
 
4203
  if (mesh->n_g_free_faces == 0)
3327
4204
    return;
3328
4205
 
3329
4206
  /* Create default writer */
3330
4207
 
3331
 
  if (fmtchr[0] == 'e' || fmtchr[0] == 'E')
3332
 
    nomrep = nomrep_ens;
3333
 
  else
3334
 
    nomrep = nomrep_def;
3335
 
 
3336
 
  cs_post_add_writer(writer_id,
3337
 
                     nomcas,
3338
 
                     nomrep,
3339
 
                     fmtchr,
3340
 
                     optchr,
3341
 
                     indic_mod,
3342
 
                     ntchr);
3343
 
 
3344
 
}
3345
 
 
3346
 
/*----------------------------------------------------------------------------
3347
 
 * Initialize main post-processing meshes
3348
 
 *----------------------------------------------------------------------------*/
3349
 
 
3350
 
void
3351
 
cs_post_init_main_meshes(void)
3352
 
{
3353
 
  /* Default values */
3354
 
 
3355
 
  cs_int_t  indic_vol = -1, indic_brd = -1, indic_syr = -1, indic_ze = -1;
3356
 
  cs_int_t  indic_mod = -1;
3357
 
  char  fmtchr[32 + 1] = "";
3358
 
  char  optchr[96 + 1] = "";
3359
 
  cs_int_t  ntchr = -1;
3360
 
 
3361
 
  cs_int_t  mesh_id = -1;
3362
 
 
3363
 
  const cs_int_t  writer_id = -1; /* Default (main) writer id */
3364
 
 
3365
 
  /* Get parameters from Fortran COMMON blocks */
3366
 
 
3367
 
  CS_PROCF(inipst, INIPST)(&indic_vol,
3368
 
                           &indic_brd,
3369
 
                           &indic_syr,
3370
 
                           &indic_ze,
3371
 
                           &indic_mod,
3372
 
                           &ntchr,
3373
 
                           fmtchr,
3374
 
                           optchr);
3375
 
 
3376
 
  fmtchr[32] = '\0';
3377
 
  optchr[96] = '\0';
3378
 
 
3379
 
  /* Definition of post-processing meshes */
3380
 
 
3381
 
  if (cs_glob_mesh->n_i_faces > 0 || cs_glob_mesh->n_b_faces > 0) {
3382
 
 
3383
 
    /*
3384
 
      If the faces -> vertices connectivity is available, we
3385
 
      may rebuild the nodal connectivity for post-processing
3386
 
      (usual mechanism).
3387
 
    */
3388
 
 
3389
 
    if (indic_vol > 0) { /* Volume mesh */
3390
 
 
3391
 
      mesh_id = -1; /* Reserved mesh id */
3392
 
 
3393
 
      cs_post_add_mesh(mesh_id,
3394
 
                       _("Fluid volume"),
3395
 
                       cs_glob_mesh->n_cells,
3396
 
                       0,
3397
 
                       0,
3398
 
                       NULL,
3399
 
                       NULL,
3400
 
                       NULL);
3401
 
 
3402
 
      cs_post_associate(mesh_id, writer_id);
3403
 
 
3404
 
    }
3405
 
 
3406
 
    if (indic_brd > 0) { /* Boundary mesh */
3407
 
 
3408
 
      mesh_id = -2;  /* Reserved mesh id */
3409
 
 
3410
 
      cs_post_add_mesh(mesh_id,
3411
 
                       _("Boundary"),
3412
 
                       0,
3413
 
                       0,
3414
 
                       cs_glob_mesh->n_b_faces,
3415
 
                       NULL,
3416
 
                       NULL,
3417
 
                       NULL);
3418
 
 
3419
 
      cs_post_associate(mesh_id, writer_id);
3420
 
 
3421
 
    }
3422
 
 
3423
 
  } /* End if cs_glob_mesh->n_i_faces > 0 || cs_glob_mesh->n_b_faces > 0 */
3424
 
 
3425
 
  /*
3426
 
    If we do not have the faces -> vertices connectivity, we may not
3427
 
    rebuild the nodal connectivity, so we must obtain it through
3428
 
    another means.
3429
 
 
3430
 
    This only happens when we have directly read a mesh in the solcom
3431
 
    format, in which  the nodal connectivity has already been read and
3432
 
    assigned to a post-processing mesh
3433
 
    (see LETGEO and cs_maillage_solcom_lit).
3434
 
  */
3435
 
 
3436
 
  else if (indic_vol > 0) {
3437
 
 
3438
 
    mesh_id = -1;
3439
 
 
3440
 
    if (cs_post_mesh_exists(mesh_id))
3441
 
      cs_post_associate(mesh_id, writer_id);
3442
 
 
3443
 
  }
 
4208
  writer = fvm_writer_init("isolated_faces",
 
4209
                           _cs_post_dirname,
 
4210
                           fmt_name,
 
4211
                           _cs_post_default_format_options,
 
4212
                           FVM_WRITER_FIXED_MESH);
 
4213
 
 
4214
  /* Build list of faces to extract */
 
4215
 
 
4216
  BFT_MALLOC(f_face_list, mesh->n_b_faces, fvm_lnum_t);
 
4217
 
 
4218
  for (i = 0; i < mesh->n_b_faces; i++) {
 
4219
    if (mesh->b_face_cells[i] < 1)
 
4220
      f_face_list[n_f_faces++] = i + 1;
 
4221
  }
 
4222
 
 
4223
  /* Extract and output mesh of isolated faces */
 
4224
 
 
4225
  exp_mesh = cs_mesh_connect_faces_to_nodal(cs_glob_mesh,
 
4226
                                            "isolated faces",
 
4227
                                            true,
 
4228
                                            0,
 
4229
                                            n_f_faces,
 
4230
                                            NULL,
 
4231
                                            f_face_list);
 
4232
 
 
4233
  if (fvm_writer_needs_tesselation(writer, exp_mesh, FVM_FACE_POLY) > 0)
 
4234
    fvm_nodal_tesselate(exp_mesh, FVM_FACE_POLY, NULL);
 
4235
 
 
4236
  fvm_writer_set_mesh_time(writer, -1, 0);
 
4237
  fvm_writer_export_nodal(writer, exp_mesh);
 
4238
 
 
4239
  exp_mesh = fvm_nodal_destroy(exp_mesh);
 
4240
 
 
4241
  /* Now check if we should generate additional meshes (EnSight Gold format) */
 
4242
 
 
4243
  if (!strcmp(fmt_name, "EnSight Gold") && mesh->n_families > 0) {
 
4244
 
 
4245
    generate_submeshes = true;
 
4246
 
 
4247
    /* Families should be sorted, so if a nonzero family is empty,
 
4248
       it is family 1 */
 
4249
    if (mesh->family_item[0] == 0)
 
4250
      max_null_family = 1;
 
4251
    if (mesh->n_families <= max_null_family)
 
4252
      generate_submeshes = false;
 
4253
 
 
4254
    /* Check how many boundary faces belong to no group */
 
4255
 
 
4256
    if (mesh->b_face_family != NULL) {
 
4257
      for (j = 0; j < n_f_faces; j++) {
 
4258
        if (mesh->b_face_family[f_face_list[j] - 1] <= max_null_family)
 
4259
          n_no_group += 1;
 
4260
      }
 
4261
    }
 
4262
    else
 
4263
      n_no_group = n_f_faces;
 
4264
 
 
4265
    fvm_parall_counter(&n_no_group, 1);
 
4266
 
 
4267
    if (n_no_group == mesh->n_g_free_faces)
 
4268
      generate_submeshes = false;
 
4269
  }
 
4270
 
 
4271
  /* Generate submeshes if necessary */
 
4272
 
 
4273
  if (generate_submeshes) {
 
4274
 
 
4275
    fvm_lnum_t n_b_faces;
 
4276
    int *fam_flag = NULL;
 
4277
    char *group_flag = NULL;
 
4278
    fvm_lnum_t *b_face_list = NULL;
 
4279
    char part_name[81];
 
4280
 
 
4281
    /* Now detect which groups may be referenced */
 
4282
 
 
4283
    BFT_MALLOC(fam_flag, mesh->n_families + 1, int);
 
4284
    memset(fam_flag, 0, (mesh->n_families + 1)*sizeof(int));
 
4285
 
 
4286
    if (mesh->b_face_family != NULL) {
 
4287
      for (i = 0; i < n_f_faces; i++)
 
4288
        fam_flag[mesh->b_face_family[f_face_list[i] - 1]] = 1;
 
4289
    }
 
4290
 
 
4291
    group_flag = _build_group_flag(mesh, fam_flag);
 
4292
 
 
4293
    /* Now extract isolated faces by groups.
 
4294
       Selector structures may not have been initialized yet,
 
4295
       so we use a direct selection here. */
 
4296
 
 
4297
    BFT_REALLOC(fam_flag, mesh->n_families, int);
 
4298
 
 
4299
    BFT_MALLOC(b_face_list, mesh->n_b_faces, fvm_lnum_t);
 
4300
 
 
4301
    for (i = 0; i < mesh->n_groups; i++) {
 
4302
 
 
4303
      if (group_flag[i] != 0) {
 
4304
 
 
4305
        const char *g_name = mesh->group_lst + mesh->group_idx[i] - 1;
 
4306
 
 
4307
        _set_fam_flags(mesh, i, fam_flag);
 
4308
 
 
4309
        n_b_faces = 0;
 
4310
        if (mesh->b_face_family != NULL) {
 
4311
          for (j = 0; j < n_f_faces; j++) {
 
4312
            fvm_lnum_t face_id = f_face_list[j] - 1;
 
4313
            int fam_id = mesh->b_face_family[face_id];
 
4314
            if (fam_id > 0 && fam_flag[fam_id - 1])
 
4315
              b_face_list[n_b_faces++] = face_id + 1;
 
4316
          }
 
4317
        }
 
4318
 
 
4319
        strcpy(part_name, "isolated: ");
 
4320
        strncat(part_name, g_name, 80 - strlen(part_name));
 
4321
 
 
4322
        exp_mesh = cs_mesh_connect_faces_to_nodal(cs_glob_mesh,
 
4323
                                                  part_name,
 
4324
                                                  false,
 
4325
                                                  0,
 
4326
                                                  n_b_faces,
 
4327
                                                  NULL,
 
4328
                                                  b_face_list);
 
4329
 
 
4330
        if (fvm_writer_needs_tesselation(writer, exp_mesh, FVM_FACE_POLY) > 0)
 
4331
          fvm_nodal_tesselate(exp_mesh, FVM_FACE_POLY, NULL);
 
4332
 
 
4333
        fvm_writer_set_mesh_time(writer, -1, 0);
 
4334
        fvm_writer_export_nodal(writer, exp_mesh);
 
4335
 
 
4336
        exp_mesh = fvm_nodal_destroy(exp_mesh);
 
4337
      }
 
4338
 
 
4339
    }
 
4340
 
 
4341
    /* Output boundary faces belonging to no group */
 
4342
 
 
4343
    if (n_no_group > 0) {
 
4344
 
 
4345
      if (mesh->b_face_family != NULL) {
 
4346
        for (j = 0, n_b_faces = 0; j < n_f_faces; j++) {
 
4347
          fvm_lnum_t face_id = f_face_list[j] - 1;
 
4348
          if (mesh->b_face_family[face_id] <= max_null_family)
 
4349
            b_face_list[n_b_faces++] = face_id + 1;
 
4350
        }
 
4351
      }
 
4352
      else {
 
4353
        for (j = 0, n_b_faces = 0; j < n_f_faces; j++) {
 
4354
          fvm_lnum_t face_id = f_face_list[j] - 1;
 
4355
          b_face_list[n_b_faces++] = face_id + 1;
 
4356
        }
 
4357
      }
 
4358
 
 
4359
      exp_mesh = cs_mesh_connect_faces_to_nodal(cs_glob_mesh,
 
4360
                                                "isolated: no_group",
 
4361
                                                false,
 
4362
                                                0,
 
4363
                                                n_b_faces,
 
4364
                                                NULL,
 
4365
                                                b_face_list);
 
4366
 
 
4367
      if (fvm_writer_needs_tesselation(writer, exp_mesh, FVM_FACE_POLY) > 0)
 
4368
        fvm_nodal_tesselate(exp_mesh, FVM_FACE_POLY, NULL);
 
4369
 
 
4370
      fvm_writer_set_mesh_time(writer, -1, 0);
 
4371
      fvm_writer_export_nodal(writer, exp_mesh);
 
4372
 
 
4373
      exp_mesh = fvm_nodal_destroy(exp_mesh);
 
4374
    }
 
4375
 
 
4376
    BFT_FREE(b_face_list);
 
4377
 
 
4378
    BFT_FREE(fam_flag);
 
4379
    BFT_FREE(group_flag);
 
4380
 
 
4381
  } /* End of submeshes generation */
 
4382
 
 
4383
  /* Free memory */
 
4384
 
 
4385
  writer = fvm_writer_finalize(writer);
 
4386
 
 
4387
  BFT_FREE(f_face_list);
3444
4388
}
3445
4389
 
3446
4390
/*----------------------------------------------------------------------------
3454
4398
{
3455
4399
  /* Default values */
3456
4400
 
3457
 
  cs_int_t  indic_vol = -1, indic_brd = -1, indic_syr = -1, indic_ze = -1;
3458
 
  cs_int_t  indic_mod = -1;
3459
 
  char  fmtchr[32 + 1] = "";
3460
 
  char  optchr[96 + 1] = "";
3461
 
  cs_int_t  ntchr = -1;
3462
 
 
3463
 
  const char  nomcas[] = "error";
3464
 
  const char  nomrep_ens[] = "error.ensight";
3465
 
  const char  nomrep_def[] = ".";
3466
 
  const char *nomrep = NULL;
3467
 
 
3468
4401
  const int writer_id = -2;
3469
4402
 
3470
4403
  if (cs_post_writer_exists(writer_id))
3471
4404
    return;
3472
4405
 
3473
 
  /* Get parameters from Fortran COMMON blocks */
3474
 
 
3475
 
  CS_PROCF(inipst, INIPST)(&indic_vol,
3476
 
                           &indic_brd,
3477
 
                           &indic_syr,
3478
 
                           &indic_ze,
3479
 
                           &indic_mod,
3480
 
                           &ntchr,
3481
 
                           fmtchr,
3482
 
                           optchr);
3483
 
 
3484
 
  fmtchr[32] = '\0';
3485
 
  optchr[96] = '\0';
3486
 
 
3487
4406
  /* Create default writer */
3488
4407
 
3489
 
  if (fmtchr[0] == 'e' || fmtchr[0] == 'E')
3490
 
    nomrep = nomrep_ens;
3491
 
  else
3492
 
    nomrep = nomrep_def;
3493
 
 
3494
 
  cs_post_add_writer(writer_id,
3495
 
                     nomcas,
3496
 
                     nomrep,
3497
 
                     fmtchr,
3498
 
                     optchr,
3499
 
                     -1, /* No time dependency here */
3500
 
                     ntchr);
 
4408
  cs_post_define_writer(writer_id,
 
4409
                        "error",
 
4410
                        _cs_post_dirname,
 
4411
                        fvm_writer_format_name(_cs_post_default_format_id),
 
4412
                        _cs_post_default_format_options,
 
4413
                        FVM_WRITER_FIXED_MESH, /* No time dependency here */
 
4414
                        true,
 
4415
                        -1,
 
4416
                        -1.0);
3501
4417
}
3502
4418
 
3503
4419
/*----------------------------------------------------------------------------
3515
4431
int
3516
4432
cs_post_init_error_writer_cells(void)
3517
4433
{
 
4434
  int i;
3518
4435
  int mesh_id = 0;
3519
4436
 
3520
4437
  const cs_mesh_t *mesh = cs_glob_mesh;
3525
4442
  if (mesh->i_face_vtx_idx != NULL || mesh->b_face_vtx_idx != NULL) {
3526
4443
 
3527
4444
    const int writer_id = -2;
3528
 
    const cs_int_t n_cells = mesh->n_cells;
3529
4445
 
3530
4446
    cs_post_init_error_writer();
 
4447
    cs_post_activate_writer(writer_id, 1);
3531
4448
 
3532
4449
    mesh_id = cs_post_get_free_mesh_id();
3533
4450
 
3534
 
    cs_post_add_mesh(mesh_id,
3535
 
                     _("Calculation domain"),
3536
 
                     n_cells,
3537
 
                     0,
3538
 
                     0,
3539
 
                     NULL,
3540
 
                     NULL,
3541
 
                     NULL);
3542
 
 
3543
 
    cs_post_associate(mesh_id, writer_id);
3544
 
 
3545
 
    cs_post_activate_writer(writer_id, 1);
3546
 
 
3547
 
    cs_post_write_meshes(-1, 0.0);
 
4451
    cs_post_define_volume_mesh_by_list(mesh_id,
 
4452
                                       _("Calculation domain"),
 
4453
                                       mesh->n_cells,
 
4454
                                       NULL,
 
4455
                                       false,
 
4456
                                       false,
 
4457
                                       1,
 
4458
                                       &writer_id);
 
4459
 
 
4460
    for (i = 0; i < _cs_post_n_meshes; i++) {
 
4461
      cs_post_mesh_t *post_mesh = _cs_post_meshes + i;
 
4462
      if (post_mesh->id == mesh_id)
 
4463
        _cs_post_write_mesh(post_mesh, -1, 0.0);
 
4464
    }
3548
4465
  }
3549
4466
 
3550
4467
  return mesh_id;