1 #ifndef DUNE_FEM_DISCRETEFUNCTION_HH 2 #define DUNE_FEM_DISCRETEFUNCTION_HH 3 4 #include <cassert> 5 6 #include <complex> 7 #include <memory> 8 #include <ostream> 9 #include <string> 10 #include <typeindex> 11 12 #include <dune/common/dynvector.hh> 13 14 #include <dune/fem/function/common/dofiterator.hh> 15 #include <dune/fem/function/common/function.hh> 16 #include <dune/fem/function/common/functor.hh> 17 #include <dune/fem/function/common/scalarproducts.hh> 18 #include <dune/fem/function/common/rangegenerators.hh> 19 #include <dune/fem/function/localfunction/temporary.hh> 20 #include <dune/fem/gridpart/common/entitysearch.hh> 21 #include <dune/fem/io/file/persistencemanager.hh> 22 #include <dune/fem/io/streams/streams.hh> 23 #include <dune/fem/misc/functor.hh> 24 #include <dune/fem/misc/threads/threadmanager.hh> 25 #include <dune/fem/space/common/discretefunctionspace.hh> 26 #include <dune/fem/storage/envelope.hh> 27 #include <dune/fem/storage/referencevector.hh> 28 #include <dune/fem/version.hh> 29 30 31 namespace Dune 32 { 33 34 namespace Fem 35 { 36 37 /** @addtogroup DiscreteFunction 38 * The DiscreteFunction is responsible for the dof storage. This can be 39 * done in various ways an is left to the user. The user has to derive his 40 * own implementation from the DiscreteFunctionDefault class. The implementations 41 * in the default class which are ineffecient for the dof storage in the derived 42 * class can be overloaded. 43 * 44 * \remarks 45 * The interface for using a DiscreteFunction is defined by 46 * the class DiscreteFunctionInterface. 47 * 48 * @{ 49 */ 50 51 /** \brief base class for determing whether a class is a discrete function or not */ 52 class IsDiscreteFunction 53 {}; 54 55 /** \brief base class for determing whether a function has local functions or not */ 56 class HasLocalFunction 57 {}; 58 59 60 template< class DiscreteFunction > 61 struct DiscreteFunctionTraits; 62 63 template< class Traits > 64 class DiscreteFunctionDefault; 65 66 //---------------------------------------------------------------------- 67 //- 68 //- --DiscreteFunctionInterface 69 //- 70 //---------------------------------------------------------------------- 71 /** This is the interface of a discrete function which describes the 72 * features of a discrete function. 73 * It contains a local function and a dof iterator which can 74 * iterate over all dofs of one level. Via the method access the local 75 * dofs and basis functions can be accessed for a given entity. 76 * The DOF-Iterators are STL-like Iterators, i.e. they can be dereferenced 77 * giving the corresponding DOF. 78 * 79 * \interfaceclass 80 */ 81 template< class Impl > 82 class DiscreteFunctionInterface 83 : public Fem::Function< typename DiscreteFunctionTraits< Impl >::DiscreteFunctionSpaceType::FunctionSpaceType, Impl >, 84 public IsDiscreteFunction, 85 public HasLocalFunction 86 { 87 typedef DiscreteFunctionInterface< Impl > ThisType; 88 typedef Fem::Function< typename DiscreteFunctionTraits< Impl >::DiscreteFunctionSpaceType::FunctionSpaceType, Impl > BaseType; 89 90 public: 91 //! type of the traits 92 typedef DiscreteFunctionTraits< Impl > Traits; 93 94 //! type of the implementaton (Barton-Nackman) 95 typedef typename Traits :: DiscreteFunctionType DiscreteFunctionType; 96 97 //! type of associated discrete function space 98 typedef typename Traits :: DiscreteFunctionSpaceType DiscreteFunctionSpaceType; 99 100 //! type of associated function space 101 typedef typename DiscreteFunctionSpaceType :: FunctionSpaceType FunctionSpaceType; 102 103 //! type of the discrete function interface (this type) 104 typedef DiscreteFunctionInterface< Impl > DiscreteFunctionInterfaceType; 105 106 //! type of domain field, i.e. type of coordinate component 107 typedef typename DiscreteFunctionSpaceType :: DomainFieldType DomainFieldType; 108 //! type of range field, i.e. dof type 109 typedef typename DiscreteFunctionSpaceType :: RangeFieldType RangeFieldType; 110 //! type of domain, i.e. type of coordinates 111 typedef typename DiscreteFunctionSpaceType :: DomainType DomainType; 112 //! type of range, i.e. result of evaluation 113 typedef typename DiscreteFunctionSpaceType :: RangeType RangeType; 114 //! type of jacobian, i.e. type of evaluated gradient 115 typedef typename DiscreteFunctionSpaceType :: JacobianRangeType JacobianRangeType; 116 117 //! type of the underlying grid part 118 typedef typename DiscreteFunctionSpaceType::GridPartType GridPartType; 119 typedef typename GridPartType::GridViewType GridView; 120 121 //! type of the underlying grid 122 typedef typename DiscreteFunctionSpaceType :: GridType GridType; 123 124 //! type of local functions 125 typedef typename Traits :: LocalFunctionType LocalFunctionType; 126 127 //! type of the dof vector used in the discrete function implementation 128 typedef typename Traits :: DofVectorType DofVectorType; 129 130 //! type of the dof iterator used in the discrete function implementation 131 typedef typename Traits :: DofIteratorType DofIteratorType; 132 133 //! type of the constantdof iterator used in the discrete function implementation 134 typedef typename Traits :: ConstDofIteratorType ConstDofIteratorType; 135 136 typedef typename Traits :: DofType DofType; 137 typedef typename Traits :: DofBlockType DofBlockType; 138 typedef typename Traits :: ConstDofBlockType ConstDofBlockType; 139 typedef typename Traits :: DofBlockPtrType DofBlockPtrType; 140 typedef typename Traits :: ConstDofBlockPtrType ConstDofBlockPtrType; 141 142 //! type of mapping base class for this discrete function 143 typedef typename BaseType :: MappingType MappingType; 144 145 typedef typename DiscreteFunctionSpaceType::LocalBlockIndices BlockIndices; 146 147 //! size of the dof blocks 148 static constexpr std::size_t blockSize = Hybrid::size( BlockIndices() ); 149 150 template< class Operation > 151 struct CommDataHandle 152 { 153 typedef typename DiscreteFunctionSpaceType 154 :: template CommDataHandle< DiscreteFunctionType, Operation > :: Type 155 Type; 156 }; 157 158 //! type of entity local functions are defined on 159 typedef typename DiscreteFunctionSpaceType :: EntityType EntityType; 160 161 protected: 162 using BaseType::asImp; 163 164 //! default constructor 165 DiscreteFunctionInterface () = default; 166 167 DiscreteFunctionInterface ( const ThisType& ) = default; 168 DiscreteFunctionInterface ( ThisType && ) = default; 169 public: 170 ThisType& operator= ( ThisType&& ) = delete; 171 ThisType &operator= ( const ThisType& ) = delete; 172 dofVector()173 DofVectorType &dofVector() 174 { 175 return asImp().dofVector(); 176 } dofVector() const177 const DofVectorType &dofVector() const 178 { 179 return asImp().dofVector(); 180 } 181 182 /** \brief obtain the name of the discrete function 183 * 184 * \returns string holding name of discrete function 185 */ name() const186 const std::string &name () const 187 { 188 return asImp().name(); 189 } 190 191 /** \brief obtain the name of the discrete function 192 * 193 * \returns string holding name of discrete function 194 */ name()195 std::string &name () 196 { 197 return asImp().name(); 198 } 199 200 /** \brief obtain an upper bound on the polynomial order of the underlying space. 201 */ order() const202 const std::string &order () const 203 { 204 return asImp().order(); 205 } 206 207 /** \copydoc Dune::Fem::DiscreteFunctionSpaceInterface::continuous */ continuous() const208 bool continuous() const 209 { 210 return asImp().continuous(); 211 } 212 213 /** \brief obtain a reference to the corresponding DiscreteFunctionSpace */ space() const214 const DiscreteFunctionSpaceType &space () const 215 { 216 return asImp().space(); 217 } 218 219 /** \brief obtain a reference to the underlying grid part */ gridPart() const220 const GridPartType &gridPart () const 221 { 222 return asImp().gridPart(); 223 } 224 225 /** \brief obtain a local function for an entity (read-write) 226 * 227 * \param[in] entity Entity to focus view of discrete function 228 * \returns a local function associated with the entity 229 */ 230 [[deprecated("Use {Const,Temporary,Mutable}LocalFunction and LocalContribution instead!")]] localFunction(const EntityType & entity)231 LocalFunctionType localFunction ( const EntityType &entity ) 232 { 233 return asImp().localFunction( entity ); 234 } 235 236 /** \brief obtain a local function for an entity (read-write) 237 * 238 * \param[in] entity Entity to focus view of discrete function 239 * \returns a local function associated with the entity 240 */ 241 [[deprecated("Use {Const,Temporary,Mutable}LocalFunction and LocalContribution instead!")]] localFunction(const EntityType & entity) const242 const LocalFunctionType localFunction ( const EntityType &entity ) const 243 { 244 return asImp().localFunction( entity ); 245 } 246 247 /** \brief obtain an uninitialized local function (read-write) 248 * 249 * \note before calling any method of the local function initialize it passing an entity 250 * 251 * \returns an uninitialized local function 252 */ 253 [[deprecated("Use {Const,Temporary,Mutable}LocalFunction and LocalContribution instead!")]] localFunction()254 LocalFunctionType localFunction () 255 { 256 return asImp().localFunction(); 257 } 258 259 260 /** \brief add scaled local Dofs to dof vector associated with the entity 261 * 262 * \param[in] entity Entity to focus view of discrete function 263 * \param[in] s scaling factor 264 * \param[in] localDofs the local dofs vector to be added 265 */ 266 template< class LocalDofs > addScaledLocalDofs(const EntityType & entity,const RangeFieldType & s,const LocalDofs & localDofs)267 void addScaledLocalDofs ( const EntityType &entity, const RangeFieldType &s, const LocalDofs &localDofs ) 268 { 269 asImp().addScaledLocalDofs( entity, s, localDofs ); 270 } 271 272 /** \brief add local Dofs to dof vector associated with the entity 273 * 274 * \param[in] entity Entity to focus view of discrete function 275 * \param[in] localDofs the local dofs vector to be added 276 */ 277 template< class LocalDofs > addLocalDofs(const EntityType & entity,const LocalDofs & localDofs)278 void addLocalDofs ( const EntityType &entity, const LocalDofs &localDofs ) 279 { 280 asImp().addLocalDofs( entity, localDofs ); 281 } 282 283 /** \brief set local Dofs to dof vector associated with the entity 284 * 285 * \param[in] entity Entity to focus view of discrete function 286 * \param[in] localDofs the local dofs vector to be set 287 */ 288 template< class LocalDofs > setLocalDofs(const EntityType & entity,const LocalDofs & localDofs)289 void setLocalDofs ( const EntityType &entity, const LocalDofs &localDofs ) 290 { 291 asImp().setLocalDofs( entity, localDofs ); 292 } 293 294 /** \brief fill local Dofs to dof vector associated with the entity 295 * 296 * \param[in] entity Entity to focus view of discrete function 297 * \param[out] localDofs the local dofs vector to be set 298 * 299 * \note localDofs should have sufficient size to store the dof values 300 */ 301 template< class Vector > getLocalDofs(const EntityType & entity,Vector & localDofs) const302 void getLocalDofs ( const EntityType &entity, Vector &localDofs ) const 303 { 304 asImp().getLocalDofs( entity, localDofs ); 305 } 306 307 /** \brief obtain an uninitialized local function (read-write) 308 * 309 * \note before calling any method of the local function initialize it passing an entity 310 * 311 * \returns an uninitialized local function 312 */ 313 [[deprecated("Use {Const,Temporary,Mutable}LocalFunction and LocalContribution instead!")]] localFunction() const314 const LocalFunctionType localFunction () const 315 { 316 return asImp().localFunction(); 317 } 318 319 /** \brief set all degrees of freedom to zero */ clear()320 void clear() 321 { 322 asImp().clear(); 323 } 324 325 /** \brief obtain total number of DoFs 326 * 327 * The number of DoFs (degrees of freedom) can also be seen as the size 328 * of the discrete function, i.e., the size of the vector that forms this 329 * discrete funciton. 330 * 331 * \returns total number of DoFs for this discrete function 332 */ size() const333 int size() const 334 { 335 return asImp().size(); 336 } 337 338 /** \brief obtain total number of blocks, i.e. size / blockSize. 339 * 340 * The number of blocks of DoFs (degrees of freedom) can also be seen 341 * as the size of the discrete function divided by the blockSize. 342 * 343 * \returns total number of DoFs blocks 344 */ blocks() const345 int blocks() const 346 { 347 return asImp().blocks(); 348 } 349 350 /** \brief obtain an iterator pointing to the first DoF (read-only) 351 * 352 * \returns a DoF iterator pointing to first DoF (degre of freedom) 353 */ dbegin() const354 ConstDofIteratorType dbegin () const 355 { 356 return asImp().dbegin (); 357 } 358 359 /** \brief obtain an iterator pointing behind the last DoF (read-only) 360 * 361 * \returns a DoF iterator pointing behind the last DoF (degree of freedom) 362 */ dend() const363 ConstDofIteratorType dend () const 364 { 365 return asImp().dend (); 366 } 367 368 /** \brief obtain an iterator pointing to the first DoF (read-write) 369 * 370 * \returns a DoF iterator pointing to first DoF (degre of freedom) 371 */ dbegin()372 DofIteratorType dbegin () 373 { 374 return asImp().dbegin (); 375 } 376 377 /** \brief obtain an iterator pointing behind the last DoF (read-write) 378 * 379 * \returns a DoF iterator pointing behind the last DoF (degree of freedom) 380 */ dend()381 DofIteratorType dend () 382 { 383 return asImp().dend (); 384 } 385 386 /** \brief axpy operation 387 * 388 * Adds s * g to this discrete function. 389 * 390 * \param[in] s scalar value to scale g with 391 * \param[in] g discrete function to add 392 */ axpy(const RangeFieldType & s,const DiscreteFunctionInterfaceType & g)393 void axpy( const RangeFieldType &s, const DiscreteFunctionInterfaceType &g ) 394 { 395 asImp().axpy( s, g ); 396 } 397 398 /** \brief Scalar product between the DoFs of two discrete functions 399 * 400 * \note This is a parallel scalar product, so do not sum over all 401 * processes after calling scalarProductDofs! 402 * 403 * \note It is assumed that the discrete function has been communicated 404 * (i.e., every local DoF hat the value of the corresponding global 405 * DoF). 406 * 407 * \param[in] other discrete function to evaluate the scalar product with 408 * 409 * \returns the scalar product of the DoF-vectors 410 */ 411 template <class DFType> scalarProductDofs(const DiscreteFunctionInterface<DFType> & other) const412 RangeFieldType scalarProductDofs ( const DiscreteFunctionInterface< DFType > &other ) const 413 { 414 return asImp().scalarProductDofs( other.asImp() ); 415 } 416 417 /** \brief Squared small l^2 norm of all dofs 418 * 419 * \note This is already parallel, so do not sum over all 420 * processes after calling scalarProductDofs! 421 * 422 * \note It is assumed that the discrete function has been communicated 423 * (i.e., every local DoF hat the value of the corresponding global 424 * DoF). 425 * 426 * \returns the squared norm of the DoF-vectors 427 */ normSquaredDofs() const428 typename Dune::FieldTraits< RangeFieldType >::real_type normSquaredDofs ( ) const 429 { 430 return asImp().normSquaredDofs( ); 431 } 432 433 /** \brief print all DoFs to a stream (for debugging purposes) 434 * 435 * \param[in] out stream to print to 436 */ print(std::ostream & out) const437 void print( std :: ostream &out ) const 438 { 439 asImp().print( out ); 440 } 441 442 /** \brief check for NaNs 443 * \returns if one of the DoFs is NaN \b false is returned, otherwise \b true 444 */ dofsValid() const445 bool dofsValid () const 446 { 447 return asImp().dofsValid(); 448 } 449 450 /** \brief assign the DoFs of another discrete function to this one 451 * 452 * \param[in] g discrete function which is copied 453 */ 454 template < class DFType > assign(const DiscreteFunctionInterface<DFType> & g)455 void assign( const DiscreteFunctionInterface< DFType > &g ) 456 { 457 asImp().assign( g ); 458 } 459 460 /** \brief return reference to data handle object */ 461 template< class Operation > dataHandle(const Operation & operation)462 typename CommDataHandle< Operation >::Type dataHandle( const Operation &operation ) 463 { 464 return asImp().dataHandle( operation ); 465 } 466 467 /** \brief do default communication of space for this discrete function */ communicate()468 void communicate() 469 { 470 CHECK_AND_CALL_INTERFACE_IMPLEMENTATION( asImp().communicate() ); 471 } 472 473 /** \brief add another discrete function to this one 474 * 475 * \param[in] g discrete function to add 476 * 477 * \returns a reference to this discrete function (i.e. *this) 478 */ 479 template < class DFType > operator +=(const DiscreteFunctionInterface<DFType> & g)480 DiscreteFunctionType &operator+=(const DiscreteFunctionInterface< DFType > &g) 481 { 482 return asImp().operator+=( g ); 483 } 484 485 /** \brief substract all degrees of freedom from given discrete function using the dof iterators 486 * 487 * \param[in] g discrete function which is substracted from this discrete function 488 * 489 * \returns reference to this (i.e. *this) 490 */ 491 template < class DFType > operator -=(const DiscreteFunctionInterface<DFType> & g)492 DiscreteFunctionType &operator-=(const DiscreteFunctionInterface< DFType > &g) 493 { 494 return asImp().operator-=( g ); 495 } 496 497 /** \brief multiply all DoFs by a scalar factor 498 * 499 * \param[in] scalar factor to muliply all DoFs by 500 * 501 * \returns a reference to this discrete function (i.e. *this) 502 */ operator *=(const RangeFieldType & scalar)503 DiscreteFunctionType &operator*= ( const RangeFieldType &scalar ) 504 { 505 return asImp() *= scalar; 506 } 507 508 /** \brief devide all DoFs by a scalar factor 509 * 510 * \param[in] scalar factor to divide all DoFs by 511 * 512 * \returns a reference to this discrete function (i.e. *this) 513 */ operator /=(const RangeFieldType & scalar)514 DiscreteFunctionType &operator/= ( const RangeFieldType &scalar ) 515 { 516 return asImp() /= scalar; 517 } 518 519 /** \brief read the discrete function from a stream 520 * 521 * \param[in] in stream to read the discrete function from 522 * 523 * \note This call will automatically enable dof compression for this 524 * discrete function. 525 */ 526 template< class StreamTraits > read(InStreamInterface<StreamTraits> & in)527 void read ( InStreamInterface< StreamTraits > &in ) 528 { 529 asImp().read( in ); 530 } 531 532 /** \brief write the discrete function into a stream 533 * 534 * \param[in] out stream to write the discrete function to 535 */ 536 template< class StreamTraits > write(OutStreamInterface<StreamTraits> & out) const537 void write ( OutStreamInterface< StreamTraits > &out ) const 538 { 539 asImp().write( out ); 540 } 541 542 /** \brief Enable this discrete function for dof compression, 543 * i.e. during grid changes a dof compression 544 * is done when the DofManagers compress is called. 545 */ enableDofCompression()546 void enableDofCompression() 547 { 548 asImp().enableDofCompression(); 549 } 550 551 //TODO: this needs to be revised, the definition should be in GridPart 552 typedef LoadBalanceLeafData< ThisType > DefaultLoadBalanceContainsCheckType; defaultLoadBalanceContainsCheck() const553 DefaultLoadBalanceContainsCheckType defaultLoadBalanceContainsCheck() const 554 { 555 return DefaultLoadBalanceContainsCheckType( *this ); 556 } 557 }; 558 559 560 561 //************************************************************************* 562 // 563 // --DiscreteFunctionDefault 564 // 565 //! Default implementation of the discrete function. This class is 566 //! responsible for the dof storage. Different implementations of the 567 //! discrete function use different dof storage. 568 //! The default implementation provides +=, -= and so on operators and 569 //! a DofIterator access, which can run over all dofs in an efficient way. 570 //! Furthermore with an entity you can access a local function to evaluate 571 //! the discrete function by multiplying the dofs and the basefunctions. 572 //! 573 //************************************************************************* 574 template< class Impl > 575 class DiscreteFunctionDefault 576 : public DiscreteFunctionInterface< Impl > , 577 public PersistentObject 578 { 579 typedef DiscreteFunctionDefault< Impl > ThisType; 580 typedef DiscreteFunctionInterface< Impl > BaseType; 581 582 public: 583 typedef typename BaseType :: Traits Traits; 584 585 //! type of the discrete function (Barton-Nackman parameter) 586 typedef Impl DiscreteFunctionType; 587 588 typedef typename BaseType::DiscreteFunctionInterfaceType DiscreteFunctionInterfaceType; 589 590 private: 591 typedef DiscreteFunctionDefault< Impl > DiscreteFunctionDefaultType; 592 593 enum { myId_ = 0 }; 594 595 protected: 596 typedef ParallelScalarProduct< DiscreteFunctionInterfaceType > ScalarProductType; 597 598 public: 599 //! type of discrete function space 600 typedef typename BaseType::DiscreteFunctionSpaceType DiscreteFunctionSpaceType; 601 602 //! type of the underlying grid part 603 typedef typename BaseType::GridPartType GridPartType; 604 605 //! type of domain vector 606 typedef typename DiscreteFunctionSpaceType :: DomainType DomainType; 607 //! type of range vector 608 typedef typename DiscreteFunctionSpaceType :: RangeType RangeType; 609 //! type of jacobian 610 typedef typename DiscreteFunctionSpaceType :: JacobianRangeType JacobianRangeType; 611 //! type of hessian 612 typedef typename DiscreteFunctionSpaceType :: HessianRangeType HessianRangeType; 613 614 //! type of domain field (usually a float type) 615 typedef typename DiscreteFunctionSpaceType :: DomainFieldType DomainFieldType; 616 //! type of range field (usually a float type) 617 typedef typename DiscreteFunctionSpaceType :: RangeFieldType RangeFieldType; 618 619 //! type of the dof iterator 620 typedef typename Traits :: DofIteratorType DofIteratorType; 621 //! type of the const dof iterator 622 typedef typename Traits :: ConstDofIteratorType ConstDofIteratorType; 623 624 //! type of DofVector 625 typedef typename Traits :: DofVectorType DofVectorType; 626 627 //! type of LocalDofVector 628 typedef typename Traits :: LocalDofVectorType LocalDofVectorType; 629 //! type of LocalDofVector 630 typedef typename Traits :: LocalDofVectorAllocatorType LocalDofVectorAllocatorType; 631 632 //! type of local functions 633 typedef typename BaseType :: LocalFunctionType LocalFunctionType; 634 typedef typename LocalFunctionType::LocalCoordinateType LocalCoordinateType; 635 636 typedef typename BaseType :: DofBlockType DofBlockType; 637 typedef typename BaseType :: ConstDofBlockType ConstDofBlockType; 638 typedef typename BaseType :: DofBlockPtrType DofBlockPtrType; 639 typedef typename BaseType :: ConstDofBlockPtrType ConstDofBlockPtrType; 640 641 typedef typename BaseType :: EntityType EntityType ; 642 643 typedef typename BaseType :: DofType DofType; 644 645 //! size type of the block vector 646 typedef typename DofVectorType::SizeType SizeType; 647 648 using BaseType::blockSize; 649 650 template< class Operation > 651 struct CommDataHandle 652 : public BaseType :: template CommDataHandle< Operation > 653 {}; 654 655 protected: 656 using BaseType :: asImp; 657 658 typedef TemporaryLocalFunction< DiscreteFunctionSpaceType > TemporaryLocalFunctionType; 659 660 /** \brief Constructor storing discrete function space and local function 661 * factory 662 * 663 * The discrete function space is passed to the interface class and the 664 * local function storage is initialized. 665 * 666 * \param[in] name name of the discrete function 667 * \param[in] dfSpace discrete function space 668 * \param[in] lfFactory local function factory 669 */ 670 DiscreteFunctionDefault ( const std::string &name, const DiscreteFunctionSpaceType &dfSpace ); 671 672 DiscreteFunctionDefault ( std::string name, std::shared_ptr< const DiscreteFunctionSpaceType > dfSpace ); 673 674 DiscreteFunctionDefault ( const ThisType& ); 675 DiscreteFunctionDefault ( ThisType && other ); 676 677 public: 678 ThisType& operator= ( ThisType&& ) = delete; 679 ThisType &operator= ( const ThisType& ) = delete; 680 681 // Default Implementations 682 // ----------------------- 683 684 /** \copydoc Dune::Fem::DiscreteFunctionInterface::name() const */ name() const685 const std::string &name () const { return name_; } 686 687 /** \copydoc Dune::Fem::DiscreteFunctionInterface::name() */ name()688 std::string &name () { return name_; } 689 690 /** \copydoc Dune::Fem::DiscreteFunctionInterface::order() */ order() const691 constexpr int order() const 692 { 693 return space().order(); 694 } 695 696 /** \copydoc Dune::Fem::DiscreteFunctionInterface::continuous */ continuous() const697 bool continuous() const 698 { 699 return space().continuous(); 700 } 701 702 /** \copydoc Dune::Fem::DiscreteFunctionInterface::space() const */ space() const703 const DiscreteFunctionSpaceType &space () const { return *dfSpace_; } 704 705 /** \brief obtain a reference to the underlying grid part */ gridPart() const706 const GridPartType &gridPart () const { return space().gridPart(); } 707 708 /** \copydoc Dune::Fem::DiscreteFunctionInterface::localFunction(const EntityType &entity) */ 709 [[deprecated("Use {Const,Temporary,Mutable}LocalFunction and LocalContribution instead!")]] localFunction(const EntityType & entity)710 LocalFunctionType localFunction ( const EntityType &entity ) { return LocalFunctionType( asImp(), entity ); } 711 712 /** \copydoc Dune::Fem::DiscreteFunctionInterface::localFunction(const EntityType &entity) */ 713 [[deprecated("Use {Const,Temporary,Mutable}LocalFunction and LocalContribution instead!")]] localFunction(const EntityType & entity) const714 const LocalFunctionType localFunction ( const EntityType &entity ) const { return LocalFunctionType( asImp(), entity ); } 715 716 /** \copydoc Dune::Fem::DiscreteFunctionInterface::localFunction() */ 717 [[deprecated("Use {Const,Temporary,Mutable}LocalFunction and LocalContribution instead!")]] localFunction()718 LocalFunctionType localFunction () { return LocalFunctionType( asImp() ); } 719 720 /** \copydoc Dune::Fem::DiscreteFunctionInterface::localFunction() */ 721 [[deprecated("Use {Const,Temporary,Mutable}LocalFunction and LocalContribution instead!")]] localFunction() const722 const LocalFunctionType localFunction () const { return LocalFunctionType( asImp() ); } 723 724 /** \copydoc Dune::Fem::DiscreteFunctionInterface::clear() */ clear()725 void clear() { dofVector().clear(); } 726 dofVector()727 DofVectorType &dofVector() { return asImp().dofVector(); } dofVector() const728 const DofVectorType &dofVector() const { return asImp().dofVector(); } 729 730 /** \copydoc Dune::Fem::DiscreteFunctionInterface::blocks() */ blocks() const731 int blocks() const { return dofVector().size(); } 732 733 /** \copydoc Dune::Fem::DiscreteFunctionInterface::block( unsigned int index ) */ block(unsigned int index)734 DofBlockPtrType block ( unsigned int index ) 735 { 736 return dofVector().blockPtr( index ); 737 } 738 739 /** \copydoc Dune::Fem::DiscreteFunctionInterface::block( unsigned int index ) const */ block(unsigned int index) const740 ConstDofBlockPtrType block ( unsigned int index ) const 741 { 742 return dofVector().blockPtr( index ); 743 } 744 745 /** \brief Return the number of blocks in the block vector 746 * 747 * \return Number of block in the block vector 748 */ size() const749 SizeType size () const { return dofVector().size() * blockSize; } 750 751 /** \brief Obtain the constant iterator pointing to the first dof 752 * 753 * \return Constant iterator pointing to the first dof 754 */ dbegin() const755 ConstDofIteratorType dbegin () const { return dofVector().begin(); } 756 757 /** \brief Obtain the non-constant iterator pointing to the first dof 758 * 759 * \return Non-Constant iterator pointing to the first dof 760 */ dbegin()761 DofIteratorType dbegin () { return dofVector().begin(); } 762 763 /** \brief Obtain the constant iterator pointing to the last dof 764 * 765 * \return Constant iterator pointing to the last dof 766 */ dend() const767 ConstDofIteratorType dend () const { return dofVector().end(); } 768 769 /** \brief Obtain the non-constant iterator pointing to the last dof 770 * 771 * \return Non-Constant iterator pointing to the last dof 772 */ dend()773 DofIteratorType dend () { return dofVector().end(); } 774 775 /** \copydoc Dune::Fem::DiscreteFunctionInterface::axpy(const RangeFieldType &s,const DiscreteFunctionInterfaceType &g) */ 776 template <class DFType> 777 void axpy ( const RangeFieldType &s, const DiscreteFunctionInterface< DFType > &g ); 778 779 /** \copydoc Dune::Fem::DiscreteFunctionInterface::axpy(const RangeFieldType &s,const DiscreteFunctionInterfaceType &g) */ axpy(const RangeFieldType & s,const DiscreteFunctionInterfaceType & g)780 void axpy ( const RangeFieldType &s, const DiscreteFunctionInterfaceType& g ) 781 { 782 dofVector().axpy( s, g.dofVector() ); 783 } 784 785 /** \copydoc Dune::Fem::DiscreteFunctionInterface::scalarProductDofs */ 786 template <class DFType> scalarProductDofs(const DiscreteFunctionInterface<DFType> & other) const787 RangeFieldType scalarProductDofs ( const DiscreteFunctionInterface< DFType > &other ) const 788 { 789 return scalarProduct_.scalarProductDofs( *this, other ); 790 } 791 792 /** \copydoc Dune::Fem::DiscreteFunctionInterface::normSquaredDofs */ normSquaredDofs() const793 typename Dune::FieldTraits< RangeFieldType >::real_type normSquaredDofs ( ) const 794 { 795 return std::real( (*this).scalarProductDofs( *this )); 796 } 797 798 /** \copydoc Dune::Fem::DiscreteFunctionInterface::print */ 799 void print ( std :: ostream &out ) const; 800 801 /** \copydoc Dune::Fem::DiscreteFunctionInterface::dofsValid */ 802 inline bool dofsValid () const; 803 804 /** \copydoc Dune::Fem::DiscreteFunctionInterface::assign(const DiscreteFunctionInterfaceType &g) */ 805 template <class DFType> 806 void assign ( const DiscreteFunctionInterface< DFType > &g ); 807 808 /** \copydoc Dune::Fem::DiscreteFunctionInterface::assign(const DiscreteFunctionInterfaceType &g) */ assign(const DiscreteFunctionType & g)809 void assign ( const DiscreteFunctionType &g ) 810 { 811 dofVector() = g.dofVector(); 812 } 813 814 /** \copydoc Dune::Fem::DiscreteFunctionInterface::dataHandle */ 815 template< class Operation > 816 typename CommDataHandle< Operation >::Type dataHandle ( const Operation &operation ); 817 818 /** \copydoc Dune::Fem::DiscreteFunctionInterface::communicate() */ communicate()819 void communicate() 820 { 821 assert( Fem :: ThreadManager :: singleThreadMode() ); 822 this->space().communicate( asImp() ); 823 } 824 825 /** \copydoc Dune::Fem::Function::evaluate(const DomainType &x,RangeType &value) const */ evaluate(const DomainType & x,RangeType & value) const826 void evaluate ( const DomainType &x, RangeType &value ) const 827 { 828 asImp().evaluateGlobal( x, [ &value ] ( const LocalCoordinateType &x, const TemporaryLocalFunctionType &localFunction ) 829 { localFunction.evaluate( x, value ); } ); 830 } 831 832 /** \copydoc Dune::Fem::Function::jacobian(const DomainType &x,JacobianRangeType &jacobian) const */ jacobian(const DomainType & x,JacobianRangeType & jacobian) const833 void jacobian ( const DomainType &x, JacobianRangeType &jacobian ) const 834 { 835 asImp().evaluateGlobal( x, [ &jacobian ] ( const LocalCoordinateType &x, const TemporaryLocalFunctionType &localFunction ) 836 { localFunction.jacobian( x, jacobian ); } ); 837 838 } 839 840 /** \copydoc Dune::Fem::Function::hessian (const DomainType &x,HessianRangeType &hessian) const */ hessian(const DomainType & x,HessianRangeType & hessian) const841 void hessian ( const DomainType &x, HessianRangeType &hessian ) const 842 { 843 asImp().evaluateGlobal( x, [ &hessian ] ( const LocalCoordinateType &x, const TemporaryLocalFunctionType &localFunction ) 844 { localFunction.hessian( x, hessian ); } ); 845 } 846 847 /** \copydoc Dune::Fem::DiscreteFunctionInterface::operator+=(const DiscreteFunctionInterface< DFType > &g) */ 848 template <class DFType> 849 DiscreteFunctionType &operator+=(const DiscreteFunctionInterface< DFType > &g); 850 851 /** \copydoc Dune::Fem::DiscreteFunctionInterface::operator+=(const DiscreteFunctionInterface< DFType > &g) */ operator +=(const DiscreteFunctionType & g)852 DiscreteFunctionType &operator+=(const DiscreteFunctionType &g) 853 { 854 dofVector() += g.dofVector(); 855 return asImp(); 856 } 857 858 /** \copydoc Dune::Fem::DiscreteFunctionInterface::operator-=(const DiscreteFunctionInterface< DFType > &g) */ 859 template <class DFType> 860 DiscreteFunctionType &operator-=(const DiscreteFunctionInterface< DFType > &g); 861 862 /** \copydoc Dune::Fem::DiscreteFunctionInterface::operator-=(const DiscreteFunctionInterface< DFType > &g) */ operator -=(const DiscreteFunctionType & g)863 DiscreteFunctionType &operator-=(const DiscreteFunctionType& g) 864 { 865 dofVector() -= g.dofVector(); 866 return asImp(); 867 } 868 869 /** \brief multiply all DoFs with a scalar factor 870 * 871 * \param[in] scalar factor to multiply DoFs with 872 * 873 * \returns reference to this discrete function (i.e. *this) 874 */ operator *=(const RangeFieldType & scalar)875 DiscreteFunctionType &operator*= ( const RangeFieldType &scalar ) 876 { 877 dofVector() *= scalar; 878 return asImp(); 879 } 880 881 /** \brief devide all DoFs by a scalar factor 882 * 883 * \param[in] scalar factor with which all dofs are devided 884 * 885 * \returns reference to this discrete function (i.e. *this) 886 */ operator /=(const RangeFieldType & scalar)887 DiscreteFunctionType &operator/= ( const RangeFieldType &scalar ) 888 { 889 return BaseType :: operator*=( RangeFieldType(1 ) / scalar ); 890 } 891 892 /** \copydoc Dune::Fem::DiscreteFunctionInterface::read */ 893 template< class StreamTraits > 894 inline void read ( InStreamInterface< StreamTraits > &in ); 895 896 /** \copydoc Dune::Fem::DiscreteFunctionInterface::write */ 897 template< class StreamTraits > 898 inline void write ( OutStreamInterface< StreamTraits > &out ) const; 899 900 /** \copydoc Dune::Fem::DiscreteFunctionInterface::enableDofCompression() 901 * 902 * \note The default implementation does nothing. 903 */ enableDofCompression()904 void enableDofCompression () 905 {} 906 907 908 /** \copydoc Dune::Fem::DiscreteFunctionInterface::addScaledLocalDofs */ 909 template< class LocalDofs > addScaledLocalDofs(const EntityType & entity,const RangeFieldType & s,const LocalDofs & localDofs)910 void addScaledLocalDofs ( const EntityType &entity, const RangeFieldType &s, const LocalDofs &localDofs ) 911 { 912 LeftAddScaled< const LocalDofs, const RangeFieldType > assignFunctor( localDofs, s ); 913 space().blockMapper().mapEach( entity, dofBlockFunctor( dofVector(), assignFunctor ) ); 914 } 915 916 /** \copydoc Dune::Fem::DiscreteFunctionInterface::addLocalDofs */ 917 template< class LocalDofs > addLocalDofs(const EntityType & entity,const LocalDofs & localDofs)918 void addLocalDofs ( const EntityType &entity, const LocalDofs &localDofs ) 919 { 920 LeftAdd< const LocalDofs > assignFunctor( localDofs ); 921 space().blockMapper().mapEach( entity, dofBlockFunctor( dofVector(), assignFunctor ) ); 922 } 923 924 /** \copydoc Dune::Fem::DiscreteFunctionInterface::setLocalDofs */ 925 template< class LocalDofs > setLocalDofs(const EntityType & entity,const LocalDofs & localDofs)926 void setLocalDofs ( const EntityType &entity, const LocalDofs &localDofs ) 927 { 928 LeftAssign< const LocalDofs > assignFunctor( localDofs ); 929 space().blockMapper().mapEach( entity, dofBlockFunctor( dofVector(), assignFunctor ) ); 930 } 931 932 /** \copydoc Dune::Fem::DiscreteFunctionInterface::getLocalDofs */ 933 template< class Vector > getLocalDofs(const EntityType & entity,Vector & localDofs) const934 void getLocalDofs ( const EntityType &entity, Vector &localDofs ) const 935 { 936 AssignFunctor< Vector > assignFunctor( localDofs ); 937 space().blockMapper().mapEach( entity, dofBlockFunctor( dofVector(), assignFunctor ) ); 938 } 939 940 // Non-Interface Methods 941 // --------------------- 942 943 template <class DFType> 944 inline bool operator== ( const DiscreteFunctionInterface< DFType> &g ) const; 945 946 template <class DFType> operator !=(const DiscreteFunctionInterface<DFType> & g) const947 bool operator!= ( const DiscreteFunctionInterface< DFType > &g ) const 948 { 949 return !(operator==( g )); 950 } 951 952 /** \brief obtain the local function storage 953 * 954 * \returns a reference to the local function storage 955 */ localDofVectorAllocator() const956 LocalDofVectorAllocatorType &localDofVectorAllocator () const 957 { 958 return ldvAllocator_; 959 } 960 961 /** \brief Initiate the assemble of values using the LocalContribution concept 962 * \tparam AssembleOperation the specific operation (Add, Set, ...) 963 */ 964 template< class AssembleOperation > beginAssemble()965 void beginAssemble () 966 { 967 const std::type_index id( typeid( AssembleOperation ) ); 968 if( assembleOperation_ != id ) 969 { 970 if( assembleOperation_ != std::type_index( typeid( void ) ) ) 971 DUNE_THROW( InvalidStateException, "Another assemble operation in progress" ); 972 assembleOperation_ = id; 973 assert( assembleCount_ == 0 ); 974 AssembleOperation::begin( asImp() ); 975 } 976 ++assembleCount_; 977 } 978 979 /** \brief Finalize the assemble of values using the LocalContribution concept 980 * \tparam AssembleOperation the specific operation (Add, Set, ...) 981 */ 982 template< class AssembleOperation > endAssemble()983 void endAssemble () 984 { 985 const std::type_index id( typeid( AssembleOperation ) ); 986 if( assembleOperation_ != id ) 987 DUNE_THROW( InvalidStateException, "Assemble operation not in progress" ); 988 assert( assembleCount_ > 0 ); 989 if( --assembleCount_ == 0 ) 990 { 991 AssembleOperation::end( asImp() ); 992 assembleOperation_ = std::type_index( typeid( void ) ); 993 } 994 } 995 996 //! get local Dofs and store a reference to it in the LocalDofVector getLocalDofReferences(const EntityType & entity,LocalDofVectorType & localDofs)997 void getLocalDofReferences ( const EntityType &entity, LocalDofVectorType &localDofs ) 998 { 999 AssignVectorReference< LocalDofVectorType > assignFunctor( localDofs ); 1000 space().blockMapper().mapEach( entity, dofBlockFunctor( dofVector(), assignFunctor ) ); 1001 } 1002 1003 protected: 1004 /** \copydoc Dune::PersistentObject::backup */ backup() const1005 virtual void backup() const 1006 { 1007 // get backup stream from persistence manager and write to it 1008 write( PersistenceManager :: backupStream() ); 1009 } 1010 1011 /** \copydoc Dune::PersistentObject::restore */ restore()1012 virtual void restore() 1013 { 1014 // get restore stream from persistence manager and read from it 1015 read( PersistenceManager :: restoreStream() ); 1016 } 1017 1018 /** \copydoc Dune::PersistentObject::insertSubData */ 1019 virtual void insertSubData(); 1020 1021 /** \copydoc Dune::PersistentObject::removeSubData */ 1022 virtual void removeSubData(); 1023 1024 /** \brief evaluate functor in global coordinate */ 1025 template< class Functor > 1026 void evaluateGlobal ( const DomainType &x, Functor functor ) const; 1027 1028 // only PersistenceManager should call backup and restore 1029 friend class PersistenceManager; 1030 1031 std::shared_ptr< const DiscreteFunctionSpaceType > dfSpace_; 1032 1033 // the local function storage 1034 typename Traits :: LocalDofVectorStackType ldvStack_; 1035 mutable LocalDofVectorAllocatorType ldvAllocator_; 1036 1037 mutable TemporaryLocalFunctionType localFunction_; 1038 1039 std::string name_; 1040 ScalarProductType scalarProduct_; 1041 1042 std::type_index assembleOperation_ = std::type_index( typeid( void ) );; 1043 std::size_t assembleCount_ = 0; 1044 }; // end class DiscreteFunctionDefault 1045 1046 1047 template< class DiscreteFunction > 1048 class ManagedDiscreteFunction; 1049 1050 1051 template< class DiscreteFunction > 1052 struct DiscreteFunctionTraits< ManagedDiscreteFunction< DiscreteFunction > > 1053 : public DiscreteFunctionTraits< DiscreteFunction > {}; 1054 1055 1056 /** \class DiscreteFunctionTraits 1057 * \brief Traits class for a DiscreteFunction 1058 * 1059 * \tparam DiscreteFunctionSpace space the discrete function lives in 1060 * \tparam DofVector implementation class of the block vector 1061 */ 1062 template< typename DiscreteFunctionSpace, typename DofVector > 1063 struct DefaultDiscreteFunctionTraits 1064 { 1065 typedef DofVector DofVectorType; 1066 1067 typedef DiscreteFunctionSpace DiscreteFunctionSpaceType; 1068 typedef typename DiscreteFunctionSpaceType::DomainType DomainType; 1069 typedef typename DiscreteFunctionSpaceType::RangeType RangeType; 1070 1071 typedef typename DofVectorType::IteratorType DofIteratorType; 1072 typedef typename DofVectorType::ConstIteratorType ConstDofIteratorType; 1073 typedef typename DofVectorType::DofBlockType DofBlockType; 1074 typedef typename DofVectorType::ConstDofBlockType ConstDofBlockType; 1075 typedef typename DofVectorType::DofBlockPtrType DofBlockPtrType; 1076 typedef typename DofVectorType::ConstDofBlockPtrType ConstDofBlockPtrType; 1077 1078 typedef typename DiscreteFunctionSpaceType::BlockMapperType MapperType; 1079 typedef typename DofVectorType::FieldType DofType; 1080 1081 typedef ThreadSafeValue< UninitializedObjectStack > LocalDofVectorStackType; 1082 typedef StackAllocator< DofType, LocalDofVectorStackType* > LocalDofVectorAllocatorType; 1083 typedef DynamicReferenceVector< DofType, LocalDofVectorAllocatorType > LocalDofVectorType; 1084 }; 1085 1086 1087 ///@} 1088 1089 } // end namespace Fem 1090 1091 } // end namespace Dune 1092 1093 #include "discretefunction_inline.hh" 1094 1095 #include "gridfunctionadapter.hh" 1096 #endif // #ifndef DUNE_FEM_DISCRETEFUNCTION_HH 1097