00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #ifndef IFPACK_ADDITIVESCHWARZ_H
00045 #define IFPACK_ADDITIVESCHWARZ_H
00046
00047 #include "Ifpack_ConfigDefs.h"
00048 #include "Ifpack_Preconditioner.h"
00049 #include "Ifpack_ConfigDefs.h"
00050 #include "Ifpack_Preconditioner.h"
00051 #include "Ifpack_Reordering.h"
00052 #include "Ifpack_RCMReordering.h"
00053 #include "Ifpack_METISReordering.h"
00054 #include "Ifpack_LocalFilter.h"
00055 #include "Ifpack_NodeFilter.h"
00056 #include "Ifpack_SingletonFilter.h"
00057 #include "Ifpack_ReorderFilter.h"
00058 #include "Ifpack_Utils.h"
00059 #include "Ifpack_OverlappingRowMatrix.h"
00060 #include "Epetra_CombineMode.h"
00061 #include "Epetra_MultiVector.h"
00062 #include "Epetra_Map.h"
00063 #include "Epetra_Comm.h"
00064 #include "Epetra_Time.h"
00065 #include "Epetra_LinearProblem.h"
00066 #include "Epetra_RowMatrix.h"
00067 #include "Epetra_CrsMatrix.h"
00068 #include "Teuchos_ParameterList.hpp"
00069 #include "Teuchos_RefCountPtr.hpp"
00070
00071 #ifdef HAVE_IFPACK_PARALLEL_SUBDOMAIN_SOLVERS
00072 #include "Ifpack_SubdomainFilter.h"
00073 #include "EpetraExt_Reindex_CrsMatrix.h"
00074 #include "EpetraExt_Reindex_MultiVector.h"
00075 #endif
00076 #ifdef IFPACK_NODE_AWARE_CODE
00077 #include "EpetraExt_OperatorOut.h"
00078 #include "EpetraExt_RowMatrixOut.h"
00079 #include "EpetraExt_BlockMapOut.h"
00080 #endif
00081
00082 #ifdef HAVE_IFPACK_AMESOS
00083 #include "Ifpack_AMDReordering.h"
00084 #endif
00085
00086
00088
00141 template<typename T>
00142 class Ifpack_AdditiveSchwarz : public virtual Ifpack_Preconditioner {
00143
00144 public:
00145
00147
00148
00159 Ifpack_AdditiveSchwarz(Epetra_RowMatrix* Matrix_in,
00160 int OverlapLevel_in = 0);
00161
00163 virtual ~Ifpack_AdditiveSchwarz() {};
00165
00167
00169
00178 virtual int SetUseTranspose(bool UseTranspose_in);
00180
00182
00184
00194 virtual int Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const;
00195
00197
00208 virtual int ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const;
00209
00211 virtual double NormInf() const;
00213
00215
00217 virtual const char * Label() const;
00218
00220 virtual bool UseTranspose() const;
00221
00223 virtual bool HasNormInf() const;
00224
00226 virtual const Epetra_Comm & Comm() const;
00227
00229 virtual const Epetra_Map & OperatorDomainMap() const;
00230
00232 virtual const Epetra_Map & OperatorRangeMap() const;
00234
00236 virtual bool IsInitialized() const
00237 {
00238 return(IsInitialized_);
00239 }
00240
00242 virtual bool IsComputed() const
00243 {
00244 return(IsComputed_);
00245 }
00246
00248
00267 virtual int SetParameters(Teuchos::ParameterList& List);
00268
00269
00270
00271
00272
00274 virtual int Initialize();
00275
00277 virtual int Compute();
00278
00280 virtual double Condest(const Ifpack_CondestType CT = Ifpack_Cheap,
00281 const int MaxIters = 1550,
00282 const double Tol = 1e-9,
00283 Epetra_RowMatrix* Matrix_in = 0);
00284
00286 virtual double Condest() const
00287 {
00288 return(Condest_);
00289 }
00290
00292 virtual const Epetra_RowMatrix& Matrix() const
00293 {
00294 return(*Matrix_);
00295 }
00296
00298 virtual bool IsOverlapping() const
00299 {
00300 return(IsOverlapping_);
00301 }
00302
00304 virtual std::ostream& Print(std::ostream&) const;
00305
00306 virtual const T* Inverse() const
00307 {
00308 return(&*Inverse_);
00309 }
00310
00312 virtual int NumInitialize() const
00313 {
00314 return(NumInitialize_);
00315 }
00316
00318 virtual int NumCompute() const
00319 {
00320 return(NumCompute_);
00321 }
00322
00324 virtual int NumApplyInverse() const
00325 {
00326 return(NumApplyInverse_);
00327 }
00328
00330 virtual double InitializeTime() const
00331 {
00332 return(InitializeTime_);
00333 }
00334
00336 virtual double ComputeTime() const
00337 {
00338 return(ComputeTime_);
00339 }
00340
00342 virtual double ApplyInverseTime() const
00343 {
00344 return(ApplyInverseTime_);
00345 }
00346
00348 virtual double InitializeFlops() const
00349 {
00350 return(InitializeFlops_);
00351 }
00352
00353 virtual double ComputeFlops() const
00354 {
00355 return(ComputeFlops_);
00356 }
00357
00358 virtual double ApplyInverseFlops() const
00359 {
00360 return(ApplyInverseFlops_);
00361 }
00362
00364 virtual int OverlapLevel() const
00365 {
00366 return(OverlapLevel_);
00367 }
00368
00370 virtual const Teuchos::ParameterList& List() const
00371 {
00372 return(List_);
00373 }
00374
00375 protected:
00376
00377
00378
00379
00380
00382 Ifpack_AdditiveSchwarz(const Ifpack_AdditiveSchwarz& RHS)
00383 { }
00384
00386 int Setup();
00387
00388
00389
00390
00391
00393 Teuchos::RefCountPtr<const Epetra_RowMatrix> Matrix_;
00395 Teuchos::RefCountPtr<Ifpack_OverlappingRowMatrix> OverlappingMatrix_;
00397
00398
00399
00400
00401
00402 #ifdef HAVE_IFPACK_PARALLEL_SUBDOMAIN_SOLVERS
00403
00404 Teuchos::RCP<Epetra_RowMatrix> LocalizedMatrix_;
00406 Teuchos::RCP<Epetra_CrsMatrix> SubdomainCrsMatrix_;
00408 Teuchos::RCP<Epetra_CrsMatrix> ReindexedCrsMatrix_;
00409
00410
00411
00412 Teuchos::RCP<Epetra_Map> tempMap_;
00413 Teuchos::RCP<Epetra_Map> tempDomainMap_;
00414 Teuchos::RCP<Epetra_Map> tempRangeMap_;
00415 Teuchos::RCP<EpetraExt::CrsMatrix_Reindex> SubdomainMatrixReindexer_;
00416 Teuchos::RCP<EpetraExt::MultiVector_Reindex> DomainVectorReindexer_;
00417 Teuchos::RCP<EpetraExt::MultiVector_Reindex> RangeVectorReindexer_;
00418 mutable Teuchos::RCP<Epetra_MultiVector> tempX_;
00419 mutable Teuchos::RCP<Epetra_MultiVector> tempY_;
00420 #else
00421 # ifdef IFPACK_NODE_AWARE_CODE
00422 Teuchos::RefCountPtr<Ifpack_NodeFilter> LocalizedMatrix_;
00423 # else
00424 Teuchos::RefCountPtr<Ifpack_LocalFilter> LocalizedMatrix_;
00425 # endif
00426 #endif
00427 #ifdef HAVE_IFPACK_PARALLEL_SUBDOMAIN_SOLVERS
00428
00430 int MpiRank_;
00432 int NumMpiProcs_;
00434 int NumMpiProcsPerSubdomain_;
00436 int NumSubdomains_;
00438 int SubdomainId_;
00439 #endif
00440
00441 string Label_;
00443 bool IsInitialized_;
00445 bool IsComputed_;
00447 bool UseTranspose_;
00449 bool IsOverlapping_;
00451 int OverlapLevel_;
00453 Teuchos::ParameterList List_;
00455 Epetra_CombineMode CombineMode_;
00457 double Condest_;
00459 bool ComputeCondest_;
00461 bool UseReordering_;
00463 string ReorderingType_;
00465 Teuchos::RefCountPtr<Ifpack_Reordering> Reordering_;
00467 Teuchos::RefCountPtr<Ifpack_ReorderFilter> ReorderedLocalizedMatrix_;
00469 bool FilterSingletons_;
00471 Teuchos::RefCountPtr<Ifpack_SingletonFilter> SingletonFilter_;
00473 int NumInitialize_;
00475 int NumCompute_;
00477 mutable int NumApplyInverse_;
00479 double InitializeTime_;
00481 double ComputeTime_;
00483 mutable double ApplyInverseTime_;
00485 double InitializeFlops_;
00487 double ComputeFlops_;
00489 mutable double ApplyInverseFlops_;
00491 Teuchos::RefCountPtr<Epetra_Time> Time_;
00493 Teuchos::RefCountPtr<T> Inverse_;
00495 #ifdef HAVE_IFPACK_PARALLEL_SUBDOMAIN_SOLVERS
00496 mutable Teuchos::RefCountPtr<Epetra_MultiVector> OverlappingX;
00497 mutable Teuchos::RefCountPtr<Epetra_MultiVector> OverlappingY;
00498 #endif
00499 # ifdef IFPACK_NODE_AWARE_CODE
00500 mutable Teuchos::RefCountPtr<Epetra_MultiVector> OverlappingX;
00501 mutable Teuchos::RefCountPtr<Epetra_MultiVector> OverlappingY;
00502 #endif
00503
00504 };
00505
00506
00507 template<typename T>
00508 Ifpack_AdditiveSchwarz<T>::
00509 Ifpack_AdditiveSchwarz(Epetra_RowMatrix* Matrix_in,
00510 int OverlapLevel_in) :
00511 #ifdef HAVE_IFPACK_PARALLEL_SUBDOMAIN_SOLVERS
00512 MpiRank_(0),
00513 NumMpiProcs_(1),
00514 NumMpiProcsPerSubdomain_(1),
00515 NumSubdomains_(1),
00516 SubdomainId_(0),
00517 #endif
00518 IsInitialized_(false),
00519 IsComputed_(false),
00520 UseTranspose_(false),
00521 IsOverlapping_(false),
00522 OverlapLevel_(OverlapLevel_in),
00523 CombineMode_(Zero),
00524 Condest_(-1.0),
00525 ComputeCondest_(true),
00526 UseReordering_(false),
00527 ReorderingType_("none"),
00528 FilterSingletons_(false),
00529 NumInitialize_(0),
00530 NumCompute_(0),
00531 NumApplyInverse_(0),
00532 InitializeTime_(0.0),
00533 ComputeTime_(0.0),
00534 ApplyInverseTime_(0.0),
00535 InitializeFlops_(0.0),
00536 ComputeFlops_(0.0),
00537 ApplyInverseFlops_(0.0)
00538 {
00539
00540 Matrix_ = Teuchos::rcp( Matrix_in, false );
00541
00542 if (Matrix_->Comm().NumProc() == 1)
00543 OverlapLevel_ = 0;
00544
00545 if ((OverlapLevel_ != 0) && (Matrix_->Comm().NumProc() > 1))
00546 IsOverlapping_ = true;
00547
00548 Teuchos::ParameterList List_in;
00549 SetParameters(List_in);
00550 }
00551
00552 #ifdef IFPACK_NODE_AWARE_CODE
00553 extern int ML_NODE_ID;
00554 #endif
00555
00556
00557 template<typename T>
00558 int Ifpack_AdditiveSchwarz<T>::Setup()
00559 {
00560
00561 Epetra_RowMatrix* MatrixPtr;
00562
00563 #ifndef HAVE_IFPACK_PARALLEL_SUBDOMAIN_SOLVERS
00564 # ifdef IFPACK_NODE_AWARE_CODE
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 int nodeID;
00582 try{ nodeID = List_.get("ML node id",0);}
00583 catch(...){fprintf(stderr,"%s","Ifpack_AdditiveSchwarz<T>::Setup(): no parameter \"ML node id\"\n\n");
00584 cout << List_ << endl;}
00585 # endif
00586 #endif
00587
00588 try{
00589 if (OverlappingMatrix_ != Teuchos::null)
00590 {
00591 #ifdef HAVE_IFPACK_PARALLEL_SUBDOMAIN_SOLVERS
00592 if (NumMpiProcsPerSubdomain_ > 1) {
00593 LocalizedMatrix_ = Teuchos::rcp(new Ifpack_SubdomainFilter(OverlappingMatrix_, SubdomainId_));
00594 } else {
00595 LocalizedMatrix_ = Teuchos::rcp(new Ifpack_LocalFilter(OverlappingMatrix_));
00596 }
00597 #else
00598 # ifdef IFPACK_NODE_AWARE_CODE
00599 Ifpack_NodeFilter *tt = new Ifpack_NodeFilter(OverlappingMatrix_,nodeID);
00600 LocalizedMatrix_ = Teuchos::rcp(tt);
00601
00602 # else
00603 LocalizedMatrix_ = Teuchos::rcp( new Ifpack_LocalFilter(OverlappingMatrix_) );
00604 # endif
00605 #endif
00606 }
00607 else
00608 {
00609 #ifdef HAVE_IFPACK_PARALLEL_SUBDOMAIN_SOLVERS
00610
00611 if (NumMpiProcsPerSubdomain_ > 1) {
00612 LocalizedMatrix_ = Teuchos::rcp(new Ifpack_SubdomainFilter(Matrix_, SubdomainId_));
00613 } else {
00614 LocalizedMatrix_ = Teuchos::rcp(new Ifpack_LocalFilter(Matrix_));
00615 }
00616 #else
00617 # ifdef IFPACK_NODE_AWARE_CODE
00618 Ifpack_NodeFilter *tt = new Ifpack_NodeFilter(Matrix_,nodeID);
00619 LocalizedMatrix_ = Teuchos::rcp(tt);
00620
00621 # else
00622 LocalizedMatrix_ = Teuchos::rcp( new Ifpack_LocalFilter(Matrix_) );
00623 # endif
00624 #endif
00625 }
00626 }
00627 catch(...) {
00628 fprintf(stderr,"%s","AdditiveSchwarz Setup: problem creating local filter matrix.\n");
00629 }
00630
00631 if (LocalizedMatrix_ == Teuchos::null)
00632 IFPACK_CHK_ERR(-5);
00633
00634
00635 if (FilterSingletons_) {
00636 SingletonFilter_ = Teuchos::rcp( new Ifpack_SingletonFilter(LocalizedMatrix_) );
00637 MatrixPtr = &*SingletonFilter_;
00638 }
00639 else
00640 MatrixPtr = &*LocalizedMatrix_;
00641
00642 if (UseReordering_) {
00643
00644
00645 if (ReorderingType_ == "rcm")
00646 Reordering_ = Teuchos::rcp( new Ifpack_RCMReordering() );
00647 else if (ReorderingType_ == "metis")
00648 Reordering_ = Teuchos::rcp( new Ifpack_METISReordering() );
00649 #ifdef HAVE_IFPACK_AMESOS
00650 else if (ReorderingType_ == "amd" )
00651 Reordering_ = Teuchos::rcp( new Ifpack_AMDReordering() );
00652 #endif
00653 else {
00654 cerr << "reordering type not correct (" << ReorderingType_ << ")" << endl;
00655 exit(EXIT_FAILURE);
00656 }
00657 if (Reordering_ == Teuchos::null) IFPACK_CHK_ERR(-5);
00658
00659 IFPACK_CHK_ERR(Reordering_->SetParameters(List_));
00660 IFPACK_CHK_ERR(Reordering_->Compute(*MatrixPtr));
00661
00662
00663 ReorderedLocalizedMatrix_ =
00664 Teuchos::rcp( new Ifpack_ReorderFilter(Teuchos::rcp( MatrixPtr, false ), Reordering_) );
00665
00666 if (ReorderedLocalizedMatrix_ == Teuchos::null) IFPACK_CHK_ERR(-5);
00667
00668 MatrixPtr = &*ReorderedLocalizedMatrix_;
00669 }
00670
00671 #ifdef HAVE_IFPACK_PARALLEL_SUBDOMAIN_SOLVERS
00672
00673
00674
00675
00676
00677 SubdomainCrsMatrix_.reset(new Epetra_CrsMatrix(Copy, MatrixPtr->RowMatrixRowMap(), -1));
00678 Teuchos::RCP<Epetra_Import> tempImporter = Teuchos::rcp(new Epetra_Import(SubdomainCrsMatrix_->Map(), MatrixPtr->Map()));
00679 SubdomainCrsMatrix_->Import(*MatrixPtr, *tempImporter, Insert);
00680 SubdomainCrsMatrix_->FillComplete();
00681
00682 if (NumMpiProcsPerSubdomain_ > 1) {
00683 tempMap_.reset(new Epetra_Map(SubdomainCrsMatrix_->RowMap().NumGlobalElements(),
00684 SubdomainCrsMatrix_->RowMap().NumMyElements(),
00685 0, SubdomainCrsMatrix_->Comm()));
00686 tempRangeMap_.reset(new Epetra_Map(SubdomainCrsMatrix_->OperatorRangeMap().NumGlobalElements(),
00687 SubdomainCrsMatrix_->OperatorRangeMap().NumMyElements(),
00688 0, SubdomainCrsMatrix_->Comm()));
00689 tempDomainMap_.reset(new Epetra_Map(SubdomainCrsMatrix_->OperatorDomainMap().NumGlobalElements(),
00690 SubdomainCrsMatrix_->OperatorDomainMap().NumMyElements(),
00691 0, SubdomainCrsMatrix_->Comm()));
00692
00693 SubdomainMatrixReindexer_.reset(new EpetraExt::CrsMatrix_Reindex(*tempMap_));
00694 DomainVectorReindexer_.reset(new EpetraExt::MultiVector_Reindex(*tempDomainMap_));
00695 RangeVectorReindexer_.reset(new EpetraExt::MultiVector_Reindex(*tempRangeMap_));
00696
00697 ReindexedCrsMatrix_.reset(&((*SubdomainMatrixReindexer_)(*SubdomainCrsMatrix_)), false);
00698
00699 MatrixPtr = &*ReindexedCrsMatrix_;
00700
00701 Inverse_ = Teuchos::rcp( new T(&*ReindexedCrsMatrix_) );
00702 } else {
00703 Inverse_ = Teuchos::rcp( new T(&*SubdomainCrsMatrix_) );
00704 }
00705 #else
00706 Inverse_ = Teuchos::rcp( new T(MatrixPtr) );
00707 #endif
00708
00709 if (Inverse_ == Teuchos::null)
00710 IFPACK_CHK_ERR(-5);
00711
00712 return(0);
00713 }
00714
00715
00716 template<typename T>
00717 int Ifpack_AdditiveSchwarz<T>::SetParameters(Teuchos::ParameterList& List_in)
00718 {
00719 #ifdef HAVE_IFPACK_PARALLEL_SUBDOMAIN_SOLVERS
00720 MpiRank_ = Matrix_->Comm().MyPID();
00721 NumMpiProcs_ = Matrix_->Comm().NumProc();
00722 NumMpiProcsPerSubdomain_ = List_in.get("subdomain: number-of-processors", 1);
00723 NumSubdomains_ = NumMpiProcs_ / NumMpiProcsPerSubdomain_;
00724 SubdomainId_ = MpiRank_ / NumMpiProcsPerSubdomain_;
00725
00726 if (NumSubdomains_ == 1) {
00727 IsOverlapping_ = false;
00728 }
00729
00730 #endif
00731
00732 ComputeCondest_ = List_in.get("schwarz: compute condest", ComputeCondest_);
00733
00734 if( Teuchos::ParameterEntry *combineModeEntry = List_in.getEntryPtr("schwarz: combine mode") )
00735 {
00736 if( typeid(std::string) == combineModeEntry->getAny().type() )
00737 {
00738 std::string mode = List_in.get("schwarz: combine mode", "Add");
00739 if (mode == "Add")
00740 CombineMode_ = Add;
00741 else if (mode == "Zero")
00742 CombineMode_ = Zero;
00743 else if (mode == "Insert")
00744 CombineMode_ = Insert;
00745 else if (mode == "InsertAdd")
00746 CombineMode_ = InsertAdd;
00747 else if (mode == "Average")
00748 CombineMode_ = Average;
00749 else if (mode == "AbsMax")
00750 CombineMode_ = AbsMax;
00751 else
00752 {
00753 TEUCHOS_TEST_FOR_EXCEPTION(
00754 true,std::logic_error
00755 ,"Error, The (Epetra) combine mode of \""<<mode<<"\" is not valid! Only the values"
00756 " \"Add\", \"Zero\", \"Insert\", \"InsertAdd\", \"Average\", and \"AbsMax\" are accepted!"
00757 );
00758 }
00759 }
00760 else if ( typeid(Epetra_CombineMode) == combineModeEntry->getAny().type() )
00761 {
00762 CombineMode_ = Teuchos::any_cast<Epetra_CombineMode>(combineModeEntry->getAny());
00763 }
00764 else
00765 {
00766
00767 Teuchos::getParameter<std::string>(List_in,"schwarz: combine mode");
00768 }
00769 }
00770 else
00771 {
00772
00773 List_in.get("schwarz: combine mode","Zero");
00774 }
00775
00776 ReorderingType_ = List_in.get("schwarz: reordering type", ReorderingType_);
00777 if (ReorderingType_ == "none")
00778 UseReordering_ = false;
00779 else
00780 UseReordering_ = true;
00781
00782
00783
00784
00785 FilterSingletons_ = List_in.get("schwarz: filter singletons", FilterSingletons_);
00786
00787
00788 List_ = List_in;
00789
00790 return(0);
00791 }
00792
00793
00794 template<typename T>
00795 int Ifpack_AdditiveSchwarz<T>::Initialize()
00796 {
00797 IsInitialized_ = false;
00798 IsComputed_ = false;
00799 Condest_ = -1.0;
00800
00801 if (Time_ == Teuchos::null)
00802 Time_ = Teuchos::rcp( new Epetra_Time(Comm()) );
00803
00804 Time_->ResetStartTime();
00805
00806
00807 if (IsOverlapping_) {
00808 #ifdef HAVE_IFPACK_PARALLEL_SUBDOMAIN_SOLVERS
00809 if (NumMpiProcsPerSubdomain_ > 1) {
00810 OverlappingMatrix_ = Teuchos::rcp( new Ifpack_OverlappingRowMatrix(Matrix_, OverlapLevel_, SubdomainId_) );
00811 } else {
00812 OverlappingMatrix_ = Teuchos::rcp( new Ifpack_OverlappingRowMatrix(Matrix_, OverlapLevel_));
00813 }
00814 #else
00815 # ifdef IFPACK_NODE_AWARE_CODE
00816 int myNodeID;
00817 try{ myNodeID = List_.get("ML node id",-1);}
00818 catch(...){fprintf(stderr,"pid %d: no such entry (returned %d)\n",Comm().MyPID(),myNodeID);}
00819
00820
00821
00822
00823
00824 OverlappingMatrix_ = Teuchos::rcp( new Ifpack_OverlappingRowMatrix(Matrix_, OverlapLevel_, myNodeID) );
00825 # else
00826 OverlappingMatrix_ = Teuchos::rcp( new Ifpack_OverlappingRowMatrix(Matrix_, OverlapLevel_) );
00827 # endif
00828 #endif
00829
00830 if (OverlappingMatrix_ == Teuchos::null) {
00831 IFPACK_CHK_ERR(-5);
00832 }
00833 }
00834
00835 # ifdef IFPACK_NODE_AWARE_CODE
00836
00837
00838
00839
00840 # endif
00841
00842 IFPACK_CHK_ERR(Setup());
00843
00844 # ifdef IFPACK_NODE_AWARE_CODE
00845
00846
00847
00848
00849 #endif
00850
00851 if (Inverse_ == Teuchos::null)
00852 IFPACK_CHK_ERR(-5);
00853
00854 if (LocalizedMatrix_ == Teuchos::null)
00855 IFPACK_CHK_ERR(-5);
00856
00857 IFPACK_CHK_ERR(Inverse_->SetUseTranspose(UseTranspose()));
00858 IFPACK_CHK_ERR(Inverse_->SetParameters(List_));
00859 IFPACK_CHK_ERR(Inverse_->Initialize());
00860
00861
00862 Label_ = "Ifpack_AdditiveSchwarz, ";
00863 if (UseTranspose())
00864 Label_ += ", transp";
00865 Label_ += ", ov = " + Ifpack_toString(OverlapLevel_)
00866 + ", local solver = \n\t\t***** `" + string(Inverse_->Label()) + "'";
00867
00868 IsInitialized_ = true;
00869 ++NumInitialize_;
00870 InitializeTime_ += Time_->ElapsedTime();
00871
00872 #ifdef IFPACK_FLOPCOUNTERS
00873
00874
00875
00876 double partial = Inverse_->InitializeFlops();
00877 double total;
00878 Comm().SumAll(&partial, &total, 1);
00879 InitializeFlops_ += total;
00880 #endif
00881
00882 return(0);
00883 }
00884
00885
00886 template<typename T>
00887 int Ifpack_AdditiveSchwarz<T>::Compute()
00888 {
00889 if (IsInitialized() == false)
00890 IFPACK_CHK_ERR(Initialize());
00891
00892 Time_->ResetStartTime();
00893 IsComputed_ = false;
00894 Condest_ = -1.0;
00895
00896 IFPACK_CHK_ERR(Inverse_->Compute());
00897
00898 IsComputed_ = true;
00899 ++NumCompute_;
00900 ComputeTime_ += Time_->ElapsedTime();
00901
00902 #ifdef IFPACK_FLOPCOUNTERS
00903
00904 double partial = Inverse_->ComputeFlops();
00905 double total;
00906 Comm().SumAll(&partial, &total, 1);
00907 ComputeFlops_ += total;
00908 #endif
00909
00910
00911 string R = "";
00912 if (UseReordering_)
00913 R = ReorderingType_ + " reord, ";
00914
00915 if (ComputeCondest_)
00916 Condest(Ifpack_Cheap);
00917
00918
00919 Label_ = "Ifpack_AdditiveSchwarz, ov = " + Ifpack_toString(OverlapLevel_)
00920 + ", local solver = \n\t\t***** `" + string(Inverse_->Label()) + "'"
00921 + "\n\t\t***** " + R + "Condition number estimate = "
00922 + Ifpack_toString(Condest_);
00923
00924 return(0);
00925 }
00926
00927
00928 template<typename T>
00929 int Ifpack_AdditiveSchwarz<T>::SetUseTranspose(bool UseTranspose_in)
00930 {
00931
00932
00933 UseTranspose_ = UseTranspose_in;
00934
00935
00936 if (Inverse_!=Teuchos::null)
00937 IFPACK_CHK_ERR(Inverse_->SetUseTranspose(UseTranspose_in));
00938 return(0);
00939 }
00940
00941
00942 template<typename T>
00943 int Ifpack_AdditiveSchwarz<T>::
00944 Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const
00945 {
00946 IFPACK_CHK_ERR(Matrix_->Apply(X,Y));
00947 return(0);
00948 }
00949
00950
00951 template<typename T>
00952 double Ifpack_AdditiveSchwarz<T>::NormInf() const
00953 {
00954 return(-1.0);
00955 }
00956
00957
00958 template<typename T>
00959 const char * Ifpack_AdditiveSchwarz<T>::Label() const
00960 {
00961 return(Label_.c_str());
00962 }
00963
00964
00965 template<typename T>
00966 bool Ifpack_AdditiveSchwarz<T>::UseTranspose() const
00967 {
00968 return(UseTranspose_);
00969 }
00970
00971
00972 template<typename T>
00973 bool Ifpack_AdditiveSchwarz<T>::HasNormInf() const
00974 {
00975 return(false);
00976 }
00977
00978
00979 template<typename T>
00980 const Epetra_Comm & Ifpack_AdditiveSchwarz<T>::Comm() const
00981 {
00982 return(Matrix_->Comm());
00983 }
00984
00985
00986 template<typename T>
00987 const Epetra_Map & Ifpack_AdditiveSchwarz<T>::OperatorDomainMap() const
00988 {
00989 return(Matrix_->OperatorDomainMap());
00990 }
00991
00992
00993 template<typename T>
00994 const Epetra_Map & Ifpack_AdditiveSchwarz<T>::OperatorRangeMap() const
00995 {
00996 return(Matrix_->OperatorRangeMap());
00997 }
00998
00999
01000 template<typename T>
01001 int Ifpack_AdditiveSchwarz<T>::
01002 ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const
01003 {
01004
01005 if (!IsComputed())
01006 IFPACK_CHK_ERR(-3);
01007
01008 int NumVectors = X.NumVectors();
01009
01010 if (NumVectors != Y.NumVectors())
01011 IFPACK_CHK_ERR(-2);
01012
01013 Time_->ResetStartTime();
01014
01015 Teuchos::RefCountPtr<Epetra_MultiVector> OverlappingX;
01016 Teuchos::RefCountPtr<Epetra_MultiVector> OverlappingY;
01017 Teuchos::RefCountPtr<Epetra_MultiVector> Xtmp;
01018
01019
01020 #ifdef IFPACK_FLOPCOUNTERS
01021 double pre_partial = Inverse_->ApplyInverseFlops();
01022 double pre_total;
01023 Comm().SumAll(&pre_partial, &pre_total, 1);
01024 #endif
01025
01026
01027 if (IsOverlapping()) {
01028 #ifdef HAVE_IFPACK_PARALLEL_SUBDOMAIN_SOLVERS
01029 if (OverlappingX == Teuchos::null) {
01030 OverlappingX = Teuchos::rcp( new Epetra_MultiVector(OverlappingMatrix_->RowMatrixRowMap(), X.NumVectors()) );
01031 if (OverlappingX == Teuchos::null) IFPACK_CHK_ERR(-5);
01032 } else assert(OverlappingX->NumVectors() == X.NumVectors());
01033 if (OverlappingY == Teuchos::null) {
01034 OverlappingY = Teuchos::rcp( new Epetra_MultiVector(OverlappingMatrix_->RowMatrixRowMap(), Y.NumVectors()) );
01035 if (OverlappingY == Teuchos::null) IFPACK_CHK_ERR(-5);
01036 } else assert(OverlappingY->NumVectors() == Y.NumVectors());
01037 #else
01038 # ifdef IFPACK_NODE_AWARE_CODE
01039 if (OverlappingX == Teuchos::null) {
01040 OverlappingX = Teuchos::rcp( new Epetra_MultiVector(OverlappingMatrix_->RowMatrixRowMap(),
01041 X.NumVectors()) );
01042 if (OverlappingX == Teuchos::null) IFPACK_CHK_ERR(-5);
01043 } else assert(OverlappingX->NumVectors() == X.NumVectors());
01044 if (OverlappingY == Teuchos::null) {
01045 OverlappingY = Teuchos::rcp( new Epetra_MultiVector(OverlappingMatrix_->RowMatrixRowMap(),
01046 Y.NumVectors()) );
01047 if (OverlappingY == Teuchos::null) IFPACK_CHK_ERR(-5);
01048 } else assert(OverlappingY->NumVectors() == Y.NumVectors());
01049 #else
01050 OverlappingX = Teuchos::rcp( new Epetra_MultiVector(OverlappingMatrix_->RowMatrixRowMap(),
01051 X.NumVectors()) );
01052 OverlappingY = Teuchos::rcp( new Epetra_MultiVector(OverlappingMatrix_->RowMatrixRowMap(),
01053 Y.NumVectors()) );
01054 if (OverlappingY == Teuchos::null) IFPACK_CHK_ERR(-5);
01055 # endif
01056 #endif
01057 OverlappingY->PutScalar(0.0);
01058 OverlappingX->PutScalar(0.0);
01059 IFPACK_CHK_ERR(OverlappingMatrix_->ImportMultiVector(X,*OverlappingX,Insert));
01060
01061
01062
01063 }
01064 else {
01065 Xtmp = Teuchos::rcp( new Epetra_MultiVector(X) );
01066 OverlappingX = Xtmp;
01067 OverlappingY = Teuchos::rcp( &Y, false );
01068 }
01069
01070 if (FilterSingletons_) {
01071
01072 Epetra_MultiVector ReducedX(SingletonFilter_->Map(),NumVectors);
01073 Epetra_MultiVector ReducedY(SingletonFilter_->Map(),NumVectors);
01074 IFPACK_CHK_ERR(SingletonFilter_->SolveSingletons(*OverlappingX,*OverlappingY));
01075 IFPACK_CHK_ERR(SingletonFilter_->CreateReducedRHS(*OverlappingY,*OverlappingX,ReducedX));
01076
01077
01078 if (!UseReordering_) {
01079 IFPACK_CHK_ERR(Inverse_->ApplyInverse(ReducedX,ReducedY));
01080 }
01081 else {
01082 Epetra_MultiVector ReorderedX(ReducedX);
01083 Epetra_MultiVector ReorderedY(ReducedY);
01084 IFPACK_CHK_ERR(Reordering_->P(ReducedX,ReorderedX));
01085 IFPACK_CHK_ERR(Inverse_->ApplyInverse(ReorderedX,ReorderedY));
01086 IFPACK_CHK_ERR(Reordering_->Pinv(ReorderedY,ReducedY));
01087 }
01088
01089
01090 IFPACK_CHK_ERR(SingletonFilter_->UpdateLHS(ReducedY,*OverlappingY));
01091 }
01092 else {
01093
01094 if (!UseReordering_) {
01095 #ifdef HAVE_IFPACK_PARALLEL_SUBDOMAIN_SOLVERS
01096 if (NumMpiProcsPerSubdomain_ > 1) {
01097 tempX_.reset(&((*RangeVectorReindexer_)(*OverlappingX)), false);
01098 tempY_.reset(&((*DomainVectorReindexer_)(*OverlappingY)), false);
01099 IFPACK_CHK_ERR(Inverse_->ApplyInverse(*tempX_,*tempY_));
01100 } else {
01101 IFPACK_CHK_ERR(Inverse_->ApplyInverse(*OverlappingX, *OverlappingY));
01102 }
01103 #else
01104 IFPACK_CHK_ERR(Inverse_->ApplyInverse(*OverlappingX,*OverlappingY));
01105 #endif
01106 }
01107 else {
01108 Epetra_MultiVector ReorderedX(*OverlappingX);
01109 Epetra_MultiVector ReorderedY(*OverlappingY);
01110 IFPACK_CHK_ERR(Reordering_->P(*OverlappingX,ReorderedX));
01111 IFPACK_CHK_ERR(Inverse_->ApplyInverse(ReorderedX,ReorderedY));
01112 IFPACK_CHK_ERR(Reordering_->Pinv(ReorderedY,*OverlappingY));
01113 }
01114 }
01115
01116 if (IsOverlapping()) {
01117 IFPACK_CHK_ERR(OverlappingMatrix_->ExportMultiVector(*OverlappingY,Y,
01118 CombineMode_));
01119 }
01120
01121 #ifdef IFPACK_FLOPCOUNTERS
01122
01123
01124 double partial = Inverse_->ApplyInverseFlops();
01125 double total;
01126 Comm().SumAll(&partial, &total, 1);
01127 ApplyInverseFlops_ += total - pre_total;
01128 #endif
01129
01130
01131 ++NumApplyInverse_;
01132 ApplyInverseTime_ += Time_->ElapsedTime();
01133
01134 return(0);
01135
01136 }
01137
01138
01139 template<typename T>
01140 std::ostream& Ifpack_AdditiveSchwarz<T>::
01141 Print(std::ostream& os) const
01142 {
01143 #ifdef IFPACK_FLOPCOUNTERS
01144 double IF = InitializeFlops();
01145 double CF = ComputeFlops();
01146 double AF = ApplyInverseFlops();
01147
01148 double IFT = 0.0, CFT = 0.0, AFT = 0.0;
01149 if (InitializeTime() != 0.0)
01150 IFT = IF / InitializeTime();
01151 if (ComputeTime() != 0.0)
01152 CFT = CF / ComputeTime();
01153 if (ApplyInverseTime() != 0.0)
01154 AFT = AF / ApplyInverseTime();
01155 #endif
01156
01157 if (Matrix().Comm().MyPID())
01158 return(os);
01159
01160 os << endl;
01161 os << "================================================================================" << endl;
01162 os << "Ifpack_AdditiveSchwarz, overlap level = " << OverlapLevel_ << endl;
01163 if (CombineMode_ == Insert)
01164 os << "Combine mode = Insert" << endl;
01165 else if (CombineMode_ == Add)
01166 os << "Combine mode = Add" << endl;
01167 else if (CombineMode_ == Zero)
01168 os << "Combine mode = Zero" << endl;
01169 else if (CombineMode_ == Average)
01170 os << "Combine mode = Average" << endl;
01171 else if (CombineMode_ == AbsMax)
01172 os << "Combine mode = AbsMax" << endl;
01173
01174 os << "Condition number estimate = " << Condest_ << endl;
01175 os << "Global number of rows = " << Matrix_->NumGlobalRows64() << endl;
01176
01177 #ifdef HAVE_IFPACK_PARALLEL_SUBDOMAIN_SOLVERS
01178 os << endl;
01179 os << "================================================================================" << endl;
01180 os << "Subcommunicator stats" << endl;
01181 os << "Number of MPI processes in simulation: " << NumMpiProcs_ << endl;
01182 os << "Number of subdomains: " << NumSubdomains_ << endl;
01183 os << "Number of MPI processes per subdomain: " << NumMpiProcsPerSubdomain_ << endl;
01184 #endif
01185
01186 os << endl;
01187 os << "Phase # calls Total Time (s) Total MFlops MFlops/s" << endl;
01188 os << "----- ------- -------------- ------------ --------" << endl;
01189 os << "Initialize() " << std::setw(5) << NumInitialize()
01190 << " " << std::setw(15) << InitializeTime()
01191 #ifdef IFPACK_FLOPCOUNTERS
01192 << " " << std::setw(15) << 1.0e-6 * IF
01193 << " " << std::setw(15) << 1.0e-6 * IFT
01194 #endif
01195 << endl;
01196 os << "Compute() " << std::setw(5) << NumCompute()
01197 << " " << std::setw(15) << ComputeTime()
01198 #ifdef IFPACK_FLOPCOUNTERS
01199 << " " << std::setw(15) << 1.0e-6 * CF
01200 << " " << std::setw(15) << 1.0e-6 * CFT
01201 #endif
01202 << endl;
01203 os << "ApplyInverse() " << std::setw(5) << NumApplyInverse()
01204 << " " << std::setw(15) << ApplyInverseTime()
01205 #ifdef IFPACK_FLOPCOUNTERS
01206 << " " << std::setw(15) << 1.0e-6 * AF
01207 << " " << std::setw(15) << 1.0e-6 * AFT
01208 #endif
01209 << endl;
01210 os << "================================================================================" << endl;
01211 os << endl;
01212
01213 return(os);
01214 }
01215
01216 #include "Ifpack_Condest.h"
01217
01218 template<typename T>
01219 double Ifpack_AdditiveSchwarz<T>::
01220 Condest(const Ifpack_CondestType CT, const int MaxIters,
01221 const double Tol, Epetra_RowMatrix* Matrix_in)
01222 {
01223 if (!IsComputed())
01224 return(-1.0);
01225
01226 Condest_ = Ifpack_Condest(*this, CT, MaxIters, Tol, Matrix_in);
01227
01228 return(Condest_);
01229 }
01230
01231 #endif // IFPACK_ADDITIVESCHWARZ_H