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