From 7d2cbb2c993e714ef013c1a65e270cd2a2eab9dc Mon Sep 17 00:00:00 2001 From: Timo Heister Date: Wed, 18 Mar 2020 09:45:19 -0400 Subject: [PATCH] remove step-19 closes #2046 --- doc/news/changes/major/20200318Heister | 5 + examples/step-19/CMakeLists.txt | 42 -- examples/step-19/doc/builds-on | 1 - examples/step-19/doc/intro.dox | 120 ------ examples/step-19/doc/kind | 1 - examples/step-19/doc/results.dox | 259 ------------ examples/step-19/doc/tooltip | 1 - examples/step-19/step-19.cc | 535 ------------------------- include/deal.II/base/data_out_base.h | 2 - 9 files changed, 5 insertions(+), 961 deletions(-) create mode 100644 doc/news/changes/major/20200318Heister delete mode 100644 examples/step-19/CMakeLists.txt delete mode 100644 examples/step-19/doc/builds-on delete mode 100644 examples/step-19/doc/intro.dox delete mode 100644 examples/step-19/doc/kind delete mode 100644 examples/step-19/doc/results.dox delete mode 100644 examples/step-19/doc/tooltip delete mode 100644 examples/step-19/step-19.cc diff --git a/doc/news/changes/major/20200318Heister b/doc/news/changes/major/20200318Heister new file mode 100644 index 0000000000..43761c691f --- /dev/null +++ b/doc/news/changes/major/20200318Heister @@ -0,0 +1,5 @@ +Removed: The outdated step-19 that was used to combine parallel visualization +output after a simulation has been removed. The DataOut class can be used for +parallel output. +
+(Timo Heister, 2020/03/18) diff --git a/examples/step-19/CMakeLists.txt b/examples/step-19/CMakeLists.txt deleted file mode 100644 index 0bb95c78d3..0000000000 --- a/examples/step-19/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -## -# CMake script for the step-19 tutorial program: -## - -# Set the name of the project and target: -SET(TARGET "step-19") - -# Declare all source files the target consists of. Here, this is only -# the one step-X.cc file, but as you expand your project you may wish -# to add other source files as well. If your project becomes much larger, -# you may want to either replace the following statement by something like -# FILE(GLOB_RECURSE TARGET_SRC "source/*.cc") -# FILE(GLOB_RECURSE TARGET_INC "include/*.h") -# SET(TARGET_SRC ${TARGET_SRC} ${TARGET_INC}) -# or switch altogether to the large project CMakeLists.txt file discussed -# in the "CMake in user projects" page accessible from the "User info" -# page of the documentation. -SET(TARGET_SRC - ${TARGET}.cc - ) - -# No sensible run target can be defined for this example step -SET(TARGET_RUN "") - -# Usually, you will not need to modify anything beyond this point... - -CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12) - -FIND_PACKAGE(deal.II 9.2.0 QUIET - HINTS ${deal.II_DIR} ${DEAL_II_DIR} ../ ../../ $ENV{DEAL_II_DIR} - ) -IF(NOT ${deal.II_FOUND}) - MESSAGE(FATAL_ERROR "\n" - "*** Could not locate a (sufficiently recent) version of deal.II. ***\n\n" - "You may want to either pass a flag -DDEAL_II_DIR=/path/to/deal.II to cmake\n" - "or set an environment variable \"DEAL_II_DIR\" that contains this path." - ) -ENDIF() - -DEAL_II_INITIALIZE_CACHED_VARIABLES() -PROJECT(${TARGET}) -DEAL_II_INVOKE_AUTOPILOT() diff --git a/examples/step-19/doc/builds-on b/examples/step-19/doc/builds-on deleted file mode 100644 index 8b13789179..0000000000 --- a/examples/step-19/doc/builds-on +++ /dev/null @@ -1 +0,0 @@ - diff --git a/examples/step-19/doc/intro.dox b/examples/step-19/doc/intro.dox deleted file mode 100644 index 5e7dff7f43..0000000000 --- a/examples/step-19/doc/intro.dox +++ /dev/null @@ -1,120 +0,0 @@ - -

Introduction

- - -In step-18, we saw a need to write -output files in an intermediate format: in a %parallel program, it doesn't scale -well if all processors participate in computing a result, and then only a -single processor generates the graphical output. Rather, each of them should -generate output for its share of the domain, and later on merge all these -output files into a single one. - - - -Thus was the beginning of step-19: it is the program that reads a number of -files written in intermediate format, and merges and converts them into the -final format that one would like to use for visualization. It can also be used -for the following purpose: if you are unsure at the time of a computation what -graphics program you would like to use, write your results in intermediate -format; it can later be converted, using the present program, to any other -format you may want. - - - -While this in itself was not interesting enough to make a tutorial program, we -have used the opportunity to introduce one class that has proven to be -extremely help- and useful in real application programs, but had not been -covered by any of the previous tutorial programs: the -ParameterHandler class. This class is used in applications that -want to have some of their behavior determined at run time, using input -files. For example, one may want to specify the geometry, or specifics of the -equation to be solved, at run time. Other typical parameters are the number of -nonlinear iterations, the name of output files, or the names of input files -specifying material properties or boundary conditions. - - - -Working with such parameter files is not rocket science. However, it is rather -tedious to write the parsers for such files, in particular if they should be -extensible, be able to group parameters into subsections, perform some error -checks such as that parameters can have only certain kinds of values (for -example, it should only be allowed to have integer values in an input file for -parameters that denote a number of iteration), and similar requirements. The -ParameterHandler class allows for all this: an application program -will declare the parameters it expects (or call a function in the library that -declares a number of parameters for you), the ParameterHandler -class then reads an input file with all these parameters, and the application -program can then get their values back from this class. - - - -In order to perform these three steps, the ParameterHandler offers -three sets of functions: first, the -ParameterHandler::declare_entry function is used to declare the -existence of a named parameter in the present section of the input file (one -can enter and leave subsections in a parameter file just like you would -navigate through a directory tree in a file system, with the functions -ParameterHandler::enter_subsection and -ParameterHandler::leave_subsection taking on the roles of the -commands cd dir and cd ..; the only difference being -that if you enter a subsection that has never been visited before, it is -created: it isn't necessary to "create" subsections explicitly). When declaring -a parameter, one has to specify its name and default value, in case the -parameter isn't later listed explicitly in the parameter file. In addition to -that, there are optional arguments indicating a pattern that a parameter has to -satisfy, such as being an integer (see the discussion above), and a help text -that might later give an explanation of what the parameter stands for. - - - -Once all parameters have been declared, parameters can be read, using the -ParameterHandler::parse_input family of functions. There are -versions of this function that can read from a file stream, that take a file -name, or that simply take a string and parse it. When reading parameters, the -class makes sure that only parameters are listed in the input that have been -declared before, and that the values of parameters satisfy the pattern that has -been given to describe the kind of values a parameter can have. Input that uses -undeclared parameters or values for parameters that do not conform to the -pattern are rejected by raising an exception. - - - -A typical input file will look like this: -@code -set Output format = dx -set Output file = my_output_file.dx - -set Maximal number of iterations = 13 - -subsection Application - set Color of output = blue - set Generate output = false -end -@endcode -Note that subsections can be nested. - - - -Finally, the application program can get the values of declared parameters back -by traversing the subsections of the parameter tree and using the -ParameterHandler::get and related functions. The -ParameterHandler::get simply returns the value of a parameter as a -string, whereas ParameterHandler::get_integer, -ParameterHandler::get_double, and -ParameterHandler::get_bool already convert them to the indicated -type. - - - -Using the ParameterHandler class therefore provides for a pretty -flexible mechanism to handle all sorts of moderately complex input files without -much effort on the side of the application programmer. We will use this to -provide all sorts of options to the step-19 program in order to convert from -intermediate file format to any other graphical file format. - - - -The rest of the story is probably best told by looking at the source of step-19 -itself. Let us, however, end this introduction by pointing the reader at the -extensive class documentation of the ParameterHandler class for -more information on specific details of that class. diff --git a/examples/step-19/doc/kind b/examples/step-19/doc/kind deleted file mode 100644 index c1d9154931..0000000000 --- a/examples/step-19/doc/kind +++ /dev/null @@ -1 +0,0 @@ -techniques diff --git a/examples/step-19/doc/results.dox b/examples/step-19/doc/results.dox deleted file mode 100644 index a9fcd3babe..0000000000 --- a/examples/step-19/doc/results.dox +++ /dev/null @@ -1,259 +0,0 @@ -

Results

