ReplicatableVector.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 "ReplicatableVector.hpp"
00037 #include "Exception.hpp"
00038 #include "PetscTools.hpp"
00039
00040 #include <cassert>
00041 #include <iostream>
00042
00043
00044
00045 void ReplicatableVector::RemovePetscContext()
00046 {
00047 if (mToAll != NULL)
00048 {
00049 VecScatterDestroy(PETSC_DESTROY_PARAM(mToAll));
00050 mToAll = NULL;
00051 }
00052
00053 if (mReplicated != NULL)
00054 {
00055 PetscTools::Destroy(mReplicated);
00056 mReplicated = NULL;
00057 }
00058
00059 if (mpData != NULL)
00060 {
00061 delete[] mpData;
00062 mpData = NULL;
00063 }
00064 }
00065
00066
00067
00068 ReplicatableVector::ReplicatableVector()
00069 : mpData(NULL),
00070 mSize(0),
00071 mToAll(NULL),
00072 mReplicated(NULL)
00073 {
00074 }
00075
00076 ReplicatableVector::ReplicatableVector(Vec vec)
00077 : mpData(NULL),
00078 mSize(0),
00079 mToAll(NULL),
00080 mReplicated(NULL)
00081 {
00082 ReplicatePetscVector(vec);
00083 }
00084
00085 ReplicatableVector::ReplicatableVector(unsigned size)
00086 : mpData(NULL),
00087 mSize(0),
00088 mToAll(NULL),
00089 mReplicated(NULL)
00090 {
00091 Resize(size);
00092 }
00093
00094 ReplicatableVector::~ReplicatableVector()
00095 {
00096 RemovePetscContext();
00097 }
00098
00099
00100
00101 unsigned ReplicatableVector::GetSize()
00102 {
00103 return mSize;
00104 }
00105
00106 void ReplicatableVector::Resize(unsigned size)
00107 {
00108
00109 RemovePetscContext();
00110
00111 mSize = size;
00112
00113 try
00114 {
00115 mpData = new double[mSize];
00116 }
00117 catch(std::bad_alloc &badAlloc)
00118 {
00119 #define COVERAGE_IGNORE
00120 std::cout << "Failed to allocate a ReplicatableVector of size " << size << std::endl;
00121 PetscTools::ReplicateException(true);
00122 throw badAlloc;
00123 #undef COVERAGE_IGNORE
00124 }
00125 PetscTools::ReplicateException(false);
00126 }
00127
00128 double& ReplicatableVector::operator[](unsigned index)
00129 {
00130 assert(index < mSize);
00131 return mpData[index];
00132 }
00133
00134
00135
00136 void ReplicatableVector::Replicate(unsigned lo, unsigned hi)
00137 {
00138
00139 Vec distributed_vec;
00140
00141 #if (PETSC_VERSION_MAJOR == 3 && PETSC_VERSION_MINOR >= 3) //PETSc 3.3 or later
00142
00143 VecCreateMPIWithArray(PETSC_COMM_WORLD, 1, hi-lo, this->GetSize(), &mpData[lo], &distributed_vec);
00144 #else
00145 VecCreateMPIWithArray(PETSC_COMM_WORLD, hi-lo, this->GetSize(), &mpData[lo], &distributed_vec);
00146 #endif
00147 #if (PETSC_VERSION_MAJOR == 3) //PETSc 3.x.x
00148 VecSetOption(distributed_vec, VEC_IGNORE_OFF_PROC_ENTRIES, PETSC_TRUE);
00149 #else
00150 VecSetOption(distributed_vec, VEC_IGNORE_OFF_PROC_ENTRIES);
00151 #endif
00152
00153 ReplicatePetscVector(distributed_vec);
00154
00155
00156 PetscTools::Destroy(distributed_vec);
00157 }
00158
00159 void ReplicatableVector::ReplicatePetscVector(Vec vec)
00160 {
00161
00162 PetscInt isize;
00163 VecGetSize(vec, &isize);
00164 unsigned size = isize;
00165
00166 if (this->GetSize() != size)
00167 {
00168 Resize(size);
00169 }
00170 if (mReplicated == NULL)
00171 {
00172
00173 VecScatterCreateToAll(vec, &mToAll, &mReplicated);
00174 }
00175
00176
00177
00178 #if ( (PETSC_VERSION_MAJOR == 3) || (PETSC_VERSION_MAJOR == 2 && PETSC_VERSION_MINOR == 3 && PETSC_VERSION_SUBMINOR == 3)) //2.3.3 or 3.x.x
00179 VecScatterBegin(mToAll, vec, mReplicated, INSERT_VALUES, SCATTER_FORWARD);
00180 VecScatterEnd (mToAll, vec, mReplicated, INSERT_VALUES, SCATTER_FORWARD);
00181 #else
00182
00183 VecScatterBegin(vec, mReplicated, INSERT_VALUES, SCATTER_FORWARD, mToAll);
00184 VecScatterEnd (vec, mReplicated, INSERT_VALUES, SCATTER_FORWARD, mToAll);
00185 #endif
00186
00187
00188
00189 double* p_replicated;
00190 VecGetArray(mReplicated, &p_replicated);
00191 for (unsigned i=0; i<size; i++)
00192 {
00193 mpData[i] = p_replicated[i];
00194 }
00195 }