PetscTools.cpp

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 #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         // No PETSc
00059         mPetscIsInitialised = false;
00060         mNumProcessors = 1;
00061         mRank = 0;
00062     }
00063 #endif
00064 }
00065 
00066 //
00067 // Information methods
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 // Little utility methods
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             // Return control to exception thrower
00132             return;
00133         }
00134         if (anyones_error)
00135         {
00136             EXCEPTION("Another process threw an exception; bailing out.");
00137         }
00138     }
00139 
00140 //
00141 // Vector & Matrix creation routines
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

Generated on Wed Mar 18 12:51:50 2009 for Chaste by  doxygen 1.5.5