This file is indexed.

/usr/include/dune/geometry/virtualrefinement.hh is in libdune-geometry-dev 2.4.1-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_GEOMETRY_VIRTUALREFINEMENT_HH
#define DUNE_GEOMETRY_VIRTUALREFINEMENT_HH

/*!
 * \file
 *
 * \brief This file contains the virtual wrapper around refinement.
 */

/*!
 * \addtogroup VirtualRefinement Virtual Refinement
 * \ingroup Refinement
 *   <!--WWWWWWWWWWWWWWWWWWWW-->
 *
 * Please have a look on the non-virtual \link Refinement
 * Refinement\endlink documentation.
 *
 * \section Virtual_General General
 * <!--=========-->
 *
 * \link Refinement Refinement\endlink can only be used when you know
 * the geometryType of your entities at compile time.  You could
 * circumvent this by using a switch(geometryType), but each case would
 * look very much the same.  If you have many such switch() statements,
 * or each case contains lots of code, or you simply have many possible
 * geometryTypes, this can be quiet annoying.
 *
 * VirtualRefinement does all of this switch() statements for you.  It
 * defines a common virtual base class per dimension, and derives one
 * class for each geometryType and coerceTo from that class.  The
 * derived classes simply wrap the non-virtual classes from \link
 * Refinement Refinement\endlink.  This makes it possible to treat each
 * geometryType (of a given dimension) the same, and thus eleminates
 * the many repetitions of lots of code.
 *
 * But the case statements are not totally gone yet.  VirtualRefinement
 * does these statements once and for all by wrapping them into the
 * buildRefinement() function.
 *
 * \section Virtual_User_interface The user Interface
 * <!--===================================-->
 *
 * \subsection VirtualRefinement The VirtualRefinement class
 * <!------------------------------------------------------>
 *
 * VirtualRefinement is not a set of unrelated specialisations of the
 * same template class.  VirtualRefinement is a base class with several
 * virtual methods, which are overloaded by the concrete
 * VirtualRefinement implementation classes.  Each implementation class
 * wraps one of the non-virtual \link Refinement Refinement\endlink
 * classes.
 *
 * The user interface is modelled closely after the the \link
 * Refinement Refinement\endlink interface.  The main differences are:
 *
 * - VirtualRefinement is not a static class, but a singleton.  Thus
 *   each VirtualRefinement implementation has to be instanciated
 *   before use.  This is done with the template function
 *   buildRefinement (see below).
 * - Since the methods of VirtualRefinement are virtual (or use virtual
 *   methods themself) they have to be called like
 *   \code
 * refinementInstace.nElements(level);
 *   \endcode
 *   instead of
 *   \code
 * RefinementTypedef::nElements(level);
 *   \endcode
 *
 * - IndexVector is a std::vector instead of a FieldVector since the
 *   number of corners of different geometry types may be different at
 *   runtime.  The user is responsible to always pass the same coerceTo
 *   parameter to buildRefinement() so he always gets the same number
 *   of corners.
 *
 * \code
 * template<int dimension>
 * class VirtualRefinement
 * {
 * public:
 *   template<int Codimension>
 *   struct Codim {
 *     class SubEntityIterator;
 *   };
 *   typedef VertexIterator; // These are aliases for Codim<codim>::SubEntityIterator
 *   typedef ElementIterator;
 *
 *   typedef IndexVector; // This is a std::vector
 *   typedef CoordVector; // This is a FieldVector
 *
 *   virtual int nVertices(int level) const;
 *   VertexIterator vBegin(int level) const;
 *   VertexIterator vEnd(int level) const;
 *   virtual int nElements(int level) const;
 *   ElementIterator eBegin(int level) const;
 *   ElementIterator eEnd(int level) const;
 * };
 * \endcode
 *
 * The iterators have the same interface as the \link Refinement
 * Refinement\endlink iterators except that IndexVector is a
 * std::vector instead of a FieldVector (see above).  Also the
 * restriction that the Iterators are not derefencable applies.
 *
 * \code
 * template<int dimension>
 * class VertexIterator
 * {
 * public:
 *   typedef VirtualRefinement<dimension> Refinement;
 *
 *   int index() const;
 *   Refinement::CoordVector coords() const;
 * };
 *
 * template<int dimension>
 * class ElementIterator
 * {
 * public:
 *   typedef VirtualRefinement<dimension> Refinement;
 *
 *   int index() const;
 *   // Coords of the center of mass of the element
 *   Refinement::CoordVector coords() const;
 *   Refinement::IndexVector vertexIndices() const;
 * };
 * \endcode
 *
 * \subsection User_interface_buildRefinement buildRefinement()
 * <!------------------------------------------>
 *
 * The declaration for buildRefinement is
 *
 * \code
 * template<int dimension, class CoordType>
 * VirtualRefinement<dimension, CoordType> &buildRefinement(GeometryType geometryType, GeometryType coerceTo);
 * \endcode
 *
 * It is expected that you know the dimension and the coordinate type
 * of the elements you want to refine at compile time.
 *
 * The simple case is that you want to refine, say, quadrilaterals and
 * the subentities should look like quadrilaterals as well.  In that
 * case you would call buildRefinement() like
 *
 * \code
 * VirtualRefinement<2, CoordType> &refinement = buildRefinement<2, CoordType>(quadrilateral, quadrilateral);
 * \endcode
 *
 * The more complicated case is that your entity is a quadrilateral,
 * but the subentities should look like triangles.  In this case call
 * buildRefinement() like
 *
 * \code
 * VirtualRefinement<2, CoordType> &refinement = buildRefinement<2, CoordType>(quadrilateral, triangle);
 * \endcode
 *
 * Summary: geometryType is the geometry type of the entity you want to
 * refine, while coerceTo is the geometry type of the subentities.
 *
 * \section Virtual_Implementing Implementing a new Refinement type
 * <!--=================================================-->
 *
 * When you write a Refinement implementation for a new combination of
 * geometryType and coerceTo, you have to tell buildRefinement() about
 * it.
 *
 * - First, you have to implement the non-virtual part in \link
 *   Refinement Refinement\endlink, if you have not done so yet.
 * - Second, visit the end of refinementvirtual.cc, and look for the
 *   specialisations of template<int dimension, class CoordType> class
 *   RefinementBuilder.  There is one specialisation for each
 *   dimension, containing the single method build().
 * - The build() contains two levels of switch statements, the outer
 *   for geomentryType and the inner for coerceTo.  Each case will
 *   either return the correct VirtualRefinement or fall throught to
 *   the end of the method and throw an error.  Insert the cases for
 *   your refinement.
 *
 * Everything else has been done for you automatically.
 *
 * \subsection Virtual_Namespaces Namespaces
 * <!------------------->
 *
 * VirtualRefinement does not use a complicated namespace scheme like
 * \link Refinement Refinement\endlink.  The complete VirtualRefinement
 * stuff simply lives directly in namespace Dune.
 *
 * \subsection Virtual_Layers Conceptual layers
 * <!--------------------------------->
 *
 * VirtualRefinement adds to more layers to the ones already defined in
 * \link Refinement Refinement\endlink:
 *
 * - <strong>Layer 3</strong> makes it easy to use several Refinement
 *   implementations in the same code, when you only know at run-time,
 *   which Refinement implementation you need.  It wraps class
 *   Refinement and it's iterators into a Proxy class, retaining it's
 *   interface but all deriving from a virtual base class
 *   VirtualRefinement<dimension, CoordType>.  This is located in
 *   refinementvirtual.cc.
 * - <strong>Layer 4</strong> defines function
 *   buildRefinement(geometryType, coerceTo), which returns the right
 *   refinement for a runtime-determined GeometryType.  It is also
 *   located in refinementvirtual.cc
 *
 * \section Implementation
 * <!--================-->
 *
 * The interface is defined by the template class VirtualRefinement.
 * It simply defines the CoordVectors and IndexVectors appropriate for
 * this dimension and CoordType, defines which iterators to use, and
 * provides some proxy or pure virtual functions.
 *
 * For each class Refinement<geometryType, CoordType, coercTo, dim> we
 * provide a class VirtualRefinementImp<geometryType, CoordType,
 * coercTo, dim>, which wraps the matching class
 * Refinement<geometryType, CoordType, coercTo, dim> and derives from
 * the matching base class VirtualRefinement<dimension, CoordType>.
 * Each VirtualRefinementImp is a singleton and has a static instance()
 * method which will return this instance as a reference to the base
 * class VirtualRefinement.  All this is done in a single template
 * class.
 *
 * \subsection Virtual_Iterators The iterators
 * <!-------------------------------->
 *
 * We can't do the same thing with the iterators as we do with class
 * VirtualRefinement.  Since they are polymorph we cannot simply pass
 * them into user code.  They are not singletons, so we also cannot
 * pass references to them.  Passing pointers to iterators would work,
 * but then the programmer has to remember to explecitely delete them.
 * Also, it is uncommon for iterators to be handled by their pointers.
 *
 * What we do instead is having a wrapper class which conforms to the
 * iterator interface and is the same for all
 * VirtualRefinementIterators of a given dimension.  This class
 * contains a pointer to a polymorph backend object implementing the
 * iterator.  The various VirtualRefinementImps then derive from the
 * abstract backend class and pass a pointer to a concrete backend
 * object when instantiating an iterator.
 *
 * \subsection Implementiaion_buildRefinement buildRefinement()
 * <!------------------------------------------>
 *
 * The template function buildRefinement() has to be specialized for
 * each dimension.  It makes no sense to test for
 * geometryType.isPrism() when dimension==2.  But this
 * way we run into a limitation of C++: we can't do partial function
 * specialisation.
 *
 * The workaround is to create a class RefinementBuilder with a lone
 * static method build() and to call that from buildRefinement().
 * Since RefinementBuilder is a class and not a function we can do
 * partial specialisations.
 *
 * It is probably possible to automatically generate the switch
 * statements with linked lists of template structs, functions
 * implementing the cases, and a recursive template function that will
 * iterate over the list, but it is probably not worth the effort, as
 * long as buildRefinement() is enough for the job.
 */

