/** 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); }
//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); } }
// 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]); } }
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; }
//! Initialize matrix static void init(Epetra_CrsMatrix& mat, double val) { mat.PutScalar(val); }