Skip to content
Snippets Groups Projects
Commit 3cafec5b authored by Markus Blatt's avatar Markus Blatt
Browse files

Makes shallow copies of twolevel method usable in different threads.

The LevelTransferPolicies have internal storage for lhs and rhs that
should be cloned in each copy to prevent overwriting values. This
patch accomplishes this.
parent fc5fd4c5
No related branches found
No related tags found
No related merge requests found
...@@ -73,14 +73,14 @@ void testTwoLevelMethod() ...@@ -73,14 +73,14 @@ void testTwoLevelMethod()
TransferPolicy; // Policy for coarse linear system creation TransferPolicy; // Policy for coarse linear system creation
typedef Dune::Amg::OneStepAMGCoarseSolverPolicy<Operator,CSmoother, Criterion> typedef Dune::Amg::OneStepAMGCoarseSolverPolicy<Operator,CSmoother, Criterion>
CoarsePolicy; // Policy for coarse solver creation CoarsePolicy; // Policy for coarse solver creation
typedef typename Dune::Amg::SmootherTraits<CSmoother>::Arguments SmootherArgs; typedef Dune::Amg::SmootherTraits<CSmoother>::Arguments SmootherArgs;
Criterion crit; Criterion crit;
CoarsePolicy coarsePolicy=CoarsePolicy(SmootherArgs(), crit); CoarsePolicy coarsePolicy=CoarsePolicy(SmootherArgs(), crit);
TransferPolicy transferPolicy(crit); TransferPolicy transferPolicy(crit);
Operator fop(mat); Operator fop(mat);
Dune::Amg::TwoLevelMethod<Operator,Operator,FSmoother> preconditioner(fop, Dune::Amg::TwoLevelMethod<Operator,Operator,FSmoother> preconditioner(fop,
Dune::stackobject_to_shared_ptr(fineSmoother), Dune::stackobject_to_shared_ptr(fineSmoother),
Dune::stackobject_to_shared_ptr<Dune::Amg::LevelTransferPolicy<Operator,Operator> >(transferPolicy), transferPolicy,
coarsePolicy); coarsePolicy);
Dune::GeneralizedPCGSolver<Vector> amgCG(fop,preconditioner,1e-8,80,2); Dune::GeneralizedPCGSolver<Vector> amgCG(fop,preconditioner,1e-8,80,2);
Dune::InverseOperatorResult res; Dune::InverseOperatorResult res;
......
...@@ -114,6 +114,9 @@ public: ...@@ -114,6 +114,9 @@ public:
*/ */
virtual void createCoarseLevelSystem(const FineOperatorType& fineOperator)=0; virtual void createCoarseLevelSystem(const FineOperatorType& fineOperator)=0;
/** @brief Clone the current object. */
virtual LevelTransferPolicy* clone() const =0;
protected: protected:
/** @brief The coarse level rhs. */ /** @brief The coarse level rhs. */
CoarseRangeType rhs_; CoarseRangeType rhs_;
...@@ -203,6 +206,11 @@ public: ...@@ -203,6 +206,11 @@ public:
prolongDamp_, ParallelInformation()); prolongDamp_, ParallelInformation());
} }
AggregationLevelTransferPolicy* clone() const
{
return new AggregationLevelTransferPolicy(*this);
}
private: private:
typename O::matrix_type::field_type prolongDamp_; typename O::matrix_type::field_type prolongDamp_;
shared_ptr<AggregatesMap> aggregatesMap_; shared_ptr<AggregatesMap> aggregatesMap_;
...@@ -365,17 +373,30 @@ public: ...@@ -365,17 +373,30 @@ public:
template<class CoarseSolverPolicy> template<class CoarseSolverPolicy>
TwoLevelMethod(const FineOperatorType& op, TwoLevelMethod(const FineOperatorType& op,
shared_ptr<SmootherType> smoother, shared_ptr<SmootherType> smoother,
shared_ptr<LevelTransferPolicy<FineOperatorType, const LevelTransferPolicy<FineOperatorType,
CoarseOperatorType> > policy, CoarseOperatorType>& policy,
CoarseSolverPolicy& coarsePolicy, CoarseSolverPolicy& coarsePolicy,
std::size_t preSteps=1, std::size_t postSteps=1) std::size_t preSteps=1, std::size_t postSteps=1)
: operator_(op), smoother_(smoother), policy_(policy), : operator_(&op), smoother_(smoother),
preSteps_(preSteps), postSteps_(postSteps) preSteps_(preSteps), postSteps_(postSteps)
{ {
policy_->createCoarseLevelSystem(operator_); policy_ = policy.clone();
policy_->createCoarseLevelSystem(*operator_);
coarseSolver_.reset(coarsePolicy.createCoarseLevelSolver(*policy_)); coarseSolver_.reset(coarsePolicy.createCoarseLevelSolver(*policy_));
} }
TwoLevelMethod(const TwoLevelMethod& other)
: operator_(other.operator_), coarseSolver_(other.coarseSolver_),
smoother_(other.smoother_), policy_(other.policy_.clone()),
preSteps_(preSteps_), postSteps_(postSteps_)
{}
~TwoLevelMethod()
{
// Each instance has its own policy.
delete policy_;
}
void pre(FineDomainType& x, FineRangeType& b) void pre(FineDomainType& x, FineRangeType& b)
{ {
smoother_->pre(x,b); smoother_->pre(x,b);
...@@ -395,7 +416,7 @@ public: ...@@ -395,7 +416,7 @@ public:
context.update=&v; context.update=&v;
context.smoother=smoother_; context.smoother=smoother_;
context.rhs=&rhs; context.rhs=&rhs;
context.matrix=&operator_; context.matrix=operator_;
// Presmoothing // Presmoothing
presmooth(context, preSteps_); presmooth(context, preSteps_);
//Coarse grid correction //Coarse grid correction
...@@ -443,14 +464,14 @@ private: ...@@ -443,14 +464,14 @@ private:
*/ */
const FineOperatorType* matrix; const FineOperatorType* matrix;
}; };
const FineOperatorType& operator_; const FineOperatorType* operator_;
/** @brief The coarse level solver. */ /** @brief The coarse level solver. */
shared_ptr<InverseOperator<typename CO::domain_type, shared_ptr<InverseOperator<typename CO::domain_type,
typename CO::range_type> > coarseSolver_; typename CO::range_type> > coarseSolver_;
/** @brief The fine level smoother. */ /** @brief The fine level smoother. */
shared_ptr<S> smoother_; shared_ptr<S> smoother_;
/** @brief Policy for prolongation, restriction, and coarse level system creation. */ /** @brief Policy for prolongation, restriction, and coarse level system creation. */
shared_ptr<LevelTransferPolicy<FO,CO> > policy_; LevelTransferPolicy<FO,CO>* policy_;
/** @brief The number of presmoothing steps to apply. */ /** @brief The number of presmoothing steps to apply. */
std::size_t preSteps_; std::size_t preSteps_;
/** @brief The number of postsmoothing steps to apply. */ /** @brief The number of postsmoothing steps to apply. */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment