vector/PetscVector.cxx

00001 // Copyright (C) 2011-2012, INRIA
00002 // Author(s): Marc Fragu
00003 //
00004 // This file is part of the linear-algebra library Seldon,
00005 // http://seldon.sourceforge.net/.
00006 //
00007 // Seldon is free software; you can redistribute it and/or modify it under the
00008 // terms of the GNU Lesser General Public License as published by the Free
00009 // Software Foundation; either version 2.1 of the License, or (at your option)
00010 // any later version.
00011 //
00012 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
00013 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
00015 // more details.
00016 //
00017 // You should have received a copy of the GNU Lesser General Public License
00018 // along with Seldon. If not, see http://www.gnu.org/licenses/.
00019 
00020 
00021 #ifndef SELDON_FILE_VECTOR_PETSCVECTOR_CXX
00022 
00023 
00024 #include "PetscVector.hxx"
00025 
00026 
00027 namespace Seldon
00028 {
00029 
00030 
00031   /****************
00032    * CONSTRUCTORS *
00033    ****************/
00034 
00035 
00037 
00040   template <class T, class Allocator>
00041   PETScVector<T, Allocator>::PETScVector():
00042     Vector_Base<T, Allocator>()
00043   {
00044     this->m_ = 0;
00045     petsc_vector_deallocated_ = false;
00046   }
00047 
00048 
00050 
00054   template <class T, class Allocator>
00055   PETScVector<T, Allocator>::PETScVector(int i, MPI_Comm mpi_communicator)
00056     :Vector_Base<T, Allocator>(i)
00057   {
00058     this->m_ = i;
00059     petsc_vector_deallocated_ = false;
00060   }
00061 
00062 
00064 
00067   template <class T, class Allocator>
00068   PETScVector<T, Allocator>::
00069   PETScVector(Vec& petsc_vector)
00070   {
00071     petsc_vector_deallocated_ = true;
00072     Copy(petsc_vector);
00073   }
00074 
00075 
00077 
00080   template <class T, class Allocator>
00081   PETScVector<T, Allocator>::
00082   PETScVector(const PETScVector<T, Allocator>& V)
00083   {
00084     Copy(V);
00085   }
00086 
00087 
00088   /**************
00089    * DESTRUCTOR *
00090    **************/
00091 
00092 
00094   template <class T, class Allocator>
00095   PETScVector<T, Allocator>::~PETScVector()
00096   {
00097     Clear();
00098   }
00099 
00100 
00102 
00105   template <class T, class Allocator>
00106   Vec& PETScVector<T, Allocator>::GetPetscVector()
00107   {
00108     return petsc_vector_;
00109   }
00110 
00111 
00113 
00116   template <class T, class Allocator>
00117   const Vec& PETScVector<T, Allocator>::GetPetscVector() const
00118   {
00119     return petsc_vector_;
00120   }
00121 
00122 
00124 
00127   template <class T, class Allocator>
00128   void PETScVector<T, Allocator>::SetCommunicator(MPI_Comm mpi_communicator)
00129   {
00130     mpi_communicator_ = mpi_communicator;
00131   }
00132 
00133 
00134   /*********************
00135    * MEMORY MANAGEMENT *
00136    *********************/
00137 
00138 
00140 
00144   template <class T, class Allocator>
00145   inline void PETScVector<T, Allocator>::Clear()
00146   {
00147     if (petsc_vector_deallocated_)
00148       return;
00149     int ierr;
00150     ierr = VecDestroy(&petsc_vector_);
00151     CHKERRABORT(mpi_communicator_, ierr);
00152     petsc_vector_deallocated_ = true;
00153   }
00154 
00155 
00157 
00161   template <class T, class Allocator>
00162   inline void PETScVector<T, Allocator>::Resize(int n)
00163   {
00164     throw Undefined("PETScVector<T, Allocator>::Resize(int n)");
00165   }
00166 
00167 
00182   template <class T, class Allocator>
00183   inline void PETScVector<T, Allocator>
00184   ::SetData(int i, typename PETScVector<T, Allocator>::pointer data)
00185   {
00186     throw Undefined("PETScVector<T, Allocator>::SetData(int i, "
00187                     "typename PETScVector<T, Allocator>::pointer data)");
00188   }
00189 
00190 
00192 
00197   template <class T, class Allocator>
00198   void PETScVector<T, Allocator>::Nullify()
00199   {
00200     throw Undefined("PETScVector<T, Allocator>::Nullify()");
00201   }
00202 
00203 
00204   /**********************************
00205    * ELEMENT ACCESS AND AFFECTATION *
00206    **********************************/
00207 
00208 
00210 
00214   template <class T, class Allocator>
00215   inline typename PETScVector<T, Allocator>::value_type
00216   PETScVector<T, Allocator>::operator() (int i) const
00217   {
00218 #ifdef SELDON_CHECK_BOUNDS
00219     if (i < 0 || i >= this->m_)
00220       throw WrongIndex("Vector<PETSc>::operator()",
00221                        string("Index should be in [0, ") + to_str(this->m_-1)
00222                        + "], but is equal to " + to_str(i) + ".");
00223 #endif
00224     int ierr;
00225     value_type ret[1];
00226     int index[1];
00227     index[0] = i;
00228     ierr = VecGetValues(petsc_vector_, 1, index, ret);
00229     CHKERRABORT(mpi_communicator_, ierr);
00230     return ret[0];
00231   }
00232 
00233 
00235 
00243   template <class T, class Allocator>
00244   inline void PETScVector<T, Allocator>
00245   ::SetBuffer(int i, T value, InsertMode insert_mode)
00246   {
00247     int ierr;
00248     int ix[1] = {i};
00249     T data[1] = {value};
00250     ierr = VecSetValues(petsc_vector_, 1, ix,
00251                         data, INSERT_VALUES);
00252     CHKERRABORT(mpi_communicator_, ierr);
00253   }
00254 
00255 
00257   template <class T, class Allocator>
00258   inline void PETScVector<T, Allocator>
00259   ::Flush()
00260   {
00261     int ierr;
00262     ierr = VecAssemblyBegin(petsc_vector_);
00263     CHKERRABORT(mpi_communicator_, ierr);
00264     ierr = VecAssemblyEnd(petsc_vector_);
00265     CHKERRABORT(mpi_communicator_, ierr);
00266   }
00267 
00268 
00270 
00278   template <class T, class Allocator>
00279   inline void PETScVector<T, Allocator>
00280   ::GetProcessorRange(int& i, int& j) const
00281   {
00282     int ierr;
00283     ierr = VecGetOwnershipRange(petsc_vector_, &i, &j);
00284     CHKERRABORT(mpi_communicator_, ierr);
00285   }
00286 
00287 
00289 
00294   template <class T, class Allocator>
00295   inline void PETScVector<T, Allocator>
00296   ::Copy(const PETScVector<T, Allocator>& X)
00297   {
00298     Copy(X.GetPetscVector());
00299   }
00300 
00301 
00303 
00308   template <class T, class Allocator>
00309   inline void PETScVector<T, Allocator>
00310   ::Copy(const Vec& petsc_vector)
00311   {
00312     Clear();
00313 
00314     int ierr;
00315     ierr = VecGetSize(petsc_vector, &this->m_);
00316     CHKERRABORT(mpi_communicator_, ierr);
00317     PetscObjectGetComm(reinterpret_cast<PetscObject>(petsc_vector),
00318                        &mpi_communicator_);
00319     CHKERRABORT(mpi_communicator_, ierr);
00320     ierr = VecDuplicate(petsc_vector, &petsc_vector_);
00321     CHKERRABORT(mpi_communicator_, ierr);
00322     ierr = VecCopy(petsc_vector, petsc_vector_);
00323     CHKERRABORT(mpi_communicator_, ierr);
00324     petsc_vector_deallocated_ = false;
00325   }
00326 
00327 
00329 
00334   template <class T, class Allocator>
00335   inline void PETScVector<T, Allocator>::Append(const T& x)
00336   {
00337     throw Undefined("PETScVector<T, Allocator>::Append(const T& x)");
00338   }
00339 
00340 
00341   /*******************
00342    * BASIC FUNCTIONS *
00343    *******************/
00344 
00345 
00347 
00350   template <class T, class Allocator>
00351   int PETScVector<T, Allocator>::GetDataSize() const
00352   {
00353     return this->m_;
00354   }
00355 
00356 
00358 
00361   template <class T, class Allocator>
00362   int PETScVector<T, Allocator>::GetLocalM() const
00363   {
00364     int size;
00365     VecGetLocalSize(petsc_vector_, &size);
00366     return size;
00367   }
00368 
00369 
00370   /************************
00371    * CONVENIENT FUNCTIONS *
00372    ************************/
00373 
00374 
00376 
00380   template <class T, class Allocator>
00381   void PETScVector<T, Allocator>::Zero()
00382   {
00383     int ierr;
00384     ierr = VecSet(petsc_vector_, 0.);
00385     CHKERRABORT(mpi_communicator_, ierr);
00386   }
00387 
00388 
00390   template <class T, class Allocator>
00391   void PETScVector<T, Allocator>::Fill()
00392   {
00393     int ierr;
00394     Vector<int> index(this->m_);
00395     Vector<double> data(this->m_);
00396     index.Fill();
00397     data.Fill();
00398     ierr = VecSetValues(petsc_vector_, this->m_, index.GetData(),
00399                         data.GetData(), INSERT_VALUES);
00400     CHKERRABORT(mpi_communicator_, ierr);
00401     Flush();
00402   }
00403 
00404 
00406 
00409   template <class T, class Allocator>
00410   template <class T0>
00411   void PETScVector<T, Allocator>::Fill(const T0& x)
00412   {
00413     int ierr;
00414     ierr = VecSet(petsc_vector_, double(x));
00415     CHKERRABORT(mpi_communicator_, ierr);
00416     Flush();
00417   }
00418 
00419 
00421 
00424   template <class T, class Allocator>
00425   void PETScVector<T, Allocator>::FillRand()
00426   {
00427     int ierr;
00428     Vector<int> index(this->m_);
00429     Vector<double> data(this->m_);
00430     index.Fill();
00431     data.FillRand();
00432     ierr = VecSetValues(petsc_vector_, this->m_, index.GetData(),
00433                         data.GetData(), INSERT_VALUES);
00434     CHKERRABORT(mpi_communicator_, ierr);
00435     Flush();
00436   }
00437 
00438 
00439   /*********
00440    * NORMS *
00441    *********/
00442 
00443 
00445 
00448   template <class T, class Allocator>
00449   typename PETScVector<T, Allocator>::value_type
00450   PETScVector<T, Allocator>::GetNormInf() const
00451   {
00452     int ierr;
00453     value_type res;
00454     ierr = VecNorm(petsc_vector_, NORM_INFINITY, &res);
00455     CHKERRABORT(mpi_communicator_, ierr);
00456     return res;
00457   }
00458 
00459 
00461 
00464   template <class T, class Allocator>
00465   int PETScVector<T, Allocator>::GetNormInfIndex() const
00466   {
00467     throw Undefined("PETScVector<T, Allocator>::GetNormInfIndex()");
00468   }
00469 
00470 
00472   // SEQUENTIAL PETSC VECTOR //
00474 
00475 
00476   /****************
00477    * CONSTRUCTORS *
00478    ****************/
00479 
00480 
00482 
00485   template <class T, class Allocator>
00486   Vector<T, PETScSeq, Allocator>::Vector():
00487     PETScVector<T, Allocator>()
00488   {
00489     this->mpi_communicator_ = MPI_COMM_WORLD;
00490     this->m_ = 0;
00491     int ierr;
00492     ierr = VecCreateSeq(PETSC_COMM_SELF, 0, &this->petsc_vector_);
00493     this->petsc_vector_deallocated_ = false;
00494   }
00495 
00496 
00498 
00502   template <class T, class Allocator>
00503   Vector<T, PETScSeq, Allocator>::Vector(int i, MPI_Comm mpi_communicator)
00504     :PETScVector<T, Allocator>(i)
00505   {
00506     int ierr;
00507     this->mpi_communicator_ = mpi_communicator;
00508     this->m_ = i;
00509     ierr = VecCreateSeq(PETSC_COMM_SELF, i, &this->petsc_vector_);
00510     CHKERRABORT(this->mpi_communicator_, ierr);
00511     ierr = VecSet(this->petsc_vector_, 0.);
00512     CHKERRABORT(this->mpi_communicator_, ierr);
00513     this->Flush();
00514   }
00515 
00516 
00518 
00521   template <class T, class Allocator>
00522   Vector<T, PETScSeq, Allocator>::
00523   Vector(Vec& petsc_vector): PETScVector<T, Allocator>(petsc_vector)
00524   {
00525   }
00526 
00527 
00529 
00532   template <class T, class Allocator>
00533   Vector<T, PETScSeq, Allocator>::
00534   Vector(const Vector<T, PETScSeq, Allocator>& V)
00535   {
00536     Copy(V);
00537   }
00538 
00539 
00540   /**************
00541    * DESTRUCTOR *
00542    **************/
00543 
00544 
00546   template <class T, class Allocator>
00547   Vector<T, PETScSeq, Allocator>::~Vector()
00548   {
00549   }
00550 
00551 
00553 
00558   template <class T, class Allocator>
00559   void Vector<T, PETScSeq, Allocator>
00560   ::Copy(const Vector<T, PETScSeq, Allocator>& X)
00561   {
00562     Copy(X.GetPetscVector());
00563   }
00564 
00565 
00567 
00572   template <class T, class Allocator>
00573   void Vector<T, PETScSeq, Allocator>
00574   ::Copy(const Vec& X)
00575   {
00576     PETScVector<T, Allocator>::Copy(X);
00577   }
00578 
00579 
00581 
00587   template <class T, class Allocator>
00588   inline void Vector<T, PETScSeq, Allocator>
00589   ::Reallocate(int i)
00590   {
00591     this->Clear();
00592     int ierr;
00593     this->m_ = i;
00594     ierr = VecCreateSeq(PETSC_COMM_SELF, i, &this->petsc_vector_);
00595     CHKERRABORT(this->mpi_communicator_, ierr);
00596     Fill(T(0));
00597     this->Flush();
00598     this->petsc_vector_deallocated_ = false;
00599   }
00600 
00601 
00603 
00608   template <class T, class Allocator>
00609   inline Vector<T, PETScSeq, Allocator>& Vector<T, PETScSeq, Allocator>
00610   ::operator= (const Vector<T, PETScSeq, Allocator>& X)
00611   {
00612     this->Copy(X);
00613     return *this;
00614   }
00615 
00616 
00618 
00621   template <class T, class Allocator>
00622   template <class T0>
00623   Vector<T, PETScSeq, Allocator>&
00624   Vector<T, PETScSeq, Allocator>::operator= (const T0& x)
00625   {
00626     this->Fill(x);
00627     return *this;
00628   }
00629 
00630 
00632 
00635   template <class T, class Allocator>
00636   template<class T0>
00637   inline Vector<T, PETScSeq, Allocator>& Vector<T, PETScSeq, Allocator>
00638   ::operator*= (const T0& alpha)
00639   {
00640     int ierr;
00641     ierr = VecScale(this->petsc_vector_, alpha);
00642     CHKERRABORT(this->mpi_communicator_, ierr);
00643     return *this;
00644   }
00645 
00646 
00648   template <class T, class Allocator>
00649   void Vector<T, PETScSeq, Allocator>::Print() const
00650   {
00651     int ierr;
00652     ierr = VecView(this->petsc_vector_, PETSC_VIEWER_STDOUT_SELF);
00653   }
00654 
00655 
00656   /**************************
00657    * OUTPUT/INPUT FUNCTIONS *
00658    **************************/
00659 
00660 
00662 
00668   template <class T, class Allocator>
00669   void Vector<T, PETScSeq, Allocator>
00670   ::Write(string FileName, bool with_size) const
00671   {
00672     throw Undefined("Vector<T, PETScSeq, Allocator>"
00673                     "::Write(string FileName, bool with_size) const");
00674   }
00675 
00676 
00678 
00684   template <class T, class Allocator>
00685   void Vector<T, PETScSeq, Allocator>
00686   ::Write(ostream& FileStream, bool with_size) const
00687   {
00688     throw Undefined("Vector<T, PETScSeq, Allocator>"
00689                     "::Write(string FileName, bool with_size) const");
00690   }
00691 
00692 
00694 
00699   template <class T, class Allocator>
00700   void Vector<T, PETScSeq, Allocator>::WriteText(string FileName) const
00701   {
00702     ofstream FileStream;
00703     FileStream.precision(cout.precision());
00704     FileStream.flags(cout.flags());
00705     FileStream.open(FileName.c_str());
00706 #ifdef SELDON_CHECK_IO
00707     // Checks if the file was opened.
00708     if (!FileStream.is_open())
00709       throw IOError("Vector<T, PETScSeq, Allocator>"
00710                     "::WriteText(string FileName)",
00711                     string("Unable to open file \"") + FileName + "\".");
00712 #endif
00713     this->WriteText(FileStream);
00714     FileStream.close();
00715   }
00716 
00717 
00719 
00724   template <class T, class Allocator>
00725   void Vector<T, PETScSeq, Allocator>::WriteText(ostream& FileStream) const
00726   {
00727     throw Undefined("Vector<T, PETScSeq, Allocator>"
00728                     "::WriteText(ostream& FileStream) const");
00729   }
00730 
00731 
00733 
00741   template <class T, class Allocator>
00742   void Vector<T, PETScSeq, Allocator>
00743   ::Read(string FileName, bool with_size)
00744   {
00745     ifstream FileStream;
00746     FileStream.open(FileName.c_str());
00747 #ifdef SELDON_CHECK_IO
00748     // Checks if the file was opened.
00749     if (!FileStream.is_open())
00750       throw IOError("Vector<T, PETScSeq, Allocator>::Read(string FileName)",
00751                     string("Unable to open file \"") + FileName + "\".");
00752 #endif
00753     this->Read(FileStream, with_size);
00754     FileStream.close();
00755   }
00756 
00757 
00759 
00767   template <class T, class Allocator>
00768   void Vector<T, PETScSeq, Allocator>
00769   ::Read(istream& FileStream, bool with_size)
00770   {
00771     throw Undefined("Vector<T, PETScSeq, Allocator>"
00772                     "::Read(istream& FileStream, bool with_size)");
00773   }
00774 
00775 
00777 
00782   template <class T, class Allocator>
00783   void Vector<T, PETScSeq, Allocator>::ReadText(string FileName)
00784   {
00785     throw Undefined("Vector<T, PETScSeq, Allocator>"
00786                     "::ReadText(string FileName)");
00787   }
00788 
00789 
00791 
00796   template <class T, class Allocator>
00797   void Vector<T, PETScSeq, Allocator>::ReadText(istream& FileStream)
00798   {
00799     throw Undefined("Vector<T, PETScSeq, Allocator>"
00800                     "::ReadText(istream& FileStream)");
00801   }
00802 
00803 
00805 
00810   template <class T, class Allocator>
00811   ostream& operator << (ostream& out,
00812                         const Vector<T, PETScSeq, Allocator>& V)
00813   {
00814     out << '\t';
00815     for (int i = 0; i < V.GetLength() - 1; i++)
00816       out << V(i) << '\t';
00817     if (V.GetLength() != 0)
00818       out << V(V.GetLength() - 1);
00819     return out;
00820   }
00821 
00822 
00824   // PARALLEL PETSC VECTOR //
00826 
00827 
00828   /****************
00829    * CONSTRUCTORS *
00830    ****************/
00831 
00832 
00834 
00837   template <class T, class Allocator>
00838   Vector<T, PETScPar, Allocator>::Vector():
00839     PETScVector<T, Allocator>()
00840   {
00841     this->mpi_communicator_ = MPI_COMM_WORLD;
00842     int ierr;
00843     ierr = VecCreateMPI(this->mpi_communicator_,
00844                         PETSC_DECIDE, 0, &this->petsc_vector_);
00845     CHKERRABORT(this->mpi_communicator_, ierr);
00846   }
00847 
00848 
00850 
00854   template <class T, class Allocator>
00855   Vector<T, PETScPar, Allocator>::Vector(int i, MPI_Comm mpi_communicator):
00856     PETScVector<T, Allocator>(i)
00857   {
00858     int ierr;
00859     this->mpi_communicator_ = mpi_communicator;
00860     ierr = VecCreateMPI(this->mpi_communicator_, PETSC_DECIDE, i,
00861                         &this->petsc_vector_);
00862     CHKERRABORT(this->mpi_communicator_, ierr);
00863     ierr = VecSet(this->petsc_vector_, 0.);
00864     CHKERRABORT(this->mpi_communicator_, ierr);
00865     this->Flush();
00866   }
00867 
00868 
00870 
00875   template <class T, class Allocator>
00876   Vector<T, PETScPar, Allocator>::Vector(int i, int Nlocal,
00877                                          MPI_Comm mpi_communicator):
00878     PETScVector<T, Allocator>(i)
00879   {
00880     int ierr;
00881     this->mpi_communicator_ = mpi_communicator;
00882     ierr = VecCreateMPI(this->mpi_communicator_, Nlocal,
00883                         i, &this->petsc_vector_);
00884     CHKERRABORT(this->mpi_communicator_, ierr);
00885     ierr = VecSet(this->petsc_vector_, 0.);
00886     CHKERRABORT(this->mpi_communicator_, ierr);
00887     this->Flush();
00888   }
00889 
00890 
00892 
00895   template <class T, class Allocator>
00896   Vector<T, PETScPar, Allocator>::
00897   Vector(Vec& petsc_vector): PETScVector<T, Allocator>(petsc_vector)
00898   {
00899   }
00900 
00901 
00903 
00906   template <class T, class Allocator>
00907   Vector<T, PETScPar, Allocator>::
00908   Vector(const Vector<T, PETScPar, Allocator>& V)
00909   {
00910     Copy(V);
00911   }
00912 
00913 
00914   /**************
00915    * DESTRUCTOR *
00916    **************/
00917 
00918 
00920   template <class T, class Allocator>
00921   Vector<T, PETScPar, Allocator>::~Vector()
00922   {
00923   }
00924 
00925 
00927 
00932   template <class T, class Allocator>
00933   void Vector<T, PETScPar, Allocator>
00934   ::Copy(const Vector<T, PETScPar, Allocator>& X)
00935   {
00936     Copy(X.GetPetscVector());
00937     this->mpi_communicator_ = X.mpi_communicator_;
00938   }
00939 
00940 
00942 
00947   template <class T, class Allocator>
00948   void Vector<T, PETScPar, Allocator>
00949   ::Copy(const Vec& X)
00950   {
00951     PETScVector<T, Allocator>::Copy(X);
00952   }
00953 
00954 
00956 
00961   template <class T, class Allocator>
00962   inline Vector<T, PETScPar, Allocator>& Vector<T, PETScPar, Allocator>
00963   ::operator= (const Vector<T, PETScPar, Allocator>& X)
00964   {
00965     this->Copy(X);
00966     return *this;
00967   }
00968 
00969 
00971 
00974   template <class T, class Allocator>
00975   template <class T0>
00976   Vector<T, PETScPar, Allocator>&
00977   Vector<T, PETScPar, Allocator>::operator= (const T0& x)
00978   {
00979     this->Fill(x);
00980     return *this;
00981   }
00982 
00983 
00985 
00988   template <class T, class Allocator>
00989   template<class T0>
00990   inline Vector<T, PETScPar, Allocator>& Vector<T, PETScPar, Allocator>
00991   ::operator*= (const T0& alpha)
00992   {
00993     int ierr;
00994     ierr = VecScale(this->petsc_vector_, alpha);
00995     CHKERRABORT(this->mpi_communicator_, ierr);
00996     return *this;
00997   }
00998 
00999 
01001   template <class T, class Allocator>
01002   void Vector<T, PETScPar, Allocator>::Print() const
01003   {
01004     int ierr;
01005     ierr = VecView(this->petsc_vector_, PETSC_VIEWER_STDOUT_WORLD);
01006   }
01007 
01008 
01010 
01016   template <class T, class Allocator>
01017   inline void Vector<T, PETScPar, Allocator>
01018   ::Reallocate(int i, int local_size)
01019   {
01020     this->Clear();
01021     int ierr;
01022     this->m_ = i;
01023     ierr = VecCreateMPI(this->mpi_communicator_, local_size, i,
01024                         &this->petsc_vector_);
01025     CHKERRABORT(this->mpi_communicator_, ierr);
01026     Fill(T(0));
01027     this->Flush();
01028     this->petsc_vector_deallocated_ = false;
01029   }
01030 
01031 
01032   /**************************
01033    * OUTPUT/INPUT FUNCTIONS *
01034    **************************/
01035 
01036 
01038 
01044   template <class T, class Allocator>
01045   void Vector<T, PETScPar, Allocator>
01046   ::Write(string FileName, bool with_size) const
01047   {
01048     throw Undefined("Vector<T, PETScPar, Allocator>"
01049                     "::Write(string FileName, bool with_size) const");
01050   }
01051 
01052 
01054 
01060   template <class T, class Allocator>
01061   void Vector<T, PETScPar, Allocator>
01062   ::Write(ostream& FileStream, bool with_size) const
01063   {
01064     int local_n;
01065     VecGetLocalSize(this->petsc_vector_, &local_n);
01066 
01067     Vector<int> index(local_n);
01068     index.Fill();
01069     int i_start, i_end;
01070     this->GetProcessorRange(i_start, i_end);
01071     for (int i = 0; i < local_n; i++)
01072       index(i) += i_start;
01073     Vector<T> data(local_n);
01074     VecGetValues(this->petsc_vector_, local_n, index.GetData(),
01075                  data.GetData());
01076     data.Write(FileStream, with_size);
01077   }
01078 
01079 
01081 
01086   template <class T, class Allocator>
01087   void Vector<T, PETScPar, Allocator>::WriteText(string FileName) const
01088   {
01089     ofstream FileStream;
01090     FileStream.precision(cout.precision());
01091     FileStream.flags(cout.flags());
01092     FileStream.open(FileName.c_str());
01093 #ifdef SELDON_CHECK_IO
01094     // Checks if the file was opened.
01095     if (!FileStream.is_open())
01096       throw IOError("Vector<T, PETScPar, Allocator>"
01097                     "::WriteText(string FileName)",
01098                     string("Unable to open file \"") + FileName + "\".");
01099 #endif
01100     this->WriteText(FileStream);
01101     FileStream.close();
01102 
01103   }
01104 
01105 
01107 
01112   template <class T, class Allocator>
01113   void Vector<T, PETScPar, Allocator>::WriteText(ostream& FileStream) const
01114   {
01115     int local_n;
01116     VecGetLocalSize(this->petsc_vector_, &local_n);
01117 
01118     Vector<int> index(local_n);
01119     index.Fill();
01120     int i_start, i_end;
01121     this->GetProcessorRange(i_start, i_end);
01122     for (int i = 0; i < local_n; i++)
01123       index(i) += i_start;
01124     Vector<T> data(local_n);
01125     VecGetValues(this->petsc_vector_, local_n, index.GetData(),
01126                  data.GetData());
01127     data.WriteText(FileStream);
01128   }
01129 
01130 
01132 
01140   template <class T, class Allocator>
01141   void Vector<T, PETScPar, Allocator>
01142   ::Read(string FileName, bool with_size)
01143   {
01144     ifstream FileStream;
01145     FileStream.open(FileName.c_str());
01146 #ifdef SELDON_CHECK_IO
01147     // Checks if the file was opened.
01148     if (!FileStream.is_open())
01149       throw IOError("Vector<T, PETScPar, Allocator>::Read(string FileName)",
01150                     string("Unable to open file \"") + FileName + "\".");
01151 #endif
01152     this->Read(FileStream, with_size);
01153     FileStream.close();
01154   }
01155 
01156 
01158 
01166   template <class T, class Allocator>
01167   void Vector<T, PETScPar, Allocator>
01168   ::Read(istream& FileStream, bool with_size)
01169   {
01170     throw Undefined("PETScVector<T, PETScPar, Allocator>"
01171                     "::Read(istream& FileStream, bool with_size)");
01172   }
01173 
01174 
01176 
01181   template <class T, class Allocator>
01182   void Vector<T, PETScPar, Allocator>::ReadText(string FileName)
01183   {
01184     throw Undefined("PETScVector<T, PETScPar, Allocator>"
01185                     "::ReadText(string FileName)");
01186   }
01187 
01188 
01190 
01195   template <class T, class Allocator>
01196   void Vector<T, PETScPar, Allocator>::ReadText(istream& FileStream)
01197   {
01198     throw Undefined("PETScVector<T, PETScPar, Allocator>"
01199                     "::ReadText(istream& FileStream)");
01200   }
01201 
01202 
01204 
01209   template <class T, class Allocator>
01210   ostream& operator << (ostream& out,
01211                         const Vector<T, PETScPar, Allocator>& V)
01212   {
01213     out << '\t';
01214     for (int i = 0; i < V.GetLength() - 1; i++)
01215       out << V(i) << '\t';
01216     if (V.GetLength() != 0)
01217       out << V(V.GetLength() - 1);
01218     return out;
01219   }
01220 
01221 
01222 } // namespace Seldon.
01223 
01224 
01225 #define SELDON_FILE_PETSCVECTOR_CXX
01226 #endif