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
Aland, Sebastian
amdis
Commits
d2aafda1
Commit
d2aafda1
authored
Jun 26, 2015
by
Praetorius, Simon
Browse files
expression and DirichletBC with lambda functions
parent
7bd09e85
Changes
12
Hide whitespace changes
Inline
Side-by-side
AMDiS/CMakeLists.txt
View file @
d2aafda1
...
...
@@ -97,7 +97,7 @@ SET(AMDIS_SRC ${SOURCE_DIR}/AdaptBase.cc
${
SOURCE_DIR
}
/DOFMatrix.cc
${
SOURCE_DIR
}
/DOFVector.cc
${
SOURCE_DIR
}
/Debug.cc
${
SOURCE_DIR
}
/DirichletBC.cc
#
${SOURCE_DIR}/DirichletBC.cc
${
SOURCE_DIR
}
/DualTraverse.cc
${
SOURCE_DIR
}
/ElInfo.cc
${
SOURCE_DIR
}
/ElInfo1d.cc
...
...
AMDiS/src/AMDiS_fwd.h
View file @
d2aafda1
...
...
@@ -28,6 +28,7 @@
#include
<boost/numeric/mtl/mtl.hpp>
#include
"OpenMP.h"
#include
"Config.h"
namespace
AMDiS
{
...
...
@@ -133,8 +134,12 @@ namespace AMDiS {
struct
BoundaryObject
;
struct
AtomicBoundary
;
#if HAS_VARIADIC_TEMPLATES
template
<
typename
ReturnType
,
typename
...
Args
>
class
AbstractFunction
;
#else
template
<
typename
ReturnType
,
typename
ArgumentType
>
class
AbstractFunction
;
#endif
template
<
typename
ReturnType
,
typename
ArgumentType1
,
typename
ArgumentType2
>
class
BinaryAbstractFunction
;
...
...
@@ -153,6 +158,7 @@ namespace AMDiS {
template
<
typename
T
>
class
DOFVector
;
template
<
typename
T
>
class
DimVec
;
template
<
typename
T
>
class
DimMat
;
template
<
typename
T
>
class
DirichletBC
;
// template<typename ITLSolver> class ITL_LinearSolverInterface;
template
<
typename
T
,
typename
MatT
,
typename
VecT
>
class
ITL_Preconditioner
;
template
<
typename
T
>
class
Matrix
;
...
...
AMDiS/src/AbstractFunction.h
View file @
d2aafda1
...
...
@@ -32,43 +32,6 @@
#include
<boost/preprocessor/repetition/repeat.hpp>
namespace
AMDiS
{
/**
* \ingroup Common
*
* \brief
* An AbstractFunction object represents a function
* f : ArgumentType -> ReturnType.
*
* AbstractFunction is a pure virtual class interface class.
* To create your own function you have to derive AbstractFunction and
* overload operator().
*/
// #ifndef HAS_VARIADIC_TEMPLATES
template
<
typename
ReturnType
,
typename
ArgumentType
>
class
AbstractFunction
{
public:
/// Constructor.
AbstractFunction
(
int
degree
=
0
)
:
degree_
(
degree
)
{}
virtual
~
AbstractFunction
()
{}
/// Returns \ref degree_.
inline
int
getDegree
()
const
{
return
degree_
;
}
/// Deligates the evaluation to overriden method f.
virtual
ReturnType
operator
()(
const
ArgumentType
&
x
)
const
=
0
;
protected:
int
degree_
;
};
// #endif
/**
* \ingroup Common
...
...
@@ -175,7 +138,68 @@ namespace AMDiS {
int
degree_
;
};
// #ifndef HAS_VARIADIC_TEMPLATES
#if HAS_VARIADIC_TEMPLATES
// C++11 implementation of AbstractFunction with arbitrary nr of arguments using variadic templates
/**
* \ingroup Common
*
* \brief
* An AbstractFunction object represents a function
* f : ArgumentTypes... -> ReturnType.
*
* AbstractFunction is a pure virtual class interface class.
* To create your own function you have to derive AbstractFunction and
* overload operator().
*/
template
<
typename
ReturnType
,
typename
...
Args
>
class
AbstractFunction
{
public:
AbstractFunction
(
int
degree
=
0
)
:
degree_
(
degree
)
{}
virtual
~
AbstractFunction
()
{}
/// Returns \ref degree_.
inline
int
getDegree
()
const
{
return
degree_
;
}
/// function evaluation.
virtual
ReturnType
operator
()(
Args
const
&
...
args
)
const
=
0
;
protected:
int
degree_
;
};
#else
template
<
typename
ReturnType
,
typename
ArgumentType
>
class
AbstractFunction
{
public:
/// Constructor.
AbstractFunction
(
int
degree
=
0
)
:
degree_
(
degree
)
{}
virtual
~
AbstractFunction
()
{}
/// Returns \ref degree_.
inline
int
getDegree
()
const
{
return
degree_
;
}
/// Deligates the evaluation to overriden method f.
virtual
ReturnType
operator
()(
const
ArgumentType
&
x
)
const
=
0
;
protected:
int
degree_
;
};
///////////////////////////////////////////////////////////////
// test of AbstractFunction with arbitrary number of arguments
...
...
@@ -225,34 +249,8 @@ namespace AMDiS {
#endif
BOOST_PP_REPEAT_FROM_TO
(
1
,
11
,
ABSTRACT_FUNCTION_MACRO
,
nil
)
// #else
//
// /// C++11 implementation of abstract functions with arbitrary nr of arguments using variadic templates
// template< typename ReturnType, typename... Ts >
// class AbstractFunction
// {
// public:
// AbstractFunction(int degree = 0)
// : degree_(degree)
// {}
//
// virtual ~AbstractFunction() {}
//
// /// Returns \ref degree_.
// inline int getDegree() const
// {
// return degree_;
// }
//
// /// function evaluation.
// virtual ReturnType operator()(Ts const&... args) const = 0;
//
// protected:
// int degree_;
// };
//
// #endif
#endif
}
#endif // AMDIS_ABSTRACTFUNCTION_H
AMDiS/src/DirichletBC.cc
View file @
d2aafda1
...
...
@@ -72,21 +72,23 @@ namespace AMDiS {
const
BasisFunction
*
basFcts
=
rowFeSpace
->
getBasisFcts
();
for
(
int
i
=
0
;
i
<
nBasFcts
;
i
++
)
{
if
(
localBound
[
i
]
==
boundaryType
)
{
double
value
=
0.0
;
if
(
f
)
{
if
(
f
)
{
for
(
int
i
=
0
;
i
<
nBasFcts
;
i
++
)
if
(
localBound
[
i
]
==
boundaryType
)
{
elInfo
->
coordToWorld
(
*
(
basFcts
->
getCoords
(
i
)),
worldCoords
);
value
=
(
*
f
)(
worldCoords
);
}
else
{
if
(
dofVec
)
value
=
(
*
dofVec
)[
dofIndices
[
i
]];
else
ERROR_EXIT
(
"There is something wrong!
\n
"
);
double
value
=
(
*
f
)(
worldCoords
);
vector
->
setDirichletDofValue
(
dofIndices
[
i
],
value
);
(
*
vector
)[
dofIndices
[
i
]]
=
value
;
}
vector
->
setDirichletDofValue
(
dofIndices
[
i
],
value
);
(
*
vector
)[
dofIndices
[
i
]]
=
value
;
}
}
else
if
(
dofVec
)
{
for
(
int
i
=
0
;
i
<
nBasFcts
;
i
++
)
if
(
localBound
[
i
]
==
boundaryType
)
{
double
value
=
value
=
(
*
dofVec
)[
dofIndices
[
i
]];
vector
->
setDirichletDofValue
(
dofIndices
[
i
],
value
);
(
*
vector
)[
dofIndices
[
i
]]
=
value
;
}
}
else
{
ERROR_EXIT
(
"No data provided to assemble DirichletBC!
\n
"
);
}
}
...
...
AMDiS/src/DirichletBC.h
View file @
d2aafda1
...
...
@@ -30,8 +30,49 @@
#include
"AbstractFunction.h"
#include
"FixVec.h"
namespace
AMDiS
{
namespace
AMDiS
{
// some tags used for tag-dispatching
struct
_value_by_abstractfunction
{};
struct
_value_by_dofvector
{};
struct
_value_by_function
{};
namespace
detail
{
template
<
class
Tag
>
struct
ValueContainer
{};
template
<
>
struct
ValueContainer
<
_value_by_abstractfunction
>
{
ValueContainer
(
AbstractFunction
<
double
,
WorldVector
<
double
>
>
*
fct
)
:
value
(
*
fct
)
{};
ValueContainer
(
AbstractFunction
<
double
,
WorldVector
<
double
>
>
&
fct
)
:
value
(
fct
)
{};
AbstractFunction
<
double
,
WorldVector
<
double
>
>
&
value
;
};
template
<
>
struct
ValueContainer
<
_value_by_dofvector
>
{
ValueContainer
(
DOFVectorBase
<
double
>
*
vec
)
:
value
(
vec
)
{};
ValueContainer
(
DOFVectorBase
<
double
>
&
vec
)
:
value
(
&
vec
)
{};
DOFVectorBase
<
double
>
*
value
;
};
#if __cplusplus > 199711L
template
<
>
struct
ValueContainer
<
_value_by_function
>
{
ValueContainer
(
std
::
function
<
double
(
WorldVector
<
double
>
)
>
fct
)
:
value
(
fct
)
{};
std
::
function
<
double
(
WorldVector
<
double
>
)
>
value
;
};
#endif
}
// end namespace detail
/**
* \ingroup Assembler
*
...
...
@@ -41,6 +82,7 @@ namespace AMDiS {
* the row corresponding to a Dirichlet dof is replaced by a row containing
* only a 1.0 in the diagonal.
*/
template
<
class
ValueTag
>
class
DirichletBC
:
public
BoundaryCondition
{
public:
...
...
@@ -50,6 +92,15 @@ namespace AMDiS {
const
FiniteElemSpace
*
rowFeSpace
,
const
FiniteElemSpace
*
colFeSpace
=
NULL
,
bool
apply
=
true
);
#if __cplusplus > 199711L
/// Constructor.
DirichletBC
(
BoundaryType
type
,
std
::
function
<
double
(
WorldVector
<
double
>
)
>
fct
,
const
FiniteElemSpace
*
rowFeSpace
,
const
FiniteElemSpace
*
colFeSpace
=
NULL
,
bool
apply
=
true
);
#endif
/// Constructor.
DirichletBC
(
BoundaryType
type
,
...
...
@@ -57,18 +108,18 @@ namespace AMDiS {
bool
apply
=
true
);
/// Implementation of BoundaryCondition::fillBoundaryCondition().
void
fillBoundaryCondition
(
DOFMatrix
*
matrix
,
virtual
void
fillBoundaryCondition
(
DOFMatrix
*
matrix
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
);
int
nBasFcts
)
override
;
/// Implementation of BoundaryCondition::fillBoundaryCondition().
void
fillBoundaryCondition
(
DOFVectorBase
<
double
>*
vector
,
virtual
void
fillBoundaryCondition
(
DOFVectorBase
<
double
>*
vector
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
);
int
nBasFcts
)
override
;
///
void
initVector
(
DOFVectorBase
<
double
>*
);
...
...
@@ -92,26 +143,31 @@ namespace AMDiS {
{
return
applyBC
;
}
inline
AbstractFunction
<
double
,
WorldVector
<
double
>
>
*
getF
()
{
return
f
;
}
inline
DOFVectorBase
<
double
>
*
getDOFVector
()
{
return
dofVec
;
}
protected:
/// Function which is evaluated at world coords of Dirichlet dofs.
AbstractFunction
<
double
,
WorldVector
<
double
>
>
*
f
;
///
WorldVector
<
double
>
worldCoords
;
void
fillBC
(
_value_by_abstractfunction
,
DOFVectorBase
<
double
>*
vector
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
);
void
fillBC
(
_value_by_function
,
DOFVectorBase
<
double
>*
vector
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
);
void
fillBC
(
_value_by_dofvector
,
DOFVectorBase
<
double
>*
vector
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
);
/// DOFVector containing the boundary values
DOFVectorBase
<
double
>
*
dofVec
;
protected:
detail
::
ValueContainer
<
ValueTag
>
container
;
/// Defines, if the boundary condition must be applied to the matrix. See
/// comment of \ref BoundaryCondition::applyBoundaryCondition.
...
...
@@ -120,4 +176,6 @@ namespace AMDiS {
}
#include
"DirichletBC.hh"
#endif
AMDiS/src/Lagrange.h
View file @
d2aafda1
...
...
@@ -36,8 +36,6 @@ namespace AMDiS {
#define MAX_DIM 3
#define MAX_DEGREE 4
template
<
typename
ReturnType
,
typename
ArgumentType
>
class
AbstractFunction
;
/** \ingroup FEMSpace
* \brief
* Lagrange basis functions. Sub class of BasisFunction
...
...
AMDiS/src/ProblemStat.cc
View file @
d2aafda1
...
...
@@ -1383,10 +1383,10 @@ namespace AMDiS {
boundaryConditionSet
=
true
;
DirichletBC
*
dirichletApply
=
new
DirichletBC
(
type
,
b
,
componentSpaces
[
row
],
componentSpaces
[
col
],
true
);
DirichletBC
*
dirichletNotApply
=
new
DirichletBC
(
type
,
b
,
componentSpaces
[
row
],
componentSpaces
[
col
],
false
);
DirichletBC
<
_value_by_abstractfunction
>
*
dirichletApply
=
new
DirichletBC
<
_value_by_abstractfunction
>
(
type
,
b
,
componentSpaces
[
row
],
componentSpaces
[
col
],
true
);
DirichletBC
<
_value_by_abstractfunction
>
*
dirichletNotApply
=
new
DirichletBC
<
_value_by_abstractfunction
>
(
type
,
b
,
componentSpaces
[
row
],
componentSpaces
[
col
],
false
);
for
(
int
i
=
0
;
i
<
nComponents
;
i
++
)
if
(
systemMatrix
&&
(
*
systemMatrix
)[
row
][
i
])
{
...
...
@@ -1402,6 +1402,38 @@ namespace AMDiS {
solution
->
getDOFVector
(
col
)
->
getBoundaryManager
()
->
addBoundaryCondition
(
dirichletApply
);
}
#if __cplusplus > 199711L
void
ProblemStatSeq
::
addDirichletBC
(
BoundaryType
type
,
int
row
,
int
col
,
std
::
function
<
double
(
WorldVector
<
double
>
)
>
b
)
{
FUNCNAME
(
"ProblemStat::addDirichletBC()"
);
TEST_EXIT
(
row
>=
0
&&
row
<
nComponents
)(
"Wrong row number: %d
\n
"
,
row
);
TEST_EXIT
(
col
>=
0
&&
col
<
nComponents
)(
"Wrong col number: %d
\n
"
,
col
);
boundaryConditionSet
=
true
;
DirichletBC
<
_value_by_function
>
*
dirichletApply
=
new
DirichletBC
<
_value_by_function
>
(
type
,
b
,
componentSpaces
[
row
],
componentSpaces
[
col
],
true
);
DirichletBC
<
_value_by_function
>
*
dirichletNotApply
=
new
DirichletBC
<
_value_by_function
>
(
type
,
b
,
componentSpaces
[
row
],
componentSpaces
[
col
],
false
);
for
(
int
i
=
0
;
i
<
nComponents
;
i
++
)
if
(
systemMatrix
&&
(
*
systemMatrix
)[
row
][
i
])
{
if
(
i
==
col
)
(
*
systemMatrix
)[
row
][
i
]
->
getBoundaryManager
()
->
addBoundaryCondition
(
dirichletApply
);
else
(
*
systemMatrix
)[
row
][
i
]
->
getBoundaryManager
()
->
addBoundaryCondition
(
dirichletNotApply
);
}
if
(
rhs
)
rhs
->
getDOFVector
(
row
)
->
getBoundaryManager
()
->
addBoundaryCondition
(
dirichletApply
);
if
(
solution
)
solution
->
getDOFVector
(
col
)
->
getBoundaryManager
()
->
addBoundaryCondition
(
dirichletApply
);
}
#endif
void
ProblemStatSeq
::
addDirichletBC
(
BoundaryType
type
,
int
row
,
int
col
,
DOFVector
<
double
>
*
vec
)
...
...
@@ -1413,8 +1445,8 @@ namespace AMDiS {
boundaryConditionSet
=
true
;
DirichletBC
*
dirichletApply
=
new
DirichletBC
(
type
,
vec
,
true
);
DirichletBC
*
dirichletNotApply
=
new
DirichletBC
(
type
,
vec
,
false
);
DirichletBC
<
_value_by_dofvector
>
*
dirichletApply
=
new
DirichletBC
<
_value_by_dofvector
>
(
type
,
vec
,
true
);
DirichletBC
<
_value_by_dofvector
>
*
dirichletNotApply
=
new
DirichletBC
<
_value_by_dofvector
>
(
type
,
vec
,
false
);
for
(
int
i
=
0
;
i
<
nComponents
;
i
++
)
if
(
systemMatrix
&&
(
*
systemMatrix
)[
row
][
i
])
{
...
...
AMDiS/src/ProblemStat.h
View file @
d2aafda1
...
...
@@ -27,6 +27,9 @@
#include
<vector>
#include
<list>
#if __cplusplus > 199711L
#include
<functional>
#endif
#include
"AMDiS_fwd.h"
#include
"ProblemStatBase.h"
#include
"Initfile.h"
...
...
@@ -188,6 +191,14 @@ namespace AMDiS {
/// abstract function.
virtual
void
addDirichletBC
(
BoundaryType
type
,
int
row
,
int
col
,
AbstractFunction
<
double
,
WorldVector
<
double
>
>
*
b
);
#if __cplusplus > 199711L
/// Adds a Dirichlet boundary condition, where the rhs is given by an
/// lambda function or a std::function object
virtual
void
addDirichletBC
(
BoundaryType
type
,
int
row
,
int
col
,
std
::
function
<
double
(
WorldVector
<
double
>
)
>
b
);
#endif
/// Adds a Dirichlet boundary condition, where the rhs is given by a DOF
/// vector.
...
...
AMDiS/src/expressions/expressions.h
View file @
d2aafda1
...
...
@@ -34,11 +34,7 @@
#include
"add_expr.hpp"
// add two expressions
#include
"mult_expr.hpp"
// multiply two expressions
#if HAS_VARIADIC_TEMPLATES && HAS_ALIAS_TEMPLATES
#include
"functorN_expr.hpp"
// apply a functor with arbitrary nr. of arguments to expressions
#else
#include
"functor_expr.hpp"
// apply a functor with 1/2/3 arguments to expressions
#endif
#include
"functor_expr.hpp"
// apply a functor with 1/2/3 arguments to expressions
#include
"cmath_expr.hpp"
// apply a cmath function to expressions
#include
"vec_functors.hpp"
// apply a vector function to expressions
...
...
AMDiS/src/expressions/functorN_expr.hpp
View file @
d2aafda1
...
...
@@ -28,13 +28,14 @@
#include
"AMDiS_fwd.h"
#include
"LazyOperatorTerm.h"
#include
"Functors.h"
#include
"expressions/functor_expr.hpp"
//
#include "expressions/functor_expr.hpp"
#include
"operations/functors.hpp"
#include
<boost/static_assert.hpp>
#include
<tuple>
#include
<utility>
#include
<functional>
namespace
AMDiS
{
...
...
@@ -71,7 +72,66 @@ namespace AMDiS
template
<
typename
...
Int
>
static
int
eval
(
F
f
,
Int
...
d
)
{
return
f
.
getDegree
(
d
...);
}
};
}
// specialization for abstract-functions
template
<
typename
R
,
typename
...
Args
>
struct
functor_degree
<
AbstractFunction
<
R
,
Args
...
>
>
{
template
<
typename
...
Int
>
static
int
eval
(
AbstractFunction
<
R
,
Args
...
>
const
&
fct
,
Int
...
d
)
{
return
fct
.
getDegree
();
}
};
template
<
typename
R
,
typename
Arg0
,
typename
Arg1
>
struct
functor_degree
<
BinaryAbstractFunction
<
R
,
Arg0
,
Arg1
>
>
{
template
<
typename
...
Int
>
static
int
eval
(
BinaryAbstractFunction
<
R
,
Arg0
,
Arg1
>
const
&
fct
,
Int
...
d
)
{
return
fct
.
getDegree
();
}
};
template
<
typename
R
,
typename
Arg0
,
typename
Arg1
,
typename
Arg2
>
struct
functor_degree
<
TertiaryAbstractFunction
<
R
,
Arg0
,
Arg1
,
Arg2
>
>
{
template
<
typename
...
Int
>
static
int
eval
(
TertiaryAbstractFunction
<
R
,
Arg0
,
Arg1
,
Arg2
>
const
&
fct
,
Int
...
d
)
{
return
fct
.
getDegree
();
}
};
}
// end namespace traits
namespace
result_of
{
/// extract result type from function pointers
template
<
class
FPtr
>
struct
Function
;
template
<
class
R
,
class
C
,
class
...
As
>
struct
Function
<
R
(
C
::*
)(
As
...)
>
{
typedef
R
result_type
;
};
template
<
class
R
,
class
C
,
class
...
As
>
struct
Function
<
R
(
C
::*
)(
As
...)
const
>
{
typedef
R
type
;
};
template
<
class
T
>
typename
Function
<
T
>::
type
function_helper
(
T
);
/// extract result type from functors
template
<
class
F
>
struct
Functor
{
typedef
decltype
(
function_helper
(
&
F
::
operator
()))
type
;
};
template
<
class
R
,
class
...
As
>
struct
Functor
<
std
::
function
<
R
(
As
...)
>
>
{
typedef
R
type
;
};
}
// end namespace result_of
namespace
detail
...
...
@@ -167,7 +227,7 @@ namespace AMDiS
typedef
LazyOperatorTerms
<
Terms
...
>
super
;
static
const
int
N
=
sizeof
...(
Terms
);
typedef
typename
traits
::
f
unctor
_result_type
<
F
>::
type
value_type
;
typedef
typename
result_of
::
F
unctor
<
F
>::
type
value_type
;
BOOST_STATIC_ASSERT_MSG
(
(
!
boost
::
is_same
<
value_type
,
traits
::
no_valid_type
>::
value
),
"********** ERROR: You have to define a result_type for your Functor **********"
);
F
f
;
///< the functor
...
...
@@ -210,50 +270,93 @@ namespace AMDiS
inline
value_type
operator
()(
const
int
&
iq
)
const
{
return
eval
(
iq
,
int_
<
N
>
());
}
};
template
<
typename
F
,
typename
Term
>
using
Function1
=
FunctionN
<
F
,
Term
>
;
template
<
typename
F
,
typename
Term1
,
typename
Term2
>
using
Function2
=
FunctionN
<
F
,
Term1
,
Term2
>
;
template
<
typename
F
,
typename
Term1
,
typename
Term2
,
typename
Term3
>
using
Function3
=
FunctionN
<
F
,
Term1
,
Term2
,
Term3
>
;
template
<
typename
F
,
typename
Term1
,
typename
Term2
,
typename
Term3
,
typename
Term4
>
using
Function4
=
FunctionN
<
F
,
Term1
,
Term2
,
Term3
,
Term4
>
;
/// A wrapper functor for AMDiS::AbstractFunctions
template
<
typename
TOut
,
typename
TIn
>
struct
Wrapper
:
public
FunctorBase
{
typedef
TOut
result_type
;
Wrapper
(
AbstractFunction
<
TOut
,
TIn
>*
fct_
)
:
fct
(
fct_
)
{}
int
getDegree
(
int
degree
)
const
{
return
fct
->
getDegree
();
}
TOut
operator
()(
const
TIn
&
x
)
const
{
return
(
*
fct
)(
x
);
}
protected: