* i.e. the z-coordinate runs fastest, then the y-coordinate, then x (if there
* are that many space directions).
*
- * The @p{Patch} class takes a template parameter denoting the space dimension
- * in which this patch operates.
+ *
+ * @sect3{Generalized patches}
+ *
+ * In general, the patches as explained above might be too
+ * restricted. For example, one might want to draw only the outer
+ * faces of a domain in a three-dimensional computation, if one is not
+ * interested in what happens inside. Then, the objects that should be
+ * drawn are two-dimensional in a three-dimensional world. The
+ * @p{Patch} class and associated output functions handle these
+ * cases. The @p{Patch} class therefore takes two template parameters,
+ * the first, named @p{dim} denoting the dimension of the object (in
+ * the above example, this would be two), while the second, named
+ * @p{spacedim}, denotes the dimension of the embedding space (this
+ * would be three). The corner points of a patch have the dimension of
+ * the space, while their number is determined by the dimension of the
+ * patch. By default, the second template parameter has the same value
+ * as the first, which would correspond to outputting a cell, rather
+ * than a face or something else.
*
*
* @sect2{Supported output formats}
* with values in the third direction taken from a data vector.
*
* The output uses two different povray-objects:
-
- * @begin{itemize}
*
+ * @begin{itemize}
* @item @p{BICUBIC_PATCH}
* A @p{bicubic_patch} is a 3-dimensional Bezier patch. It consists of 16 Points
* describing the surface. The 4 corner points are touched by the object,
* If the external file "data.inc" is used, the path to this file has to be
* included in the povray options.
*
+ *
* @sect3{EPS format}
*
* Output in this format circumvents the use of auxiliary graphic programs
* details of the viewpoint, light source, etc.
*
*
- * @author Wolfgang Bangerth 1999; EPS output based on an earlier implementation by Stefan Nauber for the old DataOut class; Povray output by Thomas Richter 1999
+ * @author Wolfgang Bangerth 1999, 2000; EPS output based on an earlier implementation by Stefan Nauber for the old DataOut class; Povray output by Thomas Richter 1999
*/
class DataOutBase
{
* @end{verbatim}
* @author Wolfgang Bangerth
*/
- template <int dim>
+ template <int dim, int spacedim=dim>
struct Patch
{
/**
* is the same as for cells
* in the triangulation.
*/
- Point<dim> vertices[GeometryInfo<dim>::vertices_per_cell];
+ Point<spacedim> vertices[GeometryInfo<dim>::vertices_per_cell];
/**
* Number of subdivisions with
* @p{n_subdivisions} to one.
*/
Patch ();
+
+ /**
+ * Exception
+ */
+ DeclException2 (ExcInvalidCombinationOfDimensions,
+ int, int,
+ << "It is not possible to have a structural dimension of " << arg1
+ << " to be larger than the space dimension of the surrounding"
+ << " space " << arg2);
};
* 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);
+ template <int dim, int spacedim>
+ static void write_ucd (const vector<Patch<dim,spacedim> > &patches,
+ const vector<string> &data_names,
+ const UcdFlags &flags,
+ ostream &out);
/**
* Write the given list of patches
* documentation for more information
* on the parameters.
*/
- template <int dim>
- static void write_gnuplot (const vector<Patch<dim> > &patches,
- const vector<string> &data_names,
- const GnuplotFlags &flags,
- ostream &out);
+ template <int dim, int spacedim>
+ static void write_gnuplot (const vector<Patch<dim,spacedim> > &patches,
+ const vector<string> &data_names,
+ const GnuplotFlags &flags,
+ ostream &out);
/**
* Write the given list of patches
* 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);
+ template <int dim, int spacedim>
+ static void write_povray (const vector<Patch<dim,spacedim> > &patches,
+ const vector<string> &data_names,
+ const PovrayFlags &flags,
+ ostream &out);
/**
* Write the given list of patches
* 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);
+ template <int dim, int spacedim>
+ static void write_eps (const vector<Patch<dim,spacedim> > &patches,
+ const vector<string> &data_names,
+ const EpsFlags &flags,
+ ostream &out);
/**
* Write the given list of patches
* 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);
+ template <int dim, int spacedim>
+ static void write_gmv (const vector<Patch<dim,spacedim> > &patches,
+ const vector<string> &data_names,
+ const GmvFlags &flags,
+ ostream &out);
/**
* thus moved into this separate
* function.
*/
- template <int dim>
- static void write_gmv_reorder_data_vectors (const vector<Patch<dim> > &patches,
- vector<vector<double> > &data_vectors);
+ template <int dim, int spacedim>
+ static void
+ write_gmv_reorder_data_vectors (const vector<Patch<dim,spacedim> > &patches,
+ vector<vector<double> > &data_vectors);
};
+
+
/**
* This class is the interface to the @p{DataOutBase} class, as already its name
* might suggest. It does not offer much functionality apart from a way to
*
* @author Wolfgang Bangerth, 1999
*/
-template <int dim>
+template <int dim, int spacedim=dim>
class DataOutInterface : private DataOutBase
{
public:
* allow the output functions to
* know what they shall print.
*/
- virtual const vector<DataOutBase::Patch<dim> > & get_patches () const = 0;
+ virtual const vector<DataOutBase::Patch<dim,spacedim> > &
+ get_patches () const = 0;
/**
* Abstract virtual function through
#include <set>
-template <int dim>
-DataOutBase::Patch<dim>::Patch () :
+template <int dim, int spacedim>
+DataOutBase::Patch<dim,spacedim>::Patch () :
n_subdivisions (1)
// all the other data has a
// constructor of its own
-{};
+{
+ Assert (dim<=spacedim, ExcInvalidCombinationOfDimensions(dim,spacedim));
+ Assert (spacedim<=3, ExcNotImplemented());
+};
-template <int dim>
-void DataOutBase::write_ucd (const vector<Patch<dim> > &patches,
- const vector<string> &data_names,
- const UcdFlags &flags,
- ostream &out)
+
+template <int dim, int spacedim>
+void DataOutBase::write_ucd (const vector<Patch<dim,spacedim> > &patches,
+ const vector<string> &data_names,
+ const UcdFlags &flags,
+ ostream &out)
{
AssertThrow (out, ExcIO());
// and cells for later use
unsigned int n_cells = 0,
n_nodes = 0;
- for (typename vector<Patch<dim> >::const_iterator patch=patches.begin();
+ for (typename vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
patch!=patches.end(); ++patch)
switch (dim)
{
{
unsigned int present_node = 1;
- for (typename vector<Patch<dim> >::const_iterator patch=patches.begin();
+ for (typename vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
patch!=patches.end(); ++patch)
{
const unsigned int n_subdivisions = patch->n_subdivisions;
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
+ {
+ out << present_node
+ << " ";
+
+ const Point<spacedim>
+ node = ((patch->vertices[1] * i / n_subdivisions) +
+ (patch->vertices[0] * (n_subdivisions-i) / n_subdivisions));
+
+ // write out coordinates
+ for (unsigned int i=0; i<spacedim; ++i)
+ out << node(i) << ' ';
+ // fill with zeroes
+ for (unsigned int i=spacedim; i<3; ++i)
+ out << "0 ";
+ out << endl;
+ };
+
break;
};
const double x_frac = i * 1./n_subdivisions,
y_frac = j * 1./n_subdivisions;
+ out << present_node
+ << " ";
+
// 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
+ const Point<spacedim>
+ 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);
+
+ // write out coordinates
+ for (unsigned int i=0; i<spacedim; ++i)
+ out << node(i) << ' ';
+ // fill with zeroes
+ for (unsigned int i=spacedim; i<3; ++i)
+ out << "0 ";
+ out << endl;
++present_node;
};
// 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;
+ << " ";
+
+ // compute coordinates for
+ // this patch point
+ const Point<spacedim>
+ 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);
+
+ // write out coordinates
+ for (unsigned int i=0; i<spacedim; ++i)
+ out << node(i) << ' ';
+ // fill with zeroes unnecessary here
+ for (unsigned int i=spacedim; i<3; ++i)
+ out << "0 ";
+ out << endl;
++present_node;
};
unsigned int present_cell = 1;
unsigned int first_vertex_of_patch = 0;
- for (typename vector<Patch<dim> >::const_iterator patch=patches.begin();
+ for (typename vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
patch!=patches.end(); ++patch)
{
const unsigned int n_subdivisions = patch->n_subdivisions;
};
-// finally update the number
+ // finally update the number
// of the first vertex of this patch
switch (dim)
{
};
-/////////////////////////////
+ /////////////////////////////
// now write data
if (n_data_sets != 0)
{
<< endl;
-// loop over all patches
+ // loop over all patches
unsigned int present_node = 1;
- for (typename vector<Patch<dim> >::const_iterator patch=patches.begin();
+ for (typename vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
patch != patches.end(); ++patch)
{
const unsigned int n_subdivisions = patch->n_subdivisions;
};
-template <int dim>
-void DataOutBase::write_gnuplot (const vector<Patch<dim> > &patches,
- const vector<string> &data_names,
- const GnuplotFlags &/*flags*/,
- ostream &out)
+
+template <int dim, int spacedim>
+void DataOutBase::write_gnuplot (const vector<Patch<dim,spacedim> > &patches,
+ const vector<string> &data_names,
+ const GnuplotFlags &/*flags*/,
+ ostream &out)
{
AssertThrow (out, ExcIO());
<< "#" << endl
<< "# ";
- switch (dim)
+ switch (spacedim)
{
case 1:
out << "<x> ";
};
-// loop over all patches
- for (typename vector<Patch<dim> >::const_iterator patch=patches.begin();
+ // loop over all patches
+ for (typename vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
patch != patches.end(); ++patch)
{
const unsigned int n_subdivisions = patch->n_subdivisions;
// compute coordinates for
// this patch point
- const Point<dim> this_point
+ const Point<spacedim> this_point
= ((((patch->vertices[1] * x_frac) +
(patch->vertices[0] * (1-x_frac))) * (1-y_frac) +
((patch->vertices[2] * x_frac) +
};
-template <int dim>
-void DataOutBase::write_povray (const vector<Patch<dim> > &patches,
- const vector<string> &data_names,
- const PovrayFlags &flags,
- ostream &out)
+
+template <int dim, int spacedim>
+void DataOutBase::write_povray (const vector<Patch<dim,spacedim> > &patches,
+ const vector<string> &data_names,
+ const PovrayFlags &flags,
+ ostream &out)
{
AssertThrow (out, ExcIO());
Assert (patches.size() > 0, ExcNoPatches());
- Assert (dim==2, ExcNotImplemented()); // only for 2-D
+ Assert (dim==2, ExcNotImplemented()); // only for 2-D surfaces on a 2-D plane
+ Assert (spacedim==2, ExcNotImplemented());
const unsigned int n_data_sets = data_names.size();
<< endl
<< "*/ " << endl;
- // include files
+ // include files
out << "#include \"colors.inc\" " << endl
<< "#include \"textures.inc\" " << endl;
-
-// use external include file for textures,
- // camera and light
+
+ // use external include file for textures,
+ // camera and light
if (flags.external_data)
out << "#include \"data.inc\" " << endl;
else // all definitions in data file
{
- // camera
+ // camera
out << endl << endl
<< "camera {" << endl
<< " location <1,4,-7>" << endl
<< " look_at <0,0,0>" << endl
<< " angle 30" << endl
<< "}" << endl;
-
- // light
+
+ // light
out << endl
<< "light_source {" << endl
<< " <1,4,-7>" << endl
<< "}" << endl;
}
};
-
+
// max. and min. heigth of solution
double hmin=0, hmax=0;
- for (typename vector<Patch<dim> >::const_iterator patch=patches.begin();
+ for (typename vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
patch != patches.end(); ++patch)
{
const unsigned int n_subdivisions = patch->n_subdivisions;
}
// loop over all patches
- for (typename vector<Patch<dim> >::const_iterator patch=patches.begin();
+ for (typename vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
patch != patches.end(); ++patch)
{
const unsigned int n_subdivisions = patch->n_subdivisions;
ExcInvalidDatasetSize (patch->data.n(), n_subdivisions+1));
- Point<dim> ver[16]; // value for all points in this patch
+ Point<spacedim> ver[16]; // value for all points in this patch
for (unsigned int i=0; i<n_subdivisions+1; ++i)
{
};
-template <int dim>
-void DataOutBase::write_eps (const vector<Patch<dim> > &patches,
- const vector<string> &/*data_names*/,
- const EpsFlags &flags,
- ostream &out)
+
+template <int dim, int spacedim>
+void DataOutBase::write_eps (const vector<Patch<dim,spacedim> > &patches,
+ const vector<string> &/*data_names*/,
+ const EpsFlags &flags,
+ ostream &out)
{
Assert (out, ExcIO());
Assert (patches.size() > 0, ExcNoPatches());
+ Assert (spacedim==dim, ExcNotImplemented());
switch (dim)
{
// note that since dim==2, we
// have exactly four vertices per
// patch and per cell
- for (typename vector<Patch<dim> >::const_iterator patch=patches.begin();
+ for (typename vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
patch!=patches.end(); ++patch)
{
const unsigned int n_subdivisions = patch->n_subdivisions;
x_frac1 = (i+1) * 1./n_subdivisions,
y_frac1 = (j+1) * 1./n_subdivisions;
- const Point<dim> points[4]
+ const Point<spacedim> points[4]
= { (((patch->vertices[1] * x_frac) +
(patch->vertices[0] * (1-x_frac))) * (1-y_frac) +
((patch->vertices[2] * x_frac) +
// compute coordinates of
// center of cell
- const Point<dim> center_point
+ const Point<spacedim> center_point
= (points[0] + points[1] + points[2] + points[3]) / 4;
const double center_height
= -(heights[0] + heights[1] + heights[2] + heights[3]) / 4;
};
-template <int dim>
-void DataOutBase::write_gmv (const vector<Patch<dim> > &patches,
- const vector<string> &data_names,
- const GmvFlags &/*flags*/,
- ostream &out)
+
+template <int dim, int spacedim>
+void DataOutBase::write_gmv (const vector<Patch<dim,spacedim> > &patches,
+ const vector<string> &data_names,
+ const GmvFlags &/*flags*/,
+ ostream &out)
{
AssertThrow (out, ExcIO());
// and cells for later use
unsigned int n_cells = 0,
n_nodes = 0;
- for (typename vector<Patch<dim> >::const_iterator patch=patches.begin();
+ for (typename vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
patch!=patches.end(); ++patch)
switch (dim)
{
Threads::ThreadManager thread_manager;
Threads::spawn (thread_manager,
Threads::encapsulate (&DataOutBase::template
- write_gmv_reorder_data_vectors<dim>)
+ write_gmv_reorder_data_vectors<dim,spacedim>)
.collect_args(patches, data_vectors));
///////////////////////////////
out << "nodes " << n_nodes << endl;
for (unsigned int d=1; d<=3; ++d)
{
- for (typename vector<Patch<dim> >::const_iterator patch=patches.begin();
+ for (typename vector<Patch<dim,spacedim> >::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)
+ if (d<=spacedim)
{
switch (dim)
{
};
}
else
- // d>dim. write zeros instead
+ // d>spacedim. write zeros instead
{
const unsigned int n_points
= static_cast<unsigned int>(pow (n_subdivisions+1, dim));
unsigned int first_vertex_of_patch = 0;
- for (typename vector<Patch<dim> >::const_iterator patch=patches.begin();
+ for (typename vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
patch!=patches.end(); ++patch)
{
const unsigned int n_subdivisions = patch->n_subdivisions;
-template <int dim>
-void DataOutBase::write_gmv_reorder_data_vectors (const vector<Patch<dim> > &patches,
- vector<vector<double> > &data_vectors)
+template <int dim, int spacedim>
+void
+DataOutBase::write_gmv_reorder_data_vectors (const vector<Patch<dim,spacedim> > &patches,
+ vector<vector<double> > &data_vectors)
{
// unlike in the main function, we
// don't have here the data_names
// loop over all patches
unsigned int next_value = 0;
- for (typename vector<Patch<dim> >::const_iterator patch=patches.begin();
+ for (typename vector<Patch<dim,spacedim> >::const_iterator patch=patches.begin();
patch != patches.end(); ++patch)
{
const unsigned int n_subdivisions = patch->n_subdivisions;
/* --------------------------- class DataOutInterface ---------------------- */
-template <int dim>
-void DataOutInterface<dim>::write_ucd (ostream &out) const
+template <int dim, int spacedim>
+void DataOutInterface<dim,spacedim>::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
+
+template <int dim, int spacedim>
+void DataOutInterface<dim,spacedim>::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
+
+template <int dim, int spacedim>
+void DataOutInterface<dim,spacedim>::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
+
+template <int dim, int spacedim>
+void DataOutInterface<dim,spacedim>::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
+
+template <int dim, int spacedim>
+void DataOutInterface<dim,spacedim>::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,
+
+template <int dim, int spacedim>
+void DataOutInterface<dim,spacedim>::write (ostream &out,
OutputFormat output_format) const
{
if (output_format == default_format)
};
-template <int dim>
-void DataOutInterface<dim>::set_default_format(OutputFormat fmt)
+
+template <int dim, int spacedim>
+void DataOutInterface<dim,spacedim>::set_default_format(OutputFormat fmt)
{
Assert(fmt != default_format, ExcNotImplemented());
default_fmt = fmt;
}
-template <int dim>
-void DataOutInterface<dim>::set_flags (const UcdFlags &flags)
+
+template <int dim, int spacedim>
+void DataOutInterface<dim,spacedim>::set_flags (const UcdFlags &flags)
{
ucd_flags = flags;
};
-template <int dim>
-void DataOutInterface<dim>::set_flags (const GnuplotFlags &flags)
+
+template <int dim, int spacedim>
+void DataOutInterface<dim,spacedim>::set_flags (const GnuplotFlags &flags)
{
gnuplot_flags = flags;
};
-template <int dim>
-void DataOutInterface<dim>::set_flags (const PovrayFlags &flags)
+
+template <int dim, int spacedim>
+void DataOutInterface<dim,spacedim>::set_flags (const PovrayFlags &flags)
{
povray_flags = flags;
};
-template <int dim>
-void DataOutInterface<dim>::set_flags (const EpsFlags &flags)
+
+template <int dim, int spacedim>
+void DataOutInterface<dim,spacedim>::set_flags (const EpsFlags &flags)
{
eps_flags = flags;
};
-template <int dim>
-void DataOutInterface<dim>::set_flags (const GmvFlags &flags)
+
+template <int dim, int spacedim>
+void DataOutInterface<dim,spacedim>::set_flags (const GmvFlags &flags)
{
gmv_flags = flags;
};
-template <int dim>
-string DataOutInterface<dim>::default_suffix (OutputFormat output_format) const
+
+template <int dim, int spacedim>
+string DataOutInterface<dim,spacedim>::default_suffix (OutputFormat output_format) const
{
if (output_format == default_format)
output_format = default_fmt;
};
-template <int dim>
-DataOutInterface<dim>::OutputFormat
-DataOutInterface<dim>::parse_output_format (const string &format_name)
+
+template <int dim, int spacedim>
+DataOutInterface<dim,spacedim>::OutputFormat
+DataOutInterface<dim,spacedim>::parse_output_format (const string &format_name)
{
if (format_name == "ucd")
return ucd;
};
-template <int dim>
-string DataOutInterface<dim>::get_output_format_names ()
+
+template <int dim, int spacedim>
+string DataOutInterface<dim,spacedim>::get_output_format_names ()
{
return "ucd|gnuplot|povray|eps|gmv";
}
-template <int dim>
-void DataOutInterface<dim>::declare_parameters (ParameterHandler &prm)
+
+template <int dim, int spacedim>
+void DataOutInterface<dim,spacedim>::declare_parameters (ParameterHandler &prm)
{
prm.declare_entry ("Output format", "gnuplot",
Patterns::Selection (get_output_format_names ()));
}
-template <int dim>
-void DataOutInterface<dim>::parse_parameters (ParameterHandler &prm)
+
+template <int dim, int spacedim>
+void DataOutInterface<dim,spacedim>::parse_parameters (ParameterHandler &prm)
{
const string& output_name = prm.get ("Output format");
default_fmt = parse_output_format (output_name);
// explicit instantiations. functions in DataOutBase are instantiated by
// the respective functions in DataOut_Interface
-template class DataOutInterface<data_out_dimension>;
-template class DataOutBase::Patch<data_out_dimension>;
+template class DataOutInterface<data_out_dimension,data_out_dimension>;
+template class DataOutBase::Patch<data_out_dimension, data_out_dimension>;
+
+// also enable plotting surfaces of 3d objects
+#if data_out_dimension == 3
+template class DataOutInterface<data_out_dimension,data_out_dimension-1>;
+template class DataOutBase::Patch<data_out_dimension, data_out_dimension-1>;
+#endif