int InitMatValues( const Epetra_CrsMatrix& newA, Epetra_CrsMatrix* A )
{
  int numMyRows = newA.NumMyRows();
  int maxNum = newA.MaxNumEntries();
  int numIn;
  int *idx = 0;
  double *vals = 0;

  idx = new int[maxNum];
  vals = new double[maxNum];

  // For each row get the values and indices, and replace the values in A.
  for (int i=0; i<numMyRows; ++i) {

    // Get the values and indices from newA.
    EPETRA_CHK_ERR( newA.ExtractMyRowCopy(i, maxNum, numIn, vals, idx) );

    // Replace the values in A
    EPETRA_CHK_ERR( A->ReplaceMyValues(i, numIn, vals, idx) );

  }

  // Clean up.
  delete [] idx;
  delete [] vals;

  return 0;
}
Esempio n. 2
0
//EpetraCrsMatrix_To_TpetraCrsMatrix: copies Epetra_CrsMatrix to its analogous Tpetra_CrsMatrix
Teuchos::RCP<Tpetra_CrsMatrix> Petra::EpetraCrsMatrix_To_TpetraCrsMatrix(const Epetra_CrsMatrix& epetraCrsMatrix_,
                                                               const Teuchos::RCP<const Teuchos::Comm<int> >& commT_)
{
  //get row map of Epetra::CrsMatrix & convert to Tpetra::Map
  auto tpetraRowMap_ = EpetraMap_To_TpetraMap(epetraCrsMatrix_.RowMap(), commT_);

  //get col map of Epetra::CrsMatrix & convert to Tpetra::Map
  auto tpetraColMap_ = EpetraMap_To_TpetraMap(epetraCrsMatrix_.ColMap(), commT_);

  //get CrsGraph of Epetra::CrsMatrix & convert to Tpetra::CrsGraph
  const Epetra_CrsGraph epetraCrsGraph_ = epetraCrsMatrix_.Graph();
  std::size_t maxEntries = epetraCrsGraph_.GlobalMaxNumIndices();
  Teuchos::RCP<Tpetra_CrsGraph> tpetraCrsGraph_ = Teuchos::rcp(new Tpetra_CrsGraph(tpetraRowMap_, tpetraColMap_, maxEntries));

  for (LO i=0; i<epetraCrsGraph_.NumMyRows(); i++) {
     LO NumEntries; LO *Indices;
     epetraCrsGraph_.ExtractMyRowView(i, NumEntries, Indices);
     tpetraCrsGraph_->insertLocalIndices(i, NumEntries, Indices);
  }
  tpetraCrsGraph_->fillComplete();

  //convert Epetra::CrsMatrix to Tpetra::CrsMatrix, after creating Tpetra::CrsMatrix based on above Tpetra::CrsGraph
  Teuchos::RCP<Tpetra_CrsMatrix> tpetraCrsMatrix_ = Teuchos::rcp(new Tpetra_CrsMatrix(tpetraCrsGraph_));
  tpetraCrsMatrix_->setAllToScalar(0.0);

  for (LO i=0; i<epetraCrsMatrix_.NumMyRows(); i++) {
     LO NumEntries; LO *Indices; ST *Values;
     epetraCrsMatrix_.ExtractMyRowView(i, NumEntries, Values, Indices);
     tpetraCrsMatrix_->replaceLocalValues(i, NumEntries, Values, Indices);
  }
  tpetraCrsMatrix_->fillComplete();

  return tpetraCrsMatrix_;

}
Esempio n. 3
0
    //! Update matrix
    static void update(Epetra_CrsMatrix& mat, double a, 
		       const Epetra_CrsMatrix& x) {
      int num_col;
      for (int i=0; i<mat.NumMyRows(); i++) {
	mat.NumMyRowEntries(i, num_col);
	for (int j=0; j<num_col; j++)
	  mat[i][j] += a*x[i][j];
      }
    }
//==============================================================================
Epetra_FastCrsMatrix::Epetra_FastCrsMatrix(const Epetra_CrsMatrix & Matrix, bool UseFloats) 
  : CrsMatrix_(Matrix),
    Values_(0),
    NumMyRows_(Matrix.NumMyRows()),
    NumMyNonzeros(Matrix.NumMyNonzeros()),
    ImportVector_(0),
    ExportVector_(0),
    CV_(Copy)
{
  if (!CrsMatrix_.Filled()) throw CrsMatrix_.ReportError("Input matrix must have called FillComplete()", -1);
  Allocate(UseFloats);
}
/*----------------------------------------------------------------------*
 |                                                           m.gee 11/05|
 *----------------------------------------------------------------------*/
bool ML_NOX::Print_Epetra_CrsMatrix(Epetra_CrsMatrix& matrix)
{
  for (int i=0; i<matrix.NumMyRows(); ++i)
  {
    printf("Lrow %5d:  ",i); fflush(stdout);
    int numentries;
    int* indices;
    double* values;
    int err  = matrix.ExtractMyRowView(i,numentries,values,indices);
    for (int j=0; j<numentries; ++j)
    printf("%5d %10.3e   ",indices[j],values[j]); 
    printf("\n"); fflush(stdout);
  }
  return true;
}
//=========================================================================
// NOTE: This method should be removed and replaced with calls to Epetra_Util_ExtractHbData()
int Epetra_LinearProblemRedistor::ExtractHbData(int & M, int & N, int & nz, int * & ptr,
																								int * & ind, double * & val, int & Nrhs,
																								double * & rhs, int & ldrhs,
																								double * & lhs, int & ldlhs) const {

	Epetra_CrsMatrix * RedistMatrix = dynamic_cast<Epetra_CrsMatrix *>(RedistProblem_->GetMatrix());
	
	if (RedistMatrix==0) EPETRA_CHK_ERR(-1); // This matrix is zero or not an Epetra_CrsMatrix
	if (!RedistMatrix->IndicesAreContiguous()) { // Data must be contiguous for this to work
		EPETRA_CHK_ERR(-2);
	}

	M = RedistMatrix->NumMyRows();
	N = RedistMatrix->NumMyCols();
	nz = RedistMatrix->NumMyNonzeros();
	val = (*RedistMatrix)[0];        // Dangerous, but cheap and effective way to access first element in

	const Epetra_CrsGraph & RedistGraph = RedistMatrix->Graph();
	ind = RedistGraph[0];  // list of values and indices

	Epetra_MultiVector * LHS = RedistProblem_->GetLHS();
	Epetra_MultiVector * RHS = RedistProblem_->GetRHS();
	Nrhs = RHS->NumVectors();
	if (Nrhs>1) {
		if (!RHS->ConstantStride()) {EPETRA_CHK_ERR(-3)}; // Must have strided vectors
		if (!LHS->ConstantStride()) {EPETRA_CHK_ERR(-4)}; // Must have strided vectors
	}
	ldrhs = RHS->Stride();
	rhs = (*RHS)[0]; // Dangerous but effective (again)
	ldlhs = LHS->Stride();
	lhs = (*LHS)[0];

	// Finally build ptr vector

	if (ptr_==0) {
		ptr_ = new int[M+1];
		ptr_[0] = 0;
		for (int i=0; i<M; i++) ptr_[i+1] = ptr_[i] + RedistGraph.NumMyIndices(i);
	}
	ptr = ptr_;
	
  return(0);
}
Esempio n. 7
0
void 
BroydenOperator::replaceBroydenMatrixValues( const Epetra_CrsMatrix & mat)
{
  double * values    ;
  int    * indices   ;
  int     numEntries ;
  int     ierr       ;

  for( int row = 0; row < mat.NumMyRows(); ++row) 
  {
    ierr = mat.ExtractMyRowView(row, numEntries, values, indices);
    ierr += crsMatrix->ReplaceGlobalValues(row, numEntries, values, indices);
    if( ierr )
    {
      cout << "ERROR (" << ierr << ") : "
           << "NOX::Epetra::BroydenOperator::replaceBroydenMatrixValues(...)"
           << " - Extract or Replace values error for row --> "
           << row << endl;
      throw "NOX Broyden Operator Error";
    }
  }
}
// ======================================================================
inline void Apply_BCsToMatrixRowsAndColumns(const int *dirichletRows, int numBCRows,const Epetra_IntVector &dirichletColumns,const Epetra_CrsMatrix & Matrix){
  /* This function zeros out rows & columns of Matrix.
     Comments: The graph of Matrix is unchanged.
  */
  // Nuke the rows
  for(int i=0;i<numBCRows;i++){
    int numEntries, *cols;
    double *vals;
    Matrix.ExtractMyRowView(dirichletRows[i],numEntries,vals,cols);
    for (int j=0; j<numEntries; j++) vals[j]=0.0;
  }/*end for*/

  // Nuke the columns
  for (int i=0; i < Matrix.NumMyRows(); i++) {
    int numEntries;
    double *vals;
    int *cols;
    Matrix.ExtractMyRowView(i,numEntries,vals,cols);
    for (int j=0; j < numEntries; j++) {
      if (dirichletColumns[ cols[j] ] > 0)  vals[j] = 0.0;
    }/*end for*/
  }/*end for*/
}/* end Apply_BCsToMatrixColumns */
Esempio n. 9
0
bool CrsMatrixInfo( const Epetra_CrsMatrix & A,
		    ostream & os ) 

{

  int MyPID = A.Comm().MyPID(); 

  // take care that matrix is already trasformed
  bool IndicesAreGlobal = A.IndicesAreGlobal();
  if( IndicesAreGlobal == true ) {
    if( MyPID == 0 ) {
      os << "WARNING : matrix must be transformed to local\n";
      os << "          before calling CrsMatrixInfo\n";
      os << "          Now returning...\n";
    }
    return false;
  }

  int NumGlobalRows = A.NumGlobalRows();
  int NumGlobalNonzeros = A.NumGlobalNonzeros();
  int NumGlobalCols = A.NumGlobalCols();
  double NormInf = A.NormInf();
  double NormOne = A.NormOne();
  int NumGlobalDiagonals = A.NumGlobalDiagonals();
  int GlobalMaxNumEntries = A.GlobalMaxNumEntries();
  int IndexBase = A.IndexBase();
  bool StorageOptimized = A.StorageOptimized();
  bool LowerTriangular = A.LowerTriangular();
  bool UpperTriangular = A.UpperTriangular();
  bool NoDiagonal = A.NoDiagonal();

  // these variables identifies quantities I have to compute,
  // since not provided by Epetra_CrsMatrix

  double MyFrobeniusNorm( 0.0 ), FrobeniusNorm( 0.0 );
  double MyMinElement( DBL_MAX ), MinElement( DBL_MAX );
  double MyMaxElement( DBL_MIN ), MaxElement( DBL_MIN );
  double MyMinAbsElement( DBL_MAX ), MinAbsElement( DBL_MAX );
  double MyMaxAbsElement( 0.0 ), MaxAbsElement( 0.0 );

  int NumMyRows = A.NumMyRows();
  int * NzPerRow = new int[NumMyRows];
  int Row; // iterator on rows
  int Col; // iterator on cols
  int MaxNumEntries = A.MaxNumEntries();
  double * Values = new double[MaxNumEntries];
  int * Indices = new int[MaxNumEntries];
  double Element, AbsElement; // generic nonzero element and its abs value
  int NumEntries;
  double * Diagonal = new double [NumMyRows];
  // SumOffDiagonal is the sum of absolute values for off-diagonals
  double * SumOffDiagonal = new double [NumMyRows];  
  for( Row=0 ;  Row<NumMyRows ; ++Row ) {
    SumOffDiagonal[Row] = 0.0;
  }
  int * IsDiagonallyDominant = new int [NumMyRows];
  int GlobalRow;

  // cycle over all matrix elements
  for( Row=0 ; Row<NumMyRows ; ++Row ) {
    GlobalRow = A.GRID(Row);
    NzPerRow[Row] = A.NumMyEntries(Row);
    A.ExtractMyRowCopy(Row,NzPerRow[Row],NumEntries,Values,Indices);
    for( Col=0 ; Col<NumEntries ; ++Col ) {
      Element = Values[Col];
      AbsElement = abs(Element);
      if( Element<MyMinElement ) MyMinElement = Element;
      if( Element>MyMaxElement ) MyMaxElement = Element;
      if( AbsElement<MyMinAbsElement ) MyMinAbsElement = AbsElement;
      if( AbsElement>MyMaxAbsElement ) MyMaxAbsElement = AbsElement;
      if( Indices[Col] == Row ) Diagonal[Row] = Element;
      else
	SumOffDiagonal[Row] += abs(Element);
      MyFrobeniusNorm += pow(Element,2);
    }
  }   

  // analise storage per row 
  int MyMinNzPerRow( NumMyRows ), MinNzPerRow( NumMyRows );
  int MyMaxNzPerRow( 0 ), MaxNzPerRow( 0 );

  for( Row=0 ; Row<NumMyRows ; ++Row ) {
    if( NzPerRow[Row]<MyMinNzPerRow ) MyMinNzPerRow=NzPerRow[Row];
    if( NzPerRow[Row]>MyMaxNzPerRow ) MyMaxNzPerRow=NzPerRow[Row];
  }

  // a test to see if matrix is diagonally-dominant

  int MyDiagonalDominance( 0 ), DiagonalDominance( 0 );
  int MyWeakDiagonalDominance( 0 ), WeakDiagonalDominance( 0 );

  for( Row=0 ; Row<NumMyRows ; ++Row ) {
    if( abs(Diagonal[Row])>SumOffDiagonal[Row] ) 
      ++MyDiagonalDominance;
    else if( abs(Diagonal[Row])==SumOffDiagonal[Row] ) 
      ++MyWeakDiagonalDominance;
  }

  // reduction operations
  
  A.Comm().SumAll(&MyFrobeniusNorm, &FrobeniusNorm, 1);
  A.Comm().MinAll(&MyMinElement, &MinElement, 1);
  A.Comm().MaxAll(&MyMaxElement, &MaxElement, 1);
  A.Comm().MinAll(&MyMinAbsElement, &MinAbsElement, 1);
  A.Comm().MaxAll(&MyMaxAbsElement, &MaxAbsElement, 1);
  A.Comm().MinAll(&MyMinNzPerRow, &MinNzPerRow, 1);
  A.Comm().MaxAll(&MyMaxNzPerRow, &MaxNzPerRow, 1);
  A.Comm().SumAll(&MyDiagonalDominance, &DiagonalDominance, 1);
  A.Comm().SumAll(&MyWeakDiagonalDominance, &WeakDiagonalDominance, 1);

  // free memory

  delete Values;
  delete Indices;
  delete Diagonal;
  delete SumOffDiagonal;
  delete IsDiagonallyDominant;
  delete NzPerRow;

  // simply no output for MyPID>0, only proc 0 write on os
  if( MyPID != 0 ) return true;

  os << "*** general Information about the matrix\n";
  os << "Number of Global Rows = " << NumGlobalRows << endl;
  os << "Number of Global Cols = " << NumGlobalCols << endl;
  os << "is the matrix square  = " <<
    ((NumGlobalRows==NumGlobalCols)?"yes":"no") << endl;
  os << "||A||_\\infty          = " << NormInf << endl;
  os << "||A||_1               = " << NormOne << endl;
  os << "||A||_F               = " << sqrt(FrobeniusNorm) << endl;
  os << "Number of nonzero diagonal entries = "
     << NumGlobalDiagonals
     << "( " << 1.0* NumGlobalDiagonals/NumGlobalRows*100
     << " %)\n";
  os << "Nonzero per row : min = " << MinNzPerRow 
     << " average = " << 1.0*NumGlobalNonzeros/NumGlobalRows
     << " max = " << MaxNzPerRow << endl; 
  os << "Maximum number of nonzero elements/row = " 
     << GlobalMaxNumEntries << endl;
  os << "min( a_{i,j} )      = " << MinElement << endl;
  os << "max( a_{i,j} )      = " << MaxElement << endl;
  os << "min( abs(a_{i,j}) ) = " << MinAbsElement << endl;
  os << "max( abs(a_{i,j}) ) = " << MaxAbsElement << endl;
  os << "Number of diagonal dominant rows        = " << DiagonalDominance 
     << " (" << 100.0*DiagonalDominance/NumGlobalRows << " % of total)\n";
  os << "Number of weakly diagonal dominant rows = " 
     << WeakDiagonalDominance 
     << " (" << 100.0*WeakDiagonalDominance/NumGlobalRows << " % of total)\n";

  os << "*** Information about the Trilinos storage\n";
  os << "Base Index                 = " << IndexBase << endl;
  os << "is storage optimized       = " 
     << ((StorageOptimized==true)?"yes":"no") << endl;
  os << "are indices global         = "
     << ((IndicesAreGlobal==true)?"yes":"no") << endl;
  os << "is matrix lower triangular = " 
     << ((LowerTriangular==true)?"yes":"no") << endl;
  os << "is matrix upper triangular = " 
     << ((UpperTriangular==true)?"yes":"no") << endl;
  os << "are there diagonal entries = " 
     <<  ((NoDiagonal==false)?"yes":"no") << endl;

  return true;

}
CrsMatrix_SolverMap::NewTypeRef
CrsMatrix_SolverMap::
operator()( OriginalTypeRef orig )
{
  origObj_ = &orig;

  assert( !orig.IndicesAreGlobal() );

  //test if matrix has missing local columns in its col std::map
  const Epetra_Map & RowMap = orig.RowMap();
  const Epetra_Map & DomainMap = orig.DomainMap();
  const Epetra_Map & ColMap = orig.ColMap();
  const Epetra_Comm & Comm = RowMap.Comm();
  int NumMyRows = RowMap.NumMyElements();
  int NumCols = DomainMap.NumMyElements();
  int Match = 0;
  for( int i = 0; i < NumCols; ++i )
    if( DomainMap.GID(i) != ColMap.GID(i) )
    {
      Match = 1;
      break;
    }

  int MatchAll = 0;
  Comm.SumAll( &Match, &MatchAll, 1 );

  if( !MatchAll )
  {
    newObj_ = origObj_;
  }
  else
  {
    //create ColMap with all local rows included
    std::vector<int> Cols(NumCols);
    //fill Cols list with GIDs of all local columns 
    for( int i = 0; i < NumCols; ++i )
      Cols[i] = DomainMap.GID(i);

    //now append to Cols any ghost column entries
    int NumMyCols = ColMap.NumMyElements();
    for( int i = 0; i < NumMyCols; ++i )
      if( !DomainMap.MyGID( ColMap.GID(i) ) ) Cols.push_back( ColMap.GID(i) );
    
    int NewNumMyCols = Cols.size();
    int NewNumGlobalCols;
    Comm.SumAll( &NewNumMyCols, &NewNumGlobalCols, 1 );
    //create new column std::map
    NewColMap_ = new Epetra_Map( NewNumGlobalCols, NewNumMyCols,&Cols[0], DomainMap.IndexBase(), Comm );

    //New Graph
    std::vector<int> NumIndicesPerRow( NumMyRows );
    for( int i = 0; i < NumMyRows; ++i )
      NumIndicesPerRow[i] = orig.NumMyEntries(i);
    NewGraph_ = new Epetra_CrsGraph( Copy, RowMap, *NewColMap_, &NumIndicesPerRow[0] );

    int MaxNumEntries = orig.MaxNumEntries();
    int NumEntries;
    std::vector<int> Indices( MaxNumEntries );
    for( int i = 0; i < NumMyRows; ++i )
    {
      int RowGID = RowMap.GID(i);
      orig.Graph().ExtractGlobalRowCopy( RowGID, MaxNumEntries, NumEntries, &Indices[0] );
      NewGraph_->InsertGlobalIndices( RowGID, NumEntries, &Indices[0] );
    }
    const Epetra_Map & RangeMap = orig.RangeMap();
    NewGraph_->FillComplete(DomainMap,RangeMap);

    //intial construction of matrix 
    Epetra_CrsMatrix * NewMatrix = new Epetra_CrsMatrix( View, *NewGraph_ );

    //insert views of row values
    int * myIndices;
    double * myValues;
    int indicesCnt;
    int numMyRows = NewMatrix->NumMyRows();
    for( int i = 0; i < numMyRows; ++i )
    {
      orig.ExtractMyRowView( i, indicesCnt, myValues, myIndices );
      NewGraph_->ExtractMyRowView( i, indicesCnt, myIndices );

      NewMatrix->InsertMyValues( i, indicesCnt, myValues, myIndices );
    }

    NewMatrix->FillComplete(DomainMap,RangeMap);

    newObj_ = NewMatrix;
  }

  return *newObj_;
}
Esempio n. 11
0
void
Stokhos::AdaptivityManager::
sumInOperator(Epetra_CrsMatrix & A,const Stokhos::AdaptivityManager::Sparse3TensorHash & Cijk,int k,const Epetra_CrsMatrix & J_k) const
{
   TEUCHOS_ASSERT(J_k.NumMyRows() == int(sg_basis_row_dof_.size()));
   TEUCHOS_ASSERT(J_k.NumMyCols() == int(sg_basis_col_dof_.size()));

   const Teuchos::Array<double> & normValues = sg_master_basis_->norm_squared();

   // loop over deterministic rows 
   for(int localM=0;localM<J_k.NumMyRows();localM++) {
      int m = J_k.GRID(localM);

      // grab row basis
      Teuchos::RCP<const Stokhos::ProductBasis<int,double> > rowStochBasis 
            = sg_basis_row_dof_[localM]; 
 
      // grab row from deterministic system
      int d_numEntries;
      int * d_Indices;
      double * d_Values;
     
      J_k.ExtractMyRowView(localM,d_numEntries,d_Values,d_Indices);
      
      // loop over stochastic degrees of freedom of this row
      for(int rb_i=0;rb_i<rowStochBasis->size();rb_i++) {
         int i = sg_master_basis_->index(rowStochBasis->term(rb_i));

         double normValue = normValues[i]; // sg_master_basis->norm_squared(i);
         
         int sg_m = getGlobalRowId(localM,rb_i);

         // we wipe out old values, capacity should gurantee
         // we don't allocate more often than neccessary!
         std::vector<int> sg_indices;
         std::vector<double> sg_values;

         // sg_indices.resize(0); 
         // sg_values.resize(0);

         // loop over each column
         for(int colInd=0;colInd<d_numEntries;colInd++) {
            int localN = d_Indices[colInd];  // grab local deterministic column id

            // grab row basis
            Teuchos::RCP<const Stokhos::ProductBasis<int,double> > colStochBasis 
                  = sg_basis_col_dof_[localN]; 

            // build values array
            for(int cb_j=0;cb_j<colStochBasis->size();cb_j++) {
               int j = sg_master_basis_->index(colStochBasis->term(cb_j));
               int sg_n = getGlobalColId(localN,cb_j);
               double cijk = Cijk.getValue(i,j,k); 

               // no reason to work it in!
               if(cijk==0) continue;

               if(scaleOp_)
                  cijk = cijk/normValue;

               sg_indices.push_back(sg_n);
               sg_values.push_back(cijk*d_Values[colInd]);
            }
         }

         // add in matrix values
         A.SumIntoGlobalValues(sg_m,sg_indices.size(),&sg_values[0],&sg_indices[0]);
      }
   }
}
Esempio n. 12
0
/*----------------------------------------------------------------------*
 | Create the spd system (public)                            mwgee 12/05|
 | Note that this is collective for ALL procs                           |
 *----------------------------------------------------------------------*/
Epetra_CrsMatrix* MOERTEL::Manager::MakeSPDProblem()
{
  // time this process
  Epetra_Time time(Comm());
  time.ResetStartTime();

  // check whether all interfaces are complete and integrated
  std::map<int,Teuchos::RCP<MOERTEL::Interface> >::iterator curr;
  for (curr=interface_.begin(); curr != interface_.end(); ++curr)
  {
    if (curr->second->IsComplete() == false)
    {
      cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n"
           << "***ERR*** interface " << curr->second->Id() << " is not Complete()\n"
           << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      return NULL;
    }
    if (curr->second->IsIntegrated() == false)
    {
      cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n"
           << "***ERR*** interface " << curr->second->Id() << " is not integrated yet\n"
           << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      return NULL;
    }
  }
  
  // check whether we have a problemmap_
  if (problemmap_==Teuchos::null)
  {
      cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n"
           << "***ERR*** No problemmap_ set\n"
           << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      return NULL;
  }
  
  // check whether we have a constraintsmap_
  if (constraintsmap_==Teuchos::null)
  {
      cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n"
           << "***ERR*** onstraintsmap is NULL\n"
           << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      return NULL;
  }
  
  // check for saddlemap_
  if (saddlemap_==Teuchos::null)
  {
      cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n"
           << "***ERR*** saddlemap_==NULL\n"
           << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      return NULL;
  }

  // check for inputmatrix
  if (inputmatrix_==Teuchos::null)
  {
      cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n"
           << "***ERR*** No inputmatrix set\n"
           << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      return NULL;
  }

  // check whether we have M and D matrices
  if (D_==Teuchos::null || M_==Teuchos::null)
  {
      cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n"
           << "***ERR*** Matrix M or D is NULL\n"
           << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      return NULL;
  }
  
  // we need a map from lagrange multiplier dofs to primal dofs on the same node
  std::vector<MOERTEL::Node*> nodes(0);
  std::map<int,int> lm_to_dof;
  for (curr=interface_.begin(); curr!=interface_.end(); ++curr)
  {
	Teuchos::RCP<MOERTEL::Interface> inter = curr->second;
    inter->GetNodeView(nodes);
    for (int i=0; i<(int)nodes.size(); ++i)
    {
      if (!nodes[i]->Nlmdof()) 
        continue;
      const int* dof = nodes[i]->Dof();
      const int* lmdof = nodes[i]->LMDof();
      for (int j=0; j<nodes[i]->Nlmdof(); ++j)
      {
        //cout << "j " << j << " maps lmdof " << lmdof[j] << " to dof " << dof[j] << endl;
        lm_to_dof[lmdof[j]] = dof[j];
      }
    }
  }
  lm_to_dof_ = Teuchos::rcp(new std::map<int,int>(lm_to_dof)); // this is a very useful map for the moertel_ml_preconditioner
  /*
               _              _
              |               |
              |  Arr  Arn  Mr | 
         S =  |               |
              |  Anr  Ann  D  | 
              |
              |  MrT  D    0  |
              |_          _   |

               _           _
              |            |
              |  Arr  Arn  | 
         A =  |            |
              |  Anr  Ann  | 
              |_          _|
  
        1) Ann is square and we need it's Range/DomainMap annmap
        
               _         _
        WT =  |_ 0 Dinv _|

        2) Build WT (has rowmap/rangemap annmap and domainmap problemmap_)
             
               _    _
              |     |
              |  Mr | 
         B =  |     |
              |  D  | 
              |_   _|
  
        3) Build B (has rowmap/rangemap problemmap_ and domainmap annmap)
        
        4) Build I, the identity matrix with maps problemmap_,problemmap_);
        
        After constructing WT ,B and I we can start building Atilde (spdmatrix_)
        
           Atilde = A + ( B WT - I) A W B^T + B WT A (W B^T - I)
           
        5) Build BWT = B * WT

        6) Build BWTmI = BWT - I

        7) Build BWTmIAWBT = BWTmI * A * W * B^T

        8) Allocate spdmatrix_  = A + BWTmIAWBT

        9) Build WBTmI = WT^T * B^T - I
        
        10) Build BWTAWBTmI = BWT * A * WBTmI and add to spdmatrix_
            Call FillComplete on spdmatrix_
            
        11) Build ImBWT = I - BWT and store it

  */    
  
  int err=0;
  //--------------------------------------------------------------------------
  // 1) create the rangemap of Ann
  std::vector<int> myanngids(problemmap_->NumMyElements());
  int count=0;
  std::map<int,int>::iterator intintcurr;
  for (intintcurr=lm_to_dof.begin(); intintcurr!=lm_to_dof.end(); ++intintcurr)
  {
    if (problemmap_->MyGID(intintcurr->second)==false) 
      continue;
    if ((int)myanngids.size()<=count) 
      myanngids.resize(myanngids.size()+50);
    myanngids[count] = intintcurr->second;
    ++count;
  }
  myanngids.resize(count);
    int numglobalelements;
  Comm().SumAll(&count,&numglobalelements,1);
  Epetra_Map* annmap = new Epetra_Map(numglobalelements,count,&myanngids[0],0,Comm());
  annmap_ = Teuchos::rcp(annmap);
  myanngids.clear();

#if 0
  //--------------------------------------------------------------------------
  // 1.5) split matrix into blocks Arr Arn Anr Ann
  Teuchos::RCP<Epetra_Map>       A11row = Teuchos::null;
  Teuchos::RCP<Epetra_Map>       A22row = annmap_;
  Teuchos::RCP<Epetra_CrsMatrix> A11    = Teuchos::null;
  Teuchos::RCP<Epetra_CrsMatrix> A12    = Teuchos::null;
  Teuchos::RCP<Epetra_CrsMatrix> A21    = Teuchos::null;
  Teuchos::RCP<Epetra_CrsMatrix> A22    = Teuchos::null;
  MOERTEL::SplitMatrix2x2(inputmatrix_,A11row,A22row,A11,A12,A21,A22);
#endif
  
#if 0
  //--------------------------------------------------------------------------
  // 1.7) create a shifted version of M and D
  Epetra_CrsMatrix* MTshifted = new Epetra_CrsMatrix(Copy,*annmap,1,false); 
  Epetra_CrsMatrix* Dshifted  = new Epetra_CrsMatrix(Copy,*annmap,1,false); 
  std::vector<int> gindices(500);
  for (intintcurr=lm_to_dof.begin(); intintcurr!=lm_to_dof.end(); ++intintcurr)
  {
    const int lmdof = intintcurr->first;
    const int dof   = intintcurr->second;
    if (D_->MyGRID(lmdof)==false)
      continue;
    const int lmlrid = D_->LRID(lmdof);
    int numentries;
    int* indices;
    double* values;
    
    // do D
    err = D_->ExtractMyRowView(lmlrid,numentries,values,indices);
    if (err) cout << "D_->ExtractMyRowView returned err=" << err << endl;
    if (numentries>(int)gindices.size()) gindices.resize(numentries);
    for (int j=0; j<numentries; ++j)
    {
      gindices[j] = D_->GCID(indices[j]);
      if (gindices[j]<0) cout << "Cannot find gcid for indices[j]\n";
    }
    err = Dshifted->InsertGlobalValues(dof,numentries,values,&gindices[0]);       
    if (err<0) cout << "Dshifted->InsertGlobalValues returned err=" << err << endl;
    
    // do MT
    err = M_->ExtractMyRowView(lmlrid,numentries,values,indices);
    if (err) cout << "M_->ExtractMyRowView returned err=" << err << endl;
    if (numentries>(int)gindices.size()) gindices.resize(numentries);
    for (int j=0; j<numentries; ++j)
    {
      gindices[j] = M_->GCID(indices[j]);
      if (gindices[j]<0) cout << "Cannot find gcid for indices[j]\n";
    }
    err = MTshifted->InsertGlobalValues(dof,numentries,values,&gindices[0]);       
    if (err<0) cout << "MTshifted->InsertGlobalValues returned err=" << err << endl;
    
  }
  gindices.clear();
  Dshifted->FillComplete(*problemmap_,*annmap);  
  Dshifted->OptimizeStorage();
  MTshifted->FillComplete(*problemmap_,*annmap);  
  MTshifted->OptimizeStorage();
  Dshifted_ = Teuchos::rcp(Dshifted);
  MTshifted_ = Teuchos::rcp(MTshifted);
#endif

  //--------------------------------------------------------------------------
  // 2) create WT, D and MT
  Epetra_CrsMatrix* WT        = new Epetra_CrsMatrix(Copy,*annmap,1,false); 
  for (intintcurr=lm_to_dof.begin(); intintcurr!=lm_to_dof.end(); ++intintcurr)
  {
    int lmdof = intintcurr->first;
    int dof   = intintcurr->second;
    if (D_->MyGRID(lmdof)==false)
      continue;
    int lmlrid = D_->LRID(lmdof);
    int numentries;
    int* indices;
    double* values;
    err = D_->ExtractMyRowView(lmlrid,numentries,values,indices);
    if (err) cout << "D_->ExtractMyRowView returned err=" << err << endl;
    bool foundit = false;
    for (int j=0; j<numentries; ++j)
    {
      int gcid = D_->GCID(indices[j]);
      if (gcid<0) cout << "Cannot find gcid for indices[j]\n";
      //cout << "Proc " << Comm().MyPID() << " lmdof " << lmdof << " dof " << dof << " gcid " << gcid << " val " << values[j] << endl;
      if (gcid==dof)
      {
        double val = 1./values[j];
        err = WT->InsertGlobalValues(dof,1,&val,&dof);
        if (err<0) cout << "WT->InsertGlobalValues returned err=" << err << endl;
        foundit = true;
        break;
      }
    }
    if (!foundit)
    {
      cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n"
           << "***ERR*** Cannot compute inverse of D_\n"
           << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n";
      cout << "lmdof " << lmdof << " dof " << dof << endl;
      return NULL;
    }  
  }
  WT->FillComplete(*problemmap_,*annmap);  
  WT_ = Teuchos::rcp(WT);

  //--------------------------------------------------------------------------
  // 3) create B
  // create a temporary matrix with rowmap of the Ann block
  Epetra_CrsMatrix* tmp = new Epetra_CrsMatrix(Copy,*annmap,120);
  std::vector<int> newindices(100);
  for (intintcurr=lm_to_dof.begin(); intintcurr!=lm_to_dof.end(); ++intintcurr)
  {
    int lmdof = intintcurr->first;
    int dof   = intintcurr->second;
    if (D_->MyGRID(lmdof)==false)
      continue;
    int lmlrid = D_->LRID(lmdof);
    if (lmlrid<0) cout << "Cannot find lmlrid for lmdof\n";
    int numentries;
    int* indices;
    double* values;
    
    // extract and add values from D
    err = D_->ExtractMyRowView(lmlrid,numentries,values,indices);
    if (err) cout << "D_->ExtractMyRowView returned err=" << err << endl;
    if (numentries>(int)newindices.size()) newindices.resize(numentries);
    for (int j=0; j<numentries; ++j)
    {
      newindices[j] = D_->GCID(indices[j]);
      if (newindices[j]<0) cout << "Cannot find gcid for indices[j]\n";
    }
    //cout << "Inserting from D in row " << dof << " cols/val ";
    //for (int j=0; j<numentries; ++j) cout << newindices[j] << "/" << values[j] << " ";
    //cout << endl;
    err = tmp->InsertGlobalValues(dof,numentries,values,&newindices[0]);
    if (err) cout << "tmp->InsertGlobalValues returned err=" << err << endl;
  
    // extract and add values from M
    err = M_->ExtractMyRowView(lmlrid,numentries,values,indices);
    if (err) cout << "M_->ExtractMyRowView returned err=" << err << endl;
    if (numentries>(int)newindices.size()) newindices.resize(numentries);
    for (int j=0; j<numentries; ++j)
    {
      newindices[j] = M_->GCID(indices[j]);
      if (newindices[j]<0) cout << "Cannot find gcid for indices[j]\n";
    }
    //cout << "Inserting from M in row " << dof << " cols/val ";
    //for (int j=0; j<numentries; ++j) cout << newindices[j] << "/" << values[j] << " ";
    //cout << endl;
    err = tmp->InsertGlobalValues(dof,numentries,values,&newindices[0]);
    if (err) cout << "tmp->InsertGlobalValues returned err=" << err << endl;
  }
  tmp->FillComplete(*(problemmap_.get()),*annmap);

  // B is transposed of tmp
  EpetraExt::RowMatrix_Transpose* trans = new EpetraExt::RowMatrix_Transpose(false);
  Epetra_CrsMatrix* B = &(dynamic_cast<Epetra_CrsMatrix&>(((*trans)(const_cast<Epetra_CrsMatrix&>(*tmp)))));
  delete tmp; tmp = NULL;
  B_ = Teuchos::rcp(new Epetra_CrsMatrix(*B));
  newindices.clear();

  //--------------------------------------------------------------------------
  // 4) create I
  Epetra_CrsMatrix* I = new Epetra_CrsMatrix(Copy,*problemmap_,1,true);
  for (int i=0; i<I->NumMyRows(); ++i)
  {
    double one = 1.0;
    int grid = I->GRID(i);
    if (grid<0) cout << "Cannot find grid for i\n";
    err = I->InsertGlobalValues(grid,1,&one,&grid);
    if (err<0) cout << "I->InsertGlobalValues returned err=" << err << endl;
  }
  I->FillComplete(*problemmap_,*problemmap_);
  I_ = Teuchos::rcp(I);
  //--------------------------------------------------------------------------
  // 5) Build BWT = B * WT
  Epetra_CrsMatrix* BWT = MOERTEL::MatMatMult(*B,false,*WT,false,OutLevel()); 
  
  //--------------------------------------------------------------------------
  // 6) Build BWTmI = BWT - I
  Epetra_CrsMatrix* BWTmI = new Epetra_CrsMatrix(Copy,*problemmap_,10,false);
  MOERTEL::MatrixMatrixAdd(*BWT,false,1.0,*BWTmI,0.0);
  MOERTEL::MatrixMatrixAdd(*I,false,-1.0,*BWTmI,1.0);
  BWTmI->FillComplete();
  
  //--------------------------------------------------------------------------
  // 7) Build BWTmIAWBT = BWTmI * A * W * B^T
  Epetra_CrsMatrix* BWTmIA = MOERTEL::MatMatMult(*BWTmI,false,*inputmatrix_,false,OutLevel());
  Epetra_CrsMatrix* WBT    = MOERTEL::MatMatMult(*WT,true,*B,true,OutLevel());
  Epetra_CrsMatrix* BWTmIAWBT = MOERTEL::MatMatMult(*BWTmIA,false,*WBT,false,OutLevel());
  delete BWTmIA; BWTmIA = NULL;
  
  //--------------------------------------------------------------------------
  // 8) Allocate spdmatrix_ and add A and BWTmIAWBT
  spdmatrix_ = Teuchos::rcp(new Epetra_CrsMatrix(Copy,*problemmap_,10,false));
  MOERTEL::MatrixMatrixAdd(*BWTmIAWBT,false,1.0,*spdmatrix_,0.0);
  delete BWTmIAWBT; BWTmIAWBT = NULL;
  MOERTEL::MatrixMatrixAdd(*inputmatrix_,false,1.0,*spdmatrix_,1.0);
  
  //--------------------------------------------------------------------------
  // 9) Build WBTmI = WT^T * B^T - I
  Epetra_CrsMatrix* WBTmI = new Epetra_CrsMatrix(Copy,*problemmap_,10,false);
  MOERTEL::MatrixMatrixAdd(*I,false,-1.0,*WBTmI,0.0);
  MOERTEL::MatrixMatrixAdd(*WBT,false,1.0,*WBTmI,1.0);
  WBTmI->FillComplete();
  delete WBT; WBT = NULL;
  
  //--------------------------------------------------------------------------
  // 10) Build BWTAWBTmI = BWT * A * WBTmI and add to spdmatrix_
  Epetra_CrsMatrix* BWTA      = MOERTEL::MatMatMult(*BWT,false,*inputmatrix_,false,OutLevel()); 
  Epetra_CrsMatrix* BWTAWBTmI = MOERTEL::MatMatMult(*BWTA,false,*WBTmI,false,OutLevel()); 
  delete BWTA; BWTA = NULL;
  delete WBTmI; WBTmI = NULL;
  MOERTEL::MatrixMatrixAdd(*BWTAWBTmI,false,1.0,*spdmatrix_,1.0);
  delete BWTAWBTmI; BWTAWBTmI = NULL;
  spdmatrix_->FillComplete(); 
  spdmatrix_->OptimizeStorage();

  //--------------------------------------------------------------------------
  // 11) Build ImBWT = I - BWT and store it as spdrhs_
  spdrhs_ = Teuchos::rcp(new Epetra_CrsMatrix(Copy,*problemmap_,10,false));
  MOERTEL::MatrixMatrixAdd(*I,false,1.0,*spdrhs_,0.0); 
  //delete I; I = NULL;
  MOERTEL::MatrixMatrixAdd(*BWT,false,-1.0,*spdrhs_,1.0);  
  delete BWT; BWT = NULL;
  spdrhs_->FillComplete(); 
  spdrhs_->OptimizeStorage();
   
  //--------------------------------------------------------------------------
  // tidy up
  lm_to_dof.clear();
  //delete annmap;
  //delete WT; WT = NULL;
  delete trans; B = NULL;

  // time this process
  double t = time.ElapsedTime();
  if (OutLevel()>5 && Comm().MyPID()==0)
    cout << "MOERTEL (Proc 0): Construct spd system in " << t << " sec\n";

  return spdmatrix_.get();
}
bool FiniteDifferenceColoringWithUpdate::differenceProbe(const Epetra_Vector& x, Epetra_CrsMatrix& jac,const Epetra_MapColoring& colors){

  // Allocate space for perturbation, get column version of x for scaling
  Epetra_Vector xp(x);
  Epetra_Vector *xcol;
  int N=jac.NumMyRows();

  if(jac.ColMap().SameAs(x.Map()))
     xcol=const_cast<Epetra_Vector*>(&x);
  else{
    xcol=new Epetra_Vector(jac.ColMap(),true);//zeros out by default
    xcol->Import(x,*jac.Importer(),InsertAdd);
  }

  // Counters for probing diagnostics
  double tmp,probing_error_lower_bound=0.0,jc_norm=0.0;

  // Grab coloring info (being very careful to ignore color 0)
  int Ncolors=colors.MaxNumColors()+1;
  int num_c0_global,num_c0_local=colors.NumElementsWithColor(0);
  colors.Comm().MaxAll(&num_c0_local,&num_c0_global,1);
  if(num_c0_global>0) Ncolors--;

  if(Ncolors==0) return false;

  // Pointers for Matrix Info
  int entries, *indices;
  double *values;

  // NTS: Fix me
  if ( diffType == Centered ) exit(1);

  double scaleFactor = 1.0;
  if ( diffType == Backward )
    scaleFactor = -1.0;

  // Compute RHS at initial solution
  computeF(x,fo,NOX::Epetra::Interface::Required::FD_Res);

  /* Probing, vector by vector since computeF does not have a MultiVector interface */
  // Assume that anything with Color 0 gets ignored.
  for(int j=1;j<Ncolors;j++){
    xp=x;
    for(int i=0;i<N;i++){
      if(colors[i]==j)
    xp[i] += scaleFactor*(alpha*abs(x[i])+beta);
    }

    computeF(xp, fp, NOX::Epetra::Interface::Required::FD_Res);

    // Do the subtraction to estimate the Jacobian (w/o including step length)
    Jc.Update(1.0, fp, -1.0, fo, 0.0);

    // Relative error in probing
     if(use_probing_diags){
       Jc.Norm2(&tmp);
       jc_norm+=tmp*tmp;
     }

    for(int i=0;i<N;i++){
      // Skip for uncolored row/columns, else update entries
      if(colors[i]==0) continue;

      jac.ExtractMyRowView(i,entries,values,indices);
      for(int k=0;k<jac.NumMyEntries(i);k++){
    if(colors[indices[k]]==j){
      values[k]=Jc[i] / (scaleFactor*(alpha*abs((*xcol)[indices[k]])+beta));
      // If probing diagnostics are on, zero out the entries as they are used
      if(use_probing_diags) Jc[i]=0.0;
      break;// Only one value per row...
    }
      }
    }
    if(use_probing_diags){
      Jc.Norm2(&tmp);
      probing_error_lower_bound+=tmp*tmp;
    }
  }

  // If diagnostics are requested, output Frobenius norm lower bound
  if(use_probing_diags && !x.Comm().MyPID()) printf("Probing Error Lower Bound (Frobenius) abs = %6.4e rel = %6.4e\n",sqrt(probing_error_lower_bound),sqrt(probing_error_lower_bound)/sqrt(jc_norm));

  // Cleanup
  if(!jac.ColMap().SameAs(x.Map()))
    delete xcol;

  return true;
}
Esempio n. 14
0
int main(int argc, char *argv[])
{

#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif

  // get the epetra matrix from the Gallery
  int nx = 8;
  int ny = 8 * Comm.NumProc();

  ParameterList GaleriList;
  GaleriList.set("nx", nx);
  GaleriList.set("ny", ny);
  GaleriList.set("mx", 1);
  GaleriList.set("my", Comm.NumProc());

  Epetra_Map* Map = CreateMap("Cartesian2D", Comm, GaleriList);
  Epetra_CrsMatrix* A = CreateCrsMatrix("Laplace2D", Map, GaleriList);

  Epetra_Vector LHS(*Map); LHS.Random();
  Epetra_Vector RHS(*Map); RHS.PutScalar(0.0);

  Epetra_LinearProblem Problem(A, &LHS, &RHS);

  AztecOO solver(Problem);

  Init();

  try {

    Space S(-1, A->NumMyRows(), A->RowMatrixRowMap().MyGlobalElements());
    Operator A_MLAPI(S, S, A, false);

    Teuchos::ParameterList MLList;
    MLList.set("max levels",3);
    MLList.set("increasing or decreasing","increasing");
    MLList.set("aggregation: type", "Uncoupled");
    MLList.set("aggregation: damping factor", 0.0);
    MLList.set("smoother: type","symmetric Gauss-Seidel");
    MLList.set("smoother: sweeps",1);
    MLList.set("smoother: damping factor",1.0);
    MLList.set("coarse: max size",3);
    MLList.set("smoother: pre or post", "both");
    MLList.set("coarse: type","Amesos-KLU");

    MultiLevelSA Prec_MLAPI(A_MLAPI, MLList);

    Epetra_Operator* Prec = new EpetraBaseOperator(A->RowMatrixRowMap(), Prec_MLAPI);

    solver.SetPrecOperator(Prec);
    solver.SetAztecOption(AZ_solver, AZ_cg_condnum);
    solver.SetAztecOption(AZ_output, 32);
    solver.Iterate(500, 1e-12);

    // destroy the preconditioner
    delete Prec;

  }
  catch (const int e) {
    cerr << "Caught exception, code = " << e << endl;
  }
  catch (...) {
    cerr << "Caught exception..." << endl;
  }

  Finalize();

  // compute the real residual

  double residual;
  LHS.Norm2(&residual);

  if( Comm.MyPID()==0 ) {
    cout << "||b-Ax||_2 = " << residual << endl;
  }

  delete A;
  delete Map;

  // for testing purposes
  if (residual > 1e-5)
    exit(EXIT_FAILURE);

#ifdef HAVE_MPI
  MPI_Finalize();
#endif

  return(EXIT_SUCCESS);
}
Esempio n. 15
0
int main(int argc, char *argv[]) {

  int i;

#ifdef EPETRA_MPI
  // Initialize MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm comm;
#endif

  // Uncomment to debug in parallel int tmp; if (comm.MyPID()==0) cin >> tmp; comm.Barrier();

  bool verbose = false;
  bool veryVerbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;

  if (!verbose) comm.SetTracebackMode(0); // This should shut down any error traceback reporting

  if (verbose) cout << comm << endl << flush;

  bool verbose1 = verbose;
  if (verbose) verbose = (comm.MyPID()==0);

  int nx = 4;
  int ny = comm.NumProc()*nx; // Scale y grid with number of processors
  
  // Create funky stencil to make sure the matrix is non-symmetric (transpose non-trivial):

  // (i-1,j-1) (i-1,j  )
  // (i  ,j-1) (i  ,j  ) (i  ,j+1)
  // (i+1,j-1) (i+1,j  )
  
  int npoints = 2;

  int xoff[] = {-1,  0,  1, -1,  0,  1,  0};
  int yoff[] = {-1, -1, -1,  0,  0,  0,  1};

  Epetra_Map * map;
  Epetra_CrsMatrix * A;
  Epetra_Vector * x, * b, * xexact;
	
  Trilinos_Util_GenerateCrsProblem(nx, ny, npoints, xoff, yoff, comm, map, A, x, b, xexact);

  if (verbose) 
    cout << "npoints = " << npoints << " nx = " << nx << " ny = " << ny  << endl ; 

  if (verbose && nx<6 ) {
    cout << *A << endl;
    cout << "B       = " << endl << *b << endl;
  }
  // Construct linear problem object
  
  Epetra_LinearProblem origProblem(A, x, b);
  Epetra_LinearProblem *redistProblem;
  
  Epetra_Time timer(comm);
  
  // Construct redistor object, use all processors and replicate full problem on each

  double start = timer.ElapsedTime();
  Epetra_LinearProblemRedistor redistor(&origProblem, comm.NumProc(), true);
  if (verbose) cout << "\nTime to construct redistor  = " 
		    << timer.ElapsedTime() - start << endl;

  bool ConstructTranspose = true; 
  bool MakeDataContiguous = true;
  
  start = timer.ElapsedTime();
  redistor.CreateRedistProblem(ConstructTranspose, MakeDataContiguous, redistProblem);
  if (verbose) cout << "\nTime to create redistributed problem = " 
		    << timer.ElapsedTime() - start << endl;
  
  
  // Now test output of redistor by performing matvecs

  int ierr = 0;
  ierr += checkResults( ConstructTranspose, &redistor, &origProblem, 
			redistProblem, verbose);
  
  
  // Now change values in original rhs and test update facility of redistor
  // Multiply b by 2
  
  double Value = 2.0;
  
  b->Scale(Value); // b = 2*b
  
  redistor.UpdateRedistRHS(b);
  if (verbose) cout << "\nTime to update redistributed RHS  = " 
		    << timer.ElapsedTime() - start << endl;
  
  ierr += checkResults( ConstructTranspose, &redistor, 
			&origProblem, redistProblem, verbose);
 
  // Now change values in original matrix and test update facility of redistor

#define  CREATE_CONST_MATRIX
#ifdef CREATE_CONST_MATRIX
  //  The easiest way that I could find to change the matrix without EPETRA_CHK_ERRs
  A->PutScalar(13.0); 
#else 

  //  This has no effect on matrices, such as when nx = 4, that have no 
  //  diagonal entries.  However, it does cause many EPETRA_CHK_ERR prints.

  // Add 2 to the diagonal of each row 
  for (i=0; i< A->NumMyRows(); i++)  {
  //  for (i=0; i < 1; i++)
    cout << " i = " << i ; 
    A->SumIntoMyValues(i, 1, &Value, &i);
  }
#endif  
  
  
  start = timer.ElapsedTime();
  redistor.UpdateRedistProblemValues(&origProblem);
  if (verbose) cout << "\nTime to update redistributed problem  = " 
		    << timer.ElapsedTime() - start << endl;
  
  ierr += checkResults(ConstructTranspose, &redistor, &origProblem, redistProblem, verbose);
  
  delete A;
  delete b;
  delete x;
  delete xexact;
  delete map;
  
  
#ifdef EPETRA_MPI
  MPI_Finalize();
#endif

  return ierr;
}
Esempio n. 16
0
int main(int argc, char *argv[])
{
  
#ifdef EPETRA_MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif

  Epetra_Time Time(Comm);

  // Create the linear problem using the class `Trilinos_Util::CrsMatrixGallery.'
  // Various matrix examples are supported; please refer to the
  // Trilinos tutorial for more details.
  
  // create Aztec stuff
  int    proc_config[AZ_PROC_SIZE], options[AZ_OPTIONS_SIZE];
#ifdef ML_MPI
  /* get number of processors and the name of this processor */
  AZ_set_proc_config(proc_config, MPI_COMM_WORLD);
  int proc   = proc_config[AZ_node];
  int nprocs = proc_config[AZ_N_procs];
#else
  AZ_set_proc_config(proc_config, AZ_NOT_MPI);
  int proc   = 0;
  int nprocs = 1;
#endif
  // read in the matrix size
  FILE *fp = fopen("ExampleMatrices/cantilever2D/data_matrix.txt","r");
  int leng;
  fscanf(fp,"%d",&leng);
  int num_PDE_eqns=2;
  int N_grid_pts = leng/num_PDE_eqns;

  // make a linear distribution of the matrix respecting the blocks size
  int leng1 = leng/nprocs;
  int leng2 = leng-leng1*nprocs;
  if (proc >= leng2)
  {
     leng2 += (proc*leng1);
  }
  else
  {
     leng1++;
     leng2 = proc*leng1;
  }
  int     N_update = leng1;
  int*    update  = new int[N_update+1];
  int     i;
  double *val=NULL;
  int    *bindx=NULL;
  for (i=0; i<N_update; i++) update[i] = i+leng2;
  
  // create the Epetra_CrSMatrix
  Epetra_Map*        StandardMap = new Epetra_Map(leng,N_update,update,0,Comm);
  Epetra_CrsMatrix*  A           = new Epetra_CrsMatrix(Copy,*StandardMap,1);
  
  AZ_input_msr_matrix("ExampleMatrices/cantilever2D/data_matrix.txt",
                      update, &val, &bindx, N_update, proc_config);

  
  for (i=0; i<leng; i++)
  {
    int row = update[i];
    A->SumIntoGlobalValues(row,1,&(val[i]),&row);
    A->SumIntoGlobalValues(row,bindx[i+1]-bindx[i],&(val[bindx[i]]),&(bindx[bindx[i]]));
  }
  A->TransformToLocal();
  
  // create solution and right-hand side (MultiVectors are fine as well)
  Epetra_Vector* LHS = new Epetra_Vector(A->OperatorDomainMap());
  Epetra_Vector* RHS = new Epetra_Vector(A->OperatorRangeMap());
  LHS->Random();
  RHS->Random();

  // build the epetra linear problem
  Epetra_LinearProblem Problem(A, LHS, RHS);
  
  // Construct a solver object for this problem
  AztecOO solver(Problem);

  // =========================== begin of ML part ===========================
  
  // create a parameter list for ML options
  ParameterList MLList;

  // set defaults for classic smoothed aggregation
  ML_Epetra::SetDefaults("SA",MLList);
  MLList.set("aggregation: damping factor", 0.0);

  // number of relaxation sweeps
  MLList.set("adaptive: max sweeps", 10);
  // number of additional null space vectors to compute
  MLList.set("adaptive: num vectors",2);

#if 1
  ML_Epetra::MultiLevelPreconditioner* MLPrec = 
    new ML_Epetra::MultiLevelPreconditioner(dynamic_cast<Epetra_RowMatrix&>(*A), MLList, false);

  // need to allocate and fill the null space (also the
  // default one, as in this case). This vector is no longer
  // needed after a call to ComputeAdaptivePreconditioner().
  int NullSpaceSize = 2;
  vector<double> NullSpace((NullSpaceSize*A->NumMyRows()));
  for (i = 0 ; i < A->NumMyRows() ; ++i)
  {
    NullSpace[i] = 1.0;
    ++i;
    NullSpace[i] = 0.0;
  }
  for (i = A->NumMyRows() ; i < 2*A->NumMyRows() ; ++i)
  {
    NullSpace[i] = 0.0;
    ++i;
    NullSpace[i] = 1.0;
  }

  MLPrec->ComputeAdaptivePreconditioner(NullSpaceSize,&NullSpace[0]);
#else
  ML_Epetra::MultiLevelPreconditioner* MLPrec = 
    new ML_Epetra::MultiLevelPreconditioner(dynamic_cast<Epetra_RowMatrix&>(*A), MLList);
#endif

  // tell AztecOO to use this preconditioner, then solve
  solver.SetPrecOperator(MLPrec);

  // =========================== end of ML part =============================
  
  solver.SetAztecOption(AZ_solver, AZ_gmres);
  solver.SetAztecOption(AZ_output, 32);

  // solve with 500 iterations and 1e-12 tolerance  
  solver.Iterate(1550, 1e-5);

  delete MLPrec;
  
  // compute the real residual

  double residual, diff;
  
  if( Comm.MyPID()==0 ) {
    cout << "||b-Ax||_2 = " << residual << endl;
    cout << "||x_exact - x||_2 = " << diff << endl;
    cout << "Total Time = " << Time.ElapsedTime() << endl;
  }

#ifdef EPETRA_MPI
  MPI_Finalize();
#endif

  return(0);
  
}
Esempio n. 17
0
int check(Epetra_CrsMatrix& A, int NumMyRows1, int NumGlobalRows1, int NumMyNonzeros1,
					int NumGlobalNonzeros1, int* MyGlobalElements, bool verbose) 
{  
  (void)MyGlobalElements;
  int ierr = 0, forierr = 0;
  int NumGlobalIndices;
  int NumMyIndices;
	int* MyViewIndices = 0;
	int* GlobalViewIndices = 0;
  double* MyViewValues = 0;
	double* GlobalViewValues = 0;
  int MaxNumIndices = A.Graph().MaxNumIndices();
  int* MyCopyIndices = new int[MaxNumIndices];
  int* GlobalCopyIndices = new int[MaxNumIndices];
  double* MyCopyValues = new double[MaxNumIndices];
  double* GlobalCopyValues = new double[MaxNumIndices];

  // Test query functions

  int NumMyRows = A.NumMyRows();
  if (verbose) cout << "\n\nNumber of local Rows = " << NumMyRows << endl<< endl;

  EPETRA_TEST_ERR(!(NumMyRows==NumMyRows1),ierr);

  int NumMyNonzeros = A.NumMyNonzeros();
  if (verbose) cout << "\n\nNumber of local Nonzero entries = " << NumMyNonzeros << endl<< endl;

  EPETRA_TEST_ERR(!(NumMyNonzeros==NumMyNonzeros1),ierr);

  int NumGlobalRows = A.NumGlobalRows();
  if (verbose) cout << "\n\nNumber of global Rows = " << NumGlobalRows << endl<< endl;

  EPETRA_TEST_ERR(!(NumGlobalRows==NumGlobalRows1),ierr);

  int NumGlobalNonzeros = A.NumGlobalNonzeros();
  if (verbose) cout << "\n\nNumber of global Nonzero entries = " << NumGlobalNonzeros << endl<< endl;

  EPETRA_TEST_ERR(!(NumGlobalNonzeros==NumGlobalNonzeros1),ierr);

  // GlobalRowView should be illegal (since we have local indices)

  EPETRA_TEST_ERR(!(A.ExtractGlobalRowView(A.RowMap().MaxMyGID(), NumGlobalIndices, GlobalViewValues, GlobalViewIndices)==-2),ierr);

  // Other binary tests

  EPETRA_TEST_ERR(A.NoDiagonal(),ierr);
  EPETRA_TEST_ERR(!(A.Filled()),ierr);
  EPETRA_TEST_ERR(!(A.MyGRID(A.RowMap().MaxMyGID())),ierr);
  EPETRA_TEST_ERR(!(A.MyGRID(A.RowMap().MinMyGID())),ierr);
  EPETRA_TEST_ERR(A.MyGRID(1+A.RowMap().MaxMyGID()),ierr);
  EPETRA_TEST_ERR(A.MyGRID(-1+A.RowMap().MinMyGID()),ierr);
  EPETRA_TEST_ERR(!(A.MyLRID(0)),ierr);
  EPETRA_TEST_ERR(!(A.MyLRID(NumMyRows-1)),ierr);
  EPETRA_TEST_ERR(A.MyLRID(-1),ierr);
  EPETRA_TEST_ERR(A.MyLRID(NumMyRows),ierr);

  forierr = 0;
  for (int i = 0; i < NumMyRows; i++) {
    int Row = A.GRID(i);
    A.ExtractGlobalRowCopy(Row, MaxNumIndices, NumGlobalIndices, GlobalCopyValues, GlobalCopyIndices);
    A.ExtractMyRowView(i, NumMyIndices, MyViewValues, MyViewIndices); // this is where the problem comes from
    forierr += !(NumGlobalIndices == NumMyIndices);
    for(int j = 1; j < NumMyIndices; j++) {
			forierr += !(MyViewIndices[j-1] < MyViewIndices[j]); // this is where the test fails
		}
    for(int j = 0; j < NumGlobalIndices; j++) {
			forierr += !(GlobalCopyIndices[j] == A.GCID(MyViewIndices[j]));
			forierr += !(A.LCID(GlobalCopyIndices[j]) == MyViewIndices[j]);
			forierr += !(GlobalCopyValues[j] == MyViewValues[j]);
    }
  }
  EPETRA_TEST_ERR(forierr,ierr);

  forierr = 0;
  for (int i = 0; i < NumMyRows; i++) {
    int Row = A.GRID(i);
    A.ExtractGlobalRowCopy(Row, MaxNumIndices, NumGlobalIndices, GlobalCopyValues, GlobalCopyIndices);
    A.ExtractMyRowCopy(i, MaxNumIndices, NumMyIndices, MyCopyValues, MyCopyIndices);
    forierr += !(NumGlobalIndices == NumMyIndices);
    for (int j = 1; j < NumMyIndices; j++) 
			forierr += !(MyCopyIndices[j-1] < MyCopyIndices[j]);
    for (int j = 0; j < NumGlobalIndices; j++) {
			forierr += !(GlobalCopyIndices[j] == A.GCID(MyCopyIndices[j]));
			forierr += !(A.LCID(GlobalCopyIndices[j]) == MyCopyIndices[j]);
			forierr += !(GlobalCopyValues[j] == MyCopyValues[j]);
    }

  }
  EPETRA_TEST_ERR(forierr,ierr);

  delete [] MyCopyIndices;
  delete [] GlobalCopyIndices;
  delete [] MyCopyValues;
  delete [] GlobalCopyValues;

  if (verbose) cout << "\n\nRows sorted check OK" << endl<< endl;

  return (ierr);
}
Esempio n. 18
0
int
NOX::Epetra::TestCompare::testCrsMatrices(
         const Epetra_CrsMatrix& mat          ,
         const Epetra_CrsMatrix& mat_expected ,
         double rtol, double atol             ,
         const std::string& name              ,
                 bool enforceStructure                  )
{
  if (utils.isPrintType(NOX::Utils::TestDetails))
    os << std::endl << "\tChecking " << name << ":  ";

  int passed = 0;

  if( !mat_expected.RowMap().SameAs( mat.RowMap() ) )
  {
    passed = 1;

    os << "Failed." << std::endl;
    os << std::endl << "\t\tRow maps are not compatible." << std::endl;

    return passed;
  }

  int      numEntries1,   numEntries2 ;
  int    * columns1   , * columns2    ;
  double * values1    , * values2     ;

  int    chkSize = 0   ;
  double maxVal  = 0.0 ;
  double infNorm = 0.0 ;

  for( int row = 0; row < mat_expected.NumMyRows(); ++row )
  {
    mat_expected.ExtractMyRowView(row, numEntries1, values1, columns1);
    mat.ExtractMyRowView         (row, numEntries2, values2, columns2);

    if( numEntries1 != numEntries2 )
    {
      if( enforceStructure )
      {
        os << std::endl << "\t\t\t";
      }
      else
        os << std::endl << "\t\tWARNING: ";

      os << "Matrix size is incompatible for Local Row " << row
         << "\n\t\t\t..... expected " << numEntries1 << " columns, found " << numEntries2
         << std::endl;

      chkSize = 1;
    }

    mat.Comm().SumAll( &chkSize, &passed, 1 );

    if( 0 != passed )
    {
      if( enforceStructure )
      {
        os << "Failed." << std::endl;
        return passed;
      }
      else
      {
        chkSize = 0;
        passed  = 0;
      }
    }


    // Comapre column indices and values
    int    baseCol = 0   ;
    int    testCol = 0   ;
    int    chkCol  = 0   ;
    double baseVal = 0.0 ;
    double testVal = 0.0 ;
    double chkVal  = 0.0 ;

    for( int col = 0; col < numEntries1; ++col )
    {
      baseCol = columns1[col];
      testCol = columns2[col];
      baseVal = values1 [col];
      testVal = values2 [col];

      if( baseCol != testCol )
      {
        if( enforceStructure )
        {
          os << std::endl << "\t\t\t";
        }
        else
          os << std::endl << "\t\tWARNING: ";

        os << "Column index for Local Row " << row << " is incompatible."
           << "\n\t\t\t..... expected " << baseCol << " , found " << testCol << std::endl;

        chkCol = 1;
      }

      mat.Comm().SumAll( &chkCol, &passed, 1 );

      if( 0 != passed )
      {
        if( enforceStructure )
        {
          os << "Failed." << std::endl;
          return passed;
        }
        else
        {
          chkCol = 0;
          passed = 0;
          continue; // skip pvalue check
        }
      }

      chkVal = fabs( testVal - baseVal ) / (atol + rtol * fabs(baseVal));

      mat.Comm().MaxAll( &chkVal, &maxVal, 1 );
      if( maxVal > infNorm )
        infNorm = maxVal;

      if( 1 < maxVal )
        break;
    }

    if( 1 < maxVal )
      break;
  }

  if( 1 < maxVal )
    passed = 1; // false by convention in NOX::TestCompare
  else
    passed = 0; // true by convention in NOX::TestCompare

  if (utils.isPrintType(NOX::Utils::TestDetails))
  {
    if( 0 == passed)
      os << "Passed." << std::endl;
    else
      os << "Failed." << std::endl;

    os << "\t\tComputed norm:        " << utils.sciformat(infNorm)
       << std::endl
       << "\t\tRelative Tolerance:   " << utils.sciformat(rtol)
       << std::endl
       << "\t\tAbsolute Tolerance:   " << utils.sciformat(rtol)
       << std::endl;
  }

  return passed;
}
Esempio n. 19
0
int main(int argc, char *argv[])
{

#ifdef HAVE_MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm Comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm Comm;
#endif

#define ML_SCALING
#ifdef ML_SCALING
   const int ntimers=4;
   enum {total, probBuild, precBuild, solve};
   ml_DblLoc timeVec[ntimers], maxTime[ntimers], minTime[ntimers];

  for (int i=0; i<ntimers; i++) timeVec[i].rank = Comm.MyPID();
  timeVec[total].value = MPI_Wtime();
#endif

  int nx;
  if (argc > 1) nx = (int) strtol(argv[1],NULL,10);
  else          nx = 256;

  if (nx < 1) nx = 256; // input a nonpositive integer if you want to specify
                        // the XML input file name.
  nx = nx*(int)sqrt((double)Comm.NumProc());
  int ny = nx;

  printf("nx = %d\nny = %d\n",nx,ny);
  fflush(stdout);

  char xmlFile[80];
  bool readXML=false;
  if (argc > 2) {strcpy(xmlFile,argv[2]); readXML = true;}
  else sprintf(xmlFile,"%s","params.xml");

  ParameterList GaleriList;
  GaleriList.set("nx", nx);
  GaleriList.set("ny", ny);

#ifdef ML_SCALING
  timeVec[probBuild].value = MPI_Wtime();
#endif
  Epetra_Map* Map = CreateMap("Cartesian2D", Comm, GaleriList);
  Epetra_CrsMatrix* A = CreateCrsMatrix("Laplace2D", Map, GaleriList);

  if (!Comm.MyPID()) printf("nx = %d, ny = %d, mx = %d, my = %d\n",nx,ny,GaleriList.get("mx",-1),GaleriList.get("my",-1));
  fflush(stdout);
  //avoid potential overflow
  double numMyRows = A->NumMyRows();
  double numGlobalRows;
  Comm.SumAll(&numMyRows,&numGlobalRows,1);
  if (!Comm.MyPID()) printf("# global rows = %1.0f\n",numGlobalRows);
  //printf("pid %d: #rows = %d\n",Comm.MyPID(),A->NumMyRows());
  fflush(stdout);

  Epetra_MultiVector *coords = CreateCartesianCoordinates("2D", Map,GaleriList);
  double *x_coord=0,*y_coord=0,*z_coord=0;
  double **ttt;
  if (!coords->ExtractView(&ttt)) {
    x_coord = ttt[0];
    y_coord = ttt[1];
  } else {
    if (!Comm.MyPID()) printf("Error extracting coordinate vectors\n");
    MPI_Finalize();
    exit(EXIT_FAILURE);
  }

  Epetra_Vector LHS(*Map); LHS.Random();
  Epetra_Vector RHS(*Map); RHS.PutScalar(0.0);
  Epetra_LinearProblem Problem(A, &LHS, &RHS);
  AztecOO solver(Problem);

#ifdef ML_SCALING
  timeVec[probBuild].value = MPI_Wtime() - timeVec[probBuild].value;
#endif

  // =========================== begin of ML part ===========================

#ifdef ML_SCALING
  timeVec[precBuild].value = MPI_Wtime();
#endif
  ParameterList MLList;

  if (readXML) {
    MLList.set("read XML",true);
    MLList.set("XML input file",xmlFile);
  }
  else {
    cout << "here" << endl;
    ML_Epetra::SetDefaults("SA",MLList);
    MLList.set("smoother: type","Chebyshev");
    MLList.set("smoother: sweeps",3);
    MLList.set("coarse: max size",1);
  }

  MLList.set("x-coordinates", x_coord);
  MLList.set("y-coordinates", y_coord);
  MLList.set("z-coordinates", z_coord);

/*
RCP<std::vector<int> >
   m_smootherAztecOptions = rcp(new std::vector<int>(AZ_OPTIONS_SIZE));
RCP<std::vector<double> >
   m_smootherAztecParams = rcp(new std::vector<double>(AZ_PARAMS_SIZE));
//int             m_smootherAztecOptions[AZ_OPTIONS_SIZE];
//double          m_smootherAztecParams[AZ_PARAMS_SIZE];

std::string smootherType("Aztec");
AZ_defaults(&(*m_smootherAztecOptions)[0],&(*m_smootherAztecParams)[0]);
(*m_smootherAztecOptions)[AZ_precond]         = AZ_dom_decomp;
(*m_smootherAztecOptions)[AZ_subdomain_solve] = AZ_icc;
bool smootherAztecAsSolver = true;
*/
  MLList.set("ML output",10);

  MLList.set("repartition: enable",1);
  MLList.set("repartition: max min ratio",1.3);
  MLList.set("repartition: min per proc",200);
  MLList.set("repartition: partitioner","Zoltan");
  MLList.set("repartition: Zoltan dimensions",2);
  MLList.set("repartition: put on single proc",1);
  MLList.set("repartition: Zoltan type","hypergraph");
  MLList.set("repartition: estimated iterations",13);

/*
MLList.set("smoother: Aztec options",m_smootherAztecOptions);
MLList.set("smoother: Aztec params",m_smootherAztecParams);
MLList.set("smoother: type",smootherType.c_str());
MLList.set("smoother: Aztec as solver", smootherAztecAsSolver);

MLList.set("ML print initial list", 0);
MLList.set("ML print final list", 0);
*/

  ML_Epetra::MultiLevelPreconditioner* MLPrec =
    new ML_Epetra::MultiLevelPreconditioner(*A, MLList);

  // verify unused parameters on process 0 (put -1 to print on all
  // processes)
  MLPrec->PrintUnused(0);
#ifdef ML_SCALING
  timeVec[precBuild].value = MPI_Wtime() - timeVec[precBuild].value;
#endif

  // =========================== end of ML part =============================

#ifdef ML_SCALING
  timeVec[solve].value = MPI_Wtime();
#endif
  solver.SetPrecOperator(MLPrec);
  solver.SetAztecOption(AZ_solver, AZ_cg);
  solver.SetAztecOption(AZ_output, 1);
  solver.Iterate(500, 1e-12);
#ifdef ML_SCALING
  timeVec[solve].value = MPI_Wtime() - timeVec[solve].value;
#endif

  // destroy the preconditioner
  delete MLPrec;

  // compute the real residual

  double residual;
  LHS.Norm2(&residual);

  if( Comm.MyPID()==0 ) {
    cout << "||b-Ax||_2 = " << residual << endl;
  }

  // for testing purposes
  if (residual > 1e-5)
    exit(EXIT_FAILURE);

  delete A;
  delete Map;
  delete coords;

#ifdef ML_SCALING
  timeVec[total].value = MPI_Wtime() - timeVec[total].value;

  //avg
  double dupTime[ntimers],avgTime[ntimers];
  for (int i=0; i<ntimers; i++) dupTime[i] = timeVec[i].value;
  MPI_Reduce(dupTime,avgTime,ntimers,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
  for (int i=0; i<ntimers; i++) avgTime[i] = avgTime[i]/Comm.NumProc();
  //min
  MPI_Reduce(timeVec,minTime,ntimers,MPI_DOUBLE_INT,MPI_MINLOC,0,MPI_COMM_WORLD);
  //max
  MPI_Reduce(timeVec,maxTime,ntimers,MPI_DOUBLE_INT,MPI_MAXLOC,0,MPI_COMM_WORLD);

  if (Comm.MyPID() == 0) {
    printf("timing :  max (pid)  min (pid)  avg\n");
    printf("Problem build         :   %2.3e (%d)  %2.3e (%d)  %2.3e \n",
             maxTime[probBuild].value,maxTime[probBuild].rank,
             minTime[probBuild].value,minTime[probBuild].rank,
             avgTime[probBuild]);
    printf("Preconditioner build  :   %2.3e (%d)  %2.3e (%d)  %2.3e \n",
             maxTime[precBuild].value,maxTime[precBuild].rank,
             minTime[precBuild].value,minTime[precBuild].rank,
             avgTime[precBuild]);
    printf("Solve                 :   %2.3e (%d)  %2.3e (%d)  %2.3e \n",
             maxTime[solve].value,maxTime[solve].rank,
             minTime[solve].value,minTime[solve].rank,
             avgTime[solve]);
    printf("Total                 :   %2.3e (%d)  %2.3e (%d)  %2.3e \n",
             maxTime[total].value,maxTime[total].rank,
             minTime[total].value,minTime[total].rank,
             avgTime[total]);
  }
#endif

#ifdef HAVE_MPI
  MPI_Finalize();
#endif

  return(EXIT_SUCCESS);
}
Esempio n. 20
0
int main(int argc, char *argv[])
{
  int i;

#ifdef EPETRA_MPI
  // Initialize MPI
  MPI_Init(&argc,&argv);
  Epetra_MpiComm comm(MPI_COMM_WORLD);
#else
  Epetra_SerialComm comm;
#endif

  // Uncomment to debug in parallel int tmp; if (comm.MyPID()==0) cin >> tmp; comm.Barrier();

  bool verbose = false;

  // Check if we should print results to standard out
  if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true;

  if (!verbose) comm.SetTracebackMode(0); // This should shut down any error traceback reporting

  if (verbose) cout << comm << endl << flush;

  if (verbose) verbose = (comm.MyPID()==0);

  if (verbose)
    cout << EpetraExt::EpetraExt_Version() << endl << endl;

  int nx = 128;
  int ny = comm.NumProc()*nx; // Scale y grid with number of processors

  // Create funky stencil to make sure the matrix is non-symmetric (transpose non-trivial):

  // (i-1,j-1) (i-1,j  )
  // (i  ,j-1) (i  ,j  ) (i  ,j+1)
  // (i+1,j-1) (i+1,j  )

  int npoints = 7;

  int xoff[] = {-1,  0,  1, -1,  0,  1,  0};
  int yoff[] = {-1, -1, -1,  0,  0,  0,  1};

  Epetra_Map * map;
  Epetra_CrsMatrix * A;
  Epetra_Vector * x, * b, * xexact;
	
  Trilinos_Util_GenerateCrsProblem(nx, ny, npoints, xoff, yoff, comm, map, A, x, b, xexact);

  if (nx<8)
  {
    cout << *A << endl;
    cout << "X exact = " << endl << *xexact << endl;
    cout << "B       = " << endl << *b << endl;
  }

  // Construct transposer 
  Epetra_Time timer(comm);

  double start = timer.ElapsedTime();

  //bool IgnoreNonLocalCols = false;
  bool MakeDataContiguous = true;
  EpetraExt::RowMatrix_Transpose transposer( MakeDataContiguous );

  if (verbose) cout << "\nTime to construct transposer  = " << timer.ElapsedTime() - start << endl;
  
  Epetra_CrsMatrix & transA = dynamic_cast<Epetra_CrsMatrix&>(transposer(*A));

  start = timer.ElapsedTime();
  if (verbose) cout << "\nTime to create transpose matrix  = " << timer.ElapsedTime() - start << endl;
 	
  // Now test output of transposer by performing matvecs
  int ierr = 0;
  ierr += checkResults(A, &transA, xexact, verbose);


  // Now change values in original matrix and test update facility of transposer
  // Add 2 to the diagonal of each row
  double Value = 2.0;
  for (i=0; i< A->NumMyRows(); i++)
  A->SumIntoMyValues(i, 1, &Value, &i);

  start = timer.ElapsedTime();
  transposer.fwd();

  if (verbose) cout << "\nTime to update transpose matrix  = " << timer.ElapsedTime() - start << endl;
 	
  ierr += checkResults(A, &transA, xexact, verbose);

  delete A;
  delete b;
  delete x;
  delete xexact;
  delete map;

  if (verbose) cout << endl << "Checking transposer for VbrMatrix objects" << endl<< endl;

  int nsizes = 4;
  int sizes[] = {4, 6, 5, 3};

  Epetra_VbrMatrix * Avbr;
  Epetra_BlockMap * bmap;

  Trilinos_Util_GenerateVbrProblem(nx, ny, npoints, xoff, yoff, nsizes, sizes,
                                   comm, bmap, Avbr, x, b, xexact);

  if (nx<8)
  {
    cout << *Avbr << endl;
    cout << "X exact = " << endl << *xexact << endl;
    cout << "B       = " << endl << *b << endl;
  }

  start = timer.ElapsedTime();
  EpetraExt::RowMatrix_Transpose transposer1( MakeDataContiguous );

  Epetra_CrsMatrix & transA1 = dynamic_cast<Epetra_CrsMatrix&>(transposer1(*Avbr));
  if (verbose) cout << "\nTime to create transpose matrix  = " << timer.ElapsedTime() - start << endl;
 	
  // Now test output of transposer by performing matvecs
;
  ierr += checkResults(Avbr, &transA1, xexact, verbose);

  // Now change values in original matrix and test update facility of transposer
  // Scale matrix on the left by rowsums

  Epetra_Vector invRowSums(Avbr->RowMap());

  Avbr->InvRowSums(invRowSums);
  Avbr->LeftScale(invRowSums);

  start = timer.ElapsedTime();
  transposer1.fwd();
  if (verbose) cout << "\nTime to update transpose matrix  = " << timer.ElapsedTime() - start << endl;
 	
  ierr += checkResults(Avbr, &transA1, xexact, verbose);

  delete Avbr;
  delete b;
  delete x;
  delete xexact;
  delete bmap;

#ifdef EPETRA_MPI
  MPI_Finalize();
#endif

  return ierr;
}