Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Praetorius, Simon
dune-multimesh
Commits
848b8812
Commit
848b8812
authored
Nov 21, 2018
by
Praetorius, Simon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
reorganization of multimesh iterator to support various implementation of increment
parent
b54b6417
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
627 additions
and
235 deletions
+627
-235
dune/multimesh/mmgridview.hh
dune/multimesh/mmgridview.hh
+1
-1
dune/multimesh/mmhierarchiciterator.hh
dune/multimesh/mmhierarchiciterator.hh
+2
-2
dune/multimesh/mmiterator.hh
dune/multimesh/mmiterator.hh
+159
-209
dune/multimesh/mmiteratorbase.hh
dune/multimesh/mmiteratorbase.hh
+226
-0
dune/multimesh/mmiteratorinterface.hh
dune/multimesh/mmiteratorinterface.hh
+84
-0
dune/multimesh/multigridview.hh
dune/multimesh/multigridview.hh
+4
-4
dune/multimesh/multiiterator.hh
dune/multimesh/multiiterator.hh
+133
-0
dune/multimesh/multimesh.hh
dune/multimesh/multimesh.hh
+17
-19
test/testgridviews.cc
test/testgridviews.cc
+1
-0
No files found.
dune/multimesh/mmgridview.hh
View file @
848b8812
...
...
@@ -223,7 +223,7 @@ namespace Dune
class
MultiMeshLeafGridView
{
public:
using
Traits
=
MultiMeshLe
vel
GridViewTraits
<
GridImp
>
;
using
Traits
=
MultiMeshLe
af
GridViewTraits
<
GridImp
>
;
/// The MultiMesh GridType
using
Grid
=
typename
Traits
::
Grid
;
...
...
dune/multimesh/mmhierarchiciterator.hh
View file @
848b8812
...
...
@@ -22,8 +22,8 @@ namespace Dune
typename
HostGrid
::
template
Codim
<
0
>
::
Entity
>
{
private:
template
<
int
codim
,
PartitionIteratorType
pitype
,
class
H
ostGrid_
>
friend
class
MultiMeshIterator
;
template
<
PartitionIteratorType
pitype
,
class
H
G
,
class
D
>
friend
class
MultiMeshIterator
Base
;
using
HostEntity
=
typename
HostGrid
::
template
Codim
<
0
>
::
Entity
;
using
EntityTest
=
std
::
function
<
bool
(
HostEntity
)
>
;
...
...
dune/multimesh/mmiterator.hh
View file @
848b8812
...
...
@@ -4,295 +4,245 @@
#define DUNE_MULTIMESH_ITERATOR_HH
#include <numeric>
#include <stack>
#include <variant>
#include <vector>
#include <dune/common/iteratorfacades.hh>
#include <dune/common/std/type_traits.hh>
#include <dune/grid/common/exceptions.hh>
#include <dune/grid/common/gridenums.hh>
#include "mmentity.hh"
#include "mmhierarchiciterator.hh"
#include "mmiteratorbase.hh"
namespace
Dune
{
/** \brief Iterator over all entities of a given codimension and level of a grid.
* \ingroup MultiMesh
*/
template
<
int
codim
,
PartitionIteratorType
pitype
,
class
HostGrid
>
class
MultiMeshIterator
class
MultiMesh
LevelIterator
:
public
Dummy
Iterator
{
public:
template
<
class
...
Args
>
MultiMeshIterator
(
Args
&&
...
args
)
{
DUNE_THROW
(
NotImplemented
,
"Not implemented for entity of codim != 0!"
);
}
int
operator
*
()
const
{
return
0
;
}
MultiMeshIterator
&
operator
++
()
{
return
*
this
;
}
MultiMeshIterator
operator
++
(
int
)
{
return
*
this
;
}
bool
operator
!=
(
MultiMeshIterator
const
&
)
const
{
return
false
;
}
using
DummyIterator
::
DummyIterator
;
};
// Implemented for codim 0 entities only
template
<
PartitionIteratorType
pitype
,
class
HostGrid
>
class
MultiMeshIterator
<
0
,
pitype
,
HostGrid
>
:
public
ForwardIteratorFacade
<
MultiMeshIterator
<
0
,
pitype
,
HostGrid
>
,
MultiEntity
<
HostGrid
>
,
MultiEntity
<
HostGrid
>
const
&>
class
MultiMeshLevelIterator
<
0
,
pitype
,
HostGrid
>
:
public
MultiMeshIteratorBase
<
pitype
,
HostGrid
,
MultiMeshLevelIterator
<
0
,
pitype
,
HostGrid
>>
{
private:
// LevelIterator to the equivalent entity in the host grid
using
HostGridLevelIterator
=
typename
HostGrid
::
template
Codim
<
0
>
::
template
Partition
<
pitype
>
::
LevelIterator
;
using
Self
=
MultiMeshLevelIterator
;
using
Super
=
MultiMeshIteratorBase
<
pitype
,
HostGrid
,
Self
>
;
using
HostEntity
=
typename
HostGrid
::
template
Codim
<
0
>
::
Entity
;
using
EntityTest
=
typename
MultiMeshHierarchicIterator
<
HostGrid
>::
EntityTest
;
using
EntityStack
=
typename
MultiMeshHierarchicIterator
<
HostGrid
>::
EntityStack
;
using
EntityTest
=
typename
Super
::
EntityTest
;
public:
//
/ Constructor. Stores a poin
ter
to
the grid
//
Level i
ter
a
to
r
template
<
class
GridImp
>
MultiMeshIterator
(
const
GridImp
*
multiMesh
,
int
level
)
:
incrementAllowed_
(
multiMesh
->
size
(),
true
)
MultiMeshLevelIterator
(
tag
::
begin_iterator
,
const
GridImp
*
multiMesh
,
int
level
)
:
Super
{
tag
::
begin_iterator
{},
multiMesh
}
,
incrementAllowed_
(
multiMesh
->
size
(),
true
)
,
contains_
(
multiMesh
->
size
(),
EntityTest
{[
level
](
const
HostEntity
&
entity
)
{
return
entity
.
level
()
==
level
;
}})
,
maxLevel_
(
multiMesh
->
size
(),
level
)
,
multiEntity_
(
multiMesh
->
size
())
{
for
(
auto
const
&
grid
:
multiMesh
->
grids_
)
{
macroIterators_
.
push_back
(
grid
->
levelGridView
(
0
).
template
begin
<
0
,
pitype
>());
macroEndIterators_
.
push_back
(
grid
->
levelGridView
(
0
).
template
end
<
0
,
pitype
>());
}
// go to first leaf entity on all grids
entityStacks_
.
reserve
(
multiMesh
->
size
());
for
(
std
::
size_t
i
=
0
;
i
<
multiMesh
->
size
();
++
i
)
{
maxLevel_
[
i
]
=
(
*
multiMesh
)[
i
].
maxLevel
();
entityStacks_
.
emplace_back
((
*
multiMesh
)[
i
].
maxLevel
());
initialIncrement
(
i
);
}
this
->
initialIncrement
();
}
/// Constructor which create the end iterator
/**
* \param multiMesh Pointer to grid instance
* \param endDummy Here only to distinguish it from the other constructor
*/
// End iterator
template
<
class
GridImp
>
MultiMeshIterator
(
const
GridImp
*
multiMesh
,
int
level
,
bool
endDummy
)
MultiMeshLevelIterator
(
tag
::
end_iterator
,
const
GridImp
*
multiMesh
,
int
level
=
-
1
)
:
Super
{
tag
::
end_iterator
{},
multiMesh
}
{}
void
initialIncrement_impl
()
{
for
(
auto
const
&
grid
:
multiMesh
->
grids_
)
macroIterators_
.
push_back
(
grid
->
levelGridView
(
0
).
template
end
<
0
,
pitype
>()
);
for
(
std
::
size_t
i
=
0
;
i
<
this
->
size
();
++
i
)
this
->
initialIncrement
(
i
);
}
/// Constructor which create the leaf-iterator
template
<
class
GridImp
>
MultiMeshIterator
(
const
GridImp
*
multiMesh
)
:
MultiMeshIterator
{
multiMesh
,
-
1
}
{}
void
increment_impl
()
{
for
(
std
::
size_t
i
=
0
;
i
<
this
->
size
();
++
i
)
incrementAllowed_
[
i
]
=
this
->
incrementAllowed
(
i
);
/// Constructor which create the end leaf-iterator
template
<
class
GridImp
>
MultiMeshIterator
(
const
GridImp
*
multiMesh
,
bool
endDummy
)
:
MultiMeshIterator
{
multiMesh
,
-
1
,
endDummy
}
{
}
for
(
std
::
size_t
i
=
0
;
i
<
this
->
size
();
++
i
)
{
if
(
incrementAllowed_
[
i
])
this
->
increment
(
i
);
}
}
/// Construct an iterator from n gridViews of possibly different type
template
<
class
...
GridViews
,
std
::
enable_if_t
<
not
Std
::
disjunction
<
std
::
is_same
<
GridViews
,
bool
>...
>::
value
,
int
>
=
0
>
MultiMeshIterator
(
GridViews
const
&
...
gridViews
)
:
incrementAllowed_
(
sizeof
...(
GridViews
),
true
)
,
maxLevel_
{
gridViews
.
grid
().
maxLevel
()...}
,
multiEntity_
(
sizeof
...(
GridViews
))
,
macroIterators_
{
gridViews
.
grid
().
levelGridView
(
0
).
template
begin
<
0
,
pitype
>()...}
,
macroEndIterators_
{
gridViews
.
grid
().
levelGridView
(
0
).
template
end
<
0
,
pitype
>()...}
,
entityStacks_
{
EntityStack
{
gridViews
.
grid
().
maxLevel
()}...}
const
MultiEntity
<
HostGrid
>&
dereference_impl
()
const
{
contains_
.
reserve
(
sizeof
...(
GridViews
));
Hybrid
::
forEach
(
std
::
forward_as_tuple
(
gridViews
...),
[
this
](
auto
const
&
gv
)
{
contains_
.
emplace_back
([
gv
](
const
HostEntity
&
entity
)
{
return
gv
.
contains
(
entity
);
});
});
// update entries in multiEntity that have changed
for
(
std
::
size_t
i
=
0
;
i
<
this
->
size
();
++
i
)
{
if
(
incrementAllowed_
[
i
])
multiEntity_
[
i
]
=
this
->
dereference
(
i
);
}
return
multiEntity_
;
}
for
(
std
::
size_t
i
=
0
;
i
<
sizeof
...(
GridViews
);
++
i
)
initialIncrement
(
i
);
bool
levelReached_impl
(
std
::
size_t
i
,
const
HostEntity
&
entity
)
const
{
return
contains_
[
i
](
entity
)
||
entity
.
isLeaf
();
}
template
<
class
...
GridViews
>
MultiMeshIterator
(
bool
endDummy
,
GridViews
const
&
...
gridViews
)
:
macroIterators_
{
gridViews
.
grid
().
levelGridView
(
0
).
template
end
<
0
,
pitype
>()...}
{}
private:
std
::
vector
<
bool
>
incrementAllowed_
;
std
::
vector
<
EntityTest
>
contains_
;
mutable
MultiEntity
<
HostGrid
>
multiEntity_
;
};
#if DUNE_HAVE_CXX_VARIANT
/// Construct an iterator from a vector of GridViews, where each GridView can be
/// either a leaf- or a level-gridView, thus we need to use a variant.
template
<
class
...
GV
>
MultiMeshIterator
(
const
std
::
vector
<
std
::
variant
<
GV
...
>>&
gridViews
)
:
incrementAllowed_
(
gridViews
.
size
(),
true
)
,
multiEntity_
(
gridViews
.
size
())
{
contains_
.
reserve
(
gridViews
.
size
());
entityStacks_
.
reserve
(
gridViews
.
size
());
maxLevel_
.
reserve
(
gridViews
.
size
());
for
(
auto
const
&
gvs
:
gridViews
)
{
macroIterators_
.
push_back
(
std
::
visit
([](
auto
const
&
gv
)
{
return
gv
.
grid
().
levelGridView
(
0
).
template
begin
<
0
,
pitype
>();
},
gvs
));
macroEndIterators_
.
push_back
(
std
::
visit
([](
auto
const
&
gv
)
{
return
gv
.
grid
().
levelGridView
(
0
).
template
end
<
0
,
pitype
>();
},
gvs
));
contains_
.
emplace_back
(
std
::
visit
([](
auto
const
&
gv
)
{
return
EntityTest
{[
gv
](
const
HostEntity
&
entity
)
{
return
gv
.
contains
(
entity
);
}};
},
gvs
));
maxLevel_
.
push_back
(
std
::
visit
([](
auto
const
&
gv
)
{
return
gv
.
grid
().
maxLevel
();
},
gvs
));
entityStacks_
.
emplace_back
(
std
::
visit
([](
auto
const
&
gv
)
{
return
gv
.
grid
().
maxLevel
();
},
gvs
));
}
// go to first leaf entity on all grids
for
(
std
::
size_t
i
=
0
;
i
<
entityStacks_
.
size
();
++
i
)
initialIncrement
(
i
);
template
<
int
codim
,
PartitionIteratorType
pitype
,
class
HostGrid
>
class
MultiMeshLeafIterator
:
public
DummyIterator
{
using
DummyIterator
::
DummyIterator
;
};
template
<
PartitionIteratorType
pitype
,
class
HostGrid
>
class
MultiMeshLeafIterator
<
0
,
pitype
,
HostGrid
>
:
public
MultiMeshIteratorBase
<
pitype
,
HostGrid
,
MultiMeshLeafIterator
<
0
,
pitype
,
HostGrid
>>
{
using
Self
=
MultiMeshLeafIterator
;
using
Super
=
MultiMeshIteratorBase
<
pitype
,
HostGrid
,
Self
>
;
using
HostEntity
=
typename
HostGrid
::
template
Codim
<
0
>
::
Entity
;
public:
// Leaf iterator
template
<
class
GridImp
>
MultiMeshLeafIterator
(
tag
::
begin_iterator
,
const
GridImp
*
multiMesh
)
:
Super
{
tag
::
begin_iterator
{},
multiMesh
}
,
incrementAllowed_
(
multiMesh
->
size
(),
true
)
,
multiEntity_
(
multiMesh
->
size
())
{
this
->
initialIncrement
();
}
template
<
class
...
GV
>
MultiMeshIterator
(
const
std
::
vector
<
std
::
variant
<
GV
...
>>&
gridViews
,
bool
endDummy
)
// End iterator
template
<
class
GridImp
>
MultiMeshLeafIterator
(
tag
::
end_iterator
,
const
GridImp
*
multiMesh
)
:
Super
{
tag
::
end_iterator
{},
multiMesh
}
{}
void
initialIncrement_impl
()
{
for
(
auto
const
&
gvs
:
gridViews
)
{
macroIterators_
.
push_back
(
std
::
visit
([](
auto
const
&
gv
)
{
return
gv
.
grid
().
levelGridView
(
0
).
template
end
<
0
,
pitype
>();
},
gvs
));
}
for
(
std
::
size_t
i
=
0
;
i
<
this
->
size
();
++
i
)
this
->
initialIncrement
(
i
);
}
#endif
/// prefix increment
void
increment
()
void
increment_impl
()
{
for
(
std
::
size_t
i
=
0
;
i
<
entityStacks_
.
size
();
++
i
)
incrementAllowed_
[
i
]
=
incrementAllowed
(
i
);
for
(
std
::
size_t
i
=
0
;
i
<
this
->
size
();
++
i
)
incrementAllowed_
[
i
]
=
this
->
incrementAllowed
(
i
);
for
(
std
::
size_t
i
=
0
;
i
<
entityStacks_
.
size
();
++
i
)
{
for
(
std
::
size_t
i
=
0
;
i
<
this
->
size
();
++
i
)
{
if
(
incrementAllowed_
[
i
])
increment
(
i
);
this
->
increment
(
i
);
}
}
/// dereferencing
MultiEntity
<
HostGrid
>
const
&
dereference
()
const
const
MultiEntity
<
HostGrid
>&
dereference_impl
()
const
{
// update entries in multiEntity that have changed
for
(
std
::
size_t
i
=
0
;
i
<
entityStacks_
.
size
();
++
i
)
{
for
(
std
::
size_t
i
=
0
;
i
<
this
->
size
();
++
i
)
{
if
(
incrementAllowed_
[
i
])
multiEntity_
[
i
]
=
dereference
(
i
);
multiEntity_
[
i
]
=
this
->
dereference
(
i
);
}
return
multiEntity_
;
}
/// equality
bool
equals
(
const
MultiMeshIterator
&
that
)
const
bool
levelReached_impl
(
std
::
size_t
/*i*/
,
const
HostEntity
&
entity
)
const
{
return
macroIterators_
==
that
.
macroIterators_
;
return
entity
.
isLeaf
()
;
}
protected:
// got to next entity in grid i
void
increment
(
std
::
size_t
i
)
{
auto
&
entityStack
=
entityStacks_
[
i
];
auto
&
macroIt
=
macroIterators_
[
i
];
auto
const
&
macroEnd
=
macroEndIterators_
[
i
];
// 1. go up in tree or to next entity on current level until we can go down again
while
(
!
entityStack
.
empty
())
{
auto
&
top
=
entityStack
.
top
();
++
top
.
it
;
if
(
top
.
it
==
top
.
end
)
{
entityStack
.
pop
();
}
else
{
break
;
}
}
private:
std
::
vector
<
bool
>
incrementAllowed_
;
mutable
MultiEntity
<
HostGrid
>
multiEntity_
;
};
// 2. if entityStack is empty, go to next macroElement
if
(
entityStack
.
empty
())
{
++
macroIt
;
if
(
macroIt
==
macroEnd
)
return
;
}
// 3. go down in tree until leaf entity
auto
child
=
dereference
(
i
);
for
(;
!
(
contains_
[
i
](
child
)
||
child
.
isLeaf
());
child
=
dereference
(
i
))
{
assert
(
child
.
isRegular
()
&&
"No irregular elements allowed in multi-mesh traversal"
);
entityStack
.
emplace
(
child
);
assert
(
entityStack
.
size
()
<=
maxLevel_
[
i
]);
}
template
<
int
codim
,
PartitionIteratorType
pitype
,
class
HostGrid
>
class
MultiMeshMasterLeafIterator
:
public
DummyIterator
{
using
DummyIterator
::
DummyIterator
;
};
template
<
PartitionIteratorType
pitype
,
class
HostGrid
>
class
MultiMeshMasterLeafIterator
<
0
,
pitype
,
HostGrid
>
:
public
MultiMeshIteratorBase
<
pitype
,
HostGrid
,
MultiMeshMasterLeafIterator
<
0
,
pitype
,
HostGrid
>>
{
using
Self
=
MultiMeshMasterLeafIterator
;
using
Super
=
MultiMeshIteratorBase
<
pitype
,
HostGrid
,
Self
>
;
using
HostEntity
=
typename
HostGrid
::
template
Codim
<
0
>
::
Entity
;
// assert(contains_[i](child) && "No valid child element found in gridView");
public:
// Leaf iterator
template
<
class
GridImp
>
MultiMeshMasterLeafIterator
(
tag
::
begin_iterator
,
const
GridImp
*
multiMesh
,
std
::
size_t
master
)
:
Super
{
tag
::
begin_iterator
{},
multiMesh
}
,
incrementAllowed_
(
multiMesh
->
size
(),
true
)
,
level_
(
multiMesh
->
size
())
,
multiEntity_
(
multiMesh
->
size
())
,
master_
(
master
)
{
this
->
initialIncrement
();
}
/// Return true, if all stacks with size > stack[i].size are finished
bool
incrementAllowed
(
std
::
size_t
i
)
const
// End iterator
template
<
class
GridImp
>
MultiMeshMasterLeafIterator
(
tag
::
end_iterator
,
const
GridImp
*
multiMesh
)
:
Super
{
tag
::
end_iterator
{},
multiMesh
}
{}
// first increment the master grid then the others
void
initialIncrement_impl
()
{
std
::
size_t
size
=
entityStacks_
[
i
].
size
();
return
std
::
accumulate
(
entityStacks_
.
begin
(),
entityStacks_
.
end
(),
true
,
[
i
,
size
](
bool
allowed
,
auto
const
&
entityStack
)
{
return
allowed
&&
(
entityStack
.
size
()
<=
size
||
entityStack
.
finished
(
size
));
});
level_
[
master_
]
=
this
->
initialIncrement
(
master_
);
for
(
std
::
size_t
i
=
0
;
i
<
this
->
size
();
++
i
)
if
(
i
!=
master_
)
level_
[
i
]
=
this
->
initialIncrement
(
i
);
}
//
got to first leaf entity on grid i
void
in
itialIncrement
(
std
::
size_t
i
)
//
first increment the master grid then the others
void
in
crement_impl
(
)
{
auto
&
entityStack
=
entityStacks_
[
i
];
auto
&
macroIt
=
macroIterators_
[
i
];
auto
const
&
macroEnd
=
macroEndIterators_
[
i
];
assert
(
entityStack
.
empty
());
if
(
macroIt
==
macroEnd
)
return
;
// 1. go down in tree until leaf entity
auto
child
=
dereference
(
i
);
for
(;
!
(
contains_
[
i
](
child
)
||
child
.
isLeaf
());
child
=
dereference
(
i
))
{
assert
(
child
.
isRegular
()
&&
"No irregular elements allowed in multi-mesh traversal"
);
entityStack
.
emplace
(
child
);
assert
(
entityStack
.
size
()
<=
maxLevel_
[
i
]);
for
(
std
::
size_t
i
=
0
;
i
<
this
->
size
();
++
i
)
incrementAllowed_
[
i
]
=
this
->
incrementAllowed
(
i
);
if
(
incrementAllowed_
[
master_
])
level_
[
master_
]
=
this
->
increment
(
master_
);
for
(
std
::
size_t
i
=
0
;
i
<
this
->
size
();
++
i
)
{
if
(
i
!=
master_
&&
incrementAllowed_
[
i
])
level_
[
i
]
=
this
->
increment
(
i
);
}
// assert(contains_[i](child) && "No valid child element found in gridView");
}
HostEntity
dereference
(
std
::
size_t
i
)
const
const
MultiEntity
<
HostGrid
>&
dereference_impl
(
)
const
{
if
(
entityStacks_
[
i
].
empty
())
{
assert
(
macroIterators_
[
i
]
!=
macroEndIterators_
[
i
]);
return
*
macroIterators_
[
i
];
}
else
{
assert
(
entityStacks_
[
i
].
top
().
it
!=
entityStacks_
[
i
].
top
().
end
);
return
*
entityStacks_
[
i
].
top
().
it
;
// update entries in multiEntity that have changed
for
(
std
::
size_t
i
=
0
;
i
<
this
->
size
();
++
i
)
{
if
(
incrementAllowed_
[
i
])
multiEntity_
[
i
]
=
this
->
dereference
(
i
);
}
return
multiEntity_
;
}
// got down to leaf entity on master grid and until the master grid level for the other grids
bool
levelReached_impl
(
std
::
size_t
i
,
const
HostEntity
&
entity
)
const
{
return
(
i
==
master_
&&
entity
.
isLeaf
())
||
entity
.
level
()
==
level_
[
master_
];
}
private:
std
::
vector
<
bool
>
incrementAllowed_
;
std
::
vector
<
EntityTest
>
contains_
;
std
::
vector
<
int
>
maxLevel_
;
std
::
vector
<
int
>
level_
;
mutable
MultiEntity
<
HostGrid
>
multiEntity_
;
std
::
vector
<
HostGridLevelIterator
>
macroIterators_
;
std
::
vector
<
HostGridLevelIterator
>
macroEndIterators_
;
std
::
vector
<
EntityStack
>
entityStacks_
;
std
::
size_t
master_
;
};
template
<
class
...
GridViews
>
inline
auto
multi_elements
(
GridViews
const
&
...
gridViews
)
template
<
PartitionIteratorType
pitype
=
All_Partition
,
class
Grid
>
inline
auto
master_leaf_elements
(
Grid
const
&
multiMesh
,
std
::
size_t
master
)
{
using
GridView0
=
std
::
tuple_element_t
<
0
,
std
::
tuple
<
GridViews
...
>>
;
using
Iterator
=
MultiMeshIterator
<
0
,
All_Partition
,
typename
GridView0
::
Grid
>
;
using
Iterator
=
MultiMeshMasterLeafIterator
<
0
,
pitype
,
Grid
>
;
using
Range
=
IteratorRange
<
Iterator
>
;
return
Range
{
Iterator
{
gridViews
...
},
Iterator
{
t
rue
,
gridViews
...
}
};
return
Range
{
Iterator
{
tag
::
begin_iterator
{},
&
multiMesh
,
master
},
Iterator
{
t
ag
::
end_iterator
{},
&
multiMesh
}
};
}
}
// end namespace Dune
...
...
dune/multimesh/mmiteratorbase.hh
0 → 100644
View file @
848b8812
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_MULTIMESH_ITERATOR_BASE_HH
#define DUNE_MULTIMESH_ITERATOR_BASE_HH
#include <numeric>
#include <stack>
#include <type_traits>
#include <dune/common/std/type_traits.hh>
#include <dune/grid/common/gridenums.hh>
#include "mmentity.hh"
#include "mmhierarchiciterator.hh"
#include "mmiteratorinterface.hh"
namespace
Dune
{
template
<
PartitionIteratorType
pitype
,
class
HostGrid
,
class
Derived
>
class
MultiMeshIteratorBase
:
public
MultiMeshIteratorInterface
<
HostGrid
,
Derived
>
{
using
Super
=
MultiMeshIteratorInterface
<
HostGrid
,
Derived
>
;
protected:
// LevelIterator to the equivalent entity in the host grid
using
HostGridLevelIterator
=
typename
HostGrid
::
template
Codim
<
0
>
::
template
Partition
<
pitype
>
::
LevelIterator
;
template
<
class
GV
>
using
IsGridView
=
Std
::
disjunction
<
std
::
is_same
<
std
::
decay_t
<
GV
>
,
typename
HostGrid
::
LeafGridView
>
,
std
::
is_same
<
std
::
decay_t
<
GV
>
,
typename
HostGrid
::
LevelGridView
>
>
;
using
HostEntity
=
typename
HostGrid
::
template
Codim
<
0
>
::
Entity
;
using
EntityTest
=
typename
MultiMeshHierarchicIterator
<
HostGrid
>::
EntityTest
;
using
EntityStack
=
typename
MultiMeshHierarchicIterator
<
HostGrid
>::
EntityStack
;
public:
/// Constructor which creates the begin iterator
/**
* \param multiMesh Pointer to grid instance
*/
template
<
class
GridImp
>
MultiMeshIteratorBase
(
tag
::
begin_iterator
,
const
GridImp
*
multiMesh
)
:
maxLevel_
(
multiMesh
->
size
())
{
for
(
std
::
size_t
i
=
0
;
i
<
multiMesh
->
size
();
++
i
)
{
macroIterators_
.
push_back
(
multiMesh
->
levelGridView
(
i
,
0
).
template
begin
<
0
,
pitype
>());
macroEndIterators_
.
push_back
(
multiMesh
->
levelGridView
(
i
,
0
).
template
end
<
0
,
pitype
>());
}
// go to first leaf entity on all grids
entityStacks_
.
reserve
(
multiMesh
->
size
());
for
(
std
::
size_t
i
=
0
;
i
<
multiMesh
->
size
();
++
i
)
{
maxLevel_
[
i
]
=
(
*
multiMesh
)[
i
].
maxLevel
();
entityStacks_
.
emplace_back
((
*
multiMesh
)[
i
].
maxLevel
());
}
}
/// Constructor which creates the end iterator
/**
* \param multiMesh Pointer to grid instance
*/
template
<
class
GridImp
>
MultiMeshIteratorBase
(
tag
::
end_iterator
,
const
GridImp
*
multiMesh
)
{
for
(
std
::
size_t
i
=
0
;
i
<
multiMesh
->
size
();
++
i
)
macroIterators_
.
push_back
(
multiMesh
->
levelGridView
(
i
,
0
).
template
end
<
0
,
pitype
>());
}
/// Construct an iterator from n gridViews of possibly different type
template
<
class
...
GridViews
,
std
::
enable_if_t
<
Std
::
conjunction
<
IsGridView
<
GridViews
>...
>::
value
,
int
>
=
0
>
MultiMeshIteratorBase
(
tag
::
begin_iterator
,
GridViews
const
&
...
gridViews
)
:
maxLevel_
{
gridViews
.
grid
().
maxLevel
()...}
,
macroIterators_
{
gridViews
.
grid
().
levelGridView
(
0
).
template
begin
<
0
,
pitype
>()...}
,
macroEndIterators_
{
gridViews
.
grid
().
levelGridView
(
0
).
template
end
<
0
,
pitype
>()...}
,
entityStacks_
{
EntityStack
{
gridViews
.
grid
().
maxLevel
()}...}
{}
template
<
class
...
GridViews
,
std
::
enable_if_t
<
Std
::
conjunction
<
IsGridView
<
GridViews
>...
>::
value
,
int
>
=
0
>
MultiMeshIteratorBase
(
tag
::
end_iterator
,
GridViews
const
&
...
gridViews
)
:
macroIterators_
{
gridViews
.
grid
().
levelGridView
(
0
).
template
end
<
0
,
pitype
>()...}
{}
#if DUNE_HAVE_CXX_VARIANT
/// Construct an iterator from a vector of GridViews, where each GridView can be
/// either a leaf- or a level-gridView, thus we need to use a variant.
template
<
class
...
GV
>
MultiMeshIteratorBase
(
tag
::
begin_iterator
,
const
std
::
vector
<
std
::
variant
<
GV
...
>>&
gridViews
)
{
entityStacks_
.
reserve
(
gridViews
.
size
());
maxLevel_
.
reserve
(
gridViews
.
size
());
for
(
auto
const
&
gvs
:
gridViews
)
{
macroIterators_
.
push_back
(
std
::
visit
([](
auto
const
&
gv
)
{
return
gv
.
grid
().
levelGridView
(
0
).
template
begin
<
0
,
pitype
>();
},
gvs
));
macroEndIterators_
.
push_back
(
std
::
visit
([](
auto
const
&
gv
)
{
return
gv
.
grid
().
levelGridView
(
0
).
template
end
<
0
,
pitype
>();
},
gvs
));
maxLevel_
.
push_back
(
std
::
visit
([](
auto
const
&
gv
)
{
return
gv
.
grid
().
maxLevel
();
},
gvs
));
entityStacks_
.
emplace_back
(
std
::
visit
([](
auto
const
&
gv
)
{
return
gv
.
grid
().
maxLevel
();
},
gvs
));
}
}
template
<
class
...
GV
>