00001 /* 00002 00003 Copyright (C) University of Oxford, 2005-2009 00004 00005 University of Oxford means the Chancellor, Masters and Scholars of the 00006 University of Oxford, having an administrative office at Wellington 00007 Square, Oxford OX1 2JD, UK. 00008 00009 This file is part of Chaste. 00010 00011 Chaste is free software: you can redistribute it and/or modify it 00012 under the terms of the GNU Lesser General Public License as published 00013 by the Free Software Foundation, either version 2.1 of the License, or 00014 (at your option) any later version. 00015 00016 Chaste is distributed in the hope that it will be useful, but WITHOUT 00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00018 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00019 License for more details. The offer of Chaste under the terms of the 00020 License is subject to the License being interpreted in accordance with 00021 English Law and subject to any action against the University of Oxford 00022 being under the jurisdiction of the English Courts. 00023 00024 You should have received a copy of the GNU Lesser General Public License 00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>. 00026 00027 */ 00028 00029 00030 #ifndef DISTRIBUTEDVECTOR_HPP_ 00031 #define DISTRIBUTEDVECTOR_HPP_ 00032 00033 #include <vector> 00034 #include <petscvec.h> 00035 #include <iostream> 00036 #include <cassert> 00037 00038 #include "DistributedVectorException.hpp" 00039 00040 class DistributedVectorFactory; 00041 00048 class DistributedVector 00049 { 00050 private: 00051 friend class TestDistributedVector; 00052 00053 // Data global to all vectors. 00054 00056 unsigned mLo; 00057 00059 unsigned mHi; 00060 00062 unsigned mProblemSize; 00063 00064 // Data local to a single vector. 00066 unsigned mSizeMultiplier; 00068 Vec mVec; 00070 double *mpVec; 00071 00076 DistributedVectorFactory *mpFactory; 00077 00078 00079 public: 00080 00086 bool IsGlobalIndexLocal(unsigned globalIndex); 00087 00097 DistributedVector(Vec vec, DistributedVectorFactory* pFactory); 00098 00102 unsigned GetHigh() const 00103 { 00104 return mHi; 00105 } 00106 00110 unsigned GetLow() const 00111 { 00112 return mLo; 00113 } 00114 00118 DistributedVectorFactory* GetFactory() 00119 { 00120 return mpFactory; 00121 } 00122 00130 double& operator[](unsigned globalIndex) throw (DistributedVectorException); 00131 00137 void Restore(); 00138 00143 class Iterator 00144 { 00145 public: 00146 unsigned Local; 00147 unsigned Global; 00154 bool operator!=(const Iterator& rOther); 00155 00157 Iterator& operator++(); 00158 }; 00159 00167 class Stripe 00168 { 00169 unsigned mStride; 00170 unsigned mStripe; 00171 double *mpVec; 00172 unsigned mLo; 00173 unsigned mHi; 00174 DistributedVectorFactory *mpFactory; 00176 public: 00183 Stripe(DistributedVector parallelVec, unsigned stripe) 00184 { 00185 mStride = parallelVec.mSizeMultiplier; 00186 mStripe = stripe; 00187 assert(mStripe < mStride); 00188 mpVec = parallelVec.mpVec; 00189 mLo = parallelVec.GetLow(); 00190 mHi = parallelVec.GetHigh(); 00191 mpFactory = parallelVec.GetFactory(); 00192 } 00193 00197 DistributedVectorFactory* GetFactory() 00198 { 00199 return mpFactory; 00200 } 00201 00210 double& operator[](unsigned globalIndex) throw (DistributedVectorException) 00211 { 00212 if (mLo <= globalIndex && globalIndex < mHi) 00213 { 00214 return mpVec[(globalIndex - mLo)*mStride + mStripe]; 00215 } 00216 throw DistributedVectorException(); 00217 } 00218 00223 double& operator[](Iterator index) throw (DistributedVectorException) 00224 { 00225 return mpVec[index.Local*mStride + mStripe]; 00226 } 00227 00228 }; 00229 00237 class Chunk 00238 { 00239 unsigned mOffset; 00240 double *mpVec; 00241 unsigned mLo; 00242 unsigned mHi; 00244 public: 00251 Chunk(DistributedVector parallelVec, unsigned chunk) 00252 { 00253 assert(chunk < parallelVec.mSizeMultiplier); 00254 mLo = parallelVec.GetLow(); 00255 mHi = parallelVec.GetHigh(); 00256 mOffset = chunk * (mHi - mLo); 00257 mpVec = parallelVec.mpVec; 00258 } 00259 00268 double& operator[](unsigned globalIndex) throw (DistributedVectorException) 00269 { 00270 if (mLo <= globalIndex && globalIndex < mHi) 00271 { 00272 //localIndex = globalIndex - mLo 00273 return mpVec[mOffset + globalIndex - mLo]; 00274 } 00275 throw DistributedVectorException(); 00276 } 00277 00282 double& operator[](Iterator index) throw (DistributedVectorException) 00283 { 00284 return mpVec[mOffset + index.Local]; 00285 } 00286 00287 }; 00288 00293 Iterator Begin(); 00294 00299 Iterator End(); 00300 00306 double& operator[](Iterator index) throw (DistributedVectorException); 00307 }; 00308 00309 00310 00311 #endif /*DISTRIBUTEDVECTOR_HPP_*/