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

Generated on Tue Aug 4 16:10:21 2009 for Chaste by  doxygen 1.5.5