<div dir="ltr"><div>Does it make sense to tackle this before 2.4? I would like to finish the TensorGridFactory before the release. If we postpone the MultiIndex in dune-common, I will go ahead with the factory.<br><br></div>Dominic<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 17, 2015 at 4:45 PM, Oliver Sander <span dir="ltr"><<a href="mailto:sander@igpm.rwth-aachen.de" target="_blank">sander@igpm.rwth-aachen.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Martin,<br>
interesting how different people view this as different things.<br>
<span class=""><br>
> personally, I never understood the class MultiIndex in the StructuredGridFactory. To me, a multiindex is an array of integers with "vector space operations" (have a look at the MultiIndex in<br>
> dune-spgrid, if you like). Unlike in StructuredGridFactory, it is not an iterator of any kind, i.e., ++multiIndex does not make sense to me.<br>
<br>
</span>I have always looked at multi-indices as dyadic representations of numbers,<br>
where the base of each digit can be chosen separately.  Then, ++multiIndex<br>
makes perfect sense -- you simply increment the numbers.<br>
<span class=""><br>
><br>
> What you are looking for (as far as I underdand it) is a special kind of a set of multiindices: Those within within a "cube". This could be realized as an iterator range of multiindices. But for<br>
> multiindices, other ranges are of interest too (e.g., all multiindices within a "simplex").<br>
<br>
</span>I've never thought about the simplex problem; you are right that this can be of interest, too.<br>
Without having giving it much thought I tend to think that your approach (i.e., having algorithmically<br>
defined sets of multi-indices, and iterators over these sets) is more general, and hence preferable.<br>
<br>
Is your implementation easy to look at and understand?<br>
<br>
Cheers,<br>
Oliver<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
><br>
> Apart from such implementation details, I'd be very happy to have such a concept in dune-common, as it would reduce the SPGrid code by a few hundred (basically redundant) lines of code.<br>
><br>
> Best,<br>
><br>
> Martin<br>
><br>
><br>
> On 03/16/2015 10:26 PM, Oliver Sander wrote:<br>
>> Am 16.03.2015 um 19:33 schrieb Dominic Kempf:<br>
>>> Sounds like a good idea to me. Maybe we could/should extend the interface<br>
>>> then? postfix operator++, the operator--s, logical and stream operators<br>
>>> come to my mind.<br>
>><br>
>> Definitely.  Also, one usually needs a way to iterate over the entire range<br>
>> of the multi-index.  Previously I have used a method 'cycle', which says how<br>
>> many times I can call operator++ before I getting an overflow, but there may<br>
>> be better solutions.<br>
>><br>
>>><br>
>>> On Mon, Mar 16, 2015 at 7:17 PM, Oliver Sander <<a href="mailto:sander@igpm.rwth-aachen.de">sander@igpm.rwth-aachen.de</a>><br>
>>> wrote:<br>
>>><br>
>>>> Hi all,<br>
>>>><br>
>>>>><br>
>>>>>      Move MultiIndex class from StructuredGridFactory to a separate header<br>
>>>>><br>
>>>>>      The TensorGridFactory needs the same class, so I move it to a new<br>
>>>> header.<br>
>>>><br>
>>>> a smart move.  I have needed (and reimplemented) such a class again and<br>
>>>> again.<br>
>>>> Maybe we should move multiindex.hh into dune-common right away?<br>
>>>> --<br>
>>>> Oliver<br>
>>>><br>
>>>><br>
>>>>><br>
>>>>>   dune/grid/utility/CMakeLists.txt           |  1 +<br>
>>>>>   dune/grid/utility/Makefile.am              |  1 +<br>
>>>>>   dune/grid/utility/multiindex.hh            | 57<br>
>>>> ++++++++++++++++++++++++++++++<br>
>>>>>   dune/grid/utility/structuredgridfactory.hh | 53<br>
>>>> +++------------------------<br>
>>>>>   dune/grid/utility/tensorgridfactory.hh     |  2 ++<br>
>>>>>   5 files changed, 65 insertions(+), 49 deletions(-)<br>
>>>>>   create mode 100644 dune/grid/utility/multiindex.hh<br>
>>>>><br>
>>>>><br>
>>>>><br>
>>>>> diff --git a/dune/grid/utility/CMakeLists.txt<br>
>>>> b/dune/grid/utility/CMakeLists.txt<br>
>>>>> index 1c42604..15d2311 100644<br>
>>>>> --- a/dune/grid/utility/CMakeLists.txt<br>
>>>>> +++ b/dune/grid/utility/CMakeLists.txt<br>
>>>>> @@ -8,6 +8,7 @@ set(HEADERS<br>
>>>>>     gridtype.hh<br>
>>>>>     hierarchicsearch.hh<br>
>>>>>     hostgridaccess.hh<br>
>>>>> +  multiindex.hh<br>
>>>>>     parmetisgridpartitioner.hh<br>
>>>>>     persistentcontainer.hh<br>
>>>>>     persistentcontainerinterface.hh<br>
>>>>> diff --git a/dune/grid/utility/Makefile.am<br>
>>>> b/dune/grid/utility/Makefile.am<br>
>>>>> index e14c152..d81c3e2 100644<br>
>>>>> --- a/dune/grid/utility/Makefile.am<br>
>>>>> +++ b/dune/grid/utility/Makefile.am<br>
>>>>> @@ -10,6 +10,7 @@ gridutility_HEADERS =                               \<br>
>>>>>        gridtype.hh                             \<br>
>>>>>        hierarchicsearch.hh                     \<br>
>>>>>        hostgridaccess.hh                       \<br>
>>>>> +     multiindex.hh \<br>
>>>>>        parmetisgridpartitioner.hh              \<br>
>>>>>        persistentcontainer.hh                  \<br>
>>>>>        persistentcontainerinterface.hh         \<br>
>>>>> diff --git a/dune/grid/utility/multiindex.hh<br>
>>>> b/dune/grid/utility/multiindex.hh<br>
>>>>> new file mode 100644<br>
>>>>> index 0000000..b6b281f<br>
>>>>> --- /dev/null<br>
>>>>> +++ b/dune/grid/utility/multiindex.hh<br>
>>>>> @@ -0,0 +1,57 @@<br>
>>>>> +#ifndef DUNE_GRID_UTILITY_MULTIINDEX_HH<br>
>>>>> +#define DUNE_GRID_UTILITY_MULTIINDEX_HH<br>
>>>>> +<br>
>>>>> +/** \file<br>
>>>>> + *  \brief Implements a multiindex with arbitrary dimension and fixed<br>
>>>> index ranges<br>
>>>>> + *  This is used by various factory classes.<br>
>>>>> + */<br>
>>>>> +<br>
>>>>> +#include<array><br>
>>>>> +<br>
>>>>> +namespace Dune<br>
>>>>> +{<br>
>>>>> + namespace FactoryUtilities<br>
>>>>> + {<br>
>>>>> +  template<std::size_t dim><br>
>>>>> +  class MultiIndex : public std::array<unsigned int,dim><br>
>>>>> +  {<br>
>>>>> +    // The range of each component<br>
>>>>> +    std::array<unsigned int,dim> limits_;<br>
>>>>> +<br>
>>>>> +  public:<br>
>>>>> +    /** \brief Constructor with a given range for each digit */<br>
>>>>> +    MultiIndex(const std::array<unsigned int,dim>& limits) :<br>
>>>> limits_(limits)<br>
>>>>> +    {<br>
>>>>> +      std::fill(this->begin(), this->end(), 0);<br>
>>>>> +    }<br>
>>>>> +<br>
>>>>> +    /** \brief Increment the MultiIndex */<br>
>>>>> +    MultiIndex<dim>& operator++()<br>
>>>>> +    {<br>
>>>>> +      for (int i=0; i<dim; i++)<br>
>>>>> +      {<br>
>>>>> +        // Augment digit<br>
>>>>> +        (*this)[i]++;<br>
>>>>> +<br>
>>>>> +        // If there is no carry-over we can stop here<br>
>>>>> +        if ((*this)[i]<limits_[i])<br>
>>>>> +          break;<br>
>>>>> +<br>
>>>>> +        (*this)[i] = 0;<br>
>>>>> +      }<br>
>>>>> +      return *this;<br>
>>>>> +    }<br>
>>>>> +<br>
>>>>> +    /** \brief Compute how many times you can call operator++ before<br>
>>>> getting to (0,...,0) again */<br>
>>>>> +    size_t cycle() const<br>
>>>>> +    {<br>
>>>>> +      size_t result = 1;<br>
>>>>> +      for (int i=0; i<dim; i++)<br>
>>>>> +        result *= limits_[i];<br>
>>>>> +      return result;<br>
>>>>> +    }<br>
>>>>> +  };<br>
>>>>> + }<br>
>>>>> +}<br>
>>>>> +<br>
>>>>> +#endif<br>
>>>>> diff --git a/dune/grid/utility/structuredgridfactory.hh<br>
>>>> b/dune/grid/utility/structuredgridfactory.hh<br>
>>>>> index 8832149..8e2700a 100644<br>
>>>>> --- a/dune/grid/utility/structuredgridfactory.hh<br>
>>>>> +++ b/dune/grid/utility/structuredgridfactory.hh<br>
>>>>> @@ -19,6 +19,7 @@<br>
>>>>>   #include <dune/common/shared_ptr.hh><br>
>>>>><br>
>>>>>   #include <dune/grid/common/gridfactory.hh><br>
>>>>> +#include <dune/grid/utility/multiindex.hh><br>
>>>>>   #include <dune/grid/yaspgrid.hh><br>
>>>>><br>
>>>>>   namespace Dune {<br>
>>>>> @@ -34,59 +35,13 @@ namespace Dune {<br>
>>>>><br>
>>>>>       static const int dimworld = GridType::dimensionworld;<br>
>>>>><br>
>>>>> -    /** \brief dim-dimensional multi-index.  The range for each<br>
>>>> component can be set individually<br>
>>>>> -     */<br>
>>>>> -    class MultiIndex<br>
>>>>> -      : public array<unsigned int,dim><br>
>>>>> -    {<br>
>>>>> -<br>
>>>>> -      // The range of each component<br>
>>>>> -      array<unsigned int,dim> limits_;<br>
>>>>> -<br>
>>>>> -    public:<br>
>>>>> -      /** \brief Constructor with a given range for each digit */<br>
>>>>> -      MultiIndex(const array<unsigned int,dim>& limits)<br>
>>>>> -        : limits_(limits)<br>
>>>>> -      {<br>
>>>>> -        std::fill(this->begin(), this->end(), 0);<br>
>>>>> -      }<br>
>>>>> -<br>
>>>>> -      /** \brief Increment the MultiIndex */<br>
>>>>> -      MultiIndex& operator++() {<br>
>>>>> -<br>
>>>>> -        for (int i=0; i<dim; i++) {<br>
>>>>> -<br>
>>>>> -          // Augment digit<br>
>>>>> -          (*this)[i]++;<br>
>>>>> -<br>
>>>>> -          // If there is no carry-over we can stop here<br>
>>>>> -          if ((*this)[i]<limits_[i])<br>
>>>>> -            break;<br>
>>>>> -<br>
>>>>> -          (*this)[i] = 0;<br>
>>>>> -<br>
>>>>> -        }<br>
>>>>> -        return *this;<br>
>>>>> -      }<br>
>>>>> -<br>
>>>>> -      /** \brief Compute how many times you can call operator++ before<br>
>>>> getting to (0,...,0) again */<br>
>>>>> -      size_t cycle() const {<br>
>>>>> -        size_t result = 1;<br>
>>>>> -        for (int i=0; i<dim; i++)<br>
>>>>> -          result *= limits_[i];<br>
>>>>> -        return result;<br>
>>>>> -      }<br>
>>>>> -<br>
>>>>> -    };<br>
>>>>> -<br>
>>>>>       /** \brief Insert a structured set of vertices into the factory */<br>
>>>>>       static void insertVertices(GridFactory<GridType>& factory,<br>
>>>>>                                  const FieldVector<ctype,dimworld>&<br>
>>>> lowerLeft,<br>
>>>>>                                  const FieldVector<ctype,dimworld>&<br>
>>>> upperRight,<br>
>>>>>                                  const array<unsigned int,dim>& vertices)<br>
>>>>>       {<br>
>>>>> -<br>
>>>>> -      MultiIndex index(vertices);<br>
>>>>> +      FactoryUtilities::MultiIndex<dim> index(vertices);<br>
>>>>><br>
>>>>>         // Compute the total number of vertices to be created<br>
>>>>>         int numVertices = index.cycle();<br>
>>>>> @@ -166,7 +121,7 @@ namespace Dune {<br>
>>>>>                 cornersTemplate[i] += unitOffsets[j];<br>
>>>>><br>
>>>>>           // Insert elements<br>
>>>>> -        MultiIndex index(elements);<br>
>>>>> +        FactoryUtilities::MultiIndex<dim> index(elements);<br>
>>>>><br>
>>>>>           // Compute the total number of elementss to be created<br>
>>>>>           int numElements = index.cycle();<br>
>>>>> @@ -234,7 +189,7 @@ namespace Dune {<br>
>>>>><br>
>>>>>           // Loop over all "cubes", and split up each cube into dim!<br>
>>>>>           // (factorial) simplices<br>
>>>>> -        MultiIndex elementsIndex(elements);<br>
>>>>> +        FactoryUtilities::MultiIndex<dim> elementsIndex(elements);<br>
>>>>>           size_t cycle = elementsIndex.cycle();<br>
>>>>><br>
>>>>>           for (size_t i=0; i<cycle; ++elementsIndex, i++) {<br>
>>>>> diff --git a/dune/grid/utility/tensorgridfactory.hh<br>
>>>> b/dune/grid/utility/tensorgridfactory.hh<br>
>>>>> index 971bc4e..8aa47cf 100644<br>
>>>>> --- a/dune/grid/utility/tensorgridfactory.hh<br>
>>>>> +++ b/dune/grid/utility/tensorgridfactory.hh<br>
>>>>> @@ -19,6 +19,8 @@<br>
>>>>>   #include<memory><br>
>>>>>   #include<vector><br>
>>>>><br>
>>>>> +#include<dune/grid/utility/multiindex.hh><br>
>>>>> +<br>
>>>>>   namespace Dune<br>
>>>>>   {<br>
>>>>>     // forward declaration of TensorGridFactoryCreator, which is the real<br>
>>>> factory<br>
>>>>><br>
>>>>> _______________________________________________<br>
>>>>> Dune-Commit mailing list<br>
>>>>> <a href="mailto:Dune-Commit@dune-project.org">Dune-Commit@dune-project.org</a><br>
>>>>> <a href="http://lists.dune-project.org/mailman/listinfo/dune-commit" target="_blank">http://lists.dune-project.org/mailman/listinfo/dune-commit</a><br>
>>>>><br>
>>>><br>
>>>><br>
>>>><br>
>>>> _______________________________________________<br>
>>>> Dune-devel mailing list<br>
>>>> <a href="mailto:Dune-devel@dune-project.org">Dune-devel@dune-project.org</a><br>
>>>> <a href="http://lists.dune-project.org/mailman/listinfo/dune-devel" target="_blank">http://lists.dune-project.org/mailman/listinfo/dune-devel</a><br>
>>>><br>
>>>><br>
>>><br>
>><br>
>><br>
>><br>
>><br>
>> _______________________________________________<br>
>> Dune-devel mailing list<br>
>> <a href="mailto:Dune-devel@dune-project.org">Dune-devel@dune-project.org</a><br>
>> <a href="http://lists.dune-project.org/mailman/listinfo/dune-devel" target="_blank">http://lists.dune-project.org/mailman/listinfo/dune-devel</a><br>
>><br>
><br>
<br>
<br>
</div></div><br>_______________________________________________<br>
Dune-devel mailing list<br>
<a href="mailto:Dune-devel@dune-project.org">Dune-devel@dune-project.org</a><br>
<a href="http://lists.dune-project.org/mailman/listinfo/dune-devel" target="_blank">http://lists.dune-project.org/mailman/listinfo/dune-devel</a><br>
<br></blockquote></div><br></div>