Warning: this documentation for the development version is under construction.
00001 // Copyright (C) 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_MATRIX_PETSCMATRIX_CXX 00022 00023 #include "PetscMatrix.hxx" 00024 00025 00026 namespace Seldon 00027 { 00028 00029 00031 00034 template <class T, class Prop, class Storage, class Allocator> 00035 inline PetscMatrix<T, Prop, Storage, Allocator>::PetscMatrix(): 00036 Matrix_Base<T, Allocator>() 00037 { 00038 mpi_communicator_ = MPI_COMM_WORLD; 00039 MatCreate(PETSC_COMM_WORLD, &petsc_matrix_); 00040 petsc_matrix_deallocated_ = false; 00041 } 00042 00043 00045 00049 template <class T, class Prop, class Storage, class Allocator> 00050 inline PetscMatrix<T, Prop, Storage, Allocator>::PetscMatrix(int i, int j): 00051 Matrix_Base<T, Allocator>(i, j) 00052 { 00053 int ierr; 00054 mpi_communicator_ = MPI_COMM_WORLD; 00055 MatCreate(mpi_communicator_, &petsc_matrix_); 00056 petsc_matrix_deallocated_ = false; 00057 } 00058 00059 00061 template <class T, class Prop, class Storage, class Allocator> 00062 inline PetscMatrix<T, Prop, Storage, Allocator> 00063 ::PetscMatrix(Mat& A): Matrix_Base<T, Allocator>() 00064 { 00065 Copy(A); 00066 } 00067 00068 00070 00073 template <class T, class Prop, class Storage, class Allocator> 00074 inline void PetscMatrix<T, Prop, Storage, Allocator> 00075 ::SetCommunicator(MPI_Comm mpi_communicator) 00076 { 00077 mpi_communicator_ = mpi_communicator; 00078 } 00079 00080 00082 00085 template <class T, class Prop, class Storage, class Allocator> 00086 inline MPI_Comm PetscMatrix<T, Prop, Storage, Allocator> 00087 ::GetCommunicator() const 00088 { 00089 return mpi_communicator_; 00090 } 00091 00092 00094 template <class T, class Prop, class Storage, class Allocator> 00095 inline PetscMatrix<T, Prop, Storage, Allocator> 00096 ::~PetscMatrix() 00097 { 00098 Clear(); 00099 } 00100 00101 00103 00107 template <class T, class Prop, class Storage, class Allocator> 00108 inline void PetscMatrix<T, Prop, Storage, Allocator> 00109 ::Clear() 00110 { 00111 if (petsc_matrix_deallocated_) 00112 return; 00113 int ierr; 00114 ierr = MatDestroy(&petsc_matrix_); 00115 CHKERRABORT(mpi_communicator_, ierr); 00116 petsc_matrix_deallocated_ = true; 00117 } 00118 00119 00121 00126 template <class T, class Prop, class Storage, class Allocator> 00127 inline void PetscMatrix<T, Prop, Storage, Allocator> 00128 ::Nullify() 00129 { 00130 throw Undefined("PetscMatrix<T, Prop, Storage, Allocator>" 00131 "::Nullify()"); 00132 } 00133 00134 00136 00139 template <class T, class Prop, class Storage, class Allocator> 00140 inline Mat& PetscMatrix<T, Prop, Storage, Allocator> 00141 ::GetPetscMatrix() 00142 { 00143 return petsc_matrix_; 00144 } 00145 00146 00148 00151 template <class T, class Prop, class Storage, class Allocator> 00152 inline const Mat& PetscMatrix<T, Prop, Storage, Allocator> 00153 ::GetPetscMatrix() const 00154 { 00155 return petsc_matrix_; 00156 } 00157 00158 00160 00167 template <class T, class Prop, class Storage, class Allocator> 00168 inline void PetscMatrix<T, Prop, Storage, Allocator> 00169 ::Resize(int i, int j) 00170 { 00171 throw Undefined("void PetscMatrix<T, Prop, Storage, Allocator>" 00172 "::Resize(int i, int j)"); 00173 } 00174 00175 00178 00192 template <class T, class Prop, class Storage, class Allocator> 00193 inline void PetscMatrix<T, Prop, Storage, Allocator> 00194 ::SetData(int i, int j, pointer data) 00195 { 00196 throw Undefined("void PetscMatrix<T, Prop, Storage, Allocator>" 00197 "::SetData(int i, int j, pointer data)"); 00198 } 00199 00200 00202 00208 template <class T, class Prop, class Storage, class Allocator> 00209 inline typename PetscMatrix<T, Prop, Storage, Allocator>::const_reference 00210 PetscMatrix<T, Prop, Storage, Allocator>::Val(int i, int j) const 00211 { 00212 throw Undefined("PetscMatrix::Val(int i, int j) const"); 00213 } 00214 00215 00217 00223 template <class T, class Prop, class Storage, class Allocator> 00224 inline typename PetscMatrix<T, Prop, Storage, Allocator>::reference 00225 PetscMatrix<T, Prop, Storage, Allocator>::Val(int i, int j) 00226 { 00227 throw Undefined("PetscMatrix::Val(int i, int j)"); 00228 } 00229 00230 00232 00237 template <class T, class Prop, class Storage, class Allocator> 00238 inline typename PetscMatrix<T, Prop, Storage, Allocator>::reference 00239 PetscMatrix<T, Prop, Storage, Allocator>::operator[] (int i) 00240 { 00241 throw Undefined("PetscMatrix::operator[] (int i)"); 00242 } 00243 00244 00246 00251 template <class T, class Prop, class Storage, class Allocator> 00252 inline typename PetscMatrix<T, Prop, Storage, Allocator>::const_reference 00253 PetscMatrix<T, Prop, Storage, Allocator>::operator[] (int i) const 00254 { 00255 throw Undefined("PetscMatrix::operator[] (int i) const"); 00256 } 00257 00258 00259 template <class T, class Prop, class Storage, class Allocator> 00260 void PetscMatrix<T, Prop, Storage, Allocator>::Set(int i, int j, T value) 00261 { 00262 throw Undefined("PetscMatrix::Set(int i, int j, T value)"); 00263 } 00264 00265 00267 00276 template <class T, class Prop, class Storage, class Allocator> 00277 void PetscMatrix<T, Prop, Storage, Allocator> 00278 ::SetBuffer(int i, int j, T value, InsertMode insert_mode = INSERT_VALUES) 00279 { 00280 int ierr; 00281 ierr = MatSetValues(petsc_matrix_, 1, &i, 1, 00282 &j, &value, insert_mode); 00283 CHKERRABORT(mpi_communicator_, ierr); 00284 } 00285 00286 00288 template <class T, class Prop, class Storage, class Allocator> 00289 void PetscMatrix<T, Prop, Storage, Allocator>::Flush() const 00290 { 00291 int ierr; 00292 ierr = MatAssemblyBegin(petsc_matrix_, MAT_FINAL_ASSEMBLY); 00293 CHKERRABORT(mpi_communicator_, ierr); 00294 ierr = MatAssemblyEnd(petsc_matrix_, MAT_FINAL_ASSEMBLY); 00295 CHKERRABORT(mpi_communicator_, ierr); 00296 } 00297 00298 00300 00308 template <class T, class Prop, class Storage, class Allocator> 00309 void PetscMatrix<T, Prop, Storage, Allocator> 00310 ::GetProcessorRowRange(int& i, int& j) const 00311 { 00312 int ierr; 00313 ierr = MatGetOwnershipRange(petsc_matrix_, &i, &j); 00314 CHKERRABORT(mpi_communicator_, ierr); 00315 } 00316 00317 00319 00324 template <class T, class Prop, class Storage, class Allocator> 00325 inline void PetscMatrix<T, Prop, Storage, Allocator> 00326 ::Copy(const Mat& A) 00327 { 00328 Clear(); 00329 int ierr; 00330 ierr = MatDuplicate(A, MAT_COPY_VALUES, &petsc_matrix_); 00331 CHKERRABORT(mpi_communicator_, ierr); 00332 MatGetSize(A, &this->m_, &this->n_); 00333 mpi_communicator_ = MPI_COMM_WORLD; 00334 petsc_matrix_deallocated_ = false; 00335 } 00336 00337 00339 00343 template <class T, class Prop, class Storage, class Allocator> 00344 void PetscMatrix<T, Prop, Storage, Allocator>::Zero() 00345 { 00346 MatScale(petsc_matrix_, T(0)); 00347 } 00348 00349 00351 template <class T, class Prop, class Storage, class Allocator> 00352 void PetscMatrix<T, Prop, Storage, Allocator>::SetIdentity() 00353 { 00354 throw Undefined("void PetscMatrix<T, Prop, Storage, Allocator>" 00355 "::SetIdentity()"); 00356 } 00357 00358 00360 00364 template <class T, class Prop, class Storage, class Allocator> 00365 void PetscMatrix<T, Prop, Storage, Allocator>::Fill() 00366 { 00367 throw Undefined("void PetscMatrix<T, Prop, Storage, Allocator>" 00368 "::Fill()"); 00369 } 00370 00371 00373 00376 template <class T, class Prop, class Storage, class Allocator> 00377 template <class T0> 00378 void PetscMatrix<T, Prop, Storage, Allocator>::Fill(const T0& x) 00379 { 00380 throw Undefined("void PetscMatrix<T, Prop, Storage, Allocator>" 00381 "::Fill(const T0& x)"); 00382 } 00383 00384 00386 00389 template <class T, class Prop, class Storage, class Allocator> 00390 void PetscMatrix<T, Prop, Storage, Allocator>::FillRand() 00391 { 00392 throw Undefined("void PetscMatrix<T, Prop, Storage, Allocator>" 00393 "::FillRand()"); 00394 } 00395 00396 00398 00409 template <class T, class Prop, class Storage, class Allocator> 00410 void PetscMatrix<T, Prop, Storage, Allocator> 00411 ::Print(int a, int b, int m, int n) const 00412 { 00413 throw Undefined("void PetscMatrix<T, Prop, Storage, Allocator>" 00414 "::Print(int a, int b, int m, int n) const"); 00415 } 00416 00417 00419 00427 template <class T, class Prop, class Storage, class Allocator> 00428 void PetscMatrix<T, Prop, Storage, Allocator>::Print(int l) const 00429 { 00430 throw Undefined("void PetscMatrix<T, Prop, Storage, Allocator>" 00431 "::Print(int l) const"); 00432 } 00433 00434 00435 /************************** 00436 * INPUT/OUTPUT FUNCTIONS * 00437 **************************/ 00438 00439 00441 00448 template <class T, class Prop, class Storage, class Allocator> 00449 void PetscMatrix<T, Prop, Storage, Allocator> 00450 ::Write(string FileName, bool with_size) const 00451 { 00452 ofstream FileStream; 00453 FileStream.open(FileName.c_str()); 00454 00455 #ifdef SELDON_CHECK_IO 00456 // Checks if the file was opened. 00457 if (!FileStream.is_open()) 00458 throw IOError("PetscMatrix::Write(string FileName)", 00459 string("Unable to open file \"") + FileName + "\"."); 00460 #endif 00461 00462 this->Write(FileStream, with_size); 00463 00464 FileStream.close(); 00465 } 00466 00467 00469 00476 template <class T, class Prop, class Storage, class Allocator> 00477 void PetscMatrix<T, Prop, Storage, Allocator> 00478 ::Write(ostream& FileStream, bool with_size) const 00479 { 00480 throw Undefined("void PetscMatrix<T, Prop, Storage, Allocator>" 00481 "::Write(ostream& FileStream, bool with_size) const"); 00482 } 00483 00484 00486 00493 template <class T, class Prop, class Storage, class Allocator> 00494 void PetscMatrix<T, Prop, Storage, Allocator> 00495 ::WriteText(string FileName) const 00496 { 00497 ofstream FileStream; 00498 FileStream.precision(cout.precision()); 00499 FileStream.flags(cout.flags()); 00500 FileStream.open(FileName.c_str()); 00501 00502 #ifdef SELDON_CHECK_IO 00503 // Checks if the file was opened. 00504 if (!FileStream.is_open()) 00505 throw IOError("PetscMatrix::WriteText(string FileName)", 00506 string("Unable to open file \"") + FileName + "\"."); 00507 #endif 00508 00509 this->WriteText(FileStream); 00510 00511 FileStream.close(); 00512 } 00513 00514 00516 00523 template <class T, class Prop, class Storage, class Allocator> 00524 void PetscMatrix<T, Prop, Storage, Allocator> 00525 ::WriteText(ostream& FileStream) const 00526 { 00527 throw Undefined("void PetscMatrix<T, Prop, Storage, Allocator>" 00528 "::WriteText(ostream& FileStream) const"); 00529 } 00530 00531 00533 00540 template <class T, class Prop, class Storage, class Allocator> 00541 void PetscMatrix<T, Prop, Storage, Allocator>::Read(string FileName) 00542 { 00543 ifstream FileStream; 00544 FileStream.open(FileName.c_str()); 00545 00546 #ifdef SELDON_CHECK_IO 00547 // Checks if the file was opened. 00548 if (!FileStream.is_open()) 00549 throw IOError("PetscMatrix::Read(string FileName)", 00550 string("Unable to open file \"") + FileName + "\"."); 00551 #endif 00552 00553 this->Read(FileStream); 00554 00555 FileStream.close(); 00556 } 00557 00558 00560 00567 template <class T, class Prop, class Storage, class Allocator> 00568 void PetscMatrix<T, Prop, Storage, Allocator> 00569 ::Read(istream& FileStream) 00570 { 00571 throw Undefined("void PetscMatrix<T, Prop, Storage, Allocator>" 00572 "::Read(istream& FileStream) const"); 00573 } 00574 00575 00577 00581 template <class T, class Prop, class Storage, class Allocator> 00582 void PetscMatrix<T, Prop, Storage, Allocator>::ReadText(string FileName) 00583 { 00584 ifstream FileStream; 00585 FileStream.open(FileName.c_str()); 00586 00587 #ifdef SELDON_CHECK_IO 00588 // Checks if the file was opened. 00589 if (!FileStream.is_open()) 00590 throw IOError("Matrix_Pointers::ReadText(string FileName)", 00591 string("Unable to open file \"") + FileName + "\"."); 00592 #endif 00593 00594 this->ReadText(FileStream); 00595 00596 FileStream.close(); 00597 } 00598 00599 00601 00605 template <class T, class Prop, class Storage, class Allocator> 00606 void PetscMatrix<T, Prop, Storage, Allocator> 00607 ::ReadText(istream& FileStream) 00608 { 00609 throw Undefined("void PetscMatrix<T, Prop, Storage, Allocator>" 00610 "::ReadText(istream& FileStream)"); 00611 } 00612 00613 00615 // Matrix<PETScSeqDense> // 00617 00618 00619 /**************** 00620 * CONSTRUCTORS * 00621 ****************/ 00622 00623 00625 00628 template <class T, class Prop, class Allocator> 00629 inline Matrix<T, Prop, PETScSeqDense, Allocator>::Matrix(): 00630 PetscMatrix<T, Prop, RowMajor, Allocator>() 00631 { 00632 } 00633 00634 00636 00640 template <class T, class Prop, class Allocator> 00641 inline Matrix<T, Prop, PETScSeqDense, Allocator>::Matrix(int i, int j): 00642 PetscMatrix<T, Prop, RowMajor, Allocator>(i, j) 00643 { 00644 MatSetType(this->petsc_matrix_, MATSEQDENSE); 00645 MatSetSizes(this->petsc_matrix_, PETSC_DECIDE, PETSC_DECIDE, i, j); 00646 } 00647 00648 00650 00653 template <class T, class Prop, class Allocator> 00654 inline Matrix<T, Prop, PETScSeqDense, Allocator>::Matrix(Mat& A): 00655 PetscMatrix<T, Prop, RowMajor, Allocator>(A) 00656 { 00657 } 00658 00659 00661 00664 template <class T, class Prop, class Allocator> 00665 inline Matrix<T, Prop, PETScSeqDense, Allocator> 00666 ::Matrix(const Matrix<T, Prop, PETScSeqDense, Allocator>& A) 00667 { 00668 this->petsc_matrix_deallocated_ = true; 00669 Copy(A); 00670 } 00671 00672 00674 00680 template <class T, class Prop, class Allocator> 00681 inline void Matrix<T, Prop, PETScSeqDense, Allocator> 00682 ::Reallocate(int i, int j) 00683 { 00684 this->Clear(); 00685 int ierr; 00686 MatCreate(MPI_COMM_SELF, &this->petsc_matrix_); 00687 MatSetSizes(this->petsc_matrix_, i, j, i, j); 00688 MatSetType(this->petsc_matrix_, MATSEQDENSE); 00689 this->petsc_matrix_deallocated_ = false; 00690 this->Flush(); 00691 } 00692 00693 00695 00701 template <class T, class Prop, class Allocator> 00702 inline typename Matrix<T, Prop, PETScSeqDense, Allocator>::value_type 00703 Matrix<T, Prop, PETScSeqDense, Allocator>::operator() (int i, int j) 00704 { 00705 #ifdef SELDON_CHECK_BOUNDS 00706 if (i < 0 || i >= this->m_) 00707 throw WrongRow("PetscMatrix<PETScSeqDense>::operator()", 00708 string("Index should be in [0, ") 00709 + to_str(this->m_-1) 00710 + "], but is equal to " + to_str(i) + "."); 00711 if (j < 0 || j >= this->n_) 00712 throw WrongCol("PetscMatrix<PETScSeqDense>::operator()", 00713 string("Index should be in [0, ") + to_str(this->n_-1) 00714 + "], but is equal to " + to_str(j) + "."); 00715 #endif 00716 PetscInt idxm[1] = {i}; 00717 PetscInt idxn[1] = {j}; 00718 PetscScalar v[1]; 00719 MatGetValues(this->petsc_matrix_, 1, idxm, 1, idxn, v); 00720 return v[0]; 00721 } 00722 00723 00725 00731 template <class T, class Prop, class Allocator> 00732 inline typename Matrix<T, Prop, PETScSeqDense, Allocator>::value_type 00733 Matrix<T, Prop, PETScSeqDense, Allocator>::operator() (int i, int j) const 00734 { 00735 #ifdef SELDON_CHECK_BOUNDS 00736 if (i < 0 || i >= this->m_) 00737 throw WrongRow("PetscMatrix<PETScSeqDense>::operator()", 00738 string("Index should be in [0, ") 00739 + to_str(this->m_-1) 00740 + "], but is equal to " + to_str(i) + "."); 00741 if (j < 0 || j >= this->n_) 00742 throw WrongCol("PetscMatrix<PETScSeqDense>::operator()", 00743 string("Index should be in [0, ") 00744 + to_str(this->n_-1) 00745 + "], but is equal to " + to_str(j) + "."); 00746 #endif 00747 PetscInt idxm[1] = {i}; 00748 PetscInt idxn[1] = {j}; 00749 PetscScalar v[1]; 00750 MatGetValues(this->petsc_matrix_, 1, idxm, 1, idxn, v); 00751 return v[0]; 00752 } 00753 00754 00756 00761 template <class T, class Prop, class Allocator> 00762 inline void Matrix<T, Prop, PETScSeqDense, Allocator> 00763 ::Copy(const Matrix<T, Prop, PETScSeqDense, Allocator>& A) 00764 { 00765 this->mpi_communicator_ = A.mpi_communicator_; 00766 PetscMatrix<T, Prop, RowMajor, Allocator>::Copy(A.GetPetscMatrix()); 00767 this->petsc_matrix_deallocated_ = false; 00768 } 00769 00770 00772 00777 template <class T, class Prop, class Allocator> 00778 inline Matrix<T, Prop, PETScSeqDense, Allocator>& 00779 Matrix<T, Prop, PETScSeqDense, Allocator> 00780 ::operator= (const Matrix<T, Prop, PETScSeqDense, Allocator>& A) 00781 { 00782 this->Copy(A); 00783 return *this; 00784 } 00785 00786 00788 00793 template <class T, class Prop, class Allocator> 00794 void Matrix<T, Prop, PETScSeqDense, Allocator>::Print() const 00795 { 00796 int ierr; 00797 ierr = MatView(this->petsc_matrix_, PETSC_VIEWER_STDOUT_SELF); 00798 CHKERRABORT(this->mpi_communicator_, ierr); 00799 } 00800 00801 00803 // Matrix<PETScMPIDense> // 00805 00806 00807 /**************** 00808 * CONSTRUCTORS * 00809 ****************/ 00810 00811 00813 00816 template <class T, class Prop, class Allocator> 00817 inline Matrix<T, Prop, PETScMPIDense, Allocator>::Matrix(): 00818 PetscMatrix<T, Prop, RowMajor, Allocator>() 00819 { 00820 } 00821 00822 00824 00828 template <class T, class Prop, class Allocator> 00829 inline Matrix<T, Prop, PETScMPIDense, Allocator>::Matrix(int i, int j): 00830 PetscMatrix<T, Prop, RowMajor, Allocator>(i, j) 00831 { 00832 MatSetType(this->petsc_matrix_, MATMPIDENSE); 00833 MatSetSizes(this->petsc_matrix_, PETSC_DECIDE, PETSC_DECIDE, i, j); 00834 } 00835 00836 00838 00841 template <class T, class Prop, class Allocator> 00842 inline Matrix<T, Prop, PETScMPIDense, Allocator>::Matrix(Mat& A): 00843 PetscMatrix<T, Prop, RowMajor, Allocator>(A) 00844 { 00845 } 00846 00847 00849 00852 template <class T, class Prop, class Allocator> 00853 inline Matrix<T, Prop, PETScMPIDense, Allocator> 00854 ::Matrix(const Matrix<T, Prop, PETScMPIDense, Allocator>& A) 00855 { 00856 this->petsc_matrix_deallocated_ = true; 00857 Copy(A); 00858 } 00859 00860 00862 00868 template <class T, class Prop, class Allocator> 00869 inline void Matrix<T, Prop, PETScMPIDense, Allocator> 00870 ::Reallocate(int i, int j, int local_i, int local_j) 00871 { 00872 this->Clear(); 00873 int ierr; 00874 MatCreate(this->mpi_communicator_, &this->petsc_matrix_); 00875 MatSetType(this->petsc_matrix_, MATMPIDENSE); 00876 MatSetSizes(this->petsc_matrix_, local_i, local_j, i, j); 00877 this->m_ = i; 00878 this->n_ = j; 00879 this->petsc_matrix_deallocated_ = false; 00880 this->Flush(); 00881 } 00882 00883 00885 00891 template <class T, class Prop, class Allocator> 00892 inline typename Matrix<T, Prop, PETScMPIDense, Allocator>::value_type 00893 Matrix<T, Prop, PETScMPIDense, Allocator>::operator() (int i, int j) 00894 { 00895 #ifdef SELDON_CHECK_BOUNDS 00896 int start, end; 00897 this->GetProcessorRowRange(start, end); 00898 if (i < start || i >= end) 00899 throw WrongRow("PetscMatrix<PETScMPIDense>::operator()", 00900 string("Index should be in [") 00901 + to_str(start) 00902 + ", " + to_str(end - 1) 00903 + "], but is equal to " 00904 + to_str(i) + "."); 00905 if (j < 0 || j >= this->n_) 00906 throw WrongCol("PetscMatrix<PETScMPIDense>::operator()", 00907 string("Index should be in [0, ") + to_str(this->n_-1) 00908 + "], but is equal to " + to_str(j) + "."); 00909 #endif 00910 PetscInt idxm[1] = {i}; 00911 PetscInt idxn[1] = {j}; 00912 PetscScalar v[1]; 00913 MatGetValues(this->petsc_matrix_, 1, idxm, 1, idxn, v); 00914 return v[0]; 00915 } 00916 00917 00919 00925 template <class T, class Prop, class Allocator> 00926 inline typename Matrix<T, Prop, PETScMPIDense, Allocator>::value_type 00927 Matrix<T, Prop, PETScMPIDense, Allocator>::operator() (int i, int j) const 00928 { 00929 #ifdef SELDON_CHECK_BOUNDS 00930 int start, end; 00931 this->GetProcessorRowRange(start, end); 00932 if (i < start || i >= end) 00933 throw WrongRow("PetscMatrix<PETScMPIDense>::operator()", 00934 string("Index should be in [") 00935 + to_str(start) 00936 + ", " + to_str(end - 1) + "], but is equal to " 00937 + to_str(i) + "."); 00938 if (j < 0 || j >= this->n_) 00939 throw WrongCol("PetscMatrix<PETScMPIDense>::operator()", 00940 string("Index should be in [0, ") 00941 + to_str(this->n_-1) 00942 + "], but is equal to " + to_str(j) + "."); 00943 #endif 00944 PetscInt idxm[1] = {i}; 00945 PetscInt idxn[1] = {j}; 00946 PetscScalar v[1]; 00947 MatGetValues(this->petsc_matrix_, 1, idxm, 1, idxn, v); 00948 return v[0]; 00949 } 00950 00951 00953 00958 template <class T, class Prop, class Allocator> 00959 inline void Matrix<T, Prop, PETScMPIDense, Allocator> 00960 ::Copy(const Matrix<T, Prop, PETScMPIDense, Allocator>& A) 00961 { 00962 this->mpi_communicator_ = A.mpi_communicator_; 00963 PetscMatrix<T, Prop, RowMajor, Allocator>::Copy(A.GetPetscMatrix()); 00964 this->petsc_matrix_deallocated_ = false; 00965 } 00966 00967 00969 00974 template <class T, class Prop, class Allocator> 00975 inline Matrix<T, Prop, PETScMPIDense, Allocator>& 00976 Matrix<T, Prop, PETScMPIDense, Allocator> 00977 ::operator= (const Matrix<T, Prop, PETScMPIDense, Allocator>& A) 00978 { 00979 this->Copy(A); 00980 return *this; 00981 } 00982 00983 00985 00990 template <class T, class Prop, class Allocator> 00991 void Matrix<T, Prop, PETScMPIDense, Allocator>::Print() const 00992 { 00993 int ierr; 00994 ierr = MatView(this->petsc_matrix_, PETSC_VIEWER_STDOUT_WORLD); 00995 CHKERRABORT(this->mpi_communicator_, ierr); 00996 } 00997 00998 01000 // Matrix<PETScMPIAIJ> // 01002 01003 01004 /**************** 01005 * CONSTRUCTORS * 01006 ****************/ 01007 01008 01010 01013 template <class T, class Prop, class Allocator> 01014 inline Matrix<T, Prop, PETScMPIAIJ, Allocator>::Matrix(): 01015 PetscMatrix<T, Prop, RowMajor, Allocator>() 01016 { 01017 } 01018 01019 01021 01025 template <class T, class Prop, class Allocator> 01026 inline Matrix<T, Prop, PETScMPIAIJ, Allocator>::Matrix(int i, int j): 01027 PetscMatrix<T, Prop, RowMajor, Allocator>(i, j) 01028 { 01029 MatSetType(this->petsc_matrix_, MATMPIAIJ); 01030 MatSetSizes(this->petsc_matrix_, PETSC_DECIDE, PETSC_DECIDE, i, j); 01031 } 01032 01033 01035 01038 template <class T, class Prop, class Allocator> 01039 inline Matrix<T, Prop, PETScMPIAIJ, Allocator>::Matrix(Mat& A): 01040 PetscMatrix<T, Prop, RowMajor, Allocator>(A) 01041 { 01042 } 01043 01044 01046 01049 template <class T, class Prop, class Allocator> 01050 inline Matrix<T, Prop, PETScMPIAIJ, Allocator> 01051 ::Matrix(const Matrix<T, Prop, PETScMPIAIJ, Allocator>& A) 01052 { 01053 this->petsc_matrix_deallocated_ = true; 01054 Copy(A); 01055 } 01056 01057 01059 01065 template <class T, class Prop, class Allocator> 01066 inline void Matrix<T, Prop, PETScMPIAIJ, Allocator> 01067 ::Reallocate(int i, int j, int local_i, int local_j) 01068 { 01069 this->Clear(); 01070 int ierr; 01071 MatCreate(this->mpi_communicator_, &this->petsc_matrix_); 01072 MatSetType(this->petsc_matrix_, MATMPIAIJ); 01073 MatSetSizes(this->petsc_matrix_, local_i, local_j, i, j); 01074 this->m_ = i; 01075 this->n_ = j; 01076 this->petsc_matrix_deallocated_ = false; 01077 this->Flush(); 01078 } 01079 01080 01082 01088 template <class T, class Prop, class Allocator> 01089 inline typename Matrix<T, Prop, PETScMPIAIJ, Allocator>::value_type 01090 Matrix<T, Prop, PETScMPIAIJ, Allocator>::operator() (int i, int j) 01091 { 01092 #ifdef SELDON_CHECK_BOUNDS 01093 int start, end; 01094 this->GetProcessorRowRange(start, end); 01095 if (i < start || i >= end) 01096 throw WrongRow("PetscMatrix<PETScMPIAIJ>::operator()", 01097 string("Index should be in [") 01098 + to_str(start) 01099 + ", " + to_str(end - 1) 01100 + "], but is equal to " 01101 + to_str(i) + "."); 01102 if (j < 0 || j >= this->n_) 01103 throw WrongCol("PetscMatrix<PETScMPIAIJ>::operator()", 01104 string("Index should be in [0, ") + to_str(this->n_-1) 01105 + "], but is equal to " + to_str(j) + "."); 01106 #endif 01107 PetscInt idxm[1] = {i}; 01108 PetscInt idxn[1] = {j}; 01109 PetscScalar v[1]; 01110 MatGetValues(this->petsc_matrix_, 1, idxm, 1, idxn, v); 01111 return v[0]; 01112 } 01113 01114 01116 01122 template <class T, class Prop, class Allocator> 01123 inline typename Matrix<T, Prop, PETScMPIAIJ, Allocator>::value_type 01124 Matrix<T, Prop, PETScMPIAIJ, Allocator>::operator() (int i, int j) const 01125 { 01126 #ifdef SELDON_CHECK_BOUNDS 01127 int start, end; 01128 this->GetProcessorRowRange(start, end); 01129 if (i < start || i >= end) 01130 throw WrongRow("PetscMatrix<PETScMPIAIJ>::operator()", 01131 string("Index should be in [") 01132 + to_str(start) 01133 + ", " + to_str(end - 1) + "], but is equal to " 01134 + to_str(i) + "."); 01135 if (j < 0 || j >= this->n_) 01136 throw WrongCol("PetscMatrix<PETScMPIAIJ>::operator()", 01137 string("Index should be in [0, ") 01138 + to_str(this->n_-1) 01139 + "], but is equal to " + to_str(j) + "."); 01140 #endif 01141 PetscInt idxm[1] = {i}; 01142 PetscInt idxn[1] = {j}; 01143 PetscScalar v[1]; 01144 MatGetValues(this->petsc_matrix_, 1, idxm, 1, idxn, v); 01145 return v[0]; 01146 } 01147 01148 01150 01155 template <class T, class Prop, class Allocator> 01156 inline void Matrix<T, Prop, PETScMPIAIJ, Allocator> 01157 ::Copy(const Matrix<T, Prop, PETScMPIAIJ, Allocator>& A) 01158 { 01159 this->mpi_communicator_ = A.mpi_communicator_; 01160 PetscMatrix<T, Prop, RowMajor, Allocator>::Copy(A.GetPetscMatrix()); 01161 this->petsc_matrix_deallocated_ = false; 01162 } 01163 01164 01166 01171 template <class T, class Prop, class Allocator> 01172 inline Matrix<T, Prop, PETScMPIAIJ, Allocator>& 01173 Matrix<T, Prop, PETScMPIAIJ, Allocator> 01174 ::operator= (const Matrix<T, Prop, PETScMPIAIJ, Allocator>& A) 01175 { 01176 this->Copy(A); 01177 return *this; 01178 } 01179 01180 01182 01187 template <class T, class Prop, class Allocator> 01188 template <class T0, class Allocator0> 01189 inline void Matrix<T, Prop, PETScMPIAIJ, Allocator> 01190 ::Copy(const Matrix<T0, General, RowSparse, Allocator0>& A) 01191 { 01192 this->Clear(); 01193 01194 int ierr; 01195 ierr = MatCreate(this->mpi_communicator_, &this->petsc_matrix_); 01196 CHKERRABORT(this->mpi_communicator_, ierr); 01197 01198 int ma = A.GetM(); 01199 int na = A.GetN(); 01200 int nnz = A.GetDataSize(); 01201 double *value = A.GetData(); 01202 int *column = A.GetInd(); 01203 int *ptr = A.GetPtr(); 01204 01205 this->m_ = ma; 01206 this->n_ = na; 01207 01208 ierr = MatSetType(this->petsc_matrix_, MATMPIAIJ); 01209 CHKERRABORT(this->mpi_communicator_, ierr); 01210 ierr = MatSetSizes(this->petsc_matrix_, PETSC_DECIDE, PETSC_DECIDE, 01211 this->m_, this->n_); 01212 CHKERRABORT(this->mpi_communicator_, ierr); 01213 int loc_start, loc_end; 01214 ierr = MatGetOwnershipRange(this->petsc_matrix_, 01215 &loc_start, &loc_end); 01216 CHKERRABORT(this->mpi_communicator_, ierr); 01217 for (int i = loc_start; i < loc_end; i++) 01218 for (int j = ptr[i]; j < ptr[i + 1]; j++) 01219 ierr = MatSetValues(this->petsc_matrix_, 1, &i, 1, &column[j], 01220 &value[j], INSERT_VALUES); 01221 ierr = MatAssemblyBegin(this->petsc_matrix_,MAT_FINAL_ASSEMBLY); 01222 CHKERRABORT(this->mpi_communicator_, ierr); 01223 ierr = MatAssemblyEnd(this->petsc_matrix_,MAT_FINAL_ASSEMBLY); 01224 CHKERRABORT(this->mpi_communicator_, ierr); 01225 } 01226 01227 01229 01232 template <class T, class Prop, class Allocator> 01233 int Matrix<T, Prop, PETScMPIAIJ, Allocator>::GetLocalM() const 01234 { 01235 int ierr; 01236 int m; 01237 ierr = MatGetLocalSize(this->petsc_matrix_, &m, PETSC_NULL); 01238 CHKERRABORT(this->mpi_communicator_, ierr); 01239 return m; 01240 } 01241 01242 01244 01247 template <class T, class Prop, class Allocator> 01248 int Matrix<T, Prop, PETScMPIAIJ, Allocator>::GetLocalN() const 01249 { 01250 int ierr; 01251 int n; 01252 ierr = MatGetLocalSize(this->petsc_matrix_, PETSC_NULL, &n); 01253 CHKERRABORT(this->mpi_communicator_, ierr); 01254 return n; 01255 } 01256 01257 01259 01264 template <class T, class Prop, class Allocator> 01265 void Matrix<T, Prop, PETScMPIAIJ, Allocator>::Print() const 01266 { 01267 int ierr; 01268 ierr = MatView(this->petsc_matrix_, PETSC_VIEWER_STDOUT_WORLD); 01269 CHKERRABORT(this->mpi_communicator_, ierr); 01270 } 01271 01272 01273 } 01274 01275 01276 #define SELDON_FILE_MATRIX_PETSCMATRIX_CXX 01277 #endif