00001 #ifndef GLOBALAGGREGATES_HH
00002 #define GLOBALAGGREGATES_HH
00003
00004 #include "aggregates.hh"
00005
00006 namespace Dune
00007 {
00008 namespace Amg
00009 {
00010
00011 template<typename T, typename TI>
00012 struct GlobalAggregatesMap
00013 {
00014 public:
00015 typedef TI ParallelIndexSet;
00016
00017 typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;
00018
00019 typedef typename ParallelIndexSet::GlobalIndex IndexedType;
00020
00021 typedef typename ParallelIndexSet::LocalIndex LocalIndex;
00022
00023 typedef T Vertex;
00024
00025 GlobalAggregatesMap(AggregatesMap<Vertex>& aggregates,
00026 const GlobalLookupIndexSet<ParallelIndexSet>& indexset)
00027 : aggregates_(aggregates), indexset_(indexset)
00028 {}
00029
00030 inline const GlobalIndex& operator[](std::size_t index)const
00031 {
00032 const Vertex& aggregate = aggregates_[index];
00033 if(aggregate >= AggregatesMap<Vertex>::ISOLATED){
00034 assert(aggregate != AggregatesMap<Vertex>::UNAGGREGATED);
00035 return isolatedMarker;
00036 }else{
00037 const Dune::IndexPair<GlobalIndex,LocalIndex >* pair = indexset_.pair(aggregate);
00038 assert(pair!=0);
00039 return pair->global();
00040 }
00041 }
00042
00043
00044 inline GlobalIndex& get(std::size_t index)
00045 {
00046 const Vertex& aggregate = aggregates_[index];
00047 assert(aggregate < AggregatesMap<Vertex>::ISOLATED);
00048 const Dune::IndexPair<GlobalIndex,LocalIndex >* pair = indexset_.pair(aggregate);
00049 assert(pair!=0);
00050 return const_cast<GlobalIndex&>(pair->global());
00051 }
00052
00053 class Proxy
00054 {
00055 public:
00056 Proxy(const GlobalLookupIndexSet<ParallelIndexSet>& indexset, Vertex& aggregate)
00057 : indexset_(&indexset), aggregate_(&aggregate)
00058 {}
00059
00060 Proxy& operator=(const GlobalIndex& global)
00061 {
00062 if(global==isolatedMarker)
00063 *aggregate_ = AggregatesMap<Vertex>::ISOLATED;
00064 else{
00065
00066 *aggregate_ = indexset_->operator[](global).local();
00067 }
00068 return *this;
00069 }
00070 private:
00071 const GlobalLookupIndexSet<ParallelIndexSet>* indexset_;
00072 Vertex* aggregate_;
00073 };
00074
00075 inline Proxy operator[](std::size_t index)
00076 {
00077 return Proxy(indexset_, aggregates_[index]);
00078 }
00079
00080 inline void put(const GlobalIndex& global, size_t i)
00081 {
00082 aggregates_[i]=indexset_[global].local();
00083
00084 }
00085
00086 private:
00087 AggregatesMap<Vertex>& aggregates_;
00088 const GlobalLookupIndexSet<ParallelIndexSet>& indexset_;
00089 static const GlobalIndex isolatedMarker;
00090 };
00091
00092 template<typename T, typename TI>
00093 const typename TI::GlobalIndex GlobalAggregatesMap<T,TI>::isolatedMarker = -1;
00094
00095 template<typename T, typename TI>
00096 struct AggregatesGatherScatter
00097 {
00098 typedef TI ParallelIndexSet;
00099 typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;
00100
00101 static const GlobalIndex& gather(const GlobalAggregatesMap<T,TI>& ga, size_t i)
00102 {
00103 return ga[i];
00104 }
00105
00106 static void scatter(GlobalAggregatesMap<T,TI>& ga, GlobalIndex global, size_t i)
00107 {
00108 ga[i]=global;
00109 }
00110 };
00111
00112 template<typename T, typename O, typename I>
00113 struct AggregatesPublisher
00114 {
00115 };
00116
00117 #if HAVE_MPI
00118 template<typename T, typename O, typename T1>
00119 struct AggregatesPublisher<T,O,ParallelInformation<T1> >
00120 {
00121 typedef T Vertex;
00122 typedef O OverlapFlags;
00123 typedef ParallelInformation<T1> ParallelInformation;
00124 typedef typename ParallelInformation::ParallelIndexSet IndexSet;
00125
00126 static void publish(AggregatesMap<Vertex>& aggregates,
00127 ParallelInformation& pinfo,
00128 const GlobalLookupIndexSet<IndexSet>& globalLookup)
00129 {
00130 typedef Dune::Amg::GlobalAggregatesMap<Vertex,IndexSet> GlobalMap;
00131 GlobalMap gmap(aggregates, globalLookup);
00132 pinfo.template buildInterface<OverlapFlags>();
00133 pinfo.template buildCommunicator<GlobalMap>(gmap, gmap);
00134 pinfo.template communicateForward<AggregatesGatherScatter<Vertex,IndexSet> >(gmap, gmap);
00135 pinfo.freeCommunicator();
00136 }
00137
00138 };
00139
00140 #endif
00141
00142 }
00143
00144 #if HAVE_MPI
00145
00146 template<class T1, class T2>
00147 class OwnerOverlapCopyCommunication;
00148 #endif
00149
00150 namespace Amg
00151 {
00152
00153 #if HAVE_MPI
00154 template<typename T, typename O, typename T1, typename T2>
00155 struct AggregatesPublisher<T,O,OwnerOverlapCopyCommunication<T1,T2> >
00156 {
00157 typedef T Vertex;
00158 typedef O OverlapFlags;
00159 typedef OwnerOverlapCopyCommunication<T1,T2> ParallelInformation;
00160 typedef typename ParallelInformation::GlobalLookupIndexSet GlobalLookupIndexSet;
00161 typedef typename ParallelInformation::ParallelIndexSet IndexSet;
00162
00163 static void publish(AggregatesMap<Vertex>& aggregates,
00164 ParallelInformation& pinfo,
00165 const GlobalLookupIndexSet& globalLookup)
00166 {
00167 typedef Dune::Amg::GlobalAggregatesMap<Vertex,IndexSet> GlobalMap;
00168 GlobalMap gmap(aggregates, globalLookup);
00169 pinfo.copyOwnerToAll(gmap,gmap);
00170 }
00171
00172 };
00173 #endif
00174
00175 template<typename T, typename O>
00176 struct AggregatesPublisher<T,O,SequentialInformation>
00177 {
00178 typedef T Vertex;
00179 typedef SequentialInformation ParallelInformation;
00180 typedef typename ParallelInformation::GlobalLookupIndexSet GlobalLookupIndexSet;
00181
00182 static void publish(AggregatesMap<Vertex>& aggregates,
00183 ParallelInformation& pinfo,
00184 const GlobalLookupIndexSet& globalLookup)
00185 {}
00186 };
00187
00188 }
00189
00190
00191 #if HAVE_MPI
00192 template<typename T, typename TI>
00193 struct CommPolicy<Amg::GlobalAggregatesMap<T,TI> >
00194 {
00195 typedef Amg::AggregatesMap<T> Type;
00196 typedef typename Amg::GlobalAggregatesMap<T,TI>::IndexedType IndexedType;
00197 typedef SizeOne IndexedTypeFlag;
00198 static int getSize(const Type&, int)
00199 {
00200 return 1;
00201 }
00202 };
00203 #endif
00204
00205 }
00206
00207 #endif