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>> ×_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 ×_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