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
7e44b707
Commit
7e44b707
authored
Dec 18, 2017
by
Praetorius, Simon
Browse files
new operator style implemented, using tags
parent
0057b587
Changes
51
Hide whitespace changes
Inline
Side-by-side
dune/amdis/Assembler.hpp
View file @
7e44b707
...
...
@@ -14,9 +14,6 @@
namespace
AMDiS
{
const
Flag
EQUAL_BASES
=
0x01L
;
const
Flag
EQUAL_LOCALBASES
=
0x02L
;
template
<
class
Traits
>
class
Assembler
{
...
...
dune/amdis/Assembler.inc.hpp
View file @
7e44b707
...
...
@@ -110,7 +110,7 @@ void Assembler<Traits>::assembleElementOperators(
auto
assemble_operators
=
[
&
](
auto
const
&
context
,
auto
&
operator_list
)
{
for
(
auto
scaled
:
operator_list
)
{
scaled
.
op
->
bind
(
element
,
geometry
);
bool
add_op
=
scaled
.
op
->
assemble
(
context
,
elementContainer
,
localViews
.
tree
()...
,
scaled
.
factor
);
bool
add_op
=
scaled
.
op
->
assemble
(
context
,
elementContainer
,
localViews
.
tree
()...);
scaled
.
op
->
unbind
();
add
=
add
||
add_op
;
}
...
...
@@ -148,18 +148,16 @@ void Assembler<Traits>::initMatrixVector(
auto
localView
=
globalBasis_
.
localView
();
forEachNode
(
localView
.
tree
(),
[
&
,
this
](
auto
const
&
rowNode
,
auto
rowTreePath
)
{
#ifdef HAVE_EXTENDED_DUNE_FUNCTIONS
if
(
rowNode
.
isLeaf
)
msg
(
globalBasis_
.
dimension
(
rowTreePath
),
" DOFs for Basis["
,
to_string
(
rowTreePath
),
"]"
);
#endif
auto
rowBasis
=
Dune
::
Functions
::
subspaceBasis
(
globalBasis_
,
rowTreePath
);
//if (rhsOperators_[rowNode].assemble(asmVector))
// rhsOperators_[rowNode].init(rowBasis);
forEachNode
(
localView
.
tree
(),
[
&
,
this
](
auto
const
&
colNode
,
auto
colTreePath
)
{
auto
colBasis
=
Dune
::
Functions
::
subspaceBasis
(
globalBasis_
,
colTreePath
);
//if (matrixOperators_[rowNode][colNode].assemble(asmMatrix))
// matrixOperators_[rowNode][colNode].init(rowBasis, colBasis);
for
(
auto
bc
:
constraints_
[
rowNode
][
colNode
].
scalar
)
bc
->
init
(
matrix
,
solution
,
rhs
,
rowBasis
,
colBasis
);
...
...
dune/amdis/ContextGeometry.hpp
0 → 100644
View file @
7e44b707
#pragma once
namespace
AMDiS
{
template
<
class
LocalContext
,
class
Geometry
,
class
LocalGeometry
>
struct
ContextGeometry
{
enum
{
dim
=
Geometry
::
mydimension
,
//< the dimension of the grid element
dow
=
Geometry
::
coorddimension
//< the dimension of the world
};
LocalContext
const
&
localContext
;
Geometry
const
&
geometry
;
LocalGeometry
const
&
localGeometry
;
/// Coordinate `p` given in `localGeometry`, transformed to coordinate in `geometry`.
template
<
class
Coordinate
>
decltype
(
auto
)
position
(
Coordinate
const
&
p
)
const
{
return
position
(
p
,
std
::
is_same
<
Geometry
,
LocalGeometry
>
{});
}
/// The integration element from the `localGeometry`, the quadrature points are
/// defined in.
template
<
class
Coordinate
>
auto
integrationElement
(
Coordinate
const
&
p
)
const
{
return
localGeometry
.
integrationElement
(
p
);
}
/// Transformation of coordinate `p` given in `localGeometry` to world space coordinates.
template
<
class
Coordinate
>
decltype
(
auto
)
global
(
Coordinate
const
&
p
)
const
{
return
geometry
.
global
(
p
);
}
private:
// implementation detail
// position for elements
template
<
class
Coordinate
>
Coordinate
const
&
position
(
Coordinate
const
&
p
,
std
::
true_type
)
const
{
return
p
;
}
// position for intersection
template
<
class
Coordinate
>
auto
position
(
Coordinate
const
&
p
,
std
::
false_type
)
const
{
return
localGeometry
.
global
(
p
);
}
};
}
// end namespace AMDiS
dune/amdis/DirichletBC.hpp
View file @
7e44b707
...
...
@@ -91,7 +91,7 @@ namespace AMDiS
{
using
WorldVector
=
typename
GlobalBasis
::
GridView
::
template
Codim
<
0
>
::
Geometry
::
GlobalCoordinate
;
template
<
class
Node
>
template
<
class
RowNode
,
class
Col
Node
>
struct
type
{
std
::
list
<
std
::
shared_ptr
<
DirichletBC
<
WorldVector
,
double
>>>
scalar
;
...
...
dune/amdis/FirstOrderAssembler.hpp
deleted
100644 → 0
View file @
0057b587
#pragma once
#include
<vector>
#include
<dune/typetree/nodetags.hh>
#include
<dune/amdis/LocalAssembler.hpp>
#include
<dune/amdis/common/Mpl.hpp>
#include
<dune/amdis/common/TypeDefs.hpp>
#include
<dune/amdis/utility/GetEntity.hpp>
namespace
AMDiS
{
template
<
class
GridView
,
class
LocalContext
,
FirstOrderType
type
>
class
FirstOrderAssembler
:
public
LocalAssembler
<
GridView
,
LocalContext
>
{
using
Super
=
LocalAssembler
<
GridView
,
LocalContext
>
;
static
constexpr
int
dim
=
GridView
::
dimension
;
static
constexpr
int
dow
=
GridView
::
dimensionworld
;
using
ElementMatrix
=
Impl
::
ElementMatrix
;
using
ElementVector
=
Impl
::
ElementVector
;
using
OrderTag
=
std
::
conditional_t
<
(
type
==
GRD_PHI
),
tag
::
fot_grd_phi
,
tag
::
fot_grd_psi
>
;
public:
FirstOrderAssembler
()
:
Super
(
1
,
type
)
{}
template
<
class
Operator
,
class
...
Args
>
void
bind
(
double
factor
,
Operator
&
op
,
LocalContext
const
&
localContext
,
Args
&&
...
args
)
{
Super
::
bind
(
op
,
localContext
,
std
::
forward
<
Args
>
(
args
)...);
factor_
=
factor
;
op
.
init
(
OrderTag
{},
localContext
,
Super
::
getQuadrature
());
}
// tag dispatching for FirstOrderType...
template
<
class
Operator
,
class
RowNode
,
class
ColNode
>
void
calculateElementMatrix
(
Operator
&
op
,
ElementMatrix
&
elementMatrix
,
RowNode
const
&
rowNode
,
ColNode
const
&
colNode
)
{
calculateElementMatrix
(
op
,
elementMatrix
,
rowNode
,
colNode
,
typename
RowNode
::
NodeTag
{},
typename
ColNode
::
NodeTag
{},
FirstOrderType_
<
type
>
);
}
template
<
class
Operator
,
class
Node
>
void
calculateElementVector
(
Operator
&
op
,
ElementVector
&
elementVector
,
Node
const
&
node
)
{
calculateElementVector
(
op
,
elementVector
,
node
,
typename
Node
::
NodeTag
{},
FirstOrderType_
<
type
>
);
}
template
<
class
Operator
,
class
RowNode
,
class
ColNode
>
void
calculateElementMatrix
(
Operator
&
op
,
ElementMatrix
&
elementMatrix
,
RowNode
const
&
rowNode
,
ColNode
const
&
colNode
,
Dune
::
TypeTree
::
LeafNodeTag
,
Dune
::
TypeTree
::
LeafNodeTag
,
FirstOrderType_t
<
GRD_PHI
>
)
{
auto
const
&
rowLocalFE
=
rowNode
.
finiteElement
();
auto
const
&
colLocalFE
=
colNode
.
finiteElement
();
auto
const
&
quad
=
Super
::
getQuadrature
().
getRule
();
for
(
std
::
size_t
iq
=
0
;
iq
<
quad
.
size
();
++
iq
)
{
// Position of the current quadrature point in the reference element
decltype
(
auto
)
local
=
Super
::
getLocal
(
quad
[
iq
].
position
());
// The transposed inverse Jacobian of the map from the reference element to the element
const
auto
jacobian
=
Super
::
getGeometry
().
jacobianInverseTransposed
(
local
);
// The multiplicative factor in the integral transformation formula
const
double
factor
=
Super
::
getLocalGeometry
().
integrationElement
(
quad
[
iq
].
position
())
*
quad
[
iq
].
weight
()
*
factor_
;
std
::
vector
<
Dune
::
FieldVector
<
double
,
1
>
>
rowShapeValues
;
rowLocalFE
.
localBasis
().
evaluateFunction
(
local
,
rowShapeValues
);
// The gradients of the shape functions on the reference element
std
::
vector
<
Dune
::
FieldMatrix
<
double
,
1
,
dim
>
>
colReferenceGradients
;
colLocalFE
.
localBasis
().
evaluateJacobian
(
local
,
colReferenceGradients
);
// Compute the shape function gradients on the real element
std
::
vector
<
Dune
::
FieldVector
<
double
,
dow
>
>
colGradients
(
colReferenceGradients
.
size
());
for
(
std
::
size_t
i
=
0
;
i
<
colGradients
.
size
();
++
i
)
jacobian
.
mv
(
colReferenceGradients
[
i
][
0
],
colGradients
[
i
]);
for
(
std
::
size_t
i
=
0
;
i
<
rowLocalFE
.
size
();
++
i
)
{
for
(
std
::
size_t
j
=
0
;
j
<
colLocalFE
.
size
();
++
j
)
{
const
int
local_i
=
rowNode
.
localIndex
(
i
);
const
int
local_j
=
colNode
.
localIndex
(
j
);
op
.
eval
(
tag
::
fot_grd_phi
{},
elementMatrix
[
local_i
][
local_j
],
iq
,
factor
,
rowShapeValues
[
i
],
colGradients
[
j
]);
}
}
}
}
template
<
class
Operator
,
class
RowNode
,
class
ColNode
>
void
calculateElementMatrix
(
Operator
&
op
,
ElementMatrix
&
elementMatrix
,
RowNode
const
&
rowNode
,
ColNode
const
&
colNode
,
Dune
::
TypeTree
::
LeafNodeTag
,
Dune
::
TypeTree
::
LeafNodeTag
,
FirstOrderType_t
<
GRD_PSI
>
)
{
auto
const
&
rowLocalFE
=
rowNode
.
finiteElement
();
auto
const
&
colLocalFE
=
colNode
.
finiteElement
();
auto
const
&
quad
=
Super
::
getQuadrature
().
getRule
();
for
(
std
::
size_t
iq
=
0
;
iq
<
quad
.
size
();
++
iq
)
{
// Position of the current quadrature point in the reference element
decltype
(
auto
)
local
=
Super
::
getLocal
(
quad
[
iq
].
position
());
// The transposed inverse Jacobian of the map from the reference element to the element
const
auto
jacobian
=
Super
::
getGeometry
().
jacobianInverseTransposed
(
local
);
// The multiplicative factor in the integral transformation formula
const
double
factor
=
Super
::
getLocalGeometry
().
integrationElement
(
quad
[
iq
].
position
())
*
quad
[
iq
].
weight
()
*
factor_
;
// The gradients of the shape functions on the reference element
std
::
vector
<
Dune
::
FieldMatrix
<
double
,
1
,
dim
>
>
rowReferenceGradients
;
rowLocalFE
.
localBasis
().
evaluateJacobian
(
local
,
rowReferenceGradients
);
// Compute the shape function gradients on the real element
std
::
vector
<
Dune
::
FieldVector
<
double
,
dow
>
>
rowGradients
(
rowReferenceGradients
.
size
());
for
(
std
::
size_t
i
=
0
;
i
<
rowGradients
.
size
();
++
i
)
jacobian
.
mv
(
rowReferenceGradients
[
i
][
0
],
rowGradients
[
i
]);
std
::
vector
<
Dune
::
FieldVector
<
double
,
1
>
>
colShapeValues
;
colLocalFE
.
localBasis
().
evaluateFunction
(
local
,
colShapeValues
);
for
(
std
::
size_t
i
=
0
;
i
<
rowLocalFE
.
size
();
++
i
)
{
for
(
std
::
size_t
j
=
0
;
j
<
colLocalFE
.
size
();
++
j
)
{
const
int
local_i
=
rowNode
.
localIndex
(
i
);
const
int
local_j
=
colNode
.
localIndex
(
j
);
op
.
eval
(
tag
::
fot_grd_psi
{},
elementMatrix
[
local_i
][
local_j
],
iq
,
factor
,
rowGradients
[
i
],
colShapeValues
[
j
]);
}
}
}
}
template
<
class
Operator
,
class
RowNode
,
class
ColNode
>
void
calculateElementMatrix
(
Operator
&
op
,
ElementMatrix
&
elementMatrix
,
RowNode
const
&
rowNode
,
ColNode
const
&
colNode
,
Dune
::
TypeTree
::
LeafNodeTag
,
Dune
::
TypeTree
::
PowerNodeTag
,
FirstOrderType_t
<
GRD_PHI
>
)
{
auto
const
&
rowLocalFE
=
rowNode
.
finiteElement
();
auto
const
&
colLocalFE
=
colNode
.
child
(
0
).
finiteElement
();
auto
const
&
quad
=
Super
::
getQuadrature
().
getRule
();
test_exit
(
dow
==
degree
(
colNode
),
"Number of childs of Power-Node must be DOW"
);
for
(
std
::
size_t
iq
=
0
;
iq
<
quad
.
size
();
++
iq
)
{
// Position of the current quadrature point in the reference element
decltype
(
auto
)
local
=
Super
::
getLocal
(
quad
[
iq
].
position
());
// The transposed inverse Jacobian of the map from the reference element to the element
const
auto
jacobian
=
Super
::
getGeometry
().
jacobianInverseTransposed
(
local
);
// The multiplicative factor in the integral transformation formula
const
double
factor
=
Super
::
getLocalGeometry
().
integrationElement
(
quad
[
iq
].
position
())
*
quad
[
iq
].
weight
()
*
factor_
;
std
::
vector
<
Dune
::
FieldVector
<
double
,
1
>
>
rowShapeValues
;
rowLocalFE
.
localBasis
().
evaluateFunction
(
local
,
rowShapeValues
);
// The gradients of the shape functions on the reference element
std
::
vector
<
Dune
::
FieldMatrix
<
double
,
1
,
dim
>
>
colReferenceGradients
;
colLocalFE
.
localBasis
().
evaluateJacobian
(
local
,
colReferenceGradients
);
// Compute the shape function gradients on the real element
std
::
vector
<
Dune
::
FieldVector
<
double
,
dow
>
>
colGradients
(
colReferenceGradients
.
size
());
for
(
std
::
size_t
i
=
0
;
i
<
colGradients
.
size
();
++
i
)
jacobian
.
mv
(
colReferenceGradients
[
i
][
0
],
colGradients
[
i
]);
// <div(u), q>
for
(
std
::
size_t
i
=
0
;
i
<
rowLocalFE
.
size
();
++
i
)
{
const
int
local_i
=
rowNode
.
localIndex
(
i
);
for
(
std
::
size_t
j
=
0
;
j
<
colLocalFE
.
size
();
++
j
)
{
for
(
std
::
size_t
k
=
0
;
k
<
degree
(
colNode
);
++
k
)
{
const
int
local_j
=
colNode
.
child
(
k
).
localIndex
(
j
);
op
.
eval
(
tag
::
fot_grd_phi
{},
elementMatrix
[
local_i
][
local_j
],
iq
,
factor
,
rowShapeValues
[
i
],
colGradients
[
j
][
k
]);
}
}
}
}
}
template
<
class
Operator
,
class
RowNode
,
class
ColNode
>
void
calculateElementMatrix
(
Operator
&
op
,
ElementMatrix
&
elementMatrix
,
RowNode
const
&
rowNode
,
ColNode
const
&
colNode
,
Dune
::
TypeTree
::
PowerNodeTag
,
Dune
::
TypeTree
::
LeafNodeTag
,
FirstOrderType_t
<
GRD_PSI
>
)
{
auto
const
&
rowLocalFE
=
rowNode
.
child
(
0
).
finiteElement
();
auto
const
&
colLocalFE
=
colNode
.
finiteElement
();
auto
const
&
quad
=
Super
::
getQuadrature
().
getRule
();
test_exit
(
dow
==
degree
(
rowNode
),
"Number of childs of Power-Node must be DOW"
);
for
(
std
::
size_t
iq
=
0
;
iq
<
quad
.
size
();
++
iq
)
{
// Position of the current quadrature point in the reference element
decltype
(
auto
)
local
=
Super
::
getLocal
(
quad
[
iq
].
position
());
// The transposed inverse Jacobian of the map from the reference element to the element
const
auto
jacobian
=
Super
::
getGeometry
().
jacobianInverseTransposed
(
local
);
// The multiplicative factor in the integral transformation formula
const
double
factor
=
Super
::
getLocalGeometry
().
integrationElement
(
quad
[
iq
].
position
())
*
quad
[
iq
].
weight
()
*
factor_
;
// The gradients of the shape functions on the reference element
std
::
vector
<
Dune
::
FieldMatrix
<
double
,
1
,
dim
>
>
rowReferenceGradients
;
rowLocalFE
.
localBasis
().
evaluateJacobian
(
local
,
rowReferenceGradients
);
// Compute the shape function gradients on the real element
std
::
vector
<
Dune
::
FieldVector
<
double
,
dow
>
>
rowGradients
(
rowReferenceGradients
.
size
());
for
(
std
::
size_t
i
=
0
;
i
<
rowGradients
.
size
();
++
i
)
jacobian
.
mv
(
rowReferenceGradients
[
i
][
0
],
rowGradients
[
i
]);
std
::
vector
<
Dune
::
FieldVector
<
double
,
1
>
>
colShapeValues
;
colLocalFE
.
localBasis
().
evaluateFunction
(
local
,
colShapeValues
);
// <p, div(v)>
for
(
std
::
size_t
j
=
0
;
j
<
colLocalFE
.
size
();
++
j
)
{
const
int
local_j
=
colNode
.
localIndex
(
j
);
for
(
std
::
size_t
i
=
0
;
i
<
rowLocalFE
.
size
();
++
i
)
{
for
(
std
::
size_t
k
=
0
;
k
<
degree
(
rowNode
);
++
k
)
{
const
int
local_i
=
rowNode
.
child
(
k
).
localIndex
(
i
);
op
.
eval
(
tag
::
fot_grd_psi
{},
elementMatrix
[
local_i
][
local_j
],
iq
,
factor
,
rowGradients
[
i
][
k
],
colShapeValues
[
j
]);
}
}
}
}
}
template
<
class
Operator
,
class
RowNode
,
class
ColNode
,
class
RowNodeTag
,
class
ColNodeTag
,
class
FOT
>
void
calculateElementMatrix
(
Operator
&
,
ElementMatrix
&
,
RowNode
const
&
,
ColNode
const
&
,
RowNodeTag
,
ColNodeTag
,
FOT
)
{
warning
(
"FirstOrderAssembler::calculateElementMatrix not implemented for RowNode x ColNode"
);
}
template
<
class
Operator
,
class
Node
>
void
calculateElementVector
(
Operator
&
op
,
ElementVector
&
elementVector
,
Node
const
&
node
,
Dune
::
TypeTree
::
LeafNodeTag
,
FirstOrderType_t
<
GRD_PSI
>
)
{
auto
const
&
localFE
=
node
.
finiteElement
();
auto
const
&
quad
=
Super
::
getQuadrature
().
getRule
();
for
(
std
::
size_t
iq
=
0
;
iq
<
quad
.
size
();
++
iq
)
{
// Position of the current quadrature point in the reference element
decltype
(
auto
)
local
=
Super
::
getLocal
(
quad
[
iq
].
position
());
// The transposed inverse Jacobian of the map from the reference element to the element
const
auto
jacobian
=
Super
::
getGeometry
().
jacobianInverseTransposed
(
local
);
// The multiplicative factor in the integral transformation formula
const
double
factor
=
Super
::
getLocalGeometry
().
integrationElement
(
quad
[
iq
].
position
())
*
quad
[
iq
].
weight
()
*
factor_
;
// The gradients of the shape functions on the reference element
std
::
vector
<
Dune
::
FieldMatrix
<
double
,
1
,
dim
>
>
rowReferenceGradients
;
localFE
.
localBasis
().
evaluateJacobian
(
local
,
rowReferenceGradients
);
// Compute the shape function gradients on the real element
std
::
vector
<
Dune
::
FieldVector
<
double
,
dow
>
>
rowGradients
(
rowReferenceGradients
.
size
());
for
(
std
::
size_t
i
=
0
;
i
<
rowGradients
.
size
();
++
i
)
jacobian
.
mv
(
rowReferenceGradients
[
i
][
0
],
rowGradients
[
i
]);
for
(
std
::
size_t
i
=
0
;
i
<
localFE
.
size
();
++
i
)
{
const
int
local_i
=
node
.
localIndex
(
i
);
op
.
eval
(
tag
::
fot_grd_psi
{},
elementVector
[
local_i
],
iq
,
factor
,
rowGradients
[
i
]);
}
}
}
template
<
class
Operator
,
class
Node
,
class
NodeTag
,
class
FOT
>
void
calculateElementVector
(
Operator
&
,
ElementVector
&
,
Node
const
&
,
NodeTag
,
FOT
)
{
warning
(
"FirstOrderAssembler::calculateElementVector not implemented for Node"
);
}
private:
double
factor_
;
};
}
// end namespace AMDiS
dune/amdis/LocalAssembler.hpp
View file @
7e44b707
#pragma once
// std c++ headers
#include
<functional>
#include
<memory>
#include
<type_traits>
// AMDiS includes
#include
<dune/amdis/QuadratureRules.hpp>
#include
<dune/amdis/common/TypeDefs.hpp>
#include
<dune/geometry/quadraturerules.hh>
#include
<dune/amdis/ContextGeometry.hpp>
#include
<dune/amdis/LocalAssemblerBase.hpp>
#include
<dune/amdis/common/Concepts.hpp>
#include
<dune/amdis/utility/FiniteElementType.hpp>
namespace
AMDiS
{
//
the LocalContext is either an Codim=0-EntityType or an IntersectionTyp
e
template
<
class
GridView
,
class
LocalContext
>
//
/ Implementation of interface \ref LocalAssemblerBas
e
template
<
class
LocalContext
,
class
Operator
,
class
...
Nodes
>
class
LocalAssembler
:
public
LocalAssemblerBase
<
LocalContext
,
Nodes
...
>
{
static
constexpr
int
dim
=
GridView
::
dimension
;
using
ctype
=
typename
GridView
::
ctype
;
using
Super
=
LocalAssemblerBase
<
LocalContext
,
Nodes
...
>
;
private:
using
Element
=
typename
Super
::
Element
;
using
ElementMatrixVector
=
typename
Super
::
ElementMatrixVector
;
using
LocalQuadratureRules
=
Dune
::
QuadratureRules
<
ctype
,
LocalContext
::
mydimension
>
;
using
QuadratureRule
=
QuadratureRuleFactory_t
<
LocalContext
,
ctype
,
dim
>
;
using
Geometry
=
typename
Super
::
Geometry
;
using
LocalGeometry
=
typename
Super
::
LocalGeometry
;
using
Geometry
=
typename
GridView
::
template
Codim
<
0
>
::
Entity
::
Geometry
;
using
LocalGeometry
=
typename
Impl
::
Get
<
LocalContext
>::
Geometry
;
using
Context
=
ContextGeometry
<
LocalContext
,
Geometry
,
LocalGeometry
>
;
public:
explicit
LocalAssembler
(
int
degree
,
FirstOrderType
type
=
GRD_PHI
)
:
degree_
(
degree
)
,
type_
(
type
)
/// Constructor. Stores a copy of operator `op`.
explicit
LocalAssembler
(
Operator
const
&
op
)
:
opStorage_
(
std
::
make_unique
<
Operator
>
(
op
))
,
op_
(
*
opStorage_
)
{}
/// Constructor. Stores the reference to the operator.
explicit
LocalAssembler
(
std
::
reference_wrapper
<
Operator
>
const
&
op
)
:
op_
(
op
)
{}
/// Constructor, initializes the geometry of the element and a
/// quadrature-rule wrapper
template
<
class
Operator
>
void
bind
(
Operator
&
op
,
LocalContext
const
&
localContext
,
Geometry
const
&
geometry
,
LocalGeometry
const
&
localGeometry
)
/// \brief Implementation of \ref LocalAssemblerBase::bind.
/**
* Binds the operator `op_` to the `element` and `geometry` and
* stores point to the `element` and `geometry`.
**/
virtual
void
bind
(
Element
const
&
element
,
Geometry
const
&
geometry
)
final
{
localContext_
=
&
localContex
t
;
element_
=
&
elemen
t
;
geometry_
=
&
geometry
;
localGeometry_
=
&
localGeometry
;
int
order
=
op
.
getQuadratureDegree
(
localGeometry
.
type
(),
localGeometry
,
degree_
,
type_
);
auto
const
&
quad
=
LocalQuadratureRules
::
rule
(
localGeometry
.
type
(),
order
);
quadrature_
.
reset
(
new
QuadratureRule
(
localContext
,
quad
));
op_
.
bind
(
element
,
geometry
);
}
void
unbind
()
/// \brief Implementation of \ref LocalAssemblerBase::unbind
/**
* Unbinds the operator `op_` and sets \ref element_ and \ref geometry_
* to nullptr.
**/
virtual
void
unbind
()
final
{
localContext_
=
nullptr
;
op_
.
unbind
()
;
geometry_
=
nullptr
;
localGeometry
_
=
nullptr
;
element
_
=
nullptr
;
}
///
\brief Returns reference to the transformed quadrature ru
le
///
Implementation of \ref LocalAssemblerBase::assemb
le
/**
* For intersections this corresponds to the points in the intersection
* geometry, but coordinates extended to the whole inside-entity. For
* elements this is a wrapper around the classical element quadrature rule.
* Access the underlying dune-quadrature rule, with `quadrature->getRule()`.
* Provides a quadrature formula with necessary degree to integrate the operator,
* stores geometry and localGeometry and a \ref ContextGeometry and calls
* \ref calculateElementVector or \ref calculateElementMatrix on the
* vector or matrix operator, respectively.
*
* The call to operator passes two optimization flags:
* 1. RowNode and ColNode implement the same local finiteelement
* 2. RowNode and ColNode are the same node in the globalBasis tree.
**/
QuadratureRule
const
&
getQuadrature
()
const
virtual
bool
assemble
(
LocalContext
const
&
localContext
,
ElementMatrixVector
&
elementMatrixVector
,
Nodes
const
&
...
nodes
)
final
{
assert
(
quadrature_
);
return
*
quadrature_
;
decltype
(
auto
)
localGeometry
=
getLocalGeometry
(
localContext
);
using
QuadratureRules
=
Dune
::
QuadratureRules
<
typename
Geometry
::
ctype
,
LocalContext
::
mydimension
>
;
int
degree
=
op_
.
getDegree
(
nodes
...);
auto
const
&
quad
=
QuadratureRules
::
rule
(
localGeometry
.
type
(),
degree
);
Context
data
{
localContext
,
getGeometry
(),
localGeometry
};
assembleImpl
(
data
,
quad
,
elementMatrixVector
,
nodes
...);
return
true
;
}
#ifndef DOXYGEN
protected:
// implementation detail
// matrix assembling
template
<
class
QuadratureRule
,
class
ElementMatrix
,
class
RowNode
,
class
ColNode
>
void
assembleImpl
(
Context
const
&
context
,
QuadratureRule
const
&
quad
,
ElementMatrix
&
elementMatrix
,
RowNode
const
&
rowNode
,
ColNode
const
&
colNode
)
{
assembleImpl
(
context
,
quad
,
elementMatrix
,
rowNode
,
colNode
,
std
::
is_same
<
FiniteElementType_t
<
RowNode
>
,
FiniteElementType_t
<
ColNode
>>
{});
}
LocalContext
const
&
getLocalContext
()
const
// local finite elements are the same for rowNode and colNode
template
<
class
QuadratureRule
,
class
ElementMatrix
,
class
RowNode
,
class
ColNode
>
void
assembleImpl
(
Context
const
&
context
,
QuadratureRule
const
&
quad
,
ElementMatrix
&
elementMatrix
,
RowNode
const
&
rowNode
,
ColNode
const
&
colNode
,
std
::
true_type
/*sameFE*/
)
{
assert
(
localContext_
);
return
*
localContext_
;
if
(
rowNode
.
treeIndex
()
==
colNode
.
treeIndex
())
op_
.
calculateElementMatrix
(
context
,
quad
,
elementMatrix
,
rowNode
,
colNode
,
std
::
true_type
{},
std
::
true_type
{});
else
op_
.
calculateElementMatrix
(
context
,
quad
,
elementMatrix
,
rowNode
,
colNode
,
std
::
true_type
{},
std
::
false_type
{});
}
// local finite elements are different for rowNode and colNode
template
<
class
QuadratureRule
,
class
ElementMatrix
,
class
RowNode
,
class
ColNode
>
void
assembleImpl
(
Context
const
&