Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
amdis
amdis-core
Commits
a090eb81
Commit
a090eb81
authored
Nov 07, 2020
by
Praetorius, Simon
Browse files
Introduce Traits class for checking whether Tree can be accessed by given TreePath
parent
1aae0253
Changes
7
Hide whitespace changes
Inline
Side-by-side
amdis/ProblemStat.hpp
View file @
a090eb81
...
...
@@ -39,6 +39,7 @@
#include <amdis/GridFunctions.hpp>
#include <amdis/gridfunctions/DiscreteFunction.hpp>
#include <amdis/io/FileWriterBase.hpp>
#include <amdis/typetree/Traits.hpp>
#include <amdis/typetree/TreePath.hpp>
namespace
AMDiS
...
...
@@ -103,8 +104,7 @@ namespace AMDiS
/// \brief Constructor taking a grid and basis.
/// Wraps both in shared pointers.
template
<
class
Grid_
,
class
Basis_
,
class
B_
=
Underlying_t
<
Basis_
>,
template
<
class
Grid_
,
class
Basis_
,
class
B_
=
Underlying_t
<
Basis_
>,
REQUIRES
(
Concepts
::
GlobalBasis
<
B_
>
)
>
ProblemStat
(
std
::
string
const
&
name
,
Grid_
&&
grid
,
Basis_
&&
globalBasis
)
:
ProblemStat
(
name
,
FWD
(
grid
))
...
...
@@ -114,8 +114,7 @@ namespace AMDiS
/// \brief Constructor taking a grid and pre-basis factory to create a global basis
/// on the fly.
template
<
class
Grid_
,
class
PBF_
,
class
GV_
=
typename
Underlying_t
<
Grid_
>
::
LeafGridView
,
template
<
class
Grid_
,
class
PBF_
,
class
GV_
=
typename
Underlying_t
<
Grid_
>
::
LeafGridView
,
REQUIRES
(
Concepts
::
PreBasisFactory
<
PBF_
,
GV_
,
MultiIndex_t
<
PBF_
>>
)
>
ProblemStat
(
std
::
string
const
&
name
,
Grid_
&&
grid
,
PBF_
const
&
preBasisFactory
)
:
ProblemStat
(
name
,
FWD
(
grid
))
...
...
@@ -161,7 +160,13 @@ namespace AMDiS
template
<
class
Operator
,
class
RowTreePath
=
RootTreePath
,
class
ColTreePath
=
RootTreePath
>
void
addMatrixOperator
(
Operator
const
&
op
,
RowTreePath
row
=
{},
ColTreePath
col
=
{})
{
systemMatrix_
->
addOperator
(
tag
::
element_operator
<
Element
>
{},
op
,
row
,
col
);
static
constexpr
bool
isValidTreePath
=
Concepts
::
ValidTreePath
<
typename
GlobalBasis
::
LocalView
::
Tree
,
RowTreePath
>
&&
Concepts
::
ValidTreePath
<
typename
GlobalBasis
::
LocalView
::
Tree
,
ColTreePath
>
;
static_assert
(
isValidTreePath
,
"Invalid row and/or col treepath passed to addMatrixOperator!"
);
if
constexpr
(
isValidTreePath
)
systemMatrix_
->
addOperator
(
tag
::
element_operator
<
Element
>
{},
op
,
row
,
col
);
}
/// Operator evaluated on the boundary of the domain with boundary index `b`
...
...
@@ -187,7 +192,13 @@ namespace AMDiS
void
addMatrixOperator
(
BoundaryType
b
,
Operator
const
&
op
,
RowTreePath
row
=
{},
ColTreePath
col
=
{})
{
using
I
=
typename
GridView
::
Intersection
;
systemMatrix_
->
addOperator
(
tag
::
boundary_operator
<
I
>
{
*
boundaryManager_
,
b
},
op
,
row
,
col
);
static
constexpr
bool
isValidTreePath
=
Concepts
::
ValidTreePath
<
typename
GlobalBasis
::
LocalView
::
Tree
,
RowTreePath
>
&&
Concepts
::
ValidTreePath
<
typename
GlobalBasis
::
LocalView
::
Tree
,
ColTreePath
>
;
static_assert
(
isValidTreePath
,
"Invalid row and/or col treepath passed to addMatrixOperator!"
);
if
constexpr
(
isValidTreePath
)
systemMatrix_
->
addOperator
(
tag
::
boundary_operator
<
I
>
{
*
boundaryManager_
,
b
},
op
,
row
,
col
);
}
/** @} */
...
...
@@ -212,7 +223,12 @@ namespace AMDiS
template
<
class
Operator
,
class
TreePath
=
RootTreePath
>
void
addVectorOperator
(
Operator
const
&
op
,
TreePath
path
=
{})
{
rhs_
->
addOperator
(
tag
::
element_operator
<
Element
>
{},
op
,
path
);
static
constexpr
bool
isValidTreePath
=
Concepts
::
ValidTreePath
<
typename
GlobalBasis
::
LocalView
::
Tree
,
TreePath
>
;
static_assert
(
isValidTreePath
,
"Invalid treepath passed to addVectorOperator!"
);
if
constexpr
(
isValidTreePath
)
rhs_
->
addOperator
(
tag
::
element_operator
<
Element
>
{},
op
,
path
);
}
/// Operator evaluated on the boundary of the domain with boundary index `b`
...
...
@@ -236,7 +252,12 @@ namespace AMDiS
void
addVectorOperator
(
BoundaryType
b
,
Operator
const
&
op
,
TreePath
path
=
{})
{
using
I
=
typename
GridView
::
Intersection
;
rhs_
->
addOperator
(
tag
::
boundary_operator
<
I
>
{
*
boundaryManager_
,
b
},
op
,
path
);
static
constexpr
bool
isValidTreePath
=
Concepts
::
ValidTreePath
<
typename
GlobalBasis
::
LocalView
::
Tree
,
TreePath
>
;
static_assert
(
isValidTreePath
,
"Invalid treepath passed to addVectorOperator!"
);
if
constexpr
(
isValidTreePath
)
rhs_
->
addOperator
(
tag
::
boundary_operator
<
I
>
{
*
boundaryManager_
,
b
},
op
,
path
);
}
/** @} */
...
...
amdis/ProblemStat.inc.hpp
View file @
a090eb81
...
...
@@ -293,20 +293,28 @@ template <class Traits>
void
ProblemStat
<
Traits
>::
addDirichletBC
(
Predicate
const
&
predicate
,
RowTreePath
row
,
ColTreePath
col
,
Values
const
&
values
)
{
static
constexpr
bool
isValidPredicate
=
Concepts
::
Functor
<
Predicate
,
bool
(
WorldVector
)
>
;
static_assert
(
Concepts
::
Functor
<
Predicate
,
bool
(
WorldVector
)
>
,
"Function passed to addDirichletBC for `predicate` does not model the Functor<bool(WorldVector)> concept"
);
auto
localView
=
globalBasis_
->
localView
();
auto
i
=
makeTreePath
(
row
);
auto
j
=
makeTreePath
(
col
);
auto
rowBasis
=
Dune
::
Functions
::
subspaceBasis
(
*
globalBasis_
,
i
);
auto
colBasis
=
Dune
::
Functions
::
subspaceBasis
(
*
globalBasis_
,
j
);
static
constexpr
bool
isValidTreePath
=
Concepts
::
ValidTreePath
<
typename
GlobalBasis
::
LocalView
::
Tree
,
RowTreePath
>
&&
Concepts
::
ValidTreePath
<
typename
GlobalBasis
::
LocalView
::
Tree
,
ColTreePath
>
;
static_assert
(
isValidTreePath
,
"Invalid row and/or col treepath passed to addDirichletBC!"
);
if
constexpr
(
isValidPredicate
&&
isValidTreePath
)
{
auto
localView
=
globalBasis_
->
localView
();
auto
i
=
makeTreePath
(
row
);
auto
j
=
makeTreePath
(
col
);
auto
rowBasis
=
Dune
::
Functions
::
subspaceBasis
(
*
globalBasis_
,
i
);
auto
colBasis
=
Dune
::
Functions
::
subspaceBasis
(
*
globalBasis_
,
j
);
auto
valueGridFct
=
makeGridFunction
(
values
,
this
->
gridView
());
auto
valueGridFct
=
makeGridFunction
(
values
,
this
->
gridView
());
auto
bc
=
makeDirichletBC
<
SystemMatrix
,
SolutionVector
,
SystemVector
>
(
std
::
move
(
rowBasis
),
std
::
move
(
colBasis
),
{
predicate
},
valueGridFct
);
boundaryConditions_
[
i
][
j
].
push_back
(
makeUniquePtr
(
std
::
move
(
bc
)));
auto
bc
=
makeDirichletBC
<
SystemMatrix
,
SolutionVector
,
SystemVector
>
(
std
::
move
(
rowBasis
),
std
::
move
(
colBasis
),
{
predicate
},
valueGridFct
);
boundaryConditions_
[
i
][
j
].
push_back
(
makeUniquePtr
(
std
::
move
(
bc
)));
}
}
...
...
@@ -316,17 +324,24 @@ template <class Traits>
void
ProblemStat
<
Traits
>::
addDirichletBC
(
BoundaryType
id
,
RowTreePath
row
,
ColTreePath
col
,
Values
const
&
values
)
{
auto
localView
=
globalBasis_
->
localView
();
auto
i
=
makeTreePath
(
row
);
auto
j
=
makeTreePath
(
col
);
auto
rowBasis
=
Dune
::
Functions
::
subspaceBasis
(
*
globalBasis_
,
i
);
auto
colBasis
=
Dune
::
Functions
::
subspaceBasis
(
*
globalBasis_
,
j
);
auto
valueGridFct
=
makeGridFunction
(
values
,
this
->
gridView
());
auto
bc
=
makeDirichletBC
<
SystemMatrix
,
SolutionVector
,
SystemVector
>
(
std
::
move
(
rowBasis
),
std
::
move
(
colBasis
),
{
*
boundaryManager_
,
id
},
valueGridFct
);
boundaryConditions_
[
i
][
j
].
push_back
(
makeUniquePtr
(
std
::
move
(
bc
)));
static
constexpr
bool
isValidTreePath
=
Concepts
::
ValidTreePath
<
typename
GlobalBasis
::
LocalView
::
Tree
,
RowTreePath
>
&&
Concepts
::
ValidTreePath
<
typename
GlobalBasis
::
LocalView
::
Tree
,
ColTreePath
>
;
static_assert
(
isValidTreePath
,
"Invalid row and/or col treepath passed to addDirichletBC!"
);
if
constexpr
(
isValidTreePath
)
{
auto
localView
=
globalBasis_
->
localView
();
auto
i
=
makeTreePath
(
row
);
auto
j
=
makeTreePath
(
col
);
auto
rowBasis
=
Dune
::
Functions
::
subspaceBasis
(
*
globalBasis_
,
i
);
auto
colBasis
=
Dune
::
Functions
::
subspaceBasis
(
*
globalBasis_
,
j
);
auto
valueGridFct
=
makeGridFunction
(
values
,
this
->
gridView
());
auto
bc
=
makeDirichletBC
<
SystemMatrix
,
SolutionVector
,
SystemVector
>
(
std
::
move
(
rowBasis
),
std
::
move
(
colBasis
),
{
*
boundaryManager_
,
id
},
valueGridFct
);
boundaryConditions_
[
i
][
j
].
push_back
(
makeUniquePtr
(
std
::
move
(
bc
)));
}
}
...
...
amdis/typetree/CMakeLists.txt
View file @
a090eb81
...
...
@@ -3,6 +3,7 @@ install(FILES
FiniteElementType.hpp
MultiIndex.hpp
RangeType.hpp
Traits.hpp
Traversal.hpp
TreeContainer.hpp
TreePath.hpp
...
...
amdis/typetree/Traits.hpp
0 → 100644
View file @
a090eb81
#pragma once
#include <type_traits>
#include <dune/typetree/treepath.hh>
#include <amdis/typetree/TreePath.hpp>
namespace
AMDiS
{
namespace
Traits
{
template
<
class
Tree
,
class
TreePath
,
class
NodeTag
=
typename
Tree
::
NodeTag
>
struct
IsValidTreePath
;
// empty treepath
template
<
class
Tree
,
class
NodeTag
>
struct
IsValidTreePath
<
Tree
,
Dune
::
TypeTree
::
HybridTreePath
<>
,
NodeTag
>
:
std
::
true_type
{};
// leaf nodes
template
<
class
Tree
,
class
I0
,
class
...
II
>
struct
IsValidTreePath
<
Tree
,
Dune
::
TypeTree
::
HybridTreePath
<
I0
,
II
...
>
,
Dune
::
TypeTree
::
LeafNodeTag
>
:
std
::
false_type
{};
// power nodes
template
<
class
Tree
,
class
I0
,
class
...
II
>
struct
IsValidTreePath
<
Tree
,
Dune
::
TypeTree
::
HybridTreePath
<
I0
,
II
...
>
,
Dune
::
TypeTree
::
PowerNodeTag
>
:
IsValidTreePath
<
typename
Tree
::
ChildType
,
Dune
::
TypeTree
::
HybridTreePath
<
II
...
>>
{};
// composite node with integer index
template
<
class
Tree
,
class
I0
,
class
...
II
>
struct
IsValidTreePath
<
Tree
,
Dune
::
TypeTree
::
HybridTreePath
<
I0
,
II
...
>
,
Dune
::
TypeTree
::
CompositeNodeTag
>
:
std
::
false_type
{};
// composite node with integral-constant index
template
<
class
Tree
,
class
Int
,
Int
i
,
class
...
II
>
struct
IsValidTreePath
<
Tree
,
Dune
::
TypeTree
::
HybridTreePath
<
std
::
integral_constant
<
Int
,
i
>
,
II
...
>
,
Dune
::
TypeTree
::
CompositeNodeTag
>
:
std
::
conditional_t
<
(
i
>=
0
&&
i
<
Tree
::
degree
()),
IsValidTreePath
<
typename
Tree
::
template
Child
<
(
i
>
=
0
&&
i
<
Tree
::
degree
())
?
i
:
0
>::
Type
,
Dune
::
TypeTree
::
HybridTreePath
<
II
...
>>
,
std
::
false_type
>
{};
}
// end namespace Traits
namespace
Concepts
{
/// \brief Check whether `Path` is a valid index of treepath for the given typetree `Tree`
template
<
class
Tree
,
class
Path
>
static
constexpr
bool
ValidTreePath
=
Traits
::
IsValidTreePath
<
Tree
,
TYPEOF
(
makeTreePath
(
std
::
declval
<
Path
>
()))
>::
value
;
}
}
// end namespace AMDiS
amdis/typetree/TreePath.hpp
View file @
a090eb81
...
...
@@ -13,7 +13,7 @@
namespace
AMDiS
{
struct
RootTreePath
{}
;
using
RootTreePath
=
Dune
::
TypeTree
::
HybridTreePath
<>
;
namespace
Concepts
{
...
...
@@ -43,11 +43,6 @@ namespace AMDiS
:
std
::
conjunction
<
std
::
is_integral
<
Indices
>
...
>
{};
template
<
>
struct
IsPreTreePath
<
RootTreePath
>
:
std
::
true_type
{};
}
// end namespace Definition
template
<
class
TP
>
...
...
@@ -119,11 +114,6 @@ namespace AMDiS
return
Dune
::
TypeTree
::
hybridTreePath
();
}
inline
auto
makeTreePath
(
RootTreePath
)
{
return
makeTreePath
();
}
template
<
class
Index
,
Index
...
I
>
auto
makeTreePath
(
std
::
integer_sequence
<
Index
,
I
...
>
)
{
...
...
test/CMakeLists.txt
View file @
a090eb81
...
...
@@ -160,3 +160,6 @@ dune_add_test(SOURCES UniqueBorderPartitionTest.cpp
MPI_RANKS 2
TIMEOUT 300
CMAKE_GUARD MPI_FOUND
)
dune_add_test
(
SOURCES ValidTreePathTest.cpp
LINK_LIBRARIES amdis
)
test/ValidTreePathTest.cpp
0 → 100644
View file @
a090eb81
#include <config.h>
#include <dune/grid/yaspgrid.hh>
#include <dune/functions/functionspacebases/compositebasis.hh>
#include <dune/functions/functionspacebases/lagrangebasis.hh>
#include <dune/functions/functionspacebases/powerbasis.hh>
#include <amdis/Environment.hpp>
#include <amdis/common/TypeTraits.hpp>
#include <amdis/typetree/Traits.hpp>
#include <amdis/typetree/TreePath.hpp>
using
namespace
AMDiS
;
int
main
(
int
argc
,
char
**
argv
)
{
Environment
env
(
argc
,
argv
);
Dune
::
YaspGrid
<
2
>
grid
({
1.0
,
1.0
},
{
1
,
1
});
using
namespace
Dune
::
Functions
::
BasisFactory
;
auto
basis
=
makeBasis
(
grid
.
leafGridView
(),
composite
(
power
<
2
>
(
lagrange
<
2
>
()),
lagrange
<
1
>
()
));
using
Tree
=
TYPEOF
(
basis
.
localView
().
tree
());
// index access of composite node
static_assert
(
not
Concepts
::
ValidTreePath
<
Tree
,
int
>
);
static_assert
(
not
Concepts
::
ValidTreePath
<
Tree
,
std
::
size_t
>
);
static_assert
(
Concepts
::
ValidTreePath
<
Tree
,
std
::
integral_constant
<
int
,
0
>>
);
static_assert
(
Concepts
::
ValidTreePath
<
Tree
,
std
::
integral_constant
<
std
::
size_t
,
0
>>
);
static_assert
(
not
Concepts
::
ValidTreePath
<
Tree
,
std
::
integral_constant
<
int
,
2
>>
);
static_assert
(
not
Concepts
::
ValidTreePath
<
Tree
,
std
::
integral_constant
<
std
::
size_t
,
2
>>
);
using
namespace
Dune
::
Indices
;
auto
tp0
=
makeTreePath
(
0
);
auto
tp1
=
makeTreePath
(
_0
);
static_assert
(
not
Concepts
::
ValidTreePath
<
Tree
,
TYPEOF
(
tp0
)
>
);
static_assert
(
Concepts
::
ValidTreePath
<
Tree
,
TYPEOF
(
tp1
)
>
);
auto
tp2
=
makeTreePath
(
_0
,
0
);
auto
tp3
=
makeTreePath
(
_0
,
_0
);
auto
tp4
=
makeTreePath
(
_1
,
0
);
static_assert
(
Concepts
::
ValidTreePath
<
Tree
,
TYPEOF
(
tp2
)
>
);
static_assert
(
Concepts
::
ValidTreePath
<
Tree
,
TYPEOF
(
tp3
)
>
);
static_assert
(
not
Concepts
::
ValidTreePath
<
Tree
,
TYPEOF
(
tp4
)
>
);
auto
tp5
=
makeTreePath
(
_0
,
0
,
0
);
auto
tp6
=
makeTreePath
(
_0
,
0
,
_0
);
static_assert
(
not
Concepts
::
ValidTreePath
<
Tree
,
TYPEOF
(
tp5
)
>
);
static_assert
(
not
Concepts
::
ValidTreePath
<
Tree
,
TYPEOF
(
tp6
)
>
);
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment