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
d5e52d52
Commit
d5e52d52
authored
Dec 20, 2020
by
Praetorius, Simon
Browse files
Fix some tests using the new algorithms
parent
d773c643
Changes
10
Hide whitespace changes
Inline
Side-by-side
amdis/algorithm/Apply.hpp
deleted
100644 → 0
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
View file @
d5e52d52
install
(
FILES
install
(
FILES
Apply.hpp
ForEach.hpp
ForEach.hpp
InnerProduct.hpp
InnerProduct.hpp
Map.hpp
Transform.hpp
Transform.hpp
DESTINATION
${
CMAKE_INSTALL_INCLUDEDIR
}
/amdis/algorithm
)
DESTINATION
${
CMAKE_INSTALL_INCLUDEDIR
}
/amdis/algorithm
)
amdis/algorithm/ForEach.hpp
View file @
d5e52d52
...
@@ -20,7 +20,7 @@ struct ForEach;
...
@@ -20,7 +20,7 @@ struct ForEach;
/**
/**
* This utility function applies the given functor `f` to the "leaf" entries in
* This utility function applies the given functor `f` to the "leaf" entries in
* a hierarchic container. Therefore, the container is traversed recursively,
* a hierarchic container. Therefore, the container is traversed recursively,
* using specializations of the `ForEach<Container>::
ap
pl
y
` class method.
* using specializations of the `ForEach<Container>::
im
pl` class method.
* If no specialization is provided, the function is applied to the whole container
* If no specialization is provided, the function is applied to the whole container
* or leaf entry, respectively.
* or leaf entry, respectively.
**/
**/
...
...
amdis/algorithm/InnerProduct.hpp
View file @
d5e52d52
...
@@ -15,14 +15,36 @@ namespace Recursive {
...
@@ -15,14 +15,36 @@ namespace Recursive {
template
<
class
>
template
<
class
>
struct
InnerProduct
;
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
* \brief Recursive inner product of two containers [in1] and [in2] following the
template
<
class
In1
,
class
In2
,
class
T
,
class
BinaryOperation1
,
class
BinaryOperation2
>
* signature of `std::inner_product` but applied to the leaf elements of the possibly
T
innerProduct
(
In1
const
&
in1
,
In2
const
&
in2
,
T
init
,
BinaryOperation1
op1
,
BinaryOperation2
op2
)
* hierarchic containers.
*
* This implements the reduction operation of the form
* ```
* T result = init;
* for (i...)
* result = op1(result, op2(in1[i], in2[i]);
* return result;
* ```
**/
template
<
class
In1
,
class
In2
,
class
T
,
class
BinaryOp1
,
class
BinaryOp2
>
T
innerProduct
(
In1
const
&
in1
,
In2
const
&
in2
,
T
init
,
BinaryOp1
op1
,
BinaryOp2
op2
)
{
{
return
InnerProduct
<
In1
>::
impl
(
in1
,
in2
,
std
::
move
(
init
),
op1
,
op2
);
return
InnerProduct
<
In1
>::
impl
(
in1
,
in2
,
std
::
move
(
init
),
op1
,
op2
);
}
}
/// Specialization of \ref innerProduct if no functors are given, use plus and multiplies
/// by default.
/**
* This implements the standard Euclidean inner product
* ```
* result = init + sum_i in1[i] * in2[i]
* ```
*
* Note, no conjugation of the first or second argument is used in this default.
**/
template
<
class
In1
,
class
In2
,
class
T
>
template
<
class
In1
,
class
In2
,
class
T
>
T
innerProduct
(
In1
const
&
in1
,
In2
const
&
in2
,
T
init
)
T
innerProduct
(
In1
const
&
in1
,
In2
const
&
in2
,
T
init
)
{
{
...
@@ -40,7 +62,8 @@ private:
...
@@ -40,7 +62,8 @@ private:
class
=
decltype
(
std
::
begin
(
std
::
declval
<
In1
>())),
class
=
decltype
(
std
::
begin
(
std
::
declval
<
In1
>())),
class
=
decltype
(
std
::
end
(
std
::
declval
<
In1
>
())),
class
=
decltype
(
std
::
end
(
std
::
declval
<
In1
>
())),
class
=
decltype
(
std
::
begin
(
std
::
declval
<
In2
>
()))
>
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
)
static
T
impl2
(
Dune
::
PriorityTag
<
2
>
,
In1
const
&
in1
,
In2
const
&
in2
,
T
init
,
BinOp1
op1
,
BinOp2
op2
)
{
{
auto
first1
=
std
::
begin
(
in1
);
auto
first1
=
std
::
begin
(
in1
);
auto
first2
=
std
::
begin
(
in2
);
auto
first2
=
std
::
begin
(
in2
);
...
@@ -52,7 +75,8 @@ private:
...
@@ -52,7 +75,8 @@ private:
// ranges with static index access
// ranges with static index access
template
<
class
In1
,
class
In2
,
class
T
,
class
BinOp1
,
class
BinOp2
,
template
<
class
In1
,
class
In2
,
class
T
,
class
BinOp1
,
class
BinOp2
,
class
=
decltype
(
std
::
declval
<
In1
>()[
std
::
integral_constant
<
std
::
size_t
,
0
>
{}])
>
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
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
>
);
static_assert
(
static_size_v
<
In1
>
==
static_size_v
<
In2
>
);
Ranges
::
forIndices
<
static_size_v
<
In1
>>
([
&
](
auto
ii
)
{
Ranges
::
forIndices
<
static_size_v
<
In1
>>
([
&
](
auto
ii
)
{
...
...
amdis/algorithm/Transform.hpp
View file @
d5e52d52
...
@@ -14,13 +14,14 @@ namespace Recursive {
...
@@ -14,13 +14,14 @@ namespace Recursive {
template
<
class
>
template
<
class
>
struct
Transform
;
struct
Transform
;
/// \brief Recursive application of a functor `op` to a hierarchic container of containers.
/// \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
* 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].
* hierarchic containers {in...} and assigns the output to the hierarchic container [out].
* Therefore, the containers are traversed recursively, using specializations of the
* Therefore, the containers are traversed recursively, using specializations of the
* `Transform<Container>::impl` class method. If no such specialization is provided,
the function
* `Transform<Container>::impl` class method. If no such specialization is provided,
* is applied to the whole containers or leaf entries, respectively.
*
the function
is applied to the whole containers or leaf entries, respectively.
**/
**/
template
<
class
Out
,
class
Op
,
class
...
In
>
template
<
class
Out
,
class
Op
,
class
...
In
>
void
transform
(
Out
&
out
,
Op
&&
op
,
In
const
&
...
in
)
void
transform
(
Out
&
out
,
Op
&&
op
,
In
const
&
...
in
)
...
@@ -34,21 +35,23 @@ struct Transform
...
@@ -34,21 +35,23 @@ struct Transform
{
{
private:
private:
// ranges with dynamic index access
// ranges with dynamic index access
template
<
class
OutIter
,
class
Op
,
class
...
InIter
>
template
<
class
OutIter
,
class
Op
,
class
In0
,
class
...
InIter
>
static
void
impl3
(
OutIter
d_first
,
O
utIter
d_last
,
Op
&&
op
,
InIter
...
first
)
static
void
impl3
(
OutIter
d_first
,
O
p
&&
op
,
In0
first0
,
In0
last0
,
InIter
...
first
)
{
{
while
(
d_
first
!=
d_
last
)
while
(
first
0
!=
last
0
)
Recursive
::
transform
(
*
d_first
++
,
op
,
*
first
++
...);
Recursive
::
transform
(
*
d_first
++
,
op
,
*
first0
++
,
*
first
++
...);
}
}
// ranges with dynamic index access
// ranges with dynamic index access
template
<
class
Out
,
class
Op
,
class
...
In
,
template
<
class
Out
,
class
Op
,
class
In0
,
class
...
In
,
class
=
decltype
(
std
::
begin
(
std
::
declval
<
Out
>())),
class
=
decltype
(
std
::
begin
(
std
::
declval
<
Out
>())),
class
=
decltype
(
std
::
end
(
std
::
declval
<
Out
>
())),
class
=
decltype
(
std
::
begin
(
std
::
declval
<
In0
>
())),
class
=
std
::
void_t
<
decltype
(
std
::
begin
(
std
::
declval
<
In
>
()))...
>>
class
=
decltype
(
std
::
end
(
std
::
declval
<
In0
>
())),
static
void
impl2
(
Dune
::
PriorityTag
<
3
>
,
Out
&
out
,
Op
&&
op
,
In
const
&
...
in
)
class
=
decltype
((
std
::
begin
(
std
::
declval
<
In
>
()),...))
>
static
void
impl2
(
Dune
::
PriorityTag
<
3
>
,
Out
&
out
,
Op
&&
op
,
In0
const
&
in0
,
In
const
&
...
in
)
{
{
impl3
(
std
::
begin
(
out
),
std
::
end
(
out
),
op
,
std
::
begin
(
in
)...);
impl3
(
std
::
begin
(
out
),
op
,
std
::
begin
(
in0
),
std
::
end
(
in0
)
,
std
::
begin
(
in
)...);
}
}
// ranges with static index access
// ranges with static index access
...
...
cmake/modules/AmdisMacros.cmake
View file @
d5e52d52
...
@@ -7,15 +7,6 @@ if (CCACHE_PROGRAM)
...
@@ -7,15 +7,6 @@ if (CCACHE_PROGRAM)
set
(
CMAKE_CXX_COMPILER_LAUNCHER
"
${
CCACHE_PROGRAM
}
"
)
set
(
CMAKE_CXX_COMPILER_LAUNCHER
"
${
CCACHE_PROGRAM
}
"
)
endif
()
endif
()
if
(
UNIX AND NOT APPLE
)
execute_process
(
COMMAND
${
CMAKE_C_COMPILER
}
-fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE ld_version
)
if
(
"
${
ld_version
}
"
MATCHES
"GNU gold"
)
set
(
CMAKE_EXE_LINKER_FLAGS
"
${
CMAKE_EXE_LINKER_FLAGS
}
-fuse-ld=gold -Wl,--disable-new-dtags"
)
set
(
CMAKE_SHARED_LINKER_FLAGS
"
${
CMAKE_SHARED_LINKER_FLAGS
}
-fuse-ld=gold -Wl,--disable-new-dtags"
)
endif
()
endif
()
if
(
NOT BACKEND
)
if
(
NOT BACKEND
)
set
(
BACKEND
"ISTL"
CACHE STRING
"LinearAlgebra backend. One of MTL, EIGEN, PETSC, ISTL"
)
set
(
BACKEND
"ISTL"
CACHE STRING
"LinearAlgebra backend. One of MTL, EIGEN, PETSC, ISTL"
)
set_property
(
CACHE BACKEND PROPERTY STRINGS
"MTL"
"EIGEN"
"ISTL"
"PETSC"
)
set_property
(
CACHE BACKEND PROPERTY STRINGS
"MTL"
"EIGEN"
"ISTL"
"PETSC"
)
...
...
test/DOFVectorTest.cpp
View file @
d5e52d52
...
@@ -32,11 +32,11 @@ void test_dofvector(DOFVector<B,T>& vec)
...
@@ -32,11 +32,11 @@ void test_dofvector(DOFVector<B,T>& vec)
vec
.
insert
(
MultiIndex
{
0
},
T
(
1
));
vec
.
insert
(
MultiIndex
{
0
},
T
(
1
));
vec
.
finish
();
vec
.
finish
();
AMDIS_TEST_EQ
(
vec
.
a
t
(
MultiIndex
{
0
}),
T
(
1
));
AMDIS_TEST_EQ
(
vec
.
ge
t
(
MultiIndex
{
0
}),
T
(
1
));
T
min
(
10
);
T
min
(
10
);
T
max
(
-
10
);
T
max
(
-
10
);
v
ec
.
forEach
(
[
&
min
,
&
max
](
auto
,
auto
value
)
{
R
ec
ursive
::
forEach
(
vec
.
coefficients
(),
[
&
min
,
&
max
](
auto
value
)
{
min
=
std
::
min
(
min
,
value
);
min
=
std
::
min
(
min
,
value
);
max
=
std
::
max
(
max
,
value
);
max
=
std
::
max
(
max
,
value
);
});
});
...
...
test/DataTransferTest.hpp
View file @
d5e52d52
...
@@ -17,6 +17,7 @@
...
@@ -17,6 +17,7 @@
#include
<amdis/ProblemStat.hpp>
#include
<amdis/ProblemStat.hpp>
#include
<amdis/ProblemStatTraits.hpp>
#include
<amdis/ProblemStatTraits.hpp>
#include
<amdis/algorithm/InnerProduct.hpp>
#include
"Tests.hpp"
#include
"Tests.hpp"
...
@@ -80,7 +81,7 @@ double calcError(Problem const& prob, Fcts const& funcs)
...
@@ -80,7 +81,7 @@ double calcError(Problem const& prob, Fcts const& funcs)
{
{
auto
&
globalBasis
=
*
prob
->
globalBasis
();
auto
&
globalBasis
=
*
prob
->
globalBasis
();
auto
localView
=
globalBasis
.
localView
();
auto
localView
=
globalBasis
.
localView
();
auto
const
&
sol
=
prob
->
solution
()
.
coefficients
()
;
auto
sol
=
prob
->
solution
();
auto
ref
=
makeDOFVector
(
globalBasis
,
DataTransferOperation
::
NO_OPERATION
);
auto
ref
=
makeDOFVector
(
globalBasis
,
DataTransferOperation
::
NO_OPERATION
);
int
k
=
0
;
int
k
=
0
;
...
@@ -94,11 +95,9 @@ double calcError(Problem const& prob, Fcts const& funcs)
...
@@ -94,11 +95,9 @@ double calcError(Problem const& prob, Fcts const& funcs)
});
});
// compare the solution with the reference
// compare the solution with the reference
double
maxError
=
0
;
double
maxError
=
Recursive
::
innerProduct
(
ref
.
coefficients
(),
sol
.
coefficients
(),
0.0
,
sol
.
forEach
([
&
](
auto
dof
,
double
coeff
)
{
[](
double
a
,
double
b
)
{
return
std
::
max
(
a
,
b
);
},
double
error
=
std
::
abs
(
ref
.
at
(
dof
)
-
coeff
);
[](
double
a
,
double
b
)
{
return
std
::
abs
(
a
-
b
);
});
maxError
=
std
::
max
(
maxError
,
error
);
});
return
maxError
;
return
maxError
;
}
}
...
...
test/DiscreteFunctionTest.cpp
View file @
d5e52d52
...
@@ -8,7 +8,6 @@
...
@@ -8,7 +8,6 @@
#include
<amdis/AMDiS.hpp>
#include
<amdis/AMDiS.hpp>
#include
<amdis/ProblemStat.hpp>
#include
<amdis/ProblemStat.hpp>
#include
<amdis/common/Apply.hpp>
#include
<amdis/common/Apply.hpp>
#include
<amdis/common/RecursiveForEach.hpp>
#include
<amdis/gridfunctions/DiscreteFunction.hpp>
#include
<amdis/gridfunctions/DiscreteFunction.hpp>
#include
<amdis/typetree/TreePath.hpp>
#include
<amdis/typetree/TreePath.hpp>
...
@@ -71,7 +70,7 @@ bool compare(DOFVector<GB,T> const& U, DOFVector<GB,T> const& V)
...
@@ -71,7 +70,7 @@ bool compare(DOFVector<GB,T> const& U, DOFVector<GB,T> const& V)
for
(
size_type
i
=
0
;
i
<
lv
.
size
();
++
i
)
for
(
size_type
i
=
0
;
i
<
lv
.
size
();
++
i
)
{
{
auto
multiIndex
=
lv
.
index
(
i
);
auto
multiIndex
=
lv
.
index
(
i
);
if
(
!
compare
(
U
.
a
t
(
multiIndex
),
V
.
a
t
(
multiIndex
)))
if
(
!
compare
(
U
.
ge
t
(
multiIndex
),
V
.
ge
t
(
multiIndex
)))
return
false
;
return
false
;
}
}
}
}
...
...
test/RecursiveTest.cpp
View file @
d5e52d52
#include
<config.h>
#include
<config.h>
#include
<amdis/Environment.hpp>
#include
<amdis/Environment.hpp>
#include
<amdis/algorithm/
Apply
.hpp>
#include
<amdis/algorithm/
Map
.hpp>
#include
<amdis/algorithm/ForEach.hpp>
#include
<amdis/algorithm/ForEach.hpp>
#include
"Tests.hpp"
#include
"Tests.hpp"
...
@@ -19,7 +19,7 @@ void test(Container& container)
...
@@ -19,7 +19,7 @@ void test(Container& container)
Recursive
::
forEach
(
container
,
[
&
](
auto
const
&
c
)
{
sum
+=
c
;
});
Recursive
::
forEach
(
container
,
[
&
](
auto
const
&
c
)
{
sum
+=
c
;
});
// create a new container with scaled elements
// create a new container with scaled elements
auto
scaled
=
Recursive
::
ap
ply
([
&
](
auto
const
&
c
)
{
return
2
*
c
;
},
container
);
auto
scaled
=
Recursive
::
m
ap
([
&
](
auto
const
&
c
)
{
return
2
*
c
;
},
container
);
// sum up agains
// sum up agains
int
sum2
=
0
;
int
sum2
=
0
;
...
...
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