- - -With all that above, here is first what we get if we just run the program -without any parameters at all: -@code -examples/\step-19> ./\step-19 - -Converter from deal.II intermediate format to other graphics formats. - -Usage: - ./\step-19 [-p parameter_file] list_of_input_files - [-x output_format] [-o output_file] - -Parameter sequences in brackets can be omitted if a parameter file is -specified on the command line and if it provides values for these -missing parameters. - -The parameter file has the following format and allows the following -values (you can cut and paste this and use it for your own parameter -file): - -# Listing of Parameters -# --------------------- -# A dummy parameter asking for an integer -set Dummy iterations = 42 - -# The name of the output file to be generated -set Output file = - -# A name for the output format to be used -set Output format = gnuplot - - -subsection DX output parameters - # A Boolean field indicating whether neighborship information between cells - # is to be written to the OpenDX output file - set Write neighbors = true -end - - -subsection Dummy subsection - # A dummy parameter that shows how one can define a parameter that can be - # assigned values from a finite set of values - set Dummy color of output = red - - # A dummy parameter that can be fed with either 'true' or 'false' - set Dummy generate output = true -end - - -subsection Eps output parameters - # Angle of the viewing position against the vertical axis - set Azimut angle = 60 - - # Name of a color function used to colorize mesh lines and/or cell - # interiors - set Color function = default - - # Whether the interior of cells shall be shaded - set Color shading of interior of cells = true - - # Whether the mesh lines, or only the surface should be drawn - set Draw mesh lines = true - - # Whether only the mesh lines, or also the interior of cells should be - # plotted. If this flag is false, then one can see through the mesh - set Fill interior of cells = true - - # Number of the input vector that is to be used to generate color - # information - set Index of vector for color = 0 - - # Number of the input vector that is to be used to generate height - # information - set Index of vector for height = 0 - - # The width in which the postscript renderer is to plot lines - set Line widths in eps units = 0.5 - - # Whether width or height should be scaled to match the given size - set Scale to width or height = width - - # Scaling for the z-direction relative to the scaling used in x- and - # y-directions - set Scaling for z-axis = 1 - - # The size (width or height) to which the eps output file is to be scaled - set Size (width or height) in eps units = 300 - - # Angle of the viewing direction against the y-axis - set Turn angle = 30 -end - -subsection Povray output parameters - # Whether camera and lighting information should be put into an external - # file "data.inc" or into the POVRAY input file - set Include external file = true - - # Whether POVRAY should use bicubic patches - set Use bicubic patches = false - - # A flag indicating whether POVRAY should use smoothed triangles instead of - # the usual ones - set Use smooth triangles = false -end - - -subsection UCD output parameters - # A flag indicating whether a comment should be written to the beginning of - # the output file indicating date and time of creation as well as the - # creating program - set Write preamble = true -end -@endcode - -That's a lot of output for such a little program, but then that's also a lot of -output formats that deal.II supports. You will realize that the output consists -of first entries in the top-level section (sorted alphabetically), then a -sorted list of subsections. Most of the parameters have been declared by the -DataOutBase class, but there are also the dummy entries and -sections we have added in the declare_parameters() function, along -with their default values and documentations. - - - -Let us try to run this program on a set of input files generated by a modified -step-18 run on 32 nodes of a -cluster. The computation was rather big, with more -than 350,000 cells and some 1.2M unknowns. That makes for 32 rather big -intermediate files that we will try to merge using the present program. Here is -the list of files, totaling some 245MB of data: -@code -examples/\step-19> ls -l *d2 --rw-r--r-- 1 bangerth wheeler 7982085 Aug 12 10:11 solution-0005.0000-000.d2 --rw-r--r-- 1 bangerth wheeler 7888316 Aug 12 10:13 solution-0005.0000-001.d2 --rw-r--r-- 1 bangerth wheeler 7715984 Aug 12 10:09 solution-0005.0000-002.d2 --rw-r--r-- 1 bangerth wheeler 7887648 Aug 12 10:06 solution-0005.0000-003.d2 --rw-r--r-- 1 bangerth wheeler 7833291 Aug 12 10:09 solution-0005.0000-004.d2 --rw-r--r-- 1 bangerth wheeler 7536394 Aug 12 10:07 solution-0005.0000-005.d2 --rw-r--r-- 1 bangerth wheeler 7817551 Aug 12 10:06 solution-0005.0000-006.d2 --rw-r--r-- 1 bangerth wheeler 7996660 Aug 12 10:07 solution-0005.0000-007.d2 --rw-r--r-- 1 bangerth wheeler 7761545 Aug 12 10:06 solution-0005.0000-008.d2 --rw-r--r-- 1 bangerth wheeler 7754027 Aug 12 10:07 solution-0005.0000-009.d2 --rw-r--r-- 1 bangerth wheeler 7607545 Aug 12 10:11 solution-0005.0000-010.d2 --rw-r--r-- 1 bangerth wheeler 7728039 Aug 12 10:07 solution-0005.0000-011.d2 --rw-r--r-- 1 bangerth wheeler 7577293 Aug 12 10:14 solution-0005.0000-012.d2 --rw-r--r-- 1 bangerth wheeler 7735626 Aug 12 10:10 solution-0005.0000-013.d2 --rw-r--r-- 1 bangerth wheeler 7629075 Aug 12 10:10 solution-0005.0000-014.d2 --rw-r--r-- 1 bangerth wheeler 7314459 Aug 12 10:09 solution-0005.0000-015.d2 --rw-r--r-- 1 bangerth wheeler 7414738 Aug 12 10:10 solution-0005.0000-016.d2 --rw-r--r-- 1 bangerth wheeler 7330518 Aug 12 10:05 solution-0005.0000-017.d2 --rw-r--r-- 1 bangerth wheeler 7418213 Aug 12 10:11 solution-0005.0000-018.d2 --rw-r--r-- 1 bangerth wheeler 7508715 Aug 12 10:08 solution-0005.0000-019.d2 --rw-r--r-- 1 bangerth wheeler 7747143 Aug 12 10:06 solution-0005.0000-020.d2 --rw-r--r-- 1 bangerth wheeler 7563548 Aug 12 10:05 solution-0005.0000-021.d2 --rw-r--r-- 1 bangerth wheeler 7846767 Aug 12 10:12 solution-0005.0000-022.d2 --rw-r--r-- 1 bangerth wheeler 7479576 Aug 12 10:12 solution-0005.0000-023.d2 --rw-r--r-- 1 bangerth wheeler 7925060 Aug 12 10:12 solution-0005.0000-024.d2 --rw-r--r-- 1 bangerth wheeler 7842034 Aug 12 10:13 solution-0005.0000-025.d2 --rw-r--r-- 1 bangerth wheeler 7585448 Aug 12 10:13 solution-0005.0000-026.d2 --rw-r--r-- 1 bangerth wheeler 7609698 Aug 12 10:10 solution-0005.0000-027.d2 --rw-r--r-- 1 bangerth wheeler 7576053 Aug 12 10:08 solution-0005.0000-028.d2 --rw-r--r-- 1 bangerth wheeler 7682418 Aug 12 10:08 solution-0005.0000-029.d2 --rw-r--r-- 1 bangerth wheeler 7544141 Aug 12 10:05 solution-0005.0000-030.d2 --rw-r--r-- 1 bangerth wheeler 7348899 Aug 12 10:04 solution-0005.0000-031.d2 -@endcode - -So let's see what happens if we attempt to merge all these files into a single -one: -@code -examples/\step-19> time ./\step-19 solution-0005.0000-*.d2 -x gmv -o solution-0005.gmv -real 2m08.35s -user 1m26.61s -system 0m05.74s - -examples/\step-19> ls -l solution-0005.gmv --rw-r--r-- 1 bangerth wheeler 240680494 Sep 9 11:53 solution-0005.gmv -@endcode -So in roughly two minutes we have merged 240MB of data. Counting reading and -writing, that averages a throughput of 3.8MB per second, not so bad. - - - -If visualized, the output looks very much like that shown for -step-18. But that's not quite as -important for the moment, rather we are interested in showing how to use the -parameter file. To this end, remember that if no parameter file is given, or if -it is empty, all the default values listed above are used. However, whatever we -specify in the parameter file is used, unless overridden again by -parameters found later on the command line. - - - -For example, let us use a simple parameter file named -solution-0005.prm that contains only one line: -@code -set Output format = gnuplot -@endcode -If we run step-19 with it again, we obtain this (for simplicity, and because we -don't want to visualize 240MB of data anyway, we only convert the one, the -twelfth, intermediate file to gnuplot format): -@code -examples/\step-19> ./\step-19 solution-0005.0000-012.d2 -p solution-0005.prm -o solution-0005.gnuplot - -examples/\step-19> ls -l solution-0005.gnuplot --rw-r--r-- 1 bangerth wheeler 20281669 Sep 9 12:15 solution-0005.gnuplot -@endcode - -We can then visualize this one file with gnuplot, obtaining something like -this: - - -That's not particularly exciting, but the file we're looking at has only one -32nd of the entire domain anyway, so we can't expect much. - -In more complicated situations, we would use parameter files that set more of -the values to non-default values. A file for which this is the case could look -like this, generating output for the OpenDX visualization program: -@code -set Output format = dx -set Output file = my_output_file.dx - -set Dummy iterations = -13 - -subsection Dummy subsection - set Dummy color of output = blue - set Dummy generate output = false -end -@endcode -If one wanted to, one could write comments into the file using the -same format as used above in the help text, i.e. everything on a line -following a hashmark (#) is considered a comment. - - - -If one runs step-19 with this input file, this is what is going to happen: -@code -examples/\step-19> ./\step-19 solution-0005.0000-012.d2 -p solution-0005.prm -Line 4: - The entry value - -13 - for the entry named - Dummy iterations - does not match the given pattern - [Integer range 1...1000 (inclusive)] -@endcode -Ah, right: valid values for the iteration parameter needed to be within the -range [1...1000]. We would fix that, then go back to run the program with -correct parameters. - - - -This program should have given some insight into the input parameter file -handling that deal.II provides. The ParameterHandler class has a -few more goodies beyond what has been shown in this program, for those who want -to use this class, it would be useful to read the documentation of that class -to get the full picture. - diff --git a/examples/step-19/doc/tooltip b/examples/step-19/doc/tooltip deleted file mode 100644 index dbb26e4390..0000000000 --- a/examples/step-19/doc/tooltip +++ /dev/null @@ -1 +0,0 @@ -Handling input parameter files. Converting output formats. diff --git a/examples/step-19/step-19.cc b/examples/step-19/step-19.cc deleted file mode 100644 index 0a76416012..0000000000 --- a/examples/step-19/step-19.cc +++ /dev/null @@ -1,535 +0,0 @@ -/* --------------------------------------------------------------------- - * - * Copyright (C) 2005 - 2018 by the deal.II authors - * - * This file is part of the deal.II library. - * - * The deal.II library is free software; you can use it, redistribute - * it, and/or modify it under the terms of the GNU Lesser General - * Public License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * The full text of the license can be found in the file LICENSE.md at - * the top level directory of deal.II. - * - * --------------------------------------------------------------------- - - * - * Author: Luca Heltai, Wolfgang Bangerth, 2005 - */ - - -// @sect4{Preliminaries} - -// As usual, we start with include files. This program is content with really -// few of these -- we only need two files from the library (one for input and -// output of graphical data, one for parameter handling), and a few C++ -// standard headers: -#include -#include - -#include -#include -#include - -// As mentioned in the first few tutorial programs, all names in deal.II are -// declared in a namespace dealii. To make using these function -// and class names simpler, we import the entire content of that namespace -// into the global scope. As done for all previous programs already, we'll -// also place everything we do here into a namespace of its own: -namespace Step19 -{ - using namespace dealii; - - // Before we start with the actual program, let us declare a few global - // variables that will be used to hold the parameters this program is going - // to use. Usually, global variables are frowned upon for a good reason, but - // since we have such a short program here that does only a single thing, we - // may stray from our usual line and make these variables global, rather - // than passing them around to all functions or encapsulating them into a - // class. - // - // The variables we have are: first, an object that will hold parameters of - // operation, such as output format (unless given on the command line); - // second, the names of input and output files; and third, the format in - // which the output is to be written: - ParameterHandler prm; - std::vector input_file_names; - std::string output_file; - std::string output_format; - - - // All the stuff this program does can be done from here on. As described in - // the introduction, what we have to do is declare what values the parameter - // file can have, parse the command line, read the input files, then write - // the output. We will do this in this order of operation, but before that - // let us declare a function that prints a message about how this program is - // to be used; the function first prints a general message, and then goes on - // to list the parameters that are allowed in the parameter file (the - // ParameterHandler class has a function to do exactly this; - // see the results section for what it prints): - void print_usage_message() - { - static const char *message = - "\n" - "Converter from deal.II intermediate format to other graphics formats.\n" - "\n" - "Usage:\n" - " ./step-19 [-p parameter_file] list_of_input_files \n" - " [-x output_format] [-o output_file]\n" - "\n" - "Parameter sequences in brackets can be omitted if a parameter file is\n" - "specified on the command line and if it provides values for these\n" - "missing parameters.\n" - "\n" - "The parameter file has the following format and allows the following\n" - "values (you can cut and paste this and use it for your own parameter\n" - "file):\n" - "\n"; - std::cout << message; - - prm.print_parameters(std::cout, ParameterHandler::Text); - } - - - // @sect4{Declaring parameters for the input file} - - // The second function is used to declare the parameters this program - // accepts from the input file. While we don't actually take many parameters - // from the input file except for, possibly, the output file name and - // format, we nevertheless want to show how to work with parameter files. - // - // In short, the ParameterHandler class works as follows: one - // declares the entries of parameters that can be given in input files - // together, and later on one can read an input file in which these - // parameters are set to their values. If a parameter is not listed in the - // input file, the default value specified in the declaration of that - // parameter is used. After that, the program can query the values assigned - // to certain parameters from the ParameterHandler object. - // - // Declaring parameters can be done using the - // ParameterHandler::declare_entry function. It's arguments are - // the name of a parameter, a default value (given as a string, even if the - // parameter is numeric in nature, and thirdly an object that describes - // constraints on values that may be passed to this parameter. In the - // example below, we use an object of type Patterns::Anything - // to denote that there are no constraints on file names (this is, of - // course, not true -- the operating system does have constraints, but from - // an application standpoint, almost all names are valid). In other cases, - // one may, for example, use Patterns::Integer to make sure - // that only parameters are accepted that can be interpreted as integer - // values (it is also possible to specify bounds for integer values, and all - // values outside this range are rejected), Patterns::Double - // for floating point values, classes that make sure that the given - // parameter value is a comma separated list of things, etc. Take a look at - // the Patterns namespace to see what is possible. - // - // The fourth argument to declare_entry is a help string that - // can be printed to document what this parameter is meant to be used for - // and other information you may consider important when declaring this - // parameter. The default value of this fourth argument is the empty string. - // - // I always wanted to have an example program describing the - // ParameterHandler class, because it is so particularly - // useful. It would have been useful in a number of previous example - // programs (for example, in order to let the tolerance for linear solvers, - // or the number of refinement steps be determined by a run-time parameter, - // rather than hard-coding them into the program), but it turned out that - // trying to explain this class there would have overloaded them with things - // that would have distracted from the main purpose. However, while writing - // this program, I realized that there aren't all that many parameters this - // program can usefully ask for, or better, it turned out: declaring and - // querying these parameters was already done centralized in one place of - // the library, namely the DataOutInterface class that handles - // exactly this -- managing parameters for input and output. - // - // So the second function call in this function is to let the - // DataOutInterface declare a good number of parameters that - // control everything from the output format to what kind of output should - // be generated if output is written in a specific graphical format. For - // example, when writing data in encapsulated postscript (EPS) format, the - // result is just a 2d projection, not data that can be viewed and rotated - // with a viewer. Therefore, one has to choose the viewing angle and a - // number of other options up front, when output is generated, rather than - // playing around with them later on. The call to - // DataOutInterface::declare_parameters declares entries that - // allow to specify them in the parameter input file during run-time. If the - // parameter file does not contain entries for them, defaults are taken. - // - // As a final note: DataOutInterface is a template, because it - // is usually used to write output for a specific space dimension. However, - // this program is supposed to be used for all dimensions at the same time, - // so we don't know at compile time what the right dimension is when - // specifying the template parameter. Fortunately, declaring parameters is - // something that is space dimension independent, so we can just pick one - // arbitrarily. We pick 1, but it could have been any other - // number as well. - void declare_parameters() - { - prm.declare_entry("Output file", - "", - Patterns::Anything(), - "The name of the output file to be generated"); - - DataOutInterface<1>::declare_parameters(prm); - - // Since everything that this program can usefully request in terms of - // input parameters is already handled by now, let us nevertheless show - // how to use input parameters in other circumstances. First, parameters - // are like files in a directory tree: they can be in the top-level - // directory, but you can also group them into subdirectories to make it - // easier to find them or to be able to use the same parameter name in - // different contexts. - // - // Let us first declare a dummy parameter in the top-level section; we - // assume that it will denote the number of iterations, and that useful - // numbers of iterations that a user should be able to specify are in the - // range 1...1000, with a default value of 42: - prm.declare_entry("Dummy iterations", - "42", - Patterns::Integer(1, 1000), - "A dummy parameter asking for an integer"); - - // Next, let us declare a sub-section (the equivalent to a - // subdirectory). When entered, all following parameter declarations will - // be within this subsection. To also visually group these declarations - // with the subsection name, I like to use curly braces to force my editor - // to indent everything that goes into this sub-section by one level of - // indentation. In this sub-section, we shall have two entries, one that - // takes a Boolean parameter and one that takes a selection list of - // values, separated by the '|' character: - prm.enter_subsection("Dummy subsection"); - { - prm.declare_entry("Dummy generate output", - "true", - Patterns::Bool(), - "A dummy parameter that can be fed with either " - "'true' or 'false'"); - prm.declare_entry("Dummy color of output", - "red", - Patterns::Selection("red|black|blue"), - "A dummy parameter that shows how one can define a " - "parameter that can be assigned values from a finite " - "set of values"); - } - prm.leave_subsection(); - // After this, we have left the subsection again. You should have gotten - // the idea by now how one can nest subsections to separate - // parameters. There are a number of other possible patterns describing - // possible values of parameters; in all cases, if you try to pass a - // parameter to the program that does not match the expectations of the - // pattern, it will reject the parameter file and ask you to fix it. After - // all, it does not make much sense if you had an entry that contained the - // entry "red" for the parameter "Generate output". - } - - - // @sect4{Parsing the command line} - - // Our next task is to see what information has been provided on the command - // line. First, we need to be sure that there is at least one parameter: an - // input file. The format and the output file can be specified in the - // parameter file, but the list of input files can't, so at least one - // parameter needs to be there. Together with the name of the program (the - // zeroth parameter), argc must therefore be at least 2. If - // this is not the case, we print an error message and exit: - void parse_command_line(const int argc, char *const *argv) - { - if (argc < 2) - { - print_usage_message(); - exit(1); - } - - // Next, collect all parameters in a list that will be somewhat simpler to - // handle than the argc/argv mechanism. We omit - // the name of the executable at the zeroth index: - std::list args; - for (int i = 1; i < argc; ++i) - args.emplace_back(argv[i]); - - // Then process all these parameters. If the parameter is -p, - // then there must be a parameter file following (which we should then - // read), in case of -x it is the name of an output - // format. Finally, for -o it is the name of the output - // file. In all cases, once we've treated a parameter, we remove it from - // the list of parameters: - while (args.size()) - { - if (args.front() == std::string("-p")) - { - if (args.size() == 1) - { - std::cerr << "Error: flag '-p' must be followed by the " - << "name of a parameter file." << std::endl; - print_usage_message(); - exit(1); - } - args.pop_front(); - const std::string parameter_file = args.front(); - args.pop_front(); - - // Now read the input file: - prm.parse_input(parameter_file); - - // Both the output file name as well as the format can be - // specified on the command line. We have therefore given them - // global variables that hold their values, but they can also be - // set in the parameter file. We therefore need to extract them - // from the parameter file here, because they may be overridden by - // later command line parameters: - if (output_file == "") - output_file = prm.get("Output file"); - - if (output_format == "") - output_format = prm.get("Output format"); - - // Finally, let us note that if we were interested in the values - // of the parameters declared above in the dummy subsection, we - // would write something like this to extract the value of the - // Boolean flag (the prm.get function returns the - // value of a parameter as a string, whereas the - // prm.get_X functions return a value already - // converted to a different type): - prm.enter_subsection("Dummy subsection"); - { - prm.get_bool("Dummy generate output"); - } - prm.leave_subsection(); - // We would assign the result to a variable, of course, but don't - // here in order not to generate an unused variable that the - // compiler might warn about. - // - // Alas, let's move on to handling of output formats: - } - else if (args.front() == std::string("-x")) - { - if (args.size() == 1) - { - std::cerr << "Error: flag '-x' must be followed by the " - << "name of an output format." << std::endl; - print_usage_message(); - exit(1); - } - args.pop_front(); - output_format = args.front(); - args.pop_front(); - } - else if (args.front() == std::string("-o")) - { - if (args.size() == 1) - { - std::cerr << "Error: flag '-o' must be followed by the " - << "name of an output file." << std::endl; - print_usage_message(); - exit(1); - } - args.pop_front(); - output_file = args.front(); - args.pop_front(); - } - - // Otherwise, this is not a parameter that starts with a known minus - // sequence, and we should consider it to be the name of an input - // file. Let us therefore add this file to the list of input files: - else - { - input_file_names.push_back(args.front()); - args.pop_front(); - } - } - - // Next check a few things and create errors if the checks fail. Firstly, - // there must be at least one input file - if (input_file_names.size() == 0) - { - std::cerr << "Error: No input file specified." << std::endl; - print_usage_message(); - exit(1); - } - } - - - // @sect4{Generating output} - - // Now that we have all the information, we need to read all the input - // files, merge them, and generate a single output file. This, after all, - // was the motivation, borne from the necessity encountered in the step-18 - // tutorial program, to write this program in the first place. - // - // So what we do first is to declare an object into which we will merge the - // data from all the input file, and read in the first file through a - // stream. Note that every time we open a file, we use the - // AssertThrow macro to check whether the file is really - // readable -- if it isn't then this will trigger an exception and - // corresponding output will be generated from the exception handler in - // main(): - template - void do_convert() - { - DataOutReader merged_data; - - { - std::ifstream input(input_file_names[0]); - AssertThrow(input, ExcIO()); - - merged_data.read(input); - } - - // For all the other input files, we read their data into an intermediate - // object, and then merge that into the first object declared above: - for (unsigned int i = 1; i < input_file_names.size(); ++i) - { - std::ifstream input(input_file_names[i]); - AssertThrow(input, ExcIO()); - - DataOutReader additional_data; - additional_data.read(input); - merged_data.merge(additional_data); - } - - // Once we have this, let us open an output stream, and parse what we got - // as the name of the output format into an identifier. Fortunately, the - // DataOutBase class has a function that does this parsing - // for us, i.e. it knows about all the presently supported output formats - // and makes sure that they can be specified in the parameter file or on - // the command line. Note that this ensures that if the library acquires - // the ability to output in other output formats, this program will be - // able to make use of this ability without having to be changed! - std::ofstream output_stream(output_file); - AssertThrow(output_stream, ExcIO()); - - const DataOutBase::OutputFormat format = - DataOutBase::parse_output_format(output_format); - - // Finally, write the merged data to the output: - merged_data.write(output_stream, format); - } - - - // @sect4{Dispatching output generation} - - // The function above takes template parameters relating to the space - // dimension of the output, and the dimension of the objects to be - // output. (For example, when outputting whole cells, these two dimensions - // are the same, but the intermediate files may contain only data pertaining - // to the faces of cells, in which case the first parameter will be one less - // than the space dimension.) - // - // The problem is: at compile time, we of course don't know the dimensions - // used in the input files. We have to plan for all cases, therefore. This - // is a little clumsy, since we need to specify the dimensions statically at - // compile time, even though we will only know about them at run time. - // - // So here is what we do: from the first input file, we determine (using a - // function in DataOutBase that exists for this purpose) these - // dimensions. We then have a series of switches that dispatch, statically, - // to the do_convert functions with different template - // arguments. Not pretty, but works. Apart from this, the function does - // nothing -- except making sure that it covered the dimensions for which it - // was called, using the AssertThrow macro at places in the - // code that shouldn't be reached: - void convert() - { - AssertThrow(input_file_names.size() > 0, - ExcMessage("No input files specified.")); - - std::ifstream input(input_file_names[0]); - AssertThrow(input, ExcIO()); - - const std::pair dimensions = - DataOutBase::determine_intermediate_format_dimensions(input); - - switch (dimensions.first) - { - case 1: - switch (dimensions.second) - { - case 1: - do_convert<1, 1>(); - return; - - case 2: - do_convert<1, 2>(); - return; - } - AssertThrow(false, ExcNotImplemented()); - break; - - case 2: - switch (dimensions.second) - { - case 2: - do_convert<2, 2>(); - return; - - case 3: - do_convert<2, 3>(); - return; - } - AssertThrow(false, ExcNotImplemented()); - break; - - case 3: - switch (dimensions.second) - { - case 3: - do_convert<3, 3>(); - return; - } - AssertThrow(false, ExcNotImplemented()); - } - - AssertThrow(false, ExcNotImplemented()); - } -} // namespace Step19 - - - -// @sect4{main()} - -// Finally, the main program. There is not much more to do than to make sure -// parameters are declared, the command line is parsed (which includes reading -// parameter files), and finally making sure the input files are read and -// output is generated. Everything else just has to do with handling -// exceptions and making sure that appropriate output is generated if one is -// thrown. -int main(int argc, char **argv) -{ - try - { - using namespace Step19; - - declare_parameters(); - parse_command_line(argc, argv); - - convert(); - } - catch (std::exception &exc) - { - std::cerr << std::endl - << std::endl - << "----------------------------------------------------" - << std::endl; - std::cerr << "Exception on processing: " << std::endl - << exc.what() << std::endl - << "Aborting!" << std::endl - << "----------------------------------------------------" - << std::endl; - - return 1; - } - catch (...) - { - std::cerr << std::endl - << std::endl - << "----------------------------------------------------" - << std::endl; - std::cerr << "Unknown exception!" << std::endl - << "Aborting!" << std::endl - << "----------------------------------------------------" - << std::endl; - return 1; - }; - - return 0; -} diff --git a/include/deal.II/base/data_out_base.h b/include/deal.II/base/data_out_base.h index bdd9088e27..0ef384f8f1 100644 --- a/include/deal.II/base/data_out_base.h +++ b/include/deal.II/base/data_out_base.h @@ -3216,8 +3216,6 @@ public: * * This function will fail if either this or the other object did not yet * set up any patches. - * - * The use of this function is demonstrated in step-19. */ void merge(const DataOutReader &other); -- 2.39.5