DistributedVectorFactory.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <cassert>
00037
00038 #include "DistributedVectorFactory.hpp"
00039 #include "PetscTools.hpp"
00040
00041
00042 bool DistributedVectorFactory::msCheckNumberOfProcessesOnLoad = true;
00043
00044 void DistributedVectorFactory::CalculateOwnership(Vec vec)
00045 {
00046 #ifndef NDEBUG
00047 if (!mPetscStatusKnown)
00048 {
00049 CheckForPetsc();
00050 }
00051 #endif
00052
00053
00054 PetscInt petsc_lo, petsc_hi;
00055 VecGetOwnershipRange(vec, &petsc_lo, &petsc_hi);
00056 mGlobalLows.clear();
00057 mLo = (unsigned)petsc_lo;
00058 mHi = (unsigned)petsc_hi;
00059
00060 PetscInt size;
00061 VecGetSize(vec, &size);
00062 mProblemSize = (unsigned) size;
00063 mNumProcs = PetscTools::GetNumProcs();
00064 }
00065
00066 void DistributedVectorFactory::SetFromFactory(DistributedVectorFactory* pFactory)
00067 {
00068 if (pFactory->GetNumProcs() != mNumProcs)
00069 {
00070 EXCEPTION("Cannot set from a factory for a different number of processes.");
00071 }
00072 if (pFactory->GetProblemSize() != mProblemSize)
00073 {
00074 EXCEPTION("Cannot set from a factory for a different problem size.");
00075 }
00076 mGlobalLows.clear();
00077 mLo = pFactory->GetLow();
00078 mHi = pFactory->GetHigh();
00079 }
00080
00081 DistributedVectorFactory::DistributedVectorFactory(Vec vec)
00082 : mPetscStatusKnown(false),
00083 mpOriginalFactory(NULL)
00084 {
00085 CalculateOwnership(vec);
00086 }
00087
00088 DistributedVectorFactory::DistributedVectorFactory(unsigned size, PetscInt local)
00089 : mPetscStatusKnown(false),
00090 mpOriginalFactory(NULL)
00091 {
00092 #ifndef NDEBUG
00093 CheckForPetsc();
00094 #endif
00095 Vec vec = PetscTools::CreateVec(size, local);
00096 CalculateOwnership(vec);
00097 PetscTools::Destroy(vec);
00098 }
00099
00100 DistributedVectorFactory::DistributedVectorFactory(DistributedVectorFactory* pOriginalFactory)
00101 : mPetscStatusKnown(false),
00102 mpOriginalFactory(pOriginalFactory)
00103 {
00104 assert(mpOriginalFactory != NULL);
00105
00106
00107
00108
00109
00110 Vec vec = PetscTools::CreateVec(mpOriginalFactory->GetProblemSize());
00111
00112 CalculateOwnership(vec);
00113 PetscTools::Destroy(vec);
00114 }
00115
00116 DistributedVectorFactory::DistributedVectorFactory(unsigned lo, unsigned hi, unsigned size, unsigned numProcs)
00117 : mLo(lo),
00118 mHi(hi),
00119 mProblemSize(size),
00120 mNumProcs(numProcs),
00121 mPetscStatusKnown(false),
00122 mpOriginalFactory(NULL)
00123 {
00124 #ifndef NDEBUG
00125 CheckForPetsc();
00126 #endif
00127 }
00128
00129 DistributedVectorFactory::~DistributedVectorFactory()
00130 {
00131 delete mpOriginalFactory;
00132 }
00133
00134 void DistributedVectorFactory::CheckForPetsc()
00135 {
00136 assert(mPetscStatusKnown==false);
00137 PetscBool petsc_is_initialised;
00138 PetscInitialized(&petsc_is_initialised);
00139
00140
00141
00142
00143
00144
00145 assert(petsc_is_initialised);
00146 mPetscStatusKnown = true;
00147 }
00148
00149 bool DistributedVectorFactory::IsGlobalIndexLocal(unsigned globalIndex)
00150 {
00151 return (mLo<=globalIndex && globalIndex<mHi);
00152 }
00153
00154 Vec DistributedVectorFactory::CreateVec()
00155 {
00156 Vec vec = PetscTools::CreateVec(mProblemSize, mHi-mLo);
00157 return vec;
00158 }
00159
00160 Vec DistributedVectorFactory::CreateVec(unsigned stride)
00161 {
00162 Vec vec;
00163 #if (PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR >= 3) //PETSc 3.3 or later
00164
00165
00166 VecCreate(PETSC_COMM_WORLD, &vec);
00167 VecSetBlockSize(vec, stride);
00168 VecSetSizes(vec, stride*(mHi-mLo), stride*mProblemSize);
00169 VecSetType(vec,VECMPI);
00170
00171 #else
00172 VecCreateMPI(PETSC_COMM_WORLD, stride*(mHi-mLo), stride*mProblemSize, &vec);
00173 VecSetBlockSize(vec, stride);
00174 #endif
00175 #if (PETSC_VERSION_MAJOR == 3) //PETSc 3.x.x
00176 VecSetOption(vec, VEC_IGNORE_OFF_PROC_ENTRIES, PETSC_TRUE);
00177 #else
00178 VecSetOption(vec, VEC_IGNORE_OFF_PROC_ENTRIES);
00179 #endif
00180 return vec;
00181 }
00182
00183 DistributedVector DistributedVectorFactory::CreateDistributedVector(Vec vec)
00184 {
00185 DistributedVector dist_vector(vec, this);
00186 return dist_vector;
00187 }
00188
00189 std::vector<unsigned> &DistributedVectorFactory::rGetGlobalLows()
00190 {
00191 if (mGlobalLows.size() != PetscTools::GetNumProcs())
00192 {
00193 assert( mGlobalLows.empty());
00194 mGlobalLows.resize(PetscTools::GetNumProcs());
00195
00196
00197 MPI_Allgather( &mLo, 1, MPI_UNSIGNED, &mGlobalLows[0], 1, MPI_UNSIGNED, PETSC_COMM_WORLD);
00198 }
00199
00200 return mGlobalLows;
00201 }
00202
00203
00204 #include "SerializationExportWrapperForCpp.hpp"
00205 CHASTE_CLASS_EXPORT(DistributedVectorFactory)