int Ifpack_SORa::TCompute(){ using std::cout; using std::endl; Epetra_Map *RowMap=const_cast<Epetra_Map*>(&A_->RowMatrixRowMap()); Epetra_Vector Adiag(*RowMap); Epetra_CrsMatrix *Askew2=0, *Aherm2=0,*W=0; int *rowptr_s,*colind_s,*rowptr_h,*colind_h; double *vals_s,*vals_h; bool RowMatrixMode=(Acrs_==Teuchos::null); // Label sprintf(Label_, "IFPACK SORa (alpha=%5.2f gamma=%5.2f)",Alpha_,Gamma_); if(RowMatrixMode){ if(!A_->Comm().MyPID()) cout<<"SORa: RowMatrix mode enabled"<<endl; // RowMatrix mode, build Acrs_ the hard way. Epetra_RowMatrix *Arow=&*A_; Epetra_Map *ColMap=const_cast<Epetra_Map*>(&A_->RowMatrixColMap()); int Nmax=A_->MaxNumEntries(); int length; std::vector<double> values(Nmax); Epetra_CrsMatrix *Acrs=new Epetra_CrsMatrix(Copy,*RowMap,Nmax); std::vector<int> indices_local(Nmax); #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES if(RowMap->GlobalIndicesInt()) { for(int i=0;i<Arow->NumMyRows();i++) { Arow->ExtractMyRowCopy(i,Nmax,length,&values[0],&indices_local[0]); for(int j=0;j<length;j++) indices_local[j]= ColMap->GID(indices_local[j]); Acrs->InsertGlobalValues(RowMap->GID(i),length,&values[0],&indices_local[0]); } } else #endif #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES if(RowMap->GlobalIndicesLongLong()) { std::vector<int_type> indices_global(Nmax); for(int i=0;i<Arow->NumMyRows();i++) { Arow->ExtractMyRowCopy(i,Nmax,length,&values[0],&indices_local[0]); for(int j=0;j<length;j++) indices_global[j]= (int_type) ColMap->GID64(indices_local[j]); Acrs->InsertGlobalValues((int_type) RowMap->GID64(i),length,&values[0],&indices_global[0]); } } else #endif throw "Ifpack_SORa::TCompute: GlobalIndices type unknown"; Acrs->FillComplete(A_->OperatorDomainMap(),A_->OperatorRangeMap()); Acrs_ = Teuchos::rcp (Acrs, true); } // Create Askew2 // Note: Here I let EpetraExt do the thinking for me. Since it gets all the maps correct for the E + F^T stencil. // There are probably more efficient ways to do this but this method has the bonus of allowing code reuse. IFPACK_CHK_ERR(EpetraExt::MatrixMatrix::Add(*Acrs_,false,1,*Acrs_,true,-1,Askew2)); Askew2->FillComplete(); // Create Aherm2 IFPACK_CHK_ERR(EpetraExt::MatrixMatrix::Add(*Acrs_,false,1,*Acrs_,true,1,Aherm2)); Aherm2->FillComplete(); int nnz2=Askew2->NumMyNonzeros(); int N=Askew2->NumMyRows(); // Grab pointers IFPACK_CHK_ERR(Askew2->ExtractCrsDataPointers(rowptr_s,colind_s,vals_s)); IFPACK_CHK_ERR(Aherm2->ExtractCrsDataPointers(rowptr_h,colind_h,vals_h)); // Sanity checking: Make sure the sparsity patterns are the same #define SANITY_CHECK #ifdef SANITY_CHECK for(int i=0;i<N;i++) if(rowptr_s[i]!=rowptr_h[i]) IFPACK_CHK_ERR(-2); for(int i=0;i<nnz2;i++) if(colind_s[i]!=colind_h[i]) IFPACK_CHK_ERR(-3); #endif // Dirichlet Detection & Nuking of Aherm2 and Askew2 // Note: Relies on Aherm2/Askew2 having identical sparsity patterns (see sanity check above) if(HaveOAZBoundaries_){ int numBCRows; int* dirRows=FindLocalDiricheltRowsFromOnesAndZeros(*Acrs_,numBCRows); Epetra_IntVector* dirCols=FindLocalDirichletColumnsFromRows(dirRows,numBCRows,*Aherm2); Apply_BCsToMatrixRowsAndColumns(dirRows,numBCRows,*dirCols,*Aherm2); Apply_BCsToMatrixRowsAndColumns(dirRows,numBCRows,*dirCols,*Askew2); delete [] dirRows; delete dirCols; } // Grab diagonal of A A_->ExtractDiagonalCopy(Adiag); // Allocate the diagonal for W Epetra_Vector *Wdiag = new Epetra_Vector(*RowMap); // Build the W matrix (lower triangle only) // Note: Relies on EpetraExt giving me identical sparsity patterns for both Askew2 and Aherm2 (see sanity check above) int maxentries=Askew2->MaxNumEntries(); int_type* gids=new int_type [maxentries]; double* newvals=new double[maxentries]; W=new Epetra_CrsMatrix(Copy,*RowMap,0); for(int i=0;i<N;i++){ // Build the - (1+alpha)/2 E - (1-alpha)/2 F part of the W matrix int_type rowgid = (int_type) Acrs_->GRID64(i); double c_data=0.0; double ipdamp=0.0; int idx=0; for(int j=rowptr_s[i];j<rowptr_s[i+1];j++){ int_type colgid = (int_type) Askew2->GCID64(colind_s[j]); c_data+=fabs(vals_s[j]); if(rowgid>colgid){ // Rely on the fact that off-diagonal entries are always numbered last, dropping the entry entirely. if(colind_s[j] < N) { gids[idx]=colgid; newvals[idx]=vals_h[j]/2 + Alpha_ * vals_s[j]/2; idx++; } else{ ipdamp+=fabs(vals_h[j]/2 + Alpha_ * vals_s[j]/2); } } } if(idx>0) IFPACK_CHK_ERR(W->InsertGlobalValues(rowgid,idx,newvals,gids)); // Do the diagonal double w_val= c_data*Alpha_*Gamma_/4 + Adiag[Acrs_->LRID(rowgid)]; if(UseInterprocDamping_) w_val+=ipdamp; W->InsertGlobalValues(rowgid,1,&w_val,&rowgid); IFPACK_CHK_ERR(Wdiag->ReplaceGlobalValues(1,&w_val,&rowgid)); } W->FillComplete(A_->OperatorDomainMap(),A_->OperatorRangeMap()); W_= Teuchos::rcp(W); Wdiag_= Teuchos::rcp(Wdiag); // Mark as computed IsComputed_=true; // Global damping, if wanted if(UseGlobalDamping_) { PowerMethod(10,LambdaMax_); if(!A_->Comm().MyPID()) printf("SORa: Global damping parameter = %6.4e (lmax=%6.4e)\n",GetOmega(),LambdaMax_); } // Cleanup delete [] gids; delete [] newvals; delete Aherm2; delete Askew2; if(RowMatrixMode) { Acrs_=Teuchos::null; } // Counters NumCompute_++; ComputeTime_ += Time_.ElapsedTime(); return 0; }
int MultiVectorTests(const Epetra_BlockMap & Map, int NumVectors, bool verbose) { const Epetra_Comm & Comm = Map.Comm(); int ierr = 0, i; double *residual = new double[NumVectors]; Epetra_BLAS BLAS; /* get number of processors and the name of this processor */ // int NumProc = Comm.getNumProc(); int MyPID = Comm.MyPID(); // Construct MultiVectors Epetra_MultiVector A(Map, NumVectors); Epetra_MultiVector sqrtA(Map, NumVectors); Epetra_MultiVector B(Map, NumVectors); Epetra_MultiVector C(Map, NumVectors); Epetra_MultiVector C_alphaA(Map, NumVectors); Epetra_MultiVector C_alphaAplusB(Map, NumVectors); Epetra_MultiVector C_plusB(Map, NumVectors); Epetra_MultiVector Weights(Map, NumVectors); // Construct double vectors double *dotvec_AB = new double[NumVectors]; double *norm1_A = new double[NumVectors]; double *norm2_sqrtA = new double[NumVectors]; double *norminf_A = new double[NumVectors]; double *normw_A = new double[NumVectors]; double *minval_A = new double[NumVectors]; double *maxval_A = new double[NumVectors]; double *meanval_A = new double[NumVectors]; // Generate data EPETRA_TEST_ERR(C.Random(),ierr); // Fill C with random numbers. double alpha = 2.0; BuildMultiVectorTests (C,alpha, A, sqrtA, B, C_alphaA, C_alphaAplusB, C_plusB, dotvec_AB, norm1_A, norm2_sqrtA, norminf_A, normw_A, Weights, minval_A, maxval_A, meanval_A); int err = 0; if (verbose) cout << "XXXXX Testing alpha * A "; // Test alpha*A Epetra_MultiVector alphaA(A); // Copy of A EPETRA_TEST_ERR(alphaA.Scale(alpha),err); EPETRA_TEST_ERR(alphaA.Update(-1.0, C_alphaA, 1.0),err); EPETRA_TEST_ERR(alphaA.Norm2(residual),err); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing C = alpha * A + B "; // Test alpha*A + B Epetra_MultiVector alphaAplusB(A); // Copy of A EPETRA_TEST_ERR(alphaAplusB.Update(1.0, B, alpha, A, 0.0),err); EPETRA_TEST_ERR(alphaAplusB.Update(-1.0, C_alphaAplusB, 1.0),err); EPETRA_TEST_ERR(alphaAplusB.Norm2(residual),err); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing C += B "; // Test + B Epetra_MultiVector plusB(C); // Copy of C EPETRA_TEST_ERR(plusB.Update(1.0, B, 1.0),err); EPETRA_TEST_ERR(plusB.Update(-1.0, C_plusB, 1.0),err); EPETRA_TEST_ERR(plusB.Norm2(residual),err); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing A.dotProd(B) "; // Test A.dotvec(B) double *dotvec = residual; EPETRA_TEST_ERR(A.Dot(B,dotvec),err); BLAS.AXPY(NumVectors,-1.0,dotvec_AB,dotvec); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing norm1_A "; // Test A.norm1() double *norm1 = residual; EPETRA_TEST_ERR(A.Norm1(norm1),err); BLAS.AXPY(NumVectors,-1.0,norm1_A,norm1); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing norm2_sqrtA "; // Test sqrtA.norm2() double *norm2 = residual; EPETRA_TEST_ERR(sqrtA.Norm2(norm2),err); BLAS.AXPY(NumVectors,-1.0,norm2_sqrtA,norm2); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing norminf_A "; // Test A.norminf() double *norminf = residual; EPETRA_TEST_ERR(A.NormInf(norminf),err); BLAS.AXPY(NumVectors,-1.0,norminf_A,norminf); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing normw_A "; // Test A.NormWeighted() double *normw = residual; EPETRA_TEST_ERR(A.NormWeighted(Weights, normw),err); BLAS.AXPY(NumVectors,-1.0,normw_A,normw); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing minval_A "; // Test A.MinValue() double *minval = residual; EPETRA_TEST_ERR(A.MinValue(minval),err); BLAS.AXPY(NumVectors,-1.0,minval_A,minval); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing maxval_A "; // Test A.MaxValue() double *maxval = residual; EPETRA_TEST_ERR(A.MaxValue(maxval),err); BLAS.AXPY(NumVectors,-1.0,maxval_A,maxval); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing meanval_A "; // Test A.MeanValue() double *meanval = residual; EPETRA_TEST_ERR(A.MeanValue(meanval),err); BLAS.AXPY(NumVectors,-1.0,meanval_A,meanval); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing abs_A "; // Test A.Abs() Epetra_MultiVector Abs_A = A; EPETRA_TEST_ERR(Abs_A.Abs(A),err); EPETRA_TEST_ERR(Abs_A.Update(1.0, A, -1.0),err); // Abs_A = A - Abs_A (should be zero since A > 0) EPETRA_TEST_ERR(Abs_A.Norm2(residual),err); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing random_A (Test1) "; // Test A.Random() Epetra_MultiVector Rand1_A(A); Epetra_MultiVector Rand2_A(A); EPETRA_TEST_ERR(Rand1_A.Random(),err); EPETRA_TEST_ERR(Rand2_A.Random(),err); // Rand2_A = Rand1_A - Rand2_A (should be nonzero since Random() should give different vectors > 0) EPETRA_TEST_ERR(Rand2_A.Update(1.0, Rand1_A, -1.0),err); EPETRA_TEST_ERR(Rand2_A.Norm2(residual),err); if (err) ierr += err; else { EPETRA_TEST_ERR(BadResidual1(verbose,residual, NumVectors),ierr); } err = 0; if (verbose) cout << "XXXXX Testing random_A (Test2) "; // Next test that each column of the multivector is different from all other columns by testing the first value // of each vector against the first value of every other vector. int randvalsdiffer = 1; // Assume they all differ for (i=0; i< NumVectors; i++) for (int j=i+1; j<NumVectors; j++) if (Rand1_A[i][0]==Rand1_A[j][0]) randvalsdiffer = 0; // make false if equal int allrandvals = 0; Comm.MinAll(&randvalsdiffer, &allrandvals, 1); // get min of all values across all processors EPETRA_TEST_ERR(1-allrandvals, err); // If allrandvals is anything but 1, this will cause an error int locerr = err; Comm.MinAll(&locerr, &err, 1); if (verbose) { if (err==0) { cout << "\t Checked OK" << endl; } else { cout << "\t Checked Failed" << endl; } } err = 0; if (verbose) cout << "XXXXX Testing random_A (Test3) "; // Next test that the first element on each processor of the first column of Rand1_A is different from all others // First we will gather them all to PE 0 Epetra_Map RandstartsMap(-1, 1, 0, Comm); // This Map has a single element on each PE int itmp = 0; int nproc = Comm.NumProc(); if (MyPID==0) itmp = nproc; Epetra_Map AllrandstartsMap(nproc, itmp, 0, Comm); // Map has NumProc elements on PE 0, none elsewhere Epetra_MultiVector Randstarts(RandstartsMap, NumVectors); Epetra_MultiVector Allrandstarts(AllrandstartsMap, NumVectors); for (i=0; i< NumVectors; i++) Randstarts[i][0] = Rand1_A[i][0]; // Load first value of local multivector Epetra_Import Randimporter(AllrandstartsMap,RandstartsMap); EPETRA_TEST_ERR(Allrandstarts.Import(Randstarts,Randimporter,Insert),err); // cout << "Randstarts = " << Randstarts << endl << "Allrandstarts = " << Allrandstarts << endl; // Allrandstarts now contains the first values for each local section of Rand1_A. // Next test that this is true. randvalsdiffer = 1; // Assume they all differ if (MyPID==0) { for (i=0; i< NumVectors; i++) for (int irand=0; irand<nproc; irand++) for (int jrand=irand+1; jrand<nproc; jrand++) if (Allrandstarts[i][irand]==Allrandstarts[i][jrand]) randvalsdiffer = 0; // make false if equal } allrandvals = 0; Comm.MinAll(&randvalsdiffer, &allrandvals, 1); // get min of all values across all processors EPETRA_TEST_ERR(1-allrandvals, err); // If allrandvals is anything but 1, this will cause an error locerr = err; Comm.MinAll(&locerr, &err, 1); if (verbose) { if (err==0) { cout << "\t Checked OK" << endl; } else { cout << "\t Checked Failed" << endl; } } // Delete everything delete [] dotvec_AB; delete [] norm1_A; delete [] norm2_sqrtA; delete [] norminf_A; delete [] normw_A; delete [] minval_A; delete [] maxval_A; delete [] meanval_A; delete [] residual; //******************************************************************* // Post-construction modification tests //******************************************************************* if (verbose) cout << "\n\nXXXXX Testing Post-construction modification of a multivector" <<endl<<endl; err = 0; Epetra_MultiVector X(Map, NumVectors); X.Random(); // Pick middle range values for GID, LID and Vector Index int testGID = Map.NumGlobalElements()/2; int testVecIndex = NumVectors/2; int GIDSize = 1; int LIDOfGID = 0; int FirstEntryOfGID = 0; if (Map.MyGID(testGID)) { LIDOfGID = Map.LID(testGID); GIDSize = Map.ElementSize(LIDOfGID); FirstEntryOfGID = Map.FirstPointInElement(LIDOfGID); } // ======================================================================== // Test int ReplaceGlobalValue (int GlobalRow, int VectorIndex, double ScalarValue) // ======================================================================== double newGIDValue = 4.0; locerr = X.ReplaceGlobalValue(testGID, testVecIndex, newGIDValue); if (Map.MyGID(testGID)) { if (X[testVecIndex][FirstEntryOfGID]!=newGIDValue) err++; if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfGID<<"] = " << X[testVecIndex][FirstEntryOfGID] << " should = " << newGIDValue << endl; } else if (locerr!=1) err++; // Test for GID out of range error (=1) // ======================================================================== // Test int ReplaceGlobalValue (int GlobalRow, intBlockRowOffset, int VectorIndex, double ScalarValue) // ======================================================================== newGIDValue = 8.0; locerr = X.ReplaceGlobalValue(testGID, GIDSize-1, testVecIndex, newGIDValue); if (Map.MyGID(testGID)) { if (X[testVecIndex][FirstEntryOfGID+GIDSize-1]!=newGIDValue) err++; if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfGID+GIDSize-1<<"] = " << X[testVecIndex][FirstEntryOfGID+GIDSize-1] << " should = " << newGIDValue << endl; } else if (locerr!=1) err++; // Test for GID out of range error (=1) // ======================================================================== // Test int SumIntoGlobalValue (int GlobalRow, int VectorIndex, double ScalarValue) // ======================================================================== newGIDValue = 1.0; locerr = X.ReplaceGlobalValue(testGID, testVecIndex, newGIDValue); locerr = X.SumIntoGlobalValue(testGID, testVecIndex, newGIDValue); if (Map.MyGID(testGID)) { if (X[testVecIndex][FirstEntryOfGID]!=(newGIDValue+newGIDValue)) err++; if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfGID<<"] = " << X[testVecIndex][FirstEntryOfGID] << " should = " << newGIDValue << endl; } else if (locerr!=1) err++; // Test for GID out of range error (=1) // ======================================================================== // Test int SumIntoGlobalValue (int GlobalRow, intBlockRowOffset, int VectorIndex, double ScalarValue) // ======================================================================== newGIDValue = 1.0; locerr = X.ReplaceGlobalValue(testGID, GIDSize-1, testVecIndex, newGIDValue); locerr = X.SumIntoGlobalValue(testGID, GIDSize-1, testVecIndex, newGIDValue); if (Map.MyGID(testGID)) { if (X[testVecIndex][FirstEntryOfGID+GIDSize-1]!=(newGIDValue+newGIDValue)) err++; if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfGID+GIDSize-1<<"] = " << X[testVecIndex][FirstEntryOfGID+GIDSize-1] << " should = " << newGIDValue << endl; } else if (locerr!=1) err++; // Test for GID out of range error (=1) // ======================================================================== // Test Local "My" versions of same routine (less complicated) // ======================================================================== // Pick middle range values for LID int testLID = Map.NumMyElements()/2; int LIDSize = Map.ElementSize(testLID); int FirstEntryOfLID = Map.FirstPointInElement(testLID); double newLIDValue = 4.0; locerr = X.ReplaceMyValue(testLID, testVecIndex, newLIDValue); if (X[testVecIndex][FirstEntryOfLID]!=newLIDValue) err++; if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfLID<<"] = " << X[testVecIndex][FirstEntryOfLID] << " should = " << newLIDValue << endl; newLIDValue = 8.0; locerr = X.ReplaceMyValue(testLID, LIDSize-1, testVecIndex, newLIDValue); if (X[testVecIndex][FirstEntryOfLID+LIDSize-1]!=newLIDValue) err++; if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfLID+LIDSize-1<<"] = " << X[testVecIndex][FirstEntryOfLID+LIDSize-1] << " should = " << newLIDValue << endl; newLIDValue = 1.0; locerr = X.ReplaceMyValue(testLID, testVecIndex, newLIDValue); locerr = X.SumIntoMyValue(testLID, testVecIndex, newLIDValue); if (X[testVecIndex][FirstEntryOfLID]!=(newLIDValue+newLIDValue)) err++; if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfLID<<"] = " << X[testVecIndex][FirstEntryOfLID] << " should = " << newLIDValue << endl; newLIDValue = 2.0; locerr = X.ReplaceMyValue(testLID, LIDSize-1, testVecIndex, newLIDValue); locerr = X.SumIntoMyValue(testLID, LIDSize-1, testVecIndex, newLIDValue); if (verbose) cout << "X["<<testVecIndex<<"]["<<FirstEntryOfLID+LIDSize-1<<"] = " << X[testVecIndex][FirstEntryOfLID+LIDSize-1] << " should = " << newLIDValue << endl; if (X[testVecIndex][FirstEntryOfLID+LIDSize-1]!=(newLIDValue+newLIDValue)) err++; ierr += err; // ======================================================================== // Test Post-construction modification of an Epetra_Vector using a vector // our multivector X // ======================================================================== if (verbose) cout << "\n\nXXXXX Testing Post-construction modification of a vector" << endl << endl; Epetra_Vector * x = X(testVecIndex); int NumEntries = 2; double * VecValues = new double[NumEntries]; int * VecGIDs = new int[NumEntries]; VecGIDs[0] = testGID; VecGIDs[1] = testGID+1; // Some pathological chance that these GIDs are not valid // ======================================================================== // Test int ReplaceGlobalValues (int NumEntries, double *Values, int *Indices) // ======================================================================== VecValues[0] = 2.0; VecValues[1] = 4.0; locerr = x->ReplaceGlobalValues(NumEntries, VecValues, VecGIDs); for (i=0; i<NumEntries; i++) { testGID = VecGIDs[i]; if (Map.MyGID(testGID)) { LIDOfGID = Map.LID(testGID); GIDSize = EPETRA_MIN(GIDSize,Map.ElementSize(LIDOfGID)); // Need this value below FirstEntryOfGID = Map.FirstPointInElement(LIDOfGID); if ((*x)[FirstEntryOfGID]!=VecValues[i]) err++; if (verbose) cout << "x["<<FirstEntryOfGID<<"] = " << (*x)[FirstEntryOfGID] << " should = " << VecValues[i] << endl; } else if (locerr!=1) err++; // Test for GID out of range error (=1) } // ======================================================================== // Test int ReplaceGlobalValues (int NumEntries, int BlockOffset, double *Values, int *Indices) // ======================================================================== VecValues[0] = 4.0; VecValues[1] = 8.0; locerr = x->ReplaceGlobalValues(NumEntries, GIDSize-1, VecValues, VecGIDs); for (i=0; i<NumEntries; i++) { testGID = VecGIDs[i]; if (Map.MyGID(testGID)) { LIDOfGID = Map.LID(testGID); FirstEntryOfGID = Map.FirstPointInElement(LIDOfGID); if ((*x)[FirstEntryOfGID+GIDSize-1]!=VecValues[i]) err++; if (verbose) cout << "x["<<FirstEntryOfGID+GIDSize-1<<"] = " << (*x)[FirstEntryOfGID+GIDSize-1] << " should = " << VecValues[i] << endl; } else if (locerr!=1) err++; // Test for GID out of range error (=1) } // ======================================================================== // Test int SumIntoGlobalValues (int NumEntries, double *Values, int *Indices) // ======================================================================== VecValues[0] = 1.0; VecValues[1] = 2.0; locerr = x->ReplaceGlobalValues(NumEntries, VecValues, VecGIDs); locerr = x->SumIntoGlobalValues(NumEntries, VecValues, VecGIDs); for (i=0; i<NumEntries; i++) { testGID = VecGIDs[i]; if (Map.MyGID(testGID)) { LIDOfGID = Map.LID(testGID); FirstEntryOfGID = Map.FirstPointInElement(LIDOfGID); if ((*x)[FirstEntryOfGID]!=(VecValues[i]+VecValues[i])) err++; if (verbose) cout << "x["<<FirstEntryOfGID<<"] = " << (*x)[FirstEntryOfGID] << " should = " << (VecValues[i]+VecValues[i]) << endl; } else if (locerr!=1) err++; // Test for GID out of range error (=1) } // ======================================================================== // Test int ReplaceGlobalValues (int NumEntries, int BlockOffset, double *Values, int *Indices) // ======================================================================== VecValues[0] = 1.0; VecValues[1] = 2.0; locerr = x->ReplaceGlobalValues(NumEntries, GIDSize-1, VecValues, VecGIDs); locerr = x->SumIntoGlobalValues(NumEntries, GIDSize-1, VecValues, VecGIDs); for (i=0; i<NumEntries; i++) { testGID = VecGIDs[i]; if (Map.MyGID(testGID)) { LIDOfGID = Map.LID(testGID); FirstEntryOfGID = Map.FirstPointInElement(LIDOfGID); if ((*x)[FirstEntryOfGID+GIDSize-1]!=(VecValues[i]+VecValues[i])) err++; if (verbose) cout << "x["<<FirstEntryOfGID+GIDSize-1<<"] = " << (*x)[FirstEntryOfGID+GIDSize-1] << " should = " << (VecValues[i]+VecValues[i]) << endl; } else if (locerr!=1) err++; // Test for GID out of range error (=1) } // ======================================================================== // Test Local "My" versions of same routine (less complicated) // ======================================================================== int * VecLIDs = new int[NumEntries]; VecLIDs[0] = testLID; VecLIDs[1] = testLID+1; // Some pathological chance that these LIDs are not valid VecValues[0] = 2.0; VecValues[1] = 4.0; locerr = x->ReplaceMyValues(NumEntries, VecValues, VecLIDs); for (i=0; i<NumEntries; i++) { testLID = VecLIDs[i]; LIDSize = EPETRA_MIN(LIDSize,Map.ElementSize(testLID)); // Need this value below FirstEntryOfLID = Map.FirstPointInElement(testLID); if ((*x)[FirstEntryOfLID]!=VecValues[i]) err++; if (verbose) cout << "x["<<FirstEntryOfLID<<"] = " << (*x)[FirstEntryOfLID] << " should = " << VecValues[i] << endl; } VecValues[0] = 4.0; VecValues[1] = 8.0; locerr = x->ReplaceMyValues(NumEntries, LIDSize-1, VecValues, VecLIDs); for (i=0; i<NumEntries; i++) { testLID = VecLIDs[i]; LIDSize = EPETRA_MIN(LIDSize,Map.ElementSize(testLID)); // Need this value below FirstEntryOfLID = Map.FirstPointInElement(testLID); if ((*x)[FirstEntryOfLID+LIDSize-1]!=VecValues[i]) err++; if (verbose) cout << "x["<<FirstEntryOfLID+LIDSize-1<<"] = " << (*x)[FirstEntryOfLID+LIDSize-1] << " should = " << VecValues[i] << endl; } VecValues[0] = 1.0; VecValues[1] = 1.0; locerr = x->ReplaceMyValues(NumEntries, VecValues, VecLIDs); locerr = x->SumIntoMyValues(NumEntries, VecValues, VecLIDs); for (i=0; i<NumEntries; i++) { testLID = VecLIDs[i]; LIDSize = EPETRA_MIN(LIDSize,Map.ElementSize(testLID)); // Need this value below FirstEntryOfLID = Map.FirstPointInElement(testLID); if ((*x)[FirstEntryOfLID]!=(VecValues[i]+VecValues[i])) err++; if (verbose) cout << "x["<<FirstEntryOfLID<<"] = " << (*x)[FirstEntryOfLID] << " should = " << (VecValues[i]+VecValues[i]) << endl; } VecValues[0] = 2.0; VecValues[1] = 4.0; locerr = x->ReplaceMyValues(NumEntries, LIDSize-1, VecValues, VecLIDs); locerr = x->SumIntoMyValues(NumEntries, LIDSize-1, VecValues, VecLIDs); for (i=0; i<NumEntries; i++) { testLID = VecLIDs[i]; LIDSize = EPETRA_MIN(LIDSize,Map.ElementSize(testLID)); // Need this value below FirstEntryOfLID = Map.FirstPointInElement(testLID); if ((*x)[FirstEntryOfLID+LIDSize-1]!=(VecValues[i]+VecValues[i])) err++; if (verbose) cout << "x["<<FirstEntryOfLID+LIDSize-1<<"] = " << (*x)[FirstEntryOfLID+LIDSize-1] << " should = " << (VecValues[i]+VecValues[i]) << endl; } delete [] VecValues; delete [] VecGIDs; delete [] VecLIDs; return(ierr); }