diff --git a/fem/common/discreteoperator.hh b/fem/common/discreteoperator.hh index 5f329d4e6313d177b53d27bc9bac2bc5397ff951..b3ea21e64e978b53bad1937668c2de13da61756e 100644 --- a/fem/common/discreteoperator.hh +++ b/fem/common/discreteoperator.hh @@ -6,6 +6,7 @@ #include <dune/common/operator.hh> // object pointer management for combined discrete operators #include "objpointer.hh" +#include "localoperator.hh" namespace Dune { @@ -26,17 +27,85 @@ namespace Dune { the generation of new objects with the operator + method. There is corresponding interface class is Operator. */ - template < class DF_DomainType , class DF_RangeType> + template <class LocalOperatorImp, class DFDomainType, class DFRangeType , + template <class,class,class> class DiscreteOperatorImp > class DiscreteOperatorDefault - : public Operator <typename DF_DomainType::RangeFieldType, - typename DF_RangeType::RangeFieldType, - DF_DomainType , DF_RangeType> + : public Operator <typename DFDomainType::RangeFieldType, + typename DFRangeType::RangeFieldType, + DFDomainType , DFRangeType> , public ObjPointerStorage { - typedef DiscreteOperatorDefault<DF_DomainType,DF_RangeType> MyType; + + protected: + // define my type for inherited classes + typedef DiscreteOperatorDefault < LocalOperatorImp , DFDomainType , + DFRangeType , DiscreteOperatorImp > DiscreteOperatorDefaultType; + + //! Operator which is called on each entity + LocalOperatorImp & localOp_; + public: //! make new operator with item points to null - DiscreteOperatorDefault () : level_ (0) {} + DiscreteOperatorDefault (LocalOperatorImp & op) + : localOp_ (op) , level_ (0) {} + + //! no public method, but has to be public, because all discrete operator + //! must be able to call this method an the template parameters are + //! allways diffrent + LocalOperatorImp & getLocalOp () + { + return localOp_; + } + + /*! add another discrete operator by combining the two local operators + and creating a new discrete operator whereby a pointer to the new + object is kept in the object where the operator was called. + If this object is deleted then all objects created during operator + + called are deleted too. + */ + template <class LocalOperatorType> + DiscreteOperatorImp< CombinedLocalOperator < LocalOperatorImp , LocalOperatorType> , + DFDomainType, DFRangeType > & + operator + (const DiscreteOperatorImp < LocalOperatorType, DFDomainType , DFRangeType > &op ) + { + typedef DiscreteOperatorImp < LocalOperatorType , DFDomainType, DFRangeType> CopyType; + typedef CombinedLocalOperator < LocalOperatorImp , LocalOperatorType > COType; + + COType *locOp = + new COType ( localOp_ , const_cast<CopyType &> (op).getLocalOp (), asImp().printInfo() ); + + typedef DiscreteOperatorImp <COType, DFDomainType, DFRangeType > OPType; + + OPType *discrOp = new OPType (op, *locOp ); + + // memorize this new generated object because is represents this + // operator and is deleted if this operator is deleted + // this is managed by the ObjPointerStorage class + this->saveObjPointer( discrOp , locOp ); + + return (*discrOp); + } + + //! This method work just the same way like the operator + + //! but this time for mutiplication with scalar + DiscreteOperatorImp< ScaledLocalOperator < LocalOperatorImp , + typename DFDomainType::RangeFieldType > , DFDomainType,DFRangeType > & + operator * (const RangeFieldType& scalar) + { + typedef ScaledLocalOperator < LocalOperatorImp, + typename DFDomainType::RangeFieldType > ScalOperatorType; + + typedef DiscreteOperatorImp < ScalOperatorType , DFDomainType,DFRangeType > ScalDiscrType; + + ScalOperatorType * sop = new ScalOperatorType ( localOp_ , scalar, asImp().printInfo() ); + ScalDiscrType *discrOp = new ScalDiscrType ( asImp() , *sop ); + + // memorize this new generated object because is represents this + // operator and is deleted if this operator is deleted + this->saveObjPointer ( discrOp, sop ); + + return (*discrOp); + } // set level void initLevel (int level) const @@ -51,23 +120,31 @@ namespace Dune { } //! apply operator, only used by mapping - void apply ( const DF_DomainType & arg, DF_RangeType & dest) const + void apply ( const DFDomainType & arg, DFRangeType & dest) const { std::cerr << "ERROR: DiscreteOperatorDefault::apply called! \n"; } //! apply operator - void operator () ( const DF_DomainType & arg, DF_RangeType & dest ) const + void operator () ( const DFDomainType & arg, DFRangeType & dest ) const { std::cerr << "ERROR: DiscreteOperatorDefault::operator () called! \n"; } + bool printInfo () { return false; } + protected: // current level of operator mutable int level_; - }; // end class DiscreteOperatorDefault + private: + DiscreteOperatorImp < LocalOperatorImp , DFDomainType , DFRangeType > & + asImp() { return static_cast <DiscreteOperatorImp < LocalOperatorImp , DFDomainType , DFRangeType > &> (*this); } + + const DiscreteOperatorImp < LocalOperatorImp , DFDomainType , DFRangeType > & + asImp() const { return static_cast <const DiscreteOperatorImp < LocalOperatorImp , DFDomainType , DFRangeType > &> (*this); } + }; // end class DiscreteOperatorDefault /** @} end documentation group */ diff --git a/fem/common/localoperator.hh b/fem/common/localoperator.hh index 9114a7a85a10fabbc5355d1e1ddc49de9e686551..94d0a805872864e81e354082ddac0e9f3336ccac 100644 --- a/fem/common/localoperator.hh +++ b/fem/common/localoperator.hh @@ -177,10 +177,22 @@ namespace Dune //! Note: first B is evaluated, then A template <class A, class B > class CombinedLocalOperator + : public ObjPointerStorage { public: //! Constructor for combinations storing the two operators - CombinedLocalOperator ( A & a, B & b ) : _a ( a ) , _b ( b ) {} + CombinedLocalOperator ( A & a, B & b , bool printMsg = false ) + : _a ( a ) , _b ( b ) , printMSG_ ( printMsg ) + { + if(printMSG_) + std::cout << "Create CombinedLocalOperator " << this << "\n"; + } + + ~CombinedLocalOperator () + { + if(printMSG_) + std::cout << "Delete CombinedLocalOperator " << this << "\n"; + } //! method to scale the belonging operators template <class ScalarType> @@ -239,6 +251,8 @@ namespace Dune and to the underlying operators */ private: + bool printMSG_; + //! operator A and B A & _a; B & _b; @@ -338,12 +352,24 @@ namespace Dune //******************************************************************** template <class A,class ScalarType> class ScaledLocalOperator + : public ObjPointerStorage { public: //! Constructor for combinations with factors - ScaledLocalOperator ( A & a , const ScalarType scalar) - : _a ( a ) , scalar_ (scalar), tmpScalar_ (scalar) {} + ScaledLocalOperator ( A & a , const ScalarType scalar, + bool printMsg = false) + : _a ( a ) , scalar_ (scalar), tmpScalar_ (scalar) , + printMSG_ ( printMsg ) + { + if(printMSG_) + std::cout << "Create ScaledLocalOperator " << this << "\n"; + } + ~ScaledLocalOperator () + { + if(printMSG_) + std::cout << "Delete ScaledLocalOperator " << this << "\n"; + } // scale this operator from outside void scaleIt ( const ScalarType & scalar); @@ -393,6 +419,8 @@ namespace Dune template<class EntityType> void applyLocal(EntityType & en1, EntityType &en2); protected: + bool printMSG_; + //! reference to local operator A A & _a; diff --git a/fem/common/objpointer.hh b/fem/common/objpointer.hh index 115d9ec3e6457ffecd1c463a95fd7e9d1a4d942f..6afd4275f43ce25752737202c3b23518ed25393f 100644 --- a/fem/common/objpointer.hh +++ b/fem/common/objpointer.hh @@ -30,7 +30,8 @@ namespace Dune { } }; - //! ??? + //! stores the new created objects when DiscreteOperatorDefault + //! operator + or operator * is called class ObjPointerStorage { typedef ObjPointerStorage MyType; @@ -53,6 +54,15 @@ namespace Dune { item_ = next; } + //! Store new generated DiscreteOperator Pointer and the LocalOperator + //! pointer + template <class DiscrOpType, class LocalOpType > + void saveObjPointer ( DiscrOpType * discrOp , LocalOpType * lop ) + { + saveObjPointer( discrOp ); + saveObjPointer( lop ); + } + private: // store the objects created by operator + in here typedef ObjPointer<MyType> ObjPointerType;