//============================================================================== Epetra_CrsMatrix * Poisson2dOperator::GeneratePrecMatrix() const { // Generate a tridiagonal matrix as an Epetra_CrsMatrix // This method illustrates how to generate a matrix that is an approximation to the true // operator. Given this matrix, we can use any of the Aztec or IFPACK preconditioners. // Create a Epetra_Matrix Epetra_CrsMatrix * A = new Epetra_CrsMatrix(Copy, *map_, 3); int NumMyElements = map_->NumMyElements(); int NumGlobalElements = map_->NumGlobalElements(); // Add rows one-at-a-time double negOne = -1.0; double posTwo = 4.0; for (int i=0; i<NumMyElements; i++) { int GlobalRow = A->GRID(i); int RowLess1 = GlobalRow - 1; int RowPlus1 = GlobalRow + 1; if (RowLess1!=-1) A->InsertGlobalValues(GlobalRow, 1, &negOne, &RowLess1); if (RowPlus1!=NumGlobalElements) A->InsertGlobalValues(GlobalRow, 1, &negOne, &RowPlus1); A->InsertGlobalValues(GlobalRow, 1, &posTwo, &GlobalRow); } // Finish up A->FillComplete(); return(A); }
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; }
/*----------------------------------------------------------------------* | 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(); }
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); }
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]); } } }
Epetra_LinearProblem* create_epetra_problem(int numProcs, int localProc, int local_n) { if (localProc == 0) { std::cout << " creating Epetra_CrsMatrix with un-even distribution..." << std::endl; } //create an Epetra_CrsMatrix with rows spread un-evenly over //processors. Epetra_MpiComm comm(MPI_COMM_WORLD); int global_num_rows = numProcs*local_n; int mid_proc = numProcs/2; bool num_procs_even = numProcs%2==0 ? true : false; int adjustment = local_n/2; //adjust local_n so that it's not equal on all procs. if (localProc < mid_proc) { local_n -= adjustment; } else { local_n += adjustment; } //if numProcs is not an even number, undo the local_n adjustment //on one proc so that the total will still be correct. if (localProc == numProcs-1) { if (num_procs_even == false) { local_n -= adjustment; } } //now we're ready to create a row-map. Epetra_Map rowmap(global_num_rows, local_n, 0, comm); //create a matrix int nnz_per_row = 9; Epetra_CrsMatrix* matrix = new Epetra_CrsMatrix(Copy, rowmap, nnz_per_row); // Add rows one-at-a-time double negOne = -1.0; double posTwo = 4.0; for (int i=0; i<local_n; i++) { int GlobalRow = matrix->GRID(i); int RowLess1 = GlobalRow - 1; int RowPlus1 = GlobalRow + 1; int RowLess2 = GlobalRow - 2; int RowPlus2 = GlobalRow + 2; int RowLess3 = GlobalRow - 3; int RowPlus3 = GlobalRow + 3; int RowLess4 = GlobalRow - 4; int RowPlus4 = GlobalRow + 4; if (RowLess4>=0) { matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowLess4); } if (RowLess3>=0) { matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowLess3); } if (RowLess2>=0) { matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowLess2); } if (RowLess1>=0) { matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowLess1); } if (RowPlus1<global_num_rows) { matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowPlus1); } if (RowPlus2<global_num_rows) { matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowPlus2); } if (RowPlus3<global_num_rows) { matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowPlus3); } if (RowPlus4<global_num_rows) { matrix->InsertGlobalValues(GlobalRow, 1, &negOne, &RowPlus4); } matrix->InsertGlobalValues(GlobalRow, 1, &posTwo, &GlobalRow); } int err = matrix->FillComplete(); if (err != 0) { throw Isorropia::Exception("create_epetra_matrix: error in matrix.FillComplete()"); } Epetra_Vector* x = new Epetra_Vector(rowmap); Epetra_Vector* b = new Epetra_Vector(rowmap); return(new Epetra_LinearProblem(matrix, x, b)); }