PetscTools.cpp

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

Generated by  doxygen 1.6.2