#include <vector>

#include <dune/common/fvector.hh>

#include "refinement.hh"
#include "type.hh"

namespace Dune
{
  // //////////////////////////////////////////
  //
  // The virtual base class and its iterators
  //

  //
  // Refinement
  //

  /*!
   * \brief VirtualRefinement base class
   *
   * \param dimension The dimension of the element to refine
   * \param CoordType The C++ type of the coordinates
   */
  template<int dimension, class CoordType>
  class VirtualRefinement
  {
  public:
    template<int codimension>
    struct Codim;
    //! The VertexIterator of the VirtualRefinement.
    typedef typename Codim<dimension>::SubEntityIterator VertexIterator;
    //! The ElementIterator of the VirtualRefinement
    typedef typename Codim<0>::SubEntityIterator ElementIterator;

    /*!
     * \brief The CoordVector of the VirtualRefinement
     *
     * This is always a typedef to a FieldVector
     */
    typedef FieldVector<CoordType, dimension> CoordVector;
    /*!
     * \brief The IndexVector of the VirtualRefinement
     *
     * This is always a typedef to a std::vector
     */
    typedef std::vector<int> IndexVector;

    template<int codimension>
    class SubEntityIteratorBack;
    typedef SubEntityIteratorBack<dimension> VertexIteratorBack;
    typedef SubEntityIteratorBack<0> ElementIteratorBack;

