/*============================================================================
 * Code_Saturne documentation page
 *============================================================================*/

/*
  This file is part of Code_Saturne, a general-purpose CFD tool.

  Copyright (C) 1998-2021 EDF S.A.

  This program is free software; you can redistribute it and/or modify it under
  the terms of the GNU General Public License as published by the Free Software
  Foundation; either version 2 of the License, or (at your option) any later
  version.

  This program is distributed in the hope that it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  details.

  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
  Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

/*-----------------------------------------------------------------------------*/

/*!
  \page cs_user_postprocess Post-processing output

  This page provides several examples that may be used or adapted
  to perform extra or advanced post-processing data extraction in
  in \ref cs_user_postprocess.c.

  The functions defined in \ref cs_user_postprocess.c, namely
  \ref cs_user_postprocess_writers, \ref cs_user_postprocess_meshes,
  \ref cs_user_postprocess_probes and
  \ref cs_user_postprocess_activate allow for the definition of post-processing
  output formats and frequency, and for the definition of surface or volume
  sections, in order to generate chronological outputs in \em EnSight, \em MED,
  or \em CGNS format, as in-situ visualization using \em Catalyst or \em Melissa.

  Point sets (probes and profiles) may also be defined, with outputs in the more
  classical comma-separated (\em csv) or white-space-separated (\em dat) text
  files, in addition to the aforementioned output types.

  - \subpage cs_user_postprocess_h_intro_p
  - \subpage cs_user_postprocess_h_writers_p
  - \subpage cs_user_postprocess_h_mesh_p
  - \subpage cs_user_postprocess_h_mesh_advanced_p
  - \subpage cs_user_postprocess_h_probes_p
  - \subpage cs_user_postprocess_h_var_p
  - \subpage cs_user_postprocess_h_interpolate_p
  - \subpage cs_user_postprocess_h_activation_p

  \page cs_user_postprocess_h_writers_p Definition of post-processing writers

  Writers may be defined in the \ref cs_user_postprocess_writers
  function.

  \section cs_user_postprocess_h_writers_mesh Mesh or sub-mesh output writers

  The following local variable definitions can shared beween several examples:

  \snippet cs_user_postprocess.c post_define_writer_freq

  In the following example, the default writer is redefined, so as to modify
  some parameters which have been set by default or by the GUI:

  \snippet cs_user_postprocess.c post_define_writer_m1

  Polygons and polyhedra may also be divided into simpler elements, as in
  the example below (only for polyhedra here), using MED format output:

  \snippet cs_user_postprocess.c post_define_writer_1

  In the next example, the defined writer discards polyhedra, and
  allows for transient mesh connectivity (i.e. meshes changing with
  time); text output is also forced:

  \snippet cs_user_postprocess.c post_define_writer_2

  \section cs_user_postprocess_h_writers_probe Probe and profile plotting writers

  \subsection cs_user_postprocess_h_writers_probe_def Defining plot and profile writers

  Default plot and probe writers, \ref CS_POST_WRITER_PROBES and
  \ref CS_POST_WRITER_PROFILES are defined by default. Redefining them
  here allows modifying some of their parameters.

  In the following example, an additional plot writer is defined. Such a writer
  may be used to output probe, profile, or other point data
  (probes may be output to 3D formats, but plot and time plot
  outputs drop cell or face-based ouptut).

  \snippet cs_user_postprocess.c post_define_writer_3

  In the next example, the default profile output writer is redefined so
  as to modify its defaults, including the output format (.dat instead
  of the default CSV).

  \snippet cs_user_postprocess-profiles.c post_writer_profile

  \subsection cs_user_postprocess_h_writers_probe_flush Forcing plot output updates

  Due to buffering, plots may not be updated at every time step, and frequency
  of that update depends both on the volume of data produced and the machine.
  Forcing updates at each time step while not required may degrade performance,
  so it is not done by default.

  Flushing parameters for time plots may be defined here. By default,
  for best performance, time plot files are kept open, and flushing is not
  forced. This behavior may be modified, as in the following example.
  The default settings should be changed before time plots are defined.

  \snippet cs_user_postprocess.c post_set_tp_flush

  \section cs_user_postprocess_h_histo Histogram output

  In this last example, a histogram writer is defined. The format can
  be changed, as well as the number of subdivisions in the format options.
  Here the format is tex (resulting tex file can be input in any tex document
  with package tikz and pgfplots), and the number of subdivisions is 10.

  \snippet cs_user_postprocess.c post_define_writer_4

  \page cs_user_postprocess_h_mesh_p Definition of post-processing and mesh zones

  \section cs_user_postprocess_h_mesh About postprocessing meshes

  Postprocessing meshes may be defined in the
  \ref cs_user_postprocess_meshes function, using one of several postprocessing
  mesh creation functions (\ref cs_post_define_volume_mesh,
  \ref cs_post_define_volume_mesh_by_func,
  \ref cs_post_define_surface_mesh, \ref cs_post_define_surface_mesh_by_func,
  \ref cs_post_define_particles_mesh,
  \ref cs_post_define_particles_mesh_by_func,
  \ref cs_post_define_existing_mesh, \ref cs_post_define_edges_mesh,
  and the probe set creation functions \ref cs_probe_set_create,
  \ref cs_probe_set_create_from_array, \ref cs_probe_set_create_from_segment,
  \ref cs_probe_set_create_from_local).

  It is possible to output variables which are normally automatically
  output on the main volume or boundary meshes to a user mesh which is a subset
  of one of these by setting the \c auto_variables argument of
  one of the \c cs_post_define_..._mesh to \c true.

  It is not possible to mix cells and faces in the same mesh (most of
  the post-processing tools being perturbed by such a case). More precisely,
  faces adjacent to selected cells and belonging to face or cell groups
  may be selected when the \c add_groups of \c cs_post_define_..._mesh
  functions is set to \c true, so as to maintain group information, but those
  faces will only be written for formats supporting this (such as MED),
  and will only bear groups, not variable fields.

  The additional variables to post-process on the defined meshes
  will be specified in the \ref cs_user_postprocess_values function.

  \warning In the parallel case, some meshes may not contain any
  local elements on a given process rank. This is not a problem at all, as
  long as the mesh is defined for all ranks (empty or not).
  It would in fact not be a good idea at all to define a post-processing
  mesh only if it contains local elements, global operations on that
  mesh would become impossible, leading to probable deadlocks or crashes.}

  \subsection cs_user_postprocess_h_mesh_reconf Example: reconfigure predefined meshes

  In the example below, the default boundary mesh output is suppressed by
  redefining it, with no writer association:

  \snippet cs_user_postprocess.c post_define_mesh_m2

  Note that the default behavior for meshes -1 and -2 is:
  \code{.C}
  int n_writers = 1;
  const int writer_ids[] = {-1});
  \endcode

  \subsection cs_user_postprocess_h_mesh_subset Example: select interior faces with y = 0.5

  In the following example, we use a geometric criteria to output only a subset of the
  main mesh, and associate the resulting mesh with user-defined writers 1 and 4:

  \snippet cs_user_postprocess.c post_define_mesh_1

  \section cs_user_postprocess_h_mesh_atach Associating with writers

  By default, meshes are associated with writers at the time of their
  definition, either explicitly for regular postprocessing meshes,
  or implicitely for probes and profiles. To prepare for future unification
  of those approaches, a previously defined mesh may be associated with a
  given writer. This allows ataching meshes to writers without requiring
  redefinition of their other characteristics.

  \subsection cs_user_postprocess_h_mesh_a4 Example: attach mesh to a histogram writer

  Post-processing meshes can be associated to writers.

  In the following example, the default boundary mesh is associated to the default
  histogram writer. The format of this writer is txt (text files) and it writes
  only at the end of the calculation.

  \snippet cs_user_postprocess.c post_attach_mesh_1

  In the following example, the default volume mesh is now associated to a user
  defined writer of Id 6.

  \snippet cs_user_postprocess.c post_attach_mesh_2

  \page cs_user_postprocess_h_mesh_advanced_p Advanced definitions of post-processing and mesh zones

  \section cs_user_postprocess_h_mesh_function Output meshes defined by user-defined functions

  More advanced mesh element selection is possible using
  \ref cs_post_define_volume_mesh_by_func or
  \ref cs_post_define_surface_mesh_by_func, which allow defining
  volume or surface meshes using user-defined element lists.

  The possibility to modify a mesh over time is limited by the most restrictive
  writer which is associated with. For instance, if writer 1 allows the
  modification of the mesh topology (argument \c time_dep
  = \ref FVM_WRITER_TRANSIENT_CONNECT in the call to \ref cs_post_define_writer)
  and writer 2 allows no modification (\c time_dep = \ref FVM_WRITER_FIXED_MESH),
  a user post-processing mesh associated with writers 1 and 2 will not be
  modifiable, but a mesh associated with writer 1 only will be modifiable. The
  modification can be done by using the advanced
  \ref cs_post_define_volume_mesh_by_func or
  \ref cs_post_define_surface_mesh_by_func, associated with a user-defined
  selection function based on time-varying criteria (such as field values
  being above a given threshold). If the \c time_dep argument is set to
  \c true, the mesh will be redefined using the selection function at
  each output time step for every modifiable mesh.

  \subsection cs_user_postprocess_h_mesh_a1 Example: surface mesh with complex selection criteria

  In the following example, we build a surface mesh containing interior faces
  separating cells of group "2" from those of group "3", (assuming no cell has
  both colors), as well as boundary faces of group "4".

  This is done by first defining 2 selection functions, whose arguments
  and behavior match the \ref cs_post_elt_select_t type.

  The function for selection of interior faces separating cells of two groups
  also illustrates the usage of the \ref cs_selector_get_family_list function
  to build a mask allowing direct checking of this criterion when comparing
  cells adjacent to a given face:

  \snippet cs_user_postprocess.c post_select_func_1

  The function for selection of boundary faces is simpler, as it simply
  needs to apply the selection criterion for boundary faces:

  \snippet cs_user_postprocess.c post_select_func_2

  Given these two functions, the mesh can be defined using the
  \ref cs_post_define_surface_mesh_by_func function, passing it the
  user-defined selection functions (actually, function pointers):

  \snippet cs_user_postprocess.c post_define_mesh_3

  \subsection cs_user_postprocess_h_mesh_a2 Example: time-varying mesh

  A mesh defined through the advanced \ref cs_post_define_surface_mesh_by_func,
  \ref cs_post_define_volume_mesh_by_func, or
  \ref cs_post_define_particles_mesh_by_func may vary in time, as long as
  the matching \c time_varying argument is set to \c true, and the mesh
  (or aliases thereof) id only associated to writers defined with the
  \ref FVM_WRITER_TRANSIENT_CONNECT option. In the case of particles,
  which always vary in time, this allows also varying the selection (filter)
  function with time.

  In the following example, we build a volume mesh containing cells
  with values of field named "He_fraction" greater than 0.05.

  First, we define the selection function:

  \snippet cs_user_postprocess.c post_select_func_3

  Then, we simply define matching volume mesh passing the associated
  selection function pointer:

  \snippet cs_user_postprocess.c post_define_mesh_4

  The matching function will be called at all time steps requiring
  output of this mesh.

  \warning some mesh formats do not allow changing meshes (or the
  implemented output functions do not allow them yet) and some may
  not allow empty meshes, even if this is only transient.

  \section cs_user_postprocess_h_mesh_other Other advanced mesh types

  \subsection cs_user_postprocess_h_mesh_a3 Example: edges mesh

  In cases where a mesh containing polygonal elements is output through
  a writer configured to divide polygons into triangles (for example when
  visualization tools do not support polygons, or when highly non convex
  faces lead to visualization artifacts), it may be useful to extract a
  mesh containing the edges of the original mesh so as to view the polygon
  boundaries as an overlay.

  In the following example, we build such a mesh (with id 5), based on the
  faces of a mesh with id 1:

  \snippet cs_user_postprocess.c post_define_mesh_5

  \subsection cs_user_postprocess_h_sfc Output of various space-filling curves

  In the below example, edge meshes illustrating various space-filling curves
  possibilities are output.

  First the below functions write the various space-filling curves either in
  serial or parallel.

  \snippet cs_user_postprocess-sfc.c sfc_fvm_writer_def

  Then a fake cell selection function is used to call the writing of the
  space-filling curves at the correct step.

  \snippet cs_user_postprocess-sfc.c sfc_cells_selection

  Finally edge meshes are defined to illustrate the various possibilities.

  \snippet cs_user_postprocess-sfc.c sfc_def

  \page cs_user_postprocess_h_probes_p Probes and profiles

  \section cs_user_postprocess_h_probes About Probes and profiles

  Sets of probes may also be defined through the \ref cs_user_postprocess_probes
  function, to allow for extraction and output of values at specific mesh
  locations, often with a higher time frequency than for volume or
  surface meshes.

  Probe sets, and profiles (which can be viewed as a series of probes
  lying on a user-defined curve) are handled as a point mesh, which can
  be associated with \em plot and \em time_plot 2D-plot writers, as well as
  any of the general (3D-output) writer types (the priviledged writer
  types being \em plot for a \em profile, and \em time_plot for other \em probes).

  Probe sets may be defined using the \ref cs_probe_set_create_from_array
  function. In some cases, it might be useful to define those in
  multiple stages, using first \ref cs_probe_set_create then a series
  of calls to \ref cs_probe_set_add_probe.

  The following example shows how probes may be added using that function.

  \snippet cs_user_postprocess.c post_define_probes_1

  The same set could also be defined using predifined arrays:

  \snippet cs_user_postprocess.c post_define_probes_2

  In both cases, labels are optional (NULL may be used instead).

  Probe set creation functions return a pointer to a \ref cs_probe_set_t
  structure which can be used to specify additional options using the
  \ref cs_probe_set_option function.

  A writer (id = CS_POST_WRITER_PROBES) using the format "time_plot" is
  associated by default to a set of monitoring probes.
  This is not the case for profiles.

  Profiles are special probe sets, for which a curvilinear coordinate is
  usually provided (or deduced, when \ref cs_probe_set_create_from_segment
  or \ref cs_probe_set_create_from_local construction function is used).
  Curvilinear coordinates may also be assigned to probe sets generated
  using \ref cs_probe_set_create or \ref cs_probe_set_create_from_array
  by using the \ref cs_probe_set_assign_curvilinear_abscissa function.

  Instead of being assigned by default to a time plot, profiles are generally
  used with writers using the "plot" format (with a "dat" or "csv" sub-option).
  Instead of using one file per variable with one column per point and
  one line per output time, this produces one file pour output time, with
  une column per variable and one line per point. But they may also be used
  with time plots (as a regular probe set), or as with any post-processing
  output mesh, with 3D formats such as EnSight or MED.

  The following example shows how to simply define a profile on a given
  segment, and associate it to writer 2:

  \snippet cs_user_postprocess.c post_define_profile_1

  Probe sets (including profiles) may also be located along the domain
  boundary, if this is specified. In the following example, we set the
  "boundary" option to "true" to specify that the probes should be located
  on the boundary instead of the default volume mesh. We could also set
  a "criteria" option to define a selection filter for the portion of the mesh
  in which probes should be located (by default, the whole mesh).

  Here We also choose to "snap" the points to the nearest vertices. Snapping
  probes to cell centers or vertices is useful mainly when the values to
  plot are located on those points.

  \snippet cs_user_postprocess.c post_define_profile_2

  \section cs_user_postprocess_h_profile_vars Defining output on a probe set

  To select a specific set of fields to output with a given probe set
  or profile, the \ref cs_probe_set_associate_field function may be used.
  It allows specifying whether the output relates to all associated writers
  or specific ones, and for multidimensional fields, allows selecting specific
  components (\c comp_id = -1 for all components, or the (0 to n-1)-th
  component if filtering is desired.

  This is used in general for probe sets whose "automatic" variables
  output is turned off (using \ref cs_probe_set_auto_var), though it can be used
  to extend that glob setting.

  Finally, the user may choose to output the curvilinear coordinates
  associated with a profile and/or the point coordinates, using the
  \ref cs_probe_set_auto_curvilinear_coords and
  \ref cs_probe_set_auto_cartesian_coords respectively, since these are
  not output by default.

  This last example illustrates a combination of those possibilities:

  \snippet cs_user_postprocess.c post_define_profile_2

  \section cs_user_postprocess_h_profile_advanced Advanced profile definitions

  As with regular meshes, profiles may be defined using user functions.

  \subsection cs_user_postprocess_h_profile_a1 Definition of a series of profiles

  In this example, we define a series of profiles. To avoid redundant code,
  an array defining both the name of each profile and the matching
  x coordinate (as a text string) is defined. The code then loops
  along these array values to define the series:

  \snippet cs_user_postprocess-profiles.c post_profile_advanced_1

  As we observe here, the \ref cs_probe_set_create_from_local requires
  a process-local definition, calling a user-defined function. This
  requires that the line_defs array be defined as static, so as to be available
  when this function is called. For this example, the function is defined
  as follows (before the calling function, preferably in the file's
  local function definitions section).

  \snippet cs_user_postprocess-profiles.c post_profile_advanced_df_1

  \subsection cs_user_postprocess_h_profile_a2 Boundary profiles

  Probes and profiles may also be associated to the mesh boundary.

  In the following example, a profile is defined based on a mesh boundary
  selection criterion, using the predefined
  \ref cs_b_face_criterion_probes_define (which assumes curvilinear coordinates
  based on the "x" direction):

  \snippet cs_user_postprocess-boundary_pressure_profile.c post_profile_def

  and in the below example using an array of 2 selection criteria:

  \snippet cs_user_postprocess-profiles.c post_profile_advanced_2

  \page cs_user_postprocess_h_var_p Definition of the variables to post-process

  \section cs_user_postprocess_h_var Additional post-processing variables

  For the mesh parts defined using the GUI or in \ref cs_user_postprocess.c,
  the \ref cs_user_postprocess_values function  of the \ref cs_user_postprocess.c
  file may be used to specify the variables to post-process (called for each
  postprocess output mesh, at every active time step of an associated \em writer).

  The output of a given variable is generated by means of a call to the
  \ref cs_post_write_var for cell or face values, \ref cs_post_write_vertex_var
  for vertex values, \ref cs_post_write_particle_values for particle or trajectory
  values, and \ref cs_post_write_probe_values for probe or profile values.

  The examples of post-processing given below use meshes defined in the
  examples for \ref cs_user_postprocess_meshes above.

  \subsection cs_user_postprocess_h_var_add_f_1 Output a given field or component with a given mesh

  To output specific field values on a given postprocessing mesh, that
  field may be attached (associated) to that mesh.

  In the following example, the pressure is output on mesh *4*, for
  all associated writers:

  \snippet cs_user_postprocess.c post_attach_field_1

  In this second example, the velocity's z component is ouput on mesh 4,
  only for writer 1:

  \snippet cs_user_postprocess.c post_attach_field_2

  If the mesh has the \c auto_variables option enabled, and a field is already
  selected for "standard" postprocessing (i.e. selected for output in the GUI,
  or \c post_vis key value includes the \c CS_POST_ON_LOCATION bit), it will
  not be output an additional time, so this option should be safely usable even
  with limited precautions.

  \subsection cs_user_postprocess_h_volume_mesh_tke Output of the turbulent kinetic energy for the Rij-Epsilon model on the volume mesh

  One can define, compute and post-process the turbulent kinetic energy for the Rij-Epsilon
  as shown in the following example:

  \snippet cs_user_postprocess.c postprocess_values_ex_1

  \subsection cs_user_postprocess_h_value_boundary_p Output of a variable on a surface mesh

  Values can also be output on a surface mesh, possibly containing a mix of
  boundary and internal faces.
  In the following example, we simply average or project adjacent cell values
  on faces, but more precise techniques could be used:

  \snippet cs_user_postprocess.c postprocess_values_ex_2

  \subsection cs_user_postprocess_h_value_volume_simple Simple output of an existing field or array

  For fields or arrays already defined on the full mesh, the "use_parent"
  option of \ref cs_post_write_var may be used to simply reference
  the values on the parent (i.e. full) mesh when requesting an output.
  Note that the example below can also be used with probes or profiles:

  \snippet cs_user_postprocess.c postprocess_values_ex_3

  \subsection cs_user_postprocess_h_value_single_t Single output of time-independent values

  Finally, a minor modification f the above example shows how it is
  possible to output time-independent values to a writer also
  used for time-dependent fields without requiring multiple outputs
  of those values:

  \snippet cs_user_postprocess.c postprocess_values_ex_4

  \section cs_user_postprocess_h_var_profile Additional profile variables

  The following examples match the advanced profile definitions given
  in \ref cs_user_postprocess_h_profile_advanced.

  The first section is common to both profile series:

  \snippet cs_user_postprocess-profiles.c post_profile_advanced_var_0

  For the profiles along fixed x, the following code is used. Note that
  this code's complexity is mainly due to extracting Reynolds stresses
  for different turbulence models and options. Specific values
  are then computed for each colum, in the switch statement:

  \snippet cs_user_postprocess-profiles.c post_profile_advanced_var_1

  For the profile defined all around a foil, the following code is used to
  compute the pressure coefficient and output its values:

  \snippet cs_user_postprocess-boundary_pressure_profile.c variables_def

  \snippet cs_user_postprocess-boundary_pressure_profile.c profile_variables

  For the last profiles series, values for each column are also computed,
  requiring a reference pressure based on the mesh point closest to
  a given point, and computation of tangential stresses, so as to
  determine drag coefficients.

  \snippet cs_user_postprocess-profiles.c post_profile_advanced_var_2

  \page cs_user_postprocess_h_interpolate_p Interpolation

  \section cs_user_postprocess_h_probe_interpolate Probe set interpolation

  By default, probes and profile values are "P0" interpolated,
  that is their value is that of the containing cell or face,
  or closest vertex.

  For cell-based values, a "P1" piecewise linear interpolation may be used.

  The P1 interpolation is based on a local least-squares gradient,
  so ghost cell values must be synchronized  (this is automatically
  the case for fields, but must be handled by the user in case of
  auxiliary arrays).

  If a field's boundary values (i.e. associated field) are known,
  they are used in the interpolation. Otherwise, if boundary conditions
  are defined, they are used. When neither boundary values nor boundary
  conditions are known (i.e. for a non-solved variable field or
  values not defined as a field), homogeneous Neumann boundary conditions
  are assumed. Improved gradient interpolation for stratification and
  "jumps" is also ignored here, so this may lead to excessively smooth
  output in areas where this should occur.

  Interpolation may be activated in a global manner for all outputs
  using a given probe set as by setting the set's "interpolate", option to 1,
  as shown on the following example. The "probes" set configured here
  is the default probe set defined using the GUI:

  \snippet cs_user_postprocess.c post_set_probes_interpolate

  If a finer control is needed, such as applying a different interpolation
  option to selected fields, or providing a more precice (but usually
  more costly interpolation, interpolation may also be defined on a case per
  case basis using the \ref cs_user_postprocess_values function.

  The following example shows how this may be done, using the built-in
  \ref cs_interpolate_from_location_p1 function (which is based on the
  "P1" interpolation described above) by passing its pointer to the
  to \ref cs_post_write_probe_values outout function.

  \snippet cs_user_postprocess-probes-interpolate.c post_probes_interpolate_var_1

  In this case, selected outputs are named by appending "_p" to the
  field name to allow combining default probe outputs with
  interpolated outputs of specific fields.

  For simplicity here, values are output to the main probe set and writer,
  which is assumed to be defined using the GUI in this example.

  Note also that interpolation could be also used in
  some \ref cs_user_extra_operations cases.

  If needed, users may also define their own interpolation functions,
  whose arguments should match \ref cs_interpolate_from_location_t and pass the
  appropriate pointer to \ref cs_post_write_probe_values.

  \page cs_user_postprocess_h_activation_p Advanced management of output times

  By default, a post-processing frequency is defined for each writer,
  as defined using the GUI or through the \ref cs_user_postprocess_writers
  function. For each writer, the user may define if an output is
  automatically generated at the end of the calculation, even if the
  last time step is not a multiple of the required time step number
  of physical time.

  For finer control, the \ref cs_user_postprocess_activate function
  file may be used to specify when post-processing outputs will be
  generated, overriding the default behavior.

  In the following example, all output is deactivated until time step 1000
  is reached, at which time the normal behavior resumes:

  \snippet cs_user_postprocess.c post_activate
*/
