diff --git a/dune/fem-dg/operator/limiter/limitpass.hh b/dune/fem-dg/operator/limiter/limitpass.hh index 22f48ad2550a5b4160ee52f8ce4961c0a7b327af..ef2d56d48ff1286f19fa1cd5c61f02298675672b 100644 --- a/dune/fem-dg/operator/limiter/limitpass.hh +++ b/dune/fem-dg/operator/limiter/limitpass.hh @@ -919,14 +919,12 @@ namespace Dune { * this pass * \param vQ order of volume quadrature * \param fQ order of face quadrature - * \param nTP dummy parameter (to be removed again) */ LimitDGPass(DiscreteModelType& problem, PreviousPassType& pass, const DiscreteFunctionSpaceType& spc, const int vQ = -1, - const int fQ = -1, - bool nTP = false ) : + const int fQ = -1 ) : BaseType(pass, spc), caller_( 0 ), discreteModel_(problem), @@ -1020,7 +1018,7 @@ namespace Dune { struct AssignFunction { template <class ArgImp, class DestImp> - static bool assign(const ArgImp& arg, DestImp& dest) + static bool assign(const ArgImp& arg, DestImp& dest, const bool firstThread) { // reconstruct if this combination of orders has been given return (arg.space().order() == 0) && (dest.space().order() == 1); @@ -1031,9 +1029,12 @@ namespace Dune { struct AssignFunction<S1,S1> { template <class ArgImp, class DestImp> - static bool assign(const ArgImp& arg, DestImp& dest) + static bool assign(const ArgImp& arg, DestImp& dest, const bool firstThread ) { - dest.assign(arg); + if( firstThread ) + { + dest.assign(arg); + } return false; } }; @@ -1045,31 +1046,6 @@ namespace Dune { { // get stopwatch Timer timer; - - // get reference to U - const ArgumentFunctionType& U = *(Dune::get< 0 >( arg )); // (*(Fem::Element<0>::get(arg))); - - // initialize dest as copy of U - // if reconstruct_ false then only reconstruct in some cases - reconstruct_ = - AssignFunction<typename ArgumentFunctionType :: - DiscreteFunctionSpaceType,DiscreteFunctionSpaceType>:: - assign( U , dest ); - - // if case of finite volume scheme set admissible functions to reconstructions - usedAdmissibleFunctions_ = reconstruct_ ? ReconstructedFunctions : admissibleFunctions_; - - // in case of reconstruction - if( reconstruct_ ) - { - // in case of non-adaptive scheme indicator not needed - calcIndicator_ = adaptive_; - - // adjust quadrature orders - argOrder_ = U.space().order(); - faceQuadOrd_ = 2 * argOrder_ + 1; - volumeQuadOrd_ = 2 * argOrder_; - } // if polOrder of destination is > 0 then we have to do something if( spc_.order() > 0 && active() ) @@ -1114,6 +1090,38 @@ namespace Dune { //! destinations. Filter out the "right" arguments for this pass. void prepare(const ArgumentType& arg, DestinationType& dest) const { + prepare( arg, dest, true ); + } + + //! In the preparations, store pointers to the actual arguments and + //! destinations. Filter out the "right" arguments for this pass. + void prepare(const ArgumentType& arg, DestinationType& dest, const bool firstThread ) const + { + // get reference to U + const ArgumentFunctionType& U = *(Dune::get< 0 >( arg )); // (*(Fem::Element<0>::get(arg))); + + // initialize dest as copy of U + // if reconstruct_ false then only reconstruct in some cases + reconstruct_ = + AssignFunction<typename ArgumentFunctionType :: + DiscreteFunctionSpaceType,DiscreteFunctionSpaceType>:: + assign( U , dest, firstThread ); + + // if case of finite volume scheme set admissible functions to reconstructions + usedAdmissibleFunctions_ = reconstruct_ ? ReconstructedFunctions : admissibleFunctions_; + + // in case of reconstruction + if( reconstruct_ ) + { + // in case of non-adaptive scheme indicator not needed + calcIndicator_ = adaptive_; + + // adjust quadrature orders + argOrder_ = U.space().order(); + faceQuadOrd_ = 2 * argOrder_ + 1; + volumeQuadOrd_ = 2 * argOrder_; + } + limitedElements_ = 0; notPhysicalElements_ = 0; @@ -1142,10 +1150,15 @@ namespace Dune { } } - //! Some management. + //! Some management (interface version) void finalize(const ArgumentType& arg, DestinationType& dest) const { - //if( notPhysicalElements_ ) + finalize( arg, dest, true ); + } + + //! Some management (thread parallel version) + void finalize(const ArgumentType& arg, DestinationType& dest, const bool notThreadParallel) const + { /* if( limitedElements_ > 0 ) { @@ -1156,13 +1169,18 @@ namespace Dune { } */ - // communicate dest - dest.communicate(); + if( notThreadParallel ) + { + // communicate dest + dest.communicate(); + } // finalize caller if( caller_ ) + { delete caller_; - caller_ = 0; + caller_ = 0; + } } //! apply local is virtual diff --git a/dune/fem-dg/pass/dgpass.hh b/dune/fem-dg/pass/dgpass.hh index 489d3d3cb07d98f91d4539d903e269c8969dcd79..6b9cf5a56e06b763165c4e0fb187d0ca9263618b 100644 --- a/dune/fem-dg/pass/dgpass.hh +++ b/dune/fem-dg/pass/dgpass.hh @@ -114,8 +114,7 @@ namespace Dune { PreviousPassType& pass, const DiscreteFunctionSpaceType& spc, const int volumeQuadOrd = -1, - const int faceQuadOrd = -1, - const bool notThreadParallel = true ) + const int faceQuadOrd = -1 ) : BaseType(pass, spc), caller_( 0 ), discreteModel_(discreteModel), @@ -137,8 +136,7 @@ namespace Dune { faceQuadOrd_( faceQuadOrd ), numberOfElements_( 0 ), localMassMatrix_( spc_ , volumeQuadOrd_ ), - reallyCompute_( true ), - notThreadParallel_( notThreadParallel ) + reallyCompute_( true ) { // make sure that either a ghost layer or an overlap layer is there for // communication of the data, otherwise the scheme will not work @@ -265,15 +263,23 @@ namespace Dune { //! In the preparations, store pointers to the actual arguments and //! destinations. Filter out the "right" arguments for this pass. virtual void prepare(const ArgumentType& arg, DestinationType& dest) const + { + prepare( arg, dest, true ); + } + + //! In the preparations, store pointers to the actual arguments and + //! destinations. Filter out the "right" arguments for this pass. + //! This is the version use with ThreadPass + void prepare(const ArgumentType& arg, DestinationType& dest, const bool firstThread ) const { arg_ = const_cast<ArgumentType*>(&arg); dest_ = &dest; numberOfElements_ = 0; - if( notThreadParallel_ && dest_ ) + if( firstThread && dest_ ) { - // clear destination (not in thread parallel version) + // clear destination (only for first pass in thread parallel version) dest_->clear(); } @@ -292,9 +298,9 @@ namespace Dune { } //! Some timestep size management. - void doFinalize(DestinationType& dest) const + void doFinalize(DestinationType& dest, const bool notThreadParallel ) const { - if( notThreadParallel_ && (&dest) ) + if( notThreadParallel && (&dest) ) { // communicate calculated function (not in thread parallel version) dest.communicate(); @@ -311,10 +317,17 @@ namespace Dune { dest_ = 0; } + //! Some timestep size management. + //! This is the version use with ThreadPass + void finalize(const ArgumentType& arg, DestinationType& dest, const bool notThreadParallel ) const + { + doFinalize( dest, notThreadParallel ); + } + //! Some timestep size management. virtual void finalize(const ArgumentType& arg, DestinationType& dest) const { - doFinalize( dest ); + doFinalize( dest, true ); } size_t numberOfElements() const @@ -920,7 +933,6 @@ namespace Dune { mutable size_t numberOfElements_ ; LocalMassMatrixType localMassMatrix_; mutable bool reallyCompute_; - const bool notThreadParallel_; }; //! @} } // end namespace Dune diff --git a/dune/fem-dg/pass/threadpass.hh b/dune/fem-dg/pass/threadpass.hh index f89737b9245580664aa9e91425e7c4d051d52d1a..be8345db5eaf76723b921df05a5d28e82cb5fa26 100644 --- a/dune/fem-dg/pass/threadpass.hh +++ b/dune/fem-dg/pass/threadpass.hh @@ -188,10 +188,9 @@ namespace Dune { typedef Fem::DomainDecomposedIteratorStorage< GridPartType > ThreadIteratorType; //typedef Fem::ThreadIterator< GridPartType > ThreadIteratorType; - // type of adaptation handler - typedef typename DiscreteModelType :: AdaptationHandlerType AdaptationHandlerType ; protected: using BaseType :: spc_; + using BaseType :: pass ; public: //- Public methods @@ -213,7 +212,7 @@ namespace Dune { problems_( Fem::ThreadManager::maxThreads() ), passes_( Fem::ThreadManager::maxThreads() ), passComputeTime_( Fem::ThreadManager::maxThreads(), 0.0 ), - firstStage_( Fem::ThreadManager::maxThreads(), false ), + firstStage_( false ), arg_(0), dest_(0), nonBlockingComm_(), numberOfElements_( 0 ), @@ -226,7 +225,7 @@ namespace Dune { // use serparate discrete problem for each thread problems_[ i ] = new DiscreteModelType( problem ); // create dg passes, the last bool disables communication in the pass itself - passes_[ i ] = new InnerPassType( *problems_[ i ], pass, spc, volumeQuadOrd, faceQuadOrd, false ); + passes_[ i ] = new InnerPassType( *problems_[ i ], pass, spc, volumeQuadOrd, faceQuadOrd ); } #ifndef NDEBUG if( Fem :: Parameter :: verbose() ) @@ -243,18 +242,39 @@ namespace Dune { } } - void setAdaptationHandler( AdaptationHandlerType& adHandle, double weight ) + template <class AdaptationType> + void setAdaptation( AdaptationType& adHandle, double weight ) { const int maxThreads = Fem::ThreadManager::maxThreads(); for(int thread=0; thread<maxThreads; ++thread) { - problems_[ thread ]->setAdaptationHandler( adHandle, + problems_[ thread ]->setAdaptation( adHandle, #ifdef USE_SMP_PARALLEL iterators_.filter( thread ), // add filter in thread parallel versions #endif weight ); } } + + //! call apropriate method on all internal passes + void enable() const + { + const int maxThreads = Fem::ThreadManager::maxThreads(); + for(int thread=0; thread<maxThreads; ++thread) + { + pass( thread ).enable(); + } + } + + //! call apropriate method on all internal passes + void disable() const + { + const int maxThreads = Fem::ThreadManager::maxThreads(); + for(int thread=0; thread<maxThreads; ++thread) + { + pass( thread ).disable(); + } + } //! print tex info void printTexInfo(std::ostream& out) const @@ -357,11 +377,6 @@ namespace Dune { void compute(const ArgumentType& arg, DestinationType& dest) const { const bool updateAlso = (& dest != 0); - if( updateAlso ) - { - // clear destination - dest.clear(); - } // reset number of elements numberOfElements_ = 0; @@ -424,13 +439,15 @@ namespace Dune { // call prepare before parallel area const int maxThreads = Fem::ThreadManager::maxThreads(); - for(int i=0; i<maxThreads; ++i ) + pass( 0 ).prepare( arg, dest, true ); + passComputeTime_[ 0 ] = 0.0 ; + for(int i=1; i<maxThreads; ++i ) { // prepare pass (make sure pass doesn't clear dest, this will conflict) - pass( i ).prepare( arg, dest ); + pass( i ).prepare( arg, dest, false ); passComputeTime_[ i ] = 0.0 ; - firstStage_[ i ] = true ; } + firstStage_ = true ; arg_ = &arg ; dest_ = &dest ; @@ -453,8 +470,7 @@ namespace Dune { if( nonBlockingComm_.nonBlockingCommunication() ) { // mark second stage - for(int i=0; i<maxThreads; ++i ) - firstStage_[ i ] = false ; + firstStage_ = false ; // see threadhandle.hh Fem :: ThreadHandle :: run( *this ); @@ -533,7 +549,7 @@ namespace Dune { // stop time Timer timer ; - const bool computeInteriorIntegrals = firstStage_[ thread ]; + const bool computeInteriorIntegrals = firstStage_; // Iterator is of same type as the space iterator typedef typename ThreadIteratorType :: IteratorType Iterator; @@ -578,7 +594,7 @@ namespace Dune { // finalize pass (make sure communication is done in case of thread parallel // program, this would give conflicts) - myPass.finalize(*arg_, *dest_); + myPass.finalize(*arg_, *dest_, false ); } } else @@ -600,7 +616,7 @@ namespace Dune { // finalize pass (make sure communication is not done in case of thread parallel // program, this would give conflicts) - myPass.finalize(*arg_, *dest_); + myPass.finalize(*arg_, *dest_, false ); } // accumulate compute time for this thread @@ -631,6 +647,7 @@ namespace Dune { protected: void setMaxTimeSteps() const { + /* const int maxThreads = Fem::ThreadManager::maxThreads(); double maxAdvStep = 0; double maxDiffStep = 0; @@ -642,6 +659,7 @@ namespace Dune { // set time steps to single problem singleProblem_.setMaxTimeSteps( maxAdvStep, maxDiffStep ); + */ } private: @@ -659,7 +677,7 @@ namespace Dune { std::vector< DiscreteModelType* > problems_; std::vector< InnerPassType* > passes_; mutable std::vector< double > passComputeTime_; - mutable std::vector< bool > firstStage_; + mutable bool firstStage_; // temporary variables mutable const ArgumentType* arg_;