    //! Get the number of Vertices
    virtual int nVertices(int level) const = 0;
    //! Get a VertexIterator
    VertexIterator vBegin(int level) const;
    //! Get a VertexIterator
    VertexIterator vEnd(int level) const;

    //! Get the number of Elements
    virtual int nElements(int level) const = 0;
    //! Get an ElementIterator
    ElementIterator eBegin(int level) const;
    //! Get an ElementIterator
    ElementIterator eEnd(int level) const;

    //! Destructor
    virtual ~VirtualRefinement()
    {}

  protected:
    virtual VertexIteratorBack *vBeginBack(int level) const = 0;
    virtual VertexIteratorBack *vEndBack(int level) const = 0;
    virtual ElementIteratorBack *eBeginBack(int level) const = 0;
    virtual ElementIteratorBack *eEndBack(int level) const = 0;
  };

  //! codim database of VirtualRefinement
  template<int dimension, class CoordType>
  template<int codimension>
  struct VirtualRefinement<dimension, CoordType>::Codim
  {
    class SubEntityIterator;
  };

  // ////////////////////////
  //
  // The refinement builder
  //

  template<int dimension, class CoordType>
  VirtualRefinement<dimension, CoordType> &
  buildRefinement(GeometryType geometryType, GeometryType coerceTo);

} // namespace Dune

#include "virtualrefinement.cc"

#endif // DUNE_GEOMETRY_VIRTUALREFINEMENT_HH