1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1999 - 2020 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_data_out_base_h
17 #define dealii_data_out_base_h
18 
19 
20 #include <deal.II/base/config.h>
21 
22 #include <deal.II/base/geometry_info.h>
23 #include <deal.II/base/mpi.h>
24 #include <deal.II/base/point.h>
25 #include <deal.II/base/table.h>
26 
27 #include <deal.II/grid/reference_cell.h>
28 
29 #include <deal.II/numerics/data_component_interpretation.h>
30 
31 // To be able to serialize XDMFEntry
32 #include <boost/serialization/map.hpp>
33 
34 #include <limits>
35 #include <string>
36 #include <tuple>
37 #include <typeinfo>
38 #include <vector>
39 
40 // Only include the Tecplot API header if the appropriate files
41 // were detected by configure
42 #ifdef DEAL_II_HAVE_TECPLOT
43 #  include <string.h>
44 
45 #  include "TECIO.h"
46 #endif
47 
48 #include <ostream>
49 
50 DEAL_II_NAMESPACE_OPEN
51 
52 // Forward declarations
53 #ifndef DOXYGEN
54 class ParameterHandler;
55 class XDMFEntry;
56 #endif
57 
58 /**
59  * This is a base class for output of data on meshes of very general form.
60  * Output data is expected as a set of <tt>patches</tt> and written to the
61  * output stream in the format expected by the visualization tool. For a list
62  * of output formats, check the enumeration #OutputFormat. For each format
63  * listed there, this class contains a function <tt>write_format</tt>, writing
64  * the output. Refer to the documentation of those functions for details on a
65  * certain format.
66  *
67  * <h3>Structure of the output data</h3>
68  *
69  * Data is not written with the deal.II mesh structure. Instead, it relies on
70  * a set of <tt>patches</tt> created by a derived class (for example the
71  * DataOut, DataOutStack, DataOutFaces, DataOutRotation, or MatrixOut
72  * classes).  Each Patch describes a single logical cell of a mesh, possibly
73  * subdivided a number of times to represent higher order polynomials defined
74  * on this cell. To this end, a patch consists of a <tt>dim</tt>-dimensional
75  * regular grid with the same number of grid points in each direction. In the
76  * simplest case it may consist of the corner points of a single mesh cell.
77  * For each point of this local grid, the Patch contains an arbitrary number
78  * of data values, though the number of data sets must be the same for each
79  * point on each patch.
80  *
81  * By offering this interface to the different output formats, it is simple to
82  * extend this class to new formats without depending on such things as actual
83  * triangulations and handling of data vectors. These things shall be provided
84  * by derived class which have a user callable interface then.
85  *
86  * Inside each patch, the data is organized in the usual lexicographical
87  * order, <i>x</i> running fastest, then <i>y</i> and <i>z</i>. Nodes are
88  * stored in this order and cells as well. Each cell in 3D is stored such that
89  * the front face is in the <i>xz</i>-plane. In order to enhance
90  * intelligibility of this concept, the following two sections are kept from a
91  * previous version of this documentation.
92  *
93  *
94  * <h4>Patches</h4>
95  *
96  * Grids can be thought of as a collection of cells; if you want to write out
97  * data on such a grid, you can do so by writing them one cell at a time. The
98  * functions in this class therefore take a list of objects describing the
99  * data on one cell each. This data for each cell usually consists of a list
100  * of vertices for this cell, and a list of data values (for example solution
101  * data, error information, etc) at each of these vertices.
102  *
103  * In some cases, this interface to a cell is too restricted, however. For
104  * example, you may have higher order elements and printing the values at the
105  * vertices only is not enough. For this reason, we not only provide writing
106  * the data on the vertices only, but the data is organizes as a tensor
107  * product grid on each cell. The parameter <tt>n_subdivisions</tt>, which is
108  * given for each patch separately, denotes how often the cell is to be
109  * divided for output; for example, <tt>n_subdivisions==1</tt> yields no
110  * subdivision of the cell, <tt>n_subdivisions==2</tt> will produce a grid of
111  * 3 times 3 points in two spatial dimensions and 3 times 3 times 3 points in
112  * three dimensions, <tt>n_subdivisions==3</tt> will yield 4 times 4 (times 4)
113  * points, etc. The actual location of these points on the patch will be
114  * computed by a multilinear transformation from the vertices given for this
115  * patch.  For cells at the boundary, a mapping might be used to calculate the
116  * position of the inner points. In that case the coordinates are stored
117  * inside the Patch, as they cannot be easily recovered otherwise.
118  *
119  * Given these comments, the actual data to be printed on this patch of points
120  * consists of several data sets each of which has a value at each of the
121  * patch points. For example with <tt>n_subdivisions==2</tt> in two space
122  * dimensions, each data set has to provide nine values, and since the patch
123  * is to be printed as a tensor product (or its transformation to the real
124  * space cell), its values are to be ordered like <i>(x0,y0) (x0,y1) (x0,y2)
125  * (x1,y0) (x1,y1) (x1,y2) (x2,y0) (x2,y1) (x2,y2)</i>, i.e. the z-coordinate
126  * runs fastest, then the y-coordinate, then x (if there are that many space
127  * directions).
128  *
129  *
130  * <h4>Generalized patches</h4>
131  *
132  * In general, the patches as explained above might be too restricted. For
133  * example, one might want to draw only the outer faces of a domain in a
134  * three-dimensional computation, if one is not interested in what happens
135  * inside. Then, the objects that should be drawn are two-dimensional in a
136  * three-dimensional world. The Patch class and associated output functions
137  * handle these cases. The Patch class therefore takes two template
138  * parameters, the first, named <tt>dim</tt> denoting the dimension of the
139  * object (in the above example, this would be two), while the second, named
140  * <tt>spacedim</tt>, denotes the dimension of the embedding space (this would
141  * be three). The corner points of a patch have the dimension of the space,
142  * while their number is determined by the dimension of the patch. By default,
143  * the second template parameter has the same value as the first, which would
144  * correspond to outputting a cell, rather than a face or something else.
145  *
146  * <h3>DataOutBaseInterface</h3>
147  *
148  * The members of this namespace are not usually called from user code
149  * directly. Rather, classes that use the functions declared here are
150  * typically derived from DataOutInterface.
151  *
152  * The interface of this class basically consists of the declaration of a data
153  * type describing a patch and a bunch of functions taking a list of patches
154  * and writing them in one format or other to the stream. It is in the
155  * responsibility of the derived classes to provide this list of patches. In
156  * addition to the list of patches, a name for each data set may be given.
157  *
158  *
159  * <h3>Querying interface</h3>
160  *
161  * This class also provides a few functions (parse_output_format(),
162  * get_output_format_names(), default_suffix()) that can be used to query
163  * which output formats this class supports. The provide a list of names for
164  * all the formats we can output, parse a string and return an enum indicating
165  * each format, and provide a way to convert a value of this enum into the
166  * usual suffix used for files of that name. Using these functions, one can
167  * entirely free applications from knowledge which formats the library
168  * presently allows to output; several of the example programs show how to do
169  * this.
170  *
171  * <h3>Output parameters</h3>
172  *
173  * All functions take a parameter which is a structure of type
174  * <tt>XFlags</tt>, where <tt>X</tt> is the name of the output format. To find
175  * out what flags are presently supported, read the documentation of the
176  * different structures.
177  *
178  * Note that usually the output formats used for scientific visualization
179  * programs have no or very few parameters (apart from some compatibility
180  * flags) because there the actual appearance of output is determined using
181  * the visualization program and the files produced by this class store more
182  * or less only raw data.
183  *
184  * The direct output formats, like Postscript or Povray need to be given a lot
185  * more parameters, though, since there the output file has to contain all
186  * details of the viewpoint, light source, etc.
187  *
188  * <h3>Writing backends</h3>
189  *
190  * An abstraction layer has been introduced to facilitate coding backends for
191  * additional visualization tools. It is applicable for data formats
192  * separating the information into a field of vertices, a field of connection
193  * information for the grid cells and data fields.
194  *
195  * For each of these fields, output functions are implemented, namely
196  * write_nodes(), write_cells() and write_data(). In order to use these
197  * functions, a format specific output stream must be written, following the
198  * examples of DXStream, GmvStream, VtkStream and so on, implemented in the
199  * .cc file.
200  *
201  * In this framework, the implementation of a new output format is reduced to
202  * writing the section headers and the new output stream class for writing a
203  * single mesh object.
204  *
205  * <h3>Credits</h3>
206  * <ul>
207  *
208  * <li>EPS output based on an earlier implementation by Stefan Nauber for the
209  * old DataOut class
210  *
211  * <li>Povray output by Thomas Richter
212  *
213  * <li>Tecplot output by Benjamin Shelton Kirk
214  *
215  * <li>Lagrange VTK output by Alexander Grayver
216  *
217  * </ul>
218  *
219  * @ingroup output
220  */
221 namespace DataOutBase
222 {
223   /**
224    * Data structure describing a patch of data in <tt>dim</tt> space
225    * dimensions.
226    *
227    * A patch consists of the following data:
228    * <ul>
229    * <li> the corner #vertices,
230    * <li> the number #n_subdivisions of the number of cells the Patch has in
231    * each space direction,
232    * <li> the #data attached to each vertex, in the usual lexicographic
233    * ordering,
234    * <li> information on #neighbors.
235    * </ul>
236    *
237    * See the general documentation of the DataOutBase class for more
238    * information on its contents and purposes.  In the case of two dimensions,
239    * the next picture is an example of <tt>n_subdivisions</tt> = 4 because the
240    * number of (sub)cells within each patch is equal to
241    * <tt>2<sup>dim</sup></tt>.
242    *
243    * @ingroup output
244    */
245   template <int dim, int spacedim = dim>
246   struct Patch
247   {
248     /**
249      * Make the <tt>spacedim</tt> template parameter available.
250      */
251     static const unsigned int space_dim = spacedim;
252 
253     /**
254      * Corner points of a patch.  Interior points are computed by a multilinear
255      * transformation of the unit cell to the cell specified by these corner
256      * points, if <code>points_are_available==false</code>.
257      *
258      * On the other hand, if <code>points_are_available==true</code>, then
259      * the coordinates of the points at which output is to be generated
260      * is attached in additional rows to the <code>data</code> table.
261      *
262      * The order of points is the same as for cells in the
263      * triangulation.
264      */
265     Point<spacedim> vertices[GeometryInfo<dim>::vertices_per_cell];
266 
267     /**
268      * Patch indices of neighbors of the current patch. This is made available
269      * for the OpenDX format that requires neighbor
270      * information for advanced output.
271      */
272     std::array<unsigned int, GeometryInfo<dim>::faces_per_cell> neighbors;
273 
274     /**
275      * Number of this patch. Since we are not sure patches are always
276      * handled in the same order, we better store this.
277      */
278     unsigned int patch_index;
279 
280     /**
281      * Number of subdivisions with which this patch is to be written.
282      * <tt>1</tt> means no subdivision, <tt>2</tt> means bisection, <tt>3</tt>
283      * trisection, etc.
284      */
285     unsigned int n_subdivisions;
286 
287     /**
288      * Data vectors. The format is as follows: <tt>data(i,.)</tt> denotes the
289      * data belonging to the <tt>i</tt>th data vector. <tt>data.n_cols()</tt>
290      * therefore equals the number of output points; this number is
291      * <tt>(subdivisions+1)^{dim}</tt>. <tt>data.n_rows()</tt> equals the number
292      * of data vectors. For the current purpose, a data vector equals one
293      * scalar, even if multiple scalars may later be interpreted as vectors.
294      *
295      * Within each column, <tt>data(.,j)</tt> are the data values at the
296      * output point <tt>j</tt>, where <tt>j</tt> denotes the usual
297      * lexicographic ordering in deal.II. This is also the order of points as
298      * provided by the <tt>QIterated</tt> class when used with the
299      * <tt>QTrapezoid</tt> class as subquadrature.
300      *
301      * Since the number of data vectors is usually the same for all patches to
302      * be printed, <tt>data.size()</tt> should yield the same value for all
303      * patches provided. The exception are patches for which
304      * points_are_available are set, where the actual coordinates of the point
305      * are appended to the 'data' field, see the documentation of the
306      * points_are_available flag.
307      */
308     Table<2, float> data;
309 
310     /**
311      * A flag indicating whether the coordinates of the interior patch points
312      * (assuming that the patch is supposed to be subdivided further) are
313      * appended to the @p data table (@p true) or not (@p false). The latter
314      * is the default and in this case the locations of the points interior to
315      * this patch are computed by (bi-, tri-)linear interpolation from the
316      * vertices of the patch.
317      *
318      * This option exists since patch points may be evaluated using a Mapping
319      * (rather than by a linear interpolation) and therefore have to be stored
320      * in the Patch structure.
321      */
322     bool points_are_available;
323 
324     /**
325      * Reference-cell type of the underlying cell of this patch.
326      */
327     ReferenceCell::Type reference_cell_type;
328 
329     /**
330      * Default constructor. Sets #n_subdivisions to one, #points_are_available
331      * to false, and #patch_index to #no_neighbor.
332      */
333     Patch();
334 
335     /**
336      * Compare the present patch for equality with another one. This is used
337      * in a few of the automated tests in our testsuite.
338      */
339     bool
340     operator==(const Patch &patch) const;
341 
342     /**
343      * Return an estimate for the memory consumption, in bytes, of this
344      * object. This is not exact (but will usually be close) because
345      * calculating the memory usage of trees (e.g., <tt>std::map</tt>) is
346      * difficult.
347      */
348     std::size_t
349     memory_consumption() const;
350 
351     /**
352      * Swap the current object's contents with those of the given argument.
353      */
354     void
355     swap(Patch<dim, spacedim> &other_patch);
356 
357     /**
358      * Value to be used if this patch has no neighbor on one side.
359      */
360     static const unsigned int no_neighbor = numbers::invalid_unsigned_int;
361 
362     /**
363      * @addtogroup Exceptions
364      * @{
365      */
366 
367     /**
368      * Exception
369      */
370     DeclException2(
371       ExcInvalidCombinationOfDimensions,
372       int,
373       int,
374       << "It is not possible to have a structural dimension of " << arg1
375       << " to be larger than the space dimension of the surrounding"
376       << " space " << arg2);
377     //@}
378   };
379 
380 
381 
382   /**
383    * A specialization of the general Patch<dim,spacedim> template that is
384    * tailored to the case of points, i.e., zero-dimensional objects embedded
385    * in @p spacedim dimensional space.
386    *
387    * The current class is compatible with the general template to allow for
388    * using the same functions accessing patches of arbitrary dimensionality
389    * in a generic way. However, it makes some variables that are nonsensical
390    * for zero-dimensional patches into @p static variables that exist only
391    * once in the entire program, as opposed to once per patch. Specifically,
392    * this is the case for the @p neighbors array and the @p n_subdivisions
393    * member variable that make no sense for zero-dimensional patches because
394    * points have no natural neighbors across their non-existent faces, nor
395    * can they reasonably be subdivided.
396    */
397   template <int spacedim>
398   struct Patch<0, spacedim>
399   {
400     /**
401      * Make the <tt>spacedim</tt> template parameter available.
402      */
403     static const unsigned int space_dim = spacedim;
404 
405     /**
406      * Corner points of a patch.  For the current class of zero-dimensional
407      * patches, there is of course only a single vertex.
408      *
409      * If <code>points_are_available==true</code>, then
410      * the coordinates of the point at which output is to be generated
411      * is attached as an additional row to the <code>data</code> table.
412      */
413     Point<spacedim> vertices[1];
414 
415     /**
416      * An unused, @p static variable that exists only to allow access
417      * from general code in a generic fashion.
418      */
419     static unsigned int neighbors[1];
420 
421     /**
422      * Number of this patch. Since we are not sure patches are always
423      * handled in the same order, we better store this.
424      */
425     unsigned int patch_index;
426 
427     /**
428      * Number of subdivisions with which this patch is to be written.
429      * <tt>1</tt> means no subdivision, <tt>2</tt> means bisection, <tt>3</tt>
430      * trisection, etc.
431      *
432      * Since subdivision makes no sense for zero-dimensional patches,
433      * this variable is not used but exists only to allow access
434      * from general code in a generic fashion.
435      */
436     static unsigned int n_subdivisions;
437 
438     /**
439      * Data vectors. The format is as follows: <tt>data(i,.)</tt> denotes the
440      * data belonging to the <tt>i</tt>th data vector. <tt>data.n_cols()</tt>
441      * therefore equals the number of output points; this number is
442      * of course one for the current class, given that we produce output on
443      * points. <tt>data.n_rows()</tt> equals the number of
444      * data vectors. For the current purpose, a data vector equals one scalar,
445      * even if multiple scalars may later be interpreted as vectors.
446      *
447      * Within each column, <tt>data(.,j)</tt> are the data values at the
448      * output point <tt>j</tt>; for the current class, @p j can only
449      * be zero.
450      *
451      * Since the number of data vectors is usually the same for all patches to
452      * be printed, <tt>data.size()</tt> should yield the same value for all
453      * patches provided. The exception are patches for which
454      * points_are_available are set, where the actual coordinates of the point
455      * are appended to the 'data' field, see the documentation of the
456      * points_are_available flag.
457      */
458     Table<2, float> data;
459 
460     /**
461      * A flag indicating whether the coordinates of the interior patch points
462      * (assuming that the patch is supposed to be subdivided further) are
463      * appended to the @p data table (@p true) or not (@p false). The latter
464      * is the default and in this case the locations of the points interior to
465      * this patch are computed by (bi-, tri-)linear interpolation from the
466      * vertices of the patch.
467      *
468      * This option exists since patch points may be evaluated using a Mapping
469      * (rather than by a linear interpolation) and therefore have to be stored
470      * in the Patch structure.
471      */
472     bool points_are_available;
473 
474     /**
475      * Reference-cell type of the underlying cell of this patch.
476      */
477     ReferenceCell::Type reference_cell_type;
478 
479     /**
480      * Default constructor. Sets #points_are_available
481      * to false, and #patch_index to #no_neighbor.
482      */
483     Patch();
484 
485     /**
486      * Compare the present patch for equality with another one. This is used
487      * in a few of the automated tests in our testsuite.
488      */
489     bool
490     operator==(const Patch &patch) const;
491 
492     /**
493      * Return an estimate for the memory consumption, in bytes, of this
494      * object. This is not exact (but will usually be close) because
495      * calculating the memory usage of trees (e.g., <tt>std::map</tt>) is
496      * difficult.
497      */
498     std::size_t
499     memory_consumption() const;
500 
501     /**
502      * Swap the current object's contents with those of the given argument.
503      */
504     void swap(Patch<0, spacedim> &other_patch);
505 
506     /**
507      * Value to be used if this patch has no neighbor on one side.
508      */
509     static const unsigned int no_neighbor = numbers::invalid_unsigned_int;
510 
511     /**
512      * @addtogroup Exceptions
513      * @{
514      */
515 
516     /**
517      * Exception
518      */
519     DeclException2(
520       ExcInvalidCombinationOfDimensions,
521       int,
522       int,
523       << "It is not possible to have a structural dimension of " << arg1
524       << " to be larger than the space dimension of the surrounding"
525       << " space " << arg2);
526     //@}
527   };
528 
529 
530   /**
531    * Base class describing common functionality between different output
532    * flags.
533    *
534    * This is implemented with the "Curiously Recurring Template Pattern";
535    * derived classes use their own type to fill in the typename so that
536    * <tt>memory_consumption</tt> works correctly. See the Wikipedia page on
537    * the pattern for more information.
538    *
539    * @ingroup output
540    */
541   template <typename FlagsType>
542   struct OutputFlagsBase
543   {
544     /**
545      * Declare all flags with name and type as offered by this class, for use
546      * in input files.
547      *
548      * This method does nothing, but child classes may override this method to
549      * add fields to <tt>prm</tt>.
550      */
551     static void
552     declare_parameters(ParameterHandler &prm);
553 
554     /**
555      * Read the parameters declared in declare_parameters() and set the flags
556      * for this output format accordingly.
557      *
558      * This method does nothing, but child classes may override this method to
559      * add fields to <tt>prm</tt>.
560      */
561     void
562     parse_parameters(const ParameterHandler &prm);
563 
564     /**
565      * Return an estimate for the memory consumption, in bytes, of this
566      * object. This is not exact (but will usually be close) because
567      * calculating the memory usage of trees (e.g., <tt>std::map</tt>) is
568      * difficult.
569      */
570     std::size_t
571     memory_consumption() const;
572   };
573 
574 
575   template <typename FlagsType>
576   void
577   OutputFlagsBase<FlagsType>::declare_parameters(ParameterHandler &)
578   {}
579 
580 
581   template <typename FlagsType>
582   void
583   OutputFlagsBase<FlagsType>::parse_parameters(const ParameterHandler &)
584   {}
585 
586 
587   template <typename FlagsType>
588   std::size_t
589   OutputFlagsBase<FlagsType>::memory_consumption() const
590   {
591     return sizeof(FlagsType);
592   }
593 
594 
595   /**
596    * Flags controlling the details of output in OpenDX format.
597    *
598    * @ingroup output
599    */
600   struct DXFlags : public OutputFlagsBase<DXFlags>
601   {
602     /**
603      * Write neighbor information. This information is necessary for instance,
604      * if OpenDX is supposed to compute integral curves (streamlines). If it
605      * is not present, streamlines end at cell boundaries.
606      */
607     bool write_neighbors;
608     /**
609      * Write integer values of the Triangulation in binary format.
610      */
611     bool int_binary;
612     /**
613      * Write coordinate vectors in binary format.
614      */
615     bool coordinates_binary;
616 
617     /**
618      * Write data vectors in binary format.
619      */
620     bool data_binary;
621 
622     /**
623      * Write binary coordinate vectors as double (64 bit) numbers instead of
624      * float (32 bit).
625      */
626     bool data_double;
627 
628     /**
629      * Constructor.
630      */
631     DXFlags(const bool write_neighbors    = false,
632             const bool int_binary         = false,
633             const bool coordinates_binary = false,
634             const bool data_binary        = false);
635 
636     /**
637      * Declare all flags with name and type as offered by this class, for use
638      * in input files.
639      */
640     static void
641     declare_parameters(ParameterHandler &prm);
642 
643     /**
644      * Read the parameters declared in declare_parameters() and set the flags
645      * for this output format accordingly.
646      *
647      * The flags thus obtained overwrite all previous contents of this object.
648      */
649     void
650     parse_parameters(const ParameterHandler &prm);
651   };
652 
653   /**
654    * Flags controlling the details of output in UCD format for AVS.
655    *
656    * @ingroup output
657    */
658   struct UcdFlags : public OutputFlagsBase<UcdFlags>
659   {
660     /**
661      * Write a comment at the beginning of the file stating the date of
662      * creation and some other data.  While this is supported by the UCD
663      * format and AVS, some other programs get confused by this, so the
664      * default is to not write a preamble. However, a preamble can be written
665      * using this flag.
666      *
667      * Default: <code>false</code>.
668      */
669     bool write_preamble;
670 
671     /**
672      * Constructor.
673      */
674     UcdFlags(const bool write_preamble = false);
675 
676     /**
677      * Declare all flags with name and type as offered by this class, for use
678      * in input files.
679      */
680     static void
681     declare_parameters(ParameterHandler &prm);
682 
683     /**
684      * Read the parameters declared in declare_parameters() and set the flags
685      * for this output format accordingly.
686      *
687      * The flags thus obtained overwrite all previous contents of this object.
688      */
689     void
690     parse_parameters(const ParameterHandler &prm);
691   };
692 
693   /**
694    * Flags controlling the details of output in Gnuplot format.
695    *
696    * @ingroup output
697    */
698   struct GnuplotFlags : public OutputFlagsBase<GnuplotFlags>
699   {
700     /**
701      * Default constructor. Sets up the dimension labels with the default values
702      of <tt>"x"</tt>, <tt>"y"</tt>, and <tt>"z"</tt>.
703      */
704     GnuplotFlags();
705 
706     /**
707      * Constructor which sets up non-default values for the dimension labels.
708      */
709     GnuplotFlags(const std::vector<std::string> &space_dimension_labels);
710 
711     /**
712      * Labels to use in each spatial dimension. These default to <tt>"x"</tt>,
713      * <tt>"y"</tt>, and <tt>"z"</tt>. Labels are printed to the Gnuplot file
714      * surrounded by angle brackets: For example, if the space dimension is 2
715      * and the labels are <tt>"x"</tt> and <tt>"t"</tt>, then the relevant
716      * line will start with
717      * @verbatim
718      * # <x> <t>
719      * @endverbatim
720      * Any extra labels will be ignored.
721      *
722      * If you specify these labels yourself then there should be at least
723      * <tt>spacedim</tt> labels, where <tt>spacedim</tt> is the spatial
724      * dimension of the output data.
725      */
726     std::vector<std::string> space_dimension_labels;
727 
728     /**
729      * Return an estimate for the memory consumption, in bytes, of this
730      * object.
731      */
732     std::size_t
733     memory_consumption() const;
734 
735     /**
736      * Exception to raise when there are not enough specified dimension
737      * labels.
738      */
739     DeclExceptionMsg(ExcNotEnoughSpaceDimensionLabels,
740                      "There should be at least one space dimension per spatial "
741                      "dimension (extras are ignored).");
742   };
743 
744   /**
745    * Flags controlling the details of output in Povray format. Several flags
746    * are implemented, see their respective documentation.
747    *
748    * @ingroup output
749    */
750   struct PovrayFlags : public OutputFlagsBase<PovrayFlags>
751   {
752     /**
753      * Normal vector interpolation, if set to true
754      *
755      * default = false
756      */
757     bool smooth;
758 
759     /**
760      * Use bicubic patches (b-splines) instead of triangles.
761      *
762      * default = false
763      */
764     bool bicubic_patch;
765 
766     /**
767      * include external "data.inc" with camera, light and texture definition
768      * for the scene.
769      *
770      * default = false
771      */
772     bool external_data;
773 
774     /**
775      * Constructor.
776      */
777     PovrayFlags(const bool smooth        = false,
778                 const bool bicubic_patch = false,
779                 const bool external_data = false);
780 
781     /**
782      * Declare all flags with name and type as offered by this class, for use
783      * in input files.
784      */
785     static void
786     declare_parameters(ParameterHandler &prm);
787 
788     /**
789      * Read the parameters declared in declare_parameters() and set the flags
790      * for this output format accordingly.
791      *
792      * The flags thus obtained overwrite all previous contents of this object.
793      */
794     void
795     parse_parameters(const ParameterHandler &prm);
796   };
797 
798 
799   /**
800    * Flags controlling the details of output in encapsulated postscript
801    * format.
802    *
803    * @ingroup output
804    */
805   struct EpsFlags : public OutputFlagsBase<EpsFlags>
806   {
807     /**
808      * This denotes the number of the data vector which shall be used for
809      * generating the height information. By default, the first data vector is
810      * taken, i.e. <tt>height_vector==0</tt>, if there is any data vector. If
811      * there is no data vector, no height information is generated.
812      */
813     unsigned int height_vector;
814 
815     /**
816      * Number of the vector which is to be taken to colorize cells. The same
817      * applies as for #height_vector.
818      */
819     unsigned int color_vector;
820 
821     /**
822      * Enum denoting the possibilities whether the scaling should be done such
823      * that the given <tt>size</tt> equals the width or the height of the
824      * resulting picture.
825      */
826     enum SizeType
827     {
828       /// Scale to given width
829       width,
830       /// Scale to given height
831       height
832     };
833 
834     /**
835      * See above. Default is <tt>width</tt>.
836      */
837     SizeType size_type;
838 
839     /**
840      * Width or height of the output as given in postscript units This usually
841      * is given by the strange unit 1/72 inch. Whether this is height or width
842      * is specified by the flag <tt>size_type</tt>.
843      *
844      * Default is 300, which represents a size of roughly 10 cm.
845      */
846     unsigned int size;
847 
848     /**
849      * Width of a line in postscript units. Default is 0.5.
850      */
851     double line_width;
852 
853     /**
854      * Angle of the line origin-viewer against the z-axis in degrees.
855      *
856      * Default is the Gnuplot-default of 60.
857      */
858     double azimut_angle;
859 
860     /**
861      * Angle by which the viewers position projected onto the x-y-plane is
862      * rotated around the z-axis, in positive sense when viewed from above.
863      * The unit are degrees, and zero equals a position above or below the
864      * negative y-axis.
865      *
866      * Default is the Gnuplot-default of 30.  An example of a Gnuplot-default
867      * of 0 is the following:
868      *
869      * @verbatim
870      *
871      *          3________7
872      *          /       /|
873      *         /       / |
874      *       2/______6/  |
875      *       |   |   |   |
876      * O-->  |   0___|___4
877      *       |  /    |  /
878      *       | /     | /
879      *      1|/______5/
880      *
881      * @endverbatim
882      */
883     double turn_angle;
884 
885     /**
886      * Factor by which the z-axis is to be stretched as compared to the x- and
887      * y-axes. This is to compensate for the different sizes that coordinate
888      * and solution values may have and to prevent that the plot looks to much
889      * out-of-place (no elevation at all if solution values are much smaller
890      * than coordinate values, or the common "extremely mountainous area" in
891      * the opposite case.
892      *
893      * Default is <tt>1.0</tt>.
894      */
895     double z_scaling;
896 
897     /**
898      * Flag the determines whether the lines bounding the cells (or the parts
899      * of each patch) are to be plotted.
900      *
901      * Default: <tt>true</tt>.
902      */
903     bool draw_mesh;
904 
905     /**
906      * Flag whether to fill the regions between the lines bounding the cells
907      * or not. If not, no hidden line removal is performed, which in this
908      * crude implementation is done through writing the cells in a back-to-
909      * front order, thereby hiding the cells in the background by cells in the
910      * foreground.
911      *
912      * If this flag is <tt>false</tt> and #draw_mesh is <tt>false</tt> as
913      * well, nothing will be printed.
914      *
915      * If this flag is <tt>true</tt>, then the cells will be drawn either
916      * colored by one of the data sets (if #shade_cells is <tt>true</tt>), or
917      * pure white (if #shade_cells is false or if there are no data sets).
918      *
919      * Default is <tt>true</tt>.
920      */
921     bool draw_cells;
922 
923     /**
924      * Flag to determine whether the cells shall be colorized by the data set
925      * denoted by #color_vector, or simply be painted in white. This flag only
926      * makes sense if <tt>#draw_cells==true</tt>. Colorization is done through
927      * #color_function.
928      *
929      * Default is <tt>true</tt>.
930      */
931     bool shade_cells;
932 
933     /**
934      * Structure keeping the three color values in the RGB system.
935      */
936     struct RgbValues
937     {
938       float red;
939       float green;
940       float blue;
941 
942       /**
943        * Return <tt>true</tt> if the color represented by the three color
944        * values is a grey scale, i.e. all components are equal.
945        */
946       bool
947       is_grey() const;
948     };
949 
950     /**
951      * Definition of a function pointer type taking a value and returning a
952      * triple of color values in RGB values.
953      *
954      * Besides the actual value by which the color is to be computed, min and
955      * max values of the data to be colorized are given as well.
956      */
957     using ColorFunction = RgbValues (*)(const double value,
958                                         const double min_value,
959                                         const double max_value);
960 
961     /**
962      * This is a pointer to the function which is used to colorize the cells.
963      * By default, it points to the static function default_color_function()
964      * which is a member of this class.
965      */
966     ColorFunction color_function;
967 
968 
969     /**
970      * Default colorization function. This one does what one usually wants: It
971      * shifts colors from black (lowest value) through blue, green and red to
972      * white (highest value). For the exact definition of the color scale
973      * refer to the implementation.
974      *
975      * This function was originally written by Stefan Nauber.
976      */
977     static RgbValues
978     default_color_function(const double value,
979                            const double min_value,
980                            const double max_value);
981 
982     /**
983      * This is an alternative color function producing a grey scale between
984      * black (lowest values) and white (highest values). You may use it by
985      * setting the #color_function variable to the address of this function.
986      */
987     static RgbValues
988     grey_scale_color_function(const double value,
989                               const double min_value,
990                               const double max_value);
991 
992     /**
993      * This is one more alternative color function producing a grey scale
994      * between white (lowest values) and black (highest values), i.e. the
995      * scale is reversed to the previous one. You may use it by setting the
996      * #color_function variable to the address of this function.
997      */
998     static RgbValues
999     reverse_grey_scale_color_function(const double value,
1000                                       const double min_value,
1001                                       const double max_value);
1002 
1003     /**
1004      * Constructor.
1005      */
1006     EpsFlags(const unsigned int  height_vector  = 0,
1007              const unsigned int  color_vector   = 0,
1008              const SizeType      size_type      = width,
1009              const unsigned int  size           = 300,
1010              const double        line_width     = 0.5,
1011              const double        azimut_angle   = 60,
1012              const double        turn_angle     = 30,
1013              const double        z_scaling      = 1.0,
1014              const bool          draw_mesh      = true,
1015              const bool          draw_cells     = true,
1016              const bool          shade_cells    = true,
1017              const ColorFunction color_function = &default_color_function);
1018 
1019     /**
1020      * Declare all flags with name and type as offered by this class, for use
1021      * in input files.
1022      *
1023      * For coloring, only the color functions declared in this class are
1024      * offered.
1025      */
1026     static void
1027     declare_parameters(ParameterHandler &prm);
1028 
1029     /**
1030      * Read the parameters declared in declare_parameters() and set the flags
1031      * for this output format accordingly.
1032      *
1033      * The flags thus obtained overwrite all previous contents of this object.
1034      */
1035     void
1036     parse_parameters(const ParameterHandler &prm);
1037   };
1038 
1039   /**
1040    * Flags controlling the details of output in GMV format. At present no
1041    * flags are implemented.
1042    *
1043    * @ingroup output
1044    */
1045   struct GmvFlags : public OutputFlagsBase<GmvFlags>
1046   {};
1047 
1048   /**
1049    * Flags controlling the details of output in Tecplot format.
1050    *
1051    * @ingroup output
1052    */
1053   struct TecplotFlags : public OutputFlagsBase<TecplotFlags>
1054   {
1055     /**
1056      * Tecplot allows to assign names to zones. This variable stores this
1057      * name.
1058      */
1059     const char *zone_name;
1060 
1061     /**
1062      * Solution time for each zone in a strand. This value must be non-
1063      * negative, otherwise it will not be written to file. Do not assign any
1064      * value for this in case of a static zone.
1065      */
1066     double solution_time;
1067 
1068     /**
1069      * Constructor.
1070      */
1071     TecplotFlags(const char * zone_name     = nullptr,
1072                  const double solution_time = -1.0);
1073 
1074     /**
1075      * Return an estimate for the memory consumption, in bytes, of this
1076      * object.
1077      */
1078     std::size_t
1079     memory_consumption() const;
1080   };
1081 
1082   /**
1083    * Flags controlling the details of output in VTK format.
1084    *
1085    * @ingroup output
1086    */
1087   struct VtkFlags : public OutputFlagsBase<VtkFlags>
1088   {
1089     /**
1090      * The time of the time step if this file is part of a time dependent
1091      * simulation.
1092      *
1093      * The value of this variable is written into the output file according to
1094      * the instructions provided in
1095      * http://www.visitusers.org/index.php?title=Time_and_Cycle_in_VTK_files
1096      * unless it is at its default value of
1097      * @verbatim std::numeric_limits<unsigned int>::min() @endverbatim.
1098      */
1099     double time;
1100 
1101     /**
1102      * The number of the time step if this file is part of a time dependent
1103      * simulation, or the cycle within a nonlinear or other iteration.
1104      *
1105      * The value of this variable is written into the output file according to
1106      * the instructions provided in
1107      * http://www.visitusers.org/index.php?title=Time_and_Cycle_in_VTK_files
1108      * unless it is at its default value of
1109      * @verbatim std::numeric_limits<unsigned int>::min() @endverbatim.
1110      */
1111     unsigned int cycle;
1112 
1113     /**
1114      * Flag to determine whether the current date and time shall be printed as
1115      * a comment in the file's second line.
1116      *
1117      * Default is <tt>true</tt>.
1118      */
1119     bool print_date_and_time;
1120 
1121     /**
1122      * A data type providing the different possible zlib compression
1123      * levels. These map directly to constants defined by zlib.
1124      */
1125     enum ZlibCompressionLevel
1126     {
1127       /**
1128        * Do not use any compression.
1129        */
1130       no_compression,
1131       /**
1132        * Use the fastest available compression algorithm.
1133        */
1134       best_speed,
1135       /**
1136        * Use the algorithm which results in the smallest compressed
1137        * files. This is the default flag.
1138        */
1139       best_compression,
1140       /**
1141        * Use the default compression algorithm. This is a compromise between
1142        * speed and file size.
1143        */
1144       default_compression
1145     };
1146 
1147     /**
1148      * Flag determining the compression level at which zlib, if available, is
1149      * run. The default is <tt>best_compression</tt>.
1150      */
1151     ZlibCompressionLevel compression_level;
1152 
1153     /**
1154      * Flag determining whether to write patches as linear cells
1155      * or as a high-order Lagrange cell.
1156      *
1157      * Default is <tt>false</tt>.
1158      *
1159      * @note The ability to write data that corresponds to higher order
1160      * polynomials rather than simply linear or bilinear is a feature that was
1161      * only introduced in VTK 8.1.0 in December 2017. You will need at least
1162      * Paraview version 5.5.0 released in April 2018 or a similarly recent
1163      * version of VisIt for this feature to work (for example, VisIt 3.1.1,
1164      * released in February 2020, does not yet support this feature). Older
1165      * versions of these programs are likely going to result in errors when
1166      * trying to read files generated with this flag set to true. Experience
1167      * with these programs shows that these error messages are likely going to
1168      * be rather less descriptive and more obscure.
1169      */
1170     bool write_higher_order_cells;
1171 
1172     /**
1173      * Constructor.
1174      */
1175     VtkFlags(
1176       const double       time  = std::numeric_limits<double>::min(),
1177       const unsigned int cycle = std::numeric_limits<unsigned int>::min(),
1178       const bool         print_date_and_time              = true,
1179       const ZlibCompressionLevel compression_level        = best_compression,
1180       const bool                 write_higher_order_cells = false);
1181   };
1182 
1183 
1184   /**
1185    * Flags for SVG output.
1186    *
1187    * @ingroup output
1188    */
1189   struct SvgFlags : public OutputFlagsBase<SvgFlags>
1190   {
1191     /**
1192      * Height of the image in SVG units. Default value is 4000.
1193      */
1194     unsigned int height;
1195 
1196     /**
1197      * Width of the image in SVG units. If left zero, the width is computed
1198      * from the height.
1199      */
1200     unsigned int width;
1201 
1202     /**
1203      * This denotes the number of the data vector which shall be used for
1204      * generating the height information. By default, the first data vector is
1205      * taken, i.e. <tt>#height_vector==0</tt>, if there is any data vector. If
1206      * there is no data vector, no height information is generated.
1207      */
1208     unsigned int height_vector;
1209 
1210     /**
1211      * Angles for the perspective view
1212      */
1213     int azimuth_angle, polar_angle;
1214 
1215     unsigned int line_thickness;
1216 
1217     /**
1218      * Draw a margin of 5% around the plotted area
1219      */
1220     bool margin;
1221 
1222     /**
1223      * Draw a colorbar encoding the cell coloring
1224      */
1225     bool draw_colorbar;
1226 
1227     /**
1228      * Constructor.
1229      */
1230     SvgFlags(const unsigned int height_vector  = 0,
1231              const int          azimuth_angle  = 37,
1232              const int          polar_angle    = 45,
1233              const unsigned int line_thickness = 1,
1234              const bool         margin         = true,
1235              const bool         draw_colorbar  = true);
1236   };
1237 
1238 
1239   /**
1240    * Flags controlling the details of output in deal.II intermediate format.
1241    * At present no flags are implemented.
1242    *
1243    * @ingroup output
1244    */
1245   struct Deal_II_IntermediateFlags
1246     : public OutputFlagsBase<Deal_II_IntermediateFlags>
1247   {
1248     /**
1249      * An indicator of the current file format version used to write
1250      * intermediate format. We do not attempt to be backward compatible, so
1251      * this number is used only to verify that the format we are writing is
1252      * what the current readers and writers understand.
1253      */
1254     static const unsigned int format_version;
1255   };
1256 
1257   /**
1258    * Flags controlling the DataOutFilter.
1259    *
1260    * @ingroup output
1261    */
1262   struct DataOutFilterFlags
1263   {
1264     /**
1265      * Filter duplicate vertices and associated values. This will drastically
1266      * reduce the output data size but will result in an output file that
1267      * does not faithfully represent the actual data if the data corresponds
1268      * to discontinuous fields. In particular, along subdomain boundaries
1269      * the data will still be discontinuous, while it will look like a
1270      * continuous field inside of the subdomain.
1271      */
1272     bool filter_duplicate_vertices;
1273 
1274     /**
1275      * Whether the XDMF output refers to HDF5 files. This affects how output
1276      * is structured.
1277      */
1278     bool xdmf_hdf5_output;
1279 
1280     /**
1281      * Constructor.
1282      */
1283     DataOutFilterFlags(const bool filter_duplicate_vertices = false,
1284                        const bool xdmf_hdf5_output          = false);
1285 
1286     /**
1287      * Declare all flags with name and type as offered by this class, for use
1288      * in input files.
1289      */
1290     static void
1291     declare_parameters(ParameterHandler &prm);
1292 
1293     /**
1294      * Read the parameters declared in <tt>declare_parameters</tt> and set the
1295      * flags for this output format accordingly.
1296      *
1297      * The flags thus obtained overwrite all previous contents of this object.
1298      */
1299     void
1300     parse_parameters(const ParameterHandler &prm);
1301 
1302     /**
1303      * Determine an estimate for the memory consumption (in bytes) of this
1304      * object.
1305      */
1306     std::size_t
1307     memory_consumption() const;
1308   };
1309 
1310   /**
1311    * DataOutFilter provides a way to remove redundant vertices and values
1312    * generated by the deal.II output. By default, DataOutBase and the classes
1313    * that build on it output data at each corner of each cell. This means that
1314    * data is output multiple times for each vertex of the mesh. The purpose of
1315    * this scheme is to support output of discontinuous quantities, either
1316    * because the finite element space is discontinuous or because the quantity
1317    * that is output is computed from a solution field and is discontinuous
1318    * across faces.
1319    *
1320    * This class is an attempt to rein in the amount of data that is written.
1321    * If the fields that are written to files are indeed discontinuous, the
1322    * only way to faithfully represent them is indeed to write multiple values
1323    * for each vertex (this is typically done by writing multiple node
1324    * locations for the same vertex and defining data at these nodes). However,
1325    * for fine meshes, one may not necessarily be interested in an exact
1326    * representation of output fields that will likely only have small
1327    * discontinuities. Rather, it may be sufficient to just output one value
1328    * per vertex, which may be chosen arbitrarily from among those that are
1329    * defined at this vertex from any of the adjacent cells.
1330    */
1331   class DataOutFilter
1332   {
1333   public:
1334     /**
1335      * Default constructor.
1336      */
1337     DataOutFilter();
1338 
1339     /**
1340      * Destructor with a given set of flags. See DataOutFilterFlags for
1341      * possible flags.
1342      */
1343     DataOutFilter(const DataOutBase::DataOutFilterFlags &flags);
1344 
1345     /**
1346      * Write a point with the specified index into the filtered data set. If
1347      * the point already exists and we are filtering redundant values, the
1348      * provided index will internally refer to another recorded point.
1349      */
1350     template <int dim>
1351     void
1352     write_point(const unsigned int index, const Point<dim> &p);
1353 
1354     /**
1355      * Record a deal.II cell in the internal reordered format.
1356      */
1357     template <int dim>
1358     void
1359     write_cell(const unsigned int index,
1360                const unsigned int start,
1361                const unsigned int d1,
1362                const unsigned int d2,
1363                const unsigned int d3);
1364 
1365     /**
1366      * Record a single deal.II cell without subdivisions (e.g. simplex) in the
1367      * internal reordered format.
1368      */
1369     void
1370     write_cell_single(const unsigned int index,
1371                       const unsigned int start,
1372                       const unsigned int n_points);
1373 
1374     /**
1375      * Filter and record a data set. If there are multiple values at a given
1376      * vertex and redundant values are being removed, one is arbitrarily
1377      * chosen as the recorded value. In the future this can be expanded to
1378      * average/min/max multiple values at a given vertex.
1379      */
1380     void
1381     write_data_set(const std::string &     name,
1382                    const unsigned int      dimension,
1383                    const unsigned int      set_num,
1384                    const Table<2, double> &data_vectors);
1385 
1386     /**
1387      * Resize and fill a vector with all the filtered node vertex points, for
1388      * output to a file.
1389      */
1390     void
1391     fill_node_data(std::vector<double> &node_data) const;
1392 
1393     /**
1394      * Resize and fill a vector with all the filtered cell vertex indices, for
1395      * output to a file.
1396      */
1397     void
1398     fill_cell_data(const unsigned int         local_node_offset,
1399                    std::vector<unsigned int> &cell_data) const;
1400 
1401     /**
1402      * Get the name of the data set indicated by the set number.
1403      */
1404     std::string
1405     get_data_set_name(const unsigned int set_num) const;
1406 
1407     /**
1408      * Get the dimensionality of the data set indicated by the set number.
1409      */
1410     unsigned int
1411     get_data_set_dim(const unsigned int set_num) const;
1412 
1413     /**
1414      * Get the raw double valued data of the data set indicated by the set
1415      * number.
1416      */
1417     const double *
1418     get_data_set(const unsigned int set_num) const;
1419 
1420     /**
1421      * Return the number of nodes in this DataOutFilter. This may be smaller
1422      * than the original number of nodes if filtering is enabled.
1423      */
1424     unsigned int
1425     n_nodes() const;
1426 
1427     /**
1428      * Return the number of filtered cells in this DataOutFilter. Cells are
1429      * not filtered so this will be the original number of cells.
1430      */
1431     unsigned int
1432     n_cells() const;
1433 
1434     /**
1435      * Return the number of filtered data sets in this DataOutFilter. Data
1436      * sets are not filtered so this will be the original number of data sets.
1437      */
1438     unsigned int
1439     n_data_sets() const;
1440 
1441     /**
1442      * Empty functions to do base class inheritance.
1443      */
1444     void
1445     flush_points();
1446 
1447     /**
1448      * Empty functions to do base class inheritance.
1449      */
1450     void
1451     flush_cells();
1452 
1453 
1454   private:
1455     /**
1456      * Empty class to provide comparison function for Map3DPoint.
1457      */
1458     struct Point3Comp
1459     {
1460       bool
1461       operator()(const Point<3> &one, const Point<3> &two) const
1462       {
1463         /*
1464          * The return statement below is an optimized version of the following
1465          * code:
1466          *
1467          * for (unsigned int d=0; d<3; ++d)
1468          * {
1469          *   if (one(d) < two(d))
1470          *     return true;
1471          *   else if (one(d) > two(d))
1472          *     return false;
1473          * }
1474          * return false;
1475          */
1476 
1477         return (one(0) < two(0) ||
1478                 (!(two(0) < one(0)) &&
1479                  (one(1) < two(1) || (!(two(1) < one(1)) && one(2) < two(2)))));
1480       }
1481     };
1482 
1483     using Map3DPoint = std::multimap<Point<3>, unsigned int, Point3Comp>;
1484 
1485     /**
1486      * Flags used to specify filtering behavior.
1487      */
1488     DataOutBase::DataOutFilterFlags flags;
1489 
1490     /**
1491      * The number of space dimensions in which the vertices represented
1492      * by the current object live. This corresponds to the usual
1493      * @p dim argument, but since this class is not templated on the
1494      * dimension, we need to store it here.
1495      */
1496     unsigned int node_dim;
1497 
1498     /**
1499      * The number of cells stored in @ref filtered_cells.
1500      */
1501     unsigned int num_cells;
1502 
1503     /**
1504      * Map of points to an internal index.
1505      */
1506     Map3DPoint existing_points;
1507 
1508     /**
1509      * Map of actual point index to internal point index.
1510      */
1511     std::map<unsigned int, unsigned int> filtered_points;
1512 
1513     /**
1514      * Map of cells to the filtered points.
1515      */
1516     std::map<unsigned int, unsigned int> filtered_cells;
1517 
1518     /**
1519      * Data set names.
1520      */
1521     std::vector<std::string> data_set_names;
1522 
1523     /**
1524      * Data set dimensions.
1525      */
1526     std::vector<unsigned int> data_set_dims;
1527 
1528     /**
1529      * Data set data.
1530      */
1531     std::vector<std::vector<double>> data_sets;
1532 
1533     /**
1534      * Record a cell vertex index based on the internal reordering.
1535      */
1536     void
1537     internal_add_cell(const unsigned int cell_index,
1538                       const unsigned int pt_index);
1539   };
1540 
1541 
1542   /**
1543    * Provide a data type specifying the presently supported output formats.
1544    */
1545   enum OutputFormat
1546   {
1547     /**
1548      * Use the format already stored in the object.
1549      */
1550     default_format,
1551 
1552     /**
1553      * Do not write any output.
1554      */
1555     none,
1556 
1557     /**
1558      * Output for OpenDX.
1559      */
1560     dx,
1561 
1562     /**
1563      * Output in the UCD format for AVS.
1564      */
1565     ucd,
1566 
1567     /**
1568      * Output for the Gnuplot tool.
1569      */
1570     gnuplot,
1571 
1572     /**
1573      * Output for the Povray raytracer.
1574      */
1575     povray,
1576 
1577     /**
1578      * Output in encapsulated PostScript.
1579      */
1580     eps,
1581 
1582     /**
1583      * Output for GMV.
1584      */
1585     gmv,
1586 
1587     /**
1588      * Output for Tecplot in text format.
1589      */
1590     tecplot,
1591 
1592     /**
1593      * Output for Tecplot in binary format. Faster and smaller than text
1594      * format.
1595      *
1596      * @deprecated Using Tecplot binary output is deprecated.
1597      */
1598     tecplot_binary,
1599 
1600     /**
1601      * Output in VTK format.
1602      */
1603     vtk,
1604 
1605     /**
1606      * Output in VTK format.
1607      */
1608     vtu,
1609 
1610     /**
1611      * Output in SVG format.
1612      */
1613     svg,
1614 
1615     /**
1616      * Output in deal.II intermediate format.
1617      */
1618     deal_II_intermediate,
1619 
1620     /**
1621      * Output in HDF5 format.
1622      */
1623     hdf5
1624   };
1625 
1626 
1627   /**
1628    * Write the given list of patches to the output stream in OpenDX format.
1629    */
1630   template <int dim, int spacedim>
1631   void
1632   write_dx(
1633     const std::vector<Patch<dim, spacedim>> &patches,
1634     const std::vector<std::string> &         data_names,
1635     const std::vector<
1636       std::tuple<unsigned int,
1637                  unsigned int,
1638                  std::string,
1639                  DataComponentInterpretation::DataComponentInterpretation>>
1640       &            nonscalar_data_ranges,
1641     const DXFlags &flags,
1642     std::ostream & out);
1643 
1644   /**
1645    * Write the given list of patches to the output stream in eps format.
1646    *
1647    * Output in this format circumvents the use of auxiliary graphic programs
1648    * converting some output format into a graphics format. This has the
1649    * advantage that output is easy and fast, and the disadvantage that you
1650    * have to give a whole bunch of parameters which determine the direction of
1651    * sight, the mode of colorization, the scaling of the height axis, etc. (Of
1652    * course, all these parameters have reasonable default values, which you
1653    * may want to change.)
1654    *
1655    * This function only supports output for two-dimensional domains (i.e.,
1656    * with dim==2), with values in the vertical direction taken from a data
1657    * vector.
1658    *
1659    * Basically, output consists of the mesh and the cells in between them. You
1660    * can draw either of these, or both, or none if you are really interested
1661    * in an empty picture. If written, the mesh uses black lines. The cells in
1662    * between the mesh are either not printed (this will result in a loss of
1663    * hidden line removal, i.e.  you can "see through" the cells to lines
1664    * behind), printed in white (which does nothing apart from the hidden line
1665    * removal), or colorized using one of the data vectors (which need not be
1666    * the same as the one used for computing the height information) and a
1667    * customizable color function. The default color functions chooses the
1668    * color between black, blue, green, red and white, with growing values of
1669    * the data field chosen for colorization. At present, cells are displayed
1670    * with one color per cell only, which is taken from the value of the data
1671    * field at the center of the cell; bilinear interpolation of the color on a
1672    * cell is not used.
1673    *
1674    * By default, the viewpoint is chosen like the default viewpoint in
1675    * GNUPLOT, i.e.  with an angle of 60 degrees with respect to the positive
1676    * z-axis and rotated 30 degrees in positive sense (as seen from above) away
1677    * from the negative y-axis.  Of course you can change these settings.
1678    *
1679    * EPS output is written without a border around the picture, i.e. the
1680    * bounding box is close to the output on all four sides. Coordinates are
1681    * written using at most five digits, to keep picture size at a reasonable
1682    * size.
1683    *
1684    * All parameters along with their default values are listed in the
1685    * documentation of the <tt>EpsFlags</tt> member class of this class. See
1686    * there for more and detailed information.
1687    */
1688   template <int spacedim>
1689   void
1690   write_eps(
1691     const std::vector<Patch<2, spacedim>> &patches,
1692     const std::vector<std::string> &       data_names,
1693     const std::vector<
1694       std::tuple<unsigned int,
1695                  unsigned int,
1696                  std::string,
1697                  DataComponentInterpretation::DataComponentInterpretation>>
1698       &             nonscalar_data_ranges,
1699     const EpsFlags &flags,
1700     std::ostream &  out);
1701 
1702   /**
1703    * This is the same function as above except for domains that are not two-
1704    * dimensional. This function is not implemented (and will throw an error if
1705    * called) but is declared to allow for dimension-independent programs.
1706    */
1707   template <int dim, int spacedim>
1708   void
1709   write_eps(
1710     const std::vector<Patch<dim, spacedim>> &patches,
1711     const std::vector<std::string> &         data_names,
1712     const std::vector<
1713       std::tuple<unsigned int,
1714                  unsigned int,
1715                  std::string,
1716                  DataComponentInterpretation::DataComponentInterpretation>>
1717       &             nonscalar_data_ranges,
1718     const EpsFlags &flags,
1719     std::ostream &  out);
1720 
1721 
1722   /**
1723    * Write the given list of patches to the output stream in GMV format.
1724    *
1725    * Data is written in the following format: nodes are considered the points
1726    * of the patches. In spatial dimensions less than three, zeroes are
1727    * inserted for the missing coordinates. The data vectors are written as
1728    * node or cell data, where for the first the data space is interpolated to
1729    * (bi-,tri-)linear elements.
1730    */
1731   template <int dim, int spacedim>
1732   void
1733   write_gmv(
1734     const std::vector<Patch<dim, spacedim>> &patches,
1735     const std::vector<std::string> &         data_names,
1736     const std::vector<
1737       std::tuple<unsigned int,
1738                  unsigned int,
1739                  std::string,
1740                  DataComponentInterpretation::DataComponentInterpretation>>
1741       &             nonscalar_data_ranges,
1742     const GmvFlags &flags,
1743     std::ostream &  out);
1744 
1745   /**
1746    * Write the given list of patches to the output stream in gnuplot format.
1747    * Visualization of two-dimensional data can then be achieved by starting
1748    * <tt>gnuplot</tt> and entering the commands
1749    *
1750    * @verbatim
1751    * set data style lines
1752    * splot "filename" using 1:2:n
1753    * @endverbatim
1754    * This example assumes that the number of the data vector displayed is
1755    * <b>n-2</b>.
1756    *
1757    * The GNUPLOT format is not able to handle data on unstructured grids
1758    * directly. Directly would mean that you only give the vertices and the
1759    * solution values thereon and the program constructs its own grid to
1760    * represent the data. This is only possible for a structured tensor product
1761    * grid in two dimensions. However, it is possible to give several such
1762    * patches within one file, which is exactly what the respective function of
1763    * this class does: writing each cell's data as a patch of data, at least if
1764    * the patches as passed from derived classes represent cells. Note that the
1765    * functions on patches need not be continuous at interfaces between
1766    * patches, so this method also works for discontinuous elements. Note also,
1767    * that GNUPLOT can do hidden line removal for patched data.
1768    *
1769    * While this discussion applies to two spatial dimensions, it is more
1770    * complicated in 3d. The reason is that we could still use patches, but it
1771    * is difficult when trying to visualize them, since if we use a cut through
1772    * the data (by, for example, using x- and z-coordinates, a fixed y-value
1773    * and plot function values in z-direction, then the patched data is not a
1774    * patch in the sense GNUPLOT wants it any more. Therefore, we use another
1775    * approach, namely writing the data on the 3d grid as a sequence of lines,
1776    * i.e. two points each associated with one or more data sets.  There are
1777    * therefore 12 lines for each subcells of a patch.
1778    *
1779    * Given the lines as described above, a cut through this data in Gnuplot
1780    * can then be achieved like this (& stands for the dollar sign in the
1781    * following):
1782    * @verbatim
1783    *   set data style lines
1784    *   splot [:][:][0:] "T" using 1:2:(&3==.5 ? &4 : -1)
1785    * @endverbatim
1786    *
1787    * This command plots data in x- and y-direction unbounded, but in
1788    * z-direction only those data points which are above the x-y-plane (we
1789    * assume here a positive solution, if it has negative values, you might
1790    * want to decrease the lower bound). Furthermore, it only takes the data
1791    * points with z-values (<tt>&3</tt>) equal to 0.5, i.e. a cut through the
1792    * domain at <tt>z=0.5</tt>. For the data points on this plane, the data
1793    * values of the first data set (<tt>&4</tt>) are raised in z-direction
1794    * above the x-y-plane; all other points are denoted the value <tt>-1</tt>
1795    * instead of the value of the data vector and are not plotted due to the
1796    * lower bound in z plotting direction, given in the third pair of brackets.
1797    *
1798    * More complex cuts are possible, including nonlinear ones. Note however,
1799    * that only those points which are actually on the cut-surface are plotted.
1800    */
1801   template <int dim, int spacedim>
1802   void
1803   write_gnuplot(
1804     const std::vector<Patch<dim, spacedim>> &patches,
1805     const std::vector<std::string> &         data_names,
1806     const std::vector<
1807       std::tuple<unsigned int,
1808                  unsigned int,
1809                  std::string,
1810                  DataComponentInterpretation::DataComponentInterpretation>>
1811       &                 nonscalar_data_ranges,
1812     const GnuplotFlags &flags,
1813     std::ostream &      out);
1814 
1815   /**
1816    * Write the given list of patches to the output stream for the Povray
1817    * raytracer.
1818    *
1819    * Output in this format creates a povray source file, include standard
1820    * camera and light source definition for rendering with povray 3.1 At
1821    * present, this format only supports output for two-dimensional data, with
1822    * values in the third direction taken from a data vector.
1823    *
1824    * The output uses two different povray-objects:
1825    *
1826    * <ul>
1827    * <li> <tt>BICUBIC_PATCH</tt> A <tt>bicubic_patch</tt> is a 3-dimensional
1828    * Bezier patch. It consists of 16 Points describing the surface. The 4
1829    * corner points are touched by the object, while the other 12 points pull
1830    * and stretch the patch into shape. One <tt>bicubic_patch</tt> is generated
1831    * on each patch. Therefore the number of subdivisions has to be 3 to provide
1832    * the patch with 16 points. A bicubic patch is not exact but generates very
1833    * smooth images.
1834    *
1835    * <li> <tt>MESH</tt> The mesh object is used to store large number of
1836    * triangles. Every square of the patch data is split into one upper-left
1837    * and one lower-right triangle. If the number of subdivisions is three, 32
1838    * triangle are generated for every patch.
1839    *
1840    * Using the smooth flag povray interpolates the normals on the triangles,
1841    * imitating a curved surface
1842    * </ul>
1843    *
1844    * All objects get one texture definition called Tex. This texture has to be
1845    * declared somewhere before the object data. This may be in an external
1846    * data file or at the beginning of the output file. Setting the
1847    * <tt>external_data</tt> flag to false, an standard camera, light and
1848    * texture (scaled to fit the scene) is added to the output file. Set to
1849    * true an include file "data.inc" is included. This file is not generated
1850    * by deal and has to include camera, light and the texture definition Tex.
1851    *
1852    * You need povray (>=3.0) to render the scene. The minimum options for
1853    * povray are:
1854    * @verbatim
1855    *   povray +I<inputfile> +W<horiz. size> +H<ver. size> +L<include path>
1856    * @endverbatim
1857    * If the external file "data.inc" is used, the path to this file has to be
1858    * included in the povray options.
1859    */
1860   template <int dim, int spacedim>
1861   void
1862   write_povray(
1863     const std::vector<Patch<dim, spacedim>> &patches,
1864     const std::vector<std::string> &         data_names,
1865     const std::vector<
1866       std::tuple<unsigned int,
1867                  unsigned int,
1868                  std::string,
1869                  DataComponentInterpretation::DataComponentInterpretation>>
1870       &                nonscalar_data_ranges,
1871     const PovrayFlags &flags,
1872     std::ostream &     out);
1873 
1874   /**
1875    * Write the given list of patches to the output stream in Tecplot ASCII
1876    * format (FEBLOCK).
1877    *
1878    * For more information consult the Tecplot Users and Reference manuals.
1879    */
1880   template <int dim, int spacedim>
1881   void
1882   write_tecplot(
1883     const std::vector<Patch<dim, spacedim>> &patches,
1884     const std::vector<std::string> &         data_names,
1885     const std::vector<
1886       std::tuple<unsigned int,
1887                  unsigned int,
1888                  std::string,
1889                  DataComponentInterpretation::DataComponentInterpretation>>
1890       &                 nonscalar_data_ranges,
1891     const TecplotFlags &flags,
1892     std::ostream &      out);
1893 
1894   /**
1895    * Write the given list of patches to the output stream in UCD format
1896    * described in the AVS developer's guide (now AVS). Due to limitations in
1897    * the present format, only node based data can be output, which in one
1898    * reason why we invented the patch concept. In order to write higher order
1899    * elements, you may split them up into several subdivisions of each cell.
1900    * These subcells will then, however, also appear as different cells by
1901    * programs which understand the UCD format.
1902    *
1903    * No use is made of the possibility to give model data since these are not
1904    * supported by all UCD aware programs. You may give cell data in derived
1905    * classes by setting all values of a given data set on a patch to the same
1906    * value.
1907    */
1908   template <int dim, int spacedim>
1909   void
1910   write_ucd(
1911     const std::vector<Patch<dim, spacedim>> &patches,
1912     const std::vector<std::string> &         data_names,
1913     const std::vector<
1914       std::tuple<unsigned int,
1915                  unsigned int,
1916                  std::string,
1917                  DataComponentInterpretation::DataComponentInterpretation>>
1918       &             nonscalar_data_ranges,
1919     const UcdFlags &flags,
1920     std::ostream &  out);
1921 
1922   /**
1923    * Write the given list of patches to the output stream in VTK format. The
1924    * data is written in the traditional VTK format as opposed to the XML-based
1925    * format that write_vtu() produces.
1926    *
1927    * The nonscalar_data_ranges argument denotes ranges of components in the
1928    * output that are considered a vector, rather than simply a collection of
1929    * scalar fields. The VTK output format has special provisions that allow
1930    * these components to be output by a single name rather than having to
1931    * group several scalar fields into a vector later on in the visualization
1932    * program.
1933    *
1934    * @note VTK is a legacy format and has largely been supplanted by the VTU
1935    * format (an XML-structured version of VTK). In particular, VTU allows for
1936    * the compression of data and consequently leads to much smaller file sizes
1937    * that equivalent VTK files for large files. Since all visualization
1938    * programs that support VTK also support VTU, you should consider using the
1939    * latter file format instead, by using the write_vtu() function.
1940    */
1941   template <int dim, int spacedim>
1942   void
1943   write_vtk(
1944     const std::vector<Patch<dim, spacedim>> &patches,
1945     const std::vector<std::string> &         data_names,
1946     const std::vector<
1947       std::tuple<unsigned int,
1948                  unsigned int,
1949                  std::string,
1950                  DataComponentInterpretation::DataComponentInterpretation>>
1951       &             nonscalar_data_ranges,
1952     const VtkFlags &flags,
1953     std::ostream &  out);
1954 
1955 
1956   /**
1957    * Write the given list of patches to the output stream in VTU format. The
1958    * data is written in the XML-based VTK format as opposed to the traditional
1959    * format that write_vtk() produces.
1960    *
1961    * The nonscalar_data_ranges argument denotes ranges of components in the
1962    * output that are considered a vector, rather than simply a collection of
1963    * scalar fields. The VTK output format has special provisions that allow
1964    * these components to be output by a single name rather than having to
1965    * group several scalar fields into a vector later on in the visualization
1966    * program.
1967    *
1968    * Some visualization programs, such as ParaView, can read several separate
1969    * VTU files to parallelize visualization. In that case, you need a
1970    * <code>.pvtu</code> file that describes which VTU files form a group. The
1971    * DataOutInterface::write_pvtu_record() function can generate such a
1972    * centralized record. Likewise, DataOutInterface::write_visit_record() does
1973    * the same for VisIt (although VisIt can also read <code>pvtu</code> records
1974    * since version 2.5.1). Finally, for time dependent problems, you may also
1975    * want to look at DataOutInterface::write_pvd_record()
1976    *
1977    * The use of this function is explained in step-40.
1978    */
1979   template <int dim, int spacedim>
1980   void
1981   write_vtu(
1982     const std::vector<Patch<dim, spacedim>> &patches,
1983     const std::vector<std::string> &         data_names,
1984     const std::vector<
1985       std::tuple<unsigned int,
1986                  unsigned int,
1987                  std::string,
1988                  DataComponentInterpretation::DataComponentInterpretation>>
1989       &             nonscalar_data_ranges,
1990     const VtkFlags &flags,
1991     std::ostream &  out);
1992 
1993   /**
1994    * This writes the header for the xml based vtu file format. This routine is
1995    * used internally together with DataOutInterface::write_vtu_footer() and
1996    * DataOutInterface::write_vtu_main() by DataOutBase::write_vtu().
1997    */
1998   void
1999   write_vtu_header(std::ostream &out, const VtkFlags &flags);
2000 
2001   /**
2002    * This function writes the footer for the xml based vtu file format. This
2003    * routine is used internally together with
2004    * DataOutInterface::write_vtu_header() and DataOutInterface::write_vtu_main()
2005    * by DataOutBase::write_vtu().
2006    */
2007   void
2008   write_vtu_footer(std::ostream &out);
2009 
2010   /**
2011    * This function writes the main part for the xml based vtu file format. This
2012    * routine is used internally together with
2013    * DataOutInterface::write_vtu_header() and
2014    * DataOutInterface::write_vtu_footer() by DataOutBase::write_vtu().
2015    */
2016   template <int dim, int spacedim>
2017   void
2018   write_vtu_main(
2019     const std::vector<Patch<dim, spacedim>> &patches,
2020     const std::vector<std::string> &         data_names,
2021     const std::vector<
2022       std::tuple<unsigned int,
2023                  unsigned int,
2024                  std::string,
2025                  DataComponentInterpretation::DataComponentInterpretation>>
2026       &             nonscalar_data_ranges,
2027     const VtkFlags &flags,
2028     std::ostream &  out);
2029 
2030   /**
2031    * Some visualization programs, such as ParaView, can read several separate
2032    * VTU files that all form part of the same simulation, in order to
2033    * parallelize visualization. In that case, you need a
2034    * <code>.pvtu</code> file that describes which VTU files (written, for
2035    * example, through the DataOutInterface::write_vtu() function) form a group.
2036    * The current function can generate such a centralized record.
2037    *
2038    * This function is typically not called by itself from user space, but
2039    * you may want to call it through DataOutInterface::write_pvtu_record()
2040    * since the DataOutInterface class has access to information that you
2041    * would have to provide to the current function by hand.
2042    *
2043    * In any case, whether this function is called directly or via
2044    * DataOutInterface::write_pvtu_record(), the central record file so
2045    * written contains a list of (scalar or vector) fields that describes which
2046    * fields can actually be found in the individual files that comprise the set
2047    * of parallel VTU files along with the names of these files. This function
2048    * gets the names and types of fields through the third and fourth
2049    * argument; you can determine these by hand, but in practice, this function
2050    * is most easily called by calling DataOutInterfaces::write_pvtu_record(),
2051    * which determines the last two arguments by calling
2052    * DataOutInterface::get_dataset_names() and
2053    * DataOutInterface::get_nonscalar_data_ranges() functions. The second
2054    * argument to this function specifies the names of the files that form the
2055    * parallel set.
2056    *
2057    * @note Use DataOutBase::write_vtu() and DataOutInterface::write_vtu()
2058    * for writing each piece. Also note that
2059    * only one parallel process needs to call the current function, listing the
2060    * names of the files written by all parallel processes.
2061    *
2062    * @note In order to tell Paraview to group together multiple
2063    * <code>pvtu</code> files that each describe one time step of a time
2064    * dependent simulation, see the DataOutBase::write_pvd_record()
2065    * function.
2066    *
2067    * @note Older versions of VisIt (before 2.5.1), can not read
2068    * <code>pvtu</code> records. However, it can read visit records as written
2069    * by the write_visit_record() function.
2070    */
2071   void
2072   write_pvtu_record(
2073     std::ostream &                  out,
2074     const std::vector<std::string> &piece_names,
2075     const std::vector<std::string> &data_names,
2076     const std::vector<
2077       std::tuple<unsigned int,
2078                  unsigned int,
2079                  std::string,
2080                  DataComponentInterpretation::DataComponentInterpretation>>
2081       &nonscalar_data_ranges);
2082 
2083   /**
2084    * In ParaView it is possible to visualize time-dependent data tagged with
2085    * the current integration time of a time dependent simulation. To use this
2086    * feature you need a <code>.pvd</code> file that describes which VTU or
2087    * PVTU file belongs to which timestep. This function writes a file that
2088    * provides this mapping, i.e., it takes a list of pairs each of which
2089    * indicates a particular time instant and the corresponding file that
2090    * contains the graphical data for this time instant.
2091    *
2092    * A typical use case, in program that computes a time dependent solution,
2093    * would be the following (<code>time</code> and <code>time_step</code> are
2094    * member variables of the class with types <code>double</code> and
2095    * <code>unsigned int</code>, respectively; the variable
2096    * <code>times_and_names</code> is of type
2097    * <code>std::vector@<std::pair@<double,std::string@> @></code>):
2098    *
2099    * @code
2100    * template <int dim>
2101    * void MyEquation<dim>::output_results () const
2102    * {
2103    *   DataOut<dim> data_out;
2104    *
2105    *   data_out.attach_dof_handler(dof_handler);
2106    *   data_out.add_data_vector(solution, "U");
2107    *   data_out.build_patches();
2108    *
2109    *   const std::string filename = "solution-" +
2110    *                                Utilities::int_to_string (timestep_n, 3) +
2111    *                                ".vtu";
2112    *   std::ofstream output(filename);
2113    *   data_out.write_vtu(output);
2114    *
2115    *   times_and_names.emplace_back (time, filename);
2116    *   std::ofstream pvd_output ("solution.pvd");
2117    *   DataOutBase::write_pvd_record (pvd_output, times_and_names);
2118    * }
2119    * @endcode
2120    *
2121    * @note See DataOutInterface::write_vtu, DataOutInterface::write_pvtu_record,
2122    * and DataOutInterface::write_vtu_in_parallel
2123    * for writing solutions at each timestep.
2124    *
2125    * @note The second element of each pair, i.e., the file in which the
2126    * graphical data for each time is stored, may itself be again a file that
2127    * references other files. For example, it could be the name for a
2128    * <code>.pvtu</code> file that references multiple parts of a parallel
2129    * computation.
2130    */
2131   void
2132   write_pvd_record(
2133     std::ostream &                                     out,
2134     const std::vector<std::pair<double, std::string>> &times_and_names);
2135 
2136   /**
2137    * This function is the exact equivalent of the write_pvtu_record() function
2138    * but for older versions of the VisIt visualization program and for one
2139    * visualization graph (or one time step only). See there for the purpose of
2140    * this function.
2141    *
2142    * This function is documented in the "Creating a master file for parallel"
2143    * section (section 5.7) of the "Getting data into VisIt" report that can be
2144    * found here:
2145    * https://wci.llnl.gov/codes/visit/2.0.0/GettingDataIntoVisIt2.0.0.pdf
2146    */
2147   void
2148   write_visit_record(std::ostream &                  out,
2149                      const std::vector<std::string> &piece_names);
2150 
2151   /**
2152    * This function is equivalent to the write_visit_record() above but for
2153    * multiple time steps. Here is an example of how the function would be
2154    * used:
2155    * @code
2156    * const unsigned int number_of_time_steps = 3;
2157    * std::vector<std::vector<std::string > > piece_names(number_of_time_steps);
2158    *
2159    * piece_names[0].emplace_back("subdomain_01.time_step_0.vtk");
2160    * piece_names[0].emplace_back("subdomain_02.time_step_0.vtk");
2161    *
2162    * piece_names[1].emplace_back("subdomain_01.time_step_1.vtk");
2163    * piece_names[1].emplace_back("subdomain_02.time_step_1.vtk");
2164    *
2165    * piece_names[2].emplace_back("subdomain_01.time_step_2.vtk");
2166    * piece_names[2].emplace_back("subdomain_02.time_step_2.vtk");
2167    *
2168    * std::ofstream visit_output ("solution.visit");
2169    *
2170    * DataOutBase::write_visit_record(visit_output, piece_names);
2171    * @endcode
2172    *
2173    * This function is documented in the "Creating a master file for parallel"
2174    * section (section 5.7) of the "Getting data into VisIt" report that can be
2175    * found here:
2176    * https://wci.llnl.gov/codes/visit/2.0.0/GettingDataIntoVisIt2.0.0.pdf
2177    */
2178   void
2179   write_visit_record(std::ostream &                               out,
2180                      const std::vector<std::vector<std::string>> &piece_names);
2181 
2182   /**
2183    * This function is equivalent to the write_visit_record() above but for
2184    * multiple time steps and with additional information about the time for
2185    * each timestep. Here is an example of how the function would be
2186    * used:
2187    * @code
2188    * const unsigned int number_of_time_steps = 3;
2189    * std::vector<std::pair<double,std::vector<std::string > > >
2190    * times_and_piece_names(number_of_time_steps);
2191    *
2192    * times_and_piece_names[0].first = 0.0;
2193    * times_and_piece_names[0].second.emplace_back("subdomain_01.time_step_0.vtk");
2194    * times_and_piece_names[0].second.emplace_back("subdomain_02.time_step_0.vtk");
2195    *
2196    * times_and_piece_names[1].first = 0.5;
2197    * times_and_piece_names[1].second.emplace_back("subdomain_01.time_step_1.vtk");
2198    * times_and_piece_names[1].second.emplace_back("subdomain_02.time_step_1.vtk");
2199    *
2200    * times_and_piece_names[2].first = 1.0;
2201    * times_and_piece_names[2].second.emplace_back("subdomain_01.time_step_2.vtk");
2202    * times_and_piece_names[2].second.emplace_back("subdomain_02.time_step_2.vtk");
2203    *
2204    * std::ofstream visit_output ("solution.visit");
2205    *
2206    * DataOutBase::write_visit_record(visit_output, times_and_piece_names);
2207    * @endcode
2208    *
2209    * This function is documented in the "Creating a master file for parallel"
2210    * section (section 5.7) of the "Getting data into VisIt" report that can be
2211    * found here:
2212    * https://wci.llnl.gov/codes/visit/2.0.0/GettingDataIntoVisIt2.0.0.pdf
2213    */
2214   void
2215   write_visit_record(
2216     std::ostream &out,
2217     const std::vector<std::pair<double, std::vector<std::string>>>
2218       &times_and_piece_names);
2219 
2220   /**
2221    * Write the given list of patches to the output stream in SVG format.
2222    *
2223    * SVG (Scalable Vector Graphics) is an XML-based vector image format
2224    * developed and maintained by the World Wide Web Consortium (W3C). This
2225    * function conforms to the latest specification SVG 1.1, released on August
2226    * 16, 2011. Controlling the graphic output is possible by setting or
2227    * clearing the respective flags (see the SvgFlags struct). At present, this
2228    * format only supports output for two-dimensional data, with values in the
2229    * third direction taken from a data vector.
2230    *
2231    * For the output, each patch is subdivided into four triangles which are
2232    * then written as polygons and filled with a linear color gradient. The
2233    * arising coloring of the patches visualizes the data values at the
2234    * vertices taken from the specified data vector. A colorbar can be drawn to
2235    * encode the coloring.
2236    *
2237    * @note This function is so far only implemented for two dimensions with an
2238    * additional dimension reserved for data information.
2239    */
2240   template <int spacedim>
2241   void
2242   write_svg(
2243     const std::vector<Patch<2, spacedim>> &patches,
2244     const std::vector<std::string> &       data_names,
2245     const std::vector<
2246       std::tuple<unsigned int,
2247                  unsigned int,
2248                  std::string,
2249                  DataComponentInterpretation::DataComponentInterpretation>>
2250       &             nonscalar_data_ranges,
2251     const SvgFlags &flags,
2252     std::ostream &  out);
2253 
2254   /**
2255    * Write the given list of patches to the output stream in deal.II
2256    * intermediate format. This is not a format understood by any other
2257    * graphics program, but is rather a direct dump of the intermediate
2258    * internal format used by deal.II. This internal format is generated by the
2259    * various classes that can generate output using the DataOutBase class, for
2260    * example from a finite element solution, and is then converted in the
2261    * present class to the final graphics format.
2262    *
2263    * Note that the intermediate format is what its name suggests: a direct
2264    * representation of internal data. It isn't standardized and will change
2265    * whenever we change our internal representation. You can only expect to
2266    * process files written in this format using the same version of deal.II
2267    * that was used for writing.
2268    *
2269    * The reason why we offer to write out this intermediate format is that it
2270    * can be read back into a deal.II program using the DataOutReader class,
2271    * which is helpful in at least two contexts: First, this can be used to
2272    * later generate graphical output in any other graphics format presently
2273    * understood; this way, it is not necessary to know at run-time which
2274    * output format is requested, or if multiple output files in different
2275    * formats are needed. Secondly, in contrast to almost all other graphics
2276    * formats, it is possible to merge several files that contain intermediate
2277    * format data, and generate a single output file from it, which may be
2278    * again in intermediate format or any of the final formats. This latter
2279    * option is most helpful for parallel programs: as demonstrated in the
2280    * step-17 example program, it is possible to let only one processor
2281    * generate the graphical output for the entire parallel program, but this
2282    * can become vastly inefficient if many processors are involved, because
2283    * the load is no longer balanced. The way out is to let each processor
2284    * generate intermediate graphical output for its chunk of the domain, and
2285    * the later merge the different files into one, which is an operation that
2286    * is much cheaper than the generation of the intermediate data.
2287    *
2288    * Intermediate format deal.II data is usually stored in files with the
2289    * ending <tt>.d2</tt>.
2290    */
2291   template <int dim, int spacedim>
2292   void
2293   write_deal_II_intermediate(
2294     const std::vector<Patch<dim, spacedim>> &patches,
2295     const std::vector<std::string> &         data_names,
2296     const std::vector<
2297       std::tuple<unsigned int,
2298                  unsigned int,
2299                  std::string,
2300                  DataComponentInterpretation::DataComponentInterpretation>>
2301       &                              nonscalar_data_ranges,
2302     const Deal_II_IntermediateFlags &flags,
2303     std::ostream &                   out);
2304 
2305   /**
2306    * Write the data in @p data_filter to a single HDF5 file containing both the
2307    * mesh and solution values.
2308    */
2309   template <int dim, int spacedim>
2310   void
2311   write_hdf5_parallel(const std::vector<Patch<dim, spacedim>> &patches,
2312                       const DataOutFilter &                    data_filter,
2313                       const std::string &                      filename,
2314                       MPI_Comm                                 comm);
2315 
2316   /**
2317    * Write the data in @p data_filter to HDF5 file(s). If @p write_mesh_file is
2318    * false, the mesh data will not be written and the solution file will
2319    * contain only the solution values. If @p write_mesh_file is true and the
2320    * filenames are the same, the resulting file will contain both mesh data
2321    * and solution values.
2322    */
2323   template <int dim, int spacedim>
2324   void
2325   write_hdf5_parallel(const std::vector<Patch<dim, spacedim>> &patches,
2326                       const DataOutFilter &                    data_filter,
2327                       const bool                               write_mesh_file,
2328                       const std::string &                      mesh_filename,
2329                       const std::string &solution_filename,
2330                       MPI_Comm           comm);
2331 
2332   /**
2333    * DataOutFilter is an intermediate data format that reduces the amount of
2334    * data that will be written to files. The object filled by this function
2335    * can then later be used again to write data in a concrete file format;
2336    * see, for example, DataOutBase::write_hdf5_parallel().
2337    */
2338   template <int dim, int spacedim>
2339   void
2340   write_filtered_data(
2341     const std::vector<Patch<dim, spacedim>> &patches,
2342     const std::vector<std::string> &         data_names,
2343     const std::vector<
2344       std::tuple<unsigned int,
2345                  unsigned int,
2346                  std::string,
2347                  DataComponentInterpretation::DataComponentInterpretation>>
2348       &            nonscalar_data_ranges,
2349     DataOutFilter &filtered_data);
2350 
2351   /**
2352    * Given an input stream that contains data written by
2353    * write_deal_II_intermediate(), determine the <tt>dim</tt> and
2354    * <tt>spacedim</tt> template parameters with which that function was
2355    * called, and return them as a pair of values.
2356    *
2357    * Note that this function eats a number of elements at the present position
2358    * of the stream, and therefore alters it. In order to read from it using,
2359    * for example, the DataOutReader class, you may wish to either reset the
2360    * stream to its previous position, or close and reopen it.
2361    */
2362   std::pair<unsigned int, unsigned int>
2363   determine_intermediate_format_dimensions(std::istream &input);
2364 
2365   /**
2366    * Return the OutputFormat value corresponding to the given string. If the
2367    * string does not match any known format, an exception is thrown.
2368    *
2369    * The main purpose of this function is to allow a program to use any
2370    * implemented output format without the need to extend the program's parser
2371    * each time a new format is implemented.
2372    *
2373    * To get a list of presently available format names, e.g. to give it to the
2374    * ParameterHandler class, use the function get_output_format_names().
2375    */
2376   OutputFormat
2377   parse_output_format(const std::string &format_name);
2378 
2379   /**
2380    * Return a list of implemented output formats. The different names are
2381    * separated by vertical bar signs (<tt>`|'</tt>) as used by the
2382    * ParameterHandler classes.
2383    */
2384   std::string
2385   get_output_format_names();
2386 
2387   /**
2388    * Provide a function which tells us which suffix a file with a given output
2389    * format usually has. At present the following formats are defined:
2390    * <ul>
2391    * <li> <tt>dx</tt>: <tt>.dx</tt>
2392    * <li> <tt>ucd</tt>: <tt>.inp</tt>
2393    * <li> <tt>gnuplot</tt>: <tt>.gnuplot</tt>
2394    * <li> <tt>povray</tt>: <tt>.pov</tt>
2395    * <li> <tt>eps</tt>: <tt>.eps</tt>
2396    * <li> <tt>gmv</tt>: <tt>.gmv</tt>
2397    * <li> <tt>tecplot</tt>: <tt>.dat</tt>
2398    * <li> <tt>tecplot_binary</tt>: <tt>.plt</tt>
2399    * <li> <tt>vtk</tt>: <tt>.vtk</tt>
2400    * <li> <tt>vtu</tt>: <tt>.vtu</tt>
2401    * <li> <tt>svg</tt>: <tt>.svg</tt>
2402    * <li> <tt>deal_II_intermediate</tt>: <tt>.d2</tt>.
2403    * </ul>
2404    *
2405    * @deprecated Using Tecplot binary output is deprecated.
2406    */
2407   std::string
2408   default_suffix(const OutputFormat output_format);
2409 
2410   /**
2411    * @addtogroup Exceptions
2412    * @{
2413    */
2414 
2415   /**
2416    * Exception
2417    */
2418   DeclException2(ExcInvalidDatasetSize,
2419                  int,
2420                  int,
2421                  << "The number of points in this data set is " << arg1
2422                  << ", but we expected " << arg2
2423                  << " in each space direction.");
2424   /**
2425    * An output function did not receive any patches for writing.
2426    */
2427   DeclExceptionMsg(ExcNoPatches,
2428                    "You are trying to write graphical data into a file, but "
2429                    "no data is available in the intermediate format that "
2430                    "the DataOutBase functions require. Did you forget to "
2431                    "call a function such as DataOut::build_patches()?");
2432   /**
2433    * Exception
2434    */
2435   DeclExceptionMsg(ExcTecplotAPIError,
2436                    "The error code of one of the Tecplot functions was "
2437                    "not zero as expected.");
2438   /**
2439    * Exception
2440    */
2441   DeclException1(ExcErrorOpeningTecplotFile,
2442                  char *,
2443                  << "There was an error opening Tecplot file " << arg1
2444                  << " for output.");
2445 
2446   //@}
2447 } // namespace DataOutBase
2448 
2449 
2450 
2451 /**
2452  * This class is the interface to the functions in the DataOutBase namespace,
2453  * as already its name might suggest. It does not offer much functionality
2454  * apart from a way to access the implemented formats and a way to dynamically
2455  * dispatch what output format to chose.
2456  *
2457  * This class is thought as a base class to classes actually generating data
2458  * for output. It has two abstract virtual functions, get_patches() and
2459  * get_dataset_names() produce the data which is actually needed. These are
2460  * the only functions that need to be overloaded by a derived class.  In
2461  * additional to that, it has a function for each output format supported by
2462  * the underlying base class which gets the output data using these two
2463  * virtual functions and passes them to the raw output functions.
2464  *
2465  * The purpose of this class is mainly two-fold: to support storing flags by
2466  * which the output in the different output formats are controlled, and means
2467  * to work with output in a way where output format, flags and other things
2468  * are determined at run time. In addition to that it offers the abstract
2469  * interface to derived classes briefly discussed above.
2470  *
2471  *
2472  * <h3>Output flags</h3>
2473  *
2474  * The way we treat flags in this class is very similar to that used in the
2475  * <tt>GridOut</tt> class. For detailed information on the why's and how's, as
2476  * well as an example of programming, we refer to the documentation of that
2477  * class.
2478  *
2479  * Basically, this class stores a set of flags for each output format
2480  * supported by the underlying <tt>DataOutBase</tt> class. These are used
2481  * whenever one of the <tt>write_*</tt> functions is used. By default, the
2482  * values of these flags are set to reasonable start-ups, but in case you want
2483  * to change them, you can create a structure holding the flags for one of the
2484  * output formats and set it using the <tt>set_flags</tt> functions of this
2485  * class to determine all future output the object might produce by that
2486  * output format.
2487  *
2488  * For information on what parameters are supported by different output
2489  * functions, please see the documentation of the <tt>DataOutBase</tt> class
2490  * and its member classes.
2491  *
2492  *
2493  * <h3>Run time selection of output parameters</h3>
2494  *
2495  * In the output flags classes, described above, many flags are defined for
2496  * output in the different formats. In order to make them available to the
2497  * input file handler class <tt>ParameterHandler</tt>, each of these has a
2498  * function declaring these flags to the parameter handler and to read them
2499  * back from an actual input file. In order to avoid that in user programs
2500  * these functions have to be called for each available output format and the
2501  * respective flag class, the present <tt>DataOutInterface</tt> class offers a
2502  * function <tt>declare_parameters</tt> which calls the respective function of
2503  * all known output format flags classes. The flags of each such format are
2504  * packed together in a subsection in the input file. Likewise, there is a
2505  * function <tt>parse_parameters</tt> which reads these parameters and stores
2506  * them in the flags associated with this object (see above).
2507  *
2508  * Using these functions, you do not have to track which formats are presently
2509  * implemented.
2510  *
2511  * Usage is as follows:
2512  * @code
2513  *   // within function declaring parameters:
2514  *   prm.enter_subsection("Output format options");
2515  *   DataOutInterface<dim>::declare_parameters(prm);
2516  *   prm.leave_subsection();
2517  *
2518  *   ...
2519  *   // within function doing the output:
2520  *   DataOut<dim> out;
2521  *   prm.enter_subsection("Output format options");
2522  *   out.parse_parameters(prm);
2523  *   prm.leave_subsection();
2524  * @endcode
2525  * Note that in the present example, the class <tt>DataOut</tt> was used.
2526  * However, any other class derived from <tt>DataOutInterface</tt> would work
2527  * alike.
2528  *
2529  *
2530  * <h3>Run time selection of formats</h3>
2531  *
2532  * This class, much like the <tt>GridOut</tt> class, has a set of functions
2533  * providing a list of supported output formats, an <tt>enum</tt> denoting all
2534  * these and a function to parse a string and return the respective
2535  * <tt>enum</tt> value if it is a valid output format's name (actually, these
2536  * functions are inherited from the base class). Finally, there is a function
2537  * <tt>write</tt>, which takes a value of this <tt>enum</tt> and dispatches to
2538  * one of the actual <tt>write_*</tt> functions depending on the output format
2539  * selected by this value.
2540  *
2541  * The functions offering the different output format names are, respectively,
2542  * <tt>default_suffix</tt>, <tt>parse_output_format</tt>, and
2543  * <tt>get_output_format_names</tt>. They make the selection of output formats
2544  * in parameter files much easier, and especially independent of the formats
2545  * presently implemented. User programs need therefore not be changed whenever
2546  * a new format is implemented.
2547  *
2548  * Additionally, objects of this class have a default format, which can be set
2549  * by the parameter "Output format" of the parameter file. Within a program,
2550  * this can be changed by the member function <tt>set_default_format</tt>.
2551  * Using this default format, it is possible to leave the format selection
2552  * completely to the parameter file. A suitable suffix for the output file
2553  * name can be obtained by <tt>default_suffix</tt> without arguments.
2554  *
2555  * @ingroup output
2556  */
2557 template <int dim, int spacedim = dim>
2558 class DataOutInterface
2559 {
2560 public:
2561   /**
2562    * Constructor.
2563    */
2564   DataOutInterface();
2565 
2566   /**
2567    * Destructor. Does nothing, but is declared virtual since this class has
2568    * virtual functions.
2569    */
2570   virtual ~DataOutInterface() = default;
2571 
2572   /**
2573    * Obtain data through get_patches() and write it to <tt>out</tt> in OpenDX
2574    * format. See DataOutBase::write_dx.
2575    */
2576   void
2577   write_dx(std::ostream &out) const;
2578 
2579   /**
2580    * Obtain data through get_patches() and write it to <tt>out</tt> in EPS
2581    * format. See DataOutBase::write_eps.
2582    */
2583   void
2584   write_eps(std::ostream &out) const;
2585 
2586   /**
2587    * Obtain data through get_patches() and write it to <tt>out</tt> in GMV
2588    * format. See DataOutBase::write_gmv.
2589    */
2590   void
2591   write_gmv(std::ostream &out) const;
2592 
2593   /**
2594    * Obtain data through get_patches() and write it to <tt>out</tt> in GNUPLOT
2595    * format. See DataOutBase::write_gnuplot.
2596    */
2597   void
2598   write_gnuplot(std::ostream &out) const;
2599 
2600   /**
2601    * Obtain data through get_patches() and write it to <tt>out</tt> in POVRAY
2602    * format. See DataOutBase::write_povray.
2603    */
2604   void
2605   write_povray(std::ostream &out) const;
2606 
2607   /**
2608    * Obtain data through get_patches() and write it to <tt>out</tt> in Tecplot
2609    * format. See DataOutBase::write_tecplot.
2610    */
2611   void
2612   write_tecplot(std::ostream &out) const;
2613 
2614   /**
2615    * Obtain data through get_patches() and write it to <tt>out</tt> in UCD
2616    * format for AVS. See DataOutBase::write_ucd.
2617    */
2618   void
2619   write_ucd(std::ostream &out) const;
2620 
2621   /**
2622    * Obtain data through get_patches() and write it to <tt>out</tt> in Vtk
2623    * format. See DataOutBase::write_vtk.
2624    *
2625    * @note VTK is a legacy format and has largely been supplanted by the VTU
2626    * format (an XML-structured version of VTK). In particular, VTU allows for
2627    * the compression of data and consequently leads to much smaller file sizes
2628    * that equivalent VTK files for large files. Since all visualization
2629    * programs that support VTK also support VTU, you should consider using the
2630    * latter file format instead, by using the write_vtu() function.
2631    */
2632   void
2633   write_vtk(std::ostream &out) const;
2634 
2635   /**
2636    * Obtain data through get_patches() and write it to <tt>out</tt> in Vtu
2637    * (VTK's XML) format. See DataOutBase::write_vtu.
2638    *
2639    * Some visualization programs, such as ParaView, can read several separate
2640    * VTU files to parallelize visualization. In that case, you need a
2641    * <code>.pvtu</code> file that describes which VTU files form a group. The
2642    * DataOutInterface::write_pvtu_record() function can generate such a
2643    * centralized record. Likewise, DataOutInterface::write_visit_record() does
2644    * the same for older versions of VisIt (although VisIt can also read
2645    * <code>pvtu</code> records since version 2.5.1). Finally,
2646    * DataOutInterface::write_pvd_record() can be used to group together the
2647    * files that jointly make up a time dependent simulation.
2648    */
2649   void
2650   write_vtu(std::ostream &out) const;
2651 
2652   /**
2653    * Collective MPI call to write the solution from all participating nodes
2654    * (those in the given communicator) to a single compressed .vtu file on a
2655    * shared file system.  The communicator can be a sub communicator of the
2656    * one used by the computation.  This routine uses MPI I/O to achieve high
2657    * performance on parallel filesystems. Also see
2658    * DataOutInterface::write_vtu().
2659    */
2660   void
2661   write_vtu_in_parallel(const std::string &filename, MPI_Comm comm) const;
2662 
2663   /**
2664    * Some visualization programs, such as ParaView, can read several separate
2665    * VTU files that all form part of the same simulation, in order to
2666    * parallelize visualization. In that case, you need a
2667    * <code>.pvtu</code> file that describes which VTU files (written, for
2668    * example, through the DataOutInterface::write_vtu() function) form a group.
2669    * The current function can generate such a centralized record.
2670    *
2671    * The central record file generated by this function
2672    * contains a list of (scalar or vector) fields that describes which
2673    * fields can actually be found in the individual files that comprise the set
2674    * of parallel VTU files along with the names of these files. This function
2675    * gets the names and types of fields through the get_dataset_names() and
2676    * get_nonscalar_data_ranges() functions of this class. The second argument
2677    * to this function specifies the names of the files that form the parallel
2678    * set.
2679    *
2680    * @note Use DataOutBase::write_vtu() and DataOutInterface::write_vtu()
2681    * for writing each piece. Also note that
2682    * only one parallel process needs to call the current function, listing the
2683    * names of the files written by all parallel processes.
2684    *
2685    * @note The use of this function is explained in step-40.
2686    *
2687    * @note In order to tell Paraview to group together multiple
2688    * <code>pvtu</code> files that each describe one time step of a time
2689    * dependent simulation, see the DataOutBase::write_pvd_record()
2690    * function.
2691    *
2692    * @note Older versions of VisIt (before 2.5.1), can not read
2693    * <code>pvtu</code> records. However, it can read visit records as written
2694    * by the write_visit_record() function.
2695    */
2696   void
2697   write_pvtu_record(std::ostream &                  out,
2698                     const std::vector<std::string> &piece_names) const;
2699 
2700   /**
2701    * This function writes several .vtu files and a .pvtu record in parallel
2702    * and constructs the filenames automatically. It is a combination of
2703    * DataOutInterface::write_vtu() or
2704    * DataOutInterface::write_vtu_in_parallel(), and
2705    * DataOutInterface::write_pvtu_record().
2706    *
2707    * For example, running
2708    * <code> write_vtu_with_pvtu_record("output/", "solution", 3, comm, 4, 2)
2709    * </code> on 10 processes generates the files
2710    * @code
2711    * output/solution_0003.0.vtu
2712    * output/solution_0003.1.vtu
2713    * output/solution_0003.pvtu
2714    * @endcode
2715    * where the `.0.vtu` file contains the output of the first half of the
2716    * processes grouped together, and the `.1.vtu` the data from the remaining
2717    * half.
2718    *
2719    * A specified @p directory and a @p filename_without_extension
2720    * form the first part of the filename. The filename is then extended with
2721    * a @p counter labeling the current timestep/iteration/etc., the processor ID,
2722    * and finally the .vtu/.pvtu ending. Since the number of timesteps to be
2723    * written depends on the application, the number of digits to be reserved in
2724    * the filename can be specified as parameter @p n_digits_for_counter, and the number
2725    * is not padded with leading zeros if this parameter is left at its default
2726    * value numbers::invalid_unsigned_int. If more than one file identifier
2727    * is needed (e.g. time step number and iteration counter of solver), the
2728    * last identifier is used as @p counter, while all other identifiers have to be
2729    * added to @p filename_without_extension when calling this function.
2730    *
2731    * In a
2732    * parallel setting, several files are typically written per time step. The
2733    * number of files written in parallel depends on the number of MPI processes
2734    * (see parameter @p mpi_communicator), and a
2735    * specified number of @p n_groups with default value 0. The background is that
2736    * VTU file output supports grouping files from several CPUs into a given
2737    * number of files using MPI I/O when writing on a parallel filesystem. The
2738    * default value of @p n_groups is 0, meaning that every MPI rank will write one
2739    * file. A value of 1 will generate one big file containing the solution over
2740    * the whole domain, while a larger value will create @p n_groups files (but not
2741    * more than there are MPI ranks).
2742    *
2743    * Note that only one processor needs to
2744    * generate the .pvtu file, where processor zero is chosen to take over this
2745    * job.
2746    *
2747    * The return value is the filename of the centralized file for the pvtu
2748    * record.
2749    *
2750    * @note The code simply combines the strings @p directory and
2751    * @p filename_without_extension, i.e., the user has to make sure that
2752    * @p directory contains a trailing character, e.g. "/", that separates the
2753    * directory from the filename.
2754    *
2755    * @note Use an empty string "" for the first argument if output is to be
2756    * written in the current working directory.
2757    */
2758   std::string
2759   write_vtu_with_pvtu_record(
2760     const std::string &directory,
2761     const std::string &filename_without_extension,
2762     const unsigned int counter,
2763     const MPI_Comm &   mpi_communicator,
2764     const unsigned int n_digits_for_counter = numbers::invalid_unsigned_int,
2765     const unsigned int n_groups             = 0) const;
2766 
2767   /**
2768    * Obtain data through get_patches() and write it to <tt>out</tt> in SVG
2769    * format. See DataOutBase::write_svg.
2770    */
2771   void
2772   write_svg(std::ostream &out) const;
2773 
2774   /**
2775    * Obtain data through get_patches() and write it to <tt>out</tt> in deal.II
2776    * intermediate format. See DataOutBase::write_deal_II_intermediate.
2777    *
2778    * Note that the intermediate format is what its name suggests: a direct
2779    * representation of internal data. It isn't standardized and will change
2780    * whenever we change our internal representation. You can only expect to
2781    * process files written in this format using the same version of deal.II
2782    * that was used for writing.
2783    */
2784   void
2785   write_deal_II_intermediate(std::ostream &out) const;
2786 
2787   /**
2788    * Create an XDMFEntry based on the data in the data_filter. This assumes
2789    * the mesh and solution data were written to a single file. See
2790    * write_xdmf_file() for an example of usage.
2791    */
2792   XDMFEntry
2793   create_xdmf_entry(const DataOutBase::DataOutFilter &data_filter,
2794                     const std::string &               h5_filename,
2795                     const double                      cur_time,
2796                     MPI_Comm                          comm) const;
2797 
2798   /**
2799    * Create an XDMFEntry based on the data in the data_filter. This assumes
2800    * the mesh and solution data were written to separate files. See
2801    * write_xdmf_file() for an example of usage.
2802    */
2803   XDMFEntry
2804   create_xdmf_entry(const DataOutBase::DataOutFilter &data_filter,
2805                     const std::string &               h5_mesh_filename,
2806                     const std::string &               h5_solution_filename,
2807                     const double                      cur_time,
2808                     MPI_Comm                          comm) const;
2809 
2810   /**
2811    * Write an XDMF file based on the provided vector of XDMFEntry objects.
2812    * Below is an example of how to use this function with HDF5 and the
2813    * DataOutFilter:
2814    *
2815    * @code
2816    * DataOutBase::DataOutFilterFlags flags(true, true);
2817    * DataOutBase::DataOutFilter data_filter(flags);
2818    * std::vector<XDMFEntry> xdmf_entries;
2819    * // Filter the data and store it in data_filter
2820    * data_out.write_filtered_data(data_filter);
2821    * // Write the filtered data to HDF5
2822    * data_out.write_hdf5_parallel(data_filter, "solution.h5", MPI_COMM_WORLD);
2823    * // Create an XDMF entry detailing the HDF5 file
2824    * auto new_xdmf_entry = data_out.create_xdmf_entry(data_filter,
2825    *                                                  "solution.h5",
2826    *                                                  simulation_time,
2827    *                                                  MPI_COMM_WORLD);
2828    * // Add the XDMF entry to the list
2829    * xdmf_entries.push_back(new_xdmf_entry);
2830    * // Create an XDMF file from all stored entries
2831    * data_out.write_xdmf_file(xdmf_entries, "solution.xdmf", MPI_COMM_WORLD);
2832    * @endcode
2833    */
2834   void
2835   write_xdmf_file(const std::vector<XDMFEntry> &entries,
2836                   const std::string &           filename,
2837                   MPI_Comm                      comm) const;
2838 
2839   /**
2840    * Write the data in @p data_filter to a single HDF5 file containing both the
2841    * mesh and solution values. Below is an example of how to use this function
2842    * with the DataOutFilter:
2843    *
2844    * @code
2845    * DataOutBase::DataOutFilterFlags flags(true, true);
2846    * DataOutBase::DataOutFilter data_filter(flags);
2847    * // Filter the data and store it in data_filter
2848    * data_out.write_filtered_data(data_filter);
2849    * // Write the filtered data to HDF5
2850    * data_out.write_hdf5_parallel(data_filter, "solution.h5", MPI_COMM_WORLD);
2851    * @endcode
2852    */
2853   void
2854   write_hdf5_parallel(const DataOutBase::DataOutFilter &data_filter,
2855                       const std::string &               filename,
2856                       MPI_Comm                          comm) const;
2857 
2858   /**
2859    * Write the data in data_filter to HDF5 file(s). If write_mesh_file is
2860    * false, the mesh data will not be written and the solution file will
2861    * contain only the solution values. If write_mesh_file is true and the
2862    * filenames are the same, the resulting file will contain both mesh data
2863    * and solution values.
2864    */
2865   void
2866   write_hdf5_parallel(const DataOutBase::DataOutFilter &data_filter,
2867                       const bool                        write_mesh_file,
2868                       const std::string &               mesh_filename,
2869                       const std::string &               solution_filename,
2870                       MPI_Comm                          comm) const;
2871 
2872   /**
2873    * DataOutFilter is an intermediate data format that reduces the amount of
2874    * data that will be written to files. The object filled by this function
2875    * can then later be used again to write data in a concrete file format;
2876    * see, for example, DataOutBase::write_hdf5_parallel().
2877    */
2878   void
2879   write_filtered_data(DataOutBase::DataOutFilter &filtered_data) const;
2880 
2881 
2882   /**
2883    * Write data and grid to <tt>out</tt> according to the given data format.
2884    * This function simply calls the appropriate <tt>write_*</tt> function. If
2885    * no output format is requested, the <tt>default_format</tt> is written.
2886    *
2887    * An error occurs if no format is provided and the default format is
2888    * <tt>default_format</tt>.
2889    */
2890   void
2891   write(std::ostream &                  out,
2892         const DataOutBase::OutputFormat output_format =
2893           DataOutBase::default_format) const;
2894 
2895   /**
2896    * Set the default format. The value set here is used anytime, output for
2897    * format <tt>default_format</tt> is requested.
2898    */
2899   void
2900   set_default_format(const DataOutBase::OutputFormat default_format);
2901 
2902 
2903   /**
2904    * Set the flags to be used for output. This method expects <tt>flags</tt>
2905    * to be a member of one of the child classes of <tt>OutputFlagsBase</tt>.
2906    */
2907   template <typename FlagType>
2908   void
2909   set_flags(const FlagType &flags);
2910 
2911 
2912   /**
2913    * A function that returns the same string as the respective function in the
2914    * base class does; the only exception being that if the parameter is
2915    * omitted, then the value for the present default format is returned, i.e.
2916    * the correct suffix for the format that was set through
2917    * set_default_format() or parse_parameters() before calling this function.
2918    */
2919   std::string
2920   default_suffix(const DataOutBase::OutputFormat output_format =
2921                    DataOutBase::default_format) const;
2922 
2923   /**
2924    * Declare parameters for all output formats by declaring subsections within
2925    * the parameter file for each output format and call the respective
2926    * <tt>declare_parameters</tt> functions of the flag classes for each output
2927    * format.
2928    *
2929    * Some of the declared subsections may not contain entries, if the
2930    * respective format does not export any flags.
2931    *
2932    * Note that the top-level parameters denoting the number of subdivisions
2933    * per patch and the output format are not declared, since they are only
2934    * passed to virtual functions and are not stored inside objects of this
2935    * type. You have to declare them yourself.
2936    */
2937   static void
2938   declare_parameters(ParameterHandler &prm);
2939 
2940   /**
2941    * Read the parameters declared in declare_parameters() and set the flags
2942    * for the output formats accordingly.
2943    *
2944    * The flags thus obtained overwrite all previous contents of the flag
2945    * objects as default-constructed or set by the set_flags() function.
2946    */
2947   void
2948   parse_parameters(ParameterHandler &prm);
2949 
2950   /**
2951    * Return an estimate for the memory consumption, in bytes, of this object.
2952    * This is not exact (but will usually be close) because calculating the
2953    * memory usage of trees (e.g., <tt>std::map</tt>) is difficult.
2954    */
2955   std::size_t
2956   memory_consumption() const;
2957 
2958 protected:
2959   /**
2960    * This is the abstract function through which derived classes propagate
2961    * preprocessed data in the form of Patch structures (declared in the base
2962    * class DataOutBase) to the actual output function. You need to overload
2963    * this function to allow the output functions to know what they shall
2964    * print.
2965    */
2966   virtual const std::vector<DataOutBase::Patch<dim, spacedim>> &
2967   get_patches() const = 0;
2968 
2969   /**
2970    * Abstract virtual function through which the names of data sets are
2971    * obtained by the output functions of the base class.
2972    */
2973   virtual std::vector<std::string>
2974   get_dataset_names() const = 0;
2975 
2976   /**
2977    * This functions returns information about how the individual components of
2978    * output files that consist of more than one data set are to be
2979    * interpreted.
2980    *
2981    * It returns a list of index pairs and corresponding name and type indicating
2982    * which components of the output are to be considered vector- or
2983    * tensor-valued rather than just a collection of scalar data. The index pairs
2984    * are inclusive; for example, if we have a Stokes problem in 2d with
2985    * components (u,v,p), then the corresponding vector data range should be
2986    * (0,1), and the returned list would consist of only a single element with a
2987    * tuple such as (0,1,"velocity",component_is_part_of_vector).
2988    *
2989    * Since some of the derived classes do not know about non-scalar data, this
2990    * function has a default implementation that simply returns an empty
2991    * string, meaning that all data is to be considered a collection of scalar
2992    * fields.
2993    */
2994   virtual std::vector<
2995     std::tuple<unsigned int,
2996                unsigned int,
2997                std::string,
2998                DataComponentInterpretation::DataComponentInterpretation>>
2999   get_nonscalar_data_ranges() const;
3000 
3001   /**
3002    * Validate that the names of the datasets returned by get_dataset_names() and
3003    * get_nonscalar_data_ranges() are valid. This currently consists of checking
3004    * that names are not used more than once. If an invalid state is encountered,
3005    * an Assert() will be triggered in debug mode.
3006    */
3007   void
3008   validate_dataset_names() const;
3009 
3010 
3011   /**
3012    * The default number of subdivisions for patches. This is filled by
3013    * parse_parameters() and should be obeyed by build_patches() in derived
3014    * classes.
3015    */
3016   unsigned int default_subdivisions;
3017 
3018 private:
3019   /**
3020    * Standard output format.  Use this format, if output format default_format
3021    * is requested. It can be changed by the <tt>set_format</tt> function or in
3022    * a parameter file.
3023    */
3024   DataOutBase::OutputFormat default_fmt;
3025 
3026   /**
3027    * Flags to be used upon output of OpenDX data. Can be changed by using the
3028    * <tt>set_flags</tt> function.
3029    */
3030   DataOutBase::DXFlags dx_flags;
3031 
3032   /**
3033    * Flags to be used upon output of UCD data. Can be changed by using the
3034    * <tt>set_flags</tt> function.
3035    */
3036   DataOutBase::UcdFlags ucd_flags;
3037 
3038   /**
3039    * Flags to be used upon output of GNUPLOT data. Can be changed by using the
3040    * <tt>set_flags</tt> function.
3041    */
3042   DataOutBase::GnuplotFlags gnuplot_flags;
3043 
3044   /**
3045    * Flags to be used upon output of POVRAY data. Can be changed by using the
3046    * <tt>set_flags</tt> function.
3047    */
3048   DataOutBase::PovrayFlags povray_flags;
3049 
3050   /**
3051    * Flags to be used upon output of EPS data in one space dimension. Can be
3052    * changed by using the <tt>set_flags</tt> function.
3053    */
3054   DataOutBase::EpsFlags eps_flags;
3055 
3056   /**
3057    * Flags to be used upon output of gmv data in one space dimension. Can be
3058    * changed by using the <tt>set_flags</tt> function.
3059    */
3060   DataOutBase::GmvFlags gmv_flags;
3061 
3062   /**
3063    * Flags to be used upon output of Tecplot data in one space dimension. Can
3064    * be changed by using the <tt>set_flags</tt> function.
3065    */
3066   DataOutBase::TecplotFlags tecplot_flags;
3067 
3068   /**
3069    * Flags to be used upon output of vtk data in one space dimension. Can be
3070    * changed by using the <tt>set_flags</tt> function.
3071    */
3072   DataOutBase::VtkFlags vtk_flags;
3073 
3074   /**
3075    * Flags to be used upon output of svg data in one space dimension. Can be
3076    * changed by using the <tt>set_flags</tt> function.
3077    */
3078   DataOutBase::SvgFlags svg_flags;
3079 
3080   /**
3081    * Flags to be used upon output of deal.II intermediate data in one space
3082    * dimension. Can be changed by using the <tt>set_flags</tt> function.
3083    */
3084   DataOutBase::Deal_II_IntermediateFlags deal_II_intermediate_flags;
3085 };
3086 
3087 
3088 
3089 /**
3090  * A class that is used to read data written in deal.II intermediate format
3091  * back in, so that it can be written out in any of the other supported
3092  * graphics formats. This class has two main purposes:
3093  *
3094  * The first use of this class is so that application programs can defer the
3095  * decision of which graphics format to use until after the program has been
3096  * run. The data is written in intermediate format into a file, and later on
3097  * it can then be converted into any graphics format you wish. This may be
3098  * useful, for example, if you want to convert it to gnuplot format to get a
3099  * quick glimpse and later on want to convert it to OpenDX format as well to
3100  * get a high quality version of the data. The present class allows to read
3101  * this intermediate format back into the program, and allows it to be written
3102  * in any other supported format using the relevant functions of the base
3103  * class.
3104  *
3105  * The second use is mostly useful in parallel programs: rather than having
3106  * one central process generate the graphical output for the entire program,
3107  * one can let each process generate the graphical data for the cells it owns,
3108  * and write it into a separate file in intermediate format. Later on, all
3109  * these intermediate files can then be read back in and merged together, a
3110  * process that is fast compared to generating the data in the first place.
3111  * The use of the intermediate format is mostly because it allows separate
3112  * files to be merged, while this is almost impossible once the data has been
3113  * written out in any of the supported established graphics formats.
3114  *
3115  * This second use scenario is explained in some detail in the step-18 example
3116  * program.
3117  *
3118  * In order to read data back into this object, you have to know the template
3119  * parameters for the space dimension which were used when writing the
3120  * data. If this knowledge is available at compile time, then this is no
3121  * problem. However, if it is not (such as in a simple format converter), then
3122  * it needs to be figured out at run time, even though the compiler already
3123  * needs it at compile time. A way around using the
3124  * DataOutBase::determine_intermediate_format_dimensions() function.
3125  *
3126  * Note that the intermediate format is what its name suggests: a direct
3127  * representation of internal data. It isn't standardized and will change
3128  * whenever we change our internal representation. You can only expect to
3129  * process files written in this format using the same version of deal.II that
3130  * was used for writing.
3131  *
3132  * @ingroup input output
3133  */
3134 template <int dim, int spacedim = dim>
3135 class DataOutReader : public DataOutInterface<dim, spacedim>
3136 {
3137 public:
3138   /**
3139    * Read a sequence of patches as written previously by
3140    * <tt>DataOutBase::write_deal_II_intermediate</tt> and store them in the
3141    * present object. This overwrites any previous content.
3142    */
3143   void
3144   read(std::istream &in);
3145 
3146   /**
3147    * This function can be used to merge the patches read by the other object
3148    * into the patches that this present object stores. This is sometimes handy
3149    * if one has, for example, a domain decomposition algorithm where each
3150    * block is represented by a DoFHandler of its own, but one wants to output
3151    * the solution on all the blocks at the same time. Alternatively, it may
3152    * also be used for parallel programs, where each process only generates
3153    * output for its share of the cells, even if all processes can see all
3154    * cells.
3155    *
3156    * For this to work, the input files for the present object and the given
3157    * argument need to have the same number of output vectors, and they need to
3158    * use the same number of subdivisions per patch. The output will probably
3159    * look rather funny if patches in both objects overlap in space.
3160    *
3161    * If you call read() for this object after merging in patches, the previous
3162    * state is overwritten, and the merged-in patches are lost.
3163    *
3164    * This function will fail if either this or the other object did not yet
3165    * set up any patches.
3166    */
3167   void
3168   merge(const DataOutReader<dim, spacedim> &other);
3169 
3170   /**
3171    * Exception
3172    */
3173   DeclExceptionMsg(ExcIncompatibleDatasetNames,
3174                    "You are trying to merge two sets of patches for which the "
3175                    "declared names of the variables do not match.");
3176   /**
3177    * Exception
3178    */
3179   DeclExceptionMsg(ExcIncompatiblePatchLists,
3180                    "You are trying to merge two sets of patches for which the "
3181                    "number of subdivisions or the number of vector components "
3182                    "do not match.");
3183   /**
3184    * Exception
3185    */
3186   DeclException4(ExcIncompatibleDimensions,
3187                  int,
3188                  int,
3189                  int,
3190                  int,
3191                  << "Either the dimensions <" << arg1 << "> and <" << arg2
3192                  << "> or the space dimensions <" << arg3 << "> and <" << arg4
3193                  << "> do not match!");
3194 
3195 protected:
3196   /**
3197    * This is the function through which this class propagates preprocessed
3198    * data in the form of Patch structures (declared in the base class
3199    * DataOutBase) to the actual output function.
3200    *
3201    * It returns the patches as read the last time a stream was given to the
3202    * read() function.
3203    */
3204   virtual const std::vector<dealii::DataOutBase::Patch<dim, spacedim>> &
3205   get_patches() const override;
3206 
3207   /**
3208    * Abstract virtual function through which the names of data sets are
3209    * obtained by the output functions of the base class.
3210    *
3211    * Return the names of the variables as read the last time we read a file.
3212    */
3213   virtual std::vector<std::string>
3214   get_dataset_names() const override;
3215 
3216   /**
3217    * This functions returns information about how the individual components of
3218    * output files that consist of more than one data set are to be
3219    * interpreted.
3220    *
3221    * It returns a list of index pairs and corresponding name indicating which
3222    * components of the output are to be considered vector-valued rather than
3223    * just a collection of scalar data. The index pairs are inclusive; for
3224    * example, if we have a Stokes problem in 2d with components (u,v,p), then
3225    * the corresponding vector data range should be (0,1), and the returned
3226    * list would consist of only a single element with a tuple such as
3227    * (0,1,"velocity").
3228    *
3229    * Since some of the derived classes do not know about vector data, this
3230    * function has a default implementation that simply returns an empty
3231    * string, meaning that all data is to be considered a collection of scalar
3232    * fields.
3233    */
3234   virtual std::vector<
3235     std::tuple<unsigned int,
3236                unsigned int,
3237                std::string,
3238                DataComponentInterpretation::DataComponentInterpretation>>
3239   get_nonscalar_data_ranges() const override;
3240 
3241 private:
3242   /**
3243    * Arrays holding the set of patches as well as the names of output
3244    * variables, all of which we read from an input stream.
3245    */
3246   std::vector<dealii::DataOutBase::Patch<dim, spacedim>> patches;
3247   std::vector<std::string>                               dataset_names;
3248 
3249   /**
3250    * Information about whether certain components of the output field are to
3251    * be considered vectors.
3252    */
3253   std::vector<
3254     std::tuple<unsigned int,
3255                unsigned int,
3256                std::string,
3257                DataComponentInterpretation::DataComponentInterpretation>>
3258     nonscalar_data_ranges;
3259 };
3260 
3261 
3262 
3263 /**
3264  * A class to store relevant data to use when writing a lightweight XDMF
3265  * file. The XDMF file in turn points to heavy data files (such as HDF5)
3266  * where the actual simulation data is stored.
3267  * This allows flexibility in arranging the data, and also
3268  * allows the mesh to be separated from the point data.
3269  */
3270 class XDMFEntry
3271 {
3272 public:
3273   /**
3274    * Default constructor that creates an invalid object.
3275    */
3276   XDMFEntry();
3277 
3278   /**
3279    * Simplified constructor that calls the complete constructor for
3280    * cases where <code>solution_filename == mesh_filename</code>, and
3281    * <code>dim==spacedim</code>.
3282    */
3283   XDMFEntry(const std::string &filename,
3284             const double       time,
3285             const unsigned int nodes,
3286             const unsigned int cells,
3287             const unsigned int dim);
3288 
3289   /**
3290    * Simplified constructor that calls the complete constructor for
3291    * cases where <code>dim==spacedim</code>.
3292    */
3293   XDMFEntry(const std::string &mesh_filename,
3294             const std::string &solution_filename,
3295             const double       time,
3296             const unsigned int nodes,
3297             const unsigned int cells,
3298             const unsigned int dim);
3299 
3300   /**
3301    * Constructor that sets all members to provided parameters.
3302    */
3303   XDMFEntry(const std::string &mesh_filename,
3304             const std::string &solution_filename,
3305             const double       time,
3306             const unsigned int nodes,
3307             const unsigned int cells,
3308             const unsigned int dim,
3309             const unsigned int spacedim);
3310 
3311   /**
3312    * Record an attribute and associated dimensionality.
3313    */
3314   void
3315   add_attribute(const std::string &attr_name, const unsigned int dimension);
3316 
3317   /**
3318    * Read or write the data of this object for serialization
3319    */
3320   template <class Archive>
3321   void
3322   serialize(Archive &ar, const unsigned int /*version*/)
3323   {
3324     ar &valid &h5_sol_filename &h5_mesh_filename &entry_time &num_nodes
3325       &num_cells &dimension &space_dimension &attribute_dims;
3326   }
3327 
3328   /**
3329    * Get the XDMF content associated with this entry.
3330    * If the entry is not valid, this returns an empty string.
3331    *
3332    * @deprecated Use @ref get_xdmf_content(const unsigned int, const ReferenceCell::Type &) instead.
3333    */
3334   DEAL_II_DEPRECATED
3335   std::string
3336   get_xdmf_content(const unsigned int indent_level) const;
3337 
3338   /**
3339    * Get the XDMF content associated with this entry.
3340    * If the entry is not valid, this returns an empty string.
3341    */
3342   std::string
3343   get_xdmf_content(const unsigned int         indent_level,
3344                    const ReferenceCell::Type &reference_cell_type) const;
3345 
3346 private:
3347   /**
3348    * Whether this entry is valid and contains data to be written.
3349    */
3350   bool valid;
3351 
3352   /**
3353    * The name of the HDF5 heavy data solution file this entry references.
3354    */
3355   std::string h5_sol_filename;
3356 
3357   /**
3358    * The name of the HDF5 mesh file this entry references.
3359    */
3360   std::string h5_mesh_filename;
3361 
3362   /**
3363    * The simulation time associated with this entry.
3364    */
3365   double entry_time;
3366 
3367   /**
3368    * The number of data nodes.
3369    */
3370   unsigned int num_nodes;
3371 
3372   /**
3373    * The number of data cells.
3374    */
3375   unsigned int num_cells;
3376 
3377   /**
3378    * The dimension associated with the data.
3379    */
3380   unsigned int dimension;
3381 
3382   /**
3383    * The dimension of the space the data lives in.
3384    * Note that dimension <= space_dimension.
3385    */
3386   unsigned int space_dimension;
3387 
3388   /**
3389    * The attributes associated with this entry and their dimension.
3390    */
3391   std::map<std::string, unsigned int> attribute_dims;
3392 };
3393 
3394 
3395 
3396 /* -------------------- inline functions ------------------- */
3397 
3398 namespace DataOutBase
3399 {
3400   inline bool
3401   EpsFlags::RgbValues::is_grey() const
3402   {
3403     return (red == green) && (red == blue);
3404   }
3405 
3406 
3407   /* -------------------- template functions ------------------- */
3408 
3409   /**
3410    * Output operator for an object of type <tt>DataOutBase::Patch</tt>. This
3411    * operator dumps the intermediate graphics format represented by the patch
3412    * data structure. It may later be converted into regular formats for a
3413    * number of graphics programs.
3414    */
3415   template <int dim, int spacedim>
3416   std::ostream &
3417   operator<<(std::ostream &out, const Patch<dim, spacedim> &patch);
3418 
3419 
3420 
3421   /**
3422    * Input operator for an object of type <tt>DataOutBase::Patch</tt>. This
3423    * operator reads the intermediate graphics format represented by the patch
3424    * data structure, using the format in which it was written using the
3425    * operator<<.
3426    */
3427   template <int dim, int spacedim>
3428   std::istream &
3429   operator>>(std::istream &in, Patch<dim, spacedim> &patch);
3430 } // namespace DataOutBase
3431 
3432 
3433 DEAL_II_NAMESPACE_CLOSE
3434 
3435 #endif
3436