1 /*============================================================================
2 * Define postprocessing output.
3 *============================================================================*/
4
5 /* VERS */
6
7 /*
8 This file is part of Code_Saturne, a general-purpose CFD tool.
9
10 Copyright (C) 1998-2021 EDF S.A.
11
12 This program is free software; you can redistribute it and/or modify it under
13 the terms of the GNU General Public License as published by the Free Software
14 Foundation; either version 2 of the License, or (at your option) any later
15 version.
16
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
20 details.
21
22 You should have received a copy of the GNU General Public License along with
23 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
24 Street, Fifth Floor, Boston, MA 02110-1301, USA.
25 */
26
27 /*----------------------------------------------------------------------------*/
28
29 #include "cs_defs.h"
30
31 /*----------------------------------------------------------------------------
32 * Standard C library headers
33 *----------------------------------------------------------------------------*/
34
35 #include "stdlib.h"
36 #include "string.h"
37
38 /*----------------------------------------------------------------------------
39 * Local headers
40 *----------------------------------------------------------------------------*/
41
42 #include "cs_headers.h"
43
44 /*----------------------------------------------------------------------------*/
45
46 BEGIN_C_DECLS
47
48 /*============================================================================
49 * Local (user defined) function definitions
50 *============================================================================*/
51
52 /*----------------------------------------------------------------------------
53 * Example function for advanced selection of interior faces.
54 *
55 * Selects interior faces separating cells of group "2" from those
56 * of group "3", (assuming no cell has both colors).
57 *
58 * parameters:
59 * input <-> pointer to input (unused here)
60 * n_faces --> number of selected faces
61 * face_ids --> array of selected face ids (0 to n-1 numbering)
62 *----------------------------------------------------------------------------*/
63
64 /*! [post_select_func_1] */
65 static void
_i_faces_select_example(void * input,cs_lnum_t * n_faces,cs_lnum_t ** face_ids)66 _i_faces_select_example(void *input,
67 cs_lnum_t *n_faces,
68 cs_lnum_t **face_ids)
69 {
70 CS_UNUSED(input);
71
72 cs_lnum_t i, face_id;
73 int n_families = 0;
74 int *family_list = NULL;
75 int *family_mask = NULL;
76
77 cs_lnum_t n_i_faces = 0;
78 cs_lnum_t *i_face_ids = NULL;
79
80 const cs_mesh_t *m = cs_glob_mesh;
81
82 /* Allocate selection list */
83
84 BFT_MALLOC(i_face_ids, m->n_i_faces, cs_lnum_t);
85
86 /* Build mask on families matching groups "2" (1), "3" (2) */
87
88 BFT_MALLOC(family_list, m->n_families, int);
89 BFT_MALLOC(family_mask, m->n_families, int);
90
91 for (i = 0; i < m->n_families; i++)
92 family_mask[i] = 0;
93
94 cs_selector_get_family_list("2", &n_families, family_list);
95
96 for (i = 0; i < n_families; i++)
97 family_mask[family_list[i] - 1] += 1;
98
99 cs_selector_get_family_list("3", &n_families, family_list);
100
101 for (i = 0; i < n_families; i++)
102 family_mask[family_list[i] - 1] += 2;
103
104 BFT_FREE(family_list);
105
106 /* Now that mask is built, test for adjacency */
107
108 for (face_id = 0; face_id < m->n_i_faces; face_id++) {
109
110 /* Adjacent cells and flags */
111
112 cs_lnum_t c1 = m->i_face_cells[face_id][0];
113 cs_lnum_t c2 = m->i_face_cells[face_id][1];
114
115 int iflag1 = family_mask[m->cell_family[c1]];
116 int iflag2 = family_mask[m->cell_family[c2]];
117
118 /* Should the face belong to the extracted mesh ? */
119
120 if ((iflag1 == 1 && iflag2 == 2) || (iflag1 == 2 && iflag2 == 1)) {
121 i_face_ids[n_i_faces] = face_id;
122 n_i_faces += 1;
123 }
124
125 }
126
127 /* Free memory */
128
129 BFT_FREE(family_mask);
130 BFT_REALLOC(i_face_ids, n_i_faces, cs_lnum_t);
131
132 /* Set return values */
133
134 *n_faces = n_i_faces;
135 *face_ids = i_face_ids;
136 }
137 /*! [post_select_func_1] */
138
139 /*----------------------------------------------------------------------------
140 * Example function for selection of boundary faces.
141 *
142 * selects boundary faces of group "4".
143 *
144 * parameters:
145 * input <-> pointer to input (unused here)
146 * n_faces --> number of selected faces
147 * face_ids --> array of selected face ids (0 to n-1 numbering)
148 *----------------------------------------------------------------------------*/
149
150 /*! [post_select_func_2] */
151 static void
_b_faces_select_example(void * input,cs_lnum_t * n_faces,cs_lnum_t ** face_ids)152 _b_faces_select_example(void *input,
153 cs_lnum_t *n_faces,
154 cs_lnum_t **face_ids)
155 {
156 CS_UNUSED(input);
157
158 cs_lnum_t n_b_faces = 0;
159 cs_lnum_t *b_face_ids = NULL;
160
161 const cs_mesh_t *m = cs_glob_mesh;
162
163 /* Allocate selection list */
164
165 BFT_MALLOC(b_face_ids, m->n_b_faces, cs_lnum_t);
166
167 /* Use simple selection function */
168
169 cs_selector_get_b_face_list("4", &n_b_faces, b_face_ids);
170
171 /* Adjust array to final size (cleaner, but not required) */
172
173 BFT_REALLOC(b_face_ids, n_b_faces, cs_lnum_t);
174
175 /* Set return values */
176
177 *n_faces = n_b_faces;
178 *face_ids = b_face_ids;
179 }
180 /*! [post_select_func_2] */
181
182 /*----------------------------------------------------------------------------
183 * Example function for selection of cells with scalar field values above
184 * a certain threshold.
185 *
186 * In this example, the selection is base on the value of a scalar field
187 * named "he_fraction" being above above 0.05.
188 *
189 * parameters:
190 * input <-> pointer to input (unused here)
191 * n_cells --> number of selected cells
192 * cell_ids --> array of selected cell ids (0 to n-1 numbering)
193 *----------------------------------------------------------------------------*/
194
195 /*! [post_select_func_3] */
196 static void
_he_fraction_05_select(void * input,cs_lnum_t * n_cells,cs_lnum_t ** cell_ids)197 _he_fraction_05_select(void *input,
198 cs_lnum_t *n_cells,
199 cs_lnum_t **cell_ids)
200 {
201 CS_UNUSED(input);
202
203 cs_lnum_t _n_cells = 0;
204 cs_lnum_t *_cell_ids = NULL;
205
206 const cs_mesh_t *m = cs_glob_mesh;
207
208 cs_field_t *f = cs_field_by_name_try("He_fraction"); /* Get access to field */
209
210 if (f == NULL)
211 bft_error(__FILE__, __LINE__, 0,
212 "No field with name \"He_fraction\" defined");
213
214 /* Before time loop, field is defined, but has no values yet,
215 so ignore that case (postprocessing mesh will be initially empty) */
216
217 if (f->val != NULL) {
218
219 BFT_MALLOC(_cell_ids, m->n_cells, cs_lnum_t); /* Allocate selection list */
220
221 for (cs_lnum_t i = 0; i < m->n_cells; i++) {
222 if (f->val[i] > 5.e-2) {
223 _cell_ids[_n_cells] = i;
224 _n_cells += 1;
225 }
226 }
227
228 BFT_REALLOC(_cell_ids, _n_cells, cs_lnum_t); /* Adjust size (good practice,
229 but not required) */
230
231 }
232
233 /* Set return values */
234
235 *n_cells = _n_cells;
236 *cell_ids = _cell_ids;
237 }
238 /*! [post_select_func_3] */
239
240 /*============================================================================
241 * User function definitions
242 *============================================================================*/
243
244 /*----------------------------------------------------------------------------*/
245 /*!
246 * \brief Define post-processing writers.
247 *
248 * The default output format and frequency may be configured, and additional
249 * post-processing writers allowing outputs in different formats or with
250 * different format options and output frequency than the main writer may
251 * be defined.
252 */
253 /*----------------------------------------------------------------------------*/
254
255 void
cs_user_postprocess_writers(void)256 cs_user_postprocess_writers(void)
257 {
258 /* Set time plot file writer flush behavior defaults. */
259
260 /*! [post_set_tp_flush] */
261 cs_time_plot_set_flush_default(1800, /* flush_wtime */
262 -1); /* n_buffer_steps */
263 /*! [post_set_tp_flush] */
264
265 /* Default output format and options */
266
267 /* Redefine default writer */
268 /* ----------------------- */
269
270 /*! [post_define_writer_m1] */
271 cs_post_define_writer(CS_POST_WRITER_DEFAULT, /* writer_id */
272 "results", /* writer name */
273 "postprocessing", /* directory name */
274 "EnSight Gold", /* format_name */
275 "", /* format_options */
276 FVM_WRITER_FIXED_MESH,
277 false, /* output_at_start */
278 true, /* output_at_end */
279 -1, /* frequency_n */
280 -1.0); /* frequency_t */
281 /*! [post_define_writer_m1] */
282
283 /* Define additional writers */
284 /* ------------------------- */
285
286 /* Common parameters for all writers */
287
288 /*! [post_define_writer_freq] */
289 double frequency_n = -1.0;
290 double frequency_t = -1.0;
291 /*! [post_define_writer_freq] */
292
293 /*! [post_define_writer_1] */
294 cs_post_define_writer(1, /* writer_id */
295 "user_txt", /* writer name */
296 "postprocessing", /* directory name */
297 "MED", /* format name */
298 "divide_polyhedra",
299 FVM_WRITER_FIXED_MESH,
300 false, /* output_at_start */
301 true, /* output_at_end */
302 -1, /* frequency_n */
303 -1.0); /* frequency_t */
304 /*! [post_define_writer_1] */
305
306 /*! [post_define_writer_2] */
307 cs_post_define_writer(2, /* writer_id */
308 "modif", /* writer name */
309 "postprocessing", /* directory name */
310 "ensight", /* format name */
311 "text",
312 FVM_WRITER_TRANSIENT_CONNECT,
313 false, /* output_at_start */
314 false, /* output_at_end */
315 3,
316 frequency_t);
317 /*! [post_define_writer_2] */
318
319 /*! [post_define_writer_3] */
320 cs_post_define_writer(3, /* writer_id */
321 "profile", /* writer name */
322 "postprocessing", /* directory name */
323 "plot", /* format name */
324 "", /* format options */
325 FVM_WRITER_FIXED_MESH,
326 false, /* output_at_start */
327 false, /* output_at_end */
328 100, /* nt_freq */
329 -1.0); /* dt_freq */
330 /*! [post_define_writer_3] */
331
332 /*! [post_define_writer_4] */
333 cs_post_define_writer(6, /* writer_id */
334 "Histogram", /* writer name */
335 "histograms", /* directory name */
336 "histogram", /* format name */
337 "10 tex", /* format options */
338 FVM_WRITER_FIXED_MESH,
339 false, /* output_at_start */
340 true, /* output at end */
341 -1, /* time step frequency */
342 -1.0); /* time value frequency */
343 /*! [post_define_writer_4] */
344 }
345
346 /*----------------------------------------------------------------------------*/
347 /*!
348 * \brief Define post-processing meshes.
349 *
350 * The main post-processing meshes may be configured, and additional
351 * post-processing meshes may be defined as a subset of the main mesh's
352 * cells or faces (both interior and boundary).
353 */
354 /*----------------------------------------------------------------------------*/
355
356 void
cs_user_postprocess_meshes(void)357 cs_user_postprocess_meshes(void)
358 {
359 /* Reconfigure predefined meshes (mesh_id -1 for volume, -2 for boundary */
360
361 /* De-activate boundary mesh output by redefining it with no writer
362 association (default is:
363 int n_writers = 1;
364 const int writer_ids[] = {CS_POST_WRITER_DEFAULT});
365 */
366
367 /*! [post_define_mesh_m2] */
368 {
369 int n_writers = 0;
370 const int *writer_ids = NULL;
371
372 cs_post_define_surface_mesh(CS_POST_MESH_BOUNDARY, /* mesh_id */
373 "Boundary", /* mesh name */
374 NULL, /* interior face selection criteria */
375 "all[]", /* boundary face selection criteria */
376 true, /* add_groups */
377 true, /* automatic variables output */
378 n_writers,
379 writer_ids);
380 }
381 /*! [post_define_mesh_m2] */
382
383 /*--------------------------------------------------------------------------*/
384
385 /* Example: select interior faces with y = 0.5 */
386
387 /*! [post_define_mesh_1] */
388 {
389 const int n_writers = 2;
390 const int writer_ids[] = {1, 4}; /* Associate to writers 1 and 4 */
391
392 const char *interior_criteria = "plane[0, -1, 0, 0.5, "
393 "epsilon = 0.0001]";
394 const char *boundary_criteria = NULL;
395
396 cs_post_define_surface_mesh(1, /* mesh id */
397 "Median plane",
398 interior_criteria,
399 boundary_criteria,
400 false, /* add_groups */
401 false, /* auto_variables */
402 n_writers,
403 writer_ids);
404
405 }
406 /*! [post_define_mesh_1] */
407
408 /*--------------------------------------------------------------------------*/
409
410 /* Advanced example:
411 Build a surface mesh containing interior faces separating cells of group "2"
412 from those of group "3", (assuming no cell has both colors), as well as
413 boundary faces of group "4". */
414
415 /*! [post_define_mesh_3] */
416 {
417 const int n_writers = 1;
418 const int writer_ids[] = {1}; /* Associate to writer 1 */
419
420 /* Define postprocessing mesh */
421
422 cs_post_define_surface_mesh_by_func(3, /* mesh id */
423 "Mixed surface",
424 _i_faces_select_example,
425 _b_faces_select_example,
426 NULL, /* i_faces_sel_input */
427 NULL, /* b_faces_sel_input */
428 false, /* time varying */
429 false, /* add_groups */
430 false, /* auto_variables */
431 n_writers,
432 writer_ids);
433 }
434 /*! [post_define_mesh_3] */
435
436 /* Advanced example:
437 Build a (time varying) volume mesh containing cells
438 with values of field named "He_fraction" > 0.05 */
439
440 /*! [post_define_mesh_4] */
441 {
442 const int n_writers = 1;
443 const int writer_ids[] = {2}; /* Associate to writer 2 */
444
445 /* Define postprocessing mesh */
446
447 cs_post_define_volume_mesh_by_func(4, /* mesh id */
448 "He_fraction_05",
449 _he_fraction_05_select,
450 NULL, /* _c_05_select_input */
451 true, /* time varying */
452 false, /* add_groups */
453 false, /* auto_variables */
454 n_writers,
455 writer_ids);
456 }
457 /*! [post_define_mesh_4] */
458
459 /*--------------------------------------------------------------------------*/
460
461 /* Example: extract face edges of another mesh */
462
463 /*! [post_define_mesh_5] */
464 {
465 const int n_writers = 1;
466 const int writer_ids[] = {4}; /* Associate to writer 4 */
467
468 cs_post_define_edges_mesh(5, /* mesh_id */
469 1, /* base_mesh_id */
470 n_writers,
471 writer_ids);
472 }
473 /*! [post_define_mesh_5] */
474
475 /*--------------------------------------------------------------------------*/
476
477 /* Example: attach default txt histogram writer on boundary mesh */
478
479 /*! [post_attach_mesh_1] */
480 cs_post_mesh_attach_writer(CS_POST_MESH_BOUNDARY, CS_POST_WRITER_HISTOGRAMS);
481 /*! [post_attach_mesh_1] */
482
483 /*--------------------------------------------------------------------------*/
484
485 /* Example: attach user tex histogram writer of id 6 on volume mesh */
486
487 /*! [post_attach_mesh_2] */
488 cs_post_mesh_attach_writer(CS_POST_MESH_VOLUME, 6);
489 /*! [post_attach_mesh_2] */
490
491 /*--------------------------------------------------------------------------*/
492
493 /* Example: output specific field on mesh with all associated writers */
494
495 /*! [post_attach_field_1] */
496 cs_post_mesh_attach_field(4,
497 CS_POST_WRITER_ALL_ASSOCIATED,
498 cs_field_id_by_name("pressure"),
499 -1);
500 /*! [post_attach_field_1] */
501 /*--------------------------------------------------------------------------*/
502
503 /* Example: output z-component of velocity field on mesh with
504 a given writer */
505
506 /*! [post_attach_field_2] */
507 cs_post_mesh_attach_field(4,
508 1,
509 CS_F_(vel)->id,
510 2);
511 /*! [post_attach_field_2] */
512 }
513
514 /*----------------------------------------------------------------------------*/
515 /*!
516 * \brief Define monitoring probes and profiles.
517 *
518 * Profiles are defined as sets of probes.
519 */
520 /*----------------------------------------------------------------------------*/
521
522 void
cs_user_postprocess_probes(void)523 cs_user_postprocess_probes(void)
524 {
525 /* Define monitoring probes */
526
527 /* A writer (id = CS_POST_WRITER_PROBES) using the format "time_plot" is
528 associated by default to a set of monitoring probes.
529 This is not the case for a profile. */
530
531 /*! [post_define_probes_1] */
532 {
533 cs_probe_set_t *pset = cs_probe_set_create("Monitoring");
534
535 cs_probe_set_add_probe(pset, 0.25, 0.025, 0.025, "M1");
536 cs_probe_set_add_probe(pset, 0.50, 0.025, 0.025, "M2");
537 cs_probe_set_add_probe(pset, 0.75, 0.025, 0.025, "M3");
538 }
539 /*! [post_define_probes_1] */
540
541 /*! [post_define_probes_2] */
542 {
543 const cs_real_t coords[][3] = {{0.25, 0.025, 0.025},
544 {0.50, 0.025, 0.025},
545 {0.75, 0.025, 0.025}};
546 const char *labels[] = {"M1", "M2", "M3"};
547
548 cs_probe_set_t *pset = cs_probe_set_create_from_array("Monitoring",
549 3,
550 coords,
551 labels);
552 }
553 /*! [post_define_probes_2] */
554
555 /*! [post_set_probes_interpolate] */
556 {
557 cs_probe_set_t *pset = cs_probe_set_get("probes");
558
559 cs_probe_set_option(pset, "interpolation", "1");
560 }
561 /*! [post_set_probes_interpolate] */
562
563 /* Add a first profile */
564
565 /*! [post_define_profile_1] */
566 {
567 cs_coord_3_t start = {0., 0.025, 0.025};
568 cs_coord_3_t end = {1., 0.025, 0.025};
569 int writer_ids[] = {2};
570
571 cs_probe_set_t *pset =
572 cs_probe_set_create_from_segment("Prof1", // name
573 11, // n_probes
574 start, // start coordinates
575 end); // end coordinates
576
577 cs_probe_set_associate_writers(pset, 1, writer_ids);
578 }
579 /*! [post_define_profile_1] */
580
581 /* Add a second profile attached to boundary vertices */
582
583 /*! [post_define_profile_2] */
584 {
585 cs_coord_3_t start = {0., 0., 0.};
586 cs_coord_3_t end = {1., 0., 0.};
587
588 cs_probe_set_t *pset =
589 cs_probe_set_create_from_segment("P2", // name
590 11, // n_probes
591 start, // start coordinates
592 end); // end coordinates
593
594 int writer_ids[] = {2};
595 cs_probe_set_associate_writers(pset, 1, writer_ids);
596
597 cs_probe_set_option(pset, "boundary", "true");
598 cs_probe_set_snap_mode(pset, CS_PROBE_SNAP_VERTEX);
599 }
600 /*! [post_define_profile_2] */
601
602 /* Define output on a profile */
603
604 /*! [post_define_profile_3] */
605 {
606 cs_coord_3_t start = {0., 0.025, 0.025};
607 cs_coord_3_t end = {1., 0.025, 0.025};
608 int writer_ids[] = {2};
609
610 cs_probe_set_t *pset =
611 cs_probe_set_create_from_segment("Prof4", // name
612 11, // n_probes
613 start, // start coordinates
614 end); // end coordinates
615
616 cs_probe_set_associate_writers(pset, 1, writer_ids);
617
618 cs_probe_set_auto_curvilinear_coords(pset, true);
619 cs_probe_set_auto_var(pset, false);
620
621 cs_probe_set_associate_field(pset,
622 CS_POST_WRITER_ALL_ASSOCIATED,
623 CS_F_(p)->id,
624 -1);
625 cs_probe_set_associate_field(pset,
626 CS_POST_WRITER_ALL_ASSOCIATED,
627 CS_F_(vel)->id,
628 0);
629 }
630 /*! [post_define_profile_3] */
631 }
632
633 /*----------------------------------------------------------------------------*/
634 /*!
635 * \brief User function for output of values on a post-processing mesh.
636 *
637 * \param[in] mesh_name name of the output mesh for the current call
638 * \param[in] mesh_id id of the output mesh for the current call
639 * \param[in] cat_id category id of the output mesh for the
640 * current call
641 * \param[in] probes pointer to associated probe set structure if
642 * the mesh is a probe set, NULL otherwise
643 * \param[in] n_cells local number of cells of post_mesh
644 * \param[in] n_i_faces local number of interior faces of post_mesh
645 * \param[in] n_b_faces local number of boundary faces of post_mesh
646 * \param[in] n_vertices local number of vertices faces of post_mesh
647 * \param[in] cell_list list of cells (0 to n-1) of post-processing
648 * mesh
649 * \param[in] i_face_list list of interior faces (0 to n-1) of
650 * post-processing mesh
651 * \param[in] b_face_list list of boundary faces (0 to n-1) of
652 * post-processing mesh
653 * \param[in] vertex_list list of vertices (0 to n-1) of
654 * post-processing mesh
655 * \param[in] ts time step status structure, or NULL
656 */
657 /*----------------------------------------------------------------------------*/
658
659 void
cs_user_postprocess_values(const char * mesh_name,int mesh_id,int cat_id,cs_probe_set_t * probes,cs_lnum_t n_cells,cs_lnum_t n_i_faces,cs_lnum_t n_b_faces,cs_lnum_t n_vertices,const cs_lnum_t cell_list[],const cs_lnum_t i_face_list[],const cs_lnum_t b_face_list[],const cs_lnum_t vertex_list[],const cs_time_step_t * ts)660 cs_user_postprocess_values(const char *mesh_name,
661 int mesh_id,
662 int cat_id,
663 cs_probe_set_t *probes,
664 cs_lnum_t n_cells,
665 cs_lnum_t n_i_faces,
666 cs_lnum_t n_b_faces,
667 cs_lnum_t n_vertices,
668 const cs_lnum_t cell_list[],
669 const cs_lnum_t i_face_list[],
670 const cs_lnum_t b_face_list[],
671 const cs_lnum_t vertex_list[],
672 const cs_time_step_t *ts)
673 {
674 CS_NO_WARN_IF_UNUSED(probes);
675 CS_NO_WARN_IF_UNUSED(n_vertices);
676 CS_NO_WARN_IF_UNUSED(vertex_list);
677
678 /* Output of k = 1/2 (R11+R22+R33) for the Rij-epsilon model
679 ------------------------------------------------------ */
680
681 /*< [postprocess_values_ex_1] */
682 if (cat_id == CS_POST_MESH_VOLUME) { /* filter: only for volume
683 postprocessing mesh */
684
685 if (cs_glob_turb_model->itytur == 3) {
686
687 cs_real_t *s_cell;
688 BFT_MALLOC(s_cell, n_cells, cs_real_t);
689
690 const cs_real_6_t *cvar_r = (const cs_real_6_t *)(CS_F_(rij)->val);
691 for (cs_lnum_t i = 0; i < n_cells; i++) {
692 cs_lnum_t cell_id = cell_list[i];
693 s_cell[i] = 0.5* ( cvar_r[cell_id][0]
694 + cvar_r[cell_id][1]
695 + cvar_r[cell_id][2]);
696 }
697
698 cs_post_write_var(mesh_id,
699 CS_POST_WRITER_ALL_ASSOCIATED, /* writer id filter */
700 "Turb energy", /* var_name */
701 1, /* var_dim */
702 true, /* interlace, */
703 false, /* use_parent */
704 CS_POST_TYPE_cs_real_t, /* var_type */
705 s_cell, /* cel_vals */
706 NULL, /* i_face_vals */
707 NULL, /* b_face_vals */
708 ts);
709
710 BFT_FREE(s_cell);
711
712 }
713
714 }
715 /*< [postprocess_values_ex_1] */
716
717 /* Output pressure on surface mesh
718 ------------------------------- */
719
720 /*< [postprocess_values_ex_2] */
721 if (strcmp(mesh_name, "pressure_surface") == 0) { /* Restrict to this mesh */
722
723 cs_real_t *cvar_p = CS_F_(p)->val; /* pressure */
724
725 /* Ensure variable is synchronized in parallel or periodic cases;
726 should already have been done before, repeated for safety */
727 cs_mesh_sync_var_scal(cvar_p);
728
729 const cs_mesh_t *m = cs_glob_mesh;
730
731 cs_real_t *s_i_faces = NULL, *s_b_faces = NULL;
732
733 /* Interior faces */
734
735 if (n_i_faces > 0) {
736 BFT_MALLOC(s_i_faces, n_i_faces, cs_real_t);
737
738 for (cs_lnum_t i = 0; i < n_i_faces; i++) {
739 cs_lnum_t face_id = i_face_list[i];
740 /* Use unweighted mean of adjacent cell values here */
741 cs_lnum_t c1 = m->i_face_cells[face_id][0];
742 cs_lnum_t c2 = m->i_face_cells[face_id][1];
743 s_i_faces[i] = 0.5 * (cvar_p[c1] + cvar_p[c2]);
744 }
745 }
746
747 /* Boundary faces */
748
749 if (n_b_faces > 0) {
750 BFT_MALLOC(s_b_faces, n_b_faces, cs_real_t);
751
752 for (cs_lnum_t i = 0; i < n_b_faces; i++) {
753 cs_lnum_t face_id = b_face_list[i];
754 /* Use adjacent cell value here */
755 cs_lnum_t cell_id = m->b_face_cells[face_id];
756 s_b_faces[i] = cvar_p[cell_id];
757 }
758 }
759
760 cs_post_write_var(mesh_id,
761 CS_POST_WRITER_ALL_ASSOCIATED, /* writer id filter */
762 "Pressure", /* var_name */
763 1, /* var_dim */
764 true, /* interlace, */
765 false, /* use_parent */
766 CS_POST_TYPE_cs_real_t, /* var_type */
767 NULL, /* cel_vals */
768 s_i_faces, /* i_face_vals */
769 s_b_faces, /* b_face_vals */
770 ts);
771
772 BFT_FREE(s_i_faces);
773 BFT_FREE(s_b_faces);
774 }
775 /*< [postprocess_values_ex_2] */
776
777 /* Output cell-based scalar user field values on volume and meshes
778 ---------------------------------------------------------------- */
779
780 /*< [postprocess_values_ex_3] */
781 if ( cat_id == CS_POST_MESH_VOLUME
782 || cat_id == CS_POST_MESH_PROBES) {
783
784 const cs_field_t *f = cs_field_by_name_try("my_field");
785
786 if (f != NULL)
787 cs_post_write_var(mesh_id,
788 CS_POST_WRITER_ALL_ASSOCIATED, /* writer id filter */
789 f->name, /* var_name */
790 1, /* var_dim */
791 true, /* interlace, */
792 true, /* use_parent */
793 CS_POST_TYPE_cs_real_t, /* var_type */
794 f->val, /* cel_vals */
795 NULL, /* i_face_vals */
796 NULL, /* b_face_vals */
797 ts);
798 }
799 /*< [postprocess_values_ex_3] */
800
801 /* Output constant cell-based scalar user field values on volume mesh
802 ------------------------------------------------------------------ */
803
804 /*< [postprocess_values_ex_4] */
805 if (cat_id == CS_POST_MESH_VOLUME) {
806
807 const cs_field_t *f = cs_field_by_name_try("my_const_field");
808
809 if (f != NULL) {
810 if (ts->nt_cur == ts->nt_prev + 1) { /* before time loop */
811
812 cs_time_step_t ts0 = *ts;
813 ts0.nt_cur = 1; /* Negative time step value implies time-independent */
814
815 cs_post_write_var(mesh_id,
816 CS_POST_WRITER_ALL_ASSOCIATED, /* writer id filter */
817 f->name, /* var_name */
818 1, /* var_dim */
819 true, /* interlace, */
820 true, /* use_parent */
821 CS_POST_TYPE_cs_real_t, /* var_type */
822 f->val, /* cel_vals */
823 NULL, /* i_face_vals */
824 NULL, /* b_face_vals */
825 &ts0);
826
827 }
828 }
829
830 }
831 /*< [postprocess_values_ex_4] */
832 }
833
834 /*----------------------------------------------------------------------------*/
835 /*!
836 * Override default frequency or calculation end based output.
837 *
838 * This allows fine-grained control of activation or deactivation,
839 *
840 * \param[in] nt_max_abs maximum time step number
841 * \param[in] nt_cur_abs current time step number
842 * \param[in] t_cur_abs absolute time at the current time step
843 */
844 /*----------------------------------------------------------------------------*/
845
846 void
cs_user_postprocess_activate(int nt_max_abs,int nt_cur_abs,double t_cur_abs)847 cs_user_postprocess_activate(int nt_max_abs,
848 int nt_cur_abs,
849 double t_cur_abs)
850 {
851 CS_NO_WARN_IF_UNUSED(nt_cur_abs);
852 CS_NO_WARN_IF_UNUSED(t_cur_abs);
853
854 /* Use the cs_post_activate_writer() function to force the
855 * "active" or "inactive" flag for a specific writer or for all
856 * writers for the current time step.
857
858 * the parameters for cs_post_activate_writer() are:
859 * writer_id <-- writer id, or 0 for all writers
860 * activate <-- false to deactivate, true to activate */
861
862 /* Example: deactivate all output before time step 1000 */
863
864 /*! [post_activate] */
865 if (nt_max_abs < 1000) {
866 int writer_id = 0; /* 0: all writers */
867 cs_post_activate_writer(writer_id, false);
868 }
869 /*! [post_activate] */
870 }
871
872 /*----------------------------------------------------------------------------*/
873
874 END_C_DECLS
875