1#ifndef DUNE_FEM_OPERATOR_LINEAR_TEST_CHECKLINEAROPERATOR_HH
2#define DUNE_FEM_OPERATOR_LINEAR_TEST_CHECKLINEAROPERATOR_HH
16#include <dune/fem/common/hybrid.hh>
17#include <dune/fem/operator/common/stencil.hh>
18#include <dune/fem/operator/common/temporarylocalmatrix.hh>
29 template<
class DomainSpace,
class RangeSpace >
34 typedef typename DomainSpace::IteratorType Iterator1;
35 typedef typename DomainSpace::EntityType Entity1;
36 typedef typename RangeSpace::IteratorType Iterator2;
37 typedef typename RangeSpace::EntityType Entity2;
39 Iterator () =
default;
41 Iterator ( Iterator1 it1, Iterator2 it2 ) : it_( it1, it2 ) {}
43 Iterator &operator++ () { ++it_.first; ++it_.second;
return *
this; }
45 std::pair< Entity1, Entity2 > operator* ()
const {
return std::make_pair( *it_.first, *it_.second ); }
47 bool operator!= (
const Iterator &other )
const {
return (it_ != other.it_); }
48 bool operator== (
const Iterator &other )
const {
return (it_ == other.it_); }
51 std::pair< Iterator1, Iterator2 > it_;
54 DiagonalRange (
const DomainSpace &dSpace,
const RangeSpace &rSpace )
55 : dSpace_( dSpace ), rSpace_( rSpace )
58 Iterator begin ()
const {
return Iterator( dSpace_.begin(), rSpace_.begin() ); }
59 Iterator end ()
const {
return Iterator( dSpace_.end(), rSpace_.end() ); }
62 const DomainSpace &dSpace_;
63 const RangeSpace &rSpace_;
71 template<
class Space1,
class Space2 >
72 DiagonalRange< Space1, Space2 > diagonalRange (
const Space1 &space1,
const Space2 &space2 )
74 return DiagonalRange< Space1, Space2 >( space1, space2 );
82 template<
class DomainSpace,
class RangeSpace >
86 typedef RangeStencil< DomainSpace, RangeSpace > ThisType;
89 template<
class Range >
90 RangeStencil (
const DomainSpace &dSpace,
const RangeSpace &rSpace,
const Range &range )
91 : BaseType( dSpace, rSpace )
93 for(
const auto &entry : range )
97 virtual void setupStencil()
const
99 DUNE_THROW(NotImplemented,
"This is done in the constructor");
105 namespace CheckLinearOperator
108 template<
class LocalMatrix >
109 inline void verifyPermutation (
const LocalMatrix &localMatrix,
const std::vector< std::pair< int, int > > &permutation )
111 for(
const auto &p : permutation )
113 if( localMatrix.get( p.first, p.second ) != 1.0 )
118 template<
class LinearOperator,
class DomainEntity,
class RangeEntity >
119 inline void_t< typename LinearOperator::LocalMatrixType >
120 verifyLocalMatrixPermutation (
const LinearOperator &linOp,
const DomainEntity &domainEntity,
const RangeEntity &rangeEntity,
121 const std::vector< std::pair< int, int > > &permutation, PriorityTag< 1 > )
124 localMat( linOp.domainSpace(), linOp.rangeSpace() );
125 localMat.bind( domainEntity, rangeEntity );
126 linOp.getLocalMatrix( domainEntity, rangeEntity, localMat );
127 verifyPermutation( localMat, permutation );
131 template<
class LinearOperator,
class DomainEntity,
class RangeEntity >
132 inline void verifyLocalMatrixPermutation (
const LinearOperator &linOp,
const DomainEntity &domainEntity,
const RangeEntity &rangeEntity,
133 const std::vector< std::pair< int, int > > &permutation, PriorityTag< 0 > )
135 static bool warn =
true;
137 std::cout <<
"Note: " <<
className( linOp ) <<
" does not support old-style local matrix interface." << std::endl;
141 template<
class LinearOperator,
class DomainEntity,
class RangeEntity >
142 inline void verifyLocalMatrixPermutation (
const LinearOperator &linOp,
const DomainEntity &domainEntity,
const RangeEntity &rangeEntity,
143 const std::vector< std::pair< int, int > > &permutation )
145 verifyLocalMatrixPermutation( linOp, domainEntity, rangeEntity, permutation, PriorityTag< 42 >() );
155 template<
class LinearOperator,
class Range >
156 inline void checkLinearOperator ( LinearOperator &linOp,
const Range &range,
const std::vector< std::pair< int, int > > &permutation )
162 typedef typename DomainFunctionType::DiscreteFunctionSpaceType DomainSpaceType;
163 typedef typename RangeFunctionType::DiscreteFunctionSpaceType RangeSpaceType;
166 const DomainSpaceType &dSpace = linOp.domainSpace();
167 const RangeSpaceType &rSpace = linOp.rangeSpace();
170 DomainFunctionType domainFunction(
"domain Function", dSpace );
171 RangeFunctionType rangeFunction1(
"range Function1", rSpace );
172 RangeFunctionType rangeFunction2(
"range Function2", rSpace );
175 RangeStencil< DomainSpaceType, RangeSpaceType > stencil( dSpace, rSpace, range );
177 for(
int k=0; k<4; ++k )
180 linOp.reserve( stencil );
187 for(
const auto &entry : range )
189 auto domainEntity = entry.first;
190 auto rangeEntity = entry.second;
193 temp.init( domainEntity, rangeEntity );
195 for(
const auto &p : permutation )
196 temp.set( p.first, p.second, 1.0 );
198 linOp.addLocalMatrix( domainEntity, rangeEntity, temp );
199 linOp.addScaledLocalMatrix( domainEntity, rangeEntity, temp, -1.0 );
203 linOp.flushAssembly();
206 for(
const auto &entry : range )
208 auto domainEntity = entry.first;
209 auto rangeEntity = entry.second;
213 temp.init( domainEntity, rangeEntity );
215 for(
const auto &p : permutation )
216 temp.set( p.first, p.second, 1.0 );
218 linOp.setLocalMatrix( domainEntity, rangeEntity, temp );
222 linOp.flushAssembly();
232 std::cout <<
"operator does not implement unitRow method\n";
238 for(
const auto &entry : range )
240 auto domainEntity = entry.first;
241 auto rangeEntity = entry.second;
243 temp.init( domainEntity, rangeEntity );
245 linOp.getLocalMatrix( domainEntity, rangeEntity, temp );
246 CheckLinearOperator::verifyPermutation( temp, permutation );
249 CheckLinearOperator::verifyLocalMatrixPermutation( linOp, domainEntity, rangeEntity, permutation );
253 domainFunction.clear();
254 std::size_t minNumDofs = std::min( domainFunction.blocks(), rangeFunction1.blocks() );
255 for( std::size_t i = 0; i < minNumDofs; ++i )
257 auto block = domainFunction.dofVector()[ i ];
258 Hybrid::forEach(
typename DomainSpaceType::LocalBlockIndices(), [ &block, i ] (
auto &&j ) { block[ j ] = i; } );
260 linOp( domainFunction, rangeFunction1 );
263 rangeFunction2.clear();
265 std::vector< double > values;
266 for(
const auto &entry : range )
268 auto domainEntity = entry.first;
269 auto rangeEntity = entry.second;
271 tmp.resize( dSpace.blockMapper().numDofs( domainEntity ) * DomainSpaceType::localBlockSize );
272 domainFunction.getLocalDofs( domainEntity, tmp );
275 values.resize( rSpace.blockMapper().numDofs( rangeEntity ) * RangeSpaceType::localBlockSize, 0.0 );
277 for(
const auto &p : permutation )
278 values[ p.first ] = tmp[ p.second ];
279 rangeFunction2.setLocalDofs( rangeEntity, values );
281 rangeFunction2.communicate();
283 rangeFunction1.dofVector() -= rangeFunction2.dofVector();
285 double diff = rangeFunction1.scalarProductDofs( rangeFunction1 );
286 if( std::abs( diff ) > 1e-8 )
default implementation for a general operator stencil
Definition: stencil.hh:35
void fill(const DomainEntityType &dEntity, const RangeEntityType &rEntity, bool fillGhost=true) const
Create stencil entries for (dEntity,rEntity) pair.
Definition: stencil.hh:93
A local matrix with a small array as storage.
Definition: temporarylocalmatrix.hh:100
Default exception for dummy implementations.
Definition: exceptions.hh:263
A free function to provide the demangled class name of a given object or type as a string.
This file implements a dense vector with a dynamic size.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:256
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:238
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:260
Dune namespace.
Definition: alignedallocator.hh:13
std::string className()
Provide the demangled class name of a type T as a string.
Definition: classname.hh:47
DomainFunction DomainFunctionType
type of discrete function in the operator's domain
Definition: operator.hh:36
DomainFunction RangeFunctionType
type of discrete function in the operator's range
Definition: operator.hh:38
Traits for type conversions and type information.
Utilities for type computations, constraining overloads, ...