// ============================================================================ void Solve(const Epetra_RowMatrix* Matrix, const Epetra_MultiVector* LHS, const Epetra_MultiVector* RHS) { if (Matrix->Comm().NumProc() != 1) throw(Exception(__FILE__, __LINE__, "Solve() works only in serial")); if (LHS->NumVectors() != RHS->NumVectors()) throw(Exception(__FILE__, __LINE__, "number of vectors in multivectors not consistent")); if(Matrix->NumGlobalRows64() > std::numeric_limits<int>::max()) throw(Exception(__FILE__, __LINE__, "Matrix->NumGlobalRows64() > std::numeric_limits<int>::max()")); int n = static_cast<int>(Matrix->NumGlobalRows64()); int NumVectors = LHS->NumVectors(); Epetra_SerialDenseMatrix DenseMatrix; DenseMatrix.Shape(n, n); for (int i = 0 ; i < n ; ++i) for (int j = 0 ; j < n ; ++j) DenseMatrix(i,j) = 0.0; // allocate storage to extract matrix rows. int Length = Matrix->MaxNumEntries(); vector<double> Values(Length); vector<int> Indices(Length); for (int j = 0 ; j < Matrix->NumMyRows() ; ++j) { int NumEntries; int ierr = Matrix->ExtractMyRowCopy(j, Length, NumEntries, &Values[0], &Indices[0]); for (int k = 0 ; k < NumEntries ; ++k) DenseMatrix(j,Indices[k]) = Values[k]; } Epetra_SerialDenseMatrix DenseX(n, NumVectors); Epetra_SerialDenseMatrix DenseB(n, NumVectors); for (int i = 0 ; i < n ; ++i) for (int j = 0 ; j < NumVectors ; ++j) DenseB(i,j) = (*RHS)[j][i]; Epetra_SerialDenseSolver DenseSolver; DenseSolver.SetMatrix(DenseMatrix); DenseSolver.SetVectors(DenseX,DenseB); DenseSolver.Factor(); DenseSolver.Solve(); for (int i = 0 ; i < n ; ++i) for (int j = 0 ; j < NumVectors ; ++j) (*LHS)[j][i] = DenseX(i,j); }
int Epetra_FECrsMatrix::ReplaceGlobalValues(const Epetra_LongLongSerialDenseVector& indices, const Epetra_SerialDenseMatrix& values, int format) { if (indices.Length() != values.M() || indices.Length() != values.N()) { return(-1); } return( ReplaceGlobalValues(indices.Length(), indices.Values(), values.A(), format) ); }
void ISVDUDV::shrink(const int down, std::vector<double> &S, Epetra_SerialDenseMatrix &U, Epetra_SerialDenseMatrix &V) { // // put RU1 into an Epetra MultiVector Epetra_LocalMap LocalMap(curRank_, 0, U_->Map().Comm()); Epetra_MultiVector Uh1(Epetra_DataAccess::View, LocalMap, U.A(), U.LDA(), curRank_-down); Epetra_MultiVector Vh1(Epetra_DataAccess::View, LocalMap, V.A(), V.LDA(), curRank_-down); // // update bases Teuchos::RCP<Epetra_MultiVector> newwU, fullU, newU, newwV, fullV, newV; fullU = Teuchos::rcp( new Epetra_MultiVector(Epetra_DataAccess::View,*U_,0,curRank_) ); newwU = Teuchos::rcp( new Epetra_MultiVector(Epetra_DataAccess::View,*workU_,0,curRank_-down) ); // multiply by Uh1 int info = newwU->Multiply('N','N',1.0,*fullU,Uh1,0.0); TEUCHOS_TEST_FOR_EXCEPTION(info != 0,std::logic_error,"ISVDUDV::shrink(): Error calling EMV::Multiply(U)."); fullU = Teuchos::null; newU = Teuchos::rcp( new Epetra_MultiVector(Epetra_DataAccess::View,*U_,0,curRank_-down) ); *newU = *newwU; newU = Teuchos::null; newwU = Teuchos::null; // multiply by Vh1 // get multivector views of V(1:numProc,1:curRank) and workV(1:numProc,1:curRank-down) double *V_A, *workV_A; int V_LDA, workV_LDA; info = V_->ExtractView(&V_A,&V_LDA); TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error, "RBGen::ISVDUDV::shrink(): Error calling Epetra_MultiVector::ExtractView() on V_."); info = workV_->ExtractView(&workV_A,&workV_LDA); TEUCHOS_TEST_FOR_EXCEPTION(info != 0, std::logic_error, "RBGen::ISVDUDV::shrink(): Error calling Epetra_MultiVector::ExtractView() on workV_."); Epetra_LocalMap lclmap(numProc_,0,A_->Comm()); fullV = Teuchos::rcp( new Epetra_MultiVector(Epetra_DataAccess::View,lclmap, V_A, V_LDA,curRank_ ) ); newwV = Teuchos::rcp( new Epetra_MultiVector(Epetra_DataAccess::View,lclmap,workV_A,workV_LDA,curRank_-down) ); // multiply workV = fullV * Vh1 info = newwV->Multiply('N','N',1.0,*fullV,Vh1,0.0); TEUCHOS_TEST_FOR_EXCEPTION(info != 0,std::logic_error,"ISVDUDV::shrink(): Error calling EMV::Multiply(V)."); fullV = Teuchos::null; // now set newV = workV newV = Teuchos::rcp( new Epetra_MultiVector(Epetra_DataAccess::View,lclmap, V_A, V_LDA, curRank_-down) ); *newV = *newwV; newV = Teuchos::null; newwV = Teuchos::null; // save new singular values for (int i=0; i<curRank_-down; i++) { sigma_[i] = S[i]; } curRank_ = curRank_-down; }
int Epetra_FECrsMatrix::ReplaceGlobalValues(const Epetra_IntSerialDenseVector& rows, const Epetra_IntSerialDenseVector& cols, const Epetra_SerialDenseMatrix& values, int format) { if (rows.Length() != values.M() || cols.Length() != values.N()) { return(-1); } return( ReplaceGlobalValues(rows.Length(), rows.Values(), cols.Length(), cols.Values(), values.A(), format) ); }
//============================================================================= int Epetra_SerialDenseSVD::SetMatrix(Epetra_SerialDenseMatrix & A_in) { ResetMatrix(); Matrix_ = &A_in; // Factor_ = &A_in; M_ = A_in.M(); N_ = A_in.N(); Min_MN_ = EPETRA_MIN(M_,N_); LDA_ = A_in.LDA(); // LDAF_ = LDA_; A_ = A_in.A(); // AF_ = A_in.A(); return(0); }
//========================================================================= // checks if two matrices are independent or not bool seperateData(Epetra_SerialDenseMatrix& a, Epetra_SerialDenseMatrix& b) { bool seperate; int r = EPETRA_MIN(a.M(),b.M()) / 2; // ensures (r,c) is valid int c = EPETRA_MIN(a.N(),b.N()) / 2; // in both matrices double orig_a = a(r,c); double new_value = a(r,c) + 1; if(b(r,c) == new_value) // there's a chance b could be independent, but new_value++; // already have new_value in (r,c). a(r,c) = new_value; if(b(r,c) == new_value) seperate = false; else seperate = true; a(r,c) = orig_a; // undo change we made to a return(seperate); }
//========================================================================= // checks the signatures of two matrices bool identicalSignatures(Epetra_SerialDenseMatrix& a, Epetra_SerialDenseMatrix& b, bool testLDA) { if((a.M() != b.M() )|| // check properties first (a.N() != b.N() )|| (a.CV() != b.CV() )) return(false); if(testLDA == true) // if we are coming from op= c->c #2 (have enough space) if(a.LDA() != b.LDA()) // then we don't check LDA (but we do check it in the test function) return(false); if(a.CV() == View) { // if we're still here, we need to check the data if(a.A() != b.A()) // for a view, this just means checking the pointers return(false); // for a copy, this means checking each element } else { // CV == Copy const int m = a.M(); const int n = a.N(); for(int i = 0; i < m; i++) for(int j = 0; j < n; j++) { if(a(i,j) != b(i,j)) return(false); } } return(true); // if we're still here, signatures are identical }
int main(int argc, char *argv[]) { int ierr = 0, i, j, k; bool debug = false; #ifdef EPETRA_MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else Epetra_SerialComm Comm; #endif 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.MyPID()==0) cout << Epetra_Version() << endl << endl; int rank = Comm.MyPID(); // char tmp; // if (rank==0) cout << "Press any key to continue..."<< endl; // if (rank==0) cin >> tmp; // Comm.Barrier(); Comm.SetTracebackMode(0); // This should shut down any error traceback reporting if (verbose) cout << Comm <<endl; // bool verbose1 = verbose; // Redefine verbose to only print on PE 0 if (verbose && rank!=0) verbose = false; int N = 20; int NRHS = 4; double * A = new double[N*N]; double * A1 = new double[N*N]; double * X = new double[(N+1)*NRHS]; double * X1 = new double[(N+1)*NRHS]; int LDX = N+1; int LDX1 = N+1; double * B = new double[N*NRHS]; double * B1 = new double[N*NRHS]; int LDB = N; int LDB1 = N; int LDA = N; int LDA1 = LDA; double OneNorm1; bool Transpose = false; Epetra_SerialDenseSolver solver; Epetra_SerialDenseMatrix * Matrix; for (int kk=0; kk<2; kk++) { for (i=1; i<=N; i++) { GenerateHilbert(A, LDA, i); OneNorm1 = 0.0; for (j=1; j<=i; j++) OneNorm1 += 1.0/((double) j); // 1-Norm = 1 + 1/2 + ...+1/n if (kk==0) { Matrix = new Epetra_SerialDenseMatrix(View, A, LDA, i, i); LDA1 = LDA; } else { Matrix = new Epetra_SerialDenseMatrix(Copy, A, LDA, i, i); LDA1 = i; } GenerateHilbert(A1, LDA1, i); if (kk==1) { solver.FactorWithEquilibration(true); solver.SolveWithTranspose(true); Transpose = true; solver.SolveToRefinedSolution(true); } for (k=0; k<NRHS; k++) for (j=0; j<i; j++) { B[j+k*LDB] = 1.0/((double) (k+3)*(j+3)); B1[j+k*LDB1] = B[j+k*LDB1]; } Epetra_SerialDenseMatrix Epetra_B(View, B, LDB, i, NRHS); Epetra_SerialDenseMatrix Epetra_X(View, X, LDX, i, NRHS); solver.SetMatrix(*Matrix); solver.SetVectors(Epetra_X, Epetra_B); ierr = check(solver, A1, LDA1, i, NRHS, OneNorm1, B1, LDB1, X1, LDX1, Transpose, verbose); assert (ierr>-1); delete Matrix; if (ierr!=0) { if (verbose) cout << "Factorization failed due to bad conditioning. This is normal if RCOND is small." << endl; break; } } } delete [] A; delete [] A1; delete [] X; delete [] X1; delete [] B; delete [] B1; ///////////////////////////////////////////////////////////////////// // Now test norms and scaling functions ///////////////////////////////////////////////////////////////////// Epetra_SerialDenseMatrix D; double ScalarA = 2.0; int DM = 10; int DN = 8; D.Shape(DM, DN); for (j=0; j<DN; j++) for (i=0; i<DM; i++) D[j][i] = (double) (1+i+j*DM) ; //cout << D << endl; double NormInfD_ref = (double)(DM*(DN*(DN+1))/2); double NormOneD_ref = (double)((DM*DN*(DM*DN+1))/2 - (DM*(DN-1)*(DM*(DN-1)+1))/2 ); double NormInfD = D.NormInf(); double NormOneD = D.NormOne(); if (verbose) { cout << " *** Before scaling *** " << endl << " Computed one-norm of test matrix = " << NormOneD << endl << " Expected one-norm = " << NormOneD_ref << endl << " Computed inf-norm of test matrix = " << NormInfD << endl << " Expected inf-norm = " << NormInfD_ref << endl; } D.Scale(ScalarA); // Scale entire D matrix by this value NormInfD = D.NormInf(); NormOneD = D.NormOne(); if (verbose) { cout << " *** After scaling *** " << endl << " Computed one-norm of test matrix = " << NormOneD << endl << " Expected one-norm = " << NormOneD_ref*ScalarA << endl << " Computed inf-norm of test matrix = " << NormInfD << endl << " Expected inf-norm = " << NormInfD_ref*ScalarA << endl; } ///////////////////////////////////////////////////////////////////// // Now test that A.Multiply(false, x, y) produces the same result // as y.Multiply('N','N', 1.0, A, x, 0.0). ///////////////////////////////////////////////////////////////////// N = 10; int M = 10; LDA = N; Epetra_SerialDenseMatrix smallA(N, M, false); Epetra_SerialDenseMatrix x(N, 1, false); Epetra_SerialDenseMatrix y1(N, 1, false); Epetra_SerialDenseMatrix y2(N, 1, false); for(i=0; i<N; ++i) { for(j=0; j<M; ++j) { smallA(i,j) = 1.0*i+2.0*j+1.0; } x(i,0) = 1.0; y1(i,0) = 0.0; y2(i,0) = 0.0; } //quick check of operator== if (x == y1) { if (verbose) cout << "err in Epetra_SerialDenseMatrix::operator==, " << "erroneously returned true." << std::endl; return(-1); } //quick check of operator!= if (x != x) { if (verbose) cout << "err in Epetra_SerialDenseMatrix::operator==, " << "erroneously returned true." << std::endl; return(-1); } int err1 = smallA.Multiply(false, x, y1); int err2 = y2.Multiply('N','N', 1.0, smallA, x, 0.0); if (err1 != 0 || err2 != 0) { if (verbose) cout << "err in Epetra_SerialDenseMatrix::Multiply"<<endl; return(err1+err2); } for(i=0; i<N; ++i) { if (y1(i,0) != y2(i,0)) { if (verbose) cout << "different versions of Multiply don't match."<<endl; return(-99); } } ///////////////////////////////////////////////////////////////////// // Now test for larger system, both correctness and performance. ///////////////////////////////////////////////////////////////////// N = 2000; NRHS = 5; LDA = N; LDB = N; LDX = N; if (verbose) cout << "\n\nComputing factor of an " << N << " x " << N << " general matrix...Please wait.\n\n" << endl; // Define A and X A = new double[LDA*N]; X = new double[LDB*NRHS]; for (j=0; j<N; j++) { for (k=0; k<NRHS; k++) X[j+k*LDX] = 1.0/((double) (j+5+k)); for (i=0; i<N; i++) { if (i==((j+2)%N)) A[i+j*LDA] = 100.0 + i; else A[i+j*LDA] = -11.0/((double) (i+5)*(j+2)); } } // Define Epetra_SerialDenseMatrix object Epetra_SerialDenseMatrix BigMatrix(Copy, A, LDA, N, N); Epetra_SerialDenseMatrix OrigBigMatrix(View, A, LDA, N, N); Epetra_SerialDenseSolver BigSolver; BigSolver.FactorWithEquilibration(true); BigSolver.SetMatrix(BigMatrix); // Time factorization Epetra_Flops counter; BigSolver.SetFlopCounter(counter); Epetra_Time Timer(Comm); double tstart = Timer.ElapsedTime(); ierr = BigSolver.Factor(); if (ierr!=0 && verbose) cout << "Error in factorization = "<<ierr<< endl; assert(ierr==0); double time = Timer.ElapsedTime() - tstart; double FLOPS = counter.Flops(); double MFLOPS = FLOPS/time/1000000.0; if (verbose) cout << "MFLOPS for Factorization = " << MFLOPS << endl; // Define Left hand side and right hand side Epetra_SerialDenseMatrix LHS(View, X, LDX, N, NRHS); Epetra_SerialDenseMatrix RHS; RHS.Shape(N,NRHS); // Allocate RHS // Compute RHS from A and X Epetra_Flops RHS_counter; RHS.SetFlopCounter(RHS_counter); tstart = Timer.ElapsedTime(); RHS.Multiply('N', 'N', 1.0, OrigBigMatrix, LHS, 0.0); time = Timer.ElapsedTime() - tstart; Epetra_SerialDenseMatrix OrigRHS = RHS; FLOPS = RHS_counter.Flops(); MFLOPS = FLOPS/time/1000000.0; if (verbose) cout << "MFLOPS to build RHS (NRHS = " << NRHS <<") = " << MFLOPS << endl; // Set LHS and RHS and solve BigSolver.SetVectors(LHS, RHS); tstart = Timer.ElapsedTime(); ierr = BigSolver.Solve(); if (ierr==1 && verbose) cout << "LAPACK guidelines suggest this matrix might benefit from equilibration." << endl; else if (ierr!=0 && verbose) cout << "Error in solve = "<<ierr<< endl; assert(ierr>=0); time = Timer.ElapsedTime() - tstart; FLOPS = BigSolver.Flops(); MFLOPS = FLOPS/time/1000000.0; if (verbose) cout << "MFLOPS for Solve (NRHS = " << NRHS <<") = " << MFLOPS << endl; double * resid = new double[NRHS]; bool OK = Residual(N, NRHS, A, LDA, BigSolver.Transpose(), BigSolver.X(), BigSolver.LDX(), OrigRHS.A(), OrigRHS.LDA(), resid); if (verbose) { if (!OK) cout << "************* Residual do not meet tolerance *************" << endl; for (i=0; i<NRHS; i++) cout << "Residual[" << i <<"] = "<< resid[i] << endl; cout << endl; } // Solve again using the Epetra_SerialDenseVector class for LHS and RHS Epetra_SerialDenseVector X2; Epetra_SerialDenseVector B2; X2.Size(BigMatrix.N()); B2.Size(BigMatrix.M()); int length = BigMatrix.N(); {for (int kk=0; kk<length; kk++) X2[kk] = ((double ) kk)/ ((double) length);} // Define entries of X2 RHS_counter.ResetFlops(); B2.SetFlopCounter(RHS_counter); tstart = Timer.ElapsedTime(); B2.Multiply('N', 'N', 1.0, OrigBigMatrix, X2, 0.0); // Define B2 = A*X2 time = Timer.ElapsedTime() - tstart; Epetra_SerialDenseVector OrigB2 = B2; FLOPS = RHS_counter.Flops(); MFLOPS = FLOPS/time/1000000.0; if (verbose) cout << "MFLOPS to build single RHS = " << MFLOPS << endl; // Set LHS and RHS and solve BigSolver.SetVectors(X2, B2); tstart = Timer.ElapsedTime(); ierr = BigSolver.Solve(); time = Timer.ElapsedTime() - tstart; if (ierr==1 && verbose) cout << "LAPACK guidelines suggest this matrix might benefit from equilibration." << endl; else if (ierr!=0 && verbose) cout << "Error in solve = "<<ierr<< endl; assert(ierr>=0); FLOPS = counter.Flops(); MFLOPS = FLOPS/time/1000000.0; if (verbose) cout << "MFLOPS to solve single RHS = " << MFLOPS << endl; OK = Residual(N, 1, A, LDA, BigSolver.Transpose(), BigSolver.X(), BigSolver.LDX(), OrigB2.A(), OrigB2.LDA(), resid); if (verbose) { if (!OK) cout << "************* Residual do not meet tolerance *************" << endl; cout << "Residual = "<< resid[0] << endl; } delete [] resid; delete [] A; delete [] X; /////////////////////////////////////////////////// // Now test default constructor and index operators /////////////////////////////////////////////////// N = 5; Epetra_SerialDenseMatrix C; // Implicit call to default constructor, should not need to call destructor C.Shape(5,5); // Make it 5 by 5 double * C1 = new double[N*N]; GenerateHilbert(C1, N, N); // Generate Hilber matrix C1[1+2*N] = 1000.0; // Make matrix nonsymmetric // Fill values of C with Hilbert values for (i=0; i<N; i++) for (j=0; j<N; j++) C(i,j) = C1[i+j*N]; // Test if values are correctly written and read for (i=0; i<N; i++) for (j=0; j<N; j++) { assert(C(i,j) == C1[i+j*N]); assert(C(i,j) == C[j][i]); } if (verbose) cout << "Default constructor and index operator check OK. Values of Hilbert matrix = " << endl << C << endl << "Values should be 1/(i+j+1), except value (1,2) should be 1000" << endl; delete [] C1; // now test sized/shaped constructor Epetra_SerialDenseMatrix shapedMatrix(10, 12); assert(shapedMatrix.M() == 10); assert(shapedMatrix.N() == 12); for(i = 0; i < 10; i++) for(j = 0; j < 12; j++) assert(shapedMatrix(i, j) == 0.0); Epetra_SerialDenseVector sizedVector(20); assert(sizedVector.Length() == 20); for(i = 0; i < 20; i++) assert(sizedVector(i) == 0.0); if (verbose) cout << "Shaped/sized constructors check OK." << endl; // test Copy/View mode in op= and cpy ctr int temperr = 0; temperr = matrixAssignment(verbose, debug); if(verbose && temperr == 0) cout << "Operator = checked OK." << endl; EPETRA_TEST_ERR(temperr, ierr); temperr = matrixCpyCtr(verbose, debug); if(verbose && temperr == 0) cout << "Copy ctr checked OK." << endl; EPETRA_TEST_ERR(temperr, ierr); // Test some vector methods Epetra_SerialDenseVector v1(3); v1[0] = 1.0; v1[1] = 3.0; v1[2] = 2.0; Epetra_SerialDenseVector v2(3); v2[0] = 2.0; v2[1] = 1.0; v2[2] = -2.0; temperr = 0; if (v1.Norm1()!=6.0) temperr++; if (fabs(sqrt(14.0)-v1.Norm2())>1.0e-6) temperr++; if (v1.NormInf()!=3.0) temperr++; if(verbose && temperr == 0) cout << "Vector Norms checked OK." << endl; temperr = 0; if (v1.Dot(v2)!=1.0) temperr++; if(verbose && temperr == 0) cout << "Vector Dot product checked OK." << endl; #ifdef EPETRA_MPI MPI_Finalize() ; #endif /* end main */ return ierr ; }
void BilinearFormUtility::computeStiffnessMatrix(FieldContainer<double> &stiffness, FieldContainer<double> &innerProductMatrix, FieldContainer<double> &optimalTestWeights) { // stiffness has dimensions (numCells, numTrialDofs, numTrialDofs) // innerProductMatrix has dim. (numCells, numTestDofs, numTestDofs) // optimalTestWeights has dim. (numCells, numTrialDofs, numTestDofs) // all this does is computes stiffness = weights^T * innerProductMatrix * weights int numCells = stiffness.dimension(0); int numTrialDofs = stiffness.dimension(1); int numTestDofs = innerProductMatrix.dimension(1); // check that all the dimensions are compatible: TEUCHOS_TEST_FOR_EXCEPTION( ( optimalTestWeights.dimension(0) != numCells ), std::invalid_argument, "stiffness.dimension(0) and optimalTestWeights.dimension(0) (numCells) do not match."); TEUCHOS_TEST_FOR_EXCEPTION( ( optimalTestWeights.dimension(1) != numTrialDofs ), std::invalid_argument, "numTrialDofs and optimalTestWeights.dimension(1) do not match."); TEUCHOS_TEST_FOR_EXCEPTION( ( optimalTestWeights.dimension(2) != numTestDofs ), std::invalid_argument, "numTestDofs and optimalTestWeights.dimension(2) do not match."); TEUCHOS_TEST_FOR_EXCEPTION( ( innerProductMatrix.dimension(2) != innerProductMatrix.dimension(1) ), std::invalid_argument, "innerProductMatrix.dimension(1) and innerProductMatrix.dimension(2) do not match."); TEUCHOS_TEST_FOR_EXCEPTION( ( stiffness.dimension(1) != stiffness.dimension(2) ), std::invalid_argument, "stiffness.dimension(1) and stiffness.dimension(2) do not match."); stiffness.initialize(0); for (int cellIndex=0; cellIndex < numCells; cellIndex++) { Epetra_SerialDenseMatrix weightsT(Copy, &optimalTestWeights(cellIndex,0,0), optimalTestWeights.dimension(2), // stride optimalTestWeights.dimension(2),optimalTestWeights.dimension(1)); Epetra_SerialDenseMatrix ipMatrixT(Copy, &innerProductMatrix(cellIndex,0,0), innerProductMatrix.dimension(2), // stride innerProductMatrix.dimension(2),innerProductMatrix.dimension(1)); Epetra_SerialDenseMatrix stiffT (View, &stiffness(cellIndex,0,0), stiffness.dimension(2), // stride stiffness.dimension(2),stiffness.dimension(1)); Epetra_SerialDenseMatrix intermediate( numTrialDofs, numTestDofs ); // account for the fact that SDM is column-major and FC is row-major: // (weightsT) * (ipMatrixT)^T * (weightsT)^T int success = intermediate.Multiply('T','T',1.0,weightsT,ipMatrixT,0.0); if (success != 0) { cout << "computeStiffnessMatrix: intermediate.Multiply() failed with error code " << success << endl; } success = stiffT.Multiply('N','N',1.0,intermediate,weightsT,0.0); // stiffT is technically the transpose of stiffness, but the construction A^T * B * A is symmetric even in general... if (success != 0) { cout << "computeStiffnessMatrix: stiffT.Multiply() failed with error code " << success << endl; } } if ( ! checkForZeroRowsAndColumns("stiffness",stiffness) ) { //cout << "stiffness: " << stiffness; } bool enforceNumericalSymmetry = false; if (enforceNumericalSymmetry) { for (unsigned int c=0; c < numCells; c++) for (unsigned int i=0; i < numTrialDofs; i++) for (unsigned int j=i+1; j < numTrialDofs; j++) { stiffness(c,i,j) = (stiffness(c,i,j) + stiffness(c,j,i)) / 2.0; stiffness(c,j,i) = stiffness(c,i,j); } } }
int main(int argc, char *argv[]) { int ierr = 0, i, j, k; #ifdef EPETRA_MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else Epetra_SerialComm Comm; #endif 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.MyPID()==0) std::cout << Epetra_Version() << std::endl << std::endl; int rank = Comm.MyPID(); // char tmp; // if (rank==0) std::cout << "Press any key to continue..."<< std::endl; // if (rank==0) cin >> tmp; // Comm.Barrier(); Comm.SetTracebackMode(0); // This should shut down any error traceback reporting if (verbose) std::cout << Comm << std::endl; // bool verbose1 = verbose; // Redefine verbose to only print on PE 0 if (verbose && rank!=0) verbose = false; int N = 20; int NRHS = 4; double * A = new double[N*N]; double * A1 = new double[N*N]; double * X = new double[(N+1)*NRHS]; double * X1 = new double[(N+1)*NRHS]; int LDX = N+1; int LDX1 = N+1; double * B = new double[N*NRHS]; double * B1 = new double[N*NRHS]; int LDB = N; int LDB1 = N; int LDA = N; int LDA1 = LDA; double OneNorm1; bool Upper = false; Epetra_SerialSpdDenseSolver solver; Epetra_SerialSymDenseMatrix * Matrix; for (int kk=0; kk<2; kk++) { for (i=1; i<=N; i++) { GenerateHilbert(A, LDA, i); OneNorm1 = 0.0; for (j=1; j<=i; j++) OneNorm1 += 1.0/((double) j); // 1-Norm = 1 + 1/2 + ...+1/n if (kk==0) { Matrix = new Epetra_SerialSymDenseMatrix(View, A, LDA, i); LDA1 = LDA; } else { Matrix = new Epetra_SerialSymDenseMatrix(Copy, A, LDA, i); LDA1 = i; } GenerateHilbert(A1, LDA1, i); if (kk==1) { solver.FactorWithEquilibration(true); Matrix->SetUpper(); Upper = true; solver.SolveToRefinedSolution(false); } for (k=0; k<NRHS; k++) for (j=0; j<i; j++) { B[j+k*LDB] = 1.0/((double) (k+3)*(j+3)); B1[j+k*LDB1] = B[j+k*LDB1]; } Epetra_SerialDenseMatrix Epetra_B(View, B, LDB, i, NRHS); Epetra_SerialDenseMatrix Epetra_X(View, X, LDX, i, NRHS); solver.SetMatrix(*Matrix); solver.SetVectors(Epetra_X, Epetra_B); ierr = check(solver, A1, LDA1, i, NRHS, OneNorm1, B1, LDB1, X1, LDX1, Upper, verbose); assert (ierr>-1); delete Matrix; if (ierr!=0) { if (verbose) std::cout << "Factorization failed due to bad conditioning. This is normal if SCOND is small." << std::endl; break; } } } delete [] A; delete [] A1; delete [] X; delete [] X1; delete [] B; delete [] B1; ///////////////////////////////////////////////////////////////////// // Now test norms and scaling functions ///////////////////////////////////////////////////////////////////// Epetra_SerialSymDenseMatrix D; double ScalarA = 2.0; int DM = 10; int DN = 10; D.Shape(DM); for (j=0; j<DN; j++) for (i=0; i<DM; i++) D[j][i] = (double) (1+i+j*DM) ; //std::cout << D << std::endl; double NormInfD_ref = (double)(DM*(DN*(DN+1))/2); double NormOneD_ref = NormInfD_ref; double NormInfD = D.NormInf(); double NormOneD = D.NormOne(); if (verbose) { std::cout << " *** Before scaling *** " << std::endl << " Computed one-norm of test matrix = " << NormOneD << std::endl << " Expected one-norm = " << NormOneD_ref << std::endl << " Computed inf-norm of test matrix = " << NormInfD << std::endl << " Expected inf-norm = " << NormInfD_ref << std::endl; } D.Scale(ScalarA); // Scale entire D matrix by this value //std::cout << D << std::endl; NormInfD = D.NormInf(); NormOneD = D.NormOne(); if (verbose) { std::cout << " *** After scaling *** " << std::endl << " Computed one-norm of test matrix = " << NormOneD << std::endl << " Expected one-norm = " << NormOneD_ref*ScalarA << std::endl << " Computed inf-norm of test matrix = " << NormInfD << std::endl << " Expected inf-norm = " << NormInfD_ref*ScalarA << std::endl; } ///////////////////////////////////////////////////////////////////// // Now test for larger system, both correctness and performance. ///////////////////////////////////////////////////////////////////// N = 2000; NRHS = 5; LDA = N; LDB = N; LDX = N; if (verbose) std::cout << "\n\nComputing factor of an " << N << " x " << N << " SPD matrix...Please wait.\n\n" << std::endl; // Define A and X A = new double[LDA*N]; X = new double[LDB*NRHS]; for (j=0; j<N; j++) { for (k=0; k<NRHS; k++) X[j+k*LDX] = 1.0/((double) (j+5+k)); for (i=0; i<N; i++) { if (i==j) A[i+j*LDA] = 100.0 + i; else A[i+j*LDA] = -1.0/((double) (i+10)*(j+10)); } } // Define Epetra_SerialDenseMatrix object Epetra_SerialSymDenseMatrix BigMatrix(Copy, A, LDA, N); Epetra_SerialSymDenseMatrix OrigBigMatrix(View, A, LDA, N); Epetra_SerialSpdDenseSolver BigSolver; BigSolver.FactorWithEquilibration(true); BigSolver.SetMatrix(BigMatrix); // Time factorization Epetra_Flops counter; BigSolver.SetFlopCounter(counter); Epetra_Time Timer(Comm); double tstart = Timer.ElapsedTime(); ierr = BigSolver.Factor(); if (ierr!=0 && verbose) std::cout << "Error in factorization = "<<ierr<< std::endl; assert(ierr==0); double time = Timer.ElapsedTime() - tstart; double FLOPS = counter.Flops(); double MFLOPS = FLOPS/time/1000000.0; if (verbose) std::cout << "MFLOPS for Factorization = " << MFLOPS << std::endl; // Define Left hand side and right hand side Epetra_SerialDenseMatrix LHS(View, X, LDX, N, NRHS); Epetra_SerialDenseMatrix RHS; RHS.Shape(N,NRHS); // Allocate RHS // Compute RHS from A and X Epetra_Flops RHS_counter; RHS.SetFlopCounter(RHS_counter); tstart = Timer.ElapsedTime(); RHS.Multiply('L', 1.0, OrigBigMatrix, LHS, 0.0); // Symmetric Matrix-multiply time = Timer.ElapsedTime() - tstart; Epetra_SerialDenseMatrix OrigRHS = RHS; FLOPS = RHS_counter.Flops(); MFLOPS = FLOPS/time/1000000.0; if (verbose) std::cout << "MFLOPS to build RHS (NRHS = " << NRHS <<") = " << MFLOPS << std::endl; // Set LHS and RHS and solve BigSolver.SetVectors(LHS, RHS); tstart = Timer.ElapsedTime(); ierr = BigSolver.Solve(); if (ierr==1 && verbose) std::cout << "LAPACK guidelines suggest this matrix might benefit from equilibration." << std::endl; else if (ierr!=0 && verbose) std::cout << "Error in solve = "<<ierr<< std::endl; assert(ierr>=0); time = Timer.ElapsedTime() - tstart; FLOPS = BigSolver.Flops(); MFLOPS = FLOPS/time/1000000.0; if (verbose) std::cout << "MFLOPS for Solve (NRHS = " << NRHS <<") = " << MFLOPS << std::endl; double * resid = new double[NRHS]; bool OK = Residual(N, NRHS, A, LDA, BigSolver.X(), BigSolver.LDX(), OrigRHS.A(), OrigRHS.LDA(), resid); if (verbose) { if (!OK) std::cout << "************* Residual do not meet tolerance *************" << std::endl; for (i=0; i<NRHS; i++) std::cout << "Residual[" << i <<"] = "<< resid[i] << std::endl; std::cout << std::endl; } // Solve again using the Epetra_SerialDenseVector class for LHS and RHS Epetra_SerialDenseVector X2; Epetra_SerialDenseVector B2; X2.Size(BigMatrix.N()); B2.Size(BigMatrix.M()); int length = BigMatrix.N(); {for (int kk=0; kk<length; kk++) X2[kk] = ((double ) kk)/ ((double) length);} // Define entries of X2 RHS_counter.ResetFlops(); B2.SetFlopCounter(RHS_counter); tstart = Timer.ElapsedTime(); B2.Multiply('N', 'N', 1.0, OrigBigMatrix, X2, 0.0); // Define B2 = A*X2 time = Timer.ElapsedTime() - tstart; Epetra_SerialDenseVector OrigB2 = B2; FLOPS = RHS_counter.Flops(); MFLOPS = FLOPS/time/1000000.0; if (verbose) std::cout << "MFLOPS to build single RHS = " << MFLOPS << std::endl; // Set LHS and RHS and solve BigSolver.SetVectors(X2, B2); tstart = Timer.ElapsedTime(); ierr = BigSolver.Solve(); time = Timer.ElapsedTime() - tstart; if (ierr==1 && verbose) std::cout << "LAPACK guidelines suggest this matrix might benefit from equilibration." << std::endl; else if (ierr!=0 && verbose) std::cout << "Error in solve = "<<ierr<< std::endl; assert(ierr>=0); FLOPS = counter.Flops(); MFLOPS = FLOPS/time/1000000.0; if (verbose) std::cout << "MFLOPS to solve single RHS = " << MFLOPS << std::endl; OK = Residual(N, 1, A, LDA, BigSolver.X(), BigSolver.LDX(), OrigB2.A(), OrigB2.LDA(), resid); if (verbose) { if (!OK) std::cout << "************* Residual do not meet tolerance *************" << std::endl; std::cout << "Residual = "<< resid[0] << std::endl; } delete [] resid; delete [] A; delete [] X; /////////////////////////////////////////////////// // Now test default constructor and index operators /////////////////////////////////////////////////// N = 5; Epetra_SerialSymDenseMatrix C; // Implicit call to default constructor, should not need to call destructor C.Shape(5); // Make it 5 by 5 double * C1 = new double[N*N]; GenerateHilbert(C1, N, N); // Generate Hilber matrix C1[1+2*N] = 1000.0; // Make matrix nonsymmetric // Fill values of C with Hilbert values for (i=0; i<N; i++) for (j=0; j<N; j++) C(i,j) = C1[i+j*N]; // Test if values are correctly written and read for (i=0; i<N; i++) for (j=0; j<N; j++) { assert(C(i,j) == C1[i+j*N]); assert(C(i,j) == C[j][i]); } if (verbose) std::cout << "Default constructor and index operator check OK. Values of Hilbert matrix = " << std::endl << C << std::endl << "Values should be 1/(i+j+1), except value (1,2) should be 1000" << std::endl; delete [] C1; #ifdef EPETRA_MPI MPI_Finalize() ; #endif /* end main */ return ierr ; }
//============================================================================= int Epetra_SerialDenseSVD::SetVectors(Epetra_SerialDenseMatrix & X_in, Epetra_SerialDenseMatrix & B_in) { if (B_in.M()!=X_in.M() || B_in.N() != X_in.N()) EPETRA_CHK_ERR(-1); if (B_in.A()==0) EPETRA_CHK_ERR(-2); if (B_in.LDA()<1) EPETRA_CHK_ERR(-3); if (X_in.A()==0) EPETRA_CHK_ERR(-4); if (X_in.LDA()<1) EPETRA_CHK_ERR(-5); ResetVectors(); LHS_ = &X_in; RHS_ = &B_in; NRHS_ = B_in.N(); B_ = B_in.A(); LDB_ = B_in.LDA(); X_ = X_in.A(); LDX_ = X_in.LDA(); return(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 int NSIDE = 1; int NPIX ; int NSTOKES = 3; NPIX = 12. * NSIDE * NSIDE +1; //total pixel size, each pixel is an element which contains 3 floats which are IQU Epetra_BlockMap PixMap(NPIX,NSTOKES,0,Comm); int * PixMyGlobalElements = PixMap.MyGlobalElements(); cout << PixMap << endl; Epetra_FEVbrMatrix invM(Copy, PixMap, 1); int BlockIndices[1]; BlockIndices[0] = 2; int RowDim, NumBlockEntries; int err; Epetra_SerialDenseMatrix Mpp(NSTOKES, NSTOKES); Mpp[0][0] = 1.; cout << Mpp << endl; Epetra_SerialDenseMatrix * Zero; for( int i=0 ; i<PixMap.NumMyElements(); ++i ) { //loop on local pixel BlockIndices[0] = PixMyGlobalElements[i]; Zero = new Epetra_SerialDenseMatrix(NSTOKES, NSTOKES); invM.BeginInsertGlobalValues(BlockIndices[0], 1, BlockIndices); err = invM.SubmitBlockEntry(Zero->A(), Zero->LDA(), NSTOKES, NSTOKES); if (err != 0) { cout << "PID:" << Comm.MyPID() << "Error in inserting init zero values in M, error code:" << err << endl; } err = invM.EndSubmitEntries(); } BlockIndices[0] = 2; cout << invM << endl; int NumHits = 2*Comm.MyPID() + 5; for( int i=0 ; i<NumHits; ++i ) { //loop on local pointing invM.BeginSumIntoGlobalValues(BlockIndices[0], 1, BlockIndices); err = invM.SubmitBlockEntry(Mpp.A(), Mpp.LDA(), NSTOKES, NSTOKES); //FIXME check order if (err != 0) { cout << "PID:" << Comm.MyPID() << "Error in inserting values in M, error code:" << err << endl; } err = invM.EndSubmitEntries(); if (err != 0) { cout << "PID:" << Comm.MyPID() << " LocalRow[i]:" << i << " Error in ending submit entries in M, error code:" << err << endl; } } invM.GlobalAssemble(); cout << invM << endl; if (Comm.MyPID() == 0) { Epetra_SerialDenseMatrix * blockM; int * BlockIndicesBlock; invM.BeginExtractMyBlockRowView(2, RowDim, NumBlockEntries, BlockIndicesBlock); invM.ExtractEntryView(blockM); cout << *blockM << endl; cout << "*blockM[0][0]" << endl; cout << *blockM[0][0] << endl; cout << "*blockM[0][4]" << endl; cout << *blockM[0][4] << endl; cout << "*blockM[1][1]" << endl; cout << *blockM[1][1] << endl; } #ifdef HAVE_MPI MPI_Finalize(); #endif return(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 bool verbose = false; // Check if we should print results to standard out verbose = true; if (verbose && Comm.MyPID()==0) cout << Epetra_Version() << endl << endl; int rank = Comm.MyPID(); if (verbose) cout << Comm <<endl; // Redefine verbose to only print on PE 0 if (verbose && rank!=0) verbose = false; int N = 5; int NRHS = 5; double * X = new double[NRHS]; double * ed_X = new double[NRHS]; double * B = new double[NRHS]; double * ed_B = new double[NRHS]; Ifpack_SerialTriDiSolver solver; Ifpack_SerialTriDiMatrix * Matrix; Epetra_SerialDenseSolver ed_solver; Epetra_SerialDenseMatrix * ed_Matrix; bool Transpose = false; bool Refine = false; solver.SolveWithTranspose(Transpose); solver.SolveToRefinedSolution(Refine); ed_solver.SolveWithTranspose(Transpose); ed_solver.SolveToRefinedSolution(Refine); Matrix = new Ifpack_SerialTriDiMatrix(5,true); ed_Matrix = new Epetra_SerialDenseMatrix(5,5); for(int i=0;i<N;++i) { B[i] = ed_B[i] =2; Matrix->D()[i]=2.0; if(i<(N-1)) { Matrix->DL()[i]=-1.0; if(i!=2) Matrix->DU()[i]=-1.0; } } Matrix->Print(std::cout); double * ed_a = ed_Matrix->A(); for(int i=0;i<N;++i) for(int j=0;j<N;++j) { if(i==j) ed_a[j*N+i] = 2.0; else if(abs(i-j) == 1) ed_a[j*N+i] = -1.0; else ed_a[j*N + i] = 0; if(i==2&&j==3) ed_a[j*N+i] = 0.0; } Epetra_SerialDenseVector LHS(Copy, X, N); Epetra_SerialDenseVector RHS(Copy, B, N); Epetra_SerialDenseVector ed_LHS(Copy, ed_X, N); Epetra_SerialDenseVector ed_RHS(Copy, ed_B, N); solver.SetMatrix(*Matrix); solver.SetVectors(LHS, RHS); ed_solver.SetMatrix(*ed_Matrix); ed_solver.SetVectors(ed_LHS, ed_RHS); solver.Solve(); ed_solver.Solve(); std::cout << " LHS vals are: "<<std::endl; bool TestPassed=true; for(int i=0;i<N;++i) { std::cout << "["<<i<<"] "<< LHS(i)<<" "<<ed_LHS(i)<<" delta "<<LHS(i)-ed_LHS(i)<<std::endl; if( fabs( (LHS(i)- ed_LHS(i))/(LHS(i)+ ed_LHS(i)) ) > 1.0e-12 ) { TestPassed = false; std::cout << " not equal for "<<i<<" delta "<< LHS(i)- ed_LHS(i)<<std::endl; } } Ifpack_SerialTriDiMatrix * tdfac = solver.FactoredMatrix(); Epetra_SerialDenseMatrix * sdfac = ed_solver.FactoredMatrix(); std::cout << " Tri Di Factored "<<std::endl; tdfac->Print(std::cout); std::cout << " Dense Factored "<<std::endl; sdfac->Print(std::cout); delete Matrix; delete ed_Matrix; delete [] X; delete [] ed_X; delete [] B; delete [] ed_B; if (!TestPassed) { cout << "Test `TestRelaxation.exe' failed!" << endl; exit(EXIT_FAILURE); } #ifdef HAVE_MPI MPI_Finalize(); #endif cout << endl; cout << "Test `TestRelaxation.exe' passed!" << endl; cout << endl; return(EXIT_SUCCESS); }
// main driver int main(int argc, char *argv[]) { #ifdef HAVE_MPI MPI_Init(&argc, &argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif if (Comm.NumProc() != 2) { #ifdef HAVE_MPI MPI_Finalize(); #endif return(0); } int NumMyElements = 0; // NODES assigned to this processor int NumMyExternalElements = 0; // nodes used by this proc, but not hosted int NumMyTotalElements = 0; int FE_NumMyElements = 0; // TRIANGLES assigned to this processor int * MyGlobalElements = 0; // nodes assigned to this processor Epetra_IntSerialDenseMatrix T; // store the grid connectivity int MyPID=Comm.MyPID(); cout << MyPID << endl; switch( MyPID ) { case 0: NumMyElements = 3; NumMyExternalElements = 2; NumMyTotalElements = NumMyElements + NumMyExternalElements; FE_NumMyElements = 3; MyGlobalElements = new int[NumMyTotalElements]; MyGlobalElements[0] = 0; MyGlobalElements[1] = 4; MyGlobalElements[2] = 3; MyGlobalElements[3] = 1; MyGlobalElements[4] = 5; break; case 1: NumMyElements = 3; NumMyExternalElements = 2; NumMyTotalElements = NumMyElements + NumMyExternalElements; FE_NumMyElements = 3; MyGlobalElements = new int[NumMyTotalElements]; MyGlobalElements[0] = 1; MyGlobalElements[1] = 2; MyGlobalElements[2] = 5; MyGlobalElements[3] = 0; MyGlobalElements[4] = 4; break; } // build Map corresponding to update Epetra_Map Map(-1,NumMyElements,MyGlobalElements,0,Comm); // vector containing coordinates BEFORE exchanging external nodes Epetra_Vector CoordX_noExt(Map); Epetra_Vector CoordY_noExt(Map); switch( MyPID ) { case 0: T.Shape(3,FE_NumMyElements); // fill x-coordinates CoordX_noExt[0] = 0.0; CoordX_noExt[1] = 1.0; CoordX_noExt[2] = 0.0; // fill y-coordinates CoordY_noExt[0] = 0.0; CoordY_noExt[1] = 1.0; CoordY_noExt[2] = 1.0; // fill connectivity T(0,0) = 0; T(0,1) = 4; T(0,2) = 3; T(1,0) = 0; T(1,1) = 1; T(1,2) = 4; T(2,0) = 4; T(2,1) = 1; T(2,2) = 5; break; case 1: T.Shape(3,FE_NumMyElements); // fill x-coordinates CoordX_noExt[0] = 1.0; CoordX_noExt[1] = 2.0; CoordX_noExt[2] = 2.0; // fill y-coordinates CoordY_noExt[0] = 0.0; CoordY_noExt[1] = 0.0; CoordY_noExt[2] = 1.0; // fill connectivity T(0,0) = 0; T(0,1) = 1; T(0,2) = 4; T(1,0) = 1; T(1,1) = 5; T(1,2) = 4; T(2,0) = 1; T(2,1) = 2; T(2,2) = 5; break; } // - - - - - - - - - - - - - - - - - - - - // // E X T E R N A L N O D E S S E T U P // // - - - - - - - - - - - - - - - - - - - - // // build target map to exchange the valus of external nodes Epetra_Map TargetMap(-1,NumMyTotalElements, MyGlobalElements, 0, Comm); // !@# rename Map -> SourceMap ????? Epetra_Import Importer(TargetMap,Map); Epetra_Vector CoordX(TargetMap); Epetra_Vector CoordY(TargetMap); CoordX.Import(CoordX_noExt,Importer,Insert); CoordY.Import(CoordY_noExt,Importer,Insert); // now CoordX_noExt and CoordY_noExt are no longer required // NOTE: better to construct CoordX and CoordY as MultiVector // - - - - - - - - - - - - // // M A T R I X S E T U P // // - - - - - - - - - - - - // // build the CRS matrix corresponding to the grid // some vectors are allocated const int MaxNnzRow = 5; Epetra_CrsMatrix A(Copy,Map,MaxNnzRow); int Element, MyRow, GlobalRow, GlobalCol, i, j, k; Epetra_IntSerialDenseMatrix Struct; // temp to create the matrix connectivity Struct.Shape(NumMyElements,MaxNnzRow); for( i=0 ; i<NumMyElements ; ++i ) for( j=0 ; j<MaxNnzRow ; ++j ) Struct(i,j) = -1; // cycle over all the finite elements for( Element=0 ; Element<FE_NumMyElements ; ++Element ) { // cycle over each row for( i=0 ; i<3 ; ++i ) { // get the global and local number of this row GlobalRow = T(Element,i); MyRow = A.LRID(GlobalRow); if( MyRow != -1 ) { // only rows stored on this proc // cycle over the columns for( j=0 ; j<3 ; ++j ) { // get the global number only of this column GlobalCol = T(Element,j); // look if GlobalCol was already put in Struct for( k=0 ; k<MaxNnzRow ; ++k ) { if( Struct(MyRow,k) == GlobalCol || Struct(MyRow,k) == -1 ) break; } if( Struct(MyRow,k) == -1 ) { // new entry Struct(MyRow,k) = GlobalCol; } else if( Struct(MyRow,k) != GlobalCol ) { // maybe not enough space has beenn allocated cerr << "ERROR: not enough space for element " << GlobalRow << "," << GlobalCol << endl; return( 0 ); } } } } } int * Indices = new int [MaxNnzRow]; double * Values = new double [MaxNnzRow]; for( i=0 ; i<MaxNnzRow ; ++i ) Values[i] = 0.0; // now use Struct to fill build the matrix structure for( int Row=0 ; Row<NumMyElements ; ++Row ) { int Length = 0; for( int j=0 ; j<MaxNnzRow ; ++j ) { if( Struct(Row,j) == -1 ) break; Indices[Length] = Struct(Row,j); Length++; } GlobalRow = MyGlobalElements[Row]; A.InsertGlobalValues(GlobalRow, Length, Values, Indices); } // replace global numbering with local one in T for( int Element=0 ; Element<FE_NumMyElements ; ++Element ) { for( int i=0 ; i<3 ; ++i ) { int global = T(Element,i); int local = find(MyGlobalElements,NumMyTotalElements, global); if( global == -1 ) { cerr << "ERROR\n"; return( EXIT_FAILURE ); } T(Element,i) = local; } } // - - - - - - - - - - - - - - // // M A T R I X F I L L - I N // // - - - - - - - - - - - - - - // // room for the local matrix Epetra_SerialDenseMatrix Ke; Ke.Shape(3,3); // now fill the matrix for( int Element=0 ; Element<FE_NumMyElements ; ++Element ) { // variables used inside int GlobalRow; int MyRow; int GlobalCol; double x_triangle[3]; double y_triangle[3]; // get the spatial coordinate of each local node for( int i=0 ; i<3 ; ++i ) { MyRow = T(Element,i); y_triangle[i] = CoordX[MyRow]; x_triangle[i] = CoordY[MyRow]; } // compute the local matrix for Element compute_loc_matrix( x_triangle, y_triangle,Ke ); // insert it in the global one // cycle over each row for( int i=0 ; i<3 ; ++i ) { // get the global and local number of this row MyRow = T(Element,i); if( MyRow < NumMyElements ) { for( int j=0 ; j<3 ; ++j ) { // get global column number GlobalRow = MyGlobalElements[MyRow]; GlobalCol = MyGlobalElements[T(Element,j)]; A.SumIntoGlobalValues(GlobalRow,1,&(Ke(i,j)),&GlobalCol); } } } } A.FillComplete(); // - - - - - - - - - - - - - // // R H S & S O L U T I O N // // - - - - - - - - - - - - - // Epetra_Vector x(Map), b(Map); x.Random(); b.PutScalar(0.0); // Solution can be obtained using Aztecoo // free memory before leaving delete MyGlobalElements; delete Indices; delete Values; #ifdef HAVE_MPI MPI_Finalize(); #endif return( EXIT_SUCCESS ); } /* main */