13#ifndef ASSEMBLERCORE_HH
14#define ASSEMBLERCORE_HH
24#include <boost/version.hpp>
25#include <boost/mpl/accumulate.hpp>
26#include <boost/mpl/bool.hpp>
27#include <boost/mpl/if.hpp>
28#include <boost/timer/timer.hpp>
30#include <boost/exception/diagnostic_information.hpp>
31#include <boost/fusion/algorithm.hpp>
32#include <boost/fusion/sequence.hpp>
33#include <boost/fusion/include/find_if.hpp>
35#include "dune/common/config.h"
37#include "dune/common/fvector.hh"
38#include "dune/common/fmatrix.hh"
39#include "dune/geometry/type.hh"
40#include "dune/grid/common/capabilities.hh"
41#include "dune/istl/bcrsmatrix.hh"
42#include "dune/istl/bdmatrix.hh"
73 static int const timerStatistics = 0x1;
74 static int const scatterStatistics = 0x2;
75 static int const lockStatistics = 0x4;
76 static int const localTimerStatistics = 0x0;
87 static int const statistics = 0;
97 namespace AssemblyDetail {
108 class RowGroupManager
119 virtual ~RowGroupManager();
122 RowGroupManager(RowGroupManager
const& m) =
delete;
123 RowGroupManager& operator=(RowGroupManager
const& m) =
delete;
130 void init(
int nrg,
size_t rows);
138 void init(
int nrg, std::vector<std::vector<size_t>>
const& colIndex);
147 void init(
int nrg, std::vector<size_t>
const& weight);
153 std::pair<size_t,size_t> range(
int n)
const;
158 std::mutex& mutex(
int n)
const;
168 std::vector<size_t> rowGroupStart;
189 template <
class Policy,
class RowVar,
class ColVar,
class SparseIdx>
192 static int const rowId = RowVar::id;
193 static int const colId = ColVar::id;
194 static int const rowSpaceIndex = RowVar::spaceIndex;
195 static int const colSpaceIndex = ColVar::spaceIndex;
196 static bool const symmetric = Policy::template BlockInfo<rowId,colId>::symmetric;
197 static bool const mirror = Policy::template BlockInfo<rowId,colId>::mirror;
198 static bool const lumped = Policy::template BlockInfo<rowId,colId>::lumped;
199 static bool const makePositive = Policy::template BlockInfo<rowId,colId>::makePositive;
201 using SparseIndex = SparseIdx;
202 typedef MatrixBlock<Policy,RowVar,ColVar,SparseIndex> Self;
203 typedef typename Policy::Scalar Scalar;
204 typedef typename Policy::Spaces Spaces;
206 typedef NumaBCRSMatrix<BlockType, SparseIndex> Matrix;
210 typedef typename RowSpace::GridView GridView;
211 typedef typename GridView::template Codim<0>::Iterator CellIterator;
213 static int const dim = ColSpace::dim;
223 MatrixBlock(MatrixBlock
const& mb)
224 : matrix(new Matrix(*mb.matrix))
225 , isDense(mb.isDense)
231 MatrixBlock& operator=(MatrixBlock
const& mb)
233 *matrix = *mb.matrix;
234 isDense = mb.isDense;
237 MatrixBlock& operator=(Scalar x)
239 assert(matrix.get());
244 MatrixBlock& operator+=(MatrixBlock
const& mb)
246 *matrix += *mb.matrix;
254 Matrix& globalMatrix()
256 assert(matrix.get());
263 Matrix
const& globalMatrix()
const
265 assert(matrix.get());
276 std::shared_ptr<Matrix const> globalMatrixPointer()
const {
return matrix; }
292 template <
class FaceOracle>
293 void init(Spaces
const& spaces, CellIterator first, CellIterator last,
296 RowSpace
const& rowSpace = *at_c<RowVar::spaceIndex>(spaces);
297 ColSpace
const& colSpace = *at_c<ColVar::spaceIndex>(spaces);
301 if (!Policy::template BlockInfo<rowId,colId>::present)
303 assert(
"Aieee! Nonpresent matrix block detected!\n"==0);
307 boost::timer::cpu_timer timer;
310 size_t const rows = rowSpace.degreesOfFreedom();
311 size_t const cols = colSpace.degreesOfFreedom();
316 if (Policy::template BlockInfo<rowId,colId>::lumped)
318 assert(RowVar::spaceIndex==ColVar::spaceIndex && rows==cols);
319 NumaCRSPatternCreator<SparseIndex> creator(rows,cols,
false,1);
320 for (
size_t i=0; i<rows; ++i)
321 creator.addElements(&i,&i+1,&i,&i+1);
322 matrix.reset(
new Matrix(creator));
329 bool const dense = RowSpace::Mapper::globalSupport || ColSpace::Mapper::globalSupport;
337 int preallocateEntriesPerRow = 0;
340 int localSize = colSpace.mapper().globalIndices(0).size();
341 preallocateEntriesPerRow = dense? 0:
346 NumaCRSPatternCreator<SparseIndex> creator(rows,cols,symmetric,preallocateEntriesPerRow);
348 if (statistics & timerStatistics)
349 std::cout <<
"initial creator construction (" << rowId <<
"," << colId <<
"): " << timer.format();
355 creator.addAllElements();
356 if (statistics & timerStatistics)
357 std::cout <<
"entering indices for (" << rowId <<
"," << colId <<
"): " << timer.format();
371 size_t const nCells = rowSpace.indexSet().size(0);
373 std::vector<typename RowSpace::Mapper::GlobalIndexRange> rIndices(nCells,rowSpace.mapper().initGlobalIndexRange());
374 std::vector<typename ColSpace::Mapper::GlobalIndexRange> cIndices(nCells,colSpace.mapper().initGlobalIndexRange());
375 for (
size_t i=0; i<nCells; ++i)
377 rIndices[i] = rowSpace.mapper().globalIndices(i);
378 cIndices[i] = colSpace.mapper().globalIndices(i);
380 if (statistics & timerStatistics)
381 std::cout <<
"gathering indices for (" << rowId <<
"," << colId <<
"): " << timer.format();
384 creator.addElements(rIndices,cIndices);
388 if(Policy::considerInnerFaces)
390 GridView
const& gridView = rowSpace.gridView();
392 for (CellIterator ci=first; ci!=last; ++ci)
394 auto const& rIndices = rowSpace.mapper().globalIndices(*ci);
396 for (
auto const& face: intersections(gridView,*ci))
399 if (face.boundary() || !face.neighbor() ||
considerFace(face)==
false)
402 auto const& cIndices = colSpace.mapper().globalIndices(face.outside());
404 creator.addElements(begin(rIndices),end(rIndices),
405 begin(cIndices),end(cIndices));
410 if (statistics & timerStatistics)
411 std::cout <<
"entering indices for (" << rowId <<
"," << colId <<
"): " << timer.format();
415 if (statistics & timerStatistics)
416 std::cout <<
"balancing for (" << rowId <<
"," << colId <<
"): " << timer.format();
423 nnz = creator.nonzeroes();
426 matrix.reset(
new Matrix(creator));
427 if (statistics & timerStatistics)
428 std::cout <<
"creating pattern & matrix for (" << rowId <<
"," << colId <<
"): " << timer.format();
439 if (statistics & timerStatistics)
440 std::cout <<
"init cleanup for (" << rowId <<
"," << colId <<
"): " << timer.format() <<
"\n";
444 bool dense()
const {
return isDense; }
447 std::shared_ptr<Matrix> matrix;
454 template <
int row,
int col>
457 template <
class MatrixBlock>
460 using type = std::conditional_t<MatrixBlock::rowId==row && MatrixBlock::colId==col,boost::mpl::true_,boost::mpl::false_>;
469 template <
class Policy,
class AnsatzVariables,
class TestVariables,
class SparseIndex>
473 struct PresenceFilter
475 template <
class Block>
478 typedef boost::mpl::bool_<Policy::template BlockInfo<Block::rowId,Block::colId>::present> type;
482 static auto create(AnsatzVariables a, TestVariables t)
484 auto joiner = [=](
auto blocks,
auto rowVar)
486 using RowVar =
decltype(rowVar);
487 auto thisRow = transform(a,[](
auto avar){
return MatrixBlock<Policy,RowVar,decltype(avar),SparseIndex>(); });
488 return join(blocks,thisRow);
490 auto allBlocks = accumulate(t,vector<>(),joiner);
491 return as_vector(filter_if<PresenceFilter>(allBlocks));
495 typedef decltype(create(AnsatzVariables(),TestVariables())) type;
504 template <
class Policy,
class RV>
507 typedef typename std::remove_reference<RV>::type RowVar;
509 static int const rowId = RowVar::id;
511 typedef typename Policy::Scalar Scalar;
512 typedef typename Policy::Spaces Spaces;
515 typedef RhsBlock<Policy,RowVar> Self;
517 static int const rowSpaceIndex = RowVar::spaceIndex;
519 typedef typename RowSpace::GridView::template Codim<0>::Iterator CellIterator;
525 void init(Spaces
const& spaces, CellIterator , CellIterator ,
int nrg)
527 RowSpace
const& rowSpace = *at_c<RowVar::spaceIndex>(spaces);
528 size_t rows = rowSpace.degreesOfFreedom();
530 rowGroupManager = std::make_unique<RowGroupManager>();
531 rowGroupManager->init(nrg,rows);
534 RowGroupManager& rowGroup() {
return *rowGroupManager; }
540 LocalVector(): ridx(RowSpace::Mapper::initSortedIndexRange()) {}
542 std::vector<BlockType> vector;
544 typedef typename RowSpace::Mapper::SortedIndexRange SortedRowIdx;
556 typedef Self RhsBlock;
557 typedef std::vector<BlockType> LocalVectorType;
559 LocalVectors(
int n, RhsBlock& rb_): localVectors(n), currentLocalVector(0), rb(&rb_) {}
562 std::vector<LocalVector> localVectors;
565 int currentLocalVector;
572 std::unique_ptr<RowGroupManager> rowGroupManager;
578 template <
class Policy,
class TestVariables>
583 struct PresenceFilter
585 template <
class Block>
588 typedef boost::mpl::bool_<Policy::template RhsBlockInfo<Block::rowId>::present> type;
592 static auto create(TestVariables t)
594 auto allBlocks = transform(t,[](
auto tvar) {
return RhsBlock<Policy,decltype(tvar)>(); });
595 return as_vector(filter_if<PresenceFilter>(allBlocks));
599 typedef decltype(create(TestVariables())) type;
608 template <
class Policy>
614 RhsLocalData(
int n_): n(n_) {}
616 template <
class RhsBlock>
617 typename RhsBlock::LocalVectors operator()(RhsBlock
const& rb)
const
621 return typename RhsBlock::LocalVectors(n,
removeConst(rb));
631 struct MatrixLocalData
637 MatrixLocalData(
size_t s_)
640 template <
class MatrixBlock>
641 auto operator()(MatrixBlock
const& mb)
const
648 return LocalMatrices<
typename MatrixBlock::BlockType,
650 typename MatrixBlock::RowSpace::Mapper::SortedIndexRange,
651 typename MatrixBlock::ColSpace::Mapper::SortedIndexRange,
661 template <
class Spaces>
662 class GetMaxDerivativeBase
665 GetMaxDerivativeBase(Spaces
const& spaces_, std::map<void const*,int>& deriv_): spaces(spaces_), deriv(deriv_) {}
668 Spaces
const& spaces;
669 std::map<void const*,int>& deriv;
672 template <
int spaceIndex>
673 void enterSpace(
int d)
const
675 void const* space = at_c<spaceIndex>(spaces);
676 auto i = deriv.find(space);
684 template <
class Functional,
class Spaces>
685 class GetMaxDerivativeMatrix:
public GetMaxDerivativeBase<Spaces>
688 GetMaxDerivativeMatrix(Spaces
const& spaces, std::map<void const*,int>& deriv): GetMaxDerivativeBase<Spaces>(spaces,deriv) {}
690 template <
class LocalMatrices>
691 void operator()(LocalMatrices
const&)
const
694 int d = Functional::template D2<MatrixBlock::rowId,MatrixBlock::colId>::derivatives;
695 this->
template enterSpace<MatrixBlock::rowSpaceIndex>(d);
696 this->
template enterSpace<MatrixBlock::colSpaceIndex>(d);
701 template <
class Functional,
class Spaces>
702 class GetMaxDerivativeRhs:
public GetMaxDerivativeBase<Spaces>
705 GetMaxDerivativeRhs(Spaces
const& spaces, std::map<void const*,int>& deriv): GetMaxDerivativeBase<Spaces>(spaces,deriv) {}
707 template <
class RBlock>
708 void operator()(RBlock
const&)
const
710 int d = Functional::template D1<RBlock::RhsBlock::rowId>::derivatives;
711 this->
template enterSpace<RBlock::RhsBlock::rowSpaceIndex>(d);
721 template <
class Functional,
class Spaces,
class LocalMatrices,
class RBlocks>
722 std::map<void const*,int> derivatives(Functional
const& f, Spaces
const& spaces, LocalMatrices
const& localMatrices, RBlocks
const& rblocks)
724 std::map<void const*,int> deriv;
726 for_each(localMatrices,GetMaxDerivativeMatrix<Functional,Spaces>(spaces,deriv));
727 for_each(rblocks,GetMaxDerivativeRhs<Functional,Spaces>(spaces,deriv));
736 template <
class Evaluators,
class TestVariables>
743 template <
class LocalVectors>
744 void operator()(LocalVectors& lv)
const
750 assert(lv.currentLocalVector < lv.localVectors.size());
752 int const rSpaceIdx = result_of::value_at_c<TestVariables,LocalVectors::RhsBlock::rowId>::type::spaceIndex;
754 auto& reval = at_c<rSpaceIdx>(eval);
756 auto& rc = lv.localVectors[lv.currentLocalVector];
759 rc.vector.resize(reval.size());
760 std::fill(rc.vector.begin(),rc.vector.end(),0);
763 rc.ridx = reval.sortedIndices();
772 template <
class Evaluators,
class AnsatzVariableSetDescription,
class TestVariableSetDescription>
773 struct NewLocalMatrix
776 : reval(reval_), ceval(ceval_)
779 template <
class LocalMatrices>
780 void operator()(LocalMatrices& lm)
const
784 int const cSpaceIdx = spaceIndex<AnsatzVariableSetDescription,MatrixBlock::colId>;
785 int const rSpaceIdx = spaceIndex<TestVariableSetDescription ,MatrixBlock::rowId>;
787 lm.push_back(at_c<rSpaceIdx>(reval).sortedIndices(),at_c<cSpaceIdx>(ceval).sortedIndices());
800 template <
class TestVariableSetDescription,
class Evaluators,
class Real,
class Cache>
801 struct UpdateLocalRhs
803 UpdateLocalRhs(
Evaluators const& evaluators_, Real integrationFactor_, Cache
const& cache_)
804 : evaluators(evaluators_)
805 , integrationFactor(integrationFactor_)
809 template <
class LocalVectors>
810 void operator()(LocalVectors& lv)
const
812 typedef typename LocalVectors::RhsBlock RhsBlock;
814 int const rSpaceIndex = spaceIndex<TestVariableSetDescription,RhsBlock::rowId>;
815 auto& rc = lv.localVectors[lv.currentLocalVector].vector;
816 size_t const rows = rc.size();
817 for (
size_t i=0; i<rows; ++i)
821 using rhsEntryType = std::remove_reference_t<
decltype(rc[i])>;
822 using d1ResultType =
decltype(cache.template d1<RhsBlock::rowId>(at_c<rSpaceIndex>(evaluators).evalData[i]));
823 static_assert(std::is_same<rhsEntryType,d1ResultType>::value,
824 "Types don't match. Check return type of d1() in problem formulation.");
826 rc[i] += integrationFactor * cache.template d1<RhsBlock::rowId>(at_c<rSpaceIndex>(evaluators).evalData[i]);
827 assert(!std::isnan(rc[i][0]));
832 Real integrationFactor;
840 template <
class AnsatzVariableSetDescription,
class TestVariableSetDescription,
class Evaluators,
class Real,
class Cache>
841 struct UpdateLocalMatrix
843 UpdateLocalMatrix(
Evaluators const& evaluators_, Real integrationFactor_, Cache
const& cache_):
844 evaluators(evaluators_), integrationFactor(integrationFactor_), cache(cache_)
847 template <
class LocalMatrices>
848 void operator()(LocalMatrices& lm)
const
853 int const rowId = MatrixBlock::rowId;
854 int const colId = MatrixBlock::colId;
855 int const rSpaceIndex = spaceIndex<TestVariableSetDescription,rowId>;
856 int const cSpaceIndex = spaceIndex<AnsatzVariableSetDescription,colId>;
857 auto const& rEval = at_c<rSpaceIndex>(evaluators).evalData;
858 auto const& cEval = at_c<cSpaceIndex>(evaluators).evalData;
863 int const rows = A.ridx().size();
864 int const cols = A.cidx().size();
867 for (
int i=0; i<rows; ++i)
869 int begin = MatrixBlock::lumped? i: 0;
870 int end = (MatrixBlock::symmetric||MatrixBlock::lumped)? i+1: cols;
871 for (
int j=begin; j<end; ++j)
873 static_assert(std::is_same<std::remove_reference_t<
decltype(A(i,j))>,
874 decltype(cache.template d2<rowId,colId>(rEval[i],cEval[j]))
875 >::value,
"Types don't match. Check return type of d2() in problem formulation.");
876 A(i,j) += integrationFactor * cache.template d2<rowId,colId>(rEval[i], cEval[j]);
877 assert(!std::isnan(A(i,j)[0][0]));
883 Real integrationFactor;
889 template <
class AnsatzVariableSetDescription,
class TestVariableSetDescription,
891 struct UpdateLocalMatrixFromInnerBoundaryCache
893 UpdateLocalMatrixFromInnerBoundaryCache(
Evaluators const& insideEval,
Evaluators const& outsideEval,
894 Real integrationFactor_, Cache
const& cache_,
bool sameCell_)
895 : insideEvaluator(insideEval)
896 , outsideEvaluator(outsideEval)
897 , integrationFactor(integrationFactor_)
899 , sameCell(sameCell_)
902 template <
class LocalMatrices>
903 void operator()(LocalMatrices& lm)
const
907 int const rSpaceIndex = spaceIndex<TestVariableSetDescription, MatrixBlock::rowId>;
908 int const cSpaceIndex = spaceIndex<AnsatzVariableSetDescription,MatrixBlock::colId>;
910 auto& A = lm.localMatrices.back();
913 int const rows = A.ridx().size();
914 int const cols = A.cidx().size();
917 for (
int i=0; i<rows; ++i)
919 int begin = MatrixBlock::lumped? i: 0;
920 int end = ((MatrixBlock::symmetric && sameCell)||MatrixBlock::lumped)? i+1: cols;
921 for (
int j=begin; j<end; ++j)
923 auto tmp = cache.template d2<MatrixBlock::rowId,MatrixBlock::colId>(
924 at_c<rSpaceIndex>(insideEvaluator).evalData[i],
925 at_c<cSpaceIndex>(outsideEvaluator).evalData[j], sameCell);
926 A(i,j) += integrationFactor * tmp;
927 assert(!std::isnan(A(i,j)[0][0]));
932 Evaluators const& insideEvaluator, outsideEvaluator;
933 Real integrationFactor;
942 template <
class GlobalRhs>
943 struct ScatterLocalRhs
951 ScatterLocalRhs(GlobalRhs& globalRhs_,
bool immediate_ =
false):
952 globalRhs(globalRhs_), immediate(immediate_)
955 template <
class LocalVectors>
956 void operator()(LocalVectors& lv)
const
958 auto& gRhs = at_c<LocalVectors::RhsBlock::rowId>(globalRhs.data);
960 auto const& rowGroups = lv.rb->rowGroup();
962 if (immediate || lv.currentLocalVector+1==lv.localVectors.size())
964 int const last = immediate ? lv.currentLocalVector : lv.localVectors.size();
967 for (
int rg=0; rg<rowGroups.size(); ++rg)
970 auto const [firstRow,lastRow] = rowGroups.range(rg);
971 std::lock_guard lock(rowGroups.mutex(rg));
974 for (
int i=0; i<last; ++i)
976 auto& ri = lv.localVectors[i].vector;
977 auto& ridx = lv.localVectors[i].ridx;
979 assert(ri.size()==ridx.size());
981 for (
int r=0; r<ridx.size(); ++r)
983 size_t const rGlobalIndex = ridx[r].first;
986 if (firstRow<=rGlobalIndex && rGlobalIndex<lastRow)
988 size_t const rLocalIndex = ridx[r].second;
989 gRhs[rGlobalIndex] += ri[rLocalIndex];
996 lv.currentLocalVector = 0;
999 ++lv.currentLocalVector;
1002 GlobalRhs& globalRhs;
1018 template <
class Functional>
1019 struct SymmetrizeLocalMatrix
1021 template <
class LocalMatrices>
1022 void operator()(LocalMatrices& lm)
const
1030 if constexpr (!MatrixBlock::lumped && MatrixBlock::symmetric)
1032 auto& m = lm.back();
1033 int const N = m.ridx().size();
1034 assert(N==m.cidx().size());
1038 for (
int i=0; i<N-1; ++i)
1039 for (
int j=i+1; j<N; ++j)
1045 if constexpr (MatrixBlock::makePositive)
1048 constexpr int row = MatrixBlock::rowId;
1049 constexpr int col = MatrixBlock::colId;
1052 using Entry =
typename MatrixBlock::BlockType;
1053 DynamicMatrix<Entry> Aloc(N,N);
1054 for (
int j=0; j<N; ++j)
1055 for (
int i=0; i<N; ++i)
1056 Aloc[i][j] = m(i,j);
1059 bool changed = makePositiveSemiDefinite(Aloc,f->template makePositiveThreshold<row,col>());
1063 for (
int j=0; j<N; ++j)
1064 for (
int i=0; i<N; ++i)
1065 m(i,j) = Aloc[i][j];
1070 Functional
const* f;
1082 template <
class Functional>
1083 struct VariationalFunctionalPolicy
1085 typedef typename Functional::Scalar Scalar;
1086 typedef typename Functional::AnsatzVars::Spaces Spaces;
1087 static constexpr bool considerInnerFaces = hasInnerBoundaryCache<Functional>;
1089 template <
int rowId>
1092 static bool const present = Functional::template D1<rowId>::present;
1096 template <
int rowId,
int colId>
1099 static bool const present = Functional::template D2<rowId,colId>::present && rowId>=colId;
1100 static bool const symmetric = (rowId==colId || Functional::template D2<rowId,colId>::symmetric)
1101 && (result_of::value_at_c<typename Functional::TestVars::Variables,rowId>::type::spaceIndex
1102 == result_of::value_at_c<typename Functional::AnsatzVars::Variables,colId>::type::spaceIndex);
1103 static bool const mirror = rowId>colId;
1104 static bool const lumped = symmetric && Functional::template D2<rowId,colId>::lumped;
1105 static bool const makePositive = symmetric && Functional::template D2<rowId,colId>::makePositive;
1113 Scalar functional()
const {
return fValue; }
1115 static constexpr bool hasValue =
true;
1127 template <
class Functional>
1128 struct WeakFormulationPolicy
1130 typedef typename Functional::Scalar Scalar;
1131 typedef typename Functional::AnsatzVars::Spaces Spaces;
1132 static constexpr bool considerInnerFaces = hasInnerBoundaryCache<Functional>;
1134 template <
int rowId>
1137 static bool const present = Functional::template D1<rowId>::present;
1141 template <
int rowId,
int colId>
1144 static bool const present = Functional::template D2<rowId,colId>::present;
1145 static bool const symmetric = Functional::template D2<rowId,colId>::symmetric
1146 && (result_of::value_at_c<typename Functional::TestVars::Variables,rowId>::type::spaceIndex
1147 == result_of::value_at_c<typename Functional::AnsatzVars::Variables,colId>::type::spaceIndex);
1148 static bool const mirror =
false;
1149 static bool const lumped = symmetric && Functional::template D2<rowId,colId>::lumped;
1150 static bool const makePositive = symmetric && Functional::template D2<rowId,colId>::makePositive;
1154 static constexpr bool hasValue =
false;
1164 template <
class Problem>
1166 VariationalFunctionalPolicy<Problem>,
1167 WeakFormulationPolicy<Problem>>;
1175 struct TakeAllBlocks
1177 template <
int row>
struct D1 {
static bool const assemble =
true; };
1178 template <
int row,
int col>
struct D2 {
static bool const assemble =
true; };
1182 template <
class BlockFilter>
1183 struct MatrixBlockFilter
1188 typedef boost::mpl::bool_<BlockFilter::template D2<X::rowId,X::colId>::assemble> type;
1192 template <
class>
struct Fill;
1194 template <
class Block,
bool,
bool>
1197 template <
class OtherBlock>
1198 static void apply(OtherBlock
const&, std::unique_ptr<Block>&,
bool,
size_t){}
1201 template <
class Scalar,
int n,
class Allocator,
bool symmetric>
1202 struct CopyBlock<
Dune::BCRSMatrix<Dune::FieldMatrix<Scalar,n,n>,Allocator>,symmetric,true>
1204 typedef Dune::BCRSMatrix<Dune::FieldMatrix<Scalar,n,n>,Allocator> Block;
1206 static void apply(Block
const& from, std::unique_ptr<Block>& to,
bool extractOnlyLowerTriangle,
size_t nnz)
1209 if(extractOnlyLowerTriangle == symmetric)
1211 to.reset(
new Block(from));
1216 if( (!extractOnlyLowerTriangle && symmetric) || (extractOnlyLowerTriangle && !symmetric) )
1218 std::vector<std::vector<size_t> > bcrsPattern(from.N());
1219 for(
size_t i=0; i<from.N(); ++i)
1220 for(
size_t j=0; j<=i; ++j)
1222 if(from.exists(i,j))
1224 bcrsPattern[i].push_back(j);
1225 if(i!=j && !extractOnlyLowerTriangle)
1226 bcrsPattern[j].push_back(i);
1229 for(std::vector<size_t>& row : bcrsPattern) std::sort(row.begin(),row.end());
1231 to.reset(
new Block(from.N(),from.M(),nnz,Block::row_wise));
1234 for (
typename Block::CreateIterator row=to->createbegin(); row!=to->createend(); ++row)
1235 for(
size_t col : bcrsPattern[row.index()]) row.insert(col);
1238 for(
size_t row=0; row<bcrsPattern.size(); ++row)
1239 for(
size_t col : bcrsPattern[row])
1241 if(row >= col) (*to)[row][col] = from[row][col];
1242 else if(!extractOnlyLowerTriangle)
1244 for(
size_t i=0; i<n; ++i)
1245 for(
size_t j=0; j<n; ++j)
1246 (*to)[row][col][i][j] = from[col][row][j][i];
1254 template <
class BCRSMat,
int rowIndex,
int columnIndex>
1257 explicit BlockToBCRS(std::unique_ptr<BCRSMat>& m,
bool extractOnlyLowerTriangle_,
size_t nnz_) : mat(m), extractOnlyLowerTriangle(extractOnlyLowerTriangle_), nnz(nnz_)
1260 template <
class MatrixBlock>
1261 void operator()(MatrixBlock
const& mb)
const
1263 CopyBlock<BCRSMat,MatrixBlock::symmetric,MatrixBlock::rowId==rowIndex && MatrixBlock::colId==columnIndex>::apply(mb.globalMatrix(),mat,extractOnlyLowerTriangle,nnz);
1267 std::unique_ptr<BCRSMat>& mat;
1268 bool extractOnlyLowerTriangle;
1290 template <
class Gr
idView>
1298 gridView(gridView_), indexSet(gridView.indexSet())
1306 gridView(gridView_), indexSet(gridView.indexSet())
1313 assert(indexSet.size(0)==boundaryFlag.size());
1314 return boundaryFlag[indexSet.index(cell)];
1318 GridView
const& gridView;
1319 typename GridView::IndexSet
const& indexSet;
1320 std::vector<bool> boundaryFlag;
1321 boost::signals2::scoped_connection refConnection;
1323 void update(
int const status)
1325 using namespace Dune;
1329 boundaryFlag.resize(indexSet.size(0));
1331 for (
auto const& cell: elements(gridView))
1332 boundaryFlag[indexSet.index(cell)] = cell.hasBoundaryIntersections();
1346 template <
class Gr
idView>
1350 template <
class Gr
idView>
1354 template <
class Entity>
1357 return cell.hasBoundaryIntersections();
1370 template <
class Gr
idView>
1374 template <
class Gr
idView>
1378 template <
class Entity>
1426 class SparseIndex = size_t,
1427 class BoundaryDetector = CachingBoundaryDetector<typename F::AnsatzVars::GridView>,
1429 F::AnsatzVars::Grid::dimension>>
1431 :
public AssemblyDetail::FormulationPolicy<F>
1434 typedef typename AssemblyDetail::FormulationPolicy<F>
Policy;
1448 typedef typename AnsatzVariableSetDescription::Grid
Grid;
1453 typedef typename AnsatzVariableSetDescription::GridView
GridView;
1456 typedef typename AnsatzVariableSetDescription::Spaces
Spaces;
1458 typedef typename AnsatzVariableSetDescription::IndexSet
IndexSet;
1471 static_assert(std::is_same<typename AnsatzVariableSetDescription::Spaces, typename TestVariableSetDescription::Spaces>::value,
1472 "VariableSetDescriptions for ansatz spaces and test spaces must provide the same space list.");
1473 static_assert(Functional::type==
WeakFormulation || std::is_same<AnsatzVariableSetDescription,TestVariableSetDescription>::value,
1474 "For problem type VariationalFunctional, ansatz and test variables must be the same.");
1486 using MatrixBlockArray =
typename AssemblyDetail::BlockArray<Policy,AnsatzVariables,TestVariables,SparseIndex>::type;
1493 typedef typename AssemblyDetail::RhsBlockArray<Policy,TestVariables>::type
RhsBlockArray;
1498 typedef typename TestVariableSetDescription::template CoefficientVectorRepresentation<>::type
RhsArray;
1512 TestVariableSetDescription::noOfVariables)>,
1513 "If a problem is of type VariationalFunctional, the present diagonal blocks need to be marked as symmetric in D2.");
1601 assemble<AssemblyDetail::TakeAllBlocks>(f,[](
auto const& cell) {
return true; },
1602 flags,nThreads,verbose);
1608 typedef typename CellIterator::Entity
Entity;
1651 template <
class BlockFilter,
class CellFilter>
1654 using namespace Dune;
1656 using namespace AssemblyDetail;
1672 std::cout <<
"Grid is not thread safe. Reducing number of used threads to 1." << std::endl;
1676 if(verbose) std::cout <<
"#tasks:" << nTasks <<
" " << std::endl;
1679 nTasks =
std::min(nTasks,cellRanges.maxRanges());
1681 if (
gatherTimings) timings.start(
"creating rhs/matrix data structures");
1683 auto clearGlobalData = [](
auto& x) { x = 0; };
1686 for_each(
getRhs().first.data,clearGlobalData);
1690 typedef filter_view<MatrixBlockArray,MatrixBlockFilter<BlockFilter>> MatrixBlockFilter;
1691 for_each(MatrixBlockFilter(
getMatrix(f)),clearGlobalData);
1693 if (
gatherTimings) timings.stop(
"creating rhs/matrix data structures");
1700 assembleCellRange<BlockFilter>(f,cellFilter,flags,
gv.template begin<0>(),
gv.template end<0>(),0);
1702 this->fValue = retval;
1708 std::vector<Scalar> values(nTasks,0.0);
1710 parallelFor([&cellRanges,
this,&f,flags,&values,&cellFilter](
int i,
int n) {
1711 auto range = cellRanges.range(n,i);
1712 values[i] = this->assembleCellRange<BlockFilter>(f,cellFilter,flags,range.begin(),range.end(),i);
1718 this->fValue = std::accumulate(values.begin(),values.end(),0.0);
1739 template <
class BlockFilter,
class CellFilter>
1740 Scalar assembleCellRange(F
const& f, CellFilter
const& cellFilter,
1743 using namespace Dune;
1745 using namespace AssemblyDetail;
1748 boost::timer::cpu_timer scatterTimer, evalTimer, localTimer, setupTimer, totalTimer;
1749 if (statistics & localTimerStatistics)
1752 scatterTimer.stop();
1763 using MatrixBlockFilter = filter_view<MatrixBlockArray,AssemblyDetail::MatrixBlockFilter<BlockFilter>>;
1768 int const dim = Grid::dimension;
1769 typedef typename Grid::ctype CoordType;
1775 auto localRhs = as_vector(transform(*globalRhsBlocks,RhsLocalData<Policy>(
nSimultaneousBlocks)));
1781 using LocalMatrices =
decltype(as_vector(transform(MatrixBlockFilter(*globalMatrix),MatrixLocalData(0))));
1782 LocalMatrices localMatrices, localNeighborMatrices;
1785 localMatrices = as_vector(transform(MatrixBlockFilter(*globalMatrix),
1787 localNeighborMatrices = as_vector(transform(MatrixBlockFilter(*globalMatrix),
1795 typedef ShapeFunctionCache<Grid,Scalar> SfCache;
1799 QuadratureTraits<QuadRule> quadratureCache;
1800 QuadratureTraits<
QuadratureRule<CoordType,dim-1>> faceQuadratureCache;
1805 auto evaluators = getEvaluators(
spaces(),&sfCache,AssemblyDetail::derivatives(f,
spaces(),localMatrices,localRhs));
1807 auto neighbourEvaluators = evaluators;
1811 auto domainCache = f.createDomainCache(flags);
1812 auto boundaryCache = f.createBoundaryCache(flags);
1813 auto innerBoundaryCache = [&](){
if constexpr (
innerBoundaries)
return f.createInnerBoundaryCache(flags);
1818 SymmetrizeLocalMatrix<Functional> symmetrizeLocalMatrix{&f};
1821 typename AnsatzVariableSetDescription::Variables ansatzVars;
1822 typename TestVariableSetDescription::Variables testVars;
1824 if (statistics & localTimerStatistics)
1830 if (statistics & localTimerStatistics)
1836 if (!cellFilter(*cell))
1843 domainCache.moveTo(*cell);
1849 int const shapeFunctionMaxOrder =
maxOrder(evaluators);
1851 if (statistics & localTimerStatistics) localTimer.resume();
1852 if (statistics & localTimerStatistics) evalTimer.stop();
1857 for_each(localRhs,ClearLocalRhs<Evaluators,TestVariables>(evaluators));
1864 int const integrationOrderOnCell = f.integrationOrder(*cell,shapeFunctionMaxOrder,
false);
1865 GeometryType gt = cell->type();
1867 QuadRule
const qr = quadratureCache.rule(gt,integrationOrderOnCell);
1870 size_t nQuadPos = qr.size();
1871 for (
size_t g=0; g<nQuadPos; ++g)
1880 domainCache.evaluateAt(quadPos,evaluators);
1882 CoordType weightTimesDetJac(cell->geometry().integrationElement(quadPos));
1883 assert(weightTimesDetJac > 0);
1885 weightTimesDetJac *= qr[g].weight();
1888 if constexpr (Self::hasValue)
1890 floc += weightTimesDetJac*domainCache.d0();
1893 typename F::DomainCache>(evaluators,weightTimesDetJac,domainCache));
1897 evaluators,weightTimesDetJac,domainCache));
1907 int const integrationOrderOnFace = f.integrationOrder(*cell,shapeFunctionMaxOrder,
true);
1916 auto faceEnd =
gv.iend(*cell);
1917 for (
auto face=
gv.ibegin(*cell); face!=faceEnd; ++face)
1928 bool const onBoundary = face->boundary();
1933 GeometryType gt = face->type();
1934 QuadratureRule<CoordType,dim-1>
const qr = faceQuadratureCache.rule(gt,integrationOrderOnFace);
1935 size_t const nQuadPos = qr.size();
1939 boundaryCache.moveTo(face);
1942 assert(face->neighbor());
1943 assert(gt == face->geometryInOutside().type());
1946 if (! f.considerFace(*face))
1949 innerBoundaryCache.moveTo(face);
1956 for_each(localNeighborMatrices,
1962 for (
size_t g=0; g<nQuadPos; ++g)
1971 CoordType weightTimesDetJac = qr[g].weight() * face->geometry().integrationElement(quadPos);
1994 boundaryCache.evaluateAt(quadPos,evaluators);
1997 if constexpr (Self::hasValue)
1999 floc += weightTimesDetJac*boundaryCache.d0();
2002 typename F::BoundaryCache>(evaluators,weightTimesDetJac,boundaryCache));
2005 Evaluators,
Scalar,
typename F::BoundaryCache>(evaluators,weightTimesDetJac,boundaryCache));
2013 innerBoundaryCache.evaluateAt(quadPos,evaluators,neighbourEvaluators);
2016 if constexpr (Self::hasValue)
2018 floc += 0.5 * weightTimesDetJac*innerBoundaryCache.d0();
2020 using InnerBoundaryCache =
typename Functional::InnerBoundaryCache;
2028 Scalar,InnerBoundaryCache>
2029 (evaluators,weightTimesDetJac,innerBoundaryCache));
2037 (evaluators,evaluators,weightTimesDetJac,innerBoundaryCache,
true));
2041 (evaluators,neighbourEvaluators,weightTimesDetJac,innerBoundaryCache,
false));
2052 for_each(localMatrices,symmetrizeLocalMatrix);
2054 if (statistics & localTimerStatistics) scatterTimer.resume();
2055 if (statistics & localTimerStatistics) localTimer.stop();
2063 for_each(localRhs,ScatterLocalRhs<RhsArray>(*globalRhs));
2065 if (statistics & localTimerStatistics) evalTimer.resume();
2066 if (statistics & localTimerStatistics) scatterTimer.stop();
2069 if (statistics & localTimerStatistics) scatterTimer.resume();
2070 if (statistics & localTimerStatistics) evalTimer.stop();
2075 for_each(localRhs,ScatterLocalRhs<RhsArray>(*globalRhs,
true));
2077 if (statistics & localTimerStatistics) scatterTimer.stop();
2080 if (statistics & localTimerStatistics)
2082 std::cerr <<
"--------------\nThread " << threadNo <<
":\n";
2083 double totalTime = setupTimer.elapsed().wall + evalTimer.elapsed().wall + scatterTimer.elapsed().wall + localTimer.elapsed().wall;
2084 std::cerr.precision(1);
2085 std::cerr.setf(std::ios_base::fixed,std::ios_base::floatfield);
2086 std::cerr <<
"Total time: " << 100* totalTimer.elapsed().wall / totalTime <<
"% -- " << totalTimer.format()
2087 <<
"Setup time: " << 100* setupTimer.elapsed().wall / totalTime <<
"% -- " << setupTimer.format()
2088 <<
"Eval times: " << 100* evalTimer.elapsed().wall / totalTime <<
"% -- " << evalTimer.format()
2089 <<
"Scatter times: " << 100* scatterTimer.elapsed().wall / totalTime <<
"% -- " << scatterTimer.format()
2090 <<
"Local times: " << 100 * localTimer.elapsed().wall / totalTime <<
"% -- " << localTimer.format();
2091 std::cerr <<
"--------------\n";
2112 if (flags &
VALUE) this->fValue = 0;
2125 std::pair<size_t,size_t>
size(
int row,
int col)
const
2127 return std::make_pair(TestVariableSetDescription::degreesOfFreedom(
spaces(),row,row+1),
2128 AnsatzVariableSetDescription::degreesOfFreedom(
spaces(),col,col+1));
2159 template <
class Matrix>
2161 int rbegin=0,
int rend=TestVariableSetDescription::noOfVariables,
2162 int cbegin=0,
int cend=AnsatzVariableSetDescription::noOfVariables)
const
2165 auto cSizes = AnsatzVariableSetDescription::variableDimensions(
spaces());
2166 auto rSizes = TestVariableSetDescription::variableDimensions(
spaces());
2169 std::vector<size_t> rowOff(rend-rbegin,0), colOff(cend-cbegin,0);
2170 std::partial_sum(rSizes.begin()+rbegin,rSizes.begin()+rend-1,rowOff.begin()+1);
2171 std::partial_sum(cSizes.begin()+cbegin,cSizes.begin()+cend-1,colOff.begin()+1);
2174 extractOnlyLowerTriangle,
2175 nnz(rbegin, rend, cbegin, cend,
2176 extractOnlyLowerTriangle),
2187 template <
int row,
int col>
2190 return (*boost::fusion::find_if<AssemblyDetail::IsBlock<row,col>>(
getMatrix())).globalMatrix();
2198 template <
class MatrixType,
class BlockInformation>
2199 MatrixType
get(
bool extractOnlyLowerTriangle)
const
2201 using BI = BlockInformation;
2202 return get<MatrixType,BI::firstRow,BI::lastRow,BI::firstCol,BI::lastCol>(extractOnlyLowerTriangle);
2212 template <
class DataOutIter>
2234 size_t nnz(
size_t rbegin=0,
size_t rend=TestVariableSetDescription::noOfVariables,
2235 size_t cbegin=0,
size_t cend=AnsatzVariableSetDescription::noOfVariables,
bool extractOnlyLowerTriangle=
false)
const
2245 size_t nrows(
int firstBlock=0,
int lastBlock=TestVariableSetDescription::noOfVariables)
const
2247 return TestVariableSetDescription::degreesOfFreedom(
spaces(),firstBlock,lastBlock);
2253 size_t ncols(
int firstBlock=0,
int lastBlock=AnsatzVariableSetDescription::noOfVariables)
const
2255 return AnsatzVariableSetDescription::degreesOfFreedom(
spaces(),firstBlock,lastBlock);
2288 createMatrix([](
auto const& face) {
return true; });
2297 createMatrix([&](
auto const& face)
2300 return f.considerFace(face);
2309 template <
class FaceOracle>
2310 void createMatrix(FaceOracle
const&
considerFace)
const
2315 block.init(this->
spaces(),
gv.template begin<0>(),
gv.template end<0>(),
2326 template <
int first=0,
int last=TestVariableSetDescription::noOfVariables>
2327 typename TestVariableSetDescription::template CoefficientVectorRepresentation<first,last>::type
rhs()
const
2329 using Rhs =
typename TestVariableSetDescription::template CoefficientVectorRepresentation<first,last>::type;
2330 return Rhs(make_range<first,last>(
getRhs().first.data));
2334 std::pair<RhsArray&,RhsBlockArray&>
getRhs()
const
2342 rhss.reset(
new RhsArray(TestVariableSetDescription::template CoefficientVectorRepresentation<>::init(
spaces())));
2350 boost::fusion::for_each(*
rhsBlocks,[&](
auto& block)
2352 block.init(this->
spaces(),
gv.template begin<0>(),
gv.template end<0>(),nrg);
2356 return std::pair<RhsArray&,RhsBlockArray&>(*
rhss,*
rhsBlocks);
2378 mutable std::shared_ptr<RhsArray>
rhss;
2390 template <
class IdxOutIter,
class DataOutIter>
2393 BlockToTriplet(
size_t rbegin_,
size_t cbegin_, std::vector<size_t>
const& rowOff_, std::vector<size_t>
const& colOff_,
2394 IdxOutIter& ri_, IdxOutIter& ci_, DataOutIter& xi_,
bool extractOnlyLowerTriangle_):
2399 template <
class MatrixBlock>
2403 if (
inRange(mb.rowId,mb.colId))
2436 CountNonzeros(
size_t& n_,
size_t rbegin_,
size_t rend_,
size_t cbegin_,
size_t cend_,
bool onlyLowerTriangle_):
2440 template <
class MatrixBlock>
2447 if (
inRange(MatrixBlock::rowId,MatrixBlock::colId))
2470 template <
class DataOutIter>
2473 BlockToSequence(
int& rbegin_,
int& rend_, DataOutIter& out_): rbegin(rbegin_), rend(rend_), out(out_) {}
2474 template <
class VectorBlock>
void operator()(VectorBlock
const& v)
const
2476 if (rbegin<=0 && rend>0)
CachingBoundaryDetector(GridView const &gridView_)
bool hasBoundaryIntersections(Cell const &cell) const
CachingBoundaryDetector(GridSignals &signals, GridView const &gridView_)
ForwardingBoundaryDetector(GridView const &)
ForwardingBoundaryDetector(GridSignals const &, GridView const &)
bool hasBoundaryIntersections(Entity const &cell) const
CellRanges< typename Grid::LeafGridView > const & cellRanges(typename Grid::LeafGridView const &) const
Returns a CellRanges object for the given grid view. The cell ranges are created on demand....
bool gridIsThreadSafe() const
Returns true if concurrent read accesses to the grid do not lead to data races.
static NumaThreadPool & instance(int maxThreads=std::numeric_limits< int >::max())
Returns a globally unique thread pool instance.
int cpus() const
Reports the total number of CPUs (usually a multiple of nodes).
A scope guard object that automatically closes a timing section on destruction.
static Timings & instance()
Returns a reference to a single default instance.
TrivialBoundaryDetector(GridView const &)
TrivialBoundaryDetector(GridSignals const &, GridView const &)
bool hasBoundaryIntersections(Entity const &cell) const
A class for assembling Galerkin representation matrices and right hand sides for variational function...
AnsatzVariableSetDescription::GridView GridView
The grid view on which the variables live.
Functional::AnsatzVars AnsatzVariableSetDescription
ansatz variables
Self & setNSimultaneousBlocks(int n)
Defines how many cells are assembled locally before scattering them together into the global data str...
CellIterator::Entity Entity
int valid()
Returns a bitfield specifyign which of the parts have been assembled since construction or flush() ac...
TestVariableSetDescription::template CoefficientVectorRepresentation ::type RhsArray
A LinearProductSpace type of right hand side coefficient vectors.
void flush(int flags=(VALUE|RHS|MATRIX))
Destructs parts of the assembled quatities according to the format (VALUE|RHS|MATRX)
static unsigned int const VALUE
DEPRECATED, enums in the Assembler namespace.
Self & setLocalStorageSize(size_t s)
Defines how many memory the locally assembled matrices may occupy before they are scattered.
Matrix get(bool extractOnlyLowerTriangle=false, int rbegin=0, int rend=TestVariableSetDescription::noOfVariables, int cbegin=0, int cend=AnsatzVariableSetDescription::noOfVariables) const
Extracts the submatrix defined by the half-open block ranges [rbegin,rend), [cbegin,...
Self & setGatherTimings(bool gt)
Whether to gather timing statistics using Kaskade::Timings.
AssemblyDetail::FormulationPolicy< F > Policy
GridView const & gridView() const
The grid view used.
Functional::Scalar field_type
Underlying field type.
void assemble(F const &f, CellFilter const &cellFilter, unsigned int flags=Assembler::EVERYTHING, int nTasks=0, bool verbose=false)
Create data in assembler.
Functional::TestVars TestVariableSetDescription
test variables
typename AssemblyDetail::BlockArray< Policy, AnsatzVariables, TestVariables, SparseIndex >::type MatrixBlockArray
A boost::fusion sequence of AssemblyDetail::MatrixBlock elements for present matrix blocks.
void toSequence(int rbegin, int rend, DataOutIter xi) const
Writes the subvector defined by the half-open block range [rbegin,rend) to the output iterator xi.
auto const & get() const
Extracts a raw single submatrix block indexed by row and column.
void reactToRefinement(GridSignals::Status const status)
static constexpr bool innerBoundaries
static unsigned int const RHS
TestVariableSetDescription::template CoefficientVectorRepresentation< first, last >::type rhs() const
Returns a contiguous subrange of the rhs coefficient vectors.
AnsatzVariableSetDescription::Grid Grid
grid
static unsigned int const MATRIX
std::shared_ptr< RhsArray > rhss
TestVariableSetDescription::Variables TestVariables
GridView::template Codim< 0 >::Iterator CellIterator
size_t ncols(int firstBlock=0, int lastBlock=AnsatzVariableSetDescription::noOfVariables) const
Returns the number of scalar cols in the column block range [firstBlock,lastBlock[.
AssemblyDetail::RhsBlockArray< Policy, TestVariables >::type RhsBlockArray
A boost::fusion sequence of AssemblyDetail::RhsBock elements for present rhs blocks.
AnsatzVariableSetDescription::Spaces Spaces
spaces
std::shared_ptr< MatrixBlockArray > matrixBlocks
size_t nrows(int firstBlock=0, int lastBlock=TestVariableSetDescription::noOfVariables) const
Returns the number of scalar rows in the row block range [firstBlock,lastBlock[.
AnsatzVariableSetDescription::Variables AnsatzVariables
Spaces const & spaces() const
Returns the list of spaces used.
VariationalFunctionalAssembler< F, SparseIndex, BoundaryDetector, QuadRule > Self
VariationalFunctionalAssembler(Spaces const &spaces)
Construct an empty assembler, gridManager is implicitly obtained from the first space.
AnsatzVariableSetDescription::IndexSet IndexSet
index set
std::pair< size_t, size_t > size(int row, int col) const
the size of a matrix block (in terms of scalar rows/columns)
size_t nnz(size_t rbegin=0, size_t rend=TestVariableSetDescription::noOfVariables, size_t cbegin=0, size_t cend=AnsatzVariableSetDescription::noOfVariables, bool extractOnlyLowerTriangle=false) const
Returns the number of structurally nonzero entries in the submatrix defined by the half-open block ra...
MatrixType get(bool extractOnlyLowerTriangle) const
Extracts the submatrix defined by the half-open block ranges given as template parameter.
std::pair< RhsArray &, RhsBlockArray & > getRhs() const
GridManagerBase< Grid > const & gridManager
static unsigned int const EVERYTHING
boost::signals2::scoped_connection refConnection
BoundaryDetector boundaryDetector
void assemble(F const &f, unsigned int flags=Assembler::EVERYTHING, int nThreads=0, bool verbose=false)
Assembly without block filter or cell filter.
std::shared_ptr< RhsBlockArray > rhsBlocks
MatrixBlockArray & getMatrix() const
Returns a mutable reference to the sequence of matrix blocks.
Self & setRowBlockFactor(double a)
Defines how many more row blocks in each matrix are used compared to the number of threads.
IndexSet const & indexSet
Utility classes for the definition and use of variational functionals.
void useQuadratureRuleInEvaluators(Evaluator &evals, QuadratureRule const &qr, int subId)
Tells all evaluators to use the given quadrature rule on the given subentity.
void moveEvaluatorsToIntegrationPoint(Evaluators &evals, Dune::FieldVector< CoordType, dim > const &x, Dune::QuadratureRule< CoordType, subDim > const &qr, int ip, int subId)
Moves all provided evaluators to the given integration point, evaluating the shape functions there.
int maxOrder(Evaluators const &evals)
Computes the maximum ansatz order used in a collection of evaluators.
typename boost::fusion::result_of::as_vector< typename boost::fusion::result_of::transform< Spaces, GetEvaluatorTypes >::type >::type Evaluators
the heterogeneous sequence type of Evaluators for the given spaces
typename GridView::template Codim< 0 >::Entity Cell
The type of cells (entities of codimension 0) in the grid view.
boost::signals2::signal< void(Status)> informAboutRefinement
A signal that is emitted thrice on grid modifications, once before adaptation takes place and twice a...
Status
The argument type of the signal that is emitted before and after grid adaptation.
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
Dune::FieldVector< T, n > min(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise minimum.
void parallelFor(Func const &f, int maxTasks=std::numeric_limits< int >::max())
A parallel for loop that executes the given functor in parallel on different CPUs.
T & removeConst(T const &t)
A convenience template for removing the const qualifier from references and pointers.
bool considerFace(Face const &face, std::vector< int > const &boundaryIds, std::vector< int > const &usedIds)
OutIter vectorToSequence(double x, OutIter iter)
void moveEvaluatorsToCell(Evaluators &evals, Cell const &cell)
Moves all provided evaluators to the given cell.
constexpr bool symmetryCheck
Specialize this template for your matrix type in order to use it with VariationalFunctionalAssembler:...
A class that provides access to signals that are emitted from the grid manager on various occasions.
A class template that supports converting certain Dune matrices into the coordinate (triplet) format.
std::remove_pointer_t< typename boost::fusion::result_of::value_at_c< Spaces, Idx >::type > type
BlockToSequence(int &rbegin_, int &rend_, DataOutIter &out_)
void operator()(VectorBlock const &v) const
std::vector< size_t > const & colOff
bool extractOnlyLowerTriangle
bool inRange(size_t r, size_t c) const
void operator()(MatrixBlock const &mb) const
BlockToTriplet(size_t rbegin_, size_t cbegin_, std::vector< size_t > const &rowOff_, std::vector< size_t > const &colOff_, IdxOutIter &ri_, IdxOutIter &ci_, DataOutIter &xi_, bool extractOnlyLowerTriangle_)
std::vector< size_t > const & rowOff
CountNonzeros(size_t &n_, size_t rbegin_, size_t rend_, size_t cbegin_, size_t cend_, bool onlyLowerTriangle_)
bool inRange(size_t r, size_t c) const
void operator()(MatrixBlock const &mb) const
Variables and their descriptions.