]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Switch to new output scheme. Use the new DataOut class and rename the old one to...
authorwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Tue, 6 Jul 1999 12:01:47 +0000 (12:01 +0000)
committerwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Tue, 6 Jul 1999 12:01:47 +0000 (12:01 +0000)
git-svn-id: https://svn.dealii.org/trunk@1541 0785d39b-7218-0410-832d-ea1e28bc413d

20 files changed:
deal.II/deal.II/Attic/examples/convergence/convergence.cc
deal.II/deal.II/Attic/examples/error-estimation/error-estimation.cc
deal.II/deal.II/Attic/examples/multigrid/multigrid.cc
deal.II/deal.II/Attic/examples/poisson/problem.cc
deal.II/deal.II/include/multigrid/multigrid.templates.h
deal.II/deal.II/include/numerics/base.h
deal.II/deal.II/include/numerics/data_io.h
deal.II/deal.II/include/numerics/data_out.h
deal.II/deal.II/include/numerics/data_out_base.h
deal.II/deal.II/include/numerics/multigrid.templates.h
deal.II/deal.II/source/numerics/base.cc
deal.II/deal.II/source/numerics/data_io.cc
deal.II/deal.II/source/numerics/data_out.cc
deal.II/deal.II/source/numerics/data_out_base.cc
tests/big-tests/convergence/convergence.cc
tests/big-tests/error-estimation/error-estimation.cc
tests/big-tests/multigrid/multigrid.cc
tests/big-tests/poisson/problem.cc
tests/deal.II/constraints.cc
tests/deal.II/grid_test.cc

index 96e905a8e84e69774fb347117bfbe68a89db779e..1a5ad43c5c4f5166c420d38dd692b7a93b528fb8 100644 (file)
@@ -11,7 +11,7 @@
 #include <grid/dof_constraints.h>
 #include <grid/grid_generator.h>
 #include <base/function.h>
-#include <basic/data_io.h>
+#include <basic/data_out.h>
 #include <fe/fe_lib.lagrange.h>
 #include <fe/fe_lib.criss_cross.h>
 #include <base/quadrature_lib.h>
@@ -269,7 +269,7 @@ int PoissonProblem<dim>::run (const unsigned int level) {
   cout << "    Making grid... ";
   GridGenerator::hyper_ball (*tria);
   HyperBallBoundary<dim> boundary_description;
-  tria->set_boundary (&boundary_description);
+  tria->set_boundary (0, boundary_description);
   tria->begin_active()->set_refine_flag();
   (++(++(tria->begin_active())))->set_refine_flag();
   tria->execute_coarsening_and_refinement ();
index 973d78951cb2042e6635f08a32aca176cd0cdf7f..31efd2cf2518852a2c53d7f3446ab0170cb07495 100644 (file)
@@ -11,7 +11,7 @@
 #include <grid/dof_constraints.h>
 #include <grid/grid_generator.h>
 #include <base/function.h>
-#include <basic/data_io.h>
+#include <basic/data_out.h>
 #include <basic/grid_out.h>
 #include <base/parameter_handler.h>
 #include <fe/fe_lib.lagrange.h>
@@ -413,7 +413,7 @@ void PoissonProblem<dim>::run (ParameterHandler &prm) {
        << "=======================================" << endl;
   cout << "Making initial grid... " << endl;
   const unsigned int start_level(prm.get_integer("Initial refinement"));
-  tria->set_boundary (boundary);
+  tria->set_boundary (0, *boundary);
   GridGenerator::hyper_ball (*tria);
   tria->refine_global (start_level);
 
@@ -630,7 +630,7 @@ void PoissonProblem<dim>::run (ParameterHandler &prm) {
   filename += "finest_mesh.gnuplot";
   cout << "    Writing finest grid to <" << filename << ">... " << endl;
   ofstream finest_mesh (filename.c_str());
-  GridOut::write_gnuplot (tria, finest_mesh);
+  GridOut().write_gnuplot (*tria, finest_mesh);
   finest_mesh.close();
 
   print_history (prm, refine_mode);
index 136acea0b2de667390ca675955b07cd015a46b96..572a209dea2a0c9636d6060e19cbe1250e6e9da7 100644 (file)
@@ -11,7 +11,7 @@
 #include <grid/dof_constraints.h>
 #include <grid/grid_generator.h>
 #include <base/function.h>
-#include <basic/data_io.h>
+#include <basic/data_out.h>
 #include <fe/fe_lib.lagrange.h>
 #include <fe/fe_lib.criss_cross.h>
 #include <fe/fe_update_flags.h>
index 4ddc11e4f8af673b61aa85e86fcbc1cd9d5266a0..bfb37b0268b4739f6a8906fdc7168fc1dfb4e52d 100644 (file)
@@ -6,7 +6,7 @@
 #include "poisson.h"
 #include <lac/vector.h>
 #include <grid/grid_generator.h>
-
+#include <basic/data_out.h>
 
 
 template <int dim>
@@ -236,6 +236,13 @@ PoissonProblem<dim>::PoissonProblem () :
 
 
 
+template <int dim>
+PoissonProblem<dim>::~PoissonProblem () 
+{
+  clear ();
+};
+
+
 
 template <int dim>
 void PoissonProblem<dim>::clear () {  
@@ -244,6 +251,13 @@ void PoissonProblem<dim>::clear () {
     dof = 0;
   };
 
+  if (boundary != 0)
+    {
+      tria->set_boundary (0);
+      delete boundary;
+      boundary = 0;
+    };
+  
   if (tria != 0) {
     delete tria;
     tria = 0;
@@ -267,12 +281,6 @@ void PoissonProblem<dim>::clear () {
       boundary_values = 0;
     };
 
-  if (boundary != 0)
-    {
-      delete boundary;
-      boundary = 0;
-    };
-  
   ProblemBase<dim>::clear ();
 };
 
@@ -407,6 +415,7 @@ bool PoissonProblem<dim>::make_grid (ParameterHandler &prm) {
 template <int dim>
 void PoissonProblem<dim>::make_zoom_in_grid () {
   GridGenerator::hyper_cube (*tria);
+  
                                   // refine first cell
   tria->begin_active()->set_refine_flag();
   tria->execute_coarsening_and_refinement ();
@@ -414,7 +423,7 @@ void PoissonProblem<dim>::make_zoom_in_grid () {
                                   // on coarsest level
   tria->begin_active()->set_refine_flag ();
   tria->execute_coarsening_and_refinement ();
-  
+
   Triangulation<dim>::active_cell_iterator cell;
   for (int i=0; i<(dim==3 ? 5 : 17); ++i) 
     {
@@ -555,7 +564,9 @@ void PoissonProblem<dim>::run (ParameterHandler &prm) {
   DataOut<dim> out;
   string o_filename = prm.get ("Output file");
   ofstream gnuplot(o_filename.c_str());
-  fill_data (out);
+  out.attach_dof_handler (*dof_handler);
+  out.add_data_vector (solution, "solution");
+  out.build_patches ();
   out.write_gnuplot (gnuplot);
   gnuplot.close ();
 
@@ -570,4 +581,4 @@ void PoissonProblem<dim>::run (ParameterHandler &prm) {
 
 
 
-template class PoissonProblem<2>;
+template class PoissonProblem<3>;
index 55ae154eee936b9c28811391b491879530498427..13ac996d17dc3f80bde36ca9720d1873382fc7e3 100644 (file)
@@ -47,7 +47,7 @@ MG<dim>::copy_to_mg(const Vector<number>& src)
     ofstream of("CT");
     DataOut<2> out;
     out.attach_dof_handler(*dofs);
-    out.add_data_vector(src,"solution","m");
+    out.add_data_vector(src,"solution");
     out.write_gnuplot(of,1);
   }
 
@@ -120,7 +120,7 @@ MG<dim>::copy_from_mg(Vector<number>& dst) const
     ofstream of("CF");
     DataOut<2> out;
     out.attach_dof_handler(*dofs);
-    out.add_data_vector(dst,"solution","m");
+    out.add_data_vector(dst,"solution");
     out.write_gnuplot(of,1);
   }
 }
index 462393f19806cbe682bed334512fb35e98980c4e..0b6b71b5f97e1cf71936e53772f6c841d91dd667 100644 (file)
@@ -11,7 +11,7 @@
 #include <grid/dof_constraints.h>
 #include <fe/fe_update_flags.h>
 #include <map>
-
+#include <string>
 
 
 
@@ -170,7 +170,7 @@ class ProblemBase {
                                      * vectors directly to the #DataOut#
                                      * object.
                                      *
-                                     * Solution name and physical units are
+                                     * The solution name are
                                      * derived by calling the virtual
                                      * function #get_solution_name#.
                                      */
@@ -178,16 +178,13 @@ class ProblemBase {
 
 
                                     /**
-                                     * Return solution name and
-                                     * physical units as a pair of
-                                     * #char*#. The default implementation
-                                     * returns #make_pair ("solution","")#,
-                                     * which results in "<dimensionless>"
-                                     * upon output.
+                                     * Return the name of the solution as a
+                                     * #string#. The default implementation
+                                     * returns #"solution"#.
                                      * Overload this function, if you
                                      * want anything else.
                                      */
-    virtual pair<char*,char*> get_solution_name () const;
+    virtual string get_solution_name () const;
 
                                     /**
                                      * Exception
index 4f767908d865c7074d7fb2630509bdcc4f0515ad..c3957fde7e4d7ae71bcab2f62283d3262ac99596 100644 (file)
@@ -182,6 +182,8 @@ class DataIn {
 
 
 /**
+ * This class is deprecated. Use the #DataOut class instead.
+ *
  * This class implements an output mechanism for grid and simulation data
  * in several formats.
  * At present it supports output in UCD (unstructured cell data) and
@@ -237,7 +239,7 @@ class DataIn {
  * want to see plus one. For example #using 1:4# would mean to plot the
  * third data vector.
  *
- * For more than one dimension, the #DataOut<dim>::write_gnuplot()# somehow
+ * For more than one dimension, the #DataOut_Old<dim>::write_gnuplot()# somehow
  * duplicates the functionality of the #Triangulation<dim>::print_gnuplot()#
  * functions. These, however, offer more functionality in some respect.
  * The grid is represented as a sequence of lines, where each cell is
@@ -376,7 +378,7 @@ class DataIn {
  * @author Wolfgang Bangerth, Guido Kanschat, Stefan Nauber, 1998, 1999
  */
 template <int dim>  
-class DataOut {
+class DataOut_Old {
   public:
                                     /**
                                      * Provide a data type specifying the
@@ -387,7 +389,7 @@ class DataOut {
                                     /**
                                      * Constructor
                                      */
-    DataOut ();
+    DataOut_Old ();
     
                                     /**
                                      * Designate a dof handler to be used
@@ -761,7 +763,7 @@ class DataOut {
 
 /**
  * Structure for the control of encapsulated postscript output. See
- * general documentation of class #DataOut# for description.
+ * general documentation of class #DataOut_Old# for description.
  *
  * @author Stefan Nauber
  */
index 576bba5783cf7cb42521c7017b2eaa2ae88a5d5c..97dcc89833e23927c64f94a48826eff83f050d19 100644 (file)
 #define __data_out_H
 /*----------------------------   data_out.h     ---------------------------*/
 
-
+#include <lac/forward-declarations.h>
+#include <basic/forward-declarations.h>
 #include <basic/data_out_base.h>
 
 
-class DataOut1 : protected DataOutBase
+
+/**
+ * This is an abstract class which provides the functionality to generate
+ * patches for output by base classes from data vectors on a grid. It alloes
+ * to store a pointer to a #DoFHandler# object and one or more pointers to
+ * node and cell data denoting functions on the grid which shall later
+ * be written in any of the implemented data formats.
+ *
+ *
+ * \subsection{User visible interface}
+ *
+ * The user visible interface of this class consists of functions which allow
+ * a user to make a #DoFHandler# object known to this class and to add data
+ * vectors which will later be written to a file in some format. Instead of
+ * pondering about the different functions, an example is probably the best
+ * way:
+ * \begin{verbatim}
+ *   ...
+ *   ...   // compute solution, which is of type Vector<double>
+ *   ...   // and contains nodal values
+ *   ...
+ *   ...   // compute error_estimator, which is of type Vector<double>
+ *   ...   // and contains one value per cell
+ *
+ *   vector<string> solution_names;
+ *   solution_names.push_back ("x-displacement");
+ *   solution_names.push_back ("y-displacement");
+ *
+ *   DataOut<dim> data_out;
+ *   data_out.attach_dof_handler (dof_handler);
+ *   data_out.add_data_vector (solution, solution_names);
+ *   data_out.add_data_vector (error_estimator, "estimated_error");
+ *
+ *   data_out.build_patches ();
+ *
+ *   ofstream output_file ("output");
+ *   data_out.write_xxx (output_file);
+ *
+ *   data_out.clear();
+ * \end{verbatim}
+ *
+ * #attach_dof_handler# tells this class that all future operations are to take
+ * place with the #DoFHandler# object and the triangulation it lives on. We then
+ * add the solution vector and the error estimator; note that they have different
+ * dimensions, because the solution is a nodal vector, here consisting of two
+ * components ("x-displacement" and "y-displacement") while the error estimator
+ * probably is a vector holding cell data. When attaching a data vector, you have
+ * to give a name to each component of the vector, which is done through an object
+ * of type #vector<string># as second argument; if only one component is in the
+ * vector, for example if we are adding cell data as in the second case, or if
+ * the finite element used by the #DoFHandler# has only one component, then you
+ * can use the second #add_data_vector# function which takes a #string# instead
+ * of the #vector<string>#.
+ *
+ * You should note that this class does not copy the vector given to it through
+ * the #add_data_vector# functions, for memory consumption reasons. It only
+ * stores a reference to it, so it is in your responsibility to make sure that
+ * the data vectors exist long enough.
+ *
+ * After adding all data vectors, you need to call a function which generates
+ * the patches for output from the stored data. This function is here called
+ * #build_patches#, but the naming is up to the derived class that actually
+ * implements this.
+ *
+ * Finally, you write the data in one format or other, indicated by #write_xxx#,
+ * to a file and may want to clear this object as soon as possible to reduce
+ * memory requirements.
+ *
+ * Please note, that in the example above, an object of type #DataOut# was
+ * used, i.e. an object of a derived class. This is necessary since this
+ * class does not provide means to actually generate the patches, only aids to
+ * store and access data.
+ *
+ * Note that the base class of this class, #DataOutInterface# offers several
+ * functions to ease programming with run-time determinable output formats
+ * (i.e. you need not use a fixed format by calling #write_xxx# in the above
+ * example, but you can select it by a run-time parameter without having
+ * to write the #if () ... else ...# clauses yourself), and also functions
+ * and classes offering ways to control the appearance of the output by
+ * setting flags for each output format.
+ * 
+ *
+ * \subsection{Information for derived classes}
+ *
+ * What is actually missing this class is a way to produce the patched for
+ * output itself, from the stored data and degree of freedom information.
+ * Since this task is often application dependent it is left to derived
+ * classes. For example, in many applications, it might be wanted to limit
+ * the depth of output to a certain number of refinement levels and write
+ * data from finer cells only in a way interpolated to coarser cells, to
+ * reduce the amount of output. Also, it might be wanted to use different
+ * numbers of subdivisions on different cells when forming a patch, for example
+ * to accomplish for different polynomial degrees of the trial space on
+ * different cells.
+ *
+ * For this reason, it is left to a derived class to provide a function, named
+ * usually #build_patches# or the like, which fills the #patches# array of
+ * this class.
+ *
+ * @author Wolfgang Bangerth, 1999
+ */
+template <int dim>
+class DataOut_DoFData : public DataOutInterface<dim>
 {
   public:
+                                    /**
+                                     * Constructor
+                                     */
+    DataOut_DoFData ();
+
+                                    /**
+                                     * Destructor.
+                                     */
+    virtual ~DataOut_DoFData ();
+
+                                    /**
+                                     * Designate a dof handler to be used
+                                     * to extract geometry data and the
+                                     * mapping between nodes and node values.
+                                     */
+    void attach_dof_handler (const DoFHandler<dim> &);
+
+                                    /**
+                                     * Add a data vector together with its
+                                     * name and the physical unit
+                                     * (for example meter, kelvin, etc). By
+                                     * default, "<dimensionless>" is assumed
+                                     * for the units.
+                                     *
+                                     * A pointer to the vector is stored, so
+                                     * you have to make sure the vector
+                                     * exists at that address at least as
+                                     * long as you call the
+                                     * #write_*# functions.
+                                     *
+                                     * It is assumed that the vector has the
+                                     * same number of components as there are
+                                     * degrees of freedom in the dof handler,
+                                     * in which case it is assumed to be a
+                                     * vector storing nodal data; or the size
+                                     * may be the number of active cells on
+                                     * the present grid, in which case it is
+                                     * assumed to be a cell data vector.
+                                     *
+                                     * If it is a vector holding DoF data,
+                                     * the names given shall be one for each
+                                     * component, if the finite element in
+                                     * use is composed of several subelements.
+                                     * If it is a finite element composed of
+                                     * only one subelement, then there is
+                                     * another function following which takes
+                                     * a single name instead of a vector of
+                                     * names.
+                                     *
+                                     * The names of a data vector shall
+                                     * only contain characters which are
+                                     * letters, underscore and a few other
+                                     * ones. Refer to the #ExcInvalidCharacter#
+                                     * exception declared in this class to
+                                     * see which characters are valid and which
+                                     * are not.
+                                     */
+    void add_data_vector (const Vector<double> &data,
+                         const vector<string> &names);
+
+                                    /**
+                                     * This function is an abbreviation to the
+                                     * above one, intended for use with finite
+                                     * elements that are not composed of
+                                     * subelements. In this case, only one
+                                     * name per data vector needs to be given,
+                                     * which is what this function takes. It
+                                     * simply relays its arguments after a
+                                     * conversion of the #name# to a vector
+                                     * of strings, to the other
+                                     * #add_data_vector# function above.
+                                     */
+    void add_data_vector (const Vector<double> &data,
+                         const string         &name);
+
+                                    /**
+                                     * Release the pointers to the data
+                                     * vectors. You have to set all data
+                                     * entries again using the
+                                     * #add_data_vector# function. The pointer
+                                     * to the dof handler is cleared as well,
+                                     * along with all other data. In effect,
+                                     * this function resets everything to a
+                                     * virgin state.  */
+    virtual void clear ();
+
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcNoDoFHandlerSelected);
+                                    /**
+                                     * Exception
+                                     */
+    DeclException3 (ExcInvalidVectorSize,
+                   int, int, int,
+                   << "The vector has size " << arg1
+                   << " but the DoFHandler objects says there are " << arg2
+                   << " degrees of freedom and there are " << arg3
+                   << " active cells.");
+                                    /**
+                                     * Exception
+                                     */
+    DeclException1 (ExcInvalidCharacter,
+                   string,
+                   << "Please use only the characters [a-zA-Z0-9_<>()] for" << endl
+                   << "description strings since AVS will only accept these." << endl
+                   << "The string you gave was <" << arg1 << ">.");
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcOldDataStillPresent);
+                                    /**
+                                     * Exception
+                                     */
+    DeclException2 (ExcInvalidNumberOfNames,
+                   int, int,
+                   << "You have to give one name per component in your "
+                   << "data vector. The number you gave was " << arg1
+                   << ", but the number of components is " << arg2);
+
   protected:
-    virtual void make_patch_list () const;
+                                    /**
+                                     * Declare an entry in the list of
+                                     * data elements.
+                                     */
+    struct DataEntry {
+                                        /**
+                                         * Constructor. If no arguments are
+                                         * given, an invalid object is
+                                         * constructed (we need a constructor
+                                         * with no explicit arguments for
+                                         * STL classes).
+                                         */
+       DataEntry (const Vector<double> *data = 0,
+                  const vector<string> &names = vector<string>());
+       
+                                        /**
+                                         * Pointer to the data vector.
+                                         */
+       const Vector<double> *data;
+       
+                                        /**
+                                         * Names of the components of this
+                                         * data vector.
+                                         */
+       vector<string> names;
+       
+                                        /**
+                                         * Physical unit name of this
+                                         * component.
+                                         */
+       string   units;
+    };
+
+                                    /**
+                                     * Pointer to the dof handler object.
+                                     */
+    const DoFHandler<dim>   *dofs;
+
+                                    /**
+                                     * List of data elements with vectors of
+                                     * values for each degree of freedom.
+                                     */
+    vector<DataEntry>  dof_data;
+
+                                    /**
+                                     * List of data elements with vectors of
+                                     * values for each cell.
+                                     */
+    vector<DataEntry>  cell_data;
+
+                                    /**
+                                     * This is a list of patches that is
+                                     * created each time #build_patches#
+                                     * is called. These patches are used
+                                     * in the output routines of the base
+                                     * classes.
+                                     */
+    vector<DataOutBase::Patch<dim> > patches;
+
+                                    /**
+                                     * Function by which the base
+                                     * class's functions get to know
+                                     * what patches they shall write
+                                     * to a file.
+                                     */
+    virtual const vector<DataOutBase::Patch<dim> > & get_patches () const;
+
+                                    /**
+                                     * Virtual function through
+                                     * which the names of data sets are
+                                     * obtained by the output functions
+                                     * of the base class.
+                                     */
+    virtual vector<string> get_dataset_names () const;
+};
+
+
+
+
+/**
+ * This class is an actual implementation of the functionality proposed by
+ * the #DataOut_DoFData# class. It offers a function #build_patches# that
+ * generates the patches to be written in some graphics format from the data
+ * stored in the base class. Most of the interface and an example of its
+ * use is described in the documentation of the base class.
+ *
+ * The only thing this class offers is the function #build_patches# which
+ * loops over all cells of the triangulation stored by the #attach_dof_handler#
+ * function of the base class and convert the data on these to actual patches
+ * which are the objects that are later output by the functions of the
+ * base classes. You can give a parameter to the function which determines
+ * how many subdivisions in each coordinate direction are to be performed,
+ * i.e. of how many subcells each patch shall consist. Default is one, but
+ * for quadratic elementsyou may want to choose two, for cubic elements three,
+ * and so on.
+ *
+ *
+ * \subsection{User interface information}
+ *
+ * The base classes of this class, #DataOutBase#, #DataOutInterface# and
+ * #DataOut_DoFData# offer several interfaces of their own. Refer to the
+ * #DataOutBase# class's documentation for a discussion of the different
+ * output formats presently supported, #DataOutInterface# for ways of
+ * selecting which format to use upon output at run-time and without
+ * the need to adapt your program when new formats become available, as
+ * well as for flags to determine aspects of output. The #DataOut_DoFData#
+ * class's documentation has an example of using nodal data to generate
+ * output.
+ *
+ * @author Wolfgang Bangerth, 1999
+ */
+template <int dim>
+class DataOut : public DataOut_DoFData<dim> 
+{
+  public:
+                                    /**
+                                     * This is the central and only function of
+                                     * this class since it builds the list of
+                                     * patches to be written by the low-level
+                                     * functions of the base class. See the
+                                     * general documentation of this class
+                                     * for further information.
+                                     */
+    virtual void build_patches (const unsigned int n_subdivisions = 1);    
 };
 
 
 
+
+
 /*----------------------------   data_out.h     ---------------------------*/
 /* end of #ifndef __data_out_H */
 #endif
index 526ea3fecbe4d7d9a5f7d3aa6064af11c1c55d0f..f55c534b17b8dae374bc3f3a1099b644c88675e0 100644 (file)
@@ -14,6 +14,9 @@
 
 
 
+
+
+
 /**
  * This is a base class for output of data on meshes of very general
  * form. It basically only provides a set of functions for several output
@@ -39,7 +42,7 @@
  * In addition to the list of patches, a name for each data set may be given.
  *
  *
- * \subsectin{Patches}
+ * \subsection{Patches}
  * Grids can be thought of as a collection of cells; if you want to write out
  * data on such a grid, you can do so by writing them one cell at a time.
  * The functions in this class therefore take a list of objects describing the
  * dimensions, each data set has to provide nine values, and since the
  * patch is to be printed as a tensor product (or its transformation to the
  * real space cell), its values are to be ordered like
- * #(x0,y0) (x1,y0) (x2,y0) (x0,y1) (x1,y1) (x2,y1) (x0,y2) (x1,y2) (x2,y2)#,
- * i.e. the x-coordinate runs fastest, then the y-coordinate, then z (if there
+ * #(x0,y0) (x0,y1) (x0,y2) (x1,y0) (x1,y1) (x1,y2) (x2,y0) (x2,y1) (x2,y2)#,
+ * i.e. the z-coordinate runs fastest, then the y-coordinate, then x (if there
  * are that many space directions).
  *
  * The #Patch# class takes a template parameter denoting the space dimension
  * in which this patch operates.
  *
  *
+ * \section{Supported output formats}
+ *
+ * \subsection{UCD format}
+ *
+ * The UCD format is described in the AVS developer's guide. Due to
+ * limitations in the present format, only node based data can be output,
+ * which in one reason why we invented the patch concept. In order to
+ * write higher order elements, you may split them up into several subdivisions
+ * of each cell. These subcells will then, however, also appear as different
+ * cells by programs which understand the UCD format.
+ * 
+ * No use is made of the possibility to give model data since these
+ * are not supported by all UCD aware programs. You may give cell data
+ * in derived classes by setting all values of a given data set on a
+ * patch to the same value.
+ *
+ *
+ * \subsection{GNUPLOT format}
+ *
+ * The GNUPLOT format is not able to handle data on unstructured grids
+ * directly. Directly would mean that you only give the vertices and
+ * the solution values thereon and the program constructs its own grid
+ * to represent the data. This is only possible for a structured tensor
+ * product grid in two dimensions. However, it is possible to give several
+ * such patches within one file, which is exactly what the respective
+ * function of this class does: writing each cell's data as a patch of
+ * data, at least if the patches as passed from derived classes
+ * represent cells. Note that the functions on patches need not be
+ * continuous at interfaces between patches, so this method also works
+ * for discontinuous elements. Note also, that GNUPLOT can do hidden
+ * line removal for patched data.
+ *
+ * While this discussion applies to two spatial dimensions, it is more
+ * complicated in 3d. The reason is that we could still use patches, but
+ * it is difficult when trying to visualize them, since if we use a cut
+ * through the data (by, for example, using x- and z-coordinates, a fixed
+ * y-value and plot function values in z-direction, then the patched data
+ * is not a patch in the sense GNUPLOT wants it any more. Therefore, we use
+ * another approach, namely writing the data on the 3d grid as a sequence
+ * of lines, i.e. two points each associated with one or more data sets.
+ * There are therefore 12 lines for each subcells of a patch.
+ *
+ * Given the lines as described above, a cut through this data in Gnuplot
+ * can then be achieved like this:
+ * \begin{verbatim}
+ * set data style lines
+ * splot [:][:][0:] "T" using 1:2:($3==.5 ? $4 : -1)
+ * \end{verbatim}
+ * This command plots data in x- and y-direction unbounded, but in z-direction
+ * only those data points which are above the x-y-plane (we assume here a
+ * positive solution, if it has negative values, you might want to decrease the
+ * lower bound). Furthermore, it only takes the data points with z-values (#$3#)
+ * equal to 0.5, i.e. a cut through the domain at #z=0.5#. For the data points
+ * on this plane, the data values of the first data set (#$4#) are raised in
+ * z-direction above the x-y-plane; all other points are denoted the value
+ * #-1# instead of the value of the data vector and are not plotted due to
+ * the lower bound in z plotting direction, given in the third pair of brackets.
+ *
+ * Of course, more complex cuts than #$3==.5# are possible, including nonlinear
+ * ones. Note however, that only those points which are actually on the
+ * cut-surface are plotted.
+ *
+ *
+ * \subsection{POVRAY format}
+ *
+ * No information presently available.
+ *
+ *
+ * \subsection{EPS format}
+ *
+ * To be filled in.
+ *
+ *
+ * \subsection{GMV format}
+ *
+ * The #write_gmv# function and the #write# function through the #gmv# parameter
+ * write the data in a format understood by the GMV (general mesh viewer)
+ * program. This program is able to generate 2d and 3d plots of almost
+ * arbitrarily many data sets, along with shading, cuts through data sets and
+ * many other nifty features.
+ *
+ * Data is written in the following format: nodes are considered the points
+ * of the patches. In spatial dimensions less than three, zeroes are
+ * inserted for the missing coordinates. The data vectors are written as
+ * node or cell data, where for the first the data space is interpolated to
+ * (bi-,tri-)linear elements.
+ *
+ *
+ * \section{Output parameters}
+ *
+ * All functions take a parameter which is a structure of type #XFlags#, where
+ * #X# is the name of the output format. To find out what flags are presently
+ * supported, read the documentation of the different structures.
+ *
+ * Note that usually the output formats used for scientific visualization
+ * programs have no or very few parameters (apart from some compatibility flags)
+ * because there the actual appearance of output is determined using the
+ * visualization program and the files produced by this class store more or less
+ * only raw data.
+ *
+ * The direct output formats, like Postscript or Povray need to be given a lot
+ * more parameters, though, since there the output file has to contain all
+ * details of the viewpoint, light source, etc.
+ *
+ *
  * @author Wolfgang Bangerth 1999
  */
 class DataOutBase 
 {
   public:
-
                                     /**
                                      * Data structure describing a
                                      * patch of data in #dim# space
                                      * dimensions. See the general
-                                     * documentation for more information
-                                     * on its contents and purposes.
-                                     */
+                                     * documentation of the
+                                     * #DataOutBase# class for more
+                                     * information on its contents
+                                     * and purposes.
+                                     *
+                                     * @author Wolfgang Bangerth */
     template <int dim>
     struct Patch
     {
@@ -100,8 +210,8 @@ class DataOutBase
                                          * is the same as for cells
                                          * in the triangulation.
                                          */
-       const Point<dim> vertices[GeometryInfo<dim>::vertices_per_cell];
-
+       Point<dim> vertices[GeometryInfo<dim>::vertices_per_cell];
+       
                                         /**
                                          * Number of subdivisions with
                                          * which this patch is to be
@@ -110,8 +220,8 @@ class DataOutBase
                                          * bisection, #3# trisection,
                                          * etc.
                                          */
-       const unsigned int n_subdivisions;
-
+       unsigned int n_subdivisions;
+       
                                         /**
                                          * Data vectors. The format is
                                          * as follows:
@@ -128,19 +238,18 @@ class DataOutBase
                                          * #data(.,j)# are the data
                                          * values at the output point #j#,
                                          * where #j# runs first over the
-                                         * direction spanned by the first
-                                         * two points of the #corners#
-                                         * array, then over the direction
-                                         * spanned by points 0 and 3 and
-                                         * finally that spanned by points
-                                         * 0 and 4 (for 3d, for lower
-                                         * dimensions, this row is
-                                         * truncated, of course).
+                                         * last direction, then over the second
+                                         * last one etc, just as if it was
+                                         * organized as an array
+                                         * #double[x][y][z]#. This is also
+                                         * the order of points as provided
+                                         * by the #QIterated# class when used
+                                         * with the #QTrapez# class as subquadrature.
                                          * Note that if #subdivisions==1#,
                                          * the elements of #data[i]# correspond
                                          * to vertices #(0,1)# in 1d,
-                                         * #(0, 1, 3, 2)# in 2d, and
-                                         * #(0, 1, 3, 2, 4, 5, 7, 6)# in 3d.
+                                         * #(0, 3, 1, 2)# in 2d, and
+                                         * #(0, 4, 3, 7, 1, 5, 2, 6)# in 3d.
                                          *
                                          * Since the number of data vectors
                                          * is usually the same for all
@@ -148,16 +257,133 @@ class DataOutBase
                                          * should yield the same value for all
                                          * patches provided.
                                          */
-       const FullMatrix<double> data;
-
+       FullMatrix<double> data;
+       
                                         /**
                                          * Default constructor.
                                          */
-       Patch ();
+       Patch () :
+                       n_subdivisions(0) {};
     };
 
 
                                     /**
+                                     * Flags describing the details of
+                                     * output in UCD format.
+                                     */
+    struct UcdFlags 
+    {
+                                        /**
+                                         * Write a comment at the beginning
+                                         * of the file stating the date of
+                                         * creation and some other data.
+                                         * While this is supported by the
+                                         * UCD format (and the AVS program),
+                                         * some other programs get confused
+                                         * by this, so you can switch it off
+                                         * this way.
+                                         *
+                                         * Default: #true#.
+                                         */
+       bool write_preamble;
+       
+                                        /**
+                                         * Constructor.
+                                         */
+       UcdFlags (const bool write_preamble = true);
+    };
+
+                                    /**
+                                     * Flags describing the details of
+                                     * output in Gnuplot format. At
+                                     * present no flags are implemented.
+                                     */
+    struct GnuplotFlags 
+    {
+      private:
+                                        /**
+                                         * Dummy entry to suppress compiler
+                                         * warnings when copying an empty
+                                         * structure. Remove this member
+                                         * when adding the first flag to
+                                         * this structure (and remove the
+                                         * #private# as well).
+                                         */
+       int dummy;
+    };
+
+                                    /**
+                                     * Flags describing the details of
+                                     * output in Povray format. At
+                                     * present no flags are implemented.
+                                     */
+    struct PovrayFlags 
+    {
+      private:
+                                        /**
+                                         * Dummy entry to suppress compiler
+                                         * warnings when copying an empty
+                                         * structure. Remove this member
+                                         * when adding the first flag to
+                                         * this structure (and remove the
+                                         * #private# as well).
+                                         */
+       int dummy;
+    };
+
+                                    /**
+                                     * Flags describing the details of
+                                     * output in encapsulated postscript
+                                     * format. At present no flags are
+                                     * implemented.
+                                     */
+    struct EpsFlags 
+    {
+      private:
+                                        /**
+                                         * Dummy entry to suppress compiler
+                                         * warnings when copying an empty
+                                         * structure. Remove this member
+                                         * when adding the first flag to
+                                         * this structure (and remove the
+                                         * #private# as well).
+                                         */
+       int dummy;
+    };
+
+                                    /**
+                                     * Flags describing the details of
+                                     * output in gmv format. At
+                                     * present no flags are implemented.
+                                     */
+    struct GmvFlags 
+    {
+      private:
+                                        /**
+                                         * Dummy entry to suppress compiler
+                                         * warnings when copying an empty
+                                         * structure. Remove this member
+                                         * when adding the first flag to
+                                         * this structure (and remove the
+                                         * #private# as well).
+                                         */
+       int dummy;
+    };
+
+                                    /**
+                                     * Write the given list of patches
+                                     * to the output stream in ucd
+                                     * format. See the general
+                                     * documentation for more information
+                                     * on the parameters.
+                                     */
+    template <int dim>
+    static void write_ucd (const vector<Patch<dim> > &patches,
+                          const vector<string>      &data_names,
+                          const UcdFlags            &flags,
+                          ostream                   &out);
+
+                                    /**
                                      * Write the given list of patches
                                      * to the output stream in gnuplot
                                      * format. See the general
@@ -167,8 +393,49 @@ class DataOutBase
     template <int dim>
     static void write_gnuplot (const vector<Patch<dim> > &patches,
                               const vector<string>      &data_names,
+                              const GnuplotFlags        &flags,
                               ostream                   &out);
 
+                                    /**
+                                     * Write the given list of patches
+                                     * to the output stream in povray
+                                     * format. See the general
+                                     * documentation for more information
+                                     * on the parameters.
+                                     */
+    template <int dim>
+    static void write_povray (const vector<Patch<dim> > &patches,
+                             const vector<string>      &data_names,
+                             const PovrayFlags         &flags,
+                             ostream                   &out);
+
+                                    /**
+                                     * Write the given list of patches
+                                     * to the output stream in eps
+                                     * format. See the general
+                                     * documentation for more information
+                                     * on the parameters.
+                                     */
+    template <int dim>
+    static void write_eps (const vector<Patch<dim> > &patches,
+                          const vector<string>      &data_names,
+                          const EpsFlags            &flags,
+                          ostream                   &out);
+
+                                    /**
+                                     * Write the given list of patches
+                                     * to the output stream in gmv
+                                     * format. See the general
+                                     * documentation for more information
+                                     * on the parameters.
+                                     */
+    template <int dim>
+    static void write_gmv (const vector<Patch<dim> > &patches,
+                          const vector<string>      &data_names,
+                          const GmvFlags            &flags,
+                          ostream                   &out);
+
+    
                                     /**
                                      * Exception
                                      */
@@ -176,6 +443,7 @@ class DataOutBase
                    int, int,
                    << "The number of data sets on this patch is " << arg1
                    << ", but we expected " << arg2);
+
                                     /**
                                      * Exception
                                      */
@@ -183,11 +451,284 @@ class DataOutBase
                    int, int,
                    << "The number of points in this data set is " << arg1
                    << ", but we expected " << arg2 << " in each space direction.");
+
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcIO);
 };
 
        
 
 
+
+
+/**
+ * This class is the interface to the #DataOutBase# class, as already its name
+ * might suggest. It does not offer much functionality apart from a way to
+ * access the implemented formats and a way to dynamically dispatch what output
+ * format to chose.
+ *
+ * This class is thought as a base class to classes actually
+ * generating data for output. It has two abstract virtual functions,
+ * #get_patches# and #get_dataset_names# which are to produce the data
+ * which is actually needed. These are the only functions that need to
+ * be overloaded by a derived class.  In additional to that, it has a
+ * function for each output format supported by the underlying base
+ * class which gets the output data using these two virtual functions
+ * and passes them to the raw output functions.
+ *
+ * The purpose of this class is mainly two-fold: to support storing flags
+ * by which the output in the different output formats are controlled,
+ * and means to work with output in a way where output format, flags and
+ * other things are determined at run time. In addition to that it offers
+ * the abstract interface to derived classes briefly discussed above.
+ *
+ *
+ * \subsection{Output flags}
+ *
+ * The way we treat flags in this class is very similar to that used in
+ * the #GridOut# class. For detailed information on the why's and how's,
+ * as well as an example of programming, we refer to the documentation
+ * of that class.
+ *
+ * In basics, this class stores a set of flags for each output format
+ * supported by the underlying #DataOutBase# class. These are used
+ * whenever one of the #write_*# functions is used. By default, the
+ * values of these flags are set to reasonable start-ups, but in case
+ * you want to change them, you can create a structure holding the flags
+ * for one of the output formats and set it using the #set_flags# functions
+ * of this class to determine all future output the object might produce
+ * by that output format.
+ *
+ * For information on what parameters are supported by different output
+ * functions, please see the documentation of the #DataOutBase# class and
+ * its member classes.
+ *
+ *
+ * \subsection{Run time selection of formats}
+ *
+ * This class, much like the #GridOut# class, has a set of functions
+ * providing a list of supported output formats, an #enum# denoting
+ * all these and a function to parse a string and return the respective
+ * #enum# value if it is a valid output format's name. Finally, there
+ * is a function #write#, which takes a value of this #enum# and
+ * dispatches to one of the actual #write_*# functions depending on
+ * the output format selected by this value. 
+ *
+ * The functions offering the different output format names are,
+ * respectively, #default_suffix#, #parse_output_format#, and
+ * #get_output_format_names#. They make the selection of ouput formats
+ * in parameter files much easier, and especially independent of
+ * the formats presently implemented. User programs need therefore not
+ * be changed whenever a new format is implemented.
+ *
+ * @author Wolfgang Bangerth, 1999
+ */
+template <int dim>
+class DataOutInterface : private DataOutBase
+{
+  public:
+                                    /**
+                                     * Provide a data type specifying the
+                                     * presently supported output formats.
+                                     */
+    enum OutputFormat { ucd, gnuplot, povray, eps, gmv };
+
+                                    /**
+                                     * Obtain data through the #get_patches#
+                                     * function and write it to #out# in
+                                     * UCD format.
+                                     */
+    void write_ucd (ostream &out) const;
+
+                                    /**
+                                     * Obtain data through the #get_patches#
+                                     * function and write it to #out# in
+                                     * GNUPLOT format.
+                                     */
+    void write_gnuplot (ostream &out) const;
+
+                                    /**
+                                     * Obtain data through the #get_patches#
+                                     * function and write it to #out# in
+                                     * POVRAY format.
+                                     */
+    void write_povray (ostream &out) const;
+
+                                    /**
+                                     * Obtain data through the #get_patches#
+                                     * function and write it to #out# in
+                                     * EPS format.
+                                     */
+    void write_eps (ostream &out) const;
+
+                                    /**
+                                     * Obtain data through the #get_patches#
+                                     * function and write it to #out# in
+                                     * GMV format.
+                                     */
+    void write_gmv (ostream &out) const;
+
+                                    /**
+                                     * Write data and grid to #out# according
+                                     * to the given data format. This function
+                                     * simply calls the appropriate
+                                     * #write_*# function.
+                                     */
+    void write (ostream &out, const OutputFormat output_format) const;
+    
+                                    /**
+                                     * Set the flags to be used for output
+                                     * in UCD format.
+                                     */
+    void set_flags (const UcdFlags &ucd_flags);
+
+                                    /**
+                                     * Set the flags to be used for output
+                                     * in GNUPLOT format.
+                                     */
+    void set_flags (const GnuplotFlags &gnuplot_flags);
+
+                                    /**
+                                     * Set the flags to be used for output
+                                     * in POVRAY format.
+                                     */
+    void set_flags (const PovrayFlags &povray_flags);
+
+                                    /**
+                                     * Set the flags to be used for output
+                                     * in 1d EPS output.
+                                     */
+    void set_flags (const EpsFlags &eps_flags);
+
+                                    /**
+                                     * Set the flags to be used for output
+                                     * in GMV format.
+                                     */
+    void set_flags (const GmvFlags &gmv_flags);
+
+    
+                                    /**
+                                     * Provide a function which tells us which
+                                     * suffix with a given output format
+                                     * usually has. At present the following
+                                     * formats are defined:
+                                     * \begin{itemize}
+                                     * \item #ucd#: #.inp#
+                                     * \item #gnuplot#: #.gnuplot#
+                                     * \item #povray#: #.pov#
+                                     * \item #eps#: #.eps#
+                                     * \item #gmv#: #.gmv#.
+                                     * \end{itemize}
+                                     *
+                                     * Since this function does not need data
+                                     * from this object, it is static and can
+                                     * thus be called without creating an
+                                     * object of this class.
+                                     */
+    static string default_suffix (const OutputFormat output_format);
+
+                                    /**
+                                     * Return the #OutputFormat# value
+                                     * corresponding to the given string. If
+                                     * the string does not match any known
+                                     * format, an exception is thrown.
+                                     *
+                                     * Since this function does not need data
+                                     * from this object, it is static and can
+                                     * thus be called without creating an
+                                     * object of this class. Its main purpose
+                                     * is to allow a program to use any
+                                     * implemented output format without the
+                                     * need to extend the program's parser
+                                     * each time a new format is implemented.
+                                     *
+                                     * To get a list of presently available
+                                     * format names, e.g. to give it to the
+                                     * #ParameterHandler# class, use the
+                                     * function #get_output_format_names ()#.
+                                     */
+    static OutputFormat parse_output_format (const string &format_name);
+
+                                    /**
+                                     * Return a list of implemented output
+                                     * formats. The different names are
+                                     * separated by vertical bar signs (#`|'#)
+                                     * as used by the #ParameterHandler#
+                                     * classes.
+                                     */
+    static string get_output_format_names ();
+
+                                    /**
+                                     * Exception
+                                     */
+    DeclException0 (ExcInvalidState);
+    
+  protected:
+                                    /**
+                                     * This is the abstract function through
+                                     * which derived classes propagate
+                                     * preprocessed data in the form of
+                                     * #Patch# structures (declared in
+                                     * the base class #DataOutBase#) to
+                                     * the actual output function. You
+                                     * need to overload this function to
+                                     * allow the output functions to
+                                     * know what they shall print.
+                                     */
+    virtual const vector<DataOutBase::Patch<dim> > & get_patches () const = 0;
+
+                                    /**
+                                     * Abstract virtual function through
+                                     * which the names of data sets are
+                                     * obtained by the output functions
+                                     * of the base class.
+                                     */
+    virtual vector<string> get_dataset_names () const = 0;
+
+  private:
+                                    /**
+                                     * Flags to be used upon output of UCD
+                                     * data. Can be changed by using the
+                                     * #set_flags# function.
+                                     */
+    UcdFlags     ucd_flags;
+
+                                    /**
+                                     * Flags to be used upon output of GNUPLOT
+                                     * data. Can be changed by using the
+                                     * #set_flags# function.
+                                     */
+    GnuplotFlags gnuplot_flags;
+
+                                    /**
+                                     * Flags to be used upon output of POVRAY
+                                     * data. Can be changed by using the
+                                     * #set_flags# function.
+                                     */
+    PovrayFlags povray_flags;
+
+                                    /**
+                                     * Flags to be used upon output of EPS
+                                     * data in one space dimension. Can be
+                                     * changed by using the #set_flags#
+                                     * function.
+                                     */
+    EpsFlags     eps_flags;    
+
+                                    /**
+                                     * Flags to be used upon output of gmv
+                                     * data in one space dimension. Can be
+                                     * changed by using the #set_flags#
+                                     * function.
+                                     */
+    GmvFlags     gmv_flags;    
+};
+
+
+
+
 /*----------------------------   data_out_base.h     ---------------------------*/
 /* end of #ifndef __data_out_base_H */
 #endif
index 55ae154eee936b9c28811391b491879530498427..13ac996d17dc3f80bde36ca9720d1873382fc7e3 100644 (file)
@@ -47,7 +47,7 @@ MG<dim>::copy_to_mg(const Vector<number>& src)
     ofstream of("CT");
     DataOut<2> out;
     out.attach_dof_handler(*dofs);
-    out.add_data_vector(src,"solution","m");
+    out.add_data_vector(src,"solution");
     out.write_gnuplot(of,1);
   }
 
@@ -120,7 +120,7 @@ MG<dim>::copy_from_mg(Vector<number>& dst) const
     ofstream of("CF");
     DataOut<2> out;
     out.attach_dof_handler(*dofs);
-    out.add_data_vector(dst,"solution","m");
+    out.add_data_vector(dst,"solution");
     out.write_gnuplot(of,1);
   }
 }
index 766117295dea2df7b290c3d25889253d7d790731..3a9b43a0629c75c65f590bd6da53966e98c66ebc 100644 (file)
@@ -8,7 +8,7 @@
 #include <numerics/vectors.h>
 #include <grid/dof_constraints.h>
 #include <grid/tria_iterator.h>
-#include <basic/data_io.h>
+#include <basic/data_out.h>
 #include <base/function.h>
 #include <fe/fe.h>
 #include <base/quadrature.h>
@@ -159,19 +159,17 @@ template <int dim>
 void ProblemBase<dim>::fill_data (DataOut<dim> &out) const {
   Assert ((tria!=0) && (dof_handler!=0), ExcNoTriaSelected());
   
-  out.clear_data_vectors ();
+  out.clear ();
   out.attach_dof_handler (*dof_handler);
 
-  pair<char*,char*> solution_name = get_solution_name ();
-  out.add_data_vector (solution,
-                      solution_name.first, solution_name.second);
+  out.add_data_vector (solution, get_solution_name());
 };
 
 
 
 template <int dim>
-pair<char*,char*> ProblemBase<dim>::get_solution_name () const {
-  return pair<char*,char*>("solution", "<dimensionless>");
+string ProblemBase<dim>::get_solution_name () const {
+  return "solution";
 };
 
 
index b64acd41349951a95d72e67fcc8004dccb02f1d1..9ce4a6627e4965fb187953d337aa8d781edff512 100644 (file)
@@ -173,13 +173,13 @@ void DataIn<dim>::read_ucd (istream &in) {
 
 
 template <int dim>
-DataOut<dim>::DataEntry::DataEntry () :
+DataOut_Old<dim>::DataEntry::DataEntry () :
                data(0), name(""), units("") {};
 
 
 
 template <int dim>
-DataOut<dim>::DataEntry::DataEntry (const Vector<double> *data,
+DataOut_Old<dim>::DataEntry::DataEntry (const Vector<double> *data,
                                    const string name,
                                    const string units) :
                        data(data), name(name), units(units) {};
@@ -188,20 +188,20 @@ DataOut<dim>::DataEntry::DataEntry (const Vector<double> *data,
 
 
 template <int dim>
-DataOut<dim>::DataOut () :
+DataOut_Old<dim>::DataOut_Old () :
                dofs(0) {};
 
 
 
 template <int dim>
-void DataOut<dim>::attach_dof_handler (const DoFHandler<dim> &d) {
+void DataOut_Old<dim>::attach_dof_handler (const DoFHandler<dim> &d) {
   dofs = &d;
 };
 
 
 
 template <int dim>
-void DataOut<dim>::add_data_vector (const Vector<double> &vec,
+void DataOut_Old<dim>::add_data_vector (const Vector<double> &vec,
                                    const string  &name,
                                    const string  &units) {
   Assert (dofs != 0, ExcNoDoFHandlerSelected ());
@@ -230,7 +230,7 @@ void DataOut<dim>::add_data_vector (const Vector<double> &vec,
 
 
 template <int dim>
-void DataOut<dim>::clear_data_vectors () {
+void DataOut_Old<dim>::clear_data_vectors () {
   dof_data.erase (dof_data.begin(), dof_data.end());
   cell_data.erase (cell_data.begin(), cell_data.end());
 };
@@ -238,7 +238,7 @@ void DataOut<dim>::clear_data_vectors () {
 
 
 template <int dim>
-void DataOut<dim>::write_ucd (ostream &out) const {
+void DataOut_Old<dim>::write_ucd (ostream &out) const {
   Assert (dofs != 0, ExcNoDoFHandlerSelected());
   Assert (dofs->get_fe().dofs_per_vertex==1,
          ExcIncorrectDofsPerVertex());
@@ -457,7 +457,7 @@ void DataOut<dim>::write_ucd (ostream &out) const {
 #if deal_II_dimension == 1
 
 template <>
-unsigned int DataOut<1>::n_boundary_faces () const {
+unsigned int DataOut_Old<1>::n_boundary_faces () const {
   return 0;
 };
 
@@ -466,7 +466,7 @@ unsigned int DataOut<1>::n_boundary_faces () const {
 
 
 template <int dim>
-unsigned int DataOut<dim>::n_boundary_faces () const {
+unsigned int DataOut_Old<dim>::n_boundary_faces () const {
   typename DoFHandler<dim>::active_face_iterator face, endf;
   unsigned long int n_faces = 0;
 
@@ -485,7 +485,7 @@ unsigned int DataOut<dim>::n_boundary_faces () const {
 #if deal_II_dimension == 1
 
 template <>
-void DataOut<1>::write_ucd_faces (ostream &, const unsigned int) const {
+void DataOut_Old<1>::write_ucd_faces (ostream &, const unsigned int) const {
   return;
 };
 
@@ -493,7 +493,7 @@ void DataOut<1>::write_ucd_faces (ostream &, const unsigned int) const {
 
 
 template <int dim>
-void DataOut<dim>::write_ucd_faces (ostream &out,
+void DataOut_Old<dim>::write_ucd_faces (ostream &out,
                                    const unsigned int starting_index) const {
   typename DoFHandler<dim>::active_face_iterator face, endf;
   unsigned int index=starting_index;
@@ -528,7 +528,7 @@ void DataOut<dim>::write_ucd_faces (ostream &out,
 
 
 template <int dim>
-void DataOut<dim>::write_gnuplot (ostream &out, unsigned int accuracy) const
+void DataOut_Old<dim>::write_gnuplot (ostream &out, unsigned int accuracy) const
 {
   Assert (dofs != 0, ExcNoDoFHandlerSelected());
   Assert ((1<=dim) && (dim<=3), ExcNotImplemented());
@@ -710,7 +710,7 @@ void DataOut<dim>::write_gnuplot (ostream &out, unsigned int accuracy) const
 
 
 template <int dim>
-void DataOut<dim>::write_gnuplot_draft (ostream &out) const
+void DataOut_Old<dim>::write_gnuplot_draft (ostream &out) const
 {
   Assert (dofs != 0, ExcNoDoFHandlerSelected());
   Assert ((1<=dim) && (dim<=3), ExcNotImplemented());
@@ -916,7 +916,7 @@ void DataOut<dim>::write_gnuplot_draft (ostream &out) const
 #if deal_II_dimension == 2
 
 template <>
-void DataOut<2>::write_povray_mesh (ostream &out) const {
+void DataOut_Old<2>::write_povray_mesh (ostream &out) const {
   Assert (dofs != 0, ExcNoDoFHandlerSelected());
 
                                   // write preamble
@@ -1023,7 +1023,7 @@ void DataOut<2>::write_povray_mesh (ostream &out) const {
 
 
 template <int dim>
-void DataOut<dim>::write_povray_mesh (ostream &) const {
+void DataOut_Old<dim>::write_povray_mesh (ostream &) const {
                                   // this is for all other dimensions that
                                   // are not explicitely specialized
   Assert (false, ExcNotImplemented());
@@ -1035,7 +1035,7 @@ void DataOut<dim>::write_povray_mesh (ostream &) const {
 #if deal_II_dimension == 2
 
 template <>
-void DataOut<2>::write_eps (ostream &out, const EpsOutputData &eod) const {
+void DataOut_Old<2>::write_eps (ostream &out, const EpsOutputData &eod) const {
   Assert (dofs != 0, ExcNoDoFHandlerSelected());
 
   {
@@ -1063,8 +1063,8 @@ void DataOut<2>::write_eps (ostream &out, const EpsOutputData &eod) const {
                                    // copying them to a multiset.
                                    // Perform the necessary turn.
    const DoFHandler<2>::active_cell_iterator endc = dofs->end();
-   multiset<DataOut<2>::EpsCellData> cells;
-   multiset<DataOut<2>::EpsCellData> cells2;
+   multiset<DataOut_Old<2>::EpsCellData> cells;
+   multiset<DataOut_Old<2>::EpsCellData> cells2;
    
    bool height_data_p = (
                           ((dof_data.size())>0) 
@@ -1140,7 +1140,7 @@ void DataOut<2>::write_eps (ostream &out, const EpsOutputData &eod) const {
    float cell_vector_min=cells.begin()->red; 
    float cell_vector_max=cell_vector_min;
 
-   for(multiset<DataOut<2>::EpsCellData>::iterator c=cells.begin();
+   for(multiset<DataOut_Old<2>::EpsCellData>::iterator c=cells.begin();
        c!=cells.end(); ++c, ++cell_index)
      {
        for (unsigned int i=0; i<4; ++i)
@@ -1173,7 +1173,7 @@ void DataOut<2>::write_eps (ostream &out, const EpsOutputData &eod) const {
        double light_norm, normal_norm;
        float color;
 
-       for (multiset<DataOut<2>::EpsCellData>::iterator c=cells.begin();c!=cells.end();++c)
+       for (multiset<DataOut_Old<2>::EpsCellData>::iterator c=cells.begin();c!=cells.end();++c)
         {
           EpsCellData cd(*c);
 
@@ -1229,7 +1229,7 @@ void DataOut<2>::write_eps (ostream &out, const EpsOutputData &eod) const {
 
    const double scale = 300 / (xmax-xmin > ymax-ymin ? xmax-xmin : ymax-ymin);
    
-   for (multiset<DataOut<2>::EpsCellData>::iterator c=cells2.begin();
+   for (multiset<DataOut_Old<2>::EpsCellData>::iterator c=cells2.begin();
        c!=cells2.end(); ++c)
      {
        EpsCellData cd (*c);
@@ -1247,7 +1247,7 @@ void DataOut<2>::write_eps (ostream &out, const EpsOutputData &eod) const {
 
 
                                    //  Now we are ready to output...
-   for (multiset<DataOut<2>::EpsCellData>::iterator c=cells.begin();
+   for (multiset<DataOut_Old<2>::EpsCellData>::iterator c=cells.begin();
        c!=cells.end(); ++c)
      {
        if (cell_data_p || cell_shade_p)
@@ -1290,7 +1290,7 @@ void DataOut<2>::write_eps (ostream &out, const EpsOutputData &eod) const {
 
 
 template <int dim>
-void DataOut<dim>::write_eps (ostream &,
+void DataOut_Old<dim>::write_eps (ostream &,
                              const EpsOutputData &) const{
                                   // this is for all other dimensions that
                                   // are not explicitely specialized
@@ -1301,7 +1301,7 @@ void DataOut<dim>::write_eps (ostream &,
 
 
 template <int dim>
-void DataOut<dim>::write_gmv (ostream &out) const
+void DataOut_Old<dim>::write_gmv (ostream &out) const
 {
                                   // this function is mostly copied from
                                   // the ucd format function
@@ -1525,7 +1525,7 @@ void DataOut<dim>::write_gmv (ostream &out) const
 
 
 template <int dim>
-void DataOut<dim>::write (ostream &out,
+void DataOut_Old<dim>::write (ostream &out,
                          const OutputFormat output_format) const {
   switch (output_format) 
     {
@@ -1561,7 +1561,7 @@ void DataOut<dim>::write (ostream &out,
 
 
 template <int dim>
-string DataOut<dim>::default_suffix (const OutputFormat output_format) 
+string DataOut_Old<dim>::default_suffix (const OutputFormat output_format) 
 {
   switch (output_format) 
     {
@@ -1590,8 +1590,8 @@ string DataOut<dim>::default_suffix (const OutputFormat output_format)
 
 
 template <int dim>
-DataOut<dim>::OutputFormat
-DataOut<dim>::parse_output_format (const string &format_name) {
+DataOut_Old<dim>::OutputFormat
+DataOut_Old<dim>::parse_output_format (const string &format_name) {
   if (format_name == "ucd")
     return ucd;
 
@@ -1618,14 +1618,14 @@ DataOut<dim>::parse_output_format (const string &format_name) {
 
 
 template <int dim>
-string DataOut<dim>::get_output_format_names () {
+string DataOut_Old<dim>::get_output_format_names () {
   return "ucd|gnuplot|gnuplot draft|povray mesh|eps|gmv";
 };
 
 
 
 template<int dim>
-bool DataOut<dim>::EpsCellData::operator < (const EpsCellData &other) const
+bool DataOut_Old<dim>::EpsCellData::operator < (const EpsCellData &other) const
 {
   double maxz = vertices[0].z, 
          othermaxz = other.vertices[0].z;
@@ -1643,7 +1643,7 @@ bool DataOut<dim>::EpsCellData::operator < (const EpsCellData &other) const
 
 
 template <int dim>
-void DataOut<dim>::EpsVertexData::turn(double azi, double ele)
+void DataOut_Old<dim>::EpsVertexData::turn(double azi, double ele)
 {
   double nx,ny,nz;
 
@@ -1675,7 +1675,7 @@ void DataOut<dim>::EpsVertexData::turn(double azi, double ele)
 
 
 template <int dim>
-void DataOut<dim>::EpsCellData::turn(double azi, double ele)
+void DataOut_Old<dim>::EpsCellData::turn(double azi, double ele)
 {
   for (unsigned i=0; i<4; ++i)
     vertices[i].turn(azi,ele);
@@ -1782,4 +1782,4 @@ void EpsOutputData::color(const float x,
 //explicit instantiations
 
 template class DataIn<deal_II_dimension>;
-template class DataOut<deal_II_dimension>;
+template class DataOut_Old<deal_II_dimension>;
index a0749a0c2c0c92aeb7c5f5fa6ace589ef08aceeb..e39d5c8898f28b8c1a271cfd3b0a87414e3b1008 100644 (file)
@@ -1 +1,253 @@
 /* $Id$ */
+
+
+#include <base/quadrature_lib.h>
+#include <lac/vector.h>
+#include <basic/data_out.h>
+#include <grid/tria.h>
+#include <grid/dof.h>
+#include <grid/dof_accessor.h>
+#include <grid/tria_iterator.h>
+#include <fe/fe.h>
+#include <fe/fe_values.h>
+
+
+template <int dim>
+DataOut_DoFData<dim>::DataEntry::DataEntry (const Vector<double> *data,
+                                           const vector<string> &names) :
+               data(data),
+               names(names)
+{};
+
+
+
+
+template <int dim>
+DataOut_DoFData<dim>::DataOut_DoFData () :
+               dofs(0)
+{};
+
+
+
+template <int dim>
+DataOut_DoFData<dim>::~DataOut_DoFData ()
+{
+  clear ();
+};
+
+
+
+template <int dim>
+void DataOut_DoFData<dim>::attach_dof_handler (const DoFHandler<dim> &d)
+{
+  Assert (dof_data.size() == 0, ExcOldDataStillPresent());
+  Assert (cell_data.size() == 0, ExcOldDataStillPresent());
+  
+  if (dofs != 0)
+    dofs->unsubscribe ();
+  
+  dofs = &d;
+  if (dofs != 0)
+    dofs->subscribe ();
+};
+
+
+
+template <int dim>
+void DataOut_DoFData<dim>::add_data_vector (const Vector<double> &vec,
+                                           const vector<string> &names)
+{
+  Assert (dofs != 0, ExcNoDoFHandlerSelected ());
+                                  // either cell data and one name,
+                                  // or dof data and n_components names
+  Assert (((vec.size() == dofs->get_tria().n_active_cells()) &&
+          (names.size() == 1))
+         ||
+         ((vec.size() == dofs->n_dofs()) &&
+          (names.size() == dofs->get_fe().n_components)),
+         ExcInvalidNumberOfNames (names.size(), dofs->get_fe().n_components));
+  for (unsigned int i=0; i<names.size(); ++i)
+    Assert (names[i].find_first_not_of("abcdefghijklmnopqrstuvwxyz"
+                                      "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                      "0123456789_<>()") == string::npos,
+           ExcInvalidCharacter (names[i]));
+  
+  DataEntry new_entry (&vec, names);
+  if (vec.size() == dofs->n_dofs())
+    dof_data.push_back (new_entry);
+  else
+    if (vec.size() == dofs->get_tria().n_active_cells())
+      cell_data.push_back (new_entry);
+    else
+      Assert (false,
+             ExcInvalidVectorSize (vec.size(),
+                                   dofs->n_dofs(),
+                                   dofs->get_tria().n_active_cells()));
+};
+
+
+
+template <int dim>
+void DataOut_DoFData<dim>::add_data_vector (const Vector<double> &vec,
+                                           const string         &name)
+{
+  add_data_vector (vec, vector<string>(1,name));
+};
+
+
+
+
+template <int dim>
+void DataOut_DoFData<dim>::clear ()
+{
+  dof_data.erase (dof_data.begin(), dof_data.end());
+  cell_data.erase (cell_data.begin(), cell_data.end());
+
+  if (dofs != 0)
+    {
+      dofs->unsubscribe ();
+      dofs = 0;
+    };
+
+                                  // delete patches
+  vector<DataOutBase::Patch<dim> > dummy;
+  patches.swap (dummy);
+};
+
+
+
+template <int dim>
+vector<string> DataOut_DoFData<dim>::get_dataset_names () const 
+{
+  vector<string> names;
+                                  // collect the names of dof
+                                  // and cell data
+  for (vector<DataEntry>::const_iterator d=dof_data.begin(); d!=dof_data.end(); ++d)
+    for (unsigned int i=0; i<d->names.size(); ++i)
+      names.push_back (d->names[i]);
+  for (vector<DataEntry>::const_iterator d=cell_data.begin(); d!=cell_data.end(); ++d)
+    {
+      Assert (d->names.size() == 1, ExcInternalError());
+      names.push_back (d->names[0]);
+    };
+
+  return names;
+};
+
+
+
+template <int dim>
+const vector<typename DataOutBase::Patch<dim> > &
+DataOut_DoFData<dim>::get_patches () const
+{
+  return patches;
+};
+
+
+
+
+
+
+template <int dim>
+void DataOut<dim>::build_patches (const unsigned int n_subdivisions) 
+{
+  Assert (dofs != 0, ExcNoDoFHandlerSelected());
+  
+  const unsigned int n_components   = dofs->get_fe().n_components;
+  const unsigned int n_datasets     = dof_data.size() * n_components +
+                                     cell_data.size();
+  
+                                  // clear the patches array
+  if (true)
+    {
+      vector<DataOutBase::Patch<dim> > dummy;
+      patches.swap (dummy);
+    };
+  
+
+                                  // first count the cells we want to
+                                  // create patches of and make sure
+                                  // there is enough memory for that
+  unsigned int n_patches = 0;
+  for (DoFHandler<dim>::active_cell_iterator cell=dofs->begin_active();
+       cell != dofs->end(); ++cell)
+    ++n_patches;
+
+
+                                  // before we start the loop:
+                                  // create a quadrature rule that
+                                  // actually has the points on this
+                                  // patch, and an object that
+                                  // extracts the data on each
+                                  // cell to these points
+  QTrapez<1>     q_trapez;
+  QIterated<dim> patch_points (q_trapez, n_subdivisions);
+  FEValues<dim>  fe_patch_values (dofs->get_fe(),
+                                 patch_points,
+                                 update_default);
+  const unsigned int n_q_points = patch_points.n_quadrature_points;
+  vector<double>          patch_values (n_q_points);
+  vector<Vector<double> > patch_values_system (n_q_points,
+                                              Vector<double>(n_components));
+  
+  DataOutBase::Patch<dim>  default_patch;
+  default_patch.n_subdivisions = n_subdivisions;
+  default_patch.data.reinit (n_datasets, n_q_points);
+  patches.insert (patches.end(), n_patches, default_patch);
+
+                                  // now loop over all cells and
+                                  // actually create the patches
+  vector<DataOutBase::Patch<dim> >::iterator patch = patches.begin();
+  unsigned int                               cell_number = 0;
+  for (DoFHandler<dim>::active_cell_iterator cell=dofs->begin_active();
+       cell != dofs->end(); ++cell, ++patch, ++cell_number)
+    {
+      Assert (patch != patches.end(), ExcInternalError());
+      
+      for (unsigned int vertex=0; vertex<GeometryInfo<dim>::vertices_per_cell; ++vertex)
+       patch->vertices[vertex] = cell->vertex(vertex);
+
+      if (n_datasets > 0)
+       {
+         fe_patch_values.reinit (cell);
+         
+                                          // first fill dof_data
+         for (unsigned int dataset=0; dataset<dof_data.size(); ++dataset)
+           {
+             if (n_components == 1)
+               {
+                 fe_patch_values.get_function_values (*dof_data[dataset].data,
+                                                      patch_values);
+                 for (unsigned int q=0; q<n_q_points; ++q)
+                   patch->data(dataset,q) = patch_values[q];
+               }
+             else
+                                                // system of components
+               {
+                 fe_patch_values.get_function_values (*dof_data[dataset].data,
+                                                      patch_values_system);
+                 for (unsigned int component=0; component<n_components; ++component)
+                   for (unsigned int q=0; q<n_q_points; ++q)
+                     patch->data(dataset*n_components+component,q) = patch_values_system[q](component);
+               };
+           };
+
+                                          // then do the cell data
+         for (unsigned int dataset=0; dataset<cell_data.size(); ++dataset)
+           {
+             const double value = (*cell_data[dataset].data)(cell_number);
+             for (unsigned int q=0; q<n_q_points; ++q)
+               patch->data(dataset,q) = value;
+           };
+       };
+    };
+};
+
+
+
+
+
+
+// explicit instantiations
+template class DataOut_DoFData<deal_II_dimension>;
+template class DataOut<deal_II_dimension>;
index 2381ebcebb816cbaf76d4ea3d564108f64b580ee..c49ce9c4e6bc29b2c537de96504d18680cdca79f 100644 (file)
 
 
 
-template <int dim>
-DataOutBase::Patch::Patch () :
-               n_subdivisions (0)
-                                // all the rest has a constructor of its own
+// egcs does not understand this at present.
+//
+// template <int dim>
+// DataOut::Patch<dim>::Patch () :
+//             n_subdivisions (0)
+//                              // all the rest has a constructor of its own
+// {};
+
+
+
+DataOutBase::UcdFlags::UcdFlags (const bool write_preamble) :
+               write_preamble (write_preamble)
 {};
 
 
 
 
+template <int dim>
+void DataOutBase::write_ucd (const vector<Patch<dim> > &patches,
+                            const vector<string>      &data_names,
+                            const UcdFlags            &flags,
+                            ostream                   &out) 
+{
+  AssertThrow (out, ExcIO());
+
+  const unsigned int n_data_sets = data_names.size();
+  
+                                  // first count the number of cells
+                                  // and cells for later use
+  unsigned int n_cells = 0,
+              n_nodes = 0;
+  for (vector<Patch<dim> >::const_iterator patch=patches.begin();
+       patch!=patches.end(); ++patch)
+    switch (dim)
+      {
+       case 1:
+             n_cells += patch->n_subdivisions;
+             n_nodes += patch->n_subdivisions+1;
+             break;
+       case 2:
+             n_cells += patch->n_subdivisions *
+                        patch->n_subdivisions;
+             n_nodes += (patch->n_subdivisions+1) *
+                        (patch->n_subdivisions+1);
+             break;
+       case 3:
+             n_cells += patch->n_subdivisions *
+                        patch->n_subdivisions *
+                        patch->n_subdivisions;
+             n_nodes += (patch->n_subdivisions+1) *
+                        (patch->n_subdivisions+1) *
+                        (patch->n_subdivisions+1);
+             break;
+       default:
+             Assert (false, ExcNotImplemented());
+      };
+
+                                  ///////////////////////
+                                  // preamble
+  if (flags.write_preamble)
+    {
+      time_t  time1= time (0);
+      tm     *time = localtime(&time1); 
+      out << "# This file was generated by the deal.II library." << endl
+         << "# Date =  "
+         << time->tm_year+1900 << "/"
+         << time->tm_mon+1 << "/"
+         << time->tm_mday << endl
+         << "# Time =  "
+         << time->tm_hour << ":"
+         << setw(2) << time->tm_min << ":"
+         << setw(2) << time->tm_sec << endl
+         << "#" << endl
+         << "# For a description of the UCD format see the AVS Developer's guide."
+         << endl
+         << "#" << endl;
+    };
+
+                                  // start with ucd data
+  out << n_nodes << ' '
+      << n_cells << ' '
+      << n_data_sets << ' '
+      << 0 << ' '                  // no cell data at present
+      << 0                         // no model data
+      << endl;
+
+                                  ///////////////////////////////
+                                  // first make up the list of used
+                                  // nodes along with their
+                                  // coordinates. number them
+                                  // consecutively starting with 1
+                                  //
+                                  // note that we have to print
+                                  // d=1..3 dimensions
+  if (true)
+    {
+      unsigned int present_node = 1;
+      
+      for (vector<Patch<dim> >::const_iterator patch=patches.begin();
+          patch!=patches.end(); ++patch)
+       {
+         const unsigned int n_subdivisions = patch->n_subdivisions;
+         
+                                          // if we have nonzero values for
+                                          // this coordinate
+         switch (dim)
+           {
+             case 1:
+             {
+               for (unsigned int i=0; i<n_subdivisions+1; ++i, ++present_node)
+                 out << present_node
+                     << "   "
+                     << ((patch->vertices[1](0) * i / n_subdivisions) +
+                         (patch->vertices[0](0) * (n_subdivisions-i) / n_subdivisions))
+                     << " 0 0\n";                        // fill with zeroes
+               break;
+             };
+              
+             case 2:
+             {
+               for (unsigned int i=0; i<n_subdivisions+1; ++i)
+                 for (unsigned int j=0; j<n_subdivisions+1; ++j)
+                   {
+                     const double x_frac = i * 1./n_subdivisions,
+                                  y_frac = j * 1./n_subdivisions;
+                     
+                                                      // compute coordinates for
+                                                      // this patch point
+                     out << present_node
+                         << "  "
+                         << (((patch->vertices[1] * x_frac) +
+                              (patch->vertices[0] * (1-x_frac))) * (1-y_frac) +
+                             ((patch->vertices[2] * x_frac) +
+                              (patch->vertices[3] * (1-x_frac))) * y_frac)
+                         << " 0\n";                   // fill with zeroes
+
+                     ++present_node;
+                   };
+             
+               break;
+             };
+              
+             case 3:
+             {
+               for (unsigned int i=0; i<n_subdivisions+1; ++i)
+                 for (unsigned int j=0; j<n_subdivisions+1; ++j)
+                   for (unsigned int k=0; k<n_subdivisions+1; ++k)
+                     {
+                                                        // note the broken
+                                                        // design of hexahedra
+                                                        // in deal.II, where
+                                                        // first the z-component
+                                                        // is counted up, before
+                                                        // increasing the y-
+                                                        // coordinate
+                       const double x_frac = i * 1./n_subdivisions,
+                                    y_frac = k * 1./n_subdivisions,
+                                    z_frac = j * 1./n_subdivisions;
+                       
+                                                        // compute coordinates for
+                                                        // this patch point
+                       out << present_node
+                           << "  "
+                           << ((((patch->vertices[1] * x_frac) +
+                                 (patch->vertices[0] * (1-x_frac))) * (1-y_frac) +
+                                ((patch->vertices[2] * x_frac) +
+                                 (patch->vertices[3] * (1-x_frac))) * y_frac)   * (1-z_frac) +
+                               (((patch->vertices[5] * x_frac) +
+                                 (patch->vertices[4] * (1-x_frac))) * (1-y_frac) +
+                                ((patch->vertices[6] * x_frac) +
+                                 (patch->vertices[7] * (1-x_frac))) * y_frac)   * z_frac)
+                           << endl;
+                       
+                       ++present_node;
+                     };
+             
+               break;
+             };
+              
+             default:
+                   Assert (false, ExcNotImplemented());
+           };
+       };
+
+                                      // note that we number starting with 1!
+      Assert (present_node == n_nodes+1,
+             ExcInternalError());
+    };
+
+                                  /////////////////////////////////////////
+                                  // write cell. number them consecutively,
+                                  // starting with 1
+  if (true)
+    {
+      unsigned int present_cell = 1;      
+      unsigned int first_vertex_of_patch = 0;
+      
+      for (vector<Patch<dim> >::const_iterator patch=patches.begin();
+          patch!=patches.end(); ++patch)
+       {
+         const unsigned int n_subdivisions = patch->n_subdivisions;
+         
+                                          // write out the cells making
+                                          // up this patch
+         switch (dim)
+           {
+             case 1:
+             {
+               for (unsigned int i=0; i<n_subdivisions; ++i, ++present_cell)
+                 out << present_cell
+                     << " 0  line  "        // set material id to 0
+                     << first_vertex_of_patch+i+1 << ' '
+                     << first_vertex_of_patch+i+1+1 << endl;
+               break;
+             };
+              
+             case 2:
+             {
+               for (unsigned int i=0; i<n_subdivisions; ++i)
+                 for (unsigned int j=0; j<n_subdivisions; ++j)
+                   {
+                     out << present_cell
+                         << " 0  quad  "    // set material id to 0
+                         << first_vertex_of_patch+i*(n_subdivisions+1)+j+1 << ' '
+                         << first_vertex_of_patch+(i+1)*(n_subdivisions+1)+j+1 << ' '
+                         << first_vertex_of_patch+(i+1)*(n_subdivisions+1)+j+1+1 << ' '
+                         << first_vertex_of_patch+i*(n_subdivisions+1)+j+1+1
+                         << endl;
+                     ++present_cell;
+                   };
+               break;
+             };
+              
+             case 3:
+             {
+               for (unsigned int i=0; i<n_subdivisions; ++i)
+                 for (unsigned int j=0; j<n_subdivisions; ++j)
+                   for (unsigned int k=0; k<n_subdivisions; ++k)
+                     {
+                       out << present_cell
+                           << " 0  hex  "    // set material id to 0
+                                                          // note: vertex indices start with 1!
+                           << first_vertex_of_patch+(i*(n_subdivisions+1)+j      )*(n_subdivisions+1)+k  +1 << ' '
+                           << first_vertex_of_patch+((i+1)*(n_subdivisions+1)+j  )*(n_subdivisions+1)+k  +1 << ' '
+                           << first_vertex_of_patch+((i+1)*(n_subdivisions+1)+j+1)*(n_subdivisions+1)+k  +1 << ' '
+                           << first_vertex_of_patch+(i*(n_subdivisions+1)+j+1    )*(n_subdivisions+1)+k  +1 << ' '
+                           << first_vertex_of_patch+(i*(n_subdivisions+1)+j      )*(n_subdivisions+1)+k+1+1 << ' '
+                           << first_vertex_of_patch+((i+1)*(n_subdivisions+1)+j  )*(n_subdivisions+1)+k+1+1 << ' '
+                           << first_vertex_of_patch+((i+1)*(n_subdivisions+1)+j+1)*(n_subdivisions+1)+k+1+1 << ' '
+                           << first_vertex_of_patch+(i*(n_subdivisions+1)+j+1    )*(n_subdivisions+1)+k+1+1 << ' '
+                           << endl;
+                       ++present_cell;
+                     };
+               break;
+             };
+
+             default:
+                   Assert (false, ExcNotImplemented());
+           };
+         
+         
+                                          // finally update the number
+                                          // of the first vertex of this patch
+         switch (dim)
+           {
+             case 1:
+                   first_vertex_of_patch += n_subdivisions+1;
+                   break;
+             case 2:
+                   first_vertex_of_patch += (n_subdivisions+1) *
+                                            (n_subdivisions+1);
+                   break;
+             case 3:
+                   first_vertex_of_patch += (n_subdivisions+1) *
+                                            (n_subdivisions+1) *
+                                            (n_subdivisions+1);
+                   break;
+             default:
+                   Assert (false, ExcNotImplemented());
+           };
+       };
+      out << endl;
+
+                                      // note that we number starting with 1!
+      Assert (present_cell == n_cells+1,
+             ExcInternalError());
+    };
+
+
+                                  /////////////////////////////
+                                  // now write data
+  if (n_data_sets != 0)
+    {      
+      out << n_data_sets << "    ";    // number of vectors
+      for (unsigned int i=0; i<n_data_sets; ++i)
+       out << 1 << ' ';               // number of components;
+                                      // only 1 supported presently
+      out << endl;
+
+      for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+       out << data_names[data_set]
+           << ",dimensionless"      // no units supported at present
+           << endl;
+      
+      
+                                      // loop over all patches
+      unsigned int present_node = 1;
+      for (typename vector<Patch<dim> >::const_iterator patch=patches.begin();
+          patch != patches.end(); ++patch)
+       {
+         const unsigned int n_subdivisions = patch->n_subdivisions;
+      
+         Assert (patch->data.m() == n_data_sets,
+                 ExcUnexpectedNumberOfDatasets (patch->data.m(), n_data_sets));
+         Assert (patch->data.n() == (dim==1 ?
+                                     n_subdivisions+1 :
+                                     (dim==2 ?
+                                      (n_subdivisions+1)*(n_subdivisions+1) :
+                                      (dim==3 ?
+                                       (n_subdivisions+1)*(n_subdivisions+1)*(n_subdivisions+1) :
+                                       0))),
+                 ExcInvalidDatasetSize (patch->data.n(), n_subdivisions+1));
+
+         switch (dim)
+           {
+             case 1:
+             {      
+               for (unsigned int i=0; i<n_subdivisions+1; ++i, ++present_node) 
+                 {
+                   out << present_node
+                       << "  ";
+                   for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                     out << patch->data(data_set,i) << ' ';
+
+                   out << endl;
+                 };
+           
+               break;
+             };
+          
+             case 2:
+             {
+               for (unsigned int i=0; i<n_subdivisions+1; ++i)
+                 for (unsigned int j=0; j<n_subdivisions+1; ++j)
+                   {
+                     out << present_node
+                         << "  ";
+                     for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                       out << patch->data(data_set,i*(n_subdivisions+1) + j) << ' ';
+
+                     out << endl;
+
+                     ++present_node;
+                   };
+
+               break;
+             };
+
+             case 3:
+             {
+               for (unsigned int i=0; i<n_subdivisions+1; ++i)
+                 for (unsigned int j=0; j<n_subdivisions+1; ++j)
+                   for (unsigned int k=0; k<n_subdivisions+1; ++k)
+                     {
+                       out << present_node
+                           << "  ";
+                       for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                         out << patch->data(data_set,
+                                            (i*(n_subdivisions+1)+j)*(n_subdivisions+1)+k)
+                             << ' ';
+                       
+                       out << endl;
+                       
+                       ++present_node;
+                     };
+
+               break;
+             };
+
+             default:
+                   Assert (false, ExcNotImplemented());
+           };
+       };  
+    };
+
+                                  // no model data
+
+                                  // assert the stream is still ok
+  AssertThrow (out, ExcIO());
+};
+
+
+
 template <int dim>
 void DataOutBase::write_gnuplot (const vector<Patch<dim> > &patches,
                                 const vector<string>      &data_names,
+                                const GnuplotFlags        &/*flags*/,
                                 ostream                   &out) 
 {
+  AssertThrow (out, ExcIO());
+  
   const unsigned int n_data_sets = data_names.size();
   
                                   // write preamble
@@ -114,9 +501,9 @@ void DataOutBase::write_gnuplot (const vector<Patch<dim> > &patches,
           
          case 2:
          {
-           for (unsigned int j=0; j<n_subdivisions+1; ++j) 
+           for (unsigned int i=0; i<n_subdivisions+1; ++i)
              {
-               for (unsigned int i=0; i<n_subdivisions+1; ++i)
+               for (unsigned int j=0; j<n_subdivisions+1; ++j)
                  {
                    const double x_frac = i * 1./n_subdivisions,
                                 y_frac = j * 1./n_subdivisions;
@@ -124,13 +511,13 @@ void DataOutBase::write_gnuplot (const vector<Patch<dim> > &patches,
                                                     // compute coordinates for
                                                     // this patch point
                    out << (((patch->vertices[1] * x_frac) +
-                            (patch->vertices[0] * (1-x_frac)) * y_frac) +
+                            (patch->vertices[0] * (1-x_frac))) * (1-y_frac) +
                            ((patch->vertices[2] * x_frac) +
-                            (patch->vertices[3] * (1-x_frac)) * (1-y_frac)))
+                            (patch->vertices[3] * (1-x_frac))) * y_frac)
                        << ' ';
                    
                    for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
-                     out << patch->data(data_set,j*(n_subdivisions+1) + i) << ' ';
+                     out << patch->data(data_set,i*(n_subdivisions+1) + j) << ' ';
 
                    out << endl;
                  };
@@ -147,13 +534,713 @@ void DataOutBase::write_gnuplot (const vector<Patch<dim> > &patches,
 
          case 3:
          {
-           Assert (false, ExcNotImplemented());
+                                            // for all grid points: draw
+                                            // lines into all positive
+                                            // coordinate directions if
+                                            // there is another grid point
+                                            // there
+           for (unsigned int i=0; i<n_subdivisions+1; ++i)
+             for (unsigned int j=0; j<n_subdivisions+1; ++j)
+               for (unsigned int k=0; k<n_subdivisions+1; ++k)
+                 {
+                                                    // note the broken
+                                                    // design of hexahedra
+                                                    // in deal.II, where
+                                                    // first the z-component
+                                                    // is counted up, before
+                                                    // increasing the y-
+                                                    // coordinate
+                   const double x_frac = i * 1./n_subdivisions,
+                                y_frac = k * 1./n_subdivisions,
+                                z_frac = j * 1./n_subdivisions;
+
+                                                    // compute coordinates for
+                                                    // this patch point
+                   const Point<dim> this_point
+                     = ((((patch->vertices[1] * x_frac) +
+                          (patch->vertices[0] * (1-x_frac))) * (1-y_frac) +
+                         ((patch->vertices[2] * x_frac) +
+                          (patch->vertices[3] * (1-x_frac))) * y_frac)   * (1-z_frac) +
+                        (((patch->vertices[5] * x_frac) +
+                          (patch->vertices[4] * (1-x_frac))) * (1-y_frac) +
+                         ((patch->vertices[6] * x_frac) +
+                          (patch->vertices[7] * (1-x_frac))) * y_frac)   * z_frac);
+
+                                                    // line into positive x-direction
+                                                    // if possible
+                   if (i < n_subdivisions)
+                     {
+                                                        // write point here
+                                                        // and its data
+                       out << this_point;
+                       for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                         out  << ' '
+                              << patch->data(data_set,
+                                             (i*(n_subdivisions+1) + j)*(n_subdivisions+1)+k);
+                       out << endl;
+                       
+                                                        // write point there
+                                                        // and its data
+                       const double x_frac_new = x_frac + 1./n_subdivisions;
+                       out << ((((patch->vertices[1] * x_frac_new) +
+                                 (patch->vertices[0] * (1-x_frac_new))) * (1-y_frac) +
+                                ((patch->vertices[2] * x_frac_new) +
+                                 (patch->vertices[3] * (1-x_frac_new))) * y_frac)   * (1-z_frac) +
+                               (((patch->vertices[5] * x_frac_new) +
+                                 (patch->vertices[4] * (1-x_frac_new))) * (1-y_frac) +
+                                ((patch->vertices[6] * x_frac_new) +
+                                 (patch->vertices[7] * (1-x_frac_new))) * y_frac)   * z_frac);
+                       for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                         out  << ' '
+                              << patch->data(data_set,
+                                             ((i+1)*(n_subdivisions+1) + j)*(n_subdivisions+1)+k);
+                       out << endl;
+
+                                                        // end of line
+                       out << endl
+                           << endl;
+                     };
+                   
+                                                    // line into positive y-direction
+                                                    // if possible
+                   if (j < n_subdivisions)
+                     {
+                                                        // write point here
+                                                        // and its data
+                       out << this_point;
+                       for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                         out  << ' '
+                              << patch->data(data_set,
+                                             (i*(n_subdivisions+1) + j)*(n_subdivisions+1)+k);
+                       out << endl;
+                       
+                                                        // write point there
+                                                        // and its data
+                       const double z_frac_new = z_frac + 1./n_subdivisions;
+                       out << ((((patch->vertices[1] * x_frac) +
+                                 (patch->vertices[0] * (1-x_frac))) * (1-y_frac) +
+                                ((patch->vertices[2] * x_frac) +
+                                 (patch->vertices[3] * (1-x_frac))) * y_frac)   * (1-z_frac_new) +
+                               (((patch->vertices[5] * x_frac) +
+                                 (patch->vertices[4] * (1-x_frac))) * (1-y_frac) +
+                                ((patch->vertices[6] * x_frac) +
+                                 (patch->vertices[7] * (1-x_frac))) * y_frac)   * z_frac_new);
+                       for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                         out  << ' '
+                              << patch->data(data_set,
+                                             (i*(n_subdivisions+1) + (j+1))*(n_subdivisions+1)+k);
+                       out << endl;
+
+                                                        // end of line
+                       out << endl
+                           << endl;
+                     };
+
+                                                    // line into positive z-direction
+                                                    // if possible
+                   if (k < n_subdivisions)
+                     {
+                                                        // write point here
+                                                        // and its data
+                       out << this_point;
+                       for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                         out  << ' '
+                              << patch->data(data_set,
+                                             (i*(n_subdivisions+1) + j)*(n_subdivisions+1)+k);
+                       out << endl;
+                       
+                                                        // write point there
+                                                        // and its data
+                       const double y_frac_new = y_frac + 1./n_subdivisions;
+                       out << ((((patch->vertices[1] * x_frac) +
+                                 (patch->vertices[0] * (1-x_frac))) * (1-y_frac_new) +
+                                ((patch->vertices[2] * x_frac) +
+                                 (patch->vertices[3] * (1-x_frac))) * y_frac_new)   * (1-z_frac) +
+                               (((patch->vertices[5] * x_frac) +
+                                 (patch->vertices[4] * (1-x_frac))) * (1-y_frac_new) +
+                                ((patch->vertices[6] * x_frac) +
+                                 (patch->vertices[7] * (1-x_frac))) * y_frac_new)   * z_frac);
+                       for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                         out  << ' '
+                              << patch->data(data_set,
+                                             (i*(n_subdivisions+1) + j)*(n_subdivisions+1)+k+1);
+                       out << endl;
+
+                                                        // end of line
+                       out << endl
+                           << endl;
+                     };                    
+                       
+                 };
+
+           break;
          };
 
          default:
                Assert (false, ExcNotImplemented());
        };
     };
+
+  AssertThrow (out, ExcIO());
+};
+
+
+
+template <int dim>
+void DataOutBase::write_povray (const vector<Patch<dim> > &/*patches*/,
+                               const vector<string>      &/*data_names*/,
+                               const PovrayFlags         &/*flags*/,
+                               ostream                   &/*out*/) 
+{
+  Assert (false, ExcNotImplemented());
+};
+
+
+
+template <int dim>
+void DataOutBase::write_eps (const vector<Patch<dim> > &/*patches*/,
+                            const vector<string>      &/*data_names*/,
+                            const EpsFlags            &/*flags*/,
+                            ostream                   &/*out*/) 
+{
+  Assert (false, ExcNotImplemented());
+};
+
+
+
+template <int dim>
+void DataOutBase::write_gmv (const vector<Patch<dim> > &patches,
+                            const vector<string>      &data_names,
+                            const GmvFlags            &/*flags*/,
+                            ostream                   &out) 
+{
+  AssertThrow (out, ExcIO());
+
+  const unsigned int n_data_sets = data_names.size();
+  
+                                  ///////////////////////
+                                  // preamble
+  out << "gmvinput ascii"
+      << endl
+      << endl;
+
+                                  // first count the number of cells
+                                  // and cells for later use
+  unsigned int n_cells = 0,
+              n_nodes = 0;
+  for (vector<Patch<dim> >::const_iterator patch=patches.begin();
+       patch!=patches.end(); ++patch)
+    switch (dim)
+      {
+       case 1:
+             n_cells += patch->n_subdivisions;
+             n_nodes += patch->n_subdivisions+1;
+             break;
+       case 2:
+             n_cells += patch->n_subdivisions *
+                        patch->n_subdivisions;
+             n_nodes += (patch->n_subdivisions+1) *
+                        (patch->n_subdivisions+1);
+             break;
+       case 3:
+             n_cells += patch->n_subdivisions *
+                        patch->n_subdivisions *
+                        patch->n_subdivisions;
+             n_nodes += (patch->n_subdivisions+1) *
+                        (patch->n_subdivisions+1) *
+                        (patch->n_subdivisions+1);
+             break;
+       default:
+             Assert (false, ExcNotImplemented());
+      };
+
+
+                                  ///////////////////////////////
+                                  // first make up a list of used
+                                  // vertices along with their
+                                  // coordinates
+                                  //
+                                  // note that we have to print
+                                  // d=1..3 dimensions
+  out << "nodes " << n_nodes << endl;
+  for (unsigned int d=1; d<=3; ++d)
+    {
+      for (vector<Patch<dim> >::const_iterator patch=patches.begin();
+          patch!=patches.end(); ++patch)
+       {
+         const unsigned int n_subdivisions = patch->n_subdivisions;
+         
+                                          // if we have nonzero values for
+                                          // this coordinate
+         if (d<=dim)
+           {
+             switch (dim)
+               {
+                 case 1:
+                 {
+                   for (unsigned int i=0; i<n_subdivisions+1; ++i)
+                     out << ((patch->vertices[1](0) * i / n_subdivisions) +
+                             (patch->vertices[0](0) * (n_subdivisions-i) / n_subdivisions))
+                         << ' ';
+                   break;
+                 };
+                  
+                 case 2:
+                 {
+                   for (unsigned int i=0; i<n_subdivisions+1; ++i)
+                     for (unsigned int j=0; j<n_subdivisions+1; ++j)
+                       {
+                         const double x_frac = i * 1./n_subdivisions,
+                                      y_frac = j * 1./n_subdivisions;
+                         
+                                                          // compute coordinates for
+                                                          // this patch point
+                         out << (((patch->vertices[1](d-1) * x_frac) +
+                                  (patch->vertices[0](d-1) * (1-x_frac))) * (1-y_frac) +
+                                 ((patch->vertices[2](d-1) * x_frac) +
+                                  (patch->vertices[3](d-1) * (1-x_frac))) * y_frac)
+                             << ' ';
+                       };
+                   break;
+                 };
+                  
+                 case 3:
+                 {
+                   for (unsigned int i=0; i<n_subdivisions+1; ++i)
+                     for (unsigned int j=0; j<n_subdivisions+1; ++j)
+                       for (unsigned int k=0; k<n_subdivisions+1; ++k)
+                         {
+                                                            // note the broken
+                                                            // design of hexahedra
+                                                            // in deal.II, where
+                                                            // first the z-component
+                                                            // is counted up, before
+                                                            // increasing the y-
+                                                            // coordinate
+                           const double x_frac = i * 1./n_subdivisions,
+                                        y_frac = k * 1./n_subdivisions,
+                                        z_frac = j * 1./n_subdivisions;
+                           
+                                                            // compute coordinates for
+                                                            // this patch point
+                           out << ((((patch->vertices[1](d-1) * x_frac) +
+                                     (patch->vertices[0](d-1) * (1-x_frac))) * (1-y_frac) +
+                                    ((patch->vertices[2](d-1) * x_frac) +
+                                     (patch->vertices[3](d-1) * (1-x_frac))) * y_frac)   * (1-z_frac) +
+                                   (((patch->vertices[5](d-1) * x_frac) +
+                                     (patch->vertices[4](d-1) * (1-x_frac))) * (1-y_frac) +
+                                    ((patch->vertices[6](d-1) * x_frac) +
+                                     (patch->vertices[7](d-1) * (1-x_frac))) * y_frac)   * z_frac)
+                               << ' ';
+                         };
+             
+                   break;
+                 };
+                  
+                 default:
+                       Assert (false, ExcNotImplemented());
+               };
+           }
+         else
+                                            // d>dim. write zeros instead
+           {
+             const unsigned int n_points = (dim==1 ?
+                                            n_subdivisions+1 :
+                                            (dim==2 ?
+                                             (n_subdivisions+1) * (n_subdivisions+1) :
+                                             (dim == 3 ?
+                                              (n_subdivisions+1) * (n_subdivisions+1) * (n_subdivisions+1) :
+                                              0)));
+             for (unsigned int i=0; i<n_points; ++i)
+               out << "0 ";
+           };
+       };
+      out << endl;
+    };
+
+  out << endl;
+
+                                  /////////////////////////////////
+                                  // now for the cells. note that
+                                  // vertices are counted from 1 onwards
+  if (true)
+    {
+      out << "cells " << n_cells << endl;
+      
+       
+      unsigned int first_vertex_of_patch = 0;
+      
+      for (vector<Patch<dim> >::const_iterator patch=patches.begin();
+          patch!=patches.end(); ++patch)
+       {
+         const unsigned int n_subdivisions = patch->n_subdivisions;
+
+                                          // write out the cells making
+                                          // up this patch
+         switch (dim)
+           {
+             case 1:
+             {
+               for (unsigned int i=0; i<n_subdivisions; ++i)
+                 out << "line 2\n  "
+                     << first_vertex_of_patch+i+1 << ' '
+                     << first_vertex_of_patch+i+1+1 << endl;
+               break;
+             };
+              
+             case 2:
+             {
+               for (unsigned int i=0; i<n_subdivisions; ++i)
+                 for (unsigned int j=0; j<n_subdivisions; ++j)
+                   out << "quad 4\n  "
+                       << first_vertex_of_patch+i*(n_subdivisions+1)+j+1 << ' '
+                       << first_vertex_of_patch+(i+1)*(n_subdivisions+1)+j+1 << ' '
+                       << first_vertex_of_patch+(i+1)*(n_subdivisions+1)+j+1+1 << ' '
+                       << first_vertex_of_patch+i*(n_subdivisions+1)+j+1+1
+                       << endl;
+               break;
+             };
+              
+             case 3:
+             {
+               for (unsigned int i=0; i<n_subdivisions; ++i)
+                 for (unsigned int j=0; j<n_subdivisions; ++j)
+                   for (unsigned int k=0; k<n_subdivisions; ++k)
+                     {
+                       out << "hex 8\n   "
+                                                          // note: vertex indices start with 1!
+                           << first_vertex_of_patch+(i*(n_subdivisions+1)+j      )*(n_subdivisions+1)+k  +1 << ' '
+                           << first_vertex_of_patch+((i+1)*(n_subdivisions+1)+j  )*(n_subdivisions+1)+k  +1 << ' '
+                           << first_vertex_of_patch+((i+1)*(n_subdivisions+1)+j+1)*(n_subdivisions+1)+k  +1 << ' '
+                           << first_vertex_of_patch+(i*(n_subdivisions+1)+j+1    )*(n_subdivisions+1)+k  +1 << ' '
+                           << first_vertex_of_patch+(i*(n_subdivisions+1)+j      )*(n_subdivisions+1)+k+1+1 << ' '
+                           << first_vertex_of_patch+((i+1)*(n_subdivisions+1)+j  )*(n_subdivisions+1)+k+1+1 << ' '
+                           << first_vertex_of_patch+((i+1)*(n_subdivisions+1)+j+1)*(n_subdivisions+1)+k+1+1 << ' '
+                           << first_vertex_of_patch+(i*(n_subdivisions+1)+j+1    )*(n_subdivisions+1)+k+1+1 << ' '
+                           << endl;
+                     };
+               break;
+             };
+
+             default:
+                   Assert (false, ExcNotImplemented());
+           };
+         
+         
+                                          // finally update the number
+                                          // of the first vertex of this patch
+         switch (dim)
+           {
+             case 1:
+                   first_vertex_of_patch += n_subdivisions+1;
+                   break;
+             case 2:
+                   first_vertex_of_patch += (n_subdivisions+1) *
+                                            (n_subdivisions+1);
+                   break;
+             case 3:
+                   first_vertex_of_patch += (n_subdivisions+1) *
+                                            (n_subdivisions+1) *
+                                            (n_subdivisions+1);
+                   break;
+             default:
+                   Assert (false, ExcNotImplemented());
+           };
+       };
+      out << endl;
+    };
+
+                                  ///////////////////////////////////////
+                                  // data output.
+  out << "variable" << endl;
+
+                                  // since here as with the vertex
+                                  // coordinates the order is a bit
+                                  // unpleasant (first all data of
+                                  // variable 1, then variable 2, etc)
+                                  // we have to copy them a bit around
+                                  //
+                                  // note that we copy vectors when
+                                  // looping over the patches since we
+                                  // have to write them one variable
+                                  // at a time and don't want to use
+                                  // more than one loop
+  if (true)
+    {
+      vector<vector<double> > data_vectors (n_data_sets,
+                                           vector<double> (n_nodes));
+                                      // loop over all patches
+      unsigned int next_value = 0;
+      for (typename vector<Patch<dim> >::const_iterator patch=patches.begin();
+          patch != patches.end(); ++patch)
+       {
+         const unsigned int n_subdivisions = patch->n_subdivisions;
+         
+         Assert (patch->data.m() == n_data_sets,
+                 ExcUnexpectedNumberOfDatasets (patch->data.m(), n_data_sets));
+         Assert (patch->data.n() == (dim==1 ?
+                                     n_subdivisions+1 :
+                                     (dim==2 ?
+                                      (n_subdivisions+1)*(n_subdivisions+1) :
+                                      (dim==3 ?
+                                       (n_subdivisions+1)*(n_subdivisions+1)*(n_subdivisions+1) :
+                                       0))),
+                 ExcInvalidDatasetSize (patch->data.n(), n_subdivisions+1));
+         
+         switch (dim)
+           {
+             case 1:
+             {      
+               for (unsigned int i=0; i<n_subdivisions+1; ++i, ++next_value) 
+                 for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                   data_vectors[data_set][next_value] = patch->data(data_set,i);
+               
+               break;
+             };
+                    
+             case 2:
+             {
+               for (unsigned int i=0; i<n_subdivisions+1; ++i)
+                 for (unsigned int j=0; j<n_subdivisions+1; ++j)
+                   {
+                     for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                       data_vectors[data_set][next_value]
+                         = patch->data(data_set,i*(n_subdivisions+1) + j);
+                     ++next_value;
+                   };
+               
+               break;
+             };
+              
+             case 3:
+             {
+               for (unsigned int i=0; i<n_subdivisions+1; ++i)
+                 for (unsigned int j=0; j<n_subdivisions+1; ++j)
+                   for (unsigned int k=0; k<n_subdivisions+1; ++k)
+                     {
+                       for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+                         data_vectors[data_set][next_value]
+                           = patch->data(data_set,
+                                         (i*(n_subdivisions+1)+j)*(n_subdivisions+1)+k);
+                       ++next_value;
+                     };
+
+               break;
+             };
+              
+             default:
+                   Assert (false, ExcNotImplemented());
+           };
+       };
+
+                                      // now write the data vectors to #out#
+                                      // the '1' means: node data (as opposed
+                                      // to cell data, which we do not
+                                      // support explicitely here)
+      for (unsigned int data_set=0; data_set<n_data_sets; ++data_set)
+       {
+         out << data_names[data_set] << " 1" << endl;
+         copy(data_vectors[data_set].begin(),
+              data_vectors[data_set].end(),
+              ostream_iterator<double>(out, " "));
+         out << endl
+             << endl;
+       };
+    };
+  
+  
+                                  // end of variable section
+  out << "endvars" << endl;
+  
+                                  // end of output
+  out << "endgmv"
+      << endl;
+  
+                                  // assert the stream is still ok
+  AssertThrow (out, ExcIO());
+};
+
+
+
+
+
+/* --------------------------- class DataOutInterface ---------------------- */
+
+
+template <int dim>
+void DataOutInterface<dim>::write_ucd (ostream &out) const 
+{
+  DataOutBase::write_ucd (get_patches(), get_dataset_names(),
+                         ucd_flags, out);
+};
+
+
+
+template <int dim>
+void DataOutInterface<dim>::write_gnuplot (ostream &out) const 
+{
+  DataOutBase::write_gnuplot (get_patches(), get_dataset_names(),
+                             gnuplot_flags, out);
+};
+
+
+
+template <int dim>
+void DataOutInterface<dim>::write_povray (ostream &out) const 
+{
+  DataOutBase::write_povray (get_patches(), get_dataset_names(),
+                            povray_flags, out);
+};
+
+
+
+template <int dim>
+void DataOutInterface<dim>::write_eps (ostream &out) const 
+{
+  DataOutBase::write_eps (get_patches(), get_dataset_names(),
+                         eps_flags, out);
+};
+
+
+
+template <int dim>
+void DataOutInterface<dim>::write_gmv (ostream &out) const 
+{
+  DataOutBase::write_gmv (get_patches(), get_dataset_names(),
+                         gmv_flags, out);
+};
+
+
+
+template <int dim>
+void DataOutInterface<dim>::write (ostream &out,
+                                  const OutputFormat output_format) const {
+  switch (output_format) 
+    {
+      case ucd:
+           write_ucd (out);
+           break;
+           
+      case gnuplot:
+           write_gnuplot (out);
+           break;
+           
+      case povray:
+           write_povray (out);
+           break;
+           
+      case eps:
+           write_eps(out);
+           break;
+           
+      case gmv:
+           write_gmv (out);
+           break;
+           
+      default:
+           Assert (false, ExcNotImplemented());
+    };
+};
+
+
+
+template <int dim>
+void DataOutInterface<dim>::set_flags (const UcdFlags &flags) 
+{
+  ucd_flags = flags;
+};
+
+
+
+template <int dim>
+void DataOutInterface<dim>::set_flags (const GnuplotFlags &flags) 
+{
+  gnuplot_flags = flags;
+};
+
+
+
+template <int dim>
+void DataOutInterface<dim>::set_flags (const PovrayFlags &flags) 
+{
+  povray_flags = flags;
+};
+
+
+
+template <int dim>
+void DataOutInterface<dim>::set_flags (const EpsFlags &flags) 
+{
+  eps_flags = flags;
+};
+
+
+
+template <int dim>
+void DataOutInterface<dim>::set_flags (const GmvFlags &flags) 
+{
+  gmv_flags = flags;
+};
+
+
+
+template <int dim>
+string DataOutInterface<dim>::default_suffix (const OutputFormat output_format) 
+{
+  switch (output_format) 
+    {
+      case ucd:
+           return ".inp";
+           
+      case gnuplot: 
+           return ".gnuplot";
+           
+      case povray: 
+           return ".pov";
+           
+      case eps: 
+           return ".eps";
+
+      case gmv:
+           return ".gmv";
+           
+      default: 
+           Assert (false, ExcNotImplemented()); 
+           return "";
+    };
+};
+  
+
+
+template <int dim>
+DataOutInterface<dim>::OutputFormat
+DataOutInterface<dim>::parse_output_format (const string &format_name) {
+  if (format_name == "ucd")
+    return ucd;
+
+  if (format_name == "gnuplot")
+    return gnuplot;
+
+  if (format_name == "povray")
+    return povray;
+
+  if (format_name == "eps")
+    return eps;
+
+  if (format_name == "gmv")
+    return gmv;
+  
+  AssertThrow (false, ExcInvalidState ());
+
+                                  // return something invalid
+  return OutputFormat(-1);
+};
+
+
+
+template <int dim>
+string DataOutInterface<dim>::get_output_format_names () {
+  return "ucd|gnuplot|povray|eps|gmv";
 };
 
 
@@ -161,9 +1248,6 @@ void DataOutBase::write_gnuplot (const vector<Patch<dim> > &patches,
 
 
   
-// explicit instantiations
-template
-void DataOutBase::write_gnuplot (const vector<Patch<deal_II_dimension> > &patches,
-                                const vector<string>                    &data_names,
-                                ostream                                 &out);
-template DataOutBase::Patch<deal_II_dimension>::Patch ();
+// explicit instantiations. functions in DataOutBase are instantiated by
+// the respective functions in DataOut_Interface
+template class DataOutInterface<deal_II_dimension>;
index 96e905a8e84e69774fb347117bfbe68a89db779e..1a5ad43c5c4f5166c420d38dd692b7a93b528fb8 100644 (file)
@@ -11,7 +11,7 @@
 #include <grid/dof_constraints.h>
 #include <grid/grid_generator.h>
 #include <base/function.h>
-#include <basic/data_io.h>
+#include <basic/data_out.h>
 #include <fe/fe_lib.lagrange.h>
 #include <fe/fe_lib.criss_cross.h>
 #include <base/quadrature_lib.h>
@@ -269,7 +269,7 @@ int PoissonProblem<dim>::run (const unsigned int level) {
   cout << "    Making grid... ";
   GridGenerator::hyper_ball (*tria);
   HyperBallBoundary<dim> boundary_description;
-  tria->set_boundary (&boundary_description);
+  tria->set_boundary (0, boundary_description);
   tria->begin_active()->set_refine_flag();
   (++(++(tria->begin_active())))->set_refine_flag();
   tria->execute_coarsening_and_refinement ();
index 973d78951cb2042e6635f08a32aca176cd0cdf7f..31efd2cf2518852a2c53d7f3446ab0170cb07495 100644 (file)
@@ -11,7 +11,7 @@
 #include <grid/dof_constraints.h>
 #include <grid/grid_generator.h>
 #include <base/function.h>
-#include <basic/data_io.h>
+#include <basic/data_out.h>
 #include <basic/grid_out.h>
 #include <base/parameter_handler.h>
 #include <fe/fe_lib.lagrange.h>
@@ -413,7 +413,7 @@ void PoissonProblem<dim>::run (ParameterHandler &prm) {
        << "=======================================" << endl;
   cout << "Making initial grid... " << endl;
   const unsigned int start_level(prm.get_integer("Initial refinement"));
-  tria->set_boundary (boundary);
+  tria->set_boundary (0, *boundary);
   GridGenerator::hyper_ball (*tria);
   tria->refine_global (start_level);
 
@@ -630,7 +630,7 @@ void PoissonProblem<dim>::run (ParameterHandler &prm) {
   filename += "finest_mesh.gnuplot";
   cout << "    Writing finest grid to <" << filename << ">... " << endl;
   ofstream finest_mesh (filename.c_str());
-  GridOut::write_gnuplot (tria, finest_mesh);
+  GridOut().write_gnuplot (*tria, finest_mesh);
   finest_mesh.close();
 
   print_history (prm, refine_mode);
index 136acea0b2de667390ca675955b07cd015a46b96..572a209dea2a0c9636d6060e19cbe1250e6e9da7 100644 (file)
@@ -11,7 +11,7 @@
 #include <grid/dof_constraints.h>
 #include <grid/grid_generator.h>
 #include <base/function.h>
-#include <basic/data_io.h>
+#include <basic/data_out.h>
 #include <fe/fe_lib.lagrange.h>
 #include <fe/fe_lib.criss_cross.h>
 #include <fe/fe_update_flags.h>
index 4ddc11e4f8af673b61aa85e86fcbc1cd9d5266a0..bfb37b0268b4739f6a8906fdc7168fc1dfb4e52d 100644 (file)
@@ -6,7 +6,7 @@
 #include "poisson.h"
 #include <lac/vector.h>
 #include <grid/grid_generator.h>
-
+#include <basic/data_out.h>
 
 
 template <int dim>
@@ -236,6 +236,13 @@ PoissonProblem<dim>::PoissonProblem () :
 
 
 
+template <int dim>
+PoissonProblem<dim>::~PoissonProblem () 
+{
+  clear ();
+};
+
+
 
 template <int dim>
 void PoissonProblem<dim>::clear () {  
@@ -244,6 +251,13 @@ void PoissonProblem<dim>::clear () {
     dof = 0;
   };
 
+  if (boundary != 0)
+    {
+      tria->set_boundary (0);
+      delete boundary;
+      boundary = 0;
+    };
+  
   if (tria != 0) {
     delete tria;
     tria = 0;
@@ -267,12 +281,6 @@ void PoissonProblem<dim>::clear () {
       boundary_values = 0;
     };
 
-  if (boundary != 0)
-    {
-      delete boundary;
-      boundary = 0;
-    };
-  
   ProblemBase<dim>::clear ();
 };
 
@@ -407,6 +415,7 @@ bool PoissonProblem<dim>::make_grid (ParameterHandler &prm) {
 template <int dim>
 void PoissonProblem<dim>::make_zoom_in_grid () {
   GridGenerator::hyper_cube (*tria);
+  
                                   // refine first cell
   tria->begin_active()->set_refine_flag();
   tria->execute_coarsening_and_refinement ();
@@ -414,7 +423,7 @@ void PoissonProblem<dim>::make_zoom_in_grid () {
                                   // on coarsest level
   tria->begin_active()->set_refine_flag ();
   tria->execute_coarsening_and_refinement ();
-  
+
   Triangulation<dim>::active_cell_iterator cell;
   for (int i=0; i<(dim==3 ? 5 : 17); ++i) 
     {
@@ -555,7 +564,9 @@ void PoissonProblem<dim>::run (ParameterHandler &prm) {
   DataOut<dim> out;
   string o_filename = prm.get ("Output file");
   ofstream gnuplot(o_filename.c_str());
-  fill_data (out);
+  out.attach_dof_handler (*dof_handler);
+  out.add_data_vector (solution, "solution");
+  out.build_patches ();
   out.write_gnuplot (gnuplot);
   gnuplot.close ();
 
@@ -570,4 +581,4 @@ void PoissonProblem<dim>::run (ParameterHandler &prm) {
 
 
 
-template class PoissonProblem<2>;
+template class PoissonProblem<3>;
index 155c7fc22437fda9ca06eb0f2ee0146fc692fd67..75d585d918add79749d945cef4e785d089a164ad 100644 (file)
@@ -255,7 +255,7 @@ int main () {
          
          Triangulation<3> tria;
          make_tria (tria, step);
-         GridOut::write_gnuplot (tria, cout);
+         GridOut().write_gnuplot (tria, cout);
          
          DoFHandler<3> dof (&tria);
          dof.distribute_dofs (*fe);
index ffd45453f53915242046ca10d92682af0b3882b4..84ebd8cf77e5fe1e43fc299bda8783d649a0ce37 100644 (file)
@@ -247,7 +247,7 @@ void test (const int test_case) {
     };
   
   
-  GridOut::write_gnuplot (tria, cout);
+  GridOut().write_gnuplot (tria, cout);
     
   cout << "     Total number of cells        = " << tria.n_cells() << endl
        << "     Total number of active cells = " << tria.n_active_cells() << endl;

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.