Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
D
dune-multimesh
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Praetorius, Simon
dune-multimesh
Commits
c1c4ad7c
Commit
c1c4ad7c
authored
Nov 22, 2018
by
Praetorius, Simon
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feature/master_grid' into 'master'
Feature/master grid See merge request
!4
parents
b54b6417
56785e12
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
646 additions
and
255 deletions
+646
-255
dune/multimesh/mmgridfactory.hh
dune/multimesh/mmgridfactory.hh
+8
-9
dune/multimesh/mmgridview.hh
dune/multimesh/mmgridview.hh
+3
-3
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
+24
-26
dune/multimesh/utility/multibasis.hh
dune/multimesh/utility/multibasis.hh
+2
-2
test/testgridviews.cc
test/testgridviews.cc
+1
-0
No files found.
dune/multimesh/mmgridfactory.hh
View file @
c1c4ad7c
...
...
@@ -51,9 +51,8 @@ namespace Dune
template
<
class
...
Args
>
explicit
GridFactory
(
std
::
size_t
n
,
Args
&&
...
args
)
{
gridFactories_
.
reserve
(
n
);
for
(
std
::
size_t
i
=
0
;
i
<
n
;
++
i
)
gridFactories_
.
emplace_back
(
std
::
forward
<
Args
>
(
args
)...
);
gridFactories_
.
emplace_back
(
new
GridFactory
<
HostGrid
>
{
args
...}
);
}
// initialize at least 1 grid
...
...
@@ -68,7 +67,7 @@ namespace Dune
virtual
void
insertVertex
(
const
GlobalCoordinate
&
pos
)
override
{
for
(
auto
&
gridFactory
:
gridFactories_
)
gridFactory
.
insertVertex
(
pos
);
gridFactory
->
insertVertex
(
pos
);
}
/// \brief Insert an element into the coarse grid
...
...
@@ -80,7 +79,7 @@ namespace Dune
const
std
::
vector
<
unsigned
int
>&
vertices
)
override
{
for
(
auto
&
gridFactory
:
gridFactories_
)
gridFactory
.
insertElement
(
type
,
vertices
);
gridFactory
->
insertElement
(
type
,
vertices
);
}
...
...
@@ -104,7 +103,7 @@ namespace Dune
Hybrid
::
ifElse
(
Std
::
is_detected
<
HasInsertElement
,
GridFactory
<
HostGrid
>>
{},
[
&
](
auto
id
)
{
for
(
auto
&
gridFactory
:
gridFactories_
)
id
(
gridFactory
)
.
insertElement
(
type
,
vertices
,
param
);
id
(
gridFactory
)
->
insertElement
(
type
,
vertices
,
param
);
});
}
...
...
@@ -117,7 +116,7 @@ namespace Dune
const
std
::
vector
<
unsigned
int
>&
vertices
)
override
{
for
(
auto
&
gridFactory
:
gridFactories_
)
gridFactory
.
insertBoundarySegment
(
vertices
);
gridFactory
->
insertBoundarySegment
(
vertices
);
}
...
...
@@ -138,7 +137,7 @@ namespace Dune
Hybrid
::
ifElse
(
Std
::
is_detected
<
HasInsertBoundarySegment
,
GridFactory
<
HostGrid
>>
{},
[
&
](
auto
id
)
{
for
(
auto
&
gridFactory
:
gridFactories_
)
id
(
gridFactory
)
.
insertBoundarySegment
(
vertices
,
boundarySegment
);
id
(
gridFactory
)
->
insertBoundarySegment
(
vertices
,
boundarySegment
);
});
}
...
...
@@ -152,12 +151,12 @@ namespace Dune
{
Grid
*
multimesh
=
new
Grid
{};
for
(
auto
&
gridFactory
:
gridFactories_
)
multimesh
->
grids_
.
emplace_back
(
gridFactory
.
createGrid
());
multimesh
->
grids_
.
emplace_back
(
gridFactory
->
createGrid
());
return
multimesh
;
}
private:
std
::
vector
<
GridFactory
<
HostGrid
>
>
gridFactories_
;
std
::
vector
<
std
::
unique_ptr
<
GridFactory
<
HostGrid
>>
>
gridFactories_
;
};
}
// end namespace Dune
...
...
dune/multimesh/mmgridview.hh
View file @
c1c4ad7c
...
...
@@ -223,13 +223,13 @@ 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
;
/// Type of the corresponding GridType hosted by the MultiMesh
using
HostGrid
=
typename
GridImp
::
HostGrid
Type
;
using
HostGrid
=
typename
GridImp
::
HostGrid
;
using
IndexSet
=
typename
Traits
::
IndexSet
;
using
Intersection
=
typename
Traits
::
Intersection
;
...
...
@@ -255,7 +255,7 @@ namespace Dune
const
HostGrid
&
grid
(
std
::
size_t
i
)
const
{
return
multiMesh_
->
grid
(
i
)
;
return
multiMesh_
[
i
]
;
}
/// Obtain the level-indexSet
...
...
dune/multimesh/mmhierarchiciterator.hh
View file @
c1c4ad7c
...
...
@@ -22,8 +22,8 @@ namespace Dune
typename
HostGrid
::
template
Codim
<
0
>
::
Entity
>
{
private:
template
<
int
codim
,
PartitionIteratorType
pitype
,
class
HostGrid_
>
friend
class
MultiMeshIterator
;
template
<
PartitionIteratorType
pitype
,
class
HG
,
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 @
c1c4ad7c
...
...
@@ -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 pointer to the grid
//
Level iterator
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
,
typename
Grid
::
HostGrid
>
;
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 @
c1c4ad7c
// -*- 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
>());