Skip to content
GitLab
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
d773c643
Commit
d773c643
authored
Dec 19, 2020
by
Praetorius, Simon
Browse files
Move all recursive algorithms to algorithm subdirectory
parent
1a410159
Changes
20
Hide whitespace changes
Inline
Side-by-side
amdis/algorithm/Apply.hpp
0 → 100644
View file @
d773c643
#pragma once
#include
<array>
#include
<tuple>
#include
<vector>
#include
<dune/common/tuplevector.hh>
#include
<amdis/common/Apply.hpp>
namespace
AMDiS
{
namespace
Recursive
{
template
<
class
T
>
struct
Apply
;
/// \brief Recursive application of a transformation functor `f` to a hierarchic
/// container of containers, returning the transformed container.
/**
* This utility function applies the given functor `f` to the "leaf" entries in
* a hierarchic container that returns a transformed container. Therefore, the
* container is traversed recursively, using specializations of the `Apply<Container>::impl`
* class method. If no specialization is provided, the function is applied to the
* whole container or leaf entry, respectively.
**/
template
<
class
F
,
class
T
>
auto
apply
(
F
&&
f
,
T
const
&
t
)
{
return
Apply
<
T
>::
impl
(
f
,
t
);
}
// specializations for container types
/// Default implementation of the recursive \ref map function.
template
<
class
T
>
struct
Apply
{
template
<
class
F
>
static
auto
impl
(
F
&&
f
,
T
const
&
t
)
{
return
f
(
t
);
}
};
template
<
class
T
,
std
::
size_t
n
>
struct
Apply
<
std
::
array
<
T
,
n
>>
{
template
<
class
F
>
static
auto
impl
(
F
&&
f
,
std
::
array
<
T
,
n
>
const
&
a
)
{
return
Ranges
::
applyIndices
<
n
>
([
&
](
auto
...
ii
)
{
return
std
::
array
{
Recursive
::
apply
(
f
,
a
[
ii
])...};
});
}
};
template
<
class
...
TT
>
struct
Apply
<
std
::
tuple
<
TT
...
>>
{
template
<
class
F
>
static
auto
impl
(
F
&&
f
,
std
::
tuple
<
TT
...
>
const
&
t
)
{
return
Ranges
::
apply
([
&
](
auto
const
&
...
ti
)
{
return
std
::
tuple
{
Recursive
::
apply
(
f
,
ti
)...};
},
t
);
}
};
template
<
class
T1
,
class
T2
>
struct
Apply
<
std
::
pair
<
T1
,
T2
>>
{
template
<
class
F
>
static
auto
impl
(
F
&&
f
,
std
::
pair
<
T1
,
T2
>
const
&
t
)
{
return
std
::
pair
{
Recursive
::
apply
(
f
,
t
.
first
),
Recursive
::
apply
(
f
,
t
.
second
)};
}
};
template
<
class
...
TT
>
struct
Apply
<
Dune
::
TupleVector
<
TT
...
>>
{
template
<
class
F
>
static
auto
impl
(
F
&&
f
,
Dune
::
TupleVector
<
TT
...
>
const
&
t
)
{
return
Ranges
::
apply
([
&
](
auto
const
&
...
ti
)
{
return
Dune
::
makeTupleVector
(
Recursive
::
apply
(
f
,
ti
)...);
},
t
);
}
};
template
<
class
T
>
struct
Apply
<
std
::
vector
<
T
>>
{
template
<
class
F
>
static
auto
impl
(
F
&&
f
,
std
::
vector
<
T
>
const
&
v
)
{
using
U
=
TYPEOF
(
Recursive
::
apply
(
f
,
std
::
declval
<
T
>
()));
std
::
vector
<
U
>
out
;
out
.
reserve
(
v
.
size
());
for
(
std
::
size_t
i
=
0
;
i
<
v
.
size
();
++
i
)
out
.
emplace_back
(
Recursive
::
apply
(
f
,
v
[
i
]));
return
out
;
}
};
}}
// end namespace AMDiS::Recursive
\ No newline at end of file
amdis/algorithm/CMakeLists.txt
0 → 100644
View file @
d773c643
install
(
FILES
Apply.hpp
ForEach.hpp
InnerProduct.hpp
Transform.hpp
DESTINATION
${
CMAKE_INSTALL_INCLUDEDIR
}
/amdis/algorithm
)
amdis/algorithm/ForEach.hpp
0 → 100644
View file @
d773c643
#pragma once
#include
<array>
#include
<tuple>
#include
<vector>
#include
<type_traits>
#include
<utility>
#include
<dune/common/tuplevector.hh>
#include
<amdis/common/ForEach.hpp>
#include
<amdis/common/TypeTraits.hpp>
namespace
AMDiS
{
namespace
Recursive
{
template
<
class
Vec
>
struct
ForEach
;
/// \brief Recursive application of a functor `f` to a hierarchic container of containers.
/**
* This utility function applies the given functor `f` to the "leaf" entries in
* a hierarchic container. Therefore, the container is traversed recursively,
* using specializations of the `ForEach<Container>::apply` class method.
* If no specialization is provided, the function is applied to the whole container
* or leaf entry, respectively.
**/
template
<
class
Container
,
class
F
>
void
forEach
(
Container
&&
container
,
F
&&
f
)
{
ForEach
<
TYPEOF
(
container
)
>::
impl
(
container
,
f
);
}
// specializations for container types
template
<
class
>
struct
ForEach
{
private:
// ranges with dynamic index access
template
<
class
Vec
,
class
F
,
class
=
decltype
(
std
::
begin
(
std
::
declval
<
Vec
>())),
class
=
decltype
(
std
::
end
(
std
::
declval
<
Vec
>
()))
>
static
void
impl2
(
Dune
::
PriorityTag
<
2
>
,
Vec
&&
vec
,
F
&&
f
)
{
for
(
auto
&&
v
:
vec
)
Recursive
::
forEach
(
v
,
f
);
}
// ranges with static index access
template
<
class
Vec
,
class
F
,
class
=
decltype
(
std
::
get
<
0
>(
std
::
declval
<
Vec
>
()))
>
static
void
impl2
(
Dune
::
PriorityTag
<
1
>
,
Vec
&&
vec
,
F
&&
f
)
{
Ranges
::
forEach
(
vec
,
[
&
](
auto
&&
v
)
{
Recursive
::
forEach
(
v
,
f
);
});
}
// no range
template
<
class
Value
,
class
F
>
static
void
impl2
(
Dune
::
PriorityTag
<
0
>
,
Value
&&
value
,
F
&&
f
)
{
f
(
value
);
}
public:
template
<
class
Vec
,
class
F
>
static
void
impl
(
Vec
&&
vec
,
F
&&
f
)
{
impl2
(
Dune
::
PriorityTag
<
5
>
{},
vec
,
f
);
}
};
}}
// end namespace AMDiS::Recursive
amdis/algorithm/InnerProduct.hpp
0 → 100644
View file @
d773c643
#pragma once
#include
<functional>
#include
<type_traits>
#include
<utility>
#include
<vector>
#include
<dune/common/typeutilities.hh>
#include
<amdis/common/ForEach.hpp>
#include
<amdis/common/StaticSize.hpp>
namespace
AMDiS
{
namespace
Recursive
{
template
<
class
>
struct
InnerProduct
;
/// \brief Recursive inner product of two containers [in1] and [in2] following the signature
/// of `std::inner_product` but applied to the leaf elements of the possibly hierarchic containers
template
<
class
In1
,
class
In2
,
class
T
,
class
BinaryOperation1
,
class
BinaryOperation2
>
T
innerProduct
(
In1
const
&
in1
,
In2
const
&
in2
,
T
init
,
BinaryOperation1
op1
,
BinaryOperation2
op2
)
{
return
InnerProduct
<
In1
>::
impl
(
in1
,
in2
,
std
::
move
(
init
),
op1
,
op2
);
}
template
<
class
In1
,
class
In2
,
class
T
>
T
innerProduct
(
In1
const
&
in1
,
In2
const
&
in2
,
T
init
)
{
return
InnerProduct
<
In1
>::
impl
(
in1
,
in2
,
std
::
move
(
init
),
std
::
plus
<>
{},
std
::
multiplies
<>
{});
}
/// General implementation of recursive inner-product
template
<
class
>
struct
InnerProduct
{
private:
// dynamic ranges
template
<
class
In1
,
class
In2
,
class
T
,
class
BinOp1
,
class
BinOp2
,
class
=
decltype
(
std
::
begin
(
std
::
declval
<
In1
>())),
class
=
decltype
(
std
::
end
(
std
::
declval
<
In1
>
())),
class
=
decltype
(
std
::
begin
(
std
::
declval
<
In2
>
()))
>
static
T
impl2
(
Dune
::
PriorityTag
<
2
>
,
In1
const
&
in1
,
In2
const
&
in2
,
T
init
,
BinOp1
op1
,
BinOp2
op2
)
{
auto
first1
=
std
::
begin
(
in1
);
auto
first2
=
std
::
begin
(
in2
);
for
(;
first1
!=
std
::
end
(
in1
);
++
first1
,
++
first2
)
init
=
Recursive
::
innerProduct
(
*
first1
,
*
first2
,
std
::
move
(
init
),
op1
,
op2
);
return
init
;
}
// ranges with static index access
template
<
class
In1
,
class
In2
,
class
T
,
class
BinOp1
,
class
BinOp2
,
class
=
decltype
(
std
::
declval
<
In1
>()[
std
::
integral_constant
<
std
::
size_t
,
0
>
{}])
>
static
T
impl2
(
Dune
::
PriorityTag
<
1
>
,
In1
const
&
in1
,
In2
const
&
in2
,
T
init
,
BinOp1
op1
,
BinOp2
op2
)
{
static_assert
(
static_size_v
<
In1
>
==
static_size_v
<
In2
>
);
Ranges
::
forIndices
<
static_size_v
<
In1
>>
([
&
](
auto
ii
)
{
init
=
Recursive
::
innerProduct
(
in1
[
ii
],
in2
[
ii
],
std
::
move
(
init
),
op1
,
op2
);
});
return
init
;
}
// no range
template
<
class
In1
,
class
In2
,
class
T
,
class
BinOp1
,
class
BinOp2
>
static
T
impl2
(
Dune
::
PriorityTag
<
0
>
,
In1
const
&
in1
,
In2
const
&
in2
,
T
init
,
BinOp1
op1
,
BinOp2
op2
)
{
return
op1
(
std
::
move
(
init
),
op2
(
in1
,
in2
));
}
public:
template
<
class
In1
,
class
In2
,
class
T
,
class
BinOp1
,
class
BinOp2
>
static
T
impl
(
In1
const
&
in1
,
In2
const
&
in2
,
T
init
,
BinOp1
op1
,
BinOp2
op2
)
{
return
impl2
(
Dune
::
PriorityTag
<
5
>
{},
in1
,
in2
,
init
,
op1
,
op2
);
}
};
}}
// end namespace AMDiS::Recursive
amdis/algorithm/Transform.hpp
0 → 100644
View file @
d773c643
#pragma once
#include
<type_traits>
#include
<utility>
#include
<vector>
#include
<dune/common/typeutilities.hh>
#include
<amdis/common/ForEach.hpp>
#include
<amdis/common/StaticSize.hpp>
namespace
AMDiS
{
namespace
Recursive
{
template
<
class
>
struct
Transform
;
/// \brief Recursive application of a functor `op` to a hierarchic container of containers.
/**
* This utility function applies the given functor `op` to the "leaf" entries in
* hierarchic containers {in...} and assigns the output to the hierarchic container [out].
* Therefore, the containers are traversed recursively, using specializations of the
* `Transform<Container>::impl` class method. If no such specialization is provided, the function
* is applied to the whole containers or leaf entries, respectively.
**/
template
<
class
Out
,
class
Op
,
class
...
In
>
void
transform
(
Out
&
out
,
Op
&&
op
,
In
const
&
...
in
)
{
Transform
<
std
::
remove_const_t
<
Out
>>::
impl
(
out
,
op
,
in
...);
}
template
<
class
>
struct
Transform
{
private:
// ranges with dynamic index access
template
<
class
OutIter
,
class
Op
,
class
...
InIter
>
static
void
impl3
(
OutIter
d_first
,
OutIter
d_last
,
Op
&&
op
,
InIter
...
first
)
{
while
(
d_first
!=
d_last
)
Recursive
::
transform
(
*
d_first
++
,
op
,
*
first
++
...);
}
// ranges with dynamic index access
template
<
class
Out
,
class
Op
,
class
...
In
,
class
=
decltype
(
std
::
begin
(
std
::
declval
<
Out
>())),
class
=
decltype
(
std
::
end
(
std
::
declval
<
Out
>
())),
class
=
std
::
void_t
<
decltype
(
std
::
begin
(
std
::
declval
<
In
>
()))...
>>
static
void
impl2
(
Dune
::
PriorityTag
<
3
>
,
Out
&
out
,
Op
&&
op
,
In
const
&
...
in
)
{
impl3
(
std
::
begin
(
out
),
std
::
end
(
out
),
op
,
std
::
begin
(
in
)...);
}
// ranges with static index access
template
<
class
Out
,
class
Op
,
class
...
In
,
class
=
decltype
(
std
::
declval
<
Out
>()[
std
::
integral_constant
<
std
::
size_t
,
0
>
{}])
>
static
void
impl2
(
Dune
::
PriorityTag
<
2
>
,
Out
&
out
,
Op
&&
op
,
In
const
&
...
in
)
{
Ranges
::
forIndices
<
static_size_v
<
Out
>>
([
&
](
auto
ii
)
{
Recursive
::
transform
(
out
[
ii
],
op
,
in
[
ii
]...);
});
}
// ranges with static getter access
template
<
class
Out
,
class
Op
,
class
...
In
,
class
=
decltype
(
std
::
get
<
0
>(
std
::
declval
<
Out
>
()))
>
static
void
impl2
(
Dune
::
PriorityTag
<
1
>
,
Out
&
out
,
Op
&&
op
,
In
const
&
...
in
)
{
Ranges
::
forIndices
<
static_size_v
<
Out
>>
([
&
](
auto
ii
)
{
Recursive
::
transform
(
std
::
get
<
ii
>
(
out
),
op
,
std
::
get
<
ii
>
(
in
)...);
});
}
// no range
template
<
class
Out
,
class
Op
,
class
...
In
>
static
void
impl2
(
Dune
::
PriorityTag
<
0
>
,
Out
&
out
,
Op
&&
op
,
In
const
&
...
in
)
{
out
=
op
(
in
...);
}
public:
template
<
class
Out
,
class
Op
,
class
...
In
>
static
void
impl
(
Out
&
out
,
Op
&&
op
,
In
const
&
...
in
)
{
impl2
(
Dune
::
PriorityTag
<
5
>
{},
out
,
op
,
in
...);
}
};
}}
// end namespace AMDiS::Recursive
amdis/common/CMakeLists.txt
View file @
d773c643
...
...
@@ -25,8 +25,6 @@ install(FILES
Order.hpp
QuadMath.hpp
Range.hpp
RecursiveApply.hpp
RecursiveForEach.hpp
SharedPtr.hpp
StaticSize.hpp
String.hpp
...
...
amdis/common/ForEach.hpp
View file @
d773c643
...
...
@@ -22,7 +22,8 @@ namespace AMDiS
(
f
(
get
<
I
>
(
tuple
)),...);
}
template
<
class
Tuple
,
class
Functor
>
template
<
class
Tuple
,
class
Functor
,
class
=
decltype
(
std
::
get
<
0
>(
std
::
declval
<
Tuple
>
()))
>
constexpr
void
forEach
(
Tuple
&&
tuple
,
Functor
&&
f
)
{
Ranges
::
forEach
(
std
::
make_index_sequence
<
static_size_v
<
Tuple
>>
{},
FWD
(
tuple
),
FWD
(
f
));
...
...
amdis/common/RecursiveApply.hpp
deleted
100644 → 0
View file @
1a410159
#pragma once
#include
<array>
#include
<tuple>
#include
<vector>
#include
<dune/common/tuplevector.hh>
#include
<amdis/common/Apply.hpp>
namespace
AMDiS
{
namespace
Recursive
{
/// Default implementation of the recursive \ref map function.
template
<
class
T
>
struct
Apply
{
template
<
class
F
>
static
auto
impl
(
F
&&
f
,
T
const
&
t
)
{
return
f
(
t
);
}
};
/// \brief Recursive application of a transformation functor `f` to a hierarchic
/// container of containers, returning the transformed container.
/**
* This utility function applies the given functor `f` to the "leaf" entries in
* a hierarchic container that returns a transformed container. Therefore, the
* container is traversed recursively, using specializations of the `Map<Container>::apply`
* class method. If no specialization is provided, the function is applied to the
* whole container or leaf entry, respectively.
**/
template
<
class
F
,
class
T
>
auto
apply
(
F
&&
f
,
T
const
&
t
)
{
return
Apply
<
T
>::
impl
(
f
,
t
);
}
// specializations for container types
template
<
class
T
,
std
::
size_t
n
>
struct
Apply
<
std
::
array
<
T
,
n
>>
{
template
<
class
F
>
static
auto
impl
(
F
&&
f
,
std
::
array
<
T
,
n
>
const
&
a
)
{
return
Ranges
::
applyIndices
<
n
>
([
&
](
auto
...
ii
)
{
return
std
::
array
{
Recursive
::
apply
(
f
,
a
[
ii
])...};
});
}
};
template
<
class
...
TT
>
struct
Apply
<
std
::
tuple
<
TT
...
>>
{
template
<
class
F
>
static
auto
impl
(
F
&&
f
,
std
::
tuple
<
TT
...
>
const
&
t
)
{
return
Ranges
::
apply
([
&
](
auto
const
&
...
ti
)
{
return
std
::
tuple
{
Recursive
::
apply
(
f
,
ti
)...};
},
t
);
}
};
template
<
class
T1
,
class
T2
>
struct
Apply
<
std
::
pair
<
T1
,
T2
>>
{
template
<
class
F
>
static
auto
impl
(
F
&&
f
,
std
::
pair
<
T1
,
T2
>
const
&
t
)
{
return
std
::
pair
{
Recursive
::
apply
(
f
,
t
.
first
),
Recursive
::
apply
(
f
,
t
.
second
)};
}
};
template
<
class
...
TT
>
struct
Apply
<
Dune
::
TupleVector
<
TT
...
>>
{
template
<
class
F
>
static
auto
impl
(
F
&&
f
,
Dune
::
TupleVector
<
TT
...
>
const
&
t
)
{
return
Ranges
::
apply
([
&
](
auto
const
&
...
ti
)
{
return
Dune
::
makeTupleVector
(
Recursive
::
apply
(
f
,
ti
)...);
},
t
);
}
};
template
<
class
T
>
struct
Apply
<
std
::
vector
<
T
>>
{
template
<
class
F
>
static
auto
impl
(
F
&&
f
,
std
::
vector
<
T
>
const
&
v
)
{
using
U
=
TYPEOF
(
Recursive
::
apply
(
f
,
std
::
declval
<
T
>
()));
std
::
vector
<
U
>
out
;
out
.
reserve
(
v
.
size
());
for
(
std
::
size_t
i
=
0
;
i
<
v
.
size
();
++
i
)
out
.
emplace_back
(
Recursive
::
apply
(
f
,
v
[
i
]));
return
out
;
}
};
}
// end namespace Recursive
}
// end namespace AMDiS
\ No newline at end of file
amdis/common/RecursiveForEach.hpp
deleted
100644 → 0
View file @
1a410159
#pragma once
#include
<array>
#include
<tuple>
#include
<vector>
#include
<type_traits>
#include
<utility>
#include
<dune/common/tuplevector.hh>
#include
<amdis/common/TypeTraits.hpp>
namespace
AMDiS
{
namespace
Recursive
{
/// Default implementation of the recursive \ref forEach function.
/**
* \tparam V The type of the container/value decayed to the raw type
**/
template
<
class
V
>
struct
ForEach
{
template
<
class
Value
,
class
F
>
static
void
impl
(
Value
&&
v
,
F
&&
f
)
{
f
(
v
);
}
};
/// \brief Recursive application of a functor `f` to a hierarchic container of containers.
/**
* This utility function applies the given functor `f` to the "leaf" entries in
* a hierarchic container. Therefore, the container is traversed recursively,
* using specializations of the `ForEach<Container>::apply` class method.
* If no specialization is provided, the function is applied to the whole container
* or leaf entry, respectively.
**/
template
<
class
Container
,
class
F
>
void
forEach
(
Container
&&
container
,
F
&&
f
)
{
ForEach
<
TYPEOF
(
container
)
>::
impl
(
container
,
f
);
}
// specializations for container types
template
<
class
...
TT
>
struct
ForEach
<
std
::
tuple
<
TT
...
>>
{
using
indices
=
std
::
make_index_sequence
<
sizeof
...(
TT
)
>
;
template
<
std
::
size_t
...
I
,
class
Tuple
,
class
F
>
static
void
impl2
(
std
::
index_sequence
<
I
...
>
,
Tuple
&&
tuple
,
F
&&
f
)
{
using
std
::
get
;
(
Recursive
::
forEach
(
get
<
I
>
(
tuple
),
f
),...);
}
template
<
class
Tuple
,
class
F
>
static
void
impl
(
Tuple
&&
tuple
,
F
&&
f
)
{
impl2
(
indices
{},
tuple
,
f
);
}
};
template
<
class
T1
,
class
T2
>
struct
ForEach
<
std
::
pair
<
T1
,
T2
>>
{
template
<
class
Pair
,
class
F
>
static
void
impl
(
Pair
&&
pair
,
F
&&
f
)
{
Recursive
::
forEach
(
pair
.
first
,
f
);
Recursive
::
forEach
(
pair
.
second
,
f
);
}
};
template
<
class
...
TT
>
struct
ForEach
<
Dune
::
TupleVector
<
TT
...
>>
{
template
<
class
Tuple
,
class
F
>
static
void
impl
(
Tuple
&&
tuple
,
F
&&
f
)
{
ForEach
<
std
::
tuple
<
TT
...
>>::
impl
(
tuple
,
f
);
}
};
template
<
class
T
,
std
::
size_t
n
>
struct
ForEach
<
std
::
array
<
T
,
n
>>
{
template
<
class
Array
,
class
F
>
static
void
impl
(
Array
&&
a
,
F
&&
f
)
{
for
(
auto
&&
ai
:
a
)
Recursive
::
forEach
(
ai
,
f
);
}
};
template
<
class
T
>
struct
ForEach
<
std
::
vector
<
T
>>
{
template
<
class
Vector
,
class
F
>
static
void
impl
(
Vector
&&
v
,
F
&&
f
)
{
for
(
auto
&&
vi
:
v
)
Recursive
::
forEach
(
vi
,
f
);
}
};
}
// end namespace Recursive
}
// end namespace AMDiS
amdis/gridfunctions/DiscreteFunction.inc.hpp
View file @
d773c643
...
...
@@ -4,6 +4,7 @@
#include
<dune/grid/utility/hierarchicsearch.hh>
#include
<amdis/algorithm/Transform.hpp>
#include
<amdis/functions/Interpolate.hpp>
#include
<amdis/gridfunctions/GridFunction.hpp>
#include
<amdis/linearalgebra/VectorFacade.hpp>
...
...
@@ -44,10 +45,10 @@ void DiscreteFunction<C,GB,TP,R>::