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
b01c33f7
Commit
b01c33f7
authored
Sep 07, 2018
by
Praetorius, Simon
Browse files
caching in local operators and dofvectors
parent
7d87fdfe
Changes
10
Hide whitespace changes
Inline
Side-by-side
examples/CMakeLists.txt
View file @
b01c33f7
...
...
@@ -20,4 +20,4 @@ foreach(project ${projects3d})
target_link_libraries
(
${
project
}
.3d amdis
)
target_compile_definitions
(
${
project
}
.3d PRIVATE AMDIS_DIM=3 AMDIS_DOW=3
)
add_dependencies
(
examples
${
project
}
.3d
)
endforeach
()
\ No newline at end of file
endforeach
()
examples/stokes3.cc
View file @
b01c33f7
...
...
@@ -32,7 +32,7 @@ int main(int argc, char** argv)
auto
_p
=
Dune
::
Indices
::
_1
;
auto
opStokes
=
makeOperator
(
tag
::
stokes
{},
viscosity
);
prob
.
addMatrixOperator
(
opStokes
,
treepath
(),
treepath
()
);
prob
.
addMatrixOperator
(
opStokes
);
auto
opZero
=
makeOperator
(
tag
::
test_trial
{},
0.0
);
prob
.
addMatrixOperator
(
opZero
,
_p
,
_p
);
...
...
src/amdis/LocalBasisCache.hpp
View file @
b01c33f7
...
...
@@ -2,117 +2,163 @@
#include
<vector>
#include
<dune/common/hash.hh>
#include
<dune/geometry/quadraturerules.hh>
#include
<dune/geometry/type.hh>
#include
<amdis/common/TupleUtility.hpp>
#include
<amdis/utility/ConcurrentCache.hpp>
namespace
AMDiS
{
namespace
Impl
template
<
class
LocalBasisType
>
class
LocalBasisCache
{
struct
HashableGeometryType
{
using
type
=
std
::
tuple
<
unsigned
int
,
unsigned
int
,
bool
>
;
type
value
;
public:
using
Traits
=
typename
LocalBasisType
::
Traits
;
HashableGeometryType
(
Dune
::
GeometryType
const
&
type
)
:
value
{
type
.
id
(),
type
.
dim
(),
type
.
isNone
()}
{}
using
DomainType
=
typename
Traits
::
DomainType
;
using
RangeType
=
typename
Traits
::
RangeType
;
using
RangeFieldType
=
typename
Traits
::
RangeFieldType
;
using
JacobianType
=
typename
Traits
::
JacobianType
;
friend
std
::
size_t
hash_value
(
HashableGeometryType
const
&
t
)
{
std
::
size_t
seed
=
0
;
Impl
::
HashTupleImpl
<
HashableGeometryType
::
type
>::
apply
(
seed
,
t
.
value
);
return
seed
;
}
using
QuadratureRule
=
Dune
::
QuadratureRule
<
RangeFieldType
,
Traits
::
dimDomain
>
;
using
QuadratureRules
=
Dune
::
QuadratureRules
<
RangeFieldType
,
Traits
::
dimDomain
>
;
friend
bool
operator
==
(
HashableGeometryType
const
&
lhs
,
HashableGeometryType
const
&
rhs
)
{
return
lhs
.
value
==
rhs
.
value
;
}
};
private:
/// Pair of GeometryType and quadrature order and size
template
<
class
LocalBasisType
,
class
Tag
>
struct
LocalBasisCache
Key
template
<
class
Tag
>
struct
Quad
Key
{
using
type
=
std
::
tuple
<
HashableGeometryType
,
int
,
int
>
;
type
value
;
unsigned
int
id
;
// topologyId
int
p
;
// quadrature order
std
::
size_t
size
;
// number of quadrature points
friend
std
::
size_t
hash_value
(
LocalBasisCacheKey
const
&
t
)
struct
hasher
{
std
::
size_t
seed
=
0
;
Impl
::
HashTupleImpl
<
LocalBasisCacheKey
::
type
>::
apply
(
seed
,
t
.
value
);
return
seed
;
std
::
size_t
operator
()(
QuadKey
const
&
t
)
const
{
std
::
size_t
seed
=
0
;
Dune
::
hash_combine
(
seed
,
t
.
id
);
Dune
::
hash_combine
(
seed
,
t
.
p
);
Dune
::
hash_combine
(
seed
,
t
.
size
);
return
seed
;
}
};
friend
bool
operator
==
(
QuadKey
const
&
lhs
,
QuadKey
const
&
rhs
)
{
return
std
::
tie
(
lhs
.
id
,
lhs
.
p
,
lhs
.
size
)
==
std
::
tie
(
rhs
.
id
,
rhs
.
p
,
rhs
.
size
);
}
};
/// Pair of GeometryType and local coordinates
template
<
class
Tag
>
struct
CoordsKey
{
unsigned
int
id
;
// topologyId
DomainType
local
;
// local coordinate
friend
bool
operator
==
(
LocalBasisCacheKey
const
&
lhs
,
LocalBasisCacheKey
const
&
rhs
)
struct
hasher
{
std
::
size_t
operator
()(
CoordsKey
const
&
t
)
const
{
std
::
size_t
seed
=
0
;
Dune
::
hash_combine
(
seed
,
t
.
id
);
Dune
::
hash_range
(
seed
,
t
.
local
.
begin
(),
t
.
local
.
end
());
return
seed
;
}
};
friend
bool
operator
==
(
CoordsKey
const
&
lhs
,
CoordsKey
const
&
rhs
)
{
return
lhs
.
value
==
rhs
.
value
;
return
std
::
tie
(
lhs
.
id
,
lhs
.
local
)
==
std
::
tie
(
rhs
.
id
,
rhs
.
local
)
;
}
};
}
}
// end namespace AMDiS
DUNE_DEFINE_STD_HASH
(
,
AMDiS
::
Impl
::
HashableGeometryType
)
DUNE_DEFINE_HASH
(
DUNE_HASH_TEMPLATE_ARGS
(
class
LocalBasisType
,
class
Tag
),
DUNE_HASH_TYPE
(
AMDiS
::
Impl
::
LocalBasisCacheKey
<
LocalBasisType
,
Tag
>
))
using
LocalValuesKey
=
CoordsKey
<
struct
ValuesTag
>
;
using
LocalGradientsKey
=
CoordsKey
<
struct
Gradients
Tag
>
;
namespace
AMDiS
{
template
<
class
LocalBasisType
>
class
LocalBasisCache
{
public:
using
Traits
=
typename
LocalBasisType
::
Traits
;
using
RangeType
=
typename
Traits
::
RangeType
;
using
RangeFieldType
=
typename
Traits
::
RangeFieldType
;
using
JacobianType
=
typename
Traits
::
JacobianType
;
using
ValuesKey
=
QuadKey
<
struct
ValuesTag
>
;
using
GradientsKey
=
QuadKey
<
struct
GradientsTag
>
;
using
QuadratureRules
=
Dune
::
QuadratureRules
<
RangeFieldType
,
Traits
::
dimDomain
>
;
public:
using
ShapeValues
=
std
::
vector
<
RangeType
>
;
using
ShapeGradients
=
std
::
vector
<
JacobianType
>
;
private:
using
ValuesKey
=
Impl
::
LocalBasisCacheKey
<
LocalBasisType
,
struct
ValuesTag
>
;
using
GradientsKey
=
Impl
::
LocalBasisCacheKey
<
LocalBasisType
,
struct
GradientsTag
>
;
using
Policy
=
tag
::
thread_local_policy
;
using
ShapeValuesContainer
=
std
::
vector
<
ShapeValues
>
;
using
ShapeGradientsContainer
=
std
::
vector
<
ShapeGradients
>
;
public:
using
ShapeValuesContainer
=
std
::
vector
<
std
::
vector
<
RangeType
>>
;
using
ShapeGradientsContainer
=
std
::
vector
<
std
::
vector
<
JacobianType
>>
;
LocalBasisCache
(
LocalBasisType
const
&
localBasis
)
:
localBasis_
(
&
localBasis
)
{}
template
<
class
LocalContext
,
class
QuadratureRule
>
ShapeValuesContainer
const
&
values
(
LocalContext
const
&
context
,
QuadratureRule
const
&
quad
)
// evaluate local basis-function at all quadrature points
template
<
class
LocalContext
>
ShapeValuesContainer
const
&
evaluateFunctionAtQp
(
LocalContext
const
&
context
,
QuadratureRule
const
&
quad
)
const
{
ValuesKey
key
{
typename
ValuesKey
::
type
{
context
.
type
(),
quad
.
order
(),
quad
.
size
()}
}
;
return
ShapeValuesCache
::
get
(
key
,
[
&
](
ShapeValuesContainer
*
data
,
ValuesKey
const
&
)
ValuesKey
key
{
context
.
type
()
.
id
()
,
quad
.
order
(),
quad
.
size
()};
return
ShapeValuesC
ontainerC
ache
::
get
(
key
,
[
&
](
ValuesKey
const
&
)
{
data
->
resize
(
quad
.
size
());
ShapeValuesContainer
data
(
quad
.
size
());
for
(
std
::
size_t
iq
=
0
;
iq
<
quad
.
size
();
++
iq
)
localBasis_
->
evaluateFunction
(
context
.
local
(
quad
[
iq
].
position
()),
(
*
data
)[
iq
]);
localBasis_
->
evaluateFunction
(
context
.
local
(
quad
[
iq
].
position
()),
data
[
iq
]);
return
data
;
});
}
template
<
class
LocalContext
,
class
QuadratureRule
>
ShapeGradientsContainer
const
&
gradients
(
LocalContext
const
&
context
,
QuadratureRule
const
&
quad
)
// evaluate local basis-gradients at all quadrature points
template
<
class
LocalContext
>
ShapeGradientsContainer
const
&
evaluateJacobianAtQp
(
LocalContext
const
&
context
,
QuadratureRule
const
&
quad
)
const
{
GradientsKey
key
{
typename
GradientsKey
::
type
{
context
.
type
(),
quad
.
order
(),
quad
.
size
()}
}
;
return
ShapeGradientsCache
::
get
(
key
,
[
&
](
ShapeGradientsContainer
*
data
,
GradientsKey
const
&
)
GradientsKey
key
{
context
.
type
()
.
id
()
,
quad
.
order
(),
quad
.
size
()};
return
ShapeGradientsC
ontainerC
ache
::
get
(
key
,
[
&
](
GradientsKey
const
&
)
{
data
->
resize
(
quad
.
size
());
ShapeGradientsContainer
data
(
quad
.
size
());
for
(
std
::
size_t
iq
=
0
;
iq
<
quad
.
size
();
++
iq
)
localBasis_
->
evaluateJacobian
(
context
.
local
(
quad
[
iq
].
position
()),
(
*
data
)[
iq
]);
localBasis_
->
evaluateJacobian
(
context
.
local
(
quad
[
iq
].
position
()),
data
[
iq
]);
return
data
;
});
}
// evaluate local basis-function at point
template
<
class
Element
>
ShapeValues
const
&
evaluateFunction
(
Element
const
&
element
,
DomainType
const
&
local
)
const
{
LocalValuesKey
key
{
element
.
type
().
id
(),
local
};
return
ShapeValuesCache
::
get
(
key
,
[
&
](
LocalValuesKey
const
&
)
{
ShapeValues
data
;
localBasis_
->
evaluateFunction
(
local
,
data
);
return
data
;
});
}
// evaluate local basis-gradients at point
template
<
class
Element
>
ShapeGradients
const
&
evaluateJacobian
(
Element
const
&
element
,
DomainType
const
&
local
)
const
{
LocalGradientsKey
key
{
element
.
type
().
id
(),
local
};
return
ShapeGradientsCache
::
get
(
key
,
[
&
](
LocalGradientsKey
const
&
)
{
ShapeGradients
data
;
localBasis_
->
evaluateJacobian
(
local
,
data
);
return
data
;
});
}
private:
using
ShapeValuesCache
=
ConcurrentCache
<
ValuesKey
,
ShapeValuesContainer
,
Policy
>
;
using
ShapeGradientsCache
=
ConcurrentCache
<
GradientsKey
,
ShapeGradientsContainer
,
Policy
>
;
using
ShapeValuesCache
=
ConcurrentCache
<
LocalValuesKey
,
ShapeValues
,
ThreadLocalPolicy
,
std
::
unordered_map
<
LocalValuesKey
,
ShapeValues
,
typename
LocalValuesKey
::
hasher
>>
;
using
ShapeGradientsCache
=
ConcurrentCache
<
LocalGradientsKey
,
ShapeGradients
,
ThreadLocalPolicy
,
std
::
unordered_map
<
LocalGradientsKey
,
ShapeGradients
,
typename
LocalGradientsKey
::
hasher
>>
;
using
ShapeValuesContainerCache
=
ConcurrentCache
<
ValuesKey
,
ShapeValuesContainer
,
ThreadLocalPolicy
,
std
::
unordered_map
<
ValuesKey
,
ShapeValuesContainer
,
typename
ValuesKey
::
hasher
>>
;
using
ShapeGradientsContainerCache
=
ConcurrentCache
<
GradientsKey
,
ShapeGradientsContainer
,
ThreadLocalPolicy
,
std
::
unordered_map
<
GradientsKey
,
ShapeGradientsContainer
,
typename
GradientsKey
::
hasher
>>
;
LocalBasisType
const
*
localBasis_
;
};
...
...
src/amdis/LocalBasisEvaluatorCache.hpp
0 → 100644
View file @
b01c33f7
#pragma once
#include
<vector>
#include
<dune/geometry/quadraturerules.hh>
#include
<dune/geometry/type.hh>
#include
<amdis/LocalBasisCache.hpp>
#include
<amdis/common/TupleUtility.hpp>
#include
<amdis/utility/ConcurrentCache.hpp>
namespace
AMDiS
{
namespace
Impl
{
/// Pair of GeometryType and quadrature order and size
template
<
class
LocalBasisType
,
class
Tag
>
struct
EvaluatorCacheKey
{
using
type
=
std
::
tuple
<
HashableGeometryType
,
typename
LocalBasisType
::
Traits
::
DomainType
>
;
type
value
;
friend
std
::
size_t
hash_value
(
EvaluatorCacheKey
const
&
t
)
{
std
::
size_t
seed
=
hash_value
(
std
::
get
<
0
>
(
t
.
value
));
Dune
::
hash_range
(
seed
,
std
::
get
<
1
>
(
t
.
value
).
begin
(),
std
::
get
<
1
>
(
t
.
value
).
end
());
return
seed
;
}
friend
bool
operator
==
(
EvaluatorCacheKey
const
&
lhs
,
EvaluatorCacheKey
const
&
rhs
)
{
return
lhs
.
value
==
rhs
.
value
;
}
};
}
}
// end namespace AMDiS
DUNE_DEFINE_HASH
(
DUNE_HASH_TEMPLATE_ARGS
(
class
LocalBasisType
,
class
Tag
),
DUNE_HASH_TYPE
(
AMDiS
::
Impl
::
EvaluatorCacheKey
<
LocalBasisType
,
Tag
>
))
namespace
AMDiS
{
template
<
class
LocalBasisType
>
class
LocalBasisEvaluatorCache
{
public:
using
Traits
=
typename
LocalBasisType
::
Traits
;
using
DomainType
=
typename
Traits
::
DomainType
;
using
RangeType
=
typename
Traits
::
RangeType
;
using
RangeFieldType
=
typename
Traits
::
RangeFieldType
;
using
JacobianType
=
typename
Traits
::
JacobianType
;
using
QuadratureRule
=
Dune
::
QuadratureRule
<
RangeFieldType
,
Traits
::
dimDomain
>
;
using
QuadratureRules
=
Dune
::
QuadratureRules
<
RangeFieldType
,
Traits
::
dimDomain
>
;
private:
using
ValuesKey
=
Impl
::
EvaluatorCacheKey
<
LocalBasisType
,
struct
ValuesTag
>
;
using
GradientsKey
=
Impl
::
EvaluatorCacheKey
<
LocalBasisType
,
struct
GradientsTag
>
;
using
Policy
=
tag
::
thread_local_policy
;
public:
using
ShapeValues
=
std
::
vector
<
RangeType
>
;
using
ShapeGradients
=
std
::
vector
<
JacobianType
>
;
LocalBasisEvaluatorCache
(
LocalBasisType
const
&
localBasis
)
:
localBasis_
(
&
localBasis
)
{}
template
<
class
LocalContext
>
ShapeValues
const
&
evaluateFunction
(
LocalContext
const
&
context
,
DomainType
const
&
local
)
{
ValuesKey
key
{
typename
ValuesKey
::
type
{
context
.
type
(),
local
}};
return
ShapeValuesCache
::
get
(
key
,
[
&
](
ShapeValues
*
data
,
ValuesKey
const
&
)
{
localBasis_
->
evaluateFunction
(
local
,
*
data
);
});
}
template
<
class
LocalContext
>
ShapeGradients
const
&
evaluateJacobian
(
LocalContext
const
&
context
,
DomainType
const
&
local
)
{
GradientsKey
key
{
typename
GradientsKey
::
type
{
context
.
type
(),
local
}};
return
ShapeGradientsCache
::
get
(
key
,
[
&
](
ShapeGradients
*
data
,
GradientsKey
const
&
)
{
localBasis_
->
evaluateJacobian
(
local
,
*
data
);
});
}
private:
using
ShapeValuesCache
=
ConcurrentCache
<
ValuesKey
,
ShapeValues
,
Policy
>
;
using
ShapeGradientsCache
=
ConcurrentCache
<
GradientsKey
,
ShapeGradients
,
Policy
>
;
LocalBasisType
const
*
localBasis_
;
};
}
// end namespace AMDiS
src/amdis/assembler/ConvectionDiffusionOperator.hpp
View file @
b01c33f7
...
...
@@ -56,16 +56,14 @@ namespace AMDiS
"Galerkin operator requires equal finite elements for test and trial space."
);
using
LocalBasisType
=
typename
FiniteElementType_t
<
RowNode
>::
Traits
::
LocalBasisType
;
using
RangeType
=
typename
LocalBasisType
::
Traits
::
RangeType
;
using
RangeFieldType
=
typename
LocalBasisType
::
Traits
::
RangeFieldType
;
using
JacobianType
=
typename
LocalBasisType
::
Traits
::
JacobianType
;
auto
localFctA
=
localFunction
(
gridFctA_
);
localFctA
.
bind
(
context
.
element
());
auto
localFctB
=
localFunction
(
gridFctB_
);
localFctB
.
bind
(
context
.
element
());
auto
localFctC
=
localFunction
(
gridFctC_
);
localFctC
.
bind
(
context
.
element
());
auto
const
&
localFE
=
rowNode
.
finiteElement
();
std
::
size_t
numLocalFe
=
localFE
.
size
();
int
quadDeg
=
std
::
max
({
this
->
getDegree
(
2
,
coeffOrder
(
localFctA
),
rowNode
,
colNode
),
this
->
getDegree
(
1
,
coeffOrder
(
localFctB
),
rowNode
,
colNode
),
...
...
@@ -74,23 +72,25 @@ namespace AMDiS
using
QuadratureRules
=
Dune
::
QuadratureRules
<
typename
Context
::
Geometry
::
ctype
,
Context
::
LocalContext
::
mydimension
>
;
auto
const
&
quad
=
QuadratureRules
::
rule
(
context
.
type
(),
quadDeg
);
for
(
auto
const
&
qp
:
quad
)
{
LocalBasisCache
<
LocalBasisType
>
cache
(
localFE
.
localBasis
());
auto
const
&
shapeGradientsCache
=
cache
.
evaluateJacobianAtQp
(
context
,
quad
);
auto
const
&
shapeValuesCache
=
cache
.
evaluateFunctionAtQp
(
context
,
quad
);
for
(
std
::
size_t
iq
=
0
;
iq
<
quad
.
size
();
++
iq
)
{
// Position of the current quadrature point in the reference element
decltype
(
auto
)
local
=
context
.
local
(
q
p
.
position
());
decltype
(
auto
)
local
=
context
.
local
(
q
uad
[
iq
]
.
position
());
// The transposed inverse Jacobian of the map from the reference element to the element
const
auto
jacobian
=
context
.
geometry
().
jacobianInverseTransposed
(
local
);
// The multiplicative factor in the integral transformation formula
const
auto
factor
=
context
.
integrationElement
(
q
p
.
position
())
*
q
p
.
weight
();
const
auto
factor
=
context
.
integrationElement
(
q
uad
[
iq
]
.
position
())
*
q
uad
[
iq
]
.
weight
();
// the values of the shape functions on the reference element at the quadrature point
thread_local
std
::
vector
<
RangeType
>
shapeValues
;
localFE
.
localBasis
().
evaluateFunction
(
local
,
shapeValues
);
auto
const
&
shapeValues
=
shapeValuesCache
[
iq
];
// The gradients of the shape functions on the reference element
thread_local
std
::
vector
<
JacobianType
>
shapeGradients
;
localFE
.
localBasis
().
evaluateJacobian
(
local
,
shapeGradients
);
auto
const
&
shapeGradients
=
shapeGradientsCache
[
iq
];
// Compute the shape function gradients on the real element
using
WorldVector
=
FieldVector
<
RangeFieldType
,
Context
::
dow
>
;
...
...
@@ -106,22 +106,22 @@ namespace AMDiS
IF_CONSTEXPR
(
conserving
)
{
WorldVector
gradAi
,
gradBi
;
for
(
std
::
size_t
i
=
0
;
i
<
l
ocalF
E
.
size
()
;
++
i
)
{
for
(
std
::
size_t
i
=
0
;
i
<
numL
ocalF
e
;
++
i
)
{
const
int
local_i
=
rowNode
.
localIndex
(
i
);
gradAi
=
A
*
gradients
[
i
];
gradBi
=
b
*
gradients
[
i
];
for
(
std
::
size_t
j
=
0
;
j
<
l
ocalF
E
.
size
()
;
++
j
)
{
for
(
std
::
size_t
j
=
0
;
j
<
numL
ocalF
e
;
++
j
)
{
const
int
local_j
=
colNode
.
localIndex
(
j
);
elementMatrix
[
local_i
][
local_j
]
+=
(
dot
(
gradAi
,
gradients
[
j
])
+
(
c
*
shapeValues
[
i
]
-
gradBi
)
*
shapeValues
[
j
])
*
factor
;
}
}
}
else
{
WorldVector
grad_i
;
for
(
std
::
size_t
i
=
0
;
i
<
l
ocalF
E
.
size
()
;
++
i
)
{
for
(
std
::
size_t
i
=
0
;
i
<
numL
ocalF
e
;
++
i
)
{
const
int
local_i
=
rowNode
.
localIndex
(
i
);
grad_i
=
A
*
gradients
[
i
];
grad_i
+=
b
*
shapeValues
[
i
];
for
(
std
::
size_t
j
=
0
;
j
<
l
ocalF
E
.
size
()
;
++
j
)
{
for
(
std
::
size_t
j
=
0
;
j
<
numL
ocalF
e
;
++
j
)
{
const
int
local_j
=
colNode
.
localIndex
(
j
);
elementMatrix
[
local_i
][
local_j
]
+=
(
dot
(
grad_i
,
gradients
[
j
])
+
c
*
shapeValues
[
i
]
*
shapeValues
[
j
])
*
factor
;
}
...
...
@@ -143,33 +143,34 @@ namespace AMDiS
static_assert
(
Node
::
isLeaf
,
"Operator can be applied to Leaf-Nodes only."
);
using
Range
Type
=
typename
FiniteElementType_t
<
Node
>::
Traits
::
LocalBasisType
::
Traits
::
RangeType
;
using
LocalBasis
Type
=
typename
FiniteElementType_t
<
Node
>::
Traits
::
LocalBasisType
;
auto
localFctF
=
localFunction
(
gridFctF_
);
localFctF
.
bind
(
context
.
element
());
auto
const
&
localFE
=
node
.
finiteElement
();
std
::
size_t
numLocalFe
=
localFE
.
size
();
int
quad_order
=
this
->
getDegree
(
0
,
coeffOrder
(
localFctF
),
node
);
using
QuadratureRules
=
Dune
::
QuadratureRules
<
typename
Context
::
Geometry
::
ctype
,
Context
::
LocalContext
::
dimension
>
;
auto
const
&
quad
=
QuadratureRules
::
rule
(
context
.
type
(),
quad_order
);
for
(
auto
const
&
qp
:
quad
)
{
// Position of the current quadrature point in the reference element
decltype
(
auto
)
local
=
context
.
local
(
qp
.
position
());
LocalBasisCache
<
LocalBasisType
>
cache
(
localFE
.
localBasis
());
auto
const
&
shapeValuesCache
=
cache
.
evaluateFunctionAtQp
(
context
,
quad
);
// The multiplicative factor in the integral transformation formula
const
auto
factor
=
context
.
integrationElement
(
qp
.
position
())
*
qp
.
weight
();
for
(
std
::
size_t
iq
=
0
;
iq
<
quad
.
size
();
++
iq
)
{
// Position of the current quadrature point in the reference element
decltype
(
auto
)
local
=
context
.
local
(
quad
[
iq
].
position
());
// the values of the shape functions on the reference element at the quadrature point
std
::
vector
<
RangeType
>
shapeValues
;
localFE
.
localBasis
().
evaluateFunction
(
local
,
shapeValues
);
auto
const
&
shapeValues
=
shapeValuesCache
[
iq
];
const
auto
f
=
localFctF
(
local
);
// The multiplicative factor in the integral transformation formula
const
auto
factor
=
localFctF
(
local
)
*
context
.
integrationElement
(
quad
[
iq
].
position
())
*
quad
[
iq
].
weight
();
for
(
std
::
size_t
i
=
0
;
i
<
l
ocalF
E
.
size
()
;
++
i
)
{
for
(
std
::
size_t
i
=
0
;
i
<
numL
ocalF
e
;
++
i
)
{
const
int
local_i
=
node
.
localIndex
(
i
);
elementVector
[
local_i
]
+=
f
*
shapeValues
[
i
]
*
factor
;
elementVector
[
local_i
]
+=
shapeValues
[
i
]
*
factor
;
}
}
...
...
src/amdis/assembler/SecondOrderGradTestGradTrial.hpp
View file @
b01c33f7
...
...
@@ -119,7 +119,7 @@ namespace AMDiS
using
RangeFieldType
=
typename
LocalBasisType
::
Traits
::
RangeFieldType
;
LocalBasisCache
<
LocalBasisType
>
cache
(
localFE
.
localBasis
());
auto
const
&
shapeGradientsCache
=
cache
.
gradients
(
context
,
quad
);
auto
const
&
shapeGradientsCache
=
cache
.
evaluateJacobianAtQp
(
context
,
quad
);
for
(
std
::
size_t
iq
=
0
;
iq
<
quad
.
size
();
++
iq
)
{
// Position of the current quadrature point in the reference element
decltype
(
auto
)
local
=
context
.
local
(
quad
[
iq
].
position
());
...
...
src/amdis/assembler/StokesOperator.hpp
View file @
b01c33f7
...
...
@@ -48,7 +48,10 @@ namespace AMDiS
using
namespace
Dune
::
Indices
;
auto
const
&
velocityLocalFE
=
tree
.
child
(
_0
,
0
).
finiteElement
();
std
::
size_t
numVelocityLocalFE
=
velocityLocalFE
.
size
();
auto
const
&
pressureLocalFE
=
tree
.
child
(
_1
).
finiteElement
();
std
::
size_t
numPressureLocalFE
=
pressureLocalFE
.
size
();
using
VelocityLocalBasisType
=
typename
std
::
decay_t
<
decltype
(
velocityLocalFE
)
>::
Traits
::
LocalBasisType
;
using
PressureLocalBasisType
=
typename
std
::
decay_t
<
decltype
(
pressureLocalFE
)
>::
Traits
::
LocalBasisType
;
...
...
@@ -56,14 +59,13 @@ namespace AMDiS
LocalBasisCache
<
VelocityLocalBasisType
>
velocityCache
(
velocityLocalFE
.
localBasis
());
LocalBasisCache
<
PressureLocalBasisType
>
pressureCache
(
pressureLocalFE
.
localBasis
());
using
PressureRange
=
typename
PressureLocalBasisType
::
Traits
::
RangeType
;
using
RangeFieldType
=
typename
VelocityLocalBasisType
::
Traits
::
RangeFieldType
;
using
VelocityJacobian
=
typename
VelocityLocalBasisType
::
Traits
::
JacobianType
;
auto
const
&
quad
=
this
->
getQuadratureRule
(
context
.
type
(),
tree
,
tree
);
auto
const
&
shapeGradientsCache
=
velocityCache
.
gradients
(
context
,
quad
);
auto
const
&
pressureValuesCache
=
pressureCache
.
values
(
context
,
quad
);
auto
const
&
shapeGradientsCache
=
velocityCache
.
evaluateJacobianAtQp
(
context
,
quad
);
auto
const
&
pressureValuesCache
=
pressureCache
.
evaluateFunctionAtQp
(
context
,
quad
);
for
(
std
::
size_t
iq
=
0
;
iq
<
quad
.
size
();
++
iq
)
{
// Position of the current quadrature point in the reference element
...
...
@@ -87,14 +89,14 @@ namespace AMDiS
auto
const
&
pressureValues
=
pressureValuesCache
[
iq
];
// <viscosity * grad(u), grad(v)>
for
(
std
::
size_t
i
=
0
;
i
<
v
elocityLocalFE
.
size
()
;
++
i
)
{
for
(
std
::
size_t
i
=
0
;
i
<
numV
elocityLocalFE
;
++
i
)
{
const
auto
value_ii
=
vel_factor
*
(
gradients
[
i
]
*
gradients
[
i
]);
for
(
std
::
size_t
k
=
0
;
k
<
Context
::
dow
;
++
k
)
{
const
auto
local_ki
=
tree
.
child
(
_0
,
k
).
localIndex
(
i
);
elementMatrix
[
local_ki
][
local_ki
]
+=
value_ii
;
}
for
(
std
::
size_t
j
=
i
+
1
;
j
<
v
elocityLocalFE
.
size
()
;
++
j
)
{
for
(
std
::
size_t
j
=
i
+
1
;
j
<
numV
elocityLocalFE
;
++
j
)
{
const
auto
value
=
vel_factor
*
(
gradients
[
i
]
*
gradients
[
j
]);
for
(
std
::
size_t
k
=
0
;
k
<
Context
::
dow
;
++
k
)
{
const
auto
local_ki
=
tree
.
child
(
_0
,
k
).
localIndex
(
i
);
...
...
@@ -106,8 +108,8 @@ namespace AMDiS
}
// <p, div(v)> + <div(u), q>
for
(
std
::
size_t
i
=
0
;
i
<
v
elocityLocalFE
.
size
()
;
++
i
)
{
for
(
std
::
size_t
j
=
0
;
j
<
p
ressureLocalFE
.
size
()
;
++
j
)
{
for
(
std
::
size_t
i
=
0
;
i
<
numV
elocityLocalFE
;
++
i
)
{
for
(
std
::
size_t
j
=
0
;
j
<
numP
ressureLocalFE
;
++
j
)
{
const
auto
value
=
factor
*
pressureValues
[
j
];
for
(
std
::
size_t
k
=
0
;
k
<
Context
::
dow
;
++
k
)
{
const
auto
local_v
=
tree
.
child
(
_0
,
k
).
localIndex
(
i
);
...
...
src/amdis/assembler/ZeroOrderTest.hpp
View file @
b01c33f7
...
...
@@ -48,7 +48,7 @@ namespace AMDiS
LocalBasisCache
<
LocalBasisType
>
cache
(
localFE
.
localBasis
());
auto
const
&
quad
=
this
->
getQuadratureRule
(
context
.
type
(),
node
);
auto
const
&
shapeValuesCache
=
cache
.
valu
es
(
context
,
quad
);
auto
const
&
shapeValuesCache
=
cache
.
e
valu
ateFunctionAtQp
(
context
,
quad
);
for
(
std
::
size_t
iq
=
0
;
iq
<
quad
.
size
();
++
iq
)
{
// Position of the current quadrature point in the reference element
decltype
(
auto
)
local
=
context
.
local
(
quad
[
iq
].
position
());
...
...
src/amdis/gridfunctions/DOFVectorView.inc.hpp
View file @
b01c33f7
#pragma once
#include
<amdis/common/FieldMatVec.hpp>
#include
<amdis/LocalBasisCache.hpp>
namespace
AMDiS
{
...
...
@@ -18,8 +19,8 @@ LocalFunction::operator()(LocalDomain const& x) const
auto
&&
fe
=
node
.
finiteElement
();
auto
&&
localBasis
=
fe
.
localBasis
();
auto
&&
shapeFunctionValues
=
shapeFunctionValueContainer_
[
node
]
;
localBasis
.
evaluateFunction
(
x
,
shapeFunctionValues
);
LocalBasisCache
<
std
::
decay_t
<
decltype
(
localBasis
)
>>
localBasisCache
(
localBasis
)
;
auto
const
&
shapeFunctionValues
=
localBasis
Cache
.
evaluateFunction
(
localView_
.
element
(),
x
);
// Get range entry associated to this node
auto
re
=
Dune
::
Functions
::
flatVectorView
(
nodeToRangeEntry
(
node
,
tp
,
y
));
...
...
@@ -68,12 +69,12 @@ GradientLocalFunction::operator()(LocalDomain const& x) const
auto
&&
fe
=
node
.
finiteElement
();
auto
&&
localBasis
=
fe
.
localBasis
();
LocalBasisCache
<
std
::
decay_t
<
decltype
(
localBasis
)
>>
localBasisCache
(
localBasis
);
auto
const
&
referenceGradients
=
localBasisCache
.
evaluateJacobian
(
localView_
.
element
(),
x
);
// The transposed inverse Jacobian of the map from the reference element to the element
auto
&&
jacobian
=
geometry_
.
value
().
jacobianInverseTransposed
(
x
);
auto
&&
referenceGradients
=
referenceGradientContainer_
[
node
];
localBasis
.
evaluateJacobian
(
x
,
referenceGradients
);
// Compute the shape function gradients on the real element
std
::
vector
<
GradientBlock
>
gradients
(
referenceGradients
.
size
());
for
(
std
::
size_t
i
=
0
;
i
<
gradients
.
size
();
++
i
)
...
...