#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>
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 ();
#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>
<< "=======================================" << 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);
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);
#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>
#include "poisson.h"
#include <lac/vector.h>
#include <grid/grid_generator.h>
-
+#include <basic/data_out.h>
template <int dim>
+template <int dim>
+PoissonProblem<dim>::~PoissonProblem ()
+{
+ clear ();
+};
+
+
template <int dim>
void PoissonProblem<dim>::clear () {
dof = 0;
};
+ if (boundary != 0)
+ {
+ tria->set_boundary (0);
+ delete boundary;
+ boundary = 0;
+ };
+
if (tria != 0) {
delete tria;
tria = 0;
boundary_values = 0;
};
- if (boundary != 0)
- {
- delete boundary;
- boundary = 0;
- };
-
ProblemBase<dim>::clear ();
};
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 ();
// 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)
{
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 ();
-template class PoissonProblem<2>;
+template class PoissonProblem<3>;
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);
}
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);
}
}
#include <grid/dof_constraints.h>
#include <fe/fe_update_flags.h>
#include <map>
-
+#include <string>
* 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#.
*/
/**
- * 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
/**
+ * 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
* 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
* @author Wolfgang Bangerth, Guido Kanschat, Stefan Nauber, 1998, 1999
*/
template <int dim>
-class DataOut {
+class DataOut_Old {
public:
/**
* Provide a data type specifying the
/**
* Constructor
*/
- DataOut ();
+ DataOut_Old ();
/**
* Designate a dof handler to be used
/**
* 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
*/
#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
+
+
+
/**
* 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
* 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
{
* 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
* bisection, #3# trisection,
* etc.
*/
- const unsigned int n_subdivisions;
-
+ unsigned int n_subdivisions;
+
/**
* Data vectors. The format is
* as follows:
* #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
* 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
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
*/
int, int,
<< "The number of data sets on this patch is " << arg1
<< ", but we expected " << arg2);
+
/**
* Exception
*/
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
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);
}
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);
}
}
#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>
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";
};
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) {};
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 ());
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());
};
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());
#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;
};
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;
#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;
};
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;
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());
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());
#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
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());
#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());
{
// 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)
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)
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);
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);
// 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)
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
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
template <int dim>
-void DataOut<dim>::write (ostream &out,
+void DataOut_Old<dim>::write (ostream &out,
const OutputFormat output_format) const {
switch (output_format)
{
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)
{
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;
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;
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;
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);
//explicit instantiations
template class DataIn<deal_II_dimension>;
-template class DataOut<deal_II_dimension>;
+template class DataOut_Old<deal_II_dimension>;
/* $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>;
-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
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;
// 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;
};
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";
};
-// 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>;
#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>
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 ();
#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>
<< "=======================================" << 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);
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);
#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>
#include "poisson.h"
#include <lac/vector.h>
#include <grid/grid_generator.h>
-
+#include <basic/data_out.h>
template <int dim>
+template <int dim>
+PoissonProblem<dim>::~PoissonProblem ()
+{
+ clear ();
+};
+
+
template <int dim>
void PoissonProblem<dim>::clear () {
dof = 0;
};
+ if (boundary != 0)
+ {
+ tria->set_boundary (0);
+ delete boundary;
+ boundary = 0;
+ };
+
if (tria != 0) {
delete tria;
tria = 0;
boundary_values = 0;
};
- if (boundary != 0)
- {
- delete boundary;
- boundary = 0;
- };
-
ProblemBase<dim>::clear ();
};
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 ();
// 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)
{
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 ();
-template class PoissonProblem<2>;
+template class PoissonProblem<3>;
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);
};
- 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;