Esempio n. 1
0
/** Setup operator
  */
void 
Stokhos::AdaptivityManager::
setupOperator(Epetra_CrsMatrix & A,const Sparse3Tensor<int,double> & Cijk,Stokhos::EpetraOperatorOrthogPoly & poly,
              bool onlyUseLinear,bool includeMean) const
{
   typedef Stokhos::Sparse3Tensor<int,double> Cijk_type;

   // build the sparse hash only once
   Sparse3TensorHash hashLookup(Cijk);

   // Zero out matrix
   A.PutScalar(0.0);

   // Compute loop bounds
   Cijk_type::k_iterator k_begin = Cijk.k_begin();
   Cijk_type::k_iterator k_end = Cijk.k_end();
   if (!includeMean && index(k_begin) == 0)
     ++k_begin;
   if (onlyUseLinear) {
     int dim = sg_master_basis_->dimension();
     k_end = Cijk.find_k(dim+1);
   }
 
   // Assemble matrix
   // const Teuchos::Array<double>& norms = sg_basis->norm_squared();
   for (Cijk_type::k_iterator k_it=k_begin; k_it!=k_end; ++k_it) {
      int k = index(k_it);
      Teuchos::RCP<Epetra_CrsMatrix> block = 
        Teuchos::rcp_dynamic_cast<Epetra_CrsMatrix>(poly.getCoeffPtr(k), 
 						    true);

      // add in matrix k
      sumInOperator(A,hashLookup,k,*block);
   }
}
//=========================================================================
int Epetra_LinearProblemRedistor::UpdateRedistProblemValues(Epetra_LinearProblem * ProblemWithNewValues) {
	
	if (!RedistProblemCreated_) EPETRA_CHK_ERR(-1);  // This method can only be called after CreateRedistProblem()

	Epetra_RowMatrix * OrigMatrix = ProblemWithNewValues->GetMatrix();
	Epetra_MultiVector * OrigLHS = ProblemWithNewValues->GetLHS();
	Epetra_MultiVector * OrigRHS = ProblemWithNewValues->GetRHS();
		
	if (OrigMatrix==0) EPETRA_CHK_ERR(-2); // There is no matrix associated with this Problem


	Epetra_CrsMatrix * RedistMatrix = dynamic_cast<Epetra_CrsMatrix *>(RedistProblem_->GetMatrix());

	// Check if the tranpose should be create or not
	if (ConstructTranspose_) {
		EPETRA_CHK_ERR(Transposer_->UpdateTransposeValues(OrigMatrix));
	}
	else {
		// If not, then just do the redistribution based on the the RedistMap
		
		EPETRA_CHK_ERR(RedistMatrix->PutScalar(0.0));
		// need to do this next step until we generalize the Import/Export ops for CrsMatrix
		Epetra_CrsMatrix * OrigCrsMatrix = dynamic_cast<Epetra_CrsMatrix *>(OrigMatrix);

		if (OrigCrsMatrix==0) EPETRA_CHK_ERR(-3); // Broken for a RowMatrix at this point
		EPETRA_CHK_ERR(RedistMatrix->Export(*OrigCrsMatrix, *RedistExporter_, Add));
	}

	// Now redistribute the RHS and LHS if non-zero


	if (OrigLHS!=0) {
		EPETRA_CHK_ERR(RedistProblem_->GetLHS()->Export(*OrigLHS, *RedistExporter_, Add));
	}

	if (OrigRHS!=0) {
		EPETRA_CHK_ERR(RedistProblem_->GetRHS()->Export(*OrigRHS, *RedistExporter_, Add));
	}

  return(0);
}
Esempio n. 3
0
//TpetraCrsMatrix_To_EpetraCrsMatrix: copies Tpetra::CrsMatrix object into its analogous
//Epetra_CrsMatrix object
void Petra::TpetraCrsMatrix_To_EpetraCrsMatrix(const Teuchos::RCP<const Tpetra_CrsMatrix>& tpetraCrsMatrix_,
                                               Epetra_CrsMatrix& epetraCrsMatrix_,
                                               const Teuchos::RCP<const Epetra_Comm>& comm_)
{
  //check if row maps of epetraCrsMatrix_ and tpetraCrsMatrix_ are the same
  const Epetra_BlockMap epetraRowMap_ = epetraCrsMatrix_.RowMap();
  Teuchos::RCP<const Tpetra_Map> tpetraRowMap_ = tpetraCrsMatrix_->getRowMap();
  Teuchos::RCP<const Epetra_Map> tpetraRowMapE_ = TpetraMap_To_EpetraMap(tpetraRowMap_, comm_);
  bool isRowSame = tpetraRowMapE_->SameAs(epetraRowMap_);
  //if epetraCrsMatrix_ and tpetraCrsMatrix_ do not have the same row map, throw an exception
  if (isRowSame != true)
  {
    EpetraExt::BlockMapToMatrixMarketFile("epetraRowMap.mm", epetraRowMap_);
    EpetraExt::BlockMapToMatrixMarketFile("tpetraRowMapE.mm", *tpetraRowMapE_);
  }
  TEUCHOS_TEST_FOR_EXCEPTION((isRowSame != true),
                             std::logic_error,
                             "Error in Petra::TpetraCrsMatrix_To_EpetraCrsMatrix! Arguments Epetra_CrsMatrix and Tpetra::CrsMatrix do not have same row map." <<  std::endl) ;

 //check if column maps of epetraCrsMatrix_ and tpetraCrsMatrix_ are the same
 const Epetra_BlockMap epetraColMap_ = epetraCrsMatrix_.ColMap();
 Teuchos::RCP<const Tpetra_Map> tpetraColMap_ = tpetraCrsMatrix_->getColMap();
 Teuchos::RCP<const Epetra_Map> tpetraColMapE_ = TpetraMap_To_EpetraMap(tpetraColMap_, comm_);
 bool isColSame = tpetraColMapE_->SameAs(epetraColMap_);
 //if epetraCrsMatrix_ and tpetraCrsMatrix_ do not have the same column map, throw an exception
 TEUCHOS_TEST_FOR_EXCEPTION((isColSame != true),
                            std::logic_error,
                            "Error in Petra::TpetraCrsMatrix_To_EpetraCrsMatrix! Arguments Epetra_CrsMatrix and Tpetra::CrsMatrix do not have same column map." <<  std::endl) ;

  epetraCrsMatrix_.PutScalar(0.0);

  for (LO i = 0; i<tpetraCrsMatrix_->getNodeNumRows(); i++) {
     LO NumEntries; const LO *Indices; const ST *Values;
     tpetraCrsMatrix_->getLocalRowView(i, NumEntries, Values, Indices);
     epetraCrsMatrix_.ReplaceMyValues(i, NumEntries, Values, Indices);
  }
}
Esempio n. 4
0
// rebuild a single subblock Epetra_CrsMatrix
void rebuildSubBlock(int i,int j,const Epetra_CrsMatrix & A,const std::vector<std::pair<int,RCP<Epetra_Map> > > & subMaps,Epetra_CrsMatrix & mat)
{
   // get the number of variables families
   int numVarFamily = subMaps.size();

   TEUCHOS_ASSERT(i>=0 && i<numVarFamily);
   TEUCHOS_ASSERT(j>=0 && j<numVarFamily);
   TEUCHOS_ASSERT(mat.Filled());

   const Epetra_Map & gRowMap = *subMaps[i].second;
   const Epetra_Map & rowMap = *Teuchos::get_extra_data<RCP<Epetra_Map> >(subMaps[i].second,"contigMap");
   int colFamilyCnt = subMaps[j].first;

   // compute the number of global variables
   // and the row and column block offset
   int numGlobalVars = 0;
   int rowBlockOffset = 0;
   int colBlockOffset = 0;
   for(int k=0;k<numVarFamily;k++) {
      numGlobalVars += subMaps[k].first;
 
      // compute block offsets
      if(k<i) rowBlockOffset += subMaps[k].first;
      if(k<j) colBlockOffset += subMaps[k].first;
   }

   // copy all global rows to here
   Epetra_Import import(gRowMap,A.RowMap());
   Epetra_CrsMatrix localA(Copy,gRowMap,0);
   localA.Import(A,import,Insert);

   // clear out the old matrix
   mat.PutScalar(0.0);

   // get entry information
   int numMyRows = rowMap.NumMyElements();
   int maxNumEntries = A.GlobalMaxNumEntries();

   // for extraction
   std::vector<int> indices(maxNumEntries);
   std::vector<double> values(maxNumEntries);

   // for insertion
   std::vector<int> colIndices(maxNumEntries);
   std::vector<double> colValues(maxNumEntries);

   // insert each row into subblock
   // let FillComplete handle column distribution
   for(int localRow=0;localRow<numMyRows;localRow++) {
      int numEntries = -1; 
      int globalRow = gRowMap.GID(localRow);
      int contigRow = rowMap.GID(localRow);

      TEUCHOS_ASSERT(globalRow>=0);
      TEUCHOS_ASSERT(contigRow>=0);

      // extract a global row copy
      int err = localA.ExtractGlobalRowCopy(globalRow, maxNumEntries, numEntries, &values[0], &indices[0]);
      TEUCHOS_ASSERT(err==0);

      int numOwnedCols = 0;
      for(int localCol=0;localCol<numEntries;localCol++) {
         int globalCol = indices[localCol];

         // determinate which block this column ID is in
         int block = globalCol / numGlobalVars;
         
         bool inFamily = true; 
 
         // test the beginning of the block
         inFamily &= (block*numGlobalVars+colBlockOffset <= globalCol);
         inFamily &= ((block*numGlobalVars+colBlockOffset+colFamilyCnt) > globalCol);

         // is this column in the variable family
         if(inFamily) {
            int familyOffset = globalCol-(block*numGlobalVars+colBlockOffset);

            colIndices[numOwnedCols] = block*colFamilyCnt + familyOffset;
            colValues[numOwnedCols] = values[localCol];

            numOwnedCols++;
         }
      }

      // insert it into the new matrix
      mat.SumIntoGlobalValues(contigRow,numOwnedCols,&colValues[0],&colIndices[0]);
   }
}
Esempio n. 5
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. 6
0
 //! Initialize matrix
 static void init(Epetra_CrsMatrix& mat, double val) { mat.PutScalar(val); }