43 #ifndef IFPACK_SUPPORTGRAPH_H
44 #define IFPACK_SUPPORTGRAPH_H
46 #if defined(Ifpack_SHOW_DEPRECATED_WARNINGS)
48 #warning "The Ifpack package is deprecated"
57 #include "Epetra_Map.h"
58 #include "Epetra_Comm.h"
59 #include "Epetra_Time.h"
60 #include "Epetra_Vector.h"
61 #include "Epetra_MultiVector.h"
62 #include "Epetra_LinearProblem.h"
63 #include "Epetra_RowMatrix.h"
64 #include "Epetra_CrsMatrix.h"
66 #include "Teuchos_ParameterList.hpp"
67 #include "Teuchos_RefCountPtr.hpp"
69 #include <boost/graph/adjacency_list.hpp>
70 #include <boost/graph/kruskal_min_spanning_tree.hpp>
71 #include <boost/graph/prim_minimum_spanning_tree.hpp>
72 #include <boost/config.hpp>
74 using Teuchos::RefCountPtr;
76 typedef std::pair<int, int>
E;
77 using namespace boost;
79 typedef adjacency_list < vecS, vecS, undirectedS,
80 no_property, property < edge_weight_t, double > >
Graph;
81 typedef graph_traits < Graph >::edge_descriptor
Edge;
82 typedef graph_traits < Graph >::vertex_descriptor
Vertex;
111 virtual int SetUseTranspose(
bool UseTranspose_in);
152 virtual const char * Label()
const;
177 return(IsInitialized_);
205 virtual int Initialize();
210 virtual int Compute();
223 const int MaxIters = 1550,
224 const double Tol = 1e-9,
240 virtual std::ostream& Print(std::ostream&)
const;
245 return(NumInitialize_);
257 return(NumApplyInverse_);
263 return(InitializeTime_);
269 return(ComputeTime_);
275 return(ApplyInverseTime_);
281 return(InitializeFlops_);
287 return(ComputeFlops_);
293 return(ApplyInverseFlops_);
305 Teuchos::RefCountPtr<const Epetra_RowMatrix>
Matrix_;
356 Teuchos::RefCountPtr<Epetra_Time>
Time_;
384 IsInitialized_(
false),
386 UseTranspose_(
false),
391 InitializeTime_(0.0),
393 ApplyInverseTime_(0.0),
394 InitializeFlops_(0.0),
396 ApplyInverseFlops_(0.0),
413 long long rows = (*Matrix_).NumGlobalRows64();
414 long long cols = (*Matrix_).NumGlobalCols64();
415 int num_edges = ((*Matrix_).NumMyNonzeros() - (*Matrix_).NumMyDiagonals())/2;
416 std::cout <<
"global num rows " << rows << std::endl;
423 std::cerr <<
"Ifpack_SupportGraph<T>::FindSupport: global num rows won't fit an int. " << rows << std::endl;
428 int num_verts = (int) rows;
431 E *edge_array =
new E[num_edges];
432 double *weights =
new double[num_edges];
435 int max_num_entries = (*Matrix_).MaxNumEntries();
436 double *values =
new double[max_num_entries];
437 int *indices =
new int[max_num_entries];
439 double * diagonal =
new double[num_verts];
442 for(
int i = 0; i < max_num_entries; i++)
450 for(
int i = 0; i < num_verts; i++)
452 (*Matrix_).ExtractMyRowCopy(i,max_num_entries,num_entries,values,indices);
454 for(
int j = 0; j < num_entries; j++)
459 diagonal[i] = values[j];
462 diagonal[i] *= DiagPertRel_;
464 diagonal[i] += DiagPertAbs_;
469 edge_array[k] =
E(i,indices[j]);
470 weights[k] = values[j];
474 weights[k] *= (1.0 + 1e-8 * drand48());
483 Graph g(edge_array, edge_array + num_edges, weights, num_verts);
486 property_map < Graph, edge_weight_t >::type weight =
get(edge_weight, g);
488 std::vector < Edge > spanning_tree;
491 kruskal_minimum_spanning_tree(g, std::back_inserter(spanning_tree));
494 std::vector<int> NumNz(num_verts,1);
497 for (std::vector < Edge >::iterator ei = spanning_tree.begin();
498 ei != spanning_tree.end(); ++ei)
500 NumNz[source(*ei,g)] = NumNz[source(*ei,g)] + 1;
501 NumNz[target(*ei,g)] = NumNz[target(*ei,g)] + 1;
506 std::vector< std::vector< int > > Indices(num_verts);
511 std::vector< std::vector< double > > Values(num_verts);
513 for(
int i = 0; i < num_verts; i++)
515 std::vector<int> temp(NumNz[i],0);
516 std::vector<double> temp2(NumNz[i],0);
521 int *l =
new int[num_verts];
522 for(
int i = 0; i < num_verts; i++)
530 for(
int i = 0; i < NumForests_; i++)
534 spanning_tree.clear();
535 kruskal_minimum_spanning_tree(g,std::back_inserter(spanning_tree));
536 for(std::vector < Edge >::iterator ei = spanning_tree.begin();
537 ei != spanning_tree.end(); ++ei)
539 NumNz[source(*ei,g)] = NumNz[source(*ei,g)] + 1;
540 NumNz[target(*ei,g)] = NumNz[target(*ei,g)] + 1;
542 for(
int i = 0; i < num_verts; i++)
544 Indices[i].resize(NumNz[i]);
545 Values[i].resize(NumNz[i]);
549 for (std::vector < Edge >::iterator ei = spanning_tree.begin();
550 ei != spanning_tree.end(); ++ei)
554 Indices[source(*ei,g)][0] = source(*ei,g);
555 Values[source(*ei,g)][0] = Values[source(*ei,g)][0] - weight[*ei];
556 Indices[target(*ei,g)][0] = target(*ei,g);
557 Values[target(*ei,g)][0] = Values[target(*ei,g)][0] - weight[*ei];
559 Indices[source(*ei,g)][l[source(*ei,g)]] = target(*ei,g);
560 Values[source(*ei,g)][l[source(*ei,g)]] = weight[*ei];
561 l[source(*ei,g)] = l[source(*ei,g)] + 1;
563 Indices[target(*ei,g)][l[target(*ei,g)]] = source(*ei,g);
564 Values[target(*ei,g)][l[target(*ei,g)]] = weight[*ei];
565 l[target(*ei,g)] = l[target(*ei,g)] + 1;
582 Matrix_->Multiply(
false, ones, surplus);
584 for(
int i = 0; i < num_verts; i++)
586 Values[i][0] += surplus[i];
587 Values[i][0] = KeepDiag_*diagonal[i] +
588 (1.-KeepDiag_) * Values[i][0];
594 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
595 if((*Matrix_).RowMatrixRowMap().GlobalIndicesLongLong())
598 for(
int i = 0; i < num_verts; i++)
600 std::vector<long long> IndicesLL(l[i]);
601 for(
int k = 0; k < l[i]; ++k)
602 IndicesLL[k] = Indices[i][k];
604 (*Support_).InsertGlobalValues(i,l[i],&Values[i][0],&IndicesLL[0]);
609 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
610 if((*Matrix_).RowMatrixRowMap().GlobalIndicesInt())
613 for(
int i = 0; i < num_verts; i++)
615 (*Support_).InsertGlobalValues(i,l[i],&Values[i][0],&Indices[i][0]);
620 throw "Ifpack_SupportGraph::FindSupport: GlobalIndices unknown.";;
622 (*Support_).FillComplete();
638 NumForests_ = List_in.
get(
"MST: forest number", NumForests_);
639 KeepDiag_ = List_in.
get(
"MST: keep diagonal", KeepDiag_);
640 Randomize_ = List_in.
get(
"MST: randomize", Randomize_);
642 DiagPertRel_ = List_in.
get(
"fact: relative threshold", DiagPertRel_);
643 DiagPertAbs_ = List_in.
get(
"fact: absolute threshold", DiagPertAbs_);
651 IsInitialized_ =
false;
661 Time_->ResetStartTime();
669 IsInitialized_ =
true;
671 InitializeTime_ += Time_->ElapsedTime();
680 if (IsInitialized() ==
false)
683 Time_->ResetStartTime();
691 ComputeTime_ += Time_->ElapsedTime();
702 UseTranspose_ = UseTranspose_in;
722 return(Label_.c_str());
732 Time_->ResetStartTime();
735 Inverse_->ApplyInverse(X,Y);
738 ApplyInverseTime_ += Time_->ElapsedTime();
747 os <<
"================================================================================" << std::endl;
748 os <<
"Ifpack_SupportGraph: " << Label () << std::endl << std::endl;
749 os <<
"Condition number estimate = " << Condest() << std::endl;
750 os <<
"Global number of rows = " << Matrix_->NumGlobalRows64() << std::endl;
751 os <<
"Number of edges in support graph = " << (Support_->NumGlobalNonzeros64()-Support_->NumGlobalDiagonals64())/2 << std::endl;
752 os <<
"Fraction of off diagonals of support graph/off diagonals of original = "
753 << ((double)Support_->NumGlobalNonzeros64()-Support_->NumGlobalDiagonals64())/(Matrix_->NumGlobalNonzeros64()-Matrix_->NumGlobalDiagonals64());
755 os <<
"Phase # calls Total Time (s) Total MFlops MFlops/s" << std::endl;
756 os <<
"----- ------- -------------- ------------ --------" << std::endl;
757 os <<
"Initialize() " << std::setw(10) << NumInitialize_
758 <<
" " << std::setw(15) << InitializeTime_
759 <<
" 0.0 0.0" << std::endl;
760 os <<
"Compute() " << std::setw(10) << NumCompute_
761 <<
" " << std::setw(22) << ComputeTime_
762 <<
" " << std::setw(15) << 1.0e-6 * ComputeFlops_;
763 if (ComputeTime_ != 0.0)
764 os <<
" " << std::setw(15) << 1.0e-6 * ComputeFlops_ / ComputeTime_ << std::endl;
766 os <<
" " << std::setw(15) << 0.0 << std::endl;
767 os <<
"ApplyInverse() " << std::setw(10) << NumApplyInverse_
768 <<
" " << std::setw(22) << ApplyInverseTime_
769 <<
" " << std::setw(15) << 1.0e-6 * ApplyInverseFlops_;
770 if (ApplyInverseTime_ != 0.0)
771 os <<
" " << std::setw(15) << 1.0e-6 * ApplyInverseFlops_ / ApplyInverseTime_ << std::endl;
773 os <<
" " << std::setw(15) << 0.0 << std::endl;
775 os << std::endl << std::endl;
776 os <<
"Now calling the underlying preconditioner's print()" << std::endl;
798 #endif // IFPACK_SUPPORTGRAPH_H
double ComputeTime_
Contains the time for all successful calls to Compute().
virtual double Condest() const
Returns the computed condition number.
Teuchos::RefCountPtr< Epetra_Time > Time_
Object used for timing purposes.
int NumApplyInverse_
Contains the number of successful call to ApplyInverse().
bool IsComputed_
If true, the preconditioner has been successfully computed.
virtual const char * Label() const
Returns a character string describing the operator.
virtual int NumApplyInverse() const
Returns the number of calls to ApplyInverse().
virtual const Epetra_Map & OperatorRangeMap() const
Returns the Epetra_Map object associated with the range of this operator.
virtual double ApplyInverseFlops() const
Returns the total number of flops to apply the preconditioner.
int NumInitialize_
Contains the number of successful calls to Initialize().
Teuchos::ParameterList List_
Stores a copy of the list given in SetParameters()
virtual double ApplyInverseTime() const
Returns the total time spent in ApplyInverse().
std::string Label_
Contains the label of this object.
int Randomize_
Option to add random pertubation to edge weights, to get random spanning trees.
virtual int ApplyInverse(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
Applies the preconditioner to X, returns the result in Y.
Ifpack_SupportGraph(Epetra_RowMatrix *Matrix_in)
Constructor.
virtual double InitializeTime() const
Returns the total time spent in Initialize().
Teuchos::RefCountPtr< Epetra_CrsMatrix > Support_
Pointers to the matrix of the support graph.
graph_traits< Graph >::edge_descriptor Edge
T & get(ParameterList &l, const std::string &name)
virtual const Epetra_Comm & Comm() const
Returns a pointer to the Epetra_Comm communicator associated with this operator.
virtual bool UseTranspose() const
Returns the current UseTranspose setting.
virtual double ComputeFlops() const
Returns the total number of flops to compute the preconditioner.
virtual int SetParameters(Teuchos::ParameterList &List)
Sets all the parameters for the preconditioner.
virtual int Apply(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
Applies the matrix to an Epetra_MultiVector.
double Condest_
Contains the estimated condition number.
virtual bool HasNormInf() const
Returns true if this object can provide an approximate Inf-norm, false otherwise. ...
virtual int SetUseTranspose(bool UseTranspose_in)
If set true, transpose of this operator will be applied (not implemented).
Ifpack_CondestType
Ifpack_CondestType: enum to define the type of condition number estimate.
virtual const Epetra_RowMatrix & Matrix() const
Returns a const reference to the internally stored matrix.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Teuchos::RefCountPtr< const Epetra_RowMatrix > Matrix_
Pointers to the matrix to be preconditioned.
int NumCompute_
Contains the number of successful call to Compute().
int NumForests_
Contains the number of forests in the support graph.
Teuchos::RefCountPtr< T > Inverse_
Pointer to the local solver.
Ifpack_Preconditioner: basic class for preconditioning in Ifpack.
virtual double NormInf() const
Returns the infinity norm of the global matrix (not implemented)
graph_traits< Graph >::vertex_descriptor Vertex
virtual const Epetra_Map & OperatorDomainMap() const
Returns the Epetra_Map object associated with the domain of this operator.
virtual int NumInitialize() const
Returns the number of calls to Initialize().
adjacency_list< vecS, vecS, undirectedS, no_property, property< edge_weight_t, double > > Graph
double InitializeFlops_
Contains the number of flops for Initialize().
virtual int NumCompute() const
Returns the number of calls to Compute().
virtual std::ostream & Print(std::ostream &) const
Prints on ostream basic information about this object.
double ComputeFlops_
Contains the number of flops for Compute().
double KeepDiag_
Contains the option to keep the diagonal of original matrix, or weighted average. ...
double Ifpack_Condest(const Ifpack_Preconditioner &IFP, const Ifpack_CondestType CT, const int MaxIters, const double Tol, Epetra_RowMatrix *Matrix)
double InitializeTime_
Contains the time for all successful calls to Initialize().
bool UseTranspose_
If true, solve with the transpose (not supported by all solvers).
bool IsInitialized_
If true, the preconditioner has been successfully initialized.
virtual bool IsComputed() const
Returns true if the preconditioner has been successfully computed.
virtual int Initialize()
Initialize the preconditioner.
double ApplyInverseTime_
Contains the time for all successful calls to ApplyInverse().
double ApplyInverseFlops_
Contain sthe number of flops for ApplyInverse().
virtual bool IsInitialized() const
Returns true if the preconditioner has been successfully initialized.
virtual int Compute()
Computes the preconditioners.
double DiagPertAbs_
Absolute diagonal pertubation.
virtual double ComputeTime() const
Returns the total time spent in Compute().
#define IFPACK_CHK_ERR(ifpack_err)
int FindSupport()
Compute the support graph.
double DiagPertRel_
Relative diagonal pertubation.
virtual double InitializeFlops() const
Returns the number of flops in the initialization phase.