Skip to content
Snippets Groups Projects
Commit a9b8972a authored by Patrick Jaap's avatar Patrick Jaap
Browse files

Merge branch 'feature/dune-functions-operator-assembler-same-bases' into 'master'

DuneFunctionsOperatorAssembler: use one localView twice if bases are the same

See merge request !80
parents 858252b4 b18fce9a
Branches
No related tags found
1 merge request!80DuneFunctionsOperatorAssembler: use one localView twice if bases are the same
Pipeline #30846 passed
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
#ifndef DUNE_FUFEM_ASSEMBLERS_DUNEFUNCTIONSOPERATORASSEMBLER_HH #ifndef DUNE_FUFEM_ASSEMBLERS_DUNEFUNCTIONSOPERATORASSEMBLER_HH
#define DUNE_FUFEM_ASSEMBLERS_DUNEFUNCTIONSOPERATORASSEMBLER_HH #define DUNE_FUFEM_ASSEMBLERS_DUNEFUNCTIONSOPERATORASSEMBLER_HH
#include <type_traits>
#include <dune/istl/matrix.hh> #include <dune/istl/matrix.hh>
#include <dune/istl/matrixindexset.hh> #include <dune/istl/matrixindexset.hh>
...@@ -37,15 +39,15 @@ public: ...@@ -37,15 +39,15 @@ public:
{ {
patternBuilder.resize(trialBasis_, ansatzBasis_); patternBuilder.resize(trialBasis_, ansatzBasis_);
auto trialLocalView = trialBasis_.localView(); // create two localViews but use only one if bases are the same
auto ansatzLocalView = ansatzBasis_.localView(); auto ansatzLocalView = ansatzBasis_.localView();
auto seperateTrialLocalView = trialBasis_.localView();
auto& trialLocalView = selectTrialLocalView(ansatzLocalView, seperateTrialLocalView);
for (const auto& element : elements(trialBasis_.gridView())) for (const auto& element : elements(trialBasis_.gridView()))
{ {
trialLocalView.bind(element); // bind the localViews to the element
bind(ansatzLocalView, trialLocalView, element);
ansatzLocalView.bind(element);
// Add element stiffness matrix onto the global stiffness matrix // Add element stiffness matrix onto the global stiffness matrix
for (size_t i=0; i<trialLocalView.size(); ++i) for (size_t i=0; i<trialLocalView.size(); ++i)
...@@ -119,9 +121,10 @@ public: ...@@ -119,9 +121,10 @@ public:
template <class MatrixBackend, class LocalAssembler> template <class MatrixBackend, class LocalAssembler>
void assembleBulkEntries(MatrixBackend&& matrixBackend, LocalAssembler&& localAssembler) const void assembleBulkEntries(MatrixBackend&& matrixBackend, LocalAssembler&& localAssembler) const
{ {
auto trialLocalView = trialBasis_.localView(); // create two localViews but use only one if bases are the same
auto ansatzLocalView = ansatzBasis_.localView(); auto ansatzLocalView = ansatzBasis_.localView();
auto seperateTrialLocalView = trialBasis_.localView();
auto& trialLocalView = selectTrialLocalView(ansatzLocalView, seperateTrialLocalView);
using Field = std::decay_t<decltype(matrixBackend(trialLocalView.index(0), ansatzLocalView.index(0)))>; using Field = std::decay_t<decltype(matrixBackend(trialLocalView.index(0), ansatzLocalView.index(0)))>;
using LocalMatrix = Dune::Matrix<Dune::FieldMatrix<Field,1,1>>; using LocalMatrix = Dune::Matrix<Dune::FieldMatrix<Field,1,1>>;
...@@ -130,12 +133,10 @@ public: ...@@ -130,12 +133,10 @@ public:
for (const auto& element : elements(trialBasis_.gridView())) for (const auto& element : elements(trialBasis_.gridView()))
{ {
trialLocalView.bind(element); // bind the localViews to the element
bind(ansatzLocalView, trialLocalView, element);
ansatzLocalView.bind(element);
localMatrix.setSize(trialLocalView.size(), ansatzLocalView.size()); localMatrix.setSize(trialLocalView.size(), ansatzLocalView.size());
localAssembler(element, localMatrix, trialLocalView, ansatzLocalView); localAssembler(element, localMatrix, trialLocalView, ansatzLocalView);
// Add element stiffness matrix onto the global stiffness matrix // Add element stiffness matrix onto the global stiffness matrix
...@@ -270,6 +271,30 @@ public: ...@@ -270,6 +271,30 @@ public:
assembleBulkEntries(matrixBackend, std::forward<LocalAssembler>(localAssembler)); assembleBulkEntries(matrixBackend, std::forward<LocalAssembler>(localAssembler));
} }
private:
//! helper function to select a trialLocalView (possibly a reference to ansatzLocalView if bases are the same)
template<class AnsatzLocalView, class TrialLocalView>
TrialLocalView& selectTrialLocalView(AnsatzLocalView& ansatzLocalView, TrialLocalView& trialLocalView) const
{
if constexpr (std::is_same<TrialBasis,AnsatzBasis>::value)
if (&trialBasis_ == &ansatzBasis_)
return ansatzLocalView;
return trialLocalView;
}
//! small helper that checks whether two localViews are the same and binds one or both to an element
template<class AnsatzLocalView, class TrialLocalView, class E>
void bind(AnsatzLocalView& ansatzLocalView, TrialLocalView& trialLocalView, const E& e) const
{
ansatzLocalView.bind(e);
if constexpr (std::is_same<TrialBasis,AnsatzBasis>::value)
if (&trialLocalView == &ansatzLocalView)
return;
// localViews differ: bind trialLocalView too
trialLocalView.bind(e);
}
protected: protected:
const TrialBasis& trialBasis_; const TrialBasis& trialBasis_;
const AnsatzBasis& ansatzBasis_; const AnsatzBasis& ansatzBasis_;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment