]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Introduce a class that can't be used.
authorWolfgang Bangerth <bangerth@colostate.edu>
Wed, 13 Sep 2017 18:45:34 +0000 (12:45 -0600)
committerWolfgang Bangerth <bangerth@colostate.edu>
Wed, 13 Sep 2017 18:47:17 +0000 (12:47 -0600)
Specifically, declare DoFInvalidAccessor that is the accessor
for cases where dim>spacedim -- i.e., things that can't logically
happen, but that at times do happen in code like

  for (quad=0; quad<GeometryInfo<dim>::quads_per_cell; ++quad)
    cell->quad(quad)->do_something();

Here, the code is not executed in 1d, but we want it to be syntactically
correct so that we can compile the function. Having a DoFInvalidAccessor
then serves the same purpose that InvalidAccessor already does for
tria accessor functions: such objects cannot be created but rather
throw an exception, but they provide the correct syntax.

include/deal.II/dofs/dof_accessor.h
include/deal.II/dofs/dof_iterator_selector.h
source/dofs/dof_accessor.cc
source/dofs/dof_accessor.inst.in

index f647257a03f558fe682f90480c5bed72e32b0db8..57f1a959a3d79890ffb04d6a2b63a27679e8933b 100644 (file)
@@ -637,10 +637,9 @@ protected:
    * a cell object, there can only be a single set of degrees of freedom, and
    * fe_index has to match the result of active_fe_index().
    */
-  void set_dof_index
-  (const unsigned int i,
-   const types::global_dof_index index,
-   const unsigned int fe_index = DoFHandlerType::default_fe_index) const;
+  void set_dof_index (const unsigned int i,
+                      const types::global_dof_index index,
+                      const unsigned int fe_index = DoFHandlerType::default_fe_index) const;
 
   void set_mg_dof_index (const int level, const unsigned int i, const types::global_dof_index index) const;
 
@@ -1141,6 +1140,81 @@ protected:
 };
 
 
+
+/* -------------------------------------------------------------------------- */
+
+
+/**
+ * A class that represents DoF accessor objects to iterators that don't make sense
+ * such as quad iterators in on 1d meshes.  This class can not be used to
+ * create objects (it will in fact throw an exception if this should ever be
+ * attempted but it sometimes allows code to be written in a simpler way in a
+ * dimension independent way. For example, it allows to write code that works
+ * on quad iterators that is dimension independent -- i.e., also compiles
+ * in 1d -- because quad iterators
+ * (via the current class) exist and are syntactically correct. You can not
+ * expect, however, to ever create an actual object of one of these iterators
+ * in 1d, meaning you need to expect to wrap the code block in which you use
+ * quad iterators into something like <code>if (dim@>1)</code> -- which makes
+ * eminent sense anyway.
+ *
+ * This class provides the minimal interface necessary for Accessor classes to
+ * interact with Iterator classes. However, this is only for syntactic
+ * correctness, none of the functions do anything but generate errors.
+ *
+ * @ingroup Accessors
+ * @author Wolfgang Bangerth, 2017
+ */
+template <int structdim, int dim, int spacedim=dim>
+class DoFInvalidAccessor : public InvalidAccessor<structdim,dim,spacedim>
+{
+public:
+  /**
+   * Propagate typedef from base class to this class.
+   */
+  typedef typename InvalidAccessor<structdim,dim,spacedim>::AccessorData AccessorData;
+
+  /**
+   * Constructor.  This class is used for iterators that do not make
+   * sense in a given dimension, for example quads for 1d meshes. Consequently,
+   * while the creation of such objects is syntactically valid, they make no
+   * semantic sense, and we generate an exception when such an object is
+   * actually generated.
+   */
+  DoFInvalidAccessor (const Triangulation<dim,spacedim> *parent     =  0,
+                      const int                 level      = -1,
+                      const int                 index      = -1,
+                      const AccessorData       *local_data =  0);
+
+  /**
+   * Copy constructor.  This class is used for iterators that do not make
+   * sense in a given dimension, for example quads for 1d meshes. Consequently,
+   * while the creation of such objects is syntactically valid, they make no
+   * semantic sense, and we generate an exception when such an object is
+   * actually generated.
+   */
+  DoFInvalidAccessor (const DoFInvalidAccessor<structdim,dim,spacedim> &);
+
+  /**
+   * Conversion from other accessors to the current invalid one. This of
+   * course also leads to a run-time error.
+   */
+  template <typename OtherAccessor>
+  DoFInvalidAccessor (const OtherAccessor &);
+
+  /**
+   * Set the index of the <i>i</i>th degree of freedom of this object to @p
+   * index. Since the current object doesn't point to anything useful, like
+   * all other functions in this class this function only throws an exception.
+   */
+  void set_dof_index (const unsigned int i,
+                      const types::global_dof_index index,
+                      const unsigned int fe_index = DoFHandler<dim,spacedim>::default_fe_index) const;
+};
+
+
+
+
 /* -------------------------------------------------------------------------- */
 
 
@@ -1773,6 +1847,21 @@ DoFAccessor<sd, DoFHandlerType, level_dof_access>::is_level_cell()
 
 
 
+template <int structdim, int dim, int spacedim>
+template <typename OtherAccessor>
+DoFInvalidAccessor<structdim, dim, spacedim>::
+DoFInvalidAccessor (const OtherAccessor &)
+{
+  Assert (false,
+          ExcMessage ("You are attempting an illegal conversion between "
+                      "iterator/accessor types. The constructor you call "
+                      "only exists to make certain template constructs "
+                      "easier to write as dimension independent code but "
+                      "the conversion is not valid in the current context."));
+}
+
+
+
 DEAL_II_NAMESPACE_CLOSE
 
 // include more templates
index b8f508d334e1daa081e5f7def7902bf72ff1f587..c292da6c670b954c7fce2cb501d7f4739c1a9142 100644 (file)
@@ -21,7 +21,7 @@
 
 DEAL_II_NAMESPACE_OPEN
 
-template <int, int, int> class InvalidAccessor;
+template <int, int, int> class DoFInvalidAccessor;
 
 template <int structdim, typename DoFHandlerType, bool lda> class DoFAccessor;
 template <typename DoFHandlerType, bool lda> class DoFCellAccessor;
@@ -61,13 +61,13 @@ namespace internal
       typedef TriaIterator      <CellAccessor> line_iterator;
       typedef TriaActiveIterator<CellAccessor> active_line_iterator;
 
-      typedef TriaRawIterator   <InvalidAccessor<2,1,spacedim> > raw_quad_iterator;
-      typedef TriaIterator      <InvalidAccessor<2,1,spacedim> > quad_iterator;
-      typedef TriaActiveIterator<InvalidAccessor<2,1,spacedim> > active_quad_iterator;
+      typedef TriaRawIterator   <DoFInvalidAccessor<2,1,spacedim> > raw_quad_iterator;
+      typedef TriaIterator      <DoFInvalidAccessor<2,1,spacedim> > quad_iterator;
+      typedef TriaActiveIterator<DoFInvalidAccessor<2,1,spacedim> > active_quad_iterator;
 
-      typedef TriaRawIterator   <InvalidAccessor<3,1,spacedim> > raw_hex_iterator;
-      typedef TriaIterator      <InvalidAccessor<3,1,spacedim> > hex_iterator;
-      typedef TriaActiveIterator<InvalidAccessor<3,1,spacedim> > active_hex_iterator;
+      typedef TriaRawIterator   <DoFInvalidAccessor<3,1,spacedim> > raw_hex_iterator;
+      typedef TriaIterator      <DoFInvalidAccessor<3,1,spacedim> > hex_iterator;
+      typedef TriaActiveIterator<DoFInvalidAccessor<3,1,spacedim> > active_hex_iterator;
 
       typedef raw_line_iterator    raw_cell_iterator;
       typedef line_iterator        cell_iterator;
@@ -108,9 +108,9 @@ namespace internal
       typedef TriaIterator      <CellAccessor> quad_iterator;
       typedef TriaActiveIterator<CellAccessor> active_quad_iterator;
 
-      typedef TriaRawIterator   <InvalidAccessor<3,2,spacedim> > raw_hex_iterator;
-      typedef TriaIterator      <InvalidAccessor<3,2,spacedim> > hex_iterator;
-      typedef TriaActiveIterator<InvalidAccessor<3,2,spacedim> > active_hex_iterator;
+      typedef TriaRawIterator   <DoFInvalidAccessor<3,2,spacedim> > raw_hex_iterator;
+      typedef TriaIterator      <DoFInvalidAccessor<3,2,spacedim> > hex_iterator;
+      typedef TriaActiveIterator<DoFInvalidAccessor<3,2,spacedim> > active_hex_iterator;
 
       typedef raw_quad_iterator    raw_cell_iterator;
       typedef quad_iterator        cell_iterator;
index 369208cc598193bee45fccc1c0b93ab4e53f1b07..48b5def831b8bf46d8c87649e9bcad7a5e2845d7 100644 (file)
@@ -36,6 +36,53 @@ const unsigned int DoFAccessor<structdim,DoFHandlerType,level_dof_access>::space
 
 
 
+/*------------------------ Functions: DoFInvalidAccessor ---------------------------*/
+
+template <int structdim, int dim, int spacedim>
+DoFInvalidAccessor<structdim, dim, spacedim>::
+DoFInvalidAccessor (const Triangulation<dim,spacedim> *,
+                    const int,
+                    const int,
+                    const AccessorData *)
+{
+  Assert (false,
+          ExcMessage ("You are attempting an illegal conversion between "
+                      "iterator/accessor types. The constructor you call "
+                      "only exists to make certain template constructs "
+                      "easier to write as dimension independent code but "
+                      "the conversion is not valid in the current context."));
+}
+
+
+
+template <int structdim, int dim, int spacedim>
+DoFInvalidAccessor<structdim, dim, spacedim>::
+DoFInvalidAccessor (const DoFInvalidAccessor &i)
+  :
+  InvalidAccessor<structdim,dim,spacedim> (static_cast<const InvalidAccessor<structdim,dim,spacedim>&>(i))
+{
+  Assert (false,
+          ExcMessage ("You are attempting an illegal conversion between "
+                      "iterator/accessor types. The constructor you call "
+                      "only exists to make certain template constructs "
+                      "easier to write as dimension independent code but "
+                      "the conversion is not valid in the current context."));
+}
+
+
+
+template <int structdim, int dim, int spacedim>
+void
+DoFInvalidAccessor<structdim, dim, spacedim>::
+set_dof_index (const unsigned int,
+               const types::global_dof_index,
+               const unsigned int) const
+{
+  Assert (false, ExcInternalError());
+}
+
+
+
 /*------------------------- Functions: DoFCellAccessor -----------------------*/
 
 
index b0374e47cc5681a3ec4acdff9d66f6dac468dbf9..7efbf4d9b102a826585f82dbb9f8a44c53153cb9 100644 (file)
@@ -164,3 +164,7 @@ for (deal_II_dimension : DIMENSIONS; lda : BOOL)
 #endif
 }
 
+for (deal_II_struct_dimension : DIMENSIONS; deal_II_dimension : DIMENSIONS; deal_II_space_dimension : DIMENSIONS)
+{
+    template class DoFInvalidAccessor<deal_II_struct_dimension,deal_II_dimension,deal_II_space_dimension>;
+}

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

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.