00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef OPM_PARALLELRESTRICTEDADDITIVESCHWARZ_HEADER_INCLUDED
00021 #define OPM_PARALLELRESTRICTEDADDITIVESCHWARZ_HEADER_INCLUDED
00022
00023 #include <opm/common/utility/platform_dependent/disable_warnings.h>
00024 #include <dune/istl/preconditioner.hh>
00025 #include <dune/istl/paamg/smoother.hh>
00026 #include <opm/common/utility/platform_dependent/reenable_warnings.h>
00027
00028 namespace Opm
00029 {
00030
00031 template<class X, class Y, class C, class T>
00032 class ParallelRestrictedOverlappingSchwarz;
00033
00034 }
00035
00036 namespace Dune
00037 {
00038
00039 namespace Amg
00040 {
00041
00048 template<class Range, class Domain, class ParallelInfo, class SeqPreconditioner>
00049 struct ConstructionTraits<Opm::ParallelRestrictedOverlappingSchwarz<Range,
00050 Domain,
00051 ParallelInfo,
00052 SeqPreconditioner> >
00053 {
00054 typedef DefaultParallelConstructionArgs<SeqPreconditioner,ParallelInfo> Arguments;
00055 typedef ConstructionTraits<SeqPreconditioner> SeqConstructionTraits;
00056
00058 static inline Opm::ParallelRestrictedOverlappingSchwarz<Range,
00059 Domain,
00060 ParallelInfo,
00061 SeqPreconditioner>*
00062 construct(Arguments& args)
00063 {
00064 return new Opm::ParallelRestrictedOverlappingSchwarz
00065 <Range,Domain,ParallelInfo,SeqPreconditioner>(*SeqConstructionTraits
00066 ::construct(args),
00067 args.getComm());
00068 }
00069
00071 static inline void deconstruct(Opm::ParallelRestrictedOverlappingSchwarz
00072 <Range,Domain,ParallelInfo,SeqPreconditioner>* bp)
00073 {
00074 SeqConstructionTraits
00075 ::deconstruct(static_cast<SeqPreconditioner*>(&bp->preconditioner));
00076 delete bp;
00077 }
00078
00079 };
00080
00087 template<class Range, class Domain, class ParallelInfo, class SeqPreconditioner>
00088 struct SmootherTraits<Opm::ParallelRestrictedOverlappingSchwarz<Range,
00089 Domain,
00090 ParallelInfo,
00091 SeqPreconditioner> >
00092 {
00093 typedef DefaultSmootherArgs<typename SeqPreconditioner::matrix_type::field_type> Arguments;
00094
00095 };
00096
00097 }
00098
00099 }
00100
00101 namespace Opm{
00102
00123 template<class Range, class Domain, class ParallelInfo, class SeqPreconditioner=Dune::Preconditioner<Range,Domain> >
00124 class ParallelRestrictedOverlappingSchwarz
00125 : public Dune::Preconditioner<Range,Domain> {
00126 friend class Dune::Amg
00127 ::ConstructionTraits<ParallelRestrictedOverlappingSchwarz<Range,
00128 Domain,
00129 ParallelInfo,
00130 SeqPreconditioner> >;
00131 public:
00133 typedef Domain domain_type;
00135 typedef Range range_type;
00137 typedef typename Domain::field_type field_type;
00139 typedef ParallelInfo communication_type;
00140
00141
00142 enum {
00144 category=Dune::SolverCategory::overlapping
00145 };
00146
00154 ParallelRestrictedOverlappingSchwarz (SeqPreconditioner& p, const communication_type& c)
00155 : preconditioner_(p), communication_(c)
00156 { }
00157
00163 virtual void pre (Domain& x, Range& b)
00164 {
00165 communication_.copyOwnerToAll(x,x);
00166 preconditioner_.pre(x,b);
00167 }
00168
00174 virtual void apply (Domain& v, const Range& d)
00175 {
00176 apply<true>(v, d);
00177 }
00178
00179 template<bool forward>
00180 void apply (Domain& v, const Range& d)
00181 {
00182
00183 Range& md = const_cast<Range&>(d);
00184 communication_.copyOwnerToAll(md,md);
00185 preconditioner_.template apply<forward>(v,d);
00186 communication_.copyOwnerToAll(v,v);
00187
00188 communication_.project(md);
00189 }
00190
00196 virtual void post (Range& x)
00197 {
00198 preconditioner_.post(x);
00199 }
00200
00201 private:
00203 SeqPreconditioner& preconditioner_;
00204
00206 const communication_type& communication_;
00207 };
00208
00209
00210 }
00211 #endif