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 "PetscTools.hpp"
00030
00031 bool PetscTools::mPetscIsInitialised = false;
00032 unsigned PetscTools::mNumProcessors = 0;
00033 unsigned PetscTools::mRank = 0;
00034
00035 void PetscTools::ResetCache()
00036 {
00037 #ifdef SPECIAL_SERIAL
00038 mPetscIsInitialised = false;
00039 mNumProcessors = 1;
00040 mRank = 0;
00041 #else
00042 PetscTruth is_there;
00043 PetscInitialized(&is_there);
00044 if (is_there)
00045 {
00046 mPetscIsInitialised = true;
00047
00048 PetscInt num_procs;
00049 MPI_Comm_size(PETSC_COMM_WORLD, &num_procs);
00050 mNumProcessors = (unsigned) num_procs;
00051
00052 PetscInt my_rank;
00053 MPI_Comm_rank(PETSC_COMM_WORLD, &my_rank);
00054 mRank = (unsigned) my_rank;
00055 }
00056 else
00057 {
00058
00059 mPetscIsInitialised = false;
00060 mNumProcessors = 1;
00061 mRank = 0;
00062 }
00063 #endif
00064 }
00065
00066
00067
00068
00069
00070 bool PetscTools::IsSequential()
00071 {
00072 if (mNumProcessors == 0)
00073 {
00074 ResetCache();
00075 }
00076 return (mNumProcessors == 1);
00077 }
00078
00079 unsigned PetscTools::NumProcs()
00080 {
00081 if (mNumProcessors == 0)
00082 {
00083 ResetCache();
00084 }
00085 return mNumProcessors;
00086 }
00087
00088 unsigned PetscTools::GetMyRank()
00089 {
00090 if (mNumProcessors == 0)
00091 {
00092 ResetCache();
00093 }
00094 return mRank;
00095 }
00096
00097 bool PetscTools::AmMaster()
00098 {
00099 if (mNumProcessors == 0)
00100 {
00101 ResetCache();
00102 }
00103 return (mRank == MASTER_RANK);
00104 }
00105
00106
00107
00108
00109
00110 void PetscTools::Barrier()
00111 {
00112 if (mNumProcessors == 0)
00113 {
00114 ResetCache();
00115 }
00116 if (mPetscIsInitialised)
00117 {
00118 PetscBarrier(PETSC_NULL);
00119 }
00120 }
00121
00122 #ifndef SPECIAL_SERIAL
00123
00124 void PetscTools::ReplicateException(bool flag)
00125 {
00126 unsigned my_error = (unsigned) flag;
00127 unsigned anyones_error;
00128 MPI_Allreduce(&my_error, &anyones_error, 1, MPI_UNSIGNED, MPI_SUM, PETSC_COMM_WORLD);
00129 if (flag)
00130 {
00131
00132 return;
00133 }
00134 if (anyones_error)
00135 {
00136 EXCEPTION("Another process threw an exception; bailing out.");
00137 }
00138 }
00139
00140
00141
00142
00143
00144 Vec PetscTools::CreateVec(int size)
00145 {
00146 assert(size>0);
00147 Vec ret;
00148 VecCreate(PETSC_COMM_WORLD, &ret);
00149 VecSetSizes(ret, PETSC_DECIDE, size);
00150 VecSetFromOptions(ret);
00151 return ret;
00152 }
00153
00154 Vec PetscTools::CreateVec(int size, double value)
00155 {
00156 assert(size>0);
00157 Vec ret = CreateVec(size);
00158
00159 #if (PETSC_VERSION_MINOR == 2) //Old API
00160 VecSet(&value, ret);
00161 #else
00162 VecSet(ret, value);
00163 #endif
00164
00165 VecAssemblyBegin(ret);
00166 VecAssemblyEnd(ret);
00167 return ret;
00168 }
00169
00170 Vec PetscTools::CreateVec(std::vector<double> data)
00171 {
00172 assert(data.size()>0);
00173 Vec ret = CreateVec(data.size());
00174
00175 double* p_ret;
00176 VecGetArray(ret, &p_ret);
00177 int lo, hi;
00178 VecGetOwnershipRange(ret, &lo, &hi);
00179
00180 for (int global_index=lo; global_index<hi; global_index++)
00181 {
00182 int local_index = global_index - lo;
00183 p_ret[local_index] = data[global_index];
00184 }
00185 VecRestoreArray(ret, &p_ret);
00186 VecAssemblyBegin(ret);
00187 VecAssemblyEnd(ret);
00188
00189 return ret;
00190 }
00191
00192 void PetscTools::SetupMat(Mat& rMat, int numRows, int numColumns,
00193 MatType matType,
00194 int numLocalRows,
00195 int numLocalColumns,
00196 int maxColsPerRow)
00197 {
00198 assert(numRows>0);
00199 assert(numColumns>0);
00200
00201 #if (PETSC_VERSION_MINOR == 2) //Old API
00202 MatCreate(PETSC_COMM_WORLD,numLocalRows,numLocalColumns,numRows,numColumns,&rMat);
00203 #else //New API
00204 MatCreate(PETSC_COMM_WORLD,&rMat);
00205 MatSetSizes(rMat,numLocalRows,numLocalColumns,numRows,numColumns);
00206 #endif
00207
00208 MatSetType(rMat, matType);
00209
00210 if (strcmp(matType,MATMPIAIJ)==0)
00211 {
00212 MatMPIAIJSetPreallocation(rMat, maxColsPerRow, PETSC_NULL, (PetscInt) (maxColsPerRow*0.5), PETSC_NULL);
00213 }
00214
00215 MatSetFromOptions(rMat);
00216 }
00217
00218 void PetscTools::DumpPetscObject(Mat& rMat, const std::string& rOutputFileFullPath)
00219 {
00220 PetscViewer view;
00221 #if (PETSC_VERSION_MINOR == 2) //Old API
00222 PetscViewerFileType type = PETSC_FILE_WRONLY;
00223 #else
00224 PetscFileMode type = FILE_MODE_WRITE;
00225 #endif
00226
00227 PetscViewerBinaryOpen(PETSC_COMM_WORLD, rOutputFileFullPath.c_str(),
00228 type, &view);
00229 MatView(rMat, view);
00230 PetscViewerDestroy(view);
00231 }
00232
00233 void PetscTools::DumpPetscObject(Vec& rVec, const std::string& rOutputFileFullPath)
00234 {
00235 PetscViewer view;
00236 #if (PETSC_VERSION_MINOR == 2) //Old API
00237 PetscViewerFileType type = PETSC_FILE_WRONLY;
00238 #else
00239 PetscFileMode type = FILE_MODE_WRITE;
00240 #endif
00241
00242 PetscViewerBinaryOpen(PETSC_COMM_WORLD, rOutputFileFullPath.c_str(),
00243 type, &view);
00244 VecView(rVec, view);
00245 PetscViewerDestroy(view);
00246 }
00247
00248 void PetscTools::ReadPetscObject(Mat& rMat, const std::string& rOutputFileFullPath)
00249 {
00250 PetscViewer view;
00251 #if (PETSC_VERSION_MINOR == 2) //Old API
00252 PetscViewerFileType type = PETSC_FILE_RDONLY;
00253 #else
00254 PetscFileMode type = FILE_MODE_READ;
00255 #endif
00256
00257 PetscViewerBinaryOpen(PETSC_COMM_WORLD, rOutputFileFullPath.c_str(),
00258 type, &view);
00259 MatLoad(view, MATMPIAIJ, &rMat);
00260 PetscViewerDestroy(view);
00261 }
00262
00263 void PetscTools::ReadPetscObject(Vec& rVec, const std::string& rOutputFileFullPath)
00264 {
00265 PetscViewer view;
00266 #if (PETSC_VERSION_MINOR == 2) //Old API
00267 PetscViewerFileType type = PETSC_FILE_RDONLY;
00268 #else
00269 PetscFileMode type = FILE_MODE_READ;
00270 #endif
00271
00272 PetscViewerBinaryOpen(PETSC_COMM_WORLD, rOutputFileFullPath.c_str(),
00273 type, &view);
00274 VecLoad(view, VECMPI, &rVec);
00275 PetscViewerDestroy(view);
00276 }
00277
00278
00279 #endif //SPECIAL_SERIAL