diff --git a/dune/istl/paamg/amg.hh b/dune/istl/paamg/amg.hh index d422b27317bda978867f8c33be6c27f7a1e39ef3..712078cf78cc79d0df0ae63a34e2cc5149e7e804 100644 --- a/dune/istl/paamg/amg.hh +++ b/dune/istl/paamg/amg.hh @@ -172,6 +172,11 @@ namespace Dune const SmootherArgs& smootherArgs, const ParallelInformation& pinfo=ParallelInformation()); + /** + * @brief Copy constructor. + */ + AMG(const AMG& amg); + ~AMG(); /** \copydoc Preconditioner::pre */ @@ -291,13 +296,33 @@ namespace Dune std::size_t verbosity_; }; + template<class M, class X, class S, class PI, class A> + inline AMG<M,X,S,PI,A>::AMG(const AMG& amg) + : matrices_(amg.matrices_), smootherArgs_(amg.smootherArgs_), + smoothers_(amg.smoothers_), solver_(amg.solver_), + rhs_(), lhs_(), update_(), + scalarProduct_(amg.scalarProduct_), gamma_(amg.gamma_), + preSteps_(amg.preSteps_), postSteps_(amg.postSteps_), + level(amg.level), buildHierarchy_(amg.buildHierarchy_), + additive(amg.additive), coarsesolverconverged(amg.coarsesolverconverged), + coarseSmoother_(amg.coarseSmoother_), verbosity_(amg.verbosity_) + { + if(amg.rhs_) + rhs_=new Hierarchy<Range,A>(*amg.rhs_); + if(amg.lhs_) + lhs_=new Hierarchy<Domain,A>(*amg.lhs_); + if(amg.update_) + update_=new Hierarchy<Domain,A>(*amg.update_); + } + template<class M, class X, class S, class PI, class A> AMG<M,X,S,PI,A>::AMG(const OperatorHierarchy& matrices, CoarseSolver& coarseSolver, const SmootherArgs& smootherArgs, std::size_t gamma, std::size_t preSmoothingSteps, std::size_t postSmoothingSteps, bool additive_) : matrices_(&matrices), smootherArgs_(smootherArgs), - smoothers_(new Hierarchy<Smoother,A>), solver_(&coarseSolver), scalarProduct_(0), + smoothers_(new Hierarchy<Smoother,A>), solver_(&coarseSolver), + rhs_(), lhs_(), update_(), scalarProduct_(0), gamma_(gamma), preSteps_(preSmoothingSteps), postSteps_(postSmoothingSteps), buildHierarchy_(false), additive(additive_), coarsesolverconverged(true), coarseSmoother_(), verbosity_(2) @@ -313,7 +338,8 @@ namespace Dune const SmootherArgs& smootherArgs, const Parameters& parms) : matrices_(&matrices), smootherArgs_(smootherArgs), - smoothers_(new Hierarchy<Smoother,A>), solver_(&coarseSolver), scalarProduct_(0), + smoothers_(new Hierarchy<Smoother,A>), solver_(&coarseSolver), + rhs_(), lhs_(), update_(), scalarProduct_(0), gamma_(parms.getGamma()), preSteps_(parms.getNoPreSmoothSteps()), postSteps_(parms.getNoPostSmoothSteps()), buildHierarchy_(false), additive(parms.getAdditive()), coarsesolverconverged(true), @@ -335,7 +361,8 @@ namespace Dune bool additive_, const PI& pinfo) : smootherArgs_(smootherArgs), - smoothers_(new Hierarchy<Smoother,A>), solver_(), scalarProduct_(0), gamma_(gamma), + smoothers_(new Hierarchy<Smoother,A>), solver_(), + rhs_(), lhs_(), update_(), scalarProduct_(0), gamma_(gamma), preSteps_(preSmoothingSteps), postSteps_(postSmoothingSteps), buildHierarchy_(true), additive(additive_), coarsesolverconverged(true), coarseSmoother_(), verbosity_(criterion.debugLevel()) @@ -355,7 +382,8 @@ namespace Dune const SmootherArgs& smootherArgs, const PI& pinfo) : smootherArgs_(smootherArgs), - smoothers_(new Hierarchy<Smoother,A>), solver_(), scalarProduct_(0), + smoothers_(new Hierarchy<Smoother,A>), solver_(), + rhs_(), lhs_(), update_(), scalarProduct_(0), gamma_(criterion.getGamma()), preSteps_(criterion.getNoPreSmoothSteps()), postSteps_(criterion.getNoPostSmoothSteps()), buildHierarchy_(true), additive(criterion.getAdditive()), coarsesolverconverged(true), @@ -378,6 +406,15 @@ namespace Dune if(coarseSmoother_) coarseSmoother_.reset(); } + if(lhs_) + delete lhs_; + lhs_=nullptr; + if(update_) + delete update_; + update_=nullptr; + if(rhs_) + delete rhs_; + rhs_=nullptr; } template<class M, class X, class S, class PI, class A> @@ -492,11 +529,17 @@ namespace Dune // No smoother to make x consistent! Do it by hand matrices_->parallelInformation().coarsest()->copyOwnerToAll(x,x); Range* copy = new Range(b); - rhs_ = new Hierarchy<Range,A>(*copy); + if(rhs_) + delete rhs_; + rhs_ = new Hierarchy<Range,A>(copy); Domain* dcopy = new Domain(x); - lhs_ = new Hierarchy<Domain,A>(*dcopy); + if(lhs_) + delete lhs_; + lhs_ = new Hierarchy<Domain,A>(dcopy); dcopy = new Domain(x); - update_ = new Hierarchy<Domain,A>(*dcopy); + if(update_) + delete update_; + update_ = new Hierarchy<Domain,A>(dcopy); matrices_->coarsenVector(*rhs_); matrices_->coarsenVector(*lhs_); matrices_->coarsenVector(*update_); @@ -826,13 +869,13 @@ namespace Dune smoother->post(*lhs); smoother->post(*lhs); } - delete &(*lhs_->finest()); + //delete &(*lhs_->finest()); delete lhs_; lhs_=nullptr; - delete &(*update_->finest()); + //delete &(*update_->finest()); delete update_; update_=nullptr; - delete &(*rhs_->finest()); + //delete &(*rhs_->finest()); delete rhs_; rhs_=nullptr; } diff --git a/dune/istl/paamg/hierarchy.hh b/dune/istl/paamg/hierarchy.hh index dbf9ae32ee94a396f19094fb3eed7c592717a234..0036300fd13d8172d33c0536039b0cc10f2d67d3 100644 --- a/dune/istl/paamg/hierarchy.hh +++ b/dune/istl/paamg/hierarchy.hh @@ -117,11 +117,23 @@ namespace Dune */ Hierarchy(MemberType& first); + /** + * @brief Construct a new hierarchy. + * @param first Pointer to the first element in the hierarchy. + * @warning Hierarchy will be responsible for the memory + * management of the pointer. + */ + Hierarchy(MemberType* first); + /** * @brief Construct a new empty hierarchy. */ Hierarchy(); + /** + * @brief Copy constructor. + */ + Hierarchy(const Hierarchy& other); /** * @brief Add an element on a coarser level. * @param args The arguments needed for the construction. @@ -234,7 +246,7 @@ namespace Dune void deleteRedistributed() { - element_->redistributed_ = 0; + element_->redistributed_ = nullptr; } private: @@ -282,9 +294,6 @@ namespace Dune ~Hierarchy(); private: - /** @brief Deactivate copying */ - Hierarchy(const Hierarchy&) - {} /** @brief The finest element in the hierarchy. */ Element* finest_; /** @brief The coarsest element in the hierarchy. */ @@ -1233,13 +1242,25 @@ namespace Dune { finest_ = allocator_.allocate(1,0); finest_->element_ = &first; - finest_->redistributed_ = 0; + finest_->redistributed_ = nullptr; nonAllocated_ = finest_; coarsest_ = finest_; - coarsest_->coarser_ = coarsest_->finer_ = 0; + coarsest_->coarser_ = coarsest_->finer_ = nullptr; levels_ = 1; } + template<class T, class A> + Hierarchy<T,A>::Hierarchy(MemberType* first) + : allocator_() + { + finest_ = allocator_.allocate(1,0); + finest_->element_ = first; + finest_->redistributed_ = nullptr; + nonAllocated_ = nullptr; + coarsest_ = finest_; + coarsest_->coarser_ = coarsest_->finer_ = nullptr; + levels_ = 1; + } template<class T, class A> Hierarchy<T,A>::~Hierarchy() { @@ -1252,8 +1273,45 @@ namespace Dune ConstructionTraits<T>::deconstruct(current->element_); } allocator_.deallocate(current, 1); - //coarsest_->coarser_ = 0; + current=nullptr; + //coarsest_->coarser_ = nullptr; + } + } + + template<class T, class A> + Hierarchy<T,A>::Hierarchy(const Hierarchy& other) + : nonAllocated_(), allocator_(other.allocator_), + levels_(other.levels_) + { + if(!other.finest_) + { + finest_=coarsest_=nonAllocated_=nullptr; + return; + } + finest_=allocator_.allocate(1,0); + Element* finer_ = nullptr; + Element* current_ = finest_; + Element* otherCurrent_ = other.finest_; + + while(otherCurrent_) + { + T* t=new T(*(otherCurrent_->element_)); + current_->element_=t; + current_->finer_=finer_; + if(otherCurrent_->redistributed_) + current_->redistributed_ = new T(*otherCurrent_->redistributed_); + else + current_->redistributed_= nullptr; + finer_=current_; + if(otherCurrent_->coarser_) + { + current_->coarser_=allocator_.allocate(1,0); + current_=current_->coarser_; + }else + current_->coarser_=nullptr; + otherCurrent_=otherCurrent_->coarser_; } + coarsest_=current_; } template<class T, class A> @@ -1276,15 +1334,15 @@ namespace Dune coarsest_ = allocator_.allocate(1,0); coarsest_->element_ = ConstructionTraits<MemberType>::construct(args); finest_ = coarsest_; - coarsest_->finer_ = 0; + coarsest_->finer_ = nullptr; }else{ coarsest_->coarser_ = allocator_.allocate(1,0); coarsest_->coarser_->finer_ = coarsest_; coarsest_ = coarsest_->coarser_; coarsest_->element_ = ConstructionTraits<MemberType>::construct(args); } - coarsest_->redistributed_ = 0; - coarsest_->coarser_=0; + coarsest_->redistributed_ = nullptr; + coarsest_->coarser_=nullptr; ++levels_; } @@ -1297,12 +1355,12 @@ namespace Dune finest_ = allocator_.allocate(1,0); finest_->element = ConstructionTraits<T>::construct(args); coarsest_ = finest_; - coarsest_->coarser_ = coarsest_->finer_ = 0; + coarsest_->coarser_ = coarsest_->finer_ = nullptr; }else{ finest_->finer_ = allocator_.allocate(1,0); finest_->finer_->coarser_ = finest_; finest_ = finest_->finer_; - finest_->finer = 0; + finest_->finer = nullptr; finest_->element = ConstructionTraits<T>::construct(args); } ++levels_; diff --git a/dune/istl/paamg/test/pthreadamgtest.cc b/dune/istl/paamg/test/pthreadamgtest.cc index f43c9e106cfe8be119c79fd8513571d030b7b707..be81e7cef2283cf14bcbe9f75da95e4b3275e9eb 100644 --- a/dune/istl/paamg/test/pthreadamgtest.cc +++ b/dune/istl/paamg/test/pthreadamgtest.cc @@ -25,7 +25,7 @@ #include <cstdlib> #include <ctime> #include <pthread.h> -#define NUM_THREADS 5 +#define NUM_THREADS 1 typedef double XREAL; @@ -96,6 +96,21 @@ void *solve(void* arg) pthread_exit(NULL); } +void *solve1(void* arg) +{ + thread_arg *amgarg=(thread_arg*) arg; + (*amgarg->amg).apply(*amgarg->x,*amgarg->b); + (*amgarg->amg).post(*amgarg->x); + +} + +void *solve2(void* arg) +{ + thread_arg *amgarg=(thread_arg*) arg; + (*amgarg->amg).pre(*amgarg->x,*amgarg->b); + (*amgarg->amg).apply(*amgarg->x,*amgarg->b); + (*amgarg->amg).post(*amgarg->x); +} template <int BS> void testAMG(int N, int coarsenTarget, int ml) @@ -184,6 +199,37 @@ void testAMG(int N, int coarsenTarget, int ml) for(int i=0; i < NUM_THREADS; ++i) pthread_join(threads[i], &retval); + + amgs.clear(); + args.clear(); + amg.pre(x, b); + amgs.resize(NUM_THREADS, amg); + for(int i=0; i < NUM_THREADS; ++i) + { + args[i].amg=&amgs[i]; + args[i].b=&bs[i]; + args[i].x=&xs[i]; + args[i].fop=&fop; + pthread_create(&threads[i], NULL, solve1, (void*) &args[i]); + } + for(int i=0; i < NUM_THREADS; ++i) + pthread_join(threads[i], &retval); + + amgs.clear(); + args.clear(); + amg.pre(x, b); + amgs.resize(NUM_THREADS, amg); + for(int i=0; i < NUM_THREADS; ++i) + { + args[i].amg=&amgs[i]; + args[i].b=&bs[i]; + args[i].x=&xs[i]; + args[i].fop=&fop; + pthread_create(&threads[i], NULL, solve2, (void*) &args[i]); + } + for(int i=0; i < NUM_THREADS; ++i) + pthread_join(threads[i], &retval); + }