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
iwr
amdis
Commits
aeaa15ee
Commit
aeaa15ee
authored
Jun 29, 2015
by
Praetorius, Simon
Browse files
allow lambda functiosn in Dirichlet BC
parent
013c2859
Changes
4
Hide whitespace changes
Inline
Side-by-side
AMDiS/CMakeLists.txt
View file @
aeaa15ee
...
...
@@ -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/DirichletBC.cc
View file @
aeaa15ee
...
...
@@ -26,77 +26,89 @@
#include
"DOFMatrix.h"
namespace
AMDiS
{
DirichletBC
::
DirichletBC
(
BoundaryType
type
,
AbstractFunction
<
double
,
WorldVector
<
double
>
>
*
fct
,
const
FiniteElemSpace
*
rowFeSpace
,
const
FiniteElemSpace
*
colFeSpace
,
bool
apply
)
:
BoundaryCondition
(
type
,
rowFeSpace
,
colFeSpace
),
f
(
fct
),
dofVec
(
NULL
),
applyBC
(
apply
)
{}
DirichletBC
::
DirichletBC
(
BoundaryType
type
,
DOFVectorBase
<
double
>
*
vec
,
bool
apply
)
:
BoundaryCondition
(
type
,
vec
->
getFeSpace
(),
vec
->
getFeSpace
()),
f
(
NULL
),
dofVec
(
vec
),
applyBC
(
apply
)
{}
void
DirichletBC
::
fillBoundaryCondition
(
DOFMatrix
*
matrix
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
)
namespace
detail
{
void
DirichletBC
::
fillBoundaryCondition
(
DOFMatrix
*
matrix
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
)
{
FUNCNAME_DBG
(
"DirichletBC::fillBoundaryCondition()"
);
TEST_EXIT_DBG
(
matrix
->
getRowFeSpace
()
==
rowFeSpace
)(
"invalid row fe space
\n
"
);
}
void
DirichletBC
::
initVector
(
DOFVectorBase
<
double
>*
vec
)
{
if
(
dynamic_cast
<
DOFVector
<
double
>*>
(
vec
))
dynamic_cast
<
DOFVector
<
double
>*>
(
vec
)
->
getDirichletValues
().
clear
();
}
}
DirichletBC
<
_value_by_dofvector
>::
DirichletBC
(
BoundaryType
type
,
DOFVectorBase
<
double
>
*
vec
,
bool
apply
)
:
super
(
type
,
vec
->
getFeSpace
(),
vec
->
getFeSpace
(),
apply
),
container
(
vec
)
{
}
void
DirichletBC
<
_value_by_dofvector
>::
fillBoundaryCondition
(
DOFVectorBase
<
double
>*
vector
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
)
{
FUNCNAME_DBG
(
"DirichletBC::fillBoundaryCondition()"
);
TEST_EXIT_DBG
(
matrix
->
getRowFeSpace
()
==
rowFeSpace
)(
"invalid row fe space
\n
"
);
for
(
int
i
=
0
;
i
<
nBasFcts
;
i
++
)
if
(
localBound
[
i
]
==
boundaryType
)
{
double
value
=
(
*
container
)[
dofIndices
[
i
]];
vector
->
setDirichletDofValue
(
dofIndices
[
i
],
value
);
(
*
vector
)[
dofIndices
[
i
]]
=
value
;
}
}
void
DirichletBC
::
fillBoundaryCondition
(
DOFVectorBase
<
double
>*
vector
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
)
// c++11 std::function of lambda-functions
void
DirichletBC
<
_value_by_function
>::
fillBoundaryCondition
(
DOFVectorBase
<
double
>*
vector
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
)
{
FUNCNAME
(
"DirichletBC::fillBoundaryCondition()"
);
TEST_EXIT_DBG
(
vector
->
getFeSpace
()
==
rowFeSpace
)(
"invalid row fe space
\n
"
);
WorldVector
<
double
>
worldCoords
;
const
BasisFunction
*
basFcts
=
rowFeSpace
->
getBasisFcts
();
if
(
f
)
{
for
(
int
i
=
0
;
i
<
nBasFcts
;
i
++
)
if
(
localBound
[
i
]
==
boundaryType
)
{
elInfo
->
coordToWorld
(
*
(
basFcts
->
getCoords
(
i
)),
worldCoords
);
double
value
=
(
*
f
)(
worldCoords
);
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
"
);
}
for
(
int
i
=
0
;
i
<
nBasFcts
;
i
++
)
if
(
localBound
[
i
]
==
boundaryType
)
{
elInfo
->
coordToWorld
(
*
(
basFcts
->
getCoords
(
i
)),
worldCoords
);
double
value
=
container
(
worldCoords
);
vector
->
setDirichletDofValue
(
dofIndices
[
i
],
value
);
(
*
vector
)[
dofIndices
[
i
]]
=
value
;
}
}
void
DirichletBC
::
initVector
(
DOFVectorBase
<
double
>*
vec
)
void
DirichletBC
<
_value_by_abstractfunction
>::
fillBoundaryCondition
(
DOFVectorBase
<
double
>*
vector
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
)
{
if
(
dynamic_cast
<
DOFVector
<
double
>*>
(
vec
))
dynamic_cast
<
DOFVector
<
double
>*>
(
vec
)
->
getDirichletValues
().
clear
();
}
WorldVector
<
double
>
worldCoords
;
const
BasisFunction
*
basFcts
=
rowFeSpace
->
getBasisFcts
();
for
(
int
i
=
0
;
i
<
nBasFcts
;
i
++
)
if
(
localBound
[
i
]
==
boundaryType
)
{
elInfo
->
coordToWorld
(
*
(
basFcts
->
getCoords
(
i
)),
worldCoords
);
double
value
=
container
(
worldCoords
);
vector
->
setDirichletDofValue
(
dofIndices
[
i
],
value
);
(
*
vector
)[
dofIndices
[
i
]]
=
value
;
}
}
}
AMDiS/src/DirichletBC.h
View file @
aeaa15ee
...
...
@@ -40,142 +40,155 @@ namespace AMDiS
namespace
detail
{
template
<
class
Tag
>
struct
ValueContainer
{};
class
DirichletBC
:
public
BoundaryCondition
{
public:
/// Constructor.
DirichletBC
(
BoundaryType
type
,
const
FiniteElemSpace
*
rowFeSpace
,
const
FiniteElemSpace
*
colFeSpace
,
bool
apply
)
:
BoundaryCondition
(
type
,
rowFeSpace
,
colFeSpace
),
applyBC
(
apply
)
{
}
/// Implementation of BoundaryCondition::fillBoundaryCondition().
virtual
void
fillBoundaryCondition
(
DOFMatrix
*
matrix
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
)
override
;
///
void
initVector
(
DOFVectorBase
<
double
>*
vec
);
/// Implementation of BoundaryCondition::boundResidual().
double
boundResidual
(
ElInfo
*
,
DOFMatrix
*
,
const
DOFVectorBase
<
double
>*
)
{
return
0.0
;
}
/// Because this is a Dirichlet boundary condition, always return true.
bool
isDirichlet
()
{
return
true
;
}
/// Returns \ref applyBC.
bool
applyBoundaryCondition
()
{
return
applyBC
;
}
protected:
/// Defines, if the boundary condition must be applied to the matrix. See
/// comment of \ref BoundaryCondition::applyBoundaryCondition.
bool
applyBC
;
};
}
// end namespace detail
/**
* \ingroup Assembler
*
* \brief
* Sub class of BoundaryCondition. Implements Dirichlet boundary conditions.
* A DOFVectors is set to a given value at a Dirichlet dof and in a DOFMatrix
* 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
{};
// specialization for AbstractFunctions as value container
template
<
>
struct
ValueContainer
<
_value_by_abstractfunction
>
class
DirichletBC
<
_value_by_abstractfunction
>
:
public
detail
::
DirichletBC
{
ValueContainer
(
AbstractFunction
<
double
,
WorldVector
<
double
>
>
*
fct
)
:
value
(
*
fct
)
{};
ValueContainer
(
AbstractFunction
<
double
,
WorldVector
<
double
>
>
&
fct
)
:
value
(
fct
)
{};
typedef
detail
::
DirichletBC
super
;
public:
/// Constructor.
DirichletBC
(
BoundaryType
type
,
AbstractFunction
<
double
,
WorldVector
<
double
>
>
*
fct
,
const
FiniteElemSpace
*
rowFeSpace
,
const
FiniteElemSpace
*
colFeSpace
=
NULL
,
bool
apply
=
true
)
:
super
(
type
,
rowFeSpace
,
colFeSpace
,
apply
),
container
(
*
fct
)
{
}
AbstractFunction
<
double
,
WorldVector
<
double
>
>
&
value
;
/// Implementation of BoundaryCondition::fillBoundaryCondition().
virtual
void
fillBoundaryCondition
(
DOFVectorBase
<
double
>*
vector
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
)
override
;
protected:
AbstractFunction
<
double
,
WorldVector
<
double
>
>
&
container
;
};
// specialization for DOFVectors as value container
template
<
>
struct
ValueContainer
<
_value_by_dofvector
>
class
DirichletBC
<
_value_by_dofvector
>
:
public
detail
::
DirichletBC
{
ValueContainer
(
DOFVectorBase
<
double
>
*
vec
)
:
value
(
vec
)
{};
ValueContainer
(
DOFVectorBase
<
double
>
&
vec
)
:
value
(
&
vec
)
{};
typedef
detail
::
DirichletBC
super
;
public:
/// Constructor.
DirichletBC
(
BoundaryType
type
,
DOFVectorBase
<
double
>
*
vec
,
bool
apply
=
true
);
DOFVectorBase
<
double
>
*
value
;
/// Implementation of BoundaryCondition::fillBoundaryCondition().
virtual
void
fillBoundaryCondition
(
DOFVectorBase
<
double
>*
vector
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
)
override
;
protected:
DOFVectorBase
<
double
>
*
container
;
};
#if __cplusplus > 199711L
// specialization for std::function or lambdas as value container
template
<
>
struct
ValueContainer
<
_value_by_function
>
class
DirichletBC
<
_value_by_function
>
:
public
detail
::
DirichletBC
{
ValueContainer
(
std
::
function
<
double
(
WorldVector
<
double
>
)
>
fct
)
:
value
(
fct
)
{};
typedef
detail
::
DirichletBC
super
;
public:
/// Constructor.
DirichletBC
(
BoundaryType
type
,
std
::
function
<
double
(
WorldVector
<
double
>
)
>
fct
,
const
FiniteElemSpace
*
rowFeSpace
,
const
FiniteElemSpace
*
colFeSpace
=
NULL
,
bool
apply
=
true
)
:
super
(
type
,
rowFeSpace
,
colFeSpace
,
apply
),
container
(
fct
)
{
}
std
::
function
<
double
(
WorldVector
<
double
>
)
>
value
;
/// Implementation of BoundaryCondition::fillBoundaryCondition().
virtual
void
fillBoundaryCondition
(
DOFVectorBase
<
double
>*
vector
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
)
override
;
protected:
std
::
function
<
double
(
WorldVector
<
double
>
)
>
container
;
};
#endif
}
// end namespace detail
/**
* \ingroup Assembler
*
* \brief
* Sub class of BoundaryCondition. Implements Dirichlet boundary conditions.
* A DOFVectors is set to a given value at a Dirichlet dof and in a DOFMatrix
* 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:
/// Constructor.
DirichletBC
(
BoundaryType
type
,
AbstractFunction
<
double
,
WorldVector
<
double
>
>
*
fct
,
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
,
DOFVectorBase
<
double
>
*
vec
,
bool
apply
=
true
);
/// Implementation of BoundaryCondition::fillBoundaryCondition().
virtual
void
fillBoundaryCondition
(
DOFMatrix
*
matrix
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
)
override
;
/// Implementation of BoundaryCondition::fillBoundaryCondition().
virtual
void
fillBoundaryCondition
(
DOFVectorBase
<
double
>*
vector
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
)
override
;
///
void
initVector
(
DOFVectorBase
<
double
>*
);
/// Implementation of BoundaryCondition::boundResidual().
double
boundResidual
(
ElInfo
*
,
DOFMatrix
*
,
const
DOFVectorBase
<
double
>*
)
{
return
0.0
;
}
/// Because this is a Dirichlet boundary condition, always return true.
bool
isDirichlet
()
{
return
true
;
}
/// Returns \ref applyBC.
bool
applyBoundaryCondition
()
{
return
applyBC
;
}
protected:
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
);
protected:
detail
::
ValueContainer
<
ValueTag
>
container
;
/// Defines, if the boundary condition must be applied to the matrix. See
/// comment of \ref BoundaryCondition::applyBoundaryCondition.
bool
applyBC
;
};
}
#include
"DirichletBC.hh"
#endif
AMDiS/src/DirichletBC.hh
deleted
100644 → 0
View file @
013c2859
/******************************************************************************
*
* AMDiS - Adaptive multidimensional simulations
*
* Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
* Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
*
* Authors:
* Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
*
* This file is part of AMDiS
*
* See also license.opensource.txt in the distribution.
*
******************************************************************************/
#include
"ElInfo.h"
#include
"BasisFunction.h"
#include
"DOFVector.h"
#include
"DOFMatrix.h"
namespace
AMDiS
{
template
<
class
Tag
>
DirichletBC
<
Tag
>::
DirichletBC
(
BoundaryType
type
,
AbstractFunction
<
double
,
WorldVector
<
double
>
>
*
fct
,
const
FiniteElemSpace
*
rowFeSpace
,
const
FiniteElemSpace
*
colFeSpace
,
bool
apply
)
:
BoundaryCondition
(
type
,
rowFeSpace
,
colFeSpace
),
container
(
fct
),
applyBC
(
apply
)
{}
#if __cplusplus > 199711L
template
<
class
Tag
>
DirichletBC
<
Tag
>::
DirichletBC
(
BoundaryType
type
,
std
::
function
<
double
(
WorldVector
<
double
>
)
>
fct
,
const
FiniteElemSpace
*
rowFeSpace
,
const
FiniteElemSpace
*
colFeSpace
,
bool
apply
)
:
BoundaryCondition
(
type
,
rowFeSpace
,
colFeSpace
),
container
(
fct
),
applyBC
(
apply
)
{}
#endif
template
<
class
Tag
>
DirichletBC
<
Tag
>::
DirichletBC
(
BoundaryType
type
,
DOFVectorBase
<
double
>
*
vec
,
bool
apply
)
:
BoundaryCondition
(
type
,
vec
->
getFeSpace
(),
vec
->
getFeSpace
()),
container
(
vec
),
applyBC
(
apply
)
{}
template
<
class
Tag
>
void
DirichletBC
<
Tag
>::
fillBoundaryCondition
(
DOFMatrix
*
matrix
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
)
{
FUNCNAME_DBG
(
"DirichletBC::fillBoundaryCondition()"
);
TEST_EXIT_DBG
(
matrix
->
getRowFeSpace
()
==
rowFeSpace
)(
"invalid row fe space
\n
"
);
}
template
<
class
Tag
>
void
DirichletBC
<
Tag
>::
fillBoundaryCondition
(
DOFVectorBase
<
double
>*
vector
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
)
{
FUNCNAME_DBG
(
"DirichletBC::fillBoundaryCondition()"
);
TEST_EXIT_DBG
(
vector
->
getFeSpace
()
==
rowFeSpace
)(
"invalid row fe space
\n
"
);
fillBC
(
Tag
(),
vector
,
elInfo
,
dofIndices
,
localBound
,
nBasFcts
);
}
template
<
class
Tag
>
void
DirichletBC
<
Tag
>::
fillBC
(
_value_by_abstractfunction
,
DOFVectorBase
<
double
>*
vector
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
)
{
WorldVector
<
double
>
worldCoords
;
const
BasisFunction
*
basFcts
=
rowFeSpace
->
getBasisFcts
();
for
(
int
i
=
0
;
i
<
nBasFcts
;
i
++
)
if
(
localBound
[
i
]
==
boundaryType
)
{
elInfo
->
coordToWorld
(
*
(
basFcts
->
getCoords
(
i
)),
worldCoords
);
double
value
=
container
.
value
(
worldCoords
);
vector
->
setDirichletDofValue
(
dofIndices
[
i
],
value
);
(
*
vector
)[
dofIndices
[
i
]]
=
value
;
}
}
// c++11 std::function of lambda-functions
template
<
class
Tag
>
void
DirichletBC
<
Tag
>::
fillBC
(
_value_by_function
,
DOFVectorBase
<
double
>*
vector
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
)
{
WorldVector
<
double
>
worldCoords
;
const
BasisFunction
*
basFcts
=
rowFeSpace
->
getBasisFcts
();
for
(
int
i
=
0
;
i
<
nBasFcts
;
i
++
)
if
(
localBound
[
i
]
==
boundaryType
)
{
elInfo
->
coordToWorld
(
*
(
basFcts
->
getCoords
(
i
)),
worldCoords
);
double
value
=
container
.
value
(
worldCoords
);
vector
->
setDirichletDofValue
(
dofIndices
[
i
],
value
);
(
*
vector
)[
dofIndices
[
i
]]
=
value
;
}
}
template
<
class
Tag
>
void
DirichletBC
<
Tag
>::
fillBC
(
_value_by_dofvector
,
DOFVectorBase
<
double
>*
vector
,
ElInfo
*
elInfo
,
const
DegreeOfFreedom
*
dofIndices
,
const
BoundaryType
*
localBound
,
int
nBasFcts
)
{
for
(
int
i
=
0
;
i
<
nBasFcts
;
i
++
)
if
(
localBound
[
i
]
==
boundaryType
)
{
double
value
=
(
*
container
.
value
)[
dofIndices
[
i
]];
vector
->
setDirichletDofValue
(
dofIndices
[
i
],
value
);
(
*
vector
)[
dofIndices
[
i
]]
=
value
;
}
}
template
<
class
Tag
>
void
DirichletBC
<
Tag
>::
initVector
(
DOFVectorBase
<
double
>*
vec
)
{
if
(
dynamic_cast
<
DOFVector
<
double
>*>
(
vec
))
dynamic_cast
<
DOFVector
<
double
>*>
(
vec
)
->
getDirichletValues
().
clear
();
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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