int main(int argc, char *argv[]) { Teuchos::GlobalMPISession mpiSession(&argc, &argv); int rank = Teuchos::GlobalMPISession::getRank(); #ifdef HAVE_MPI Epetra_MpiComm Comm(MPI_COMM_WORLD); //cout << "rank: " << rank << " of " << numProcs << endl; #else Epetra_SerialComm Comm; #endif Comm.Barrier(); // set breakpoint here to allow debugger attachment to other MPI processes than the one you automatically attached to. int numRanks = Teuchos::GlobalMPISession::getNProc(); FieldContainer<IndexType> partitionDofCounts(256); int myDofs = 0; if (rank==0) { myDofs = 300; } partitionDofCounts[rank] = myDofs; MPIWrapper::entryWiseSum(partitionDofCounts); int partitionDofOffset = 0; // add this to a local partition dof index to get the global dof index for (int i=0; i<rank; i++) { partitionDofOffset += partitionDofCounts[i]; } int globalDofCount = partitionDofOffset; for (int i=rank; i<numRanks; i++) { globalDofCount += partitionDofCounts[i]; } int activeCellCount = 1; Intrepid::FieldContainer<int> globalCellIDDofOffsets(activeCellCount); // global copy: MPIWrapper::entryWiseSum(globalCellIDDofOffsets); return 0; }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI Teuchos::GlobalMPISession mpiSession(&argc, &argv,0); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif int commRank = Teuchos::GlobalMPISession::getRank(); Comm.Barrier(); // set breakpoint here to allow debugger attachment to other MPI processes than the one you automatically attached to. Teuchos::CommandLineProcessor cmdp(false,true); // false: don't throw exceptions; true: do return errors for unrecognized options // problem parameters: double mu = 0.1; double permCoef = 1e4; int numRefs = 0; int k = 2, delta_k = 2; string norm = "Graph"; cmdp.setOption("polyOrder",&k,"polynomial order for field variable u"); cmdp.setOption("delta_k", &delta_k, "test space polynomial order enrichment"); cmdp.setOption("numRefs",&numRefs,"number of refinements"); cmdp.setOption("norm", &norm, "norm"); cmdp.setOption("mu", &mu, "mu"); cmdp.setOption("permCoef", &permCoef, "Permeability coefficient"); if (cmdp.parse(argc,argv) != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) { #ifdef HAVE_MPI MPI_Finalize(); #endif return -1; } FunctionPtr zero = TFunction<double>::zero(); FunctionPtr one = TFunction<double>::constant(1); FunctionPtr sin2pix = Teuchos::rcp( new Sin_ax(2*pi) ); FunctionPtr cos2pix = Teuchos::rcp( new Cos_ax(2*pi) ); FunctionPtr sin2piy = Teuchos::rcp( new Sin_ay(2*pi) ); FunctionPtr cos2piy = Teuchos::rcp( new Cos_ay(2*pi) ); FunctionPtr u1_exact = sin2pix*cos2piy; FunctionPtr u2_exact = -cos2pix*sin2piy; FunctionPtr x2 = TFunction<double>::xn(2); FunctionPtr y2 = TFunction<double>::yn(2); FunctionPtr p_exact = x2*y2 - 1./9; FunctionPtr permInv = permCoef*(sin2pix + 1.1); VarFactoryPtr vf = VarFactory::varFactory(); //fields: VarPtr sigma1 = vf->fieldVar("sigma1", VECTOR_L2); VarPtr sigma2 = vf->fieldVar("sigma2", VECTOR_L2); VarPtr u1 = vf->fieldVar("u1", L2); VarPtr u2 = vf->fieldVar("u2", L2); VarPtr p = vf->fieldVar("p", L2); // traces: VarPtr u1hat = vf->traceVar("u1hat"); VarPtr u2hat = vf->traceVar("u2hat"); VarPtr t1c = vf->fluxVar("t1c"); VarPtr t2c = vf->fluxVar("t2c"); // test: VarPtr v1 = vf->testVar("v1", HGRAD); VarPtr v2 = vf->testVar("v2", HGRAD); VarPtr tau1 = vf->testVar("tau1", HDIV); VarPtr tau2 = vf->testVar("tau2", HDIV); VarPtr q = vf->testVar("q", HGRAD); BFPtr bf = Teuchos::rcp( new BF(vf) ); bf->addTerm(1./mu*sigma1, tau1); bf->addTerm(1./mu*sigma2, tau2); bf->addTerm(u1, tau1->div()); bf->addTerm(u2, tau2->div()); bf->addTerm(-u1hat, tau1->dot_normal()); bf->addTerm(-u2hat, tau2->dot_normal()); bf->addTerm(sigma1, v1->grad()); bf->addTerm(sigma2, v2->grad()); bf->addTerm(-p, v1->dx()); bf->addTerm(-p, v2->dy()); bf->addTerm(t1c, v1); bf->addTerm(t2c, v2); bf->addTerm(mu*permInv*u1, v1); bf->addTerm(mu*permInv*u2, v2); bf->addTerm(-u1, q->dx()); bf->addTerm(-u2, q->dy()); bf->addTerm(u1hat, q->times_normal_x()); bf->addTerm(u2hat, q->times_normal_y()); RHSPtr rhs = RHS::rhs(); BCPtr bc = BC::bc(); SpatialFilterPtr y_equals_one = SpatialFilter::matchingY(1.0); SpatialFilterPtr y_equals_zero = SpatialFilter::matchingY(0); SpatialFilterPtr x_equals_one = SpatialFilter::matchingX(1.0); SpatialFilterPtr x_equals_zero = SpatialFilter::matchingX(0.0); bc->addDirichlet(u1hat, y_equals_zero, u1_exact); bc->addDirichlet(u2hat, y_equals_zero, u2_exact); bc->addDirichlet(u1hat, x_equals_zero, u1_exact); bc->addDirichlet(u2hat, x_equals_zero, u2_exact); bc->addDirichlet(u1hat, y_equals_one, u1_exact); bc->addDirichlet(u2hat, y_equals_one, u2_exact); bc->addDirichlet(u1hat, x_equals_one, u1_exact); bc->addDirichlet(u2hat, x_equals_one, u2_exact); bc->addZeroMeanConstraint(p); MeshPtr mesh = MeshFactory::quadMesh(bf, k+1, delta_k, 1, 1, 4, 4); map<string, IPPtr> brinkmanIPs; brinkmanIPs["Graph"] = bf->graphNorm(); brinkmanIPs["Decoupled"] = Teuchos::rcp(new IP); brinkmanIPs["Decoupled"]->addTerm(tau1); brinkmanIPs["Decoupled"]->addTerm(tau2); brinkmanIPs["Decoupled"]->addTerm(tau1->div()); brinkmanIPs["Decoupled"]->addTerm(tau2->div()); brinkmanIPs["Decoupled"]->addTerm(permInv*v1); brinkmanIPs["Decoupled"]->addTerm(permInv*v2); brinkmanIPs["Decoupled"]->addTerm(v1->grad()); brinkmanIPs["Decoupled"]->addTerm(v2->grad()); brinkmanIPs["Decoupled"]->addTerm(q); brinkmanIPs["Decoupled"]->addTerm(q->grad()); // brinkmanIPs["CoupledRobust"] = Teuchos::rcp(new IP); // brinkmanIPs["CoupledRobust"]->addTerm(tau->div()-beta*v->grad()); // brinkmanIPs["CoupledRobust"]->addTerm(Function<double>::min(one/Function<double>::h(),Function<double>::constant(1./sqrt(epsilon)))*tau); // brinkmanIPs["CoupledRobust"]->addTerm(sqrt(epsilon)*v->grad()); // brinkmanIPs["CoupledRobust"]->addTerm(beta*v->grad()); // brinkmanIPs["CoupledRobust"]->addTerm(Function<double>::min(sqrt(epsilon)*one/Function<double>::h(),one)*v); IPPtr ip = brinkmanIPs[norm]; SolutionPtr soln = TSolution<double>::solution(mesh, bc, rhs, ip); double threshold = 0.20; RefinementStrategy refStrategy(soln, threshold); ostringstream refName; refName << "brinkman"; HDF5Exporter exporter(mesh,refName.str()); for (int refIndex=0; refIndex <= numRefs; refIndex++) { soln->solve(false); double energyError = soln->energyErrorTotal(); if (commRank == 0) { // if (refIndex > 0) // refStrategy.printRefinementStatistics(refIndex-1); cout << "Refinement:\t " << refIndex << " \tElements:\t " << mesh->numActiveElements() << " \tDOFs:\t " << mesh->numGlobalDofs() << " \tEnergy Error:\t " << energyError << endl; } exporter.exportSolution(soln, refIndex); if (refIndex != numRefs) refStrategy.refine(); } return 0; }
int main(int argc, char *argv[]) { int returnierr=0; using std::cout; using std::endl; using std::flush; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); int size; // Number of MPI processes, My process ID MPI_Comm_size(MPI_COMM_WORLD, &size); if (size > 1) { cout << "This example cannot be run on more than one processor!" << endl; MPI_Finalize(); returnierr = -1; return returnierr; } #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; #ifdef EPETRA_MPI Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif if (!verbose) Comm.SetTracebackMode(0); // This should shut down any error traceback reporting if (verbose) { cout << EpetraExt::EpetraExt_Version() << endl << endl; cout << Comm << endl << flush; } Comm.Barrier(); int NumMyElements = 3; Epetra_Map Map( NumMyElements, 0, Comm ); Epetra_CrsGraph Graph( Copy, Map, 1 ); int index[2]; index[0] = 2; Graph.InsertGlobalIndices( 0, 1, &index[0] ); index[0] = 0; index[1] = 2; Graph.InsertGlobalIndices( 1, 2, &index[0] ); index[0] = 1; Graph.InsertGlobalIndices( 2, 1, &index[0] ); Graph.FillComplete(); // Create an Epetra::CrsMatrix Epetra_CrsMatrix Matrix( Copy, Graph ); double value[2]; index[0] = 2; value[0] = 3.0; Matrix.ReplaceMyValues( 0, 1, &value[0], &index[0] ); index[0] = 0; index[1] = 2; value[0] = 2.0; value[1] = 2.5; Matrix.ReplaceMyValues( 1, 2, &value[0], &index[0] ); index[0] = 1; value[0] = 1.0; Matrix.ReplaceMyValues( 2, 1, &value[0], &index[0] ); Matrix.FillComplete(); EpetraExt::AmesosBTF_CrsMatrix BTFTrans( 0.0, true, verbose ); Epetra_CrsMatrix & NewMatrix = BTFTrans( Matrix ); if (verbose) { cout << "*************** PERFORMING BTF TRANSFORM ON CRS_MATRIX **************" <<endl<<endl; cout << "CrsMatrix *before* BTF transform: " << endl << endl; cout << Matrix << endl; } BTFTrans.fwd(); if (verbose) { cout << "CrsMatrix *after* BTF transform: " << endl << endl; cout << NewMatrix << endl; } #ifdef EPETRA_MPI MPI_Finalize(); #endif return returnierr; }
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 = (Comm.MyPID() == 0); double TotalResidual = 0.0; // Create the Map, defined as a grid, of size nx x ny x nz, // subdivided into mx x my x mz cubes, each assigned to a // different processor. #ifndef FILENAME_SPECIFIED_ON_COMMAND_LINE ParameterList GaleriList; GaleriList.set("nx", 4); GaleriList.set("ny", 4); GaleriList.set("nz", 4 * Comm.NumProc()); GaleriList.set("mx", 1); GaleriList.set("my", 1); GaleriList.set("mz", Comm.NumProc()); Epetra_Map* Map = CreateMap("Cartesian3D", Comm, GaleriList); // Create a matrix, in this case corresponding to a 3D Laplacian // discretized using a classical 7-point stencil. Please refer to // the Galeri documentation for an overview of available matrices. // // NOTE: matrix must be symmetric if DSCPACK is used. Epetra_CrsMatrix* Matrix = CreateCrsMatrix("Laplace3D", Map, GaleriList); #else bool transpose = false ; bool distribute = false ; bool symmetric ; Epetra_CrsMatrix *Matrix = 0 ; Epetra_Map *Map = 0 ; MyCreateCrsMatrix( argv[1], Comm, Map, transpose, distribute, symmetric, Matrix ) ; #endif // build vectors, in this case with 1 vector Epetra_MultiVector LHS(*Map, 1); Epetra_MultiVector RHS(*Map, 1); // create a linear problem object Epetra_LinearProblem Problem(Matrix, &LHS, &RHS); // use this list to set up parameters, now it is required // to use all the available processes (if supported by the // underlying solver). Uncomment the following two lines // to let Amesos print out some timing and status information. ParameterList List; List.set("PrintTiming",true); List.set("PrintStatus",true); List.set("MaxProcs",Comm.NumProc()); std::vector<std::string> SolverType; SolverType.push_back("Amesos_Paraklete"); SolverType.push_back("Amesos_Klu"); Comm.Barrier() ; #if 1 SolverType.push_back("Amesos_Lapack"); SolverType.push_back("Amesos_Umfpack"); SolverType.push_back("Amesos_Pardiso"); SolverType.push_back("Amesos_Taucs"); SolverType.push_back("Amesos_Superlu"); SolverType.push_back("Amesos_Superludist"); SolverType.push_back("Amesos_Mumps"); SolverType.push_back("Amesos_Dscpack"); SolverType.push_back("Amesos_Scalapack"); #endif Epetra_Time Time(Comm); // this is the Amesos factory object that will create // a specific Amesos solver. Amesos Factory; // Cycle over all solvers. // Only installed solvers will be tested. for (unsigned int i = 0 ; i < SolverType.size() ; ++i) { // Check whether the solver is available or not if (Factory.Query(SolverType[i])) { // 1.- set exact solution (constant vector) LHS.PutScalar(1.0); // 2.- create corresponding rhs Matrix->Multiply(false, LHS, RHS); // 3.- randomize solution vector LHS.Random(); // 4.- create the amesos solver object Amesos_BaseSolver* Solver = Factory.Create(SolverType[i], Problem); assert (Solver != 0); Solver->SetParameters(List); Solver->SetUseTranspose( true) ; // 5.- factorize and solve Comm.Barrier() ; if (verbose) std::cout << std::endl << "Solver " << SolverType[i] << ", verbose = " << verbose << std::endl ; Comm.Barrier() ; Time.ResetStartTime(); AMESOS_CHK_ERR(Solver->SymbolicFactorization()); if (verbose) std::cout << std::endl << "Solver " << SolverType[i] << ", symbolic factorization time = " << Time.ElapsedTime() << std::endl; Comm.Barrier() ; AMESOS_CHK_ERR(Solver->NumericFactorization()); if (verbose) std::cout << "Solver " << SolverType[i] << ", numeric factorization time = " << Time.ElapsedTime() << std::endl; Comm.Barrier() ; AMESOS_CHK_ERR(Solver->Solve()); if (verbose) std::cout << "Solver " << SolverType[i] << ", solve time = " << Time.ElapsedTime() << std::endl; Comm.Barrier() ; // 6.- compute difference between exact solution and Amesos one // (there are other ways of doing this in Epetra, but let's // keep it simple) double d = 0.0, d_tot = 0.0; for (int j = 0 ; j< LHS.Map().NumMyElements() ; ++j) d += (LHS[0][j] - 1.0) * (LHS[0][j] - 1.0); Comm.SumAll(&d,&d_tot,1); if (verbose) std::cout << "Solver " << SolverType[i] << ", ||x - x_exact||_2 = " << sqrt(d_tot) << std::endl; // 7.- delete the object delete Solver; TotalResidual += d_tot; } } delete Matrix; delete Map; if (TotalResidual > 1e-9) exit(EXIT_FAILURE); #ifdef HAVE_MPI MPI_Finalize(); #endif return(EXIT_SUCCESS); } // end of main()
int main(int argc, char *argv[]) { #ifdef EPETRA_MPI // Initialize MPI MPI_Init( &argc, &argv ); //int size, rank; // Number of MPI processes, My process ID //MPI_Comm_size(MPI_COMM_WORLD, &size); //MPI_Comm_rank(MPI_COMM_WORLD, &rank); #else //int size = 1; // Serial case (not using MPI) //int rank = 0; #endif bool verbose = false; int nx = 5; int ny = 5; if( argc > 1 ) { if( argc > 4 ) { cout << "Usage: " << argv[0] << " [-v [nx [ny]]]" << endl; exit(1); } int loc = 1; // Check if we should print results to standard out if(argv[loc][0]=='-' && argv[loc][1]=='v') { verbose = true; ++loc; } if (loc < argc) nx = atoi( argv[loc++] ); if( loc < argc) ny = atoi( argv[loc] ); } #ifdef EPETRA_MPI Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); bool verbose1 = false; if(verbose) verbose1 = (MyPID==0); if(verbose1) cout << EpetraExt::EpetraExt_Version() << endl << endl; Comm.Barrier(); if(verbose) cout << Comm << endl << flush; Comm.Barrier(); int NumGlobalElements = nx * ny; if( NumGlobalElements < NumProc ) { cout << "NumGlobalElements = " << NumGlobalElements << " cannot be < number of processors = " << NumProc; exit(1); } int IndexBase = 0; Epetra_Map Map( NumGlobalElements, IndexBase, Comm ); // Extract the global indices of the elements local to this processor int NumMyElements = Map.NumMyElements(); std::vector<int> MyGlobalElements( NumMyElements ); Map.MyGlobalElements( &MyGlobalElements[0] ); if( verbose ) cout << Map; // Create the number of non-zeros for a tridiagonal (1D problem) or banded // (2D problem) matrix std::vector<int> NumNz( NumMyElements, 5 ); int global_i; int global_j; for (int i = 0; i < NumMyElements; ++i) { global_j = MyGlobalElements[i] / nx; global_i = MyGlobalElements[i] - global_j * nx; if (global_i == 0) NumNz[i] -= 1; // By having separate statements, if (global_i == nx-1) NumNz[i] -= 1; // this works for 2D as well as 1D if (global_j == 0) NumNz[i] -= 1; // systems (i.e. nx x 1 or 1 x ny) if (global_j == ny-1) NumNz[i] -= 1; // or even a 1 x 1 system } if(verbose) { cout << endl << "NumNz: "; for (int i = 0; i < NumMyElements; i++) cout << NumNz[i] << " "; cout << endl; } // end if // Create the Epetra Compressed Row Sparse Graph Epetra_CrsGraph A( Copy, Map, &NumNz[0] ); std::vector<int> Indices(5); int NumEntries; for (int i = 0; i < NumMyElements; ++i ) { global_j = MyGlobalElements[i] / nx; global_i = MyGlobalElements[i] - global_j * nx; NumEntries = 0; // (i,j-1) entry if (global_j > 0 && ny > 1) Indices[NumEntries++] = global_i + (global_j-1)*nx; // (i-1,j) entry if (global_i > 0) Indices[NumEntries++] = global_i-1 + global_j *nx; // (i,j) entry Indices[NumEntries++] = MyGlobalElements[i]; // (i+1,j) entry if (global_i < nx-1) Indices[NumEntries++] = global_i+1 + global_j *nx; // (i,j+1) entry if (global_j < ny-1 && ny > 1) Indices[NumEntries++] = global_i + (global_j+1)*nx; // Insert the global indices A.InsertGlobalIndices( MyGlobalElements[i], NumEntries, &Indices[0] ); } // end i loop // Finish up graph construction A.FillComplete(); EpetraExt::CrsGraph_MapColoring Greedy0MapColoringTransform( EpetraExt::CrsGraph_MapColoring::GREEDY, 0, false, verbose ); Epetra_MapColoring & Greedy0ColorMap = Greedy0MapColoringTransform( A ); printColoring(Greedy0ColorMap, &A,verbose); EpetraExt::CrsGraph_MapColoring Greedy1MapColoringTransform( EpetraExt::CrsGraph_MapColoring::GREEDY, 1, false, verbose ); Epetra_MapColoring & Greedy1ColorMap = Greedy1MapColoringTransform( A ); printColoring(Greedy1ColorMap, &A,verbose); EpetraExt::CrsGraph_MapColoring Greedy2MapColoringTransform( EpetraExt::CrsGraph_MapColoring::GREEDY, 2, false, verbose ); Epetra_MapColoring & Greedy2ColorMap = Greedy2MapColoringTransform( A ); printColoring(Greedy2ColorMap, &A,verbose); EpetraExt::CrsGraph_MapColoring Lubi0MapColoringTransform( EpetraExt::CrsGraph_MapColoring::LUBY, 0, false, verbose ); Epetra_MapColoring & Lubi0ColorMap = Lubi0MapColoringTransform( A ); printColoring(Lubi0ColorMap, &A,verbose); EpetraExt::CrsGraph_MapColoring Lubi1MapColoringTransform( EpetraExt::CrsGraph_MapColoring::LUBY, 1, false, verbose ); Epetra_MapColoring & Lubi1ColorMap = Lubi1MapColoringTransform( A ); printColoring(Lubi1ColorMap, &A,verbose); EpetraExt::CrsGraph_MapColoring Lubi2MapColoringTransform( EpetraExt::CrsGraph_MapColoring::LUBY, 2, false, verbose ); Epetra_MapColoring & Lubi2ColorMap = Lubi2MapColoringTransform( A ); printColoring(Lubi2ColorMap, &A,verbose); #ifdef EPETRA_MPI if( verbose ) cout << "Parallel Map Coloring 1!\n"; EpetraExt::CrsGraph_MapColoring Parallel1MapColoringTransform( EpetraExt::CrsGraph_MapColoring::PSEUDO_PARALLEL, 0, false, verbose ); Epetra_MapColoring & Parallel1ColorMap = Parallel1MapColoringTransform( A ); printColoring(Parallel1ColorMap, &A,verbose); if( verbose ) cout << "Parallel Map Coloring 2!\n"; EpetraExt::CrsGraph_MapColoring Parallel2MapColoringTransform( EpetraExt::CrsGraph_MapColoring::JONES_PLASSMAN, 0, false, verbose ); Epetra_MapColoring & Parallel2ColorMap = Parallel2MapColoringTransform( A ); printColoring(Parallel2ColorMap, &A,verbose); #endif #ifdef EPETRA_MPI MPI_Finalize(); #endif return 0; }
int main(int argc, char *argv[]) { int ierr=0, returnierr=0; #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.SetTracebackMode(0); // This should shut down any error traceback reporting } int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if (verbose && MyPID==0) cout << Epetra_Version() << endl << endl; if (verbose) cout << Comm << endl; bool verbose1 = verbose; if (verbose) verbose = (MyPID==0); int NumMyElements = 10000; int NumMyElements1 = NumMyElements; // Used for local map long long NumGlobalElements = NumMyElements*NumProc+EPETRA_MIN(NumProc,3); if (MyPID < 3) NumMyElements++; int IndexBase = 0; bool DistributedGlobal = (NumGlobalElements>NumMyElements); Epetra_Map* Map; // Test exceptions if (verbose) cout << "*******************************************************************************************" << endl << " Testing Exceptions (Expect error messages if EPETRA_NO_ERROR_REPORTS is not defined" << endl << "*******************************************************************************************" << endl << endl << endl; try { if (verbose) cout << "Checking Epetra_Map(-2, IndexBase, Comm)" << endl; Map = new Epetra_Map((long long)-2, IndexBase, Comm); } catch (int Error) { if (Error!=-1) { if (Error!=0) { EPETRA_TEST_ERR(Error,returnierr); if (verbose) cout << "Error code should be -1" << endl; } else { cout << "Error code = " << Error << "Should be -1" << endl; returnierr+=1; } } else if (verbose) cout << "Checked OK\n\n" << endl; } try { if (verbose) cout << "Checking Epetra_Map(2, 3, IndexBase, Comm)" << endl; Map = new Epetra_Map((long long)2, 3, IndexBase, Comm); } catch (int Error) { if (Error!=-4) { if (Error!=0) { EPETRA_TEST_ERR(Error,returnierr); if (verbose) cout << "Error code should be -4" << endl; } else { cout << "Error code = " << Error << "Should be -4" << endl; returnierr+=1; } } else if (verbose) cout << "Checked OK\n\n" << endl; } if (verbose) cerr << flush; if (verbose) cout << flush; Comm.Barrier(); if (verbose) cout << endl << endl << "*******************************************************************************************" << endl << " Testing valid constructor now......................................................" << endl << "*******************************************************************************************" << endl << endl << endl; // Test Epetra-defined uniform linear distribution constructor Map = new Epetra_Map(NumGlobalElements, IndexBase, Comm); if (verbose) cout << "Checking Epetra_Map(NumGlobalElements, IndexBase, Comm)" << endl; ierr = checkmap(*Map, NumGlobalElements, NumMyElements, 0, IndexBase, Comm, DistributedGlobal); EPETRA_TEST_ERR(ierr,returnierr); if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl; delete Map; // Test User-defined linear distribution constructor Map = new Epetra_Map(NumGlobalElements, NumMyElements, IndexBase, Comm); if (verbose) cout << "Checking Epetra_Map(NumGlobalElements, NumMyElements, IndexBase, Comm)" << endl; ierr = checkmap(*Map, NumGlobalElements, NumMyElements, 0, IndexBase, Comm, DistributedGlobal); EPETRA_TEST_ERR(ierr,returnierr); if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl; delete Map; // Test User-defined arbitrary distribution constructor // Generate Global Element List. Do in reverse for fun! long long * MyGlobalElements = new long long[NumMyElements]; int MaxMyGID = (Comm.MyPID()+1)*NumMyElements-1+IndexBase; if (Comm.MyPID()>2) MaxMyGID+=3; for (int i = 0; i<NumMyElements; i++) MyGlobalElements[i] = MaxMyGID-i; Map = new Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase, Comm); if (verbose) cout << "Checking Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase, Comm)" << endl; ierr = checkmap(*Map, NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase, Comm, DistributedGlobal); EPETRA_TEST_ERR(ierr,returnierr); if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl; // Test Copy constructor Epetra_Map* Map1 = new Epetra_Map(*Map); // Test SameAs() method bool same = Map1->SameAs(*Map); EPETRA_TEST_ERR(!(same==true),ierr);// should return true since Map1 is a copy of Map Epetra_BlockMap* Map2 = new Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase, Comm); same = Map2->SameAs(*Map); EPETRA_TEST_ERR(!(same==true),ierr); // Map and Map2 were created with the same sets of parameters delete Map2; // now test SameAs() on a map that is different Map2 = new Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase-1, Comm); same = Map2->SameAs(*Map); EPETRA_TEST_ERR(!(same==false),ierr); // IndexBases are different delete Map2; // Back to testing copy constructor if (verbose) cout << "Checking Epetra_Map(*Map)" << endl; ierr = checkmap(*Map1, NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase, Comm, DistributedGlobal); EPETRA_TEST_ERR(ierr,returnierr); if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl; Epetra_Map* SmallMap = 0; if (verbose1) { // Build a small map for test cout. Use 10 elements from current map long long* MyEls = Map->MyGlobalElements64(); int IndBase = Map->IndexBase(); int MyLen = EPETRA_MIN(10+Comm.MyPID(),Map->NumMyElements()); SmallMap = new Epetra_Map((long long)-1, MyLen, MyEls, IndBase, Comm); } delete [] MyGlobalElements; delete Map; delete Map1; // Test reference-counting in Epetra_Map if (verbose) cout << "Checking Epetra_Map reference counting" << endl; ierr = checkMapDataClass(Comm, verbose); EPETRA_TEST_ERR(ierr,returnierr); if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl; // Test LocalMap constructor Epetra_LocalMap* LocalMap = new Epetra_LocalMap((long long)NumMyElements1, IndexBase, Comm); if (verbose) cout << "Checking Epetra_LocalMap(NumMyElements1, IndexBase, Comm)" << endl; ierr = checkmap(*LocalMap, NumMyElements1, NumMyElements1, 0, IndexBase, Comm, false); EPETRA_TEST_ERR(ierr,returnierr); if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl; // Test Copy constructor Epetra_LocalMap* LocalMap1 = new Epetra_LocalMap(*LocalMap); if (verbose) cout << "Checking Epetra_LocalMap(*LocalMap)" << endl; ierr = checkmap(*LocalMap1, NumMyElements1, NumMyElements1, 0, IndexBase, Comm, false); EPETRA_TEST_ERR(ierr,returnierr); if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl; delete LocalMap1; delete LocalMap; // Test reference-counting in Epetra_LocalMap if (verbose) cout << "Checking Epetra_LocalMap reference counting" << endl; ierr = checkLocalMapDataClass(Comm, verbose); EPETRA_TEST_ERR(ierr,returnierr); if (verbose && ierr==0) cout << "Checked OK\n\n" <<endl; // Test output if (verbose1) { if (verbose) cout << "Test ostream << operator" << endl << flush; cout << *SmallMap; delete SmallMap; } #ifdef EPETRA_MPI MPI_Finalize(); #endif return returnierr; }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI Teuchos::GlobalMPISession mpiSession(&argc, &argv,0); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif int commRank = Teuchos::GlobalMPISession::getRank(); Comm.Barrier(); // set breakpoint here to allow debugger attachment to other MPI processes than the one you automatically attached to. Teuchos::CommandLineProcessor cmdp(false,true); // false: don't throw exceptions; true: do return errors for unrecognized options // problem parameters: int spaceDim = 2; double Re = 40; bool steady = false; string problemChoice = "TaylorGreen"; int numRefs = 1; int p = 2, delta_p = 2; int numXElems = 1; int numTElems = 1; int numSlabs = 1; bool useConformingTraces = false; string solverChoice = "KLU"; string multigridStrategyString = "W-cycle"; bool useCondensedSolve = false; bool useConjugateGradient = true; bool logFineOperator = false; // double solverTolerance = 1e-8; double nonlinearTolerance = 1e-5; // int maxLinearIterations = 10000; int maxNonlinearIterations = 20; int cgMaxIterations = 10000; double cgTol = 1e-8; bool computeL2Error = false; bool exportSolution = false; bool saveSolution = false; bool loadSolution = false; int loadRef = 0; int loadDirRef = 0; string norm = "Graph"; string rootDir = "."; string tag=""; cmdp.setOption("spaceDim", &spaceDim, "spatial dimension"); cmdp.setOption("Re", &Re, "Re"); cmdp.setOption("steady", "transient", &steady, "use steady incompressible Navier-Stokes"); cmdp.setOption("problem", &problemChoice, "Kovasznay, TaylorGreen"); cmdp.setOption("polyOrder",&p,"polynomial order for field variable u"); cmdp.setOption("delta_p", &delta_p, "test space polynomial order enrichment"); cmdp.setOption("numRefs",&numRefs,"number of refinements"); cmdp.setOption("numXElems",&numXElems,"number of elements in x direction"); cmdp.setOption("numTElems",&numTElems,"number of elements in t direction"); cmdp.setOption("numSlabs",&numSlabs,"number of time slabs to use"); cmdp.setOption("norm", &norm, "norm"); cmdp.setOption("conformingTraces", "nonconformingTraces", &useConformingTraces, "use conforming traces"); cmdp.setOption("solver", &solverChoice, "KLU, SuperLU, MUMPS, GMG-Direct, GMG-ILU, GMG-IC"); cmdp.setOption("multigridStrategy", &multigridStrategyString, "Multigrid strategy: V-cycle, W-cycle, Full, or Two-level"); cmdp.setOption("useCondensedSolve", "useStandardSolve", &useCondensedSolve); cmdp.setOption("CG", "GMRES", &useConjugateGradient); cmdp.setOption("logFineOperator", "dontLogFineOperator", &logFineOperator); // cmdp.setOption("solverTolerance", &solverTolerance, "iterative solver tolerance"); cmdp.setOption("nonlinearTolerance", &nonlinearTolerance, "nonlinear solver tolerance"); // cmdp.setOption("maxLinearIterations", &maxLinearIterations, "maximum number of iterations for linear solver"); cmdp.setOption("maxNonlinearIterations", &maxNonlinearIterations, "maximum number of iterations for Newton solver"); cmdp.setOption("exportDir", &rootDir, "export directory"); cmdp.setOption("computeL2Error", "skipL2Error", &computeL2Error, "compute L2 error"); cmdp.setOption("exportSolution", "skipExport", &exportSolution, "export solution to HDF5"); cmdp.setOption("saveSolution", "skipSave", &saveSolution, "save mesh and solution to HDF5"); cmdp.setOption("loadSolution", "skipLoad", &loadSolution, "load mesh and solution from HDF5"); cmdp.setOption("loadRef", &loadRef, "load refinement number"); cmdp.setOption("loadDirRef", &loadDirRef, "which refinement directory to load from"); cmdp.setOption("tag", &tag, "output tag"); if (cmdp.parse(argc,argv) != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) { #ifdef HAVE_MPI MPI_Finalize(); #endif return -1; } map<string, Teuchos::RCP<IncompressibleProblem>> problems; problems["ManufacturedSolution"] = Teuchos::rcp(new IncompressibleManufacturedSolution(steady, Re, numXElems)); problems["Kovasznay"] = Teuchos::rcp(new KovasznayProblem(steady, Re)); problems["TaylorGreen"] = Teuchos::rcp(new TaylorGreenProblem(steady, Re, numXElems, numSlabs)); problems["Cylinder"] = Teuchos::rcp(new CylinderProblem(steady, Re, numSlabs)); problems["SquareCylinder"] = Teuchos::rcp(new SquareCylinderProblem(steady, Re, numSlabs)); Teuchos::RCP<IncompressibleProblem> problem = problems.at(problemChoice); // if (commRank == 0) // { // Solver::printAvailableSolversReport(); // cout << endl; // } Teuchos::RCP<Time> totalTimer = Teuchos::TimeMonitor::getNewCounter("Total Time"); totalTimer->start(true); for (; problem->currentStep() < problem->numSlabs(); problem->advanceStep()) { if (problem->numSlabs() > 1 && commRank == 0 && !steady) cout << "Solving time slab [" << problem->currentT0() << ", " << problem->currentT1() << "]" << endl; ostringstream problemName; string isSteady = "Steady"; if (!steady) isSteady = "Transient"; problemName << isSteady << problemChoice << spaceDim << "D_slab" << problem->currentStep() << "_" << norm << "_" << Re << "_p" << p << "_" << solverChoice; if (tag != "") problemName << "_" << tag; ostringstream saveDir; saveDir << problemName.str() << "_ref" << loadRef; int success = mkdir((rootDir+"/"+saveDir.str()).c_str(), S_IRWXU | S_IRWXG); string dataFileLocation = rootDir + "/" + saveDir.str() + "/" + saveDir.str() + ".data"; string exportName = saveDir.str(); ostringstream loadDir; loadDir << problemName.str() << "_ref" << loadDirRef; string loadFilePrefix = ""; if (loadSolution) { loadFilePrefix = rootDir + "/" + loadDir.str() + "/" + saveDir.str(); if (commRank == 0) cout << "Loading previous solution " << loadFilePrefix << endl; } // ostringstream saveDir; // saveDir << problemName.str() << "_ref" << loadRef; string saveFilePrefix = rootDir + "/" + saveDir.str() + "/" + problemName.str(); if (saveSolution && commRank == 0) cout << "Saving to " << saveFilePrefix << endl; Teuchos::ParameterList parameters; parameters.set("spaceDim", spaceDim); parameters.set("steady", steady); parameters.set("mu", 1./Re); parameters.set("useConformingTraces", useConformingTraces); parameters.set("fieldPolyOrder", p); parameters.set("delta_p", delta_p); parameters.set("numTElems", numTElems); parameters.set("norm", norm); parameters.set("savedSolutionAndMeshPrefix", loadFilePrefix); SpaceTimeIncompressibleFormulationPtr form = Teuchos::rcp(new SpaceTimeIncompressibleFormulation(problem, parameters)); MeshPtr mesh = form->solutionUpdate()->mesh(); vector<MeshPtr> meshesCoarseToFine; MeshPtr k0Mesh = Teuchos::rcp( new Mesh (mesh->getTopology()->deepCopy(), form->bf(), 1, delta_p) ); meshesCoarseToFine.push_back(k0Mesh); meshesCoarseToFine.push_back(mesh); // mesh->registerObserver(k0Mesh); // Set up boundary conditions problem->setBCs(form); // Set up solution SolutionPtr solutionUpdate = form->solutionUpdate(); SolutionPtr solutionBackground = form->solutionBackground(); // dynamic_cast<AnalyticalIncompressibleProblem*>(problem.get())->projectExactSolution(solutionBackground); RefinementStrategyPtr refStrategy = form->getRefinementStrategy(); Teuchos::RCP<HDF5Exporter> exporter; if (exportSolution) exporter = Teuchos::rcp(new HDF5Exporter(mesh,exportName, rootDir)); Teuchos::RCP<Time> solverTime = Teuchos::TimeMonitor::getNewCounter("Solve Time"); map<string, SolverPtr> solvers; solvers["KLU"] = Solver::getSolver(Solver::KLU, true); #if defined(HAVE_AMESOS_SUPERLUDIST) || defined(HAVE_AMESOS2_SUPERLUDIST) solvers["SuperLUDist"] = Solver::getSolver(Solver::SuperLUDist, true); #endif #ifdef HAVE_AMESOS_MUMPS solvers["MUMPS"] = Solver::getSolver(Solver::MUMPS, true); #endif bool useStaticCondensation = false; GMGOperator::MultigridStrategy multigridStrategy; if (multigridStrategyString == "Two-level") { multigridStrategy = GMGOperator::TWO_LEVEL; } else if (multigridStrategyString == "W-cycle") { multigridStrategy = GMGOperator::W_CYCLE; } else if (multigridStrategyString == "V-cycle") { multigridStrategy = GMGOperator::V_CYCLE; } else if (multigridStrategyString == "Full-V") { multigridStrategy = GMGOperator::FULL_MULTIGRID_V; } else if (multigridStrategyString == "Full-W") { multigridStrategy = GMGOperator::FULL_MULTIGRID_W; } else { TEUCHOS_TEST_FOR_EXCEPTION(true, std::invalid_argument, "unrecognized multigrid strategy"); } ofstream dataFile(dataFileLocation); dataFile << "ref\t " << "elements\t " << "dofs\t " << "energy\t " << "l2\t " << "solvetime\t" << "iterations\t " << endl; // { // // ostringstream saveFile; // // saveFile << saveFilePrefix << "_ref" << -1; // // form->save(saveFile.str()); // exporter->exportSolution(solutionBackground, -1); // if (commRank == 0) // cout << "Done exporting" << endl; // } for (int refIndex=loadRef; refIndex <= numRefs; refIndex++) { double l2Update = 1e10; int iterCount = 0; solverTime->start(true); Teuchos::RCP<GMGSolver> gmgSolver; if (solverChoice[0] == 'G') { // gmgSolver = Teuchos::rcp( new GMGSolver(solutionUpdate, k0Mesh, maxLinearIterations, solverTolerance, Solver::getDirectSolver(true), useStaticCondensation)); bool reuseFactorization = true; SolverPtr coarseSolver = Solver::getDirectSolver(reuseFactorization); gmgSolver = Teuchos::rcp(new GMGSolver(solutionUpdate, meshesCoarseToFine, cgMaxIterations, cgTol, multigridStrategy, coarseSolver, useCondensedSolve)); gmgSolver->setUseConjugateGradient(useConjugateGradient); int azOutput = 20; // print residual every 20 CG iterations gmgSolver->setAztecOutput(azOutput); gmgSolver->gmgOperator()->setNarrateOnRankZero(logFineOperator,"finest GMGOperator"); // gmgSolver->setAztecOutput(azOutput); // if (solverChoice == "GMG-Direct") // gmgSolver->gmgOperator()->setSchwarzFactorizationType(GMGOperator::Direct); // if (solverChoice == "GMG-ILU") // gmgSolver->gmgOperator()->setSchwarzFactorizationType(GMGOperator::ILU); // if (solverChoice == "GMG-IC") // gmgSolver->gmgOperator()->setSchwarzFactorizationType(GMGOperator::IC); } while (l2Update > nonlinearTolerance && iterCount < maxNonlinearIterations) { if (solverChoice[0] == 'G') solutionUpdate->solve(gmgSolver); else solutionUpdate->condensedSolve(solvers[solverChoice]); // Compute L2 norm of update double u1L2Update = solutionUpdate->L2NormOfSolutionGlobal(form->u(1)->ID()); double u2L2Update = solutionUpdate->L2NormOfSolutionGlobal(form->u(2)->ID()); l2Update = sqrt(u1L2Update*u1L2Update + u2L2Update*u2L2Update); if (commRank == 0) cout << "Nonlinear Update:\t " << l2Update << endl; form->updateSolution(); iterCount++; } double solveTime = solverTime->stop(); double energyError = solutionUpdate->energyErrorTotal(); double l2Error = 0; if (computeL2Error) { l2Error = problem->computeL2Error(form, solutionBackground); } if (commRank == 0) { cout << "Refinement: " << refIndex << " \tElements: " << mesh->numActiveElements() << " \tDOFs: " << mesh->numGlobalDofs() << " \tEnergy Error: " << energyError << " \tL2 Error: " << l2Error << " \tSolve Time: " << solveTime << " \tTotal Time: " << totalTimer->totalElapsedTime(true) // << " \tIteration Count: " << iterationCount << endl; dataFile << refIndex << " " << mesh->numActiveElements() << " " << mesh->numGlobalDofs() << " " << energyError << " " << l2Error << " " << solveTime << " " << totalTimer->totalElapsedTime(true) // << " " << iterationCount << endl; } if (exportSolution) exporter->exportSolution(solutionBackground, refIndex); if (saveSolution) { ostringstream saveFile; saveFile << saveFilePrefix << "_ref" << refIndex; form->save(saveFile.str()); } if (refIndex != numRefs) { // k0Mesh = Teuchos::rcp( new Mesh (mesh->getTopology()->deepCopy(), form->bf(), 1, delta_p) ); // meshesCoarseToFine.push_back(k0Mesh); refStrategy->refine(); meshesCoarseToFine.push_back(mesh); } } dataFile.close(); } double totalTime = totalTimer->stop(); if (commRank == 0) cout << "Total time = " << totalTime << endl; return 0; }
// *********************************************************** int DG_Prob::Eigenvectors(const double Dt, const Epetra_Map & Map) { printf("Entrou em Eigenvectors\n"); #ifdef HAVE_MPI Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif //MPI::COMM_WORLD.Barrier(); Comm.Barrier(); Teuchos::RCP<Epetra_FECrsMatrix> M = Teuchos::rcp(new Epetra_FECrsMatrix(Copy, Map,0));//&NNz[0]); Teuchos::RCP<Epetra_FEVector> RHS = Teuchos::rcp(new Epetra_FEVector(Map,1)); DG_MatrizVetor_Epetra(Dt,M,RHS); Teuchos::RCP<Epetra_CrsMatrix> A = Teuchos::rcp(new Epetra_CrsMatrix(Copy, Map,0 /* &NNz[0]*/) ); Epetra_Export Exporter(Map,Map); A->PutScalar(0.0); A->Export(*(M.ptr()),Exporter,Add); A->FillComplete(); using std::cout; // int nx = 5; bool boolret; int MyPID = Comm.MyPID(); bool verbose = true; bool debug = false; std::string which("LR"); Teuchos::CommandLineProcessor cmdp(false,true); cmdp.setOption("verbose","quiet",&verbose,"Print messages and results."); cmdp.setOption("debug","nodebug",&debug,"Print debugging information."); cmdp.setOption("sort",&which,"Targetted eigenvalues (SM,LM,SR,LR,SI,or LI)."); typedef double ScalarType; typedef Teuchos::ScalarTraits<ScalarType> SCT; typedef SCT::magnitudeType MagnitudeType; typedef Epetra_MultiVector MV; typedef Epetra_Operator OP; typedef Anasazi::MultiVecTraits<ScalarType,MV> MVT; typedef Anasazi::OperatorTraits<ScalarType,MV,OP> OPT; // double rho = 2*nx+1; // Compute coefficients for discrete convection-diffution operator // const double one = 1.0; // int NumEntries, info; //************************************ // Start the block Arnoldi iteration //*********************************** // // Variables used for the Block Krylov Schur Method // int nev = 10; int blockSize = 1; int numBlocks = 20; int maxRestarts = 500; //int stepSize = 5; double tol = 1e-8; // Create a sort manager to pass into the block Krylov-Schur solver manager // --> Make sure the reference-counted pointer is of type Anasazi::SortManager<> // --> The block Krylov-Schur solver manager uses Anasazi::BasicSort<> by default, // so you can also pass in the parameter "Which", instead of a sort manager. Teuchos::RCP<Anasazi::SortManager<MagnitudeType> > MySort = Teuchos::rcp( new Anasazi::BasicSort<MagnitudeType>( which ) ); // Set verbosity level int verbosity = Anasazi::Errors + Anasazi::Warnings; if (verbose) { verbosity += Anasazi::FinalSummary + Anasazi::TimingDetails; } if (debug) { verbosity += Anasazi::Debug; } // // Create parameter list to pass into solver manager // Teuchos::ParameterList MyPL; MyPL.set( "Verbosity", verbosity ); MyPL.set( "Sort Manager", MySort ); //MyPL.set( "Which", which ); MyPL.set( "Block Size", blockSize ); MyPL.set( "Num Blocks", numBlocks ); MyPL.set( "Maximum Restarts", maxRestarts ); //MyPL.set( "Step Size", stepSize ); MyPL.set( "Convergence Tolerance", tol ); // Create an Epetra_MultiVector for an initial vector to start the solver. // Note: This needs to have the same number of columns as the blocksize. Teuchos::RCP<Epetra_MultiVector> ivec = Teuchos::rcp( new Epetra_MultiVector(Map, blockSize) ); ivec->Random(); // Create the eigenproblem. Teuchos::RCP<Anasazi::BasicEigenproblem<double, MV, OP> > MyProblem = Teuchos::rcp( new Anasazi::BasicEigenproblem<double, MV, OP>(A, ivec) ); // Inform the eigenproblem that the operator A is symmetric //MyProblem->setHermitian(rho==0.0); // Set the number of eigenvalues requested MyProblem->setNEV( nev ); // Inform the eigenproblem that you are finishing passing it information boolret = MyProblem->setProblem(); if (boolret != true) { if (verbose && MyPID == 0) { cout << "Anasazi::BasicEigenproblem::setProblem() returned with error." << endl; } #ifdef HAVE_MPI MPI_Finalize() ; #endif return -1; } // Initialize the Block Arnoldi solver Anasazi::BlockKrylovSchurSolMgr<double, MV, OP> MySolverMgr(MyProblem, MyPL); // Solve the problem to the specified tolerances or length Anasazi::ReturnType returnCode = MySolverMgr.solve(); if (returnCode != Anasazi::Converged && MyPID==0 && verbose) { cout << "Anasazi::EigensolverMgr::solve() returned unconverged." << endl; } // Get the Ritz values from the eigensolver std::vector<Anasazi::Value<double> > ritzValues = MySolverMgr.getRitzValues(); // Output computed eigenvalues and their direct residuals if (verbose && MyPID==0) { int numritz = (int)ritzValues.size(); cout.setf(std::ios_base::right, std::ios_base::adjustfield); cout<<endl<< "Computed Ritz Values"<< endl; if (MyProblem->isHermitian()) { cout<< std::setw(16) << "Real Part" << endl; cout<<"-----------------------------------------------------------"<<endl; for (int i=0; i<numritz; i++) { cout<< std::setw(16) << ritzValues[i].realpart << endl; } cout<<"-----------------------------------------------------------"<<endl; } else { cout<< std::setw(16) << "Real Part" << std::setw(16) << "Imag Part" << endl; cout<<"-----------------------------------------------------------"<<endl; for (int i=0; i<numritz; i++) { cout<< std::setw(16) << ritzValues[i].realpart << std::setw(16) << ritzValues[i].imagpart << endl; } cout<<"-----------------------------------------------------------"<<endl; } } // Get the eigenvalues and eigenvectors from the eigenproblem Anasazi::Eigensolution<ScalarType,MV> sol = MyProblem->getSolution(); std::vector<Anasazi::Value<ScalarType> > evals = sol.Evals; Teuchos::RCP<MV> evecs = sol.Evecs; std::vector<int> index = sol.index; int numev = sol.numVecs; if (numev > 0) { // Compute residuals. Teuchos::LAPACK<int,double> lapack; std::vector<double> normA(numev); if (MyProblem->isHermitian()) { // Get storage Epetra_MultiVector Aevecs(Map,numev); Teuchos::SerialDenseMatrix<int,double> B(numev,numev); B.putScalar(0.0); for (int i=0; i<numev; i++) {B(i,i) = evals[i].realpart;} // Compute A*evecs OPT::Apply( *A, *evecs, Aevecs ); // Compute A*evecs - lambda*evecs and its norm MVT::MvTimesMatAddMv( -1.0, *evecs, B, 1.0, Aevecs ); MVT::MvNorm( Aevecs, normA ); // Scale the norms by the eigenvalue for (int i=0; i<numev; i++) { normA[i] /= Teuchos::ScalarTraits<double>::magnitude( evals[i].realpart ); } } else { // The problem is non-Hermitian. int i=0; std::vector<int> curind(1); std::vector<double> resnorm(1), tempnrm(1); Teuchos::RCP<MV> tempAevec; Teuchos::RCP<const MV> evecr, eveci; Epetra_MultiVector Aevec(Map,numev); // Compute A*evecs OPT::Apply( *A, *evecs, Aevec ); Teuchos::SerialDenseMatrix<int,double> Breal(1,1), Bimag(1,1); while (i<numev) { if (index[i]==0) { // Get a view of the current eigenvector (evecr) curind[0] = i; evecr = MVT::CloneView( *evecs, curind ); // Get a copy of A*evecr tempAevec = MVT::CloneCopy( Aevec, curind ); // Compute A*evecr - lambda*evecr Breal(0,0) = evals[i].realpart; MVT::MvTimesMatAddMv( -1.0, *evecr, Breal, 1.0, *tempAevec ); // Compute the norm of the residual and increment counter MVT::MvNorm( *tempAevec, resnorm ); normA[i] = resnorm[0]/Teuchos::ScalarTraits<MagnitudeType>::magnitude( evals[i].realpart ); i++; } else { // Get a view of the real part of the eigenvector (evecr) curind[0] = i; evecr = MVT::CloneView( *evecs, curind ); // Get a copy of A*evecr tempAevec = MVT::CloneCopy( Aevec, curind ); // Get a view of the imaginary part of the eigenvector (eveci) curind[0] = i+1; eveci = MVT::CloneView( *evecs, curind ); // Set the eigenvalue into Breal and Bimag Breal(0,0) = evals[i].realpart; Bimag(0,0) = evals[i].imagpart; // Compute A*evecr - evecr*lambdar + eveci*lambdai MVT::MvTimesMatAddMv( -1.0, *evecr, Breal, 1.0, *tempAevec ); MVT::MvTimesMatAddMv( 1.0, *eveci, Bimag, 1.0, *tempAevec ); MVT::MvNorm( *tempAevec, tempnrm ); // Get a copy of A*eveci tempAevec = MVT::CloneCopy( Aevec, curind ); // Compute A*eveci - eveci*lambdar - evecr*lambdai MVT::MvTimesMatAddMv( -1.0, *evecr, Bimag, 1.0, *tempAevec ); MVT::MvTimesMatAddMv( -1.0, *eveci, Breal, 1.0, *tempAevec ); MVT::MvNorm( *tempAevec, resnorm ); // Compute the norms and scale by magnitude of eigenvalue normA[i] = lapack.LAPY2( tempnrm[i], resnorm[i] ) / lapack.LAPY2( evals[i].realpart, evals[i].imagpart ); normA[i+1] = normA[i]; i=i+2; } } } // Output computed eigenvalues and their direct residuals if (verbose && MyPID==0) { cout.setf(std::ios_base::right, std::ios_base::adjustfield); cout<<endl<< "Actual Residuals"<<endl; if (MyProblem->isHermitian()) { cout<< std::setw(16) << "Real Part" << std::setw(20) << "Direct Residual"<< endl; cout<<"-----------------------------------------------------------"<<endl; for (int i=0; i<numev; i++) { cout<< std::setw(16) << evals[i].realpart << std::setw(20) << normA[i] << endl; } cout<<"-----------------------------------------------------------"<<endl; } else { cout<< std::setw(16) << "Real Part" << std::setw(16) << "Imag Part" << std::setw(20) << "Direct Residual"<< endl; cout<<"-----------------------------------------------------------"<<endl; for (int i=0; i<numev; i++) { cout<< std::setw(16) << evals[i].realpart << std::setw(16) << evals[i].imagpart << std::setw(20) << normA[i] << endl; } cout<<"-----------------------------------------------------------"<<endl; } } } #ifdef EPETRA_MPI MPI_Finalize(); #endif return 0; }
int main(int argc, char *argv[]) { // Initialize MPI #ifdef HAVE_MPI MPI_Init(&argc,&argv); #endif // Create a communicator for Epetra objects #ifdef HAVE_MPI Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else Epetra_SerialComm Comm; #endif bool verbose = false; bool success = false; try { int globalLength = 100; // This should suffice if (argc > 1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; // Get the process ID and the total number of processors int MyPID = Comm.MyPID(); // Set up the printing utilities Teuchos::RCP<Teuchos::ParameterList> noxParamsPtr = Teuchos::rcp(new Teuchos::ParameterList); Teuchos::ParameterList& noxParams = *(noxParamsPtr.get()); // Only print output if the "-v" flag is set on the command line Teuchos::ParameterList& printParams = noxParams.sublist("Printing"); printParams.set("MyPID", MyPID); printParams.set("Output Precision", 5); printParams.set("Output Processor", 0); if( verbose ) printParams.set("Output Information", NOX::Utils::OuterIteration + NOX::Utils::OuterIterationStatusTest + NOX::Utils::InnerIteration + NOX::Utils::Parameters + NOX::Utils::Details + NOX::Utils::Warning + NOX::Utils::TestDetails); else printParams.set("Output Information", NOX::Utils::Error); NOX::Utils printing(printParams); // Identify the test problem if (printing.isPrintType(NOX::Utils::TestDetails)) printing.out() << "Starting epetra/NOX_Vector/NOX_Vector.exe" << std::endl; // Create a TestCompare class NOX::TestCompare tester( printing.out(), printing); double tolerance = 1.e-12; NOX::TestCompare::CompareType aComp = NOX::TestCompare::Absolute; // Identify processor information #ifdef HAVE_MPI printing.out() << "Parallel Run" << std::endl; printing.out() << "Number of processors = " << Comm.NumProc() << std::endl; printing.out() << "Print Process = " << MyPID << std::endl; Comm.Barrier(); if (printing.isPrintType(NOX::Utils::TestDetails)) printing.out() << "Process " << MyPID << " is alive!" << std::endl; Comm.Barrier(); #else printing.out() << "Serial Run" << std::endl; #endif // Create a map describing data distribution Epetra_Map * standardMap = new Epetra_Map(globalLength, 0, Comm); // Return value int status = 0; // *** Start Testing Here!!! *** // First create the Epetra_Vector needed to construct our NOX vector Epetra_Vector * epetraVec = new Epetra_Vector(*standardMap, true); NOX::Epetra::Vector * noxVec1 = new NOX::Epetra::Vector(*epetraVec, NOX::DeepCopy); delete epetraVec; epetraVec = 0; NOX::Epetra::Vector * noxVec2 = new NOX::Epetra::Vector(*noxVec1); noxVec2->init(1.0); // Test our norms NOX::Abstract::Vector::NormType oneNorm = NOX::Abstract::Vector::OneNorm, twoNorm = NOX::Abstract::Vector::TwoNorm, infNorm = NOX::Abstract::Vector::MaxNorm; double expectedOneNorm = (double) globalLength, expectedTwoNorm = sqrt( (double) globalLength), expectedInfNorm = 1.0; status += tester.testValue( noxVec2->norm(oneNorm), expectedOneNorm, tolerance, "One-Norm Test", aComp); status += tester.testValue( noxVec2->norm(twoNorm), expectedTwoNorm, tolerance, "Two-Norm Test", aComp); status += tester.testValue( noxVec2->norm(infNorm), expectedInfNorm, tolerance, "Max-Norm Test", aComp); // Test random, reciprocal and dot methods noxVec1->random(); // Threshold values since we want to do a reciprocal int myLength = standardMap->NumMyElements(); for( int i = 0; i < myLength; ++i ) if( fabs(noxVec1->getEpetraVector()[i]) < 1.e-8 ) noxVec1->getEpetraVector()[i] = 1.e-8; noxVec2->reciprocal(*noxVec1); double product = noxVec1->innerProduct(*noxVec2); status += tester.testValue( product, expectedOneNorm, tolerance, "Random, Reciprocal and Dot Test", aComp); // Test abs and weighted-norm methods /* ---------------------------- NOT SUPPORTED AT THIS TIME ---------------------------- noxVec2->abs(*noxVec2); double wNorm = noxVec1->norm(*noxVec2); status += tester.testValue( wNorm, noxVec1->norm(oneNorm), tolerance, "Abs and Weighted-Norm Test", aComp); */ // Test operator= , abs, update and scale methods (*noxVec2) = (*noxVec1); noxVec2->abs(*noxVec2); double sumAll = noxVec1->norm(oneNorm); noxVec2->update( 1.0, *noxVec1, 1.0 ); noxVec2->scale(0.5); double sumPositive = noxVec2->norm(oneNorm); (*noxVec2) = (*noxVec1); noxVec2->abs(*noxVec2); noxVec2->update( 1.0, *noxVec1, -1.0 ); noxVec2->scale(0.5); double sumNegative = noxVec2->norm(oneNorm); status += tester.testValue( (sumPositive + sumNegative), sumAll, tolerance, "Abs, Operator= , Update and Scale Test", aComp); success = status==0; if (success) printing.out() << "Test passed!" << std::endl; else printing.out() << "Test failed!" << std::endl; delete noxVec2; delete noxVec1; delete standardMap; } TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success); #ifdef HAVE_MPI MPI_Finalize(); #endif return ( success ? EXIT_SUCCESS : EXIT_FAILURE ); }
int main(int argc, char *argv[]) { int i; // Initialize MPI #ifdef HAVE_MPI MPI_Init(&argc,&argv); #endif // Create a communicator for Epetra objects #ifdef HAVE_MPI Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else Epetra_SerialComm Comm; #endif bool verbose = false; if (argc > 1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; // Get the process ID and the total number of processors int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); int NumGlobalElements = 2; // Hardcoded for D&S Example problem // A maximum of 2 procesors is allowed since there are only 2 equations if (NumProc >= 3) { std::cout << "ERROR: Maximum number of processors is 2!" << std::endl; exit(1); } // Create the Problem class. This creates all required // Epetra objects for the problem and allows calls to the // function (RHS) and Jacobian evaluation routines. DennisSchnabel Problem(NumGlobalElements, Comm); // Get the vector from the Problem Teuchos::RCP<Epetra_Vector> soln = Problem.getSolution(); NOX::Epetra::Vector noxSoln(soln, NOX::Epetra::Vector::CreateView); // Initialize Solution if (MyPID==0) { (*soln)[0]=2.0; if (NumProc==1) (*soln)[1]=0.5; } else (*soln)[0]=0.5; // Begin Nonlinear Solver ************************************ // Create the top level parameter list Teuchos::RCP<Teuchos::ParameterList> nlParamsPtr = Teuchos::rcp(new Teuchos::ParameterList); Teuchos::ParameterList& nlParams = *(nlParamsPtr.get()); // Set the nonlinear solver method nlParams.set("Nonlinear Solver", "Line Search Based"); // Set the printing parameters in the "Printing" sublist Teuchos::ParameterList& printParams = nlParams.sublist("Printing"); printParams.set("MyPID", MyPID); printParams.set("Output Precision", 5); printParams.set("Output Processor", 0); if ( verbose ) printParams.set("Output Information", NOX::Utils::OuterIteration + NOX::Utils::OuterIterationStatusTest + NOX::Utils::InnerIteration + NOX::Utils::Parameters + NOX::Utils::Details + NOX::Utils::Warning + NOX::Utils::TestDetails); else printParams.set("Output Information", NOX::Utils::Error + NOX::Utils::TestDetails); NOX::Utils printing(printParams); // Identify the test problem if (printing.isPrintType(NOX::Utils::TestDetails)) std::cout << "Starting epetra/DS6.5.1/DS_6_5_1.exe" << std::endl; // Identify processor information #ifdef HAVE_MPI if (printing.isPrintType(NOX::Utils::TestDetails)) { std::cout << "Parallel Run" << std::endl; std::cout << "Number of processors = " << NumProc << std::endl; std::cout << "Print Process = " << MyPID << std::endl; } Comm.Barrier(); if (printing.isPrintType(NOX::Utils::TestDetails)) std::cout << "Process " << MyPID << " is alive!" << std::endl; Comm.Barrier(); #else if (printing.isPrintType(NOX::Utils::TestDetails)) std::cout << "Serial Run" << std::endl; #endif // Sublist for line search Teuchos::ParameterList& searchParams = nlParams.sublist("Line Search"); // This test is designed to exercise the following linesearch searchParams.set("Method", "Polynomial"); // Sublist for direction Teuchos::ParameterList& dirParams = nlParams.sublist("Direction"); dirParams.set("Method", "Newton"); Teuchos::ParameterList& newtonParams = dirParams.sublist("Newton"); newtonParams.set("Forcing Term Method", "Constant"); // Sublist for linear solver for the Newton method Teuchos::ParameterList& lsParams = newtonParams.sublist("Linear Solver"); lsParams.set("Aztec Solver", "GMRES"); lsParams.set("Max Iterations", 20); lsParams.set("Tolerance", 1e-4); lsParams.set("Preconditioner", "None"); if( verbose ) lsParams.set("Output Frequency", 1); // Debugging output #ifdef HAVE_NOX_DEBUG #ifdef HAVE_NOX_EPETRAEXT lsParams.set("Write Linear System", true); lsParams.set("Write Linear System File Prefix", "LinSys_Output_Test"); #endif #endif // Create the interface between the test problem and the nonlinear solver Teuchos::RCP<Problem_Interface> interface = Teuchos::rcp(new Problem_Interface(Problem)); // Create the Epetra_RowMatrix. Uncomment one or more of the following: // 1. User supplied (Epetra_RowMatrix) Teuchos::RCP<Epetra_RowMatrix> A = Problem.getJacobian(); // Create the callback interfaces for filling the residual and Jacbian Teuchos::RCP<NOX::Epetra::Interface::Required> iReq = interface; Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac = interface; // Create the Linear System Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linSys = Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams, iReq, iJac, A, noxSoln)); // Create the Group Teuchos::RCP<NOX::Epetra::Group> grpPtr = Teuchos::rcp(new NOX::Epetra::Group(printParams, iReq, noxSoln, linSys)); // Create the convergence tests Teuchos::RCP<NOX::StatusTest::NormF> testNormF = Teuchos::rcp(new NOX::StatusTest::NormF(1.0e-6)); Teuchos::RCP<NOX::StatusTest::MaxIters> testMaxIters = Teuchos::rcp(new NOX::StatusTest::MaxIters(25)); Teuchos::RCP<NOX::StatusTest::Combo> combo = Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR, testNormF, testMaxIters)); // Create the method Teuchos::RCP<NOX::Solver::Generic> solver = NOX::Solver::buildSolver(grpPtr, combo, nlParamsPtr); NOX::StatusTest::StatusType status = solver->solve(); // Get the Epetra_Vector with the final solution from the solver const NOX::Epetra::Group& finalGroup = dynamic_cast<const NOX::Epetra::Group&>(solver->getSolutionGroup()); const Epetra_Vector& finalSolution = (dynamic_cast<const NOX::Epetra::Vector&>(finalGroup.getX())).getEpetraVector(); // End Nonlinear Solver ************************************** // Output the parameter list if (printing.isPrintType(NOX::Utils::Parameters)) { std::cout << std::endl << "Final Parameters" << std::endl << "****************" << std::endl; solver->getList().print(cout); std::cout << std::endl; } // Print solution char file_name[25]; FILE *ifp; int NumMyElements = soln->Map().NumMyElements(); (void) sprintf(file_name, "output.%d",MyPID); ifp = fopen(file_name, "w"); for (i=0; i<NumMyElements; i++) fprintf(ifp, "%d %E\n", soln->Map().MinMyGID()+i, finalSolution[i]); fclose(ifp); // Report results int testStatus = 0; // Converged // 1. Convergence if (status != NOX::StatusTest::Converged) { if (MyPID==0) std::cout << "Nonlinear solver failed to converge!" << std::endl; testStatus = 1; } // 2. Nonlinear Iterations (7) if (const_cast<Teuchos::ParameterList&>(solver->getList()).sublist("Output").get("Nonlinear Iterations",0) != 7) { testStatus = 2; } // 3. Linear Iterations (14) if (const_cast<Teuchos::ParameterList&>(solver->getList()).sublist("Direction").sublist("Newton").sublist("Linear Solver").sublist("Output").get("Total Number of Linear Iterations",0) != 14) { testStatus = 3; } // 4. Number of Non-trivial Line Searches (2) if (const_cast<Teuchos::ParameterList&>(solver->getList()).sublist("Line Search").sublist("Output").get("Total Number of Non-trivial Line Searches",0) != 2) { testStatus = 4; } // 5. Number of Line Search Inner Iterations (4) if (const_cast<Teuchos::ParameterList&>(solver->getList()).sublist("Line Search").sublist("Output").get("Total Number of Line Search Inner Iterations",0) != 4) { testStatus = 5; } // 6. Number of Failed Line Searches (0) if (const_cast<Teuchos::ParameterList&>(solver->getList()).sublist("Line Search").sublist("Output").get("Total Number of Failed Line Searches",-1) != 0) { testStatus = 6; } if (testStatus == 0) std::cout << "Test passed!" << std::endl; else std::cout << "Test failed!" << std::endl; #ifdef HAVE_MPI MPI_Finalize() ; #endif return testStatus; } // end main
int main(int argc, char *argv[]) { int ierr = 0; int i; int forierr = 0; long long* Indices; bool debug = true; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); int rank; // My process ID MPI_Comm_rank(MPI_COMM_WORLD, &rank); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else int rank = 0; 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 && rank == 0) cout << Epetra_Version() << endl << endl; //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 int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if(verbose) cout << "Processor "<<MyPID<<" of "<< NumProc << " is alive." << endl; bool verbose1 = verbose; // Redefine verbose to only print on PE 0 if(verbose && rank != 0) verbose = false; int NumMyEquations = 5; long long NumGlobalEquations = NumMyEquations*NumProc+EPETRA_MIN(NumProc,3); if(MyPID < 3) NumMyEquations++; // Construct a Map that puts approximately the same Number of equations on each processor Epetra_Map& Map = *new Epetra_Map(NumGlobalEquations, NumMyEquations, 0LL, Comm); // Get update list and number of local equations from newly created Map long long* MyGlobalElements = new long long[Map.NumMyElements()]; Map.MyGlobalElements(MyGlobalElements); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor int* NumNz = new int[NumMyEquations]; // We are building a tridiagonal matrix where each row has (-1 2 -1) // So we need 2 off-diagonal terms (except for the first and last equation) for(i=0; i<NumMyEquations; i++) if(MyGlobalElements[i]==0 || MyGlobalElements[i] == NumGlobalEquations-1) NumNz[i] = 1; else NumNz[i] = 2; // Create a Epetra_CrsGraph Epetra_CrsGraph& A = *new Epetra_CrsGraph(Copy, Map, NumNz); EPETRA_TEST_ERR(A.IndicesAreGlobal(),ierr); EPETRA_TEST_ERR(A.IndicesAreLocal(),ierr); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 Indices = new long long[2]; int NumEntries; forierr = 0; for(i = 0; i < NumMyEquations; i++) { if(MyGlobalElements[i] == 0) { Indices[0] = 1; NumEntries = 1; } else if(MyGlobalElements[i] == NumGlobalEquations-1) { Indices[0] = NumGlobalEquations-2; NumEntries = 1; } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; NumEntries = 2; } forierr += !(A.InsertGlobalIndices(MyGlobalElements[i], NumEntries, Indices)==0); forierr += !(A.InsertGlobalIndices(MyGlobalElements[i], 1, MyGlobalElements+i)>0); // Put in the diagonal entry (should cause realloc) } EPETRA_TEST_ERR(forierr,ierr); //A.PrintGraphData(cout); delete[] Indices; // Finish up EPETRA_TEST_ERR(!(A.IndicesAreGlobal()),ierr); EPETRA_TEST_ERR(!(A.FillComplete()==0),ierr); EPETRA_TEST_ERR(!(A.IndicesAreLocal()),ierr); EPETRA_TEST_ERR(A.StorageOptimized(),ierr); A.OptimizeStorage(); EPETRA_TEST_ERR(!(A.StorageOptimized()),ierr); EPETRA_TEST_ERR(A.UpperTriangular(),ierr); EPETRA_TEST_ERR(A.LowerTriangular(),ierr); if(verbose) cout << "\n*****Testing variable entry constructor\n" << endl; int NumMyNonzeros = 3 * NumMyEquations; if(A.LRID(0) >= 0) NumMyNonzeros--; // If I own first global row, then there is one less nonzero if(A.LRID(NumGlobalEquations-1) >= 0) NumMyNonzeros--; // If I own last global row, then there is one less nonzero EPETRA_TEST_ERR(check(A, NumMyEquations, NumGlobalEquations, NumMyNonzeros, 3*NumGlobalEquations-2, MyGlobalElements, verbose),ierr); forierr = 0; for(i = 0; i < NumMyEquations; i++) forierr += !(A.NumGlobalIndices(MyGlobalElements[i])==NumNz[i]+1); EPETRA_TEST_ERR(forierr,ierr); for(i = 0; i < NumMyEquations; i++) forierr += !(A.NumMyIndices(i)==NumNz[i]+1); EPETRA_TEST_ERR(forierr,ierr); if(verbose) cout << "NumIndices function check OK" << endl; delete &A; if(debug) Comm.Barrier(); if(verbose) cout << "\n*****Testing constant entry constructor\n" << endl; Epetra_CrsGraph& AA = *new Epetra_CrsGraph(Copy, Map, 5); if(debug) Comm.Barrier(); for(i = 0; i < NumMyEquations; i++) AA.InsertGlobalIndices(MyGlobalElements[i], 1, MyGlobalElements+i); // Note: All processors will call the following Insert routines, but only the processor // that owns it will actually do anything long long One = 1; if(AA.MyGlobalRow(0)) { EPETRA_TEST_ERR(!(AA.InsertGlobalIndices(0, 0, &One)==0),ierr); } else EPETRA_TEST_ERR(!(AA.InsertGlobalIndices(0, 1, &One)==-2),ierr); EPETRA_TEST_ERR(!(AA.FillComplete()==0),ierr); EPETRA_TEST_ERR(AA.StorageOptimized(),ierr); EPETRA_TEST_ERR(!(AA.UpperTriangular()),ierr); EPETRA_TEST_ERR(!(AA.LowerTriangular()),ierr); if(debug) Comm.Barrier(); EPETRA_TEST_ERR(check(AA, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations, MyGlobalElements, verbose),ierr); if(debug) Comm.Barrier(); forierr = 0; for(i = 0; i < NumMyEquations; i++) forierr += !(AA.NumGlobalIndices(MyGlobalElements[i])==1); EPETRA_TEST_ERR(forierr,ierr); if(verbose) cout << "NumIndices function check OK" << endl; if(debug) Comm.Barrier(); if(verbose) cout << "\n*****Testing copy constructor\n" << endl; Epetra_CrsGraph& B = *new Epetra_CrsGraph(AA); delete &AA; EPETRA_TEST_ERR(check(B, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations, MyGlobalElements, verbose),ierr); forierr = 0; for(i = 0; i < NumMyEquations; i++) forierr += !(B.NumGlobalIndices(MyGlobalElements[i])==1); EPETRA_TEST_ERR(forierr,ierr); if(verbose) cout << "NumIndices function check OK" << endl; if(debug) Comm.Barrier(); if(verbose) cout << "\n*****Testing post construction modifications\n" << endl; EPETRA_TEST_ERR(!(B.InsertGlobalIndices(0, 1, &One)==-2),ierr); delete &B; // Release all objects delete[] MyGlobalElements; delete[] NumNz; delete ⤅ if (verbose1) { // Test ostream << operator (if verbose1) // Construct a Map that puts 2 equations on each PE int NumMyElements1 = 4; int NumMyEquations1 = NumMyElements1; long long NumGlobalEquations1 = NumMyEquations1*NumProc; Epetra_Map& Map1 = *new Epetra_Map(NumGlobalEquations1, NumMyElements1, 1LL, Comm); // Get update list and number of local equations from newly created Map long long* MyGlobalElements1 = new long long[Map1.NumMyElements()]; Map1.MyGlobalElements(MyGlobalElements1); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor int* NumNz1 = new int[NumMyEquations1]; // We are building a tridiagonal matrix where each row has (-1 2 -1) // So we need 2 off-diagonal terms (except for the first and last equation) for(i = 0; i < NumMyEquations1; i++) if(MyGlobalElements1[i]==1 || MyGlobalElements1[i] == NumGlobalEquations1) NumNz1[i] = 1; else NumNz1[i] = 2; // Create a Epetra_Graph using 1-based arithmetic Epetra_CrsGraph& A1 = *new Epetra_CrsGraph(Copy, Map1, NumNz1); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 long long* Indices1 = new long long[2]; int NumEntries1; forierr = 0; for(i = 0; i < NumMyEquations1; i++) { if(MyGlobalElements1[i]==1) { Indices1[0] = 2; NumEntries1 = 1; } else if(MyGlobalElements1[i] == NumGlobalEquations1) { Indices1[0] = NumGlobalEquations1-1; NumEntries1 = 1; } else { Indices1[0] = MyGlobalElements1[i]-1; Indices1[1] = MyGlobalElements1[i]+1; NumEntries1 = 2; } forierr += !(A1.InsertGlobalIndices(MyGlobalElements1[i], NumEntries1, Indices1)==0); forierr += !(A1.InsertGlobalIndices(MyGlobalElements1[i], 1, MyGlobalElements1+i)>0); // Put in the diagonal entry } EPETRA_TEST_ERR(forierr,ierr); // Finish up EPETRA_TEST_ERR(!(A1.FillComplete()==0),ierr); if(verbose) cout << "Print out tridiagonal matrix, each part on each processor. Index base is one.\n" << endl; cout << A1 << endl; // Release all objects delete[] NumNz1; delete[] Indices1; delete[] MyGlobalElements1; delete &A1; delete &Map1; } // Test copy constructor, op=, and reference-counting int tempierr = 0; if(verbose) cout << "\n*****Checking cpy ctr, op=, and reference counting." << endl; tempierr = checkCopyAndAssignment(Comm, verbose); EPETRA_TEST_ERR(tempierr, ierr); if(verbose && (tempierr == 0)) cout << "Checked OK." << endl; // Test shared-ownership code (not implemented yet) tempierr = 0; if(verbose) cout << "\n*****Checking shared-ownership tests." << endl; tempierr = checkSharedOwnership(Comm, verbose); EPETRA_TEST_ERR(tempierr, ierr); if(verbose && (tempierr == 0)) cout << "Checked OK." << endl; #ifdef EPETRA_MPI MPI_Finalize() ; #endif /* end main */ return(ierr); }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI MPI_Init(&argc, &argv); // define an Epetra communicator Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif // get the proc ID of this process int MyPID = Comm.MyPID(); // get the total number of processes int NumProc = Comm.NumProc(); // output some information to std output cout << Comm << endl; // ======================== // // now some basic MPI calls // // ------------------------ // int ivalue; double dvalue, dvalue2; double* dvalues; dvalues = new double[NumProc]; double* dvalues2; dvalues2 = new double[NumProc]; int root = 0; // equivalent to MPI_Barrier Comm.Barrier(); if (MyPID == root) dvalue = 12.0; // On input, the root processor contains the list of values // (in this case, a single value). On exit, all processes will // have he same list of values. Note that all values must be allocated // vefore the broadcast // equivalent to MPI_Broadcast Comm.Broadcast(&dvalue, 1, root); // as before, but with integer values. As C++ can bind to the appropriate // interface based on argument typing, the type of data is not required. Comm.Broadcast(&ivalue, 1, root); // equivalent MPI_Allgather Comm.GatherAll(dvalues, dvalues2, 1); // equivalent to MPI_Allreduce with MPI_SUM dvalue = 1.0*MyPID; Comm.SumAll( &dvalue, dvalues, 1); // equivalent to MPI_Allreduce with MPI_SUM Comm.MaxAll( &dvalue, dvalues, 1); // equiavant to MPI_Scan with MPI_SUM dvalue = 1.0 * MyPID; Comm.ScanSum(&dvalue, &dvalue2, 1); cout << "On proc " << MyPID << " dvalue2 = " << dvalue2 << endl; delete[] dvalues; delete[] dvalues2; // ======================= // // Finalize MPI and return // // ----------------------- // #ifdef HAVE_MPI MPI_Finalize(); #endif return( EXIT_SUCCESS ); } /* main */
int main(int argc, char * argv[]) { // Set up the Epetra communicator #ifdef EPETRA_MPI MPI_Init(&argc, &argv); int size; // Number of MPI processes int rank; // My process ID MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else int size = 1; // Serial case (not using MPI) int rank = 0; // Processor ID Epetra_SerialComm Comm; #endif // cout << Comm << endl; int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); bool verbose = (MyPID == 0); cout << "MyPID = " << MyPID << endl << "NumProc = " << NumProc << endl; // Get the problem size from the command line argument if (argc < 2 || argc > 3) { if (verbose) cout << "Usage: " << argv[0] << " nx [ny]" << endl; exit(1); } // end if int nx = atoi(argv[1]); // Get the dimensions for a 1D or 2D int ny = 1; // central difference problem if (argc == 3) ny = atoi(argv[2]); int NumGlobalElements = nx * ny; if (NumGlobalElements < NumProc) { if (verbose) cout << "numGlobalElements = " << NumGlobalElements << " cannot be < number of processors = " << NumProc << endl; exit(1); } // end if // Epetra distribution map int IndexBase = 0; // Zero-based indices Epetra_Map Map(NumGlobalElements, IndexBase, Comm); // if (verbose) cout << Map << endl; // Extract the global indices of the elements local to this processor int NumMyElements = Map.NumMyElements(); int * MyGlobalElements = new int[NumMyElements]; Map.MyGlobalElements(MyGlobalElements); for (int p = 0; p < NumProc; p++) if (p == MyPID) { cout << endl << "Processor " << MyPID << ": Global elements = "; for (int i = 0; i < NumMyElements; i++) cout << MyGlobalElements[i] << " "; cout << endl; Comm.Barrier(); } // end if // Create the number of non-zeros for a tridiagonal (1D problem) or banded // (2D problem) matrix int * NumNz = new int[NumMyElements]; int global_i; int global_j; for (int i = 0; i < NumMyElements; i++) { NumNz[i] = 5; global_j = MyGlobalElements[i] / nx; global_i = MyGlobalElements[i] - global_j * nx; if (global_i == 0) NumNz[i] -= 1; // By having separate statements, if (global_i == nx-1) NumNz[i] -= 1; // this works for 2D as well as 1D if (global_j == 0) NumNz[i] -= 1; // systems (i.e. nx x 1 or 1 x ny) if (global_j == ny-1) NumNz[i] -= 1; // or even a 1 x 1 system } if (verbose) { cout << endl << "NumNz: "; for (int i = 0; i < NumMyElements; i++) cout << NumNz[i] << " "; cout << endl; } // end if // Create the Epetra Compressed Row Sparse matrix // Note: the actual values for the matrix entries are meaningless for // this exercise, but I assign them anyway. Epetra_CrsMatrix A(Copy, Map, NumNz); double * Values = new double[4]; for (int i = 0; i < 4; i++) Values[i] = -1.0; int * Indices = new int[4]; double diag = 2.0; if (ny > 1) diag = 4.0; int NumEntries; for (int i = 0; i < NumMyElements; i++) { global_j = MyGlobalElements[i] / nx; global_i = MyGlobalElements[i] - global_j * nx; NumEntries = 0; if (global_j > 0 && ny > 1) Indices[NumEntries++] = global_i + (global_j-1)*nx; if (global_i > 0) Indices[NumEntries++] = global_i-1 + global_j *nx; if (global_i < nx-1) Indices[NumEntries++] = global_i+1 + global_j *nx; if (global_j < ny-1 && ny > 1) Indices[NumEntries++] = global_i + (global_j+1)*nx; // Put in the off-diagonal terms assert(A.InsertGlobalValues(MyGlobalElements[i], NumEntries, Values, Indices) == 0); // Put in the diagonal entry assert(A.InsertGlobalValues(MyGlobalElements[i], 1, &diag, MyGlobalElements+i) == 0); } // end i loop // Finish up matrix construction delete [] Values; delete [] Indices; assert(A.FillComplete() == 0); // cout << endl << A << endl; // Create the local distance-1 adjancency graph // This is essentially a transpose of the Epetra_CrsGraph, where off- // processor couplings are ignored and global indexes are converted to // local. We use the C++ standard libraries vector and set, since we // don't know how many nonzeroes we will end up with for each column. vector< set<int> > adj1(NumMyElements); for (int lr = 0; lr < adj1.size(); lr++) { int lrid; // Local row ID double * Values = new double[NumNz[lr]]; int * Indices = new int[NumNz[lr]]; assert(A.ExtractMyRowCopy(lr, NumNz[lr], NumNz[lr], Values, Indices) == 0); for (int i = 0; i < NumNz[lr]; i++) { lrid = A.LRID(Indices[i]); if (lrid >= 0) adj1[lrid].insert(lr); } // end i loop delete [] Values; delete [] Indices; } // end lr loop if (verbose) { cout << endl; for (int lr = 0; lr < NumMyElements; lr++) { cout << "adj1[" << lr << "] = { "; for (set<int>::const_iterator p = adj1[lr].begin(); p != adj1[lr].end(); p++) cout << *p << " "; cout << "}" << endl; } // end lr loop } // end if // Create the local distance-2 adjancency graph // This is built from the distance-1 adjancency graph. We use the C++ // standard libraries vector and set, since we don't know how many // nonzeroes we will end up with for each column. vector< set<int> > adj2(NumMyElements); for (int lc = 0; lc < NumMyElements; lc++) { for (set<int>::const_iterator p = adj1[lc].begin(); p != adj1[lc].end(); p++) { int lrid; // Local row ID double * Values = new double[NumNz[*p]]; int * Indices = new int[NumNz[*p]]; assert(A.ExtractMyRowCopy(*p, NumNz[*p], NumNz[*p], Values, Indices) == 0); for (int i = 0; i < NumNz[*p]; i++) { lrid = A.LRID(Indices[i]); if (lrid >= 0) adj2[lc].insert(lrid); } // end i loop delete [] Values; delete [] Indices; } // end p loop } // end lc loop cout << endl; for (int lc = 0; lc < NumMyElements; lc++) { cout << "adj2[" << lc << "] = { "; for (set<int>::const_iterator p = adj2[lc].begin(); p != adj2[lc].end(); p++) cout << *p << " "; cout << "}" << endl; } // end lc loop // Now that we have the local distance-2 adjacency graph, we can compute a // color map using a greedy algorithm. The first step is to compute Delta, // the maximum size (degree) of adj1. size_t Delta = 0; for (int i = 0; i < NumMyElements; i++) Delta = max(Delta, adj1[i].size()); cout << endl << "Delta = " << Delta << endl << endl; // Now create a color map and initialize all values to 0, which // indicates that none of the columns have yet been colored. int * color_map = new int[NumMyElements]; for (int i = 0; i < NumMyElements; i++) color_map[i] = 0; // Apply the distance-2 greedy coloring algorithm for (int column = 0; column < NumMyElements; column++) { set<int> allowedColors; // Create the set of allowed colors for (int i = 1; i < Delta*Delta+1; i++) allowedColors.insert(i); for (set<int>::const_iterator p = adj2[column].begin(); p != adj2[column].end(); p++) if (color_map[*p] > 0) allowedColors.erase(color_map[*p]); color_map[column] = *(allowedColors.begin()); cout << "color_map[" << column << "] = " << color_map[column] << endl; } // end col loop // New section to Epetra_MapColoring Epetra_MapColoring C1(Map, color_map); cout << C1; // Clean up delete [] MyGlobalElements; delete [] NumNz; delete [] color_map; cout << endl << argv[0] << " done." << endl; } // end main
int main( int argc, char **argv ) { // check for parallel computation #ifdef HAVE_MPI MPI_Init(&argc, &argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif // define main parameters double c = 0.9999; // continuation parameter int N = 50; // number of grid points int maxNewtonIters = 20; // max number of Newton iterations int maxSteps = 50; // max number of continuation steps taken int ilocal, iglobal; // counter variables used for loops: // ilocal = counter for local elements on this processor; // iglobal = counter to signify global position across all procs int Myele; // holds the number of elements on the processor // Set flag for whether the computations will be Matrix-free (true) or will use a computed // Jacobian (false) bool doMatFree = false; // Create output file to save solutions ofstream outFile("Heq5.dat"); outFile.setf(ios::scientific, ios::floatfield); outFile.precision(10); // Define the problem class HeqProblem Problem(N,&Comm,outFile); // Build initial guess. The initial guess should be a solution vector x close to the // bifurcation point. // Create the initial guess vector Epetra_Vector InitialGuess(Problem.GetMap()); // Get the number of elements on this processor Myele = Problem.GetMap().NumMyElements(); // Compute the initial guess. For this example, it is a line from (0,1) to (1,8/3) for (ilocal=0; ilocal<Myele; ilocal++) { iglobal=Problem.GetMap().GID(ilocal); InitialGuess[ilocal]= 1.0 + (5.0*iglobal)/(3.0*(N-1)); } // Create the null vector for the Jacobian (ie, J*v=0, used to solve the system of equations // f(x,p)=0; J*v=0; v0*v=1. The solution of the system is [x*,v*,p*]. ) Teuchos::RCP<NOX::Abstract::Vector> nullVec = Teuchos::rcp(new NOX::Epetra::Vector(InitialGuess)); // Initialize to all ones nullVec->init(1.0); // NOTE: init is a function within the NOX::Abstract:Vector class which initializes every // value of the vector to the value within the parentheses (must be in 'double' format) // Create the top level parameter list Teuchos::RCP<Teuchos::ParameterList> ParamList = Teuchos::rcp(new Teuchos::ParameterList); // Create LOCA sublist Teuchos::ParameterList& locaParamsList = ParamList->sublist("LOCA"); // Create the sublist for continuation and set the stepper parameters Teuchos::ParameterList& stepperList = locaParamsList.sublist("Stepper"); //stepperList.set("Continuation Method", "Arc Length");// Default stepperList.set("Continuation Method", "Natural"); stepperList.set("Continuation Parameter", "dummy"); // Must set stepperList.set("Initial Value", 999.0); // Must set stepperList.set("Max Value", 50.0e4); // Must set stepperList.set("Min Value", 0.0); // Must set stepperList.set("Max Steps", maxSteps); // Should set stepperList.set("Max Nonlinear Iterations", maxNewtonIters); // Should set stepperList.set("Bordered Solver Method", "Bordering"); // Teuchos::ParameterList& nestedList = // stepperList.sublist("Nested Bordered Solver"); // nestedList.set("Bordered Solver Method", "Householder"); // nestedList.set("Include UV In Preconditioner", true); // //nestedList.set("Use P For Preconditioner", true); // nestedList.set("Preconditioner Method", "SMW"); // Set up parameters to compute Eigenvalues #ifdef HAVE_LOCA_ANASAZI // Create Anasazi Eigensolver sublist (needs --with-loca-anasazi) stepperList.set("Compute Eigenvalues",true); Teuchos::ParameterList& aList = stepperList.sublist("Eigensolver"); aList.set("Method", "Anasazi"); aList.set("Block Size", 1); // Size of blocks aList.set("Num Blocks", 20); // Size of Arnoldi factorization aList.set("Num Eigenvalues", 5); // Number of eigenvalues // aList.set("Sorting Order", "SR"); aList.set("Convergence Tolerance", 2.0e-7); // Tolerance aList.set("Step Size", 1); // How often to check convergence aList.set("Maximum Restarts",2); // Maximum number of restarts aList.set("Verbosity", Anasazi::Errors + Anasazi::Warnings + Anasazi::FinalSummary); // Verbosity #else stepperList.set("Compute Eigenvalues",false); #endif // Create bifurcation sublist. Note that for turning point continuation, the "type" // is set to "Turning Point". If not doing TP, type should be "None". Teuchos::ParameterList& bifurcationList = locaParamsList.sublist("Bifurcation"); bifurcationList.set("Type", "Turning Point"); bifurcationList.set("Bifurcation Parameter", "c"); // bifurcationList.set("Formulation", "Minimally Augmented"); bifurcationList.set("Symmetric Jacobian", false); bifurcationList.set("Update Null Vectors Every Continuation Step", true); bifurcationList.set("Update Null Vectors Every Nonlinear Iteration", false); bifurcationList.set("Transpose Solver Method","Explicit Transpose"); // bifurcationList.set("Transpose Solver Method","Transpose Preconditioner"); // bifurcationList.set("Transpose Solver Method","Left Preconditioning"); bifurcationList.set("Initial Null Vector Computation", "Solve df/dp"); // bifurcationList.set("Initial A Vector", nullVec); // minimally augmented // bifurcationList.set("Initial B Vector", nullVec); //minimally augmented // bifurcationList.set("Bordered Solver Method", "Householder"); // bifurcationList.set("Include UV In Preconditioner", true); // //bifurcationList.set("Use P For Preconditioner", true); // bifurcationList.set("Preconditioner Method", "SMW"); bifurcationList.set("Formulation", "Moore-Spence"); bifurcationList.set("Solver Method", "Phipps Bordering"); // better for nearly singular matrices // bifurcationList.set("Solver Method", "Salinger Bordering"); bifurcationList.set("Initial Null Vector", nullVec); bifurcationList.set("Length Normalization Vector", nullVec); // Create the sublist for the predictor Teuchos::ParameterList& predictorList = locaParamsList.sublist("Predictor"); predictorList.set("Method", "Secant"); // Default // predictorList.set("Method", "Constant"); // Other options // predictorList.set("Method", "Tangent"); // Other options // Create step size sublist Teuchos::ParameterList& stepSizeList = locaParamsList.sublist("Step Size"); stepSizeList.set("Method", "Adaptive"); // Default stepSizeList.set("Initial Step Size", 0.1); // Should set stepSizeList.set("Min Step Size", 1.0e-6); // Should set stepSizeList.set("Max Step Size", 1.0); // Should set stepSizeList.set("Aggressiveness", 0.1); // Set up NOX info Teuchos::ParameterList& nlParams = ParamList->sublist("NOX"); // Set the nonlinear solver method nlParams.set("Nonlinear Solver", "Line Search Based"); // Set the printing parameters in the "Printing" sublist. This list determines how much // of the NOX information is output Teuchos::ParameterList& printParams = nlParams.sublist("Printing"); printParams.set("MyPID", Comm.MyPID()); printParams.set("Output Precision", 5); printParams.set("Output Processor", 0); printParams.set("Output Information", NOX::Utils::OuterIteration + NOX::Utils::OuterIterationStatusTest + NOX::Utils::InnerIteration + NOX::Utils::LinearSolverDetails + NOX::Utils::Parameters + NOX::Utils::Details + NOX::Utils::Warning + NOX::Utils::StepperIteration + NOX::Utils::StepperDetails + NOX::Utils::StepperParameters); // NOX parameters - Sublist for line search Teuchos::ParameterList& searchParams = nlParams.sublist("Line Search"); searchParams.set("Method", "Backtrack"); // searchParams.set("Method", "Full Step"); // Sublist for direction Teuchos::ParameterList& dirParams = nlParams.sublist("Direction"); dirParams.set("Method", "Newton"); Teuchos::ParameterList& newtonParams = dirParams.sublist("Newton"); newtonParams.set("Forcing Term Method", "Constant"); // Sublist for linear solver for the Newton method Teuchos::ParameterList& lsParams = newtonParams.sublist("Linear Solver"); lsParams.set("Aztec Solver", "GMRES"); lsParams.set("Max Iterations", 800); lsParams.set("Tolerance", 1e-8); lsParams.set("Output Frequency", 1); lsParams.set("Preconditioner", "None"); // lsParams.set("Preconditioner", "AztecOO"); // lsParams.set("Aztec Preconditioner", "ilu"); // lsParams.set("Scaling", "None"); // lsParams.set("Scaling", "Row Sum"); lsParams.set("Compute Scaling Manually", false); // lsParams.set("Preconditioner", "Ifpack"); // lsParams.set("Ifpack Preconditioner", "ILU"); // lsParams.set("Preconditioner", "New Ifpack"); // Teuchos::ParameterList& ifpackParams = lsParams.sublist("Ifpack"); // ifpackParams.set("fact: level-of-fill", 1); // Set up the continuation parameter vector LOCA::ParameterVector p; p.addParameter("c",c); p.addParameter("dummy",999.0); // Create the problem interface Teuchos::RCP<SimpleProblemInterface> interface = Teuchos::rcp(new SimpleProblemInterface(&Problem,c) ); Teuchos::RCP<LOCA::Epetra::Interface::Required> iReq = interface; // Create the operator to hold either the Jacobian matrix or the Matrix-free operator Teuchos::RCP<Epetra_Operator> A; // Teuchos::RCP<Epetra_RowMatrix> A; Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac; // Need a NOX::Epetra::Vector for constructor // This becomes the initial guess vector that is used for the nonlinear solves NOX::Epetra::Vector noxInitGuess(InitialGuess, NOX::DeepCopy); if (doMatFree) { // Matrix Free application (Epetra Operator): Teuchos::RCP<NOX::Epetra::MatrixFree> MF = Teuchos::rcp(new NOX::Epetra::MatrixFree(printParams, interface, noxInitGuess)); A = MF; iJac = MF; } else { // Computed Jacobian application A = Teuchos::rcp( Problem.GetMatrix(), false ); iJac = interface; } // Create scaling object Teuchos::RCP<NOX::Epetra::Scaling> scaling = Teuchos::null; // scaling = Teuchos::rcp(new NOX::Epetra::Scaling); // Teuchos::RCP<Epetra_Vector> scalingVector = // Teuchos::rcp(new Epetra_Vector(soln.Map())); // //scaling->addRowSumScaling(NOX::Epetra::Scaling::Left, scalingVector); // scaling->addColSumScaling(NOX::Epetra::Scaling::Right, scalingVector); // Create transpose scaling object Teuchos::RCP<NOX::Epetra::Scaling> trans_scaling = Teuchos::null; // trans_scaling = Teuchos::rcp(new NOX::Epetra::Scaling); // Teuchos::RCP<Epetra_Vector> transScalingVector = // Teuchos::rcp(new Epetra_Vector(soln.Map())); // trans_scaling->addRowSumScaling(NOX::Epetra::Scaling::Right, // transScalingVector); // trans_scaling->addColSumScaling(NOX::Epetra::Scaling::Left, // transScalingVector); //bifurcationList.set("Transpose Scaling", trans_scaling); // Build the linear system solver Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linSys = Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams, iReq, iJac, A, noxInitGuess, scaling)); // use if scaling // noxInitGuess)); // use if no scaling // Create the Loca (continuation) vector NOX::Epetra::Vector locaSoln(noxInitGuess); // Create Epetra Factory Teuchos::RCP<LOCA::Abstract::Factory> epetraFactory = Teuchos::rcp(new LOCA::Epetra::Factory); // Create global data object Teuchos::RCP<LOCA::GlobalData> globalData = LOCA::createGlobalData(ParamList, epetraFactory); // Create the Group - must be LOCA group Teuchos::RCP<LOCA::Epetra::Group> grpPtr = Teuchos::rcp(new LOCA::Epetra::Group(globalData, printParams, iReq, locaSoln, linSys, p)); // Calculate the first F(x0) as a starting point. This is only needed for // certain status tests, to ensure that an initial residual (|r0|) is calculated grpPtr->computeF(); // Set up the status tests to check for convergence // Determines the error tolerance for the Newton solves Teuchos::RCP<NOX::StatusTest::NormF> testNormF = Teuchos::rcp(new NOX::StatusTest::NormF(1.0e-4)); // Sets the max number of nonlinear (Newton) iterations that will be taken. If this is not // already set, it will default to the '20' given Teuchos::RCP<NOX::StatusTest::MaxIters> testMaxIters = Teuchos::rcp(new NOX::StatusTest::MaxIters(stepperList.get("Max Nonlinear Iterations", 20))); // This combination of tests will be used by NOX to determine whether the step converged Teuchos::RCP<NOX::StatusTest::Combo> combo = Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR, testNormF, testMaxIters)); // This is sample code to write and read parameters to/from a file. Currently not activated! // To use, change the 'XXXHAVE_TEUCHOS_EXTENDED' TO 'HAVE_TEUCHOS_EXTENDED' #ifdef XXXHAVE_TEUCHOS_EXTENDED // Write the parameter list to a file cout << "Writing parameter list to \"input.xml\"" << endl; Teuchos::writeParameterListToXmlFile(*ParamList, "input.xml"); // Read in the parameter list from a file cout << "Reading parameter list from \"input.xml\"" << endl; Teuchos::RCP<Teuchos::ParameterList> paramList2 = Teuchos::rcp(new Teuchos::ParameterList); Teuchos::updateParametersFromXmlFile("input.xml", paramList2.get()); ParamList = paramList2; #endif // Create the stepper LOCA::Stepper stepper(globalData, grpPtr, combo, ParamList); LOCA::Abstract::Iterator::IteratorStatus status = stepper.run(); // Check if the stepper completed if (status == LOCA::Abstract::Iterator::Finished) globalData->locaUtils->out() << "\nAll tests passed!" << endl; else if (globalData->locaUtils->isPrintType(NOX::Utils::Error)) globalData->locaUtils->out() << "\nStepper failed to converge!" << endl; // Output the stepper parameter list info if (globalData->locaUtils->isPrintType(NOX::Utils::StepperParameters)) { globalData->locaUtils->out() << endl << "Final Parameters" << endl << "*******************" << endl; stepper.getList()->print(globalData->locaUtils->out()); globalData->locaUtils->out() << endl; } // Make sure all processors are done and close the output file Comm.Barrier(); outFile.close(); // Deallocate memory LOCA::destroyGlobalData(globalData); #ifdef HAVE_MPI MPI_Finalize(); #endif return(EXIT_SUCCESS); } // DONE!!
int main(int argc, char *argv[]) { int returnierr=0; using std::cout; using std::endl; using std::flush; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); int size; // Number of MPI processes, My process ID MPI_Comm_size(MPI_COMM_WORLD, &size); if (size > 1) { cout << "This example cannot be run on more than one processor!" << endl; MPI_Finalize(); returnierr = -1; return returnierr; } #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; #ifdef EPETRA_MPI Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif if (!verbose) Comm.SetTracebackMode(0); // This should shut down any error traceback reporting if (verbose) { cout << EpetraExt::EpetraExt_Version() << endl << endl; cout << Comm << endl << flush; } Comm.Barrier(); int NumMyElements = 3; Epetra_Map Map( NumMyElements, 0, Comm ); Epetra_CrsGraph Graph( Copy, Map, 1 ); int index[2]; index[0] = 2; Graph.InsertGlobalIndices( 0, 1, &index[0] ); index[0] = 0; index[1] = 2; Graph.InsertGlobalIndices( 1, 2, &index[0] ); index[0] = 1; Graph.InsertGlobalIndices( 2, 1, &index[0] ); Graph.FillComplete(); if (verbose) { cout << "***************** PERFORMING BTF TRANSFORM ON CRS_GRAPH *****************" <<endl<<endl; cout << "CrsGraph *before* BTF transform: " << endl << endl; cout << Graph << endl; } EpetraExt::AmesosBTF_CrsGraph BTFTrans( true, verbose ); Epetra_CrsGraph & NewBTFGraph = BTFTrans( Graph ); if (verbose) { cout << "CrsGraph *after* BTF transform: " << endl << endl; cout << NewBTFGraph << endl; } // Use BTF graph transformation to solve linear system. // Create an Epetra::CrsMatrix Epetra_CrsMatrix Matrix( Copy, Graph ); double value[2]; index[0] = 2; value[0] = 3.0; Matrix.ReplaceMyValues( 0, 1, &value[0], &index[0] ); index[0] = 0; index[1] = 2; value[0] = 2.0; value[1] = 2.5; Matrix.ReplaceMyValues( 1, 2, &value[0], &index[0] ); index[0] = 1; value[0] = 1.0; Matrix.ReplaceMyValues( 2, 1, &value[0], &index[0] ); Matrix.FillComplete(); // Create the solution and right-hand side vectors. Epetra_MultiVector RHS( Map, 1 ), LHS( Map, 1 ); LHS.PutScalar( 0.0 ); RHS.ReplaceMyValue( 0, 0, 3.0 ); RHS.ReplaceMyValue( 1, 0, 4.5 ); RHS.ReplaceMyValue( 2, 0, 1.0 ); Epetra_LinearProblem problem( &Matrix, &LHS, &RHS ); if (verbose) { cout << "*************** PERFORMING BTF TRANSFORM ON LINEAR_PROBLEM **************" <<endl<<endl; cout << "CrsMatrix *before* BTF transform: " << endl << endl; cout << Matrix << endl; cout << "MultiVector RHS *before* BTF transform: " << endl << endl; RHS.Print( cout ); } // Create the linear problem transform. EpetraExt::LinearProblem_GraphTrans * LPTrans = new EpetraExt::LinearProblem_GraphTrans( *(dynamic_cast<EpetraExt::StructuralSameTypeTransform<Epetra_CrsGraph>*>(&BTFTrans)) ); Epetra_LinearProblem* tProblem = &((*LPTrans)( problem )); LPTrans->fwd(); if (verbose) { cout << "CrsMatrix *after* BTF transform: " << endl << endl; dynamic_cast<Epetra_CrsMatrix*>(tProblem->GetMatrix())->Print( cout ); cout << "MultiVector RHS *after* BTF transform: " << endl << endl; tProblem->GetRHS()->Print( cout ); } if (verbose) { cout << endl << "*************** PERFORMING REINDEXING ON LINEAR_PROBLEM **************" <<endl<<endl; } EpetraExt::ViewTransform<Epetra_LinearProblem> * ReIdx_LPTrans = new EpetraExt::LinearProblem_Reindex( 0 ); Epetra_LinearProblem* tProblem2 = &((*ReIdx_LPTrans)( *tProblem )); ReIdx_LPTrans->fwd(); if (verbose) { cout << endl << "CrsMatrix *after* BTF transform *and* reindexing: " << endl << endl; dynamic_cast<Epetra_CrsMatrix*>(tProblem2->GetMatrix())->Print( cout ); cout << endl <<"Column Map *before* reindexing: " << endl << endl; cout << dynamic_cast<Epetra_CrsMatrix*>(tProblem->GetMatrix())->ColMap() << endl; cout << "Column Map *after* reindexing: " << endl << endl; cout << dynamic_cast<Epetra_CrsMatrix*>(tProblem2->GetMatrix())->ColMap() << endl; } #ifdef EPETRA_MPI MPI_Finalize(); #endif return returnierr; }
int main( int argc, char **argv ) { // check for parallel computation #ifdef HAVE_MPI MPI_Init(&argc, &argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif // define main parameters double c = 0.25; // continuation parameter int N = 50; // number of grid points int maxNewtonIters = 20; // max number of Newton iterations int maxSteps = 75; // max number of continuation steps taken // Set flag for whether the computations will be Matrix-free (true) or will use a computed // Jacobian (false) bool doMatFree = false; // Create output file to save solutions ofstream outFile("Heq4.dat"); outFile.setf(ios::scientific, ios::floatfield); outFile.precision(10); // Define the problem class HeqProblem Problem(N,&Comm,outFile); // Create the initial guess vector and set it to all ones Epetra_Vector InitialGuess(Problem.GetMap()); InitialGuess.PutScalar(1.0); // Create the top level parameter list Teuchos::RCP<Teuchos::ParameterList> ParamList = Teuchos::rcp(new Teuchos::ParameterList); // Create LOCA sublist Teuchos::ParameterList& locaParamsList = ParamList->sublist("LOCA"); // Create the sublist for continuation and set the stepper parameters Teuchos::ParameterList& stepperList = locaParamsList.sublist("Stepper"); stepperList.set("Continuation Method", "Arc Length");// Default // stepperList.set("Continuation Method", "Natural"); stepperList.set("Continuation Parameter", "c"); // Must set stepperList.set("Initial Value", c); // Must set stepperList.set("Max Value", 100.0); // Must set stepperList.set("Min Value", 0.0); // Must set stepperList.set("Max Steps", maxSteps); // Should set stepperList.set("Max Nonlinear Iterations", maxNewtonIters); // Should set // Set up parameters to compute Eigenvalues #ifdef HAVE_LOCA_ANASAZI // Create Anasazi Eigensolver sublist (needs --with-loca-anasazi) stepperList.set("Compute Eigenvalues",true); Teuchos::ParameterList& aList = stepperList.sublist("Eigensolver"); aList.set("Method", "Anasazi"); aList.set("Block Size", 1); // Size of blocks aList.set("Num Blocks", 20); // Size of Arnoldi factorization aList.set("Num Eigenvalues", 5); // Number of eigenvalues // aList.set("Sorting Order", "SR"); aList.set("Convergence Tolerance", 2.0e-7); // Tolerance aList.set("Step Size", 1); // How often to check convergence aList.set("Maximum Restarts",2); // Maximum number of restarts aList.set("Verbosity", Anasazi::Errors + Anasazi::Warnings + Anasazi::FinalSummary); // Verbosity #else stepperList.set("Compute Eigenvalues",false); #endif stepperList.set("Bordered Solver Method", "Householder"); // stepperList.set("Bordered Solver Method", "Bordering"); // Teuchos::ParameterList& nestedList = // stepperList.sublist("Nested Bordered Solver"); // nestedList.set("Bordered Solver Method", "Householder"); // nestedList.set("Include UV In Preconditioner", true); // //nestedList.set("Use P For Preconditioner", true); // nestedList.set("Preconditioner Method", "SMW"); // Create bifurcation sublist -- use if not doing turning point Teuchos::ParameterList& bifurcationList = locaParamsList.sublist("Bifurcation"); bifurcationList.set("Type", "None"); // Default // Create predictor sublist Teuchos::ParameterList& predictorList = locaParamsList.sublist("Predictor"); predictorList.set("Method", "Secant"); // Default // predictorList.set("Method", "Constant"); // Other options // predictorList.set("Method", "Tangent"); // Other options // Create step size sublist Teuchos::ParameterList& stepSizeList = locaParamsList.sublist("Step Size"); stepSizeList.set("Method", "Adaptive"); // Default stepSizeList.set("Initial Step Size", 0.1); // Should set stepSizeList.set("Min Step Size", 1.0e-4); // Should set stepSizeList.set("Max Step Size", 1.0); // Should set stepSizeList.set("Aggressiveness", 0.1); // Set up NOX info Teuchos::ParameterList& nlParams = ParamList->sublist("NOX"); // Set the nonlinear solver method nlParams.set("Nonlinear Solver", "Line Search Based"); // Set the printing parameters in the "Printing" sublist Teuchos::ParameterList& printParams = nlParams.sublist("Printing"); printParams.set("MyPID", Comm.MyPID()); printParams.set("Output Precision", 5); printParams.set("Output Processor", 0); printParams.set("Output Information", NOX::Utils::OuterIteration + NOX::Utils::OuterIterationStatusTest + NOX::Utils::InnerIteration + NOX::Utils::LinearSolverDetails + NOX::Utils::Parameters + NOX::Utils::Details + NOX::Utils::Warning + NOX::Utils::StepperIteration + NOX::Utils::StepperDetails + NOX::Utils::StepperParameters); // NOX parameters - Sublist for line search Teuchos::ParameterList& searchParams = nlParams.sublist("Line Search"); searchParams.set("Method", "Full Step"); // searchParams.set("Method", "Backtrack"); // Sublist for direction Teuchos::ParameterList& dirParams = nlParams.sublist("Direction"); dirParams.set("Method", "Newton"); Teuchos::ParameterList& newtonParams = dirParams.sublist("Newton"); newtonParams.set("Forcing Term Method", "Constant"); // Sublist for linear solver for the Newton method Teuchos::ParameterList& lsParams = newtonParams.sublist("Linear Solver"); lsParams.set("Aztec Solver", "GMRES"); lsParams.set("Max Iterations", 800); lsParams.set("Tolerance", 1e-8); lsParams.set("Output Frequency", 1); lsParams.set("Preconditioner", "None"); // lsParams.set("Preconditioner", "AztecOO"); // lsParams.set("Aztec Preconditioner", "ilu"); // lsParams.set("Preconditioner", "Ifpack"); // lsParams.set("Ifpack Preconditioner", "ILU"); // lsParams.set("Preconditioner", "New Ifpack"); // Teuchos::ParameterList& ifpackParams = lsParams.sublist("Ifpack"); // ifpackParams.set("fact: level-of-fill", 1); // set up the continuation parameter vector LOCA::ParameterVector p; p.addParameter("c",c); // Set up the problem interface Teuchos::RCP<SimpleProblemInterface> interface = Teuchos::rcp(new SimpleProblemInterface(&Problem,c) ); Teuchos::RCP<LOCA::Epetra::Interface::Required> iReq = interface; // Create the operator to hold either the Jacobian matrix or the Matrix-free operator Teuchos::RCP<Epetra_Operator> A; Teuchos::RCP<NOX::Epetra::Interface::Jacobian> iJac; // Need a NOX::Epetra::Vector for constructor // This becomes the initial guess vector that is used for the nonlinear solves NOX::Epetra::Vector noxInitGuess(InitialGuess, NOX::DeepCopy); if (doMatFree) { // Matrix Free application (Epetra Operator): Teuchos::RCP<NOX::Epetra::MatrixFree> MF = Teuchos::rcp(new NOX::Epetra::MatrixFree(printParams, interface, noxInitGuess)); A = MF; iJac = MF; } else { // Computed Jacobian application A = Teuchos::rcp( Problem.GetMatrix(), false ); iJac = interface; } // Build the linear system solver Teuchos::RCP<NOX::Epetra::LinearSystemAztecOO> linSys = Teuchos::rcp(new NOX::Epetra::LinearSystemAztecOO(printParams, lsParams, iReq, iJac, A, noxInitGuess)); // Create the Loca (continuation) vector NOX::Epetra::Vector locaSoln(noxInitGuess); // Create Epetra Factory Teuchos::RCP<LOCA::Abstract::Factory> epetraFactory = Teuchos::rcp(new LOCA::Epetra::Factory); // Create global data object Teuchos::RCP<LOCA::GlobalData> globalData = LOCA::createGlobalData(ParamList, epetraFactory); // Create the Group - must be LOCA group Teuchos::RCP<LOCA::Epetra::Group> grpPtr = Teuchos::rcp(new LOCA::Epetra::Group(globalData, printParams, iReq, locaSoln, linSys, p)); // Calculate the first F(x0) as a starting point. This is only needed for // certain status tests, to ensure that an initial residual (|r0|) is calculated grpPtr->computeF(); // Set up the status tests to check for convergence // Determines the error tolerance for the Newton solves Teuchos::RCP<NOX::StatusTest::NormF> testNormF = Teuchos::rcp(new NOX::StatusTest::NormF(1.0e-4)); // Sets the max number of nonlinear (Newton) iterations that will be taken. If this is not // already set, it will default to the '20' given Teuchos::RCP<NOX::StatusTest::MaxIters> testMaxIters = Teuchos::rcp(new NOX::StatusTest::MaxIters(stepperList.get("Max Nonlinear Iterations", 20))); // This combination of tests will be used by NOX to determine whether the step converged Teuchos::RCP<NOX::StatusTest::Combo> combo = Teuchos::rcp(new NOX::StatusTest::Combo(NOX::StatusTest::Combo::OR, testNormF, testMaxIters)); // This is sample code to write and read parameters to/from a file. Currently not activated! // To use, change the 'XXXHAVE_TEUCHOS_EXTENDED' TO 'HAVE_TEUCHOS_EXTENDED' #ifdef XXXHAVE_TEUCHOS_EXTENDED // Write the parameter list to a file cout << "Writing parameter list to \"input.xml\"" << endl; Teuchos::writeParameterListToXmlFile(*ParamList, "input.xml"); // Read in the parameter list from a file cout << "Reading parameter list from \"input.xml\"" << endl; Teuchos::RCP<Teuchos::ParameterList> paramList2 = Teuchos::rcp(new Teuchos::ParameterList); Teuchos::updateParametersFromXmlFile("input.xml", paramList2.get()); ParamList = paramList2; #endif // Create the stepper LOCA::Stepper stepper(globalData, grpPtr, combo, ParamList); LOCA::Abstract::Iterator::IteratorStatus status = stepper.run(); // Check if the stepper completed if (status == LOCA::Abstract::Iterator::Finished) globalData->locaUtils->out() << "\nAll tests passed!" << endl; else if (globalData->locaUtils->isPrintType(NOX::Utils::Error)) globalData->locaUtils->out() << "\nStepper failed to converge!" << endl; // Output the stepper parameter list info if (globalData->locaUtils->isPrintType(NOX::Utils::StepperParameters)) { globalData->locaUtils->out() << endl << "Final Parameters" << endl << "*******************" << endl; stepper.getList()->print(globalData->locaUtils->out()); globalData->locaUtils->out() << endl; } // Make sure all processors are done and close the output file Comm.Barrier(); outFile.close(); // Deallocate memory LOCA::destroyGlobalData(globalData); #ifdef HAVE_MPI MPI_Finalize(); #endif return(EXIT_SUCCESS); } // DONE!!
int main(int argc, char *argv[]) { // Initialize MPI #ifdef HAVE_MPI MPI_Init(&argc,&argv); #endif // Create a communicator for Epetra objects #ifdef HAVE_MPI Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else Epetra_SerialComm Comm; #endif bool verbose = false; if (argc > 1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; // Get the process ID and the total number of processors int MyPID = Comm.MyPID(); #ifdef HAVE_MPI int NumProc = Comm.NumProc(); #endif // Set up the printing utilities Teuchos::RCP<Teuchos::ParameterList> noxParamsPtr = Teuchos::rcp(new Teuchos::ParameterList); Teuchos::ParameterList& noxParams = *(noxParamsPtr.get()); // Only print output if the "-v" flag is set on the command line Teuchos::ParameterList& printParams = noxParams.sublist("Printing"); printParams.set("MyPID", MyPID); printParams.set("Output Precision", 5); printParams.set("Output Processor", 0); if( verbose ) printParams.set("Output Information", NOX::Utils::OuterIteration + NOX::Utils::OuterIterationStatusTest + NOX::Utils::InnerIteration + NOX::Utils::Parameters + NOX::Utils::Details + NOX::Utils::Warning + NOX::Utils::TestDetails); else printParams.set("Output Information", NOX::Utils::Error + NOX::Utils::TestDetails); NOX::Utils printing(printParams); // Identify the test problem if (printing.isPrintType(NOX::Utils::TestDetails)) printing.out() << "Starting epetra/NOX_NewTest/NOX_NewTest.exe" << endl; // Identify processor information #ifdef HAVE_MPI if (printing.isPrintType(NOX::Utils::TestDetails)) { printing.out() << "Parallel Run" << endl; printing.out() << "Number of processors = " << NumProc << endl; printing.out() << "Print Process = " << MyPID << endl; } Comm.Barrier(); if (printing.isPrintType(NOX::Utils::TestDetails)) printing.out() << "Process " << MyPID << " is alive!" << endl; Comm.Barrier(); #else if (printing.isPrintType(NOX::Utils::TestDetails)) printing.out() << "Serial Run" << endl; #endif // *** Insert your testing here! *** // Final return value (0 = successfull, non-zero = failure) int status = 0; // Summarize test results if (status == 0) printing.out() << "Test passed!" << endl; else printing.out() << "Test failed!" << endl; #ifdef HAVE_MPI MPI_Finalize(); #endif // Final return value (0 = successfull, non-zero = failure) return status; }
int main(int argc, char *argv[]) { // Initialize MPI #ifdef HAVE_MPI MPI_Init(&argc,&argv); #endif // Create a communicator for Epetra objects #ifdef HAVE_MPI Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else Epetra_SerialComm Comm; #endif int * testInt = new int[100]; delete [] testInt; bool verbose = false; if (argc > 1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; // Get the process ID and the total number of processors int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); // Set up theolver options parameter list Teuchos::RCP<Teuchos::ParameterList> noxParamsPtr = Teuchos::rcp(new Teuchos::ParameterList); Teuchos::ParameterList & noxParams = *(noxParamsPtr.get()); // Set up the printing utilities // Only print output if the "-v" flag is set on the command line Teuchos::ParameterList& printParams = noxParams.sublist("Printing"); printParams.set("MyPID", MyPID); printParams.set("Output Precision", 5); printParams.set("Output Processor", 0); if( verbose ) printParams.set("Output Information", NOX::Utils::OuterIteration + NOX::Utils::OuterIterationStatusTest + NOX::Utils::InnerIteration + NOX::Utils::Parameters + NOX::Utils::Details + NOX::Utils::Warning + NOX::Utils::TestDetails); else printParams.set("Output Information", NOX::Utils::Error + NOX::Utils::TestDetails); Teuchos::RCP<NOX::Utils> printing = Teuchos::rcp( new NOX::Utils(printParams) ); // Identify the test problem if (printing->isPrintType(NOX::Utils::TestDetails)) printing->out() << "Starting epetra/NOX_Operators/NOX_BroydenOp.exe" << std::endl; // Identify processor information #ifdef HAVE_MPI if (printing->isPrintType(NOX::Utils::TestDetails)) { printing->out() << "Parallel Run" << std::endl; printing->out() << "Number of processors = " << NumProc << std::endl; printing->out() << "Print Process = " << MyPID << std::endl; } Comm.Barrier(); if (printing->isPrintType(NOX::Utils::TestDetails)) printing->out() << "Process " << MyPID << " is alive!" << std::endl; Comm.Barrier(); #else if (printing->isPrintType(NOX::Utils::TestDetails)) printing->out() << "Serial Run" << std::endl; #endif int status = 0; // Create a TestCompare class NOX::Epetra::TestCompare tester( printing->out(), *printing); double abstol = 1.e-4; double reltol = 1.e-4 ; // Test NOX::Epetra::BroydenOperator int numGlobalElems = 3 * NumProc; Epetra_Map broydenRowMap ( numGlobalElems, 0, Comm ); Epetra_Vector broydenWorkVec ( broydenRowMap ); Epetra_CrsGraph broydenWorkGraph( Copy, broydenRowMap, 0 ); std::vector<int> globalIndices(3); for( int lcol = 0; lcol < 3; ++lcol ) globalIndices[lcol] = 3 * MyPID + lcol; std::vector<int> myGlobalIndices(2); // Row 1 structure myGlobalIndices[0] = globalIndices[0]; myGlobalIndices[1] = globalIndices[2]; broydenWorkGraph.InsertGlobalIndices( globalIndices[0], 2, &myGlobalIndices[0] ); // Row 2 structure myGlobalIndices[0] = globalIndices[0]; myGlobalIndices[1] = globalIndices[1]; broydenWorkGraph.InsertGlobalIndices( globalIndices[1], 2, &myGlobalIndices[0] ); // Row 3 structure myGlobalIndices[0] = globalIndices[1]; myGlobalIndices[1] = globalIndices[2]; broydenWorkGraph.InsertGlobalIndices( globalIndices[2], 2, &myGlobalIndices[0] ); broydenWorkGraph.FillComplete(); Teuchos::RCP<Epetra_CrsMatrix> broydenWorkMatrix = Teuchos::rcp( new Epetra_CrsMatrix( Copy, broydenWorkGraph ) ); // Create an identity matrix broydenWorkVec.PutScalar(1.0); broydenWorkMatrix->ReplaceDiagonalValues(broydenWorkVec); NOX::Epetra::BroydenOperator broydenOp( noxParams, printing, broydenWorkVec, broydenWorkMatrix, true ); broydenWorkVec[0] = 1.0; broydenWorkVec[1] = -1.0; broydenWorkVec[2] = 2.0; broydenOp.setStepVector( broydenWorkVec ); broydenWorkVec[0] = 2.0; broydenWorkVec[1] = 1.0; broydenWorkVec[2] = 3.0; broydenOp.setYieldVector( broydenWorkVec ); broydenOp.computeSparseBroydenUpdate(); // Create the gold matrix for comparison Teuchos::RCP<Epetra_CrsMatrix> goldMatrix = Teuchos::rcp( new Epetra_CrsMatrix( Copy, broydenWorkGraph ) ); int numCols ; double * values ; // Row 1 answers goldMatrix->ExtractMyRowView( 0, numCols, values ); values[0] = 6.0 ; values[1] = 2.0 ; // Row 2 answers goldMatrix->ExtractMyRowView( 1, numCols, values ); values[0] = 5.0 ; values[1] = 0.0 ; // Row 3 structure goldMatrix->ExtractMyRowView( 2, numCols, values ); values[0] = -1.0 ; values[1] = 7.0 ; goldMatrix->Scale(0.2); status += tester.testCrsMatrices( broydenOp.getBroydenMatrix(), *goldMatrix, reltol, abstol, "Broyden Sparse Operator Update Test" ); // Now try a dense Broyden Update Epetra_CrsGraph broydenWorkGraph2( Copy, broydenRowMap, 0 ); myGlobalIndices.resize(3); // All Rowsstructure myGlobalIndices[0] = globalIndices[0]; myGlobalIndices[1] = globalIndices[1]; myGlobalIndices[2] = globalIndices[2]; broydenWorkGraph2.InsertGlobalIndices( globalIndices[0], 3, &myGlobalIndices[0] ); broydenWorkGraph2.InsertGlobalIndices( globalIndices[1], 3, &myGlobalIndices[0] ); broydenWorkGraph2.InsertGlobalIndices( globalIndices[2], 3, &myGlobalIndices[0] ); broydenWorkGraph2.FillComplete(); Teuchos::RCP<Epetra_CrsMatrix> broydenWorkMatrix2 = Teuchos::rcp( new Epetra_CrsMatrix( Copy, broydenWorkGraph2 ) ); // Create an identity matrix broydenWorkVec.PutScalar(1.0); broydenWorkMatrix2->ReplaceDiagonalValues(broydenWorkVec); NOX::Epetra::BroydenOperator broydenOp2( noxParams, printing, broydenWorkVec, broydenWorkMatrix2, true ); broydenWorkVec[0] = 1.0; broydenWorkVec[1] = -1.0; broydenWorkVec[2] = 2.0; broydenOp2.setStepVector( broydenWorkVec ); broydenWorkVec[0] = 2.0; broydenWorkVec[1] = 1.0; broydenWorkVec[2] = 3.0; broydenOp2.setYieldVector( broydenWorkVec ); broydenOp2.computeSparseBroydenUpdate(); // Create the gold matrix for comparison Teuchos::RCP<Epetra_CrsMatrix> goldMatrix2 = Teuchos::rcp( new Epetra_CrsMatrix( Copy, broydenWorkGraph2 ) ); // Row 1 answers goldMatrix2->ExtractMyRowView( 0, numCols, values ); values[0] = 7.0 ; values[1] = -1.0 ; values[2] = 2.0 ; // Row 2 answers goldMatrix2->ExtractMyRowView( 1, numCols, values ); values[0] = 2.0 ; values[1] = 4.0 ; values[2] = 4.0 ; // Row 3 structure goldMatrix2->ExtractMyRowView( 2, numCols, values ); values[0] = 1.0 ; values[1] = -1.0 ; values[2] = 8.0 ; double scaleF = 1.0 / 6.0; goldMatrix2->Scale( scaleF ); status += tester.testCrsMatrices( broydenOp2.getBroydenMatrix(), *goldMatrix2, reltol, abstol, "Broyden Sparse Operator Update Test (Dense)" ); // Now test the ability to remove active entries in the Broyden update Epetra_CrsGraph inactiveGraph( Copy, broydenRowMap, 0 ); // Row 1 structure inactiveGraph.InsertGlobalIndices( globalIndices[0], 1, &myGlobalIndices[1] ); // Row 2 structure inactiveGraph.InsertGlobalIndices( globalIndices[1], 1, &myGlobalIndices[2] ); // Row 3 structure inactiveGraph.InsertGlobalIndices( globalIndices[2], 1, &myGlobalIndices[0] ); inactiveGraph.FillComplete(); // Inactivate entries in dense matrix to arrive again at the original sparse structure broydenOp2.removeEntriesFromBroydenUpdate( inactiveGraph ); #ifdef HAVE_NOX_DEBUG if( verbose ) broydenOp2.outputActiveEntries(); #endif // Reset to the identity matrix broydenOp2.resetBroydenMatrix( *broydenWorkMatrix2 ); // Step and Yield vectors are already set broydenOp2.computeSparseBroydenUpdate(); status += tester.testCrsMatrices( broydenOp2.getBroydenMatrix(), *goldMatrix, reltol, abstol, "Broyden Sparse Operator Update Test (Entry Removal)", false ); // Summarize test results if( status == 0 ) printing->out() << "Test passed!" << std::endl; else printing->out() << "Test failed!" << std::endl; #ifdef HAVE_MPI MPI_Finalize(); #endif // Final return value (0 = successfull, non-zero = failure) return status; }
int main(int argc, char *argv[]) { // Initialize MPI #ifdef HAVE_MPI MPI_Init(&argc,&argv); #endif // Create a communicator for Epetra objects #ifdef HAVE_MPI Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else Epetra_SerialComm Comm; #endif bool verbose = false; if (argc > 1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; // Get the process ID and the total number of processors int MyPID = Comm.MyPID(); #ifdef HAVE_MPI int NumProc = Comm.NumProc(); #endif // define the parameters of the nonlinear PDE problem int nx = 5; int ny = 6; double lambda = 1.0; PDEProblem Problem(nx,ny,lambda,&Comm); // starting solution, here a zero vector Epetra_Vector InitialGuess(Problem.GetMatrix()->Map()); InitialGuess.PutScalar(0.0); // random vector upon which to apply each operator being tested Epetra_Vector directionVec(Problem.GetMatrix()->Map()); directionVec.Random(); // Set up the problem interface Teuchos::RCP<SimpleProblemInterface> interface = Teuchos::rcp(new SimpleProblemInterface(&Problem) ); // Set up theolver options parameter list Teuchos::RCP<Teuchos::ParameterList> noxParamsPtr = Teuchos::rcp(new Teuchos::ParameterList); Teuchos::ParameterList & noxParams = *(noxParamsPtr.get()); // Set the nonlinear solver method noxParams.set("Nonlinear Solver", "Line Search Based"); // Set up the printing utilities // Only print output if the "-v" flag is set on the command line Teuchos::ParameterList& printParams = noxParams.sublist("Printing"); printParams.set("MyPID", MyPID); printParams.set("Output Precision", 5); printParams.set("Output Processor", 0); if( verbose ) printParams.set("Output Information", NOX::Utils::OuterIteration + NOX::Utils::OuterIterationStatusTest + NOX::Utils::InnerIteration + NOX::Utils::Parameters + NOX::Utils::Details + NOX::Utils::Warning + NOX::Utils::TestDetails); else printParams.set("Output Information", NOX::Utils::Error + NOX::Utils::TestDetails); NOX::Utils printing(printParams); // Identify the test problem if (printing.isPrintType(NOX::Utils::TestDetails)) printing.out() << "Starting epetra/NOX_Operators/NOX_Operators.exe" << std::endl; // Identify processor information #ifdef HAVE_MPI if (printing.isPrintType(NOX::Utils::TestDetails)) { printing.out() << "Parallel Run" << std::endl; printing.out() << "Number of processors = " << NumProc << std::endl; printing.out() << "Print Process = " << MyPID << std::endl; } Comm.Barrier(); if (printing.isPrintType(NOX::Utils::TestDetails)) printing.out() << "Process " << MyPID << " is alive!" << std::endl; Comm.Barrier(); #else if (printing.isPrintType(NOX::Utils::TestDetails)) printing.out() << "Serial Run" << std::endl; #endif int status = 0; Teuchos::RCP<NOX::Epetra::Interface::Required> iReq = interface; // Need a NOX::Epetra::Vector for constructor NOX::Epetra::Vector noxInitGuess(InitialGuess, NOX::DeepCopy); // Analytic matrix Teuchos::RCP<Epetra_CrsMatrix> A = Teuchos::rcp( Problem.GetMatrix(), false ); Epetra_Vector A_resultVec(Problem.GetMatrix()->Map()); interface->computeJacobian( InitialGuess, *A ); A->Apply( directionVec, A_resultVec ); // FD operator Teuchos::RCP<Epetra_CrsGraph> graph = Teuchos::rcp( const_cast<Epetra_CrsGraph*>(&A->Graph()), false ); Teuchos::RCP<NOX::Epetra::FiniteDifference> FD = Teuchos::rcp( new NOX::Epetra::FiniteDifference(printParams, iReq, noxInitGuess, graph) ); Epetra_Vector FD_resultVec(Problem.GetMatrix()->Map()); FD->computeJacobian(InitialGuess, *FD); FD->Apply( directionVec, FD_resultVec ); // Matrix-Free operator Teuchos::RCP<NOX::Epetra::MatrixFree> MF = Teuchos::rcp( new NOX::Epetra::MatrixFree(printParams, iReq, noxInitGuess) ); Epetra_Vector MF_resultVec(Problem.GetMatrix()->Map()); MF->computeJacobian(InitialGuess, *MF); MF->Apply( directionVec, MF_resultVec ); // Need NOX::Epetra::Vectors for tests NOX::Epetra::Vector noxAvec ( A_resultVec , NOX::DeepCopy ); NOX::Epetra::Vector noxFDvec( FD_resultVec, NOX::DeepCopy ); NOX::Epetra::Vector noxMFvec( MF_resultVec, NOX::DeepCopy ); // Create a TestCompare class NOX::Epetra::TestCompare tester( printing.out(), printing); double abstol = 1.e-4; double reltol = 1.e-4 ; //NOX::TestCompare::CompareType aComp = NOX::TestCompare::Absolute; status += tester.testVector( noxFDvec, noxAvec, reltol, abstol, "Finite-Difference Operator Apply Test" ); status += tester.testVector( noxMFvec, noxAvec, reltol, abstol, "Matrix-Free Operator Apply Test" ); // Summarize test results if( status == 0 ) printing.out() << "Test passed!" << std::endl; else printing.out() << "Test failed!" << std::endl; #ifdef HAVE_MPI MPI_Finalize(); #endif // Final return value (0 = successfull, non-zero = failure) return status; }
int main(int argc, char *argv[]) { int ierr = 0, i; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); int rank; // My process ID MPI_Comm_rank(MPI_COMM_WORLD, &rank); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else int rank = 0; Epetra_SerialComm Comm; #endif #ifdef HAVE_EPETRA_TEUCHOS Teuchos::RCP<Teuchos::FancyOStream> fancyOut = Teuchos::VerboseObjectBase::getDefaultOStream(); if (Comm.NumProc() > 1 ) { fancyOut->setShowProcRank(true); fancyOut->setOutputToRootOnly(-1); } std::ostream &out = *fancyOut; #else std::ostream &out = std::cout; #endif Comm.SetTracebackMode(0); // This should shut down any error tracing 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; // char tmp; // if (rank==0) out << "Press any key to continue..."<< endl; // if (rank==0) cin >> tmp; // Comm.Barrier(); int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if (verbose && MyPID==0) out << Epetra_Version() << endl << endl; if (verbose) out << Comm <<endl; bool verbose1 = verbose; // Redefine verbose to only print on PE 0 if (verbose && rank!=0) verbose = false; int NumMyElements = 10000; int NumMyElements1 = NumMyElements; // Needed for localmap int NumGlobalElements = NumMyElements*NumProc+EPETRA_MIN(NumProc,3); if (MyPID < 3) NumMyElements++; int IndexBase = 0; int ElementSize = 7; // Test LocalMap constructor // and Petra-defined uniform linear distribution constructor if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_LocalMap(NumMyElements1, IndexBase, Comm)" << endl; if (verbose) out << " and Epetra_BlockMap(NumGlobalElements, ElementSize, IndexBase, Comm)" << endl; if (verbose) out << "*********************************************************" << endl; Epetra_LocalMap *LocalMap = new Epetra_LocalMap(NumMyElements1, IndexBase, Comm); Epetra_BlockMap * BlockMap = new Epetra_BlockMap(NumGlobalElements, ElementSize, IndexBase, Comm); EPETRA_TEST_ERR(VectorTests(*BlockMap, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, verbose),ierr); delete BlockMap; // Test User-defined linear distribution constructor if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_BlockMap(NumGlobalElements, NumMyElements, ElementSize, IndexBase, Comm)" << endl; if (verbose) out << "*********************************************************" << endl; BlockMap = new Epetra_BlockMap(NumGlobalElements, NumMyElements, ElementSize, IndexBase, Comm); EPETRA_TEST_ERR(VectorTests(*BlockMap, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, verbose),ierr); delete BlockMap; // Test User-defined arbitrary distribution constructor // Generate Global Element List. Do in reverse for fun! int * MyGlobalElements = new int[NumMyElements]; int MaxMyGID = (Comm.MyPID()+1)*NumMyElements-1+IndexBase; if (Comm.MyPID()>2) MaxMyGID+=3; for (i = 0; i<NumMyElements; i++) MyGlobalElements[i] = MaxMyGID-i; if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_BlockMap(NumGlobalElements, NumMyElements, MyGlobalElements, ElementSize, IndexBase, Comm)" << endl; if (verbose) out << "*********************************************************" << endl; BlockMap = new Epetra_BlockMap(NumGlobalElements, NumMyElements, MyGlobalElements, ElementSize, IndexBase, Comm); EPETRA_TEST_ERR(VectorTests(*BlockMap, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, verbose),ierr); delete BlockMap; int * ElementSizeList = new int[NumMyElements]; int NumMyEquations = 0; int NumGlobalEquations = 0; for (i = 0; i<NumMyElements; i++) { ElementSizeList[i] = i%6+2; // blocksizes go from 2 to 7 NumMyEquations += ElementSizeList[i]; } ElementSize = 7; // Set to maximum for use in checkmap NumGlobalEquations = Comm.NumProc()*NumMyEquations; // Adjust NumGlobalEquations based on processor ID if (Comm.NumProc() > 3) { if (Comm.MyPID()>2) NumGlobalEquations += 3*((NumMyElements)%6+2); else NumGlobalEquations -= (Comm.NumProc()-3)*((NumMyElements-1)%6+2); } if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_BlockMap(NumGlobalElements, NumMyElements, MyGlobalElements, ElementSizeList, IndexBase, Comm)" << endl; if (verbose) out << "*********************************************************" << endl; BlockMap = new Epetra_BlockMap(NumGlobalElements, NumMyElements, MyGlobalElements, ElementSizeList, IndexBase, Comm); EPETRA_TEST_ERR(VectorTests(*BlockMap, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, verbose),ierr); // Test Copy constructor if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_BlockMap(*BlockMap)" << endl; if (verbose) out << "*********************************************************" << endl; Epetra_BlockMap * BlockMap1 = new Epetra_BlockMap(*BlockMap); EPETRA_TEST_ERR(VectorTests(*BlockMap, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*BlockMap, *LocalMap, verbose),ierr); delete [] ElementSizeList; delete [] MyGlobalElements; delete BlockMap; delete BlockMap1; // Test Petra-defined uniform linear distribution constructor if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_Map(NumGlobalElements, IndexBase, Comm)" << endl; if (verbose) out << "*********************************************************" << endl; Epetra_Map * Map = new Epetra_Map(NumGlobalElements, IndexBase, Comm); EPETRA_TEST_ERR(VectorTests(*Map, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*Map, *LocalMap, verbose),ierr); delete Map; // Test User-defined linear distribution constructor if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_Map(NumGlobalElements, NumMyElements, IndexBase, Comm)" << endl; if (verbose) out << "*********************************************************" << endl; Map = new Epetra_Map(NumGlobalElements, NumMyElements, IndexBase, Comm); EPETRA_TEST_ERR(VectorTests(*Map, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*Map, *LocalMap, verbose),ierr); delete Map; // Test User-defined arbitrary distribution constructor // Generate Global Element List. Do in reverse for fun! MyGlobalElements = new int[NumMyElements]; MaxMyGID = (Comm.MyPID()+1)*NumMyElements-1+IndexBase; if (Comm.MyPID()>2) MaxMyGID+=3; for (i = 0; i<NumMyElements; i++) MyGlobalElements[i] = MaxMyGID-i; if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase, Comm)" << endl; if (verbose) out << "*********************************************************" << endl; Map = new Epetra_Map(NumGlobalElements, NumMyElements, MyGlobalElements, IndexBase, Comm); EPETRA_TEST_ERR(VectorTests(*Map, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*Map, *LocalMap, verbose),ierr); // Test Copy constructor if (verbose) out << "\n*********************************************************" << endl; if (verbose) out << "Checking Epetra_Map(*Map)" << endl; if (verbose) out << "*********************************************************" << endl; Epetra_Map Map1(*Map); EPETRA_TEST_ERR(VectorTests(*Map, verbose),ierr); EPETRA_TEST_ERR(MatrixTests(*Map, *LocalMap, verbose),ierr); delete [] MyGlobalElements; delete Map; if (verbose1) { // Test Vector MFLOPS for 2D Dot Product int M = 1; int K = 1000000; Epetra_Map Map2(-1, K, IndexBase, Comm); Epetra_LocalMap Map3(M, IndexBase, Comm); Epetra_Vector A(Map2);A.Random(); Epetra_Vector B(Map2);B.Random(); Epetra_Vector C(Map3);C.Random(); // Test Epetra_Vector label const char* VecLabel = A.Label(); const char* VecLabel1 = "Epetra::Vector"; if (verbose) out << endl << endl <<"This should say " << VecLabel1 << ": " << VecLabel << endl << endl << endl; EPETRA_TEST_ERR(strcmp(VecLabel1,VecLabel),ierr); if (verbose) out << "Testing Assignment operator" << endl; double tmp1 = 1.00001* (double) (MyPID+1); double tmp2 = tmp1; A[1] = tmp1; tmp2 = A[1]; out << "On PE "<< MyPID << " A[1] should equal = " << tmp1; if (tmp1==tmp2) out << " and it does!" << endl; else out << " but it equals " << tmp2; Comm.Barrier(); if (verbose) out << endl << endl << "Testing MFLOPs" << endl; Epetra_Flops counter; C.SetFlopCounter(counter); Epetra_Time mytimer(Comm); C.Multiply('T', 'N', 0.5, A, B, 0.0); double Multiply_time = mytimer.ElapsedTime(); double Multiply_flops = C.Flops(); if (verbose) out << "\n\nTotal FLOPs = " << Multiply_flops << endl; if (verbose) out << "Total Time = " << Multiply_time << endl; if (verbose) out << "MFLOPs = " << Multiply_flops/Multiply_time/1000000.0 << endl; Comm.Barrier(); // Test Vector ostream operator with Petra-defined uniform linear distribution constructor // and a small vector Epetra_Map Map4(100, IndexBase, Comm); double * Dp = new double[100]; for (i=0; i<100; i++) Dp[i] = i; Epetra_Vector D(View, Map4,Dp); if (verbose) out << "\n\nTesting ostream operator: Multivector should be 100-by-2 and print i,j indices" << endl << endl; out << D << endl; if (verbose) out << "Traceback Mode value = " << D.GetTracebackMode() << endl; delete [] Dp; } #ifdef EPETRA_MPI MPI_Finalize(); #endif return ierr; }
int main(int argc, char *argv[]) { int ierr = 0, forierr = 0; bool debug = false; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); int rank; // My process ID MPI_Comm_rank(MPI_COMM_WORLD, &rank); Epetra_MpiComm Comm( MPI_COMM_WORLD ); #else int rank = 0; 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; int verbose_int = verbose ? 1 : 0; Comm.Broadcast(&verbose_int, 1, 0); verbose = verbose_int==1 ? true : false; // char tmp; // if (rank==0) 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 int MyPID = Comm.MyPID(); int NumProc = Comm.NumProc(); if(verbose && MyPID==0) cout << Epetra_Version() << std::endl << std::endl; if (verbose) cout << "Processor "<<MyPID<<" of "<< NumProc << " is alive."<<endl; bool verbose1 = verbose; // Redefine verbose to only print on PE 0 if(verbose && rank!=0) verbose = false; int NumMyEquations = 10000; int NumGlobalEquations = (NumMyEquations * NumProc) + EPETRA_MIN(NumProc,3); if(MyPID < 3) NumMyEquations++; // Construct a Map that puts approximately the same Number of equations on each processor Epetra_Map Map(NumGlobalEquations, NumMyEquations, 0, Comm); // Get update list and number of local equations from newly created Map int* MyGlobalElements = new int[Map.NumMyElements()]; Map.MyGlobalElements(MyGlobalElements); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor int* NumNz = new int[NumMyEquations]; // We are building a tridiagonal matrix where each row has (-1 2 -1) // So we need 2 off-diagonal terms (except for the first and last equation) for (int i = 0; i < NumMyEquations; i++) if((MyGlobalElements[i] == 0) || (MyGlobalElements[i] == NumGlobalEquations - 1)) NumNz[i] = 1; else NumNz[i] = 2; // Create a Epetra_Matrix Epetra_CrsMatrix A(Copy, Map, NumNz); EPETRA_TEST_ERR(A.IndicesAreGlobal(),ierr); EPETRA_TEST_ERR(A.IndicesAreLocal(),ierr); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 double* Values = new double[2]; Values[0] = -1.0; Values[1] = -1.0; int* Indices = new int[2]; double two = 2.0; int NumEntries; forierr = 0; for (int i = 0; i < NumMyEquations; i++) { if(MyGlobalElements[i] == 0) { Indices[0] = 1; NumEntries = 1; } else if (MyGlobalElements[i] == NumGlobalEquations-1) { Indices[0] = NumGlobalEquations-2; NumEntries = 1; } else { Indices[0] = MyGlobalElements[i]-1; Indices[1] = MyGlobalElements[i]+1; NumEntries = 2; } forierr += !(A.InsertGlobalValues(MyGlobalElements[i], NumEntries, Values, Indices)==0); forierr += !(A.InsertGlobalValues(MyGlobalElements[i], 1, &two, MyGlobalElements+i)>0); // Put in the diagonal entry } EPETRA_TEST_ERR(forierr,ierr); int * indexOffsetTmp; int * indicesTmp; double * valuesTmp; // Finish up EPETRA_TEST_ERR(!(A.IndicesAreGlobal()),ierr); EPETRA_TEST_ERR(!(A.ExtractCrsDataPointers(indexOffsetTmp, indicesTmp, valuesTmp)==-1),ierr); // Should fail EPETRA_TEST_ERR(!(A.FillComplete(false)==0),ierr); EPETRA_TEST_ERR(!(A.ExtractCrsDataPointers(indexOffsetTmp, indicesTmp, valuesTmp)==-1),ierr); // Should fail EPETRA_TEST_ERR(!(A.IndicesAreLocal()),ierr); EPETRA_TEST_ERR(A.StorageOptimized(),ierr); A.OptimizeStorage(); EPETRA_TEST_ERR(!(A.StorageOptimized()),ierr); EPETRA_TEST_ERR(!(A.ExtractCrsDataPointers(indexOffsetTmp, indicesTmp, valuesTmp)==0),ierr); // Should succeed const Epetra_CrsGraph & GofA = A.Graph(); EPETRA_TEST_ERR((indicesTmp!=GofA[0] || valuesTmp!=A[0]),ierr); // Extra check to see if operator[] is consistent EPETRA_TEST_ERR(A.UpperTriangular(),ierr); EPETRA_TEST_ERR(A.LowerTriangular(),ierr); int NumMyNonzeros = 3 * NumMyEquations; if(A.LRID(0) >= 0) NumMyNonzeros--; // If I own first global row, then there is one less nonzero if(A.LRID(NumGlobalEquations-1) >= 0) NumMyNonzeros--; // If I own last global row, then there is one less nonzero EPETRA_TEST_ERR(check(A, NumMyEquations, NumGlobalEquations, NumMyNonzeros, 3*NumGlobalEquations-2, MyGlobalElements, verbose),ierr); forierr = 0; for (int i = 0; i < NumMyEquations; i++) forierr += !(A.NumGlobalEntries(MyGlobalElements[i])==NumNz[i]+1); EPETRA_TEST_ERR(forierr,ierr); forierr = 0; for (int i = 0; i < NumMyEquations; i++) forierr += !(A.NumMyEntries(i)==NumNz[i]+1); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nNumEntries function check OK" << std::endl<< std::endl; EPETRA_TEST_ERR(check_graph_sharing(Comm),ierr); // Create vectors for Power method Epetra_Vector q(Map); Epetra_Vector z(Map); Epetra_Vector resid(Map); // variable needed for iteration double lambda = 0.0; // int niters = 10000; int niters = 200; double tolerance = 1.0e-1; ///////////////////////////////////////////////////////////////////////////////////////////////// // Iterate Epetra_Flops flopcounter; A.SetFlopCounter(flopcounter); q.SetFlopCounter(A); z.SetFlopCounter(A); resid.SetFlopCounter(A); Epetra_Time timer(Comm); EPETRA_TEST_ERR(power_method(false, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); double elapsed_time = timer.ElapsedTime(); double total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops(); double MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for first solve = " << MFLOPs << std::endl<< std::endl; ///////////////////////////////////////////////////////////////////////////////////////////////// // Solve transpose problem if (verbose) cout << "\n\nUsing transpose of matrix and solving again (should give same result).\n\n" << std::endl; // Iterate lambda = 0.0; flopcounter.ResetFlops(); timer.ResetStartTime(); EPETRA_TEST_ERR(power_method(true, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = timer.ElapsedTime(); total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops(); MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for transpose solve = " << MFLOPs << std::endl<< endl; ///////////////////////////////////////////////////////////////////////////////////////////////// // Increase diagonal dominance if (verbose) cout << "\n\nIncreasing the magnitude of first diagonal term and solving again\n\n" << endl; if (A.MyGlobalRow(0)) { int numvals = A.NumGlobalEntries(0); double * Rowvals = new double [numvals]; int * Rowinds = new int [numvals]; A.ExtractGlobalRowCopy(0, numvals, numvals, Rowvals, Rowinds); // Get A[0,0] for (int i=0; i<numvals; i++) if (Rowinds[i] == 0) Rowvals[i] *= 10.0; A.ReplaceGlobalValues(0, numvals, Rowvals, Rowinds); delete [] Rowvals; delete [] Rowinds; } // Iterate (again) lambda = 0.0; flopcounter.ResetFlops(); timer.ResetStartTime(); EPETRA_TEST_ERR(power_method(false, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = timer.ElapsedTime(); total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops(); MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for second solve = " << MFLOPs << endl<< endl; ///////////////////////////////////////////////////////////////////////////////////////////////// // Solve transpose problem if (verbose) cout << "\n\nUsing transpose of matrix and solving again (should give same result).\n\n" << endl; // Iterate (again) lambda = 0.0; flopcounter.ResetFlops(); timer.ResetStartTime(); EPETRA_TEST_ERR(power_method(true, A, q, z, resid, &lambda, niters, tolerance, verbose),ierr); elapsed_time = timer.ElapsedTime(); total_flops = A.Flops() + q.Flops() + z.Flops() + resid.Flops(); MFLOPs = total_flops/elapsed_time/1000000.0; if (verbose) cout << "\n\nTotal MFLOPs for tranpose of second solve = " << MFLOPs << endl<< endl; if (verbose) cout << "\n\n*****Testing constant entry constructor" << endl<< endl; Epetra_CrsMatrix AA(Copy, Map, 5); if (debug) Comm.Barrier(); double dble_one = 1.0; for (int i=0; i< NumMyEquations; i++) AA.InsertGlobalValues(MyGlobalElements[i], 1, &dble_one, MyGlobalElements+i); // Note: All processors will call the following Insert routines, but only the processor // that owns it will actually do anything int One = 1; if (AA.MyGlobalRow(0)) { EPETRA_TEST_ERR(!(AA.InsertGlobalValues(0, 0, &dble_one, &One)==0),ierr); } else EPETRA_TEST_ERR(!(AA.InsertGlobalValues(0, 1, &dble_one, &One)==-1),ierr); EPETRA_TEST_ERR(!(AA.FillComplete(false)==0),ierr); EPETRA_TEST_ERR(AA.StorageOptimized(),ierr); EPETRA_TEST_ERR(!(AA.UpperTriangular()),ierr); EPETRA_TEST_ERR(!(AA.LowerTriangular()),ierr); if (debug) Comm.Barrier(); EPETRA_TEST_ERR(check(AA, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations, MyGlobalElements, verbose),ierr); if (debug) Comm.Barrier(); forierr = 0; for (int i=0; i<NumMyEquations; i++) forierr += !(AA.NumGlobalEntries(MyGlobalElements[i])==1); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nNumEntries function check OK" << endl<< endl; if (debug) Comm.Barrier(); if (verbose) cout << "\n\n*****Testing copy constructor" << endl<< endl; Epetra_CrsMatrix B(AA); EPETRA_TEST_ERR(check(B, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations, MyGlobalElements, verbose),ierr); forierr = 0; for (int i=0; i<NumMyEquations; i++) forierr += !(B.NumGlobalEntries(MyGlobalElements[i])==1); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nNumEntries function check OK" << endl<< endl; if (debug) Comm.Barrier(); if (verbose) cout << "\n\n*****Testing local view constructor" << endl<< endl; Epetra_CrsMatrix BV(View, AA.RowMap(), AA.ColMap(), 0); forierr = 0; int* Inds; double* Vals; for (int i = 0; i < NumMyEquations; i++) { forierr += !(AA.ExtractMyRowView(i, NumEntries, Vals, Inds)==0); forierr += !(BV.InsertMyValues(i, NumEntries, Vals, Inds)==0); } BV.FillComplete(false); EPETRA_TEST_ERR(check(BV, NumMyEquations, NumGlobalEquations, NumMyEquations, NumGlobalEquations, MyGlobalElements, verbose),ierr); forierr = 0; for (int i=0; i<NumMyEquations; i++) forierr += !(BV.NumGlobalEntries(MyGlobalElements[i])==1); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nNumEntries function check OK" << endl<< endl; if (debug) Comm.Barrier(); if (verbose) cout << "\n\n*****Testing post construction modifications" << endl<< endl; EPETRA_TEST_ERR(!(B.InsertGlobalValues(0, 1, &dble_one, &One)==-2),ierr); // Release all objects delete [] NumNz; delete [] Values; delete [] Indices; delete [] MyGlobalElements; if (verbose1) { // Test ostream << operator (if verbose1) // Construct a Map that puts 2 equations on each PE int NumMyElements1 = 2; int NumMyEquations1 = NumMyElements1; int NumGlobalEquations1 = NumMyEquations1*NumProc; Epetra_Map Map1(-1, NumMyElements1, 0, Comm); // Get update list and number of local equations from newly created Map int * MyGlobalElements1 = new int[Map1.NumMyElements()]; Map1.MyGlobalElements(MyGlobalElements1); // Create an integer vector NumNz that is used to build the Petra Matrix. // NumNz[i] is the Number of OFF-DIAGONAL term for the ith global equation on this processor int * NumNz1 = new int[NumMyEquations1]; // We are building a tridiagonal matrix where each row has (-1 2 -1) // So we need 2 off-diagonal terms (except for the first and last equation) for (int i=0; i<NumMyEquations1; i++) if (MyGlobalElements1[i]==0 || MyGlobalElements1[i] == NumGlobalEquations1-1) NumNz1[i] = 1; else NumNz1[i] = 2; // Create a Epetra_Matrix Epetra_CrsMatrix A1(Copy, Map1, NumNz1); // Add rows one-at-a-time // Need some vectors to help // Off diagonal Values will always be -1 double *Values1 = new double[2]; Values1[0] = -1.0; Values1[1] = -1.0; int *Indices1 = new int[2]; double two1 = 2.0; int NumEntries1; forierr = 0; for (int i=0; i<NumMyEquations1; i++) { if (MyGlobalElements1[i]==0) { Indices1[0] = 1; NumEntries1 = 1; } else if (MyGlobalElements1[i] == NumGlobalEquations1-1) { Indices1[0] = NumGlobalEquations1-2; NumEntries1 = 1; } else { Indices1[0] = MyGlobalElements1[i]-1; Indices1[1] = MyGlobalElements1[i]+1; NumEntries1 = 2; } forierr += !(A1.InsertGlobalValues(MyGlobalElements1[i], NumEntries1, Values1, Indices1)==0); forierr += !(A1.InsertGlobalValues(MyGlobalElements1[i], 1, &two1, MyGlobalElements1+i)>0); // Put in the diagonal entry } EPETRA_TEST_ERR(forierr,ierr); delete [] Indices1; delete [] Values1; // Finish up EPETRA_TEST_ERR(!(A1.FillComplete(false)==0),ierr); // Test diagonal extraction function Epetra_Vector checkDiag(Map1); EPETRA_TEST_ERR(!(A1.ExtractDiagonalCopy(checkDiag)==0),ierr); forierr = 0; for (int i=0; i<NumMyEquations1; i++) forierr += !(checkDiag[i]==two1); EPETRA_TEST_ERR(forierr,ierr); // Test diagonal replacement method forierr = 0; for (int i=0; i<NumMyEquations1; i++) checkDiag[i]=two1*two1; EPETRA_TEST_ERR(forierr,ierr); EPETRA_TEST_ERR(!(A1.ReplaceDiagonalValues(checkDiag)==0),ierr); Epetra_Vector checkDiag1(Map1); EPETRA_TEST_ERR(!(A1.ExtractDiagonalCopy(checkDiag1)==0),ierr); forierr = 0; for (int i=0; i<NumMyEquations1; i++) forierr += !(checkDiag[i]==checkDiag1[i]); EPETRA_TEST_ERR(forierr,ierr); if (verbose) cout << "\n\nDiagonal extraction and replacement OK.\n\n" << endl; double orignorm = A1.NormOne(); EPETRA_TEST_ERR(!(A1.Scale(4.0)==0),ierr); EPETRA_TEST_ERR(!(A1.NormOne()!=orignorm),ierr); if (verbose) cout << "\n\nMatrix scale OK.\n\n" << endl; if (verbose) cout << "\n\nPrint out tridiagonal matrix, each part on each processor.\n\n" << endl; cout << A1 << endl; // Release all objects delete [] NumNz1; delete [] MyGlobalElements1; } if (verbose) cout << "\n\n*****Testing LeftScale and RightScale" << endl << endl; int NumMyElements2 = 7; int NumMyRows2 = 1;//This value should not be changed without editing the // code below. Epetra_Map RowMap(-1,NumMyRows2,0,Comm); Epetra_Map ColMap(NumMyElements2,NumMyElements2,0,Comm); // The DomainMap needs to be different from the ColMap for the test to // be meaningful. Epetra_Map DomainMap(NumMyElements2,0,Comm); int NumMyRangeElements2 = 0; // We need to distribute the elements differently for the range map also. if (MyPID % 2 == 0) NumMyRangeElements2 = NumMyRows2*2; //put elements on even number procs if (NumProc % 2 == 1 && MyPID == NumProc-1) NumMyRangeElements2 = NumMyRows2; //If number of procs is odd, put // the last NumMyElements2 elements on the last proc Epetra_Map RangeMap(-1,NumMyRangeElements2,0,Comm); Epetra_CrsMatrix A2(Copy,RowMap,ColMap,NumMyElements2); double * Values2 = new double[NumMyElements2]; int * Indices2 = new int[NumMyElements2]; for (int i=0; i<NumMyElements2; i++) { Values2[i] = i+MyPID; Indices2[i]=i; } A2.InsertMyValues(0,NumMyElements2,Values2,Indices2); A2.FillComplete(DomainMap,RangeMap,false); Epetra_CrsMatrix A2copy(A2); double * RowLeftScaleValues = new double[NumMyRows2]; double * ColRightScaleValues = new double[NumMyElements2]; int RowLoopLength = RowMap.MaxMyGID()-RowMap.MinMyGID()+1; for (int i=0; i<RowLoopLength; i++) RowLeftScaleValues[i] = (i + RowMap.MinMyGID() ) % 2 + 1; // For the column map, all procs own all elements for (int i=0; i<NumMyElements2;i++) ColRightScaleValues[i] = i % 2 + 1; int RangeLoopLength = RangeMap.MaxMyGID()-RangeMap.MinMyGID()+1; double * RangeLeftScaleValues = new double[RangeLoopLength]; int DomainLoopLength = DomainMap.MaxMyGID()-DomainMap.MinMyGID()+1; double * DomainRightScaleValues = new double[DomainLoopLength]; for (int i=0; i<RangeLoopLength; i++) RangeLeftScaleValues[i] = 1.0/((i + RangeMap.MinMyGID() ) % 2 + 1); for (int i=0; i<DomainLoopLength;i++) DomainRightScaleValues[i] = 1.0/((i + DomainMap.MinMyGID() ) % 2 + 1); Epetra_Vector xRow(View,RowMap,RowLeftScaleValues); Epetra_Vector xCol(View,ColMap,ColRightScaleValues); Epetra_Vector xRange(View,RangeMap,RangeLeftScaleValues); Epetra_Vector xDomain(View,DomainMap,DomainRightScaleValues); double A2infNorm = A2.NormInf(); double A2oneNorm = A2.NormOne(); if (verbose1) cout << A2; EPETRA_TEST_ERR(A2.LeftScale(xRow),ierr); double A2infNorm1 = A2.NormInf(); double A2oneNorm1 = A2.NormOne(); bool ScalingBroke = false; if (A2infNorm1>2*A2infNorm||A2infNorm1<A2infNorm) { EPETRA_TEST_ERR(-31,ierr); ScalingBroke = true; } if (A2oneNorm1>2*A2oneNorm||A2oneNorm1<A2oneNorm) { EPETRA_TEST_ERR(-32,ierr); ScalingBroke = true; } if (verbose1) cout << A2; EPETRA_TEST_ERR(A2.RightScale(xCol),ierr); double A2infNorm2 = A2.NormInf(); double A2oneNorm2 = A2.NormOne(); if (A2infNorm2>=2*A2infNorm1||A2infNorm2<=A2infNorm1) { EPETRA_TEST_ERR(-33,ierr); ScalingBroke = true; } if (A2oneNorm2>2*A2oneNorm1||A2oneNorm2<=A2oneNorm1) { EPETRA_TEST_ERR(-34,ierr); ScalingBroke = true; } if (verbose1) cout << A2; EPETRA_TEST_ERR(A2.RightScale(xDomain),ierr); double A2infNorm3 = A2.NormInf(); double A2oneNorm3 = A2.NormOne(); // The last two scaling ops cancel each other out if (A2infNorm3!=A2infNorm1) { EPETRA_TEST_ERR(-35,ierr) ScalingBroke = true; } if (A2oneNorm3!=A2oneNorm1) { EPETRA_TEST_ERR(-36,ierr) ScalingBroke = true; } if (verbose1) cout << A2; EPETRA_TEST_ERR(A2.LeftScale(xRange),ierr); double A2infNorm4 = A2.NormInf(); double A2oneNorm4 = A2.NormOne(); // The 4 scaling ops all cancel out if (A2infNorm4!=A2infNorm) { EPETRA_TEST_ERR(-37,ierr) ScalingBroke = true; } if (A2oneNorm4!=A2oneNorm) { EPETRA_TEST_ERR(-38,ierr) ScalingBroke = true; } // // Now try changing the values underneath and make sure that // telling one process about the change causes NormInf() and // NormOne() to recompute the norm on all processes. // double *values; int num_my_rows = A2.NumMyRows() ; int num_entries; for ( int i=0 ; i< num_my_rows; i++ ) { EPETRA_TEST_ERR( A2.ExtractMyRowView( i, num_entries, values ), ierr ); for ( int j = 0 ; j <num_entries; j++ ) { values[j] *= 2.0; } } if ( MyPID == 0 ) A2.SumIntoGlobalValues( 0, 0, 0, 0 ) ; double A2infNorm5 = A2.NormInf(); double A2oneNorm5 = A2.NormOne(); if (A2infNorm5!=2.0 * A2infNorm4) { EPETRA_TEST_ERR(-39,ierr) ScalingBroke = true; } if (A2oneNorm5!= 2.0 * A2oneNorm4) { EPETRA_TEST_ERR(-40,ierr) ScalingBroke = true; } // // Restore the values underneath // for ( int i=0 ; i< num_my_rows; i++ ) { EPETRA_TEST_ERR( A2.ExtractMyRowView( i, num_entries, values ), ierr ); for ( int j = 0 ; j <num_entries; j++ ) { values[j] /= 2.0; } } if (verbose1) cout << A2; if (ScalingBroke) { if (verbose) cout << endl << "LeftScale and RightScale tests FAILED" << endl << endl; } else { if (verbose) cout << endl << "LeftScale and RightScale tests PASSED" << endl << endl; } Comm.Barrier(); if (verbose) cout << "\n\n*****Testing InvRowMaxs and InvColMaxs" << endl << endl; if (verbose1) cout << A2 << endl; EPETRA_TEST_ERR(A2.InvRowMaxs(xRow),ierr); EPETRA_TEST_ERR(A2.InvRowMaxs(xRange),ierr); if (verbose1) cout << xRow << endl << xRange << endl; if (verbose) cout << "\n\n*****Testing InvRowSums and InvColSums" << endl << endl; bool InvSumsBroke = false; // Works! EPETRA_TEST_ERR(A2.InvRowSums(xRow),ierr); if (verbose1) cout << xRow; EPETRA_TEST_ERR(A2.LeftScale(xRow),ierr); float A2infNormFloat = A2.NormInf(); if (verbose1) cout << A2 << endl; if (fabs(1.0-A2infNormFloat) > 1.e-5) { EPETRA_TEST_ERR(-41,ierr); InvSumsBroke = true; } // Works int expectedcode = 1; if (Comm.NumProc()>1) expectedcode = 0; EPETRA_TEST_ERR(!(A2.InvColSums(xDomain)==expectedcode),ierr); // This matrix has a single row, the first column has a zero, so a warning is issued. if (verbose1) cout << xDomain << endl; EPETRA_TEST_ERR(A2.RightScale(xDomain),ierr); float A2oneNormFloat2 = A2.NormOne(); if (verbose1) cout << A2; if (fabs(1.0-A2oneNormFloat2)>1.e-5) { EPETRA_TEST_ERR(-42,ierr) InvSumsBroke = true; } // Works! EPETRA_TEST_ERR(A2.InvRowSums(xRange),ierr); if (verbose1) cout << xRange; EPETRA_TEST_ERR(A2.LeftScale(xRange),ierr); float A2infNormFloat2 = A2.NormInf(); // We use a float so that rounding error // will not prevent the sum from being 1.0. if (verbose1) cout << A2; if (fabs(1.0-A2infNormFloat2)>1.e-5) { cout << "InfNorm should be = 1, but InfNorm = " << A2infNormFloat2 << endl; EPETRA_TEST_ERR(-43,ierr); InvSumsBroke = true; } // Doesn't work - may not need this test because column ownership is not unique /* EPETRA_TEST_ERR(A2.InvColSums(xCol),ierr); cout << xCol; EPETRA_TEST_ERR(A2.RightScale(xCol),ierr); float A2oneNormFloat = A2.NormOne(); cout << A2; if (fabs(1.0-A2oneNormFloat)>1.e-5) { EPETRA_TEST_ERR(-44,ierr); InvSumsBroke = true; } */ delete [] ColRightScaleValues; delete [] DomainRightScaleValues; if (verbose) cout << "Begin partial sum testing." << endl; // Test with a matrix that has partial sums for a subset of the rows // on multiple processors. (Except for the serial case, of course.) int NumMyRows3 = 2; // Changing this requires further changes below int * myGlobalElements = new int[NumMyRows3]; for (int i=0; i<NumMyRows3; i++) myGlobalElements[i] = MyPID+i; Epetra_Map RowMap3(NumProc*2, NumMyRows3, myGlobalElements, 0, Comm); int NumMyElements3 = 5; Epetra_CrsMatrix A3(Copy, RowMap3, NumMyElements3); double * Values3 = new double[NumMyElements3]; int * Indices3 = new int[NumMyElements3]; for (int i=0; i < NumMyElements3; i++) { Values3[i] = (int) (MyPID + (i+1)); Indices3[i]=i; } for (int i=0; i<NumMyRows3; i++) { A3.InsertGlobalValues(myGlobalElements[i],NumMyElements3,Values3,Indices3); } Epetra_Map RangeMap3(NumProc+1, 0, Comm); Epetra_Map DomainMap3(NumMyElements3, 0, Comm); EPETRA_TEST_ERR(A3.FillComplete(DomainMap3, RangeMap3,false),ierr); if (verbose1) cout << A3; Epetra_Vector xRange3(RangeMap3,false); Epetra_Vector xDomain3(DomainMap3,false); EPETRA_TEST_ERR(A3.InvRowSums(xRange3),ierr); if (verbose1) cout << xRange3; EPETRA_TEST_ERR(A3.LeftScale(xRange3),ierr); float A3infNormFloat = A3.NormInf(); if (verbose1) cout << A3; if (1.0!=A3infNormFloat) { cout << "InfNorm should be = 1, but InfNorm = " << A3infNormFloat <<endl; EPETRA_TEST_ERR(-61,ierr); InvSumsBroke = true; } // we want to take the transpose of our matrix and fill in different values. int NumMyColumns3 = NumMyRows3; Epetra_Map ColMap3cm(RowMap3); Epetra_Map RowMap3cm(A3.ColMap()); Epetra_CrsMatrix A3cm(Copy,RowMap3cm,ColMap3cm,NumProc+1); double *Values3cm = new double[NumMyColumns3]; int * Indices3cm = new int[NumMyColumns3]; for (int i=0; i<NumMyColumns3; i++) { Values3cm[i] = MyPID + i + 1; Indices3cm[i]= i + MyPID; } for (int ii=0; ii<NumMyElements3; ii++) { A3cm.InsertGlobalValues(ii, NumMyColumns3, Values3cm, Indices3cm); } // The DomainMap and the RangeMap from the last test will work fine for // the RangeMap and DomainMap, respectively, but I will make copies to // avaoid confusion when passing what looks like a DomainMap where we // need a RangeMap and vice vera. Epetra_Map RangeMap3cm(DomainMap3); Epetra_Map DomainMap3cm(RangeMap3); EPETRA_TEST_ERR(A3cm.FillComplete(DomainMap3cm,RangeMap3cm),ierr); if (verbose1) cout << A3cm << endl; // Again, we can copy objects from the last example. //Epetra_Vector xRange3cm(xDomain3); //Don't use at this time Epetra_Vector xDomain3cm(DomainMap3cm,false); EPETRA_TEST_ERR(A3cm.InvColSums(xDomain3cm),ierr); if (verbose1) cout << xDomain3cm << endl; EPETRA_TEST_ERR(A3cm.RightScale(xDomain3cm),ierr); float A3cmOneNormFloat = A3cm.NormOne(); if (verbose1) cout << A3cm << endl; if (1.0!=A3cmOneNormFloat) { cout << "OneNorm should be = 1, but OneNorm = " << A3cmOneNormFloat << endl; EPETRA_TEST_ERR(-62,ierr); InvSumsBroke = true; } if (verbose) cout << "End partial sum testing" << endl; if (verbose) cout << "Begin replicated testing" << endl; // We will now view the shared row as a repliated row, rather than one // that has partial sums of its entries on mulitple processors. // We will reuse much of the data used for the partial sum tesitng. Epetra_Vector xRow3(RowMap3,false); Epetra_CrsMatrix A4(Copy, RowMap3, NumMyElements3); for (int ii=0; ii < NumMyElements3; ii++) { Values3[ii] = (int)((ii*.6)+1.0); } for (int ii=0; ii<NumMyRows3; ii++) { A4.InsertGlobalValues(myGlobalElements[ii],NumMyElements3,Values3,Indices3); } EPETRA_TEST_ERR(A4.FillComplete(DomainMap3, RangeMap3,false),ierr); if (verbose1) cout << A4 << endl; // The next two lines should be expanded into a verifiable test. EPETRA_TEST_ERR(A4.InvRowMaxs(xRow3),ierr); EPETRA_TEST_ERR(A4.InvRowMaxs(xRange3),ierr); if (verbose1) cout << xRow3 << xRange3; EPETRA_TEST_ERR(A4.InvRowSums(xRow3),ierr); if (verbose1) cout << xRow3; EPETRA_TEST_ERR(A4.LeftScale(xRow3),ierr); float A4infNormFloat = A4.NormInf(); if (verbose1) cout << A4; if (2.0!=A4infNormFloat && NumProc != 1) { if (verbose1) cout << "InfNorm should be = 2 (because one column is replicated on two processors and NormOne() does not handle replication), but InfNorm = " << A4infNormFloat <<endl; EPETRA_TEST_ERR(-63,ierr); InvSumsBroke = true; } else if (1.0!=A4infNormFloat && NumProc == 1) { if (verbose1) cout << "InfNorm should be = 1, but InfNorm = " << A4infNormFloat <<endl; EPETRA_TEST_ERR(-63,ierr); InvSumsBroke = true; } Epetra_Vector xCol3cm(ColMap3cm,false); Epetra_CrsMatrix A4cm(Copy, RowMap3cm, ColMap3cm, NumProc+1); //Use values from A3cm for (int ii=0; ii<NumMyElements3; ii++) { A4cm.InsertGlobalValues(ii,NumMyColumns3,Values3cm,Indices3cm); } EPETRA_TEST_ERR(A4cm.FillComplete(DomainMap3cm, RangeMap3cm,false),ierr); if (verbose1) cout << A4cm << endl; // The next two lines should be expanded into a verifiable test. EPETRA_TEST_ERR(A4cm.InvColMaxs(xCol3cm),ierr); EPETRA_TEST_ERR(A4cm.InvColMaxs(xDomain3cm),ierr); if (verbose1) cout << xCol3cm << xDomain3cm; EPETRA_TEST_ERR(A4cm.InvColSums(xCol3cm),ierr); if (verbose1) cout << xCol3cm << endl; EPETRA_TEST_ERR(A4cm.RightScale(xCol3cm),ierr); float A4cmOneNormFloat = A4cm.NormOne(); if (verbose1) cout << A4cm << endl; if (2.0!=A4cmOneNormFloat && NumProc != 1) { if (verbose1) cout << "OneNorm should be = 2 (because one column is replicated on two processors and NormOne() does not handle replication), but OneNorm = " << A4cmOneNormFloat << endl; EPETRA_TEST_ERR(-64,ierr); InvSumsBroke = true; } else if (1.0!=A4cmOneNormFloat && NumProc == 1) { if (verbose1) cout << "OneNorm should be = 1, but OneNorm = " << A4infNormFloat <<endl; EPETRA_TEST_ERR(-64,ierr); InvSumsBroke = true; } if (verbose) cout << "End replicated testing" << endl; if (InvSumsBroke) { if (verbose) cout << endl << "InvRowSums tests FAILED" << endl << endl; } else if (verbose) cout << endl << "InvRowSums tests PASSED" << endl << endl; A3cm.PutScalar(2.0); int nnz_A3cm = A3cm.Graph().NumGlobalNonzeros(); double check_frobnorm = sqrt(nnz_A3cm*4.0); double frobnorm = A3cm.NormFrobenius(); bool frobnorm_test_failed = false; if (fabs(check_frobnorm-frobnorm) > 5.e-5) { frobnorm_test_failed = true; } if (frobnorm_test_failed) { if (verbose) std::cout << "Frobenius-norm test FAILED."<<std::endl; EPETRA_TEST_ERR(-65, ierr); } delete [] Values2; delete [] Indices2; delete [] myGlobalElements; delete [] Values3; delete [] Indices3; delete [] Values3cm; delete [] Indices3cm; delete [] RangeLeftScaleValues; delete [] RowLeftScaleValues; #ifdef EPETRA_MPI MPI_Finalize() ; #endif /* end main */ return ierr ; }
int main(int argc, char *argv[]) { #ifdef ENABLE_INTEL_FLOATING_POINT_EXCEPTIONS cout << "NOTE: enabling floating point exceptions for divide by zero.\n"; _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~_MM_MASK_INVALID); #endif Teuchos::GlobalMPISession mpiSession(&argc, &argv); int rank = Teuchos::GlobalMPISession::getRank(); #ifdef HAVE_MPI Epetra_MpiComm Comm(MPI_COMM_WORLD); //cout << "rank: " << rank << " of " << numProcs << endl; #else Epetra_SerialComm Comm; #endif Comm.Barrier(); // set breakpoint here to allow debugger attachment to other MPI processes than the one you automatically attached to. Teuchos::CommandLineProcessor cmdp(false,true); // false: don't throw exceptions; true: do return errors for unrecognized options double minTol = 1e-8; bool use3D = false; int refCount = 10; int k = 4; // poly order for field variables int delta_k = use3D ? 3 : 2; // test space enrichment int k_coarse = 0; bool useMumps = true; bool useGMGSolver = true; bool enforceOneIrregularity = true; bool useStaticCondensation = false; bool conformingTraces = false; bool useDiagonalScaling = false; // of the global stiffness matrix in GMGSolver bool printRefinementDetails = false; bool useWeightedGraphNorm = true; // graph norm scaled according to units, more or less int numCells = 2; int AztecOutputLevel = 1; int gmgMaxIterations = 10000; int smootherOverlap = 0; double relativeTol = 1e-6; double D = 1.0; // characteristic length scale cmdp.setOption("polyOrder",&k,"polynomial order for field variable u"); cmdp.setOption("delta_k", &delta_k, "test space polynomial order enrichment"); cmdp.setOption("k_coarse", &k_coarse, "polynomial order for field variables on coarse mesh"); cmdp.setOption("numRefs",&refCount,"number of refinements"); cmdp.setOption("D", &D, "domain dimension"); cmdp.setOption("useConformingTraces", "useNonConformingTraces", &conformingTraces); cmdp.setOption("enforceOneIrregularity", "dontEnforceOneIrregularity", &enforceOneIrregularity); cmdp.setOption("smootherOverlap", &smootherOverlap, "overlap for smoother"); cmdp.setOption("printRefinementDetails", "dontPrintRefinementDetails", &printRefinementDetails); cmdp.setOption("azOutput", &AztecOutputLevel, "Aztec output level"); cmdp.setOption("numCells", &numCells, "number of cells in the initial mesh"); cmdp.setOption("useScaledGraphNorm", "dontUseScaledGraphNorm", &useWeightedGraphNorm); // cmdp.setOption("gmgTol", &gmgTolerance, "tolerance for GMG convergence"); cmdp.setOption("relativeTol", &relativeTol, "Energy error-relative tolerance for iterative solver."); cmdp.setOption("gmgMaxIterations", &gmgMaxIterations, "tolerance for GMG convergence"); bool enhanceUField = false; cmdp.setOption("enhanceUField", "dontEnhanceUField", &enhanceUField); cmdp.setOption("useStaticCondensation", "dontUseStaticCondensation", &useStaticCondensation); if (cmdp.parse(argc,argv) != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) { #ifdef HAVE_MPI MPI_Finalize(); #endif return -1; } double width = D, height = D, depth = D; VarFactory varFactory; // fields: VarPtr u = varFactory.fieldVar("u", L2); VarPtr sigma = varFactory.fieldVar("\\sigma", VECTOR_L2); FunctionPtr n = Function::normal(); // traces: VarPtr u_hat; if (conformingTraces) { u_hat = varFactory.traceVar("\\widehat{u}", u); } else { cout << "Note: using non-conforming traces.\n"; u_hat = varFactory.traceVar("\\widehat{u}", u, L2); } VarPtr sigma_n_hat = varFactory.fluxVar("\\widehat{\\sigma}_{n}", sigma * n); // test functions: VarPtr tau = varFactory.testVar("\\tau", HDIV); VarPtr v = varFactory.testVar("v", HGRAD); BFPtr poissonBF = Teuchos::rcp( new BF(varFactory) ); FunctionPtr alpha = Function::constant(1); // viscosity // tau terms: poissonBF->addTerm(sigma / alpha, tau); poissonBF->addTerm(-u, tau->div()); // (sigma1, tau1) poissonBF->addTerm(u_hat, tau * n); // v terms: poissonBF->addTerm(- sigma, v->grad()); // (mu sigma1, grad v1) poissonBF->addTerm( sigma_n_hat, v); int horizontalCells = numCells, verticalCells = numCells, depthCells = numCells; vector<double> domainDimensions; domainDimensions.push_back(width); domainDimensions.push_back(height); vector<int> elementCounts; elementCounts.push_back(horizontalCells); elementCounts.push_back(verticalCells); if (use3D) { domainDimensions.push_back(depth); elementCounts.push_back(depthCells); } MeshPtr mesh, k0Mesh; int H1Order = k + 1; int H1Order_coarse = k_coarse + 1; if (!use3D) { Teuchos::ParameterList pl; map<int,int> trialOrderEnhancements; if (enhanceUField) { trialOrderEnhancements[u->ID()] = 1; } BFPtr poissonBilinearForm = poissonBF; pl.set("useMinRule", true); pl.set("bf",poissonBilinearForm); pl.set("H1Order", H1Order); pl.set("delta_k", delta_k); pl.set("horizontalElements", horizontalCells); pl.set("verticalElements", verticalCells); pl.set("divideIntoTriangles", false); pl.set("useConformingTraces", conformingTraces); pl.set("trialOrderEnhancements", &trialOrderEnhancements); pl.set("x0",(double)0); pl.set("y0",(double)0); pl.set("width", width); pl.set("height",height); mesh = MeshFactory::quadMesh(pl); pl.set("H1Order", H1Order_coarse); k0Mesh = MeshFactory::quadMesh(pl); } else { mesh = MeshFactory::rectilinearMesh(poissonBF, domainDimensions, elementCounts, H1Order, delta_k); k0Mesh = MeshFactory::rectilinearMesh(poissonBF, domainDimensions, elementCounts, H1Order_coarse, delta_k); } mesh->registerObserver(k0Mesh); // ensure that the k0 mesh refinements track those of the solution mesh RHSPtr rhs = RHS::rhs(); // zero FunctionPtr sin_pi_x = Teuchos::rcp( new Sin_ax(PI/D) ); FunctionPtr sin_pi_y = Teuchos::rcp( new Sin_ay(PI/D) ); FunctionPtr u_exact = sin_pi_x * sin_pi_y; FunctionPtr f = -(2.0 * PI * PI / (D * D)) * sin_pi_x * sin_pi_y; rhs->addTerm( f * v ); BCPtr bc = BC::bc(); SpatialFilterPtr boundary = SpatialFilter::allSpace(); bc->addDirichlet(u_hat, boundary, u_exact); IPPtr graphNorm; FunctionPtr h = Teuchos::rcp( new hFunction() ); if (useWeightedGraphNorm) { graphNorm = IP::ip(); graphNorm->addTerm( tau->div() ); // u graphNorm->addTerm( (h / alpha) * tau - h * v->grad() ); // sigma graphNorm->addTerm( v ); // boundary term (adjoint to u) graphNorm->addTerm( h * tau ); // // new effort, with the idea that the test norm should be considered in reference space, basically // graphNorm = IP::ip(); // graphNorm->addTerm( tau->div() ); // u // graphNorm->addTerm( tau / h - v->grad() ); // sigma // graphNorm->addTerm( v / h ); // boundary term (adjoint to u) // graphNorm->addTerm( tau / h ); } else { map<int, double> trialWeights; // on the squared terms in the trial space norm trialWeights[u->ID()] = 1.0 / (D * D); trialWeights[sigma->ID()] = 1.0; graphNorm = poissonBF->graphNorm(trialWeights, 1.0); // 1.0: weight on the L^2 terms } SolutionPtr solution = Solution::solution(mesh, bc, rhs, graphNorm); solution->setUseCondensedSolve(useStaticCondensation); mesh->registerSolution(solution); // sign up for projection of old solution onto refined cells. double energyThreshold = 0.2; RefinementStrategy refinementStrategy( solution, energyThreshold ); refinementStrategy.setReportPerCellErrors(true); refinementStrategy.setEnforceOneIrregularity(enforceOneIrregularity); Teuchos::RCP<Solver> coarseSolver, fineSolver; if (useMumps) { #ifdef HAVE_AMESOS_MUMPS coarseSolver = Teuchos::rcp( new MumpsSolver(512, true) ); #else cout << "useMumps=true, but MUMPS is not available!\n"; exit(0); #endif } else { coarseSolver = Teuchos::rcp( new KluSolver ); } GMGSolver* gmgSolver; if (useGMGSolver) { double tol = relativeTol; int maxIters = gmgMaxIterations; BCPtr zeroBCs = bc->copyImposingZero(); gmgSolver = new GMGSolver(zeroBCs, k0Mesh, graphNorm, mesh, solution->getDofInterpreter(), solution->getPartitionMap(), maxIters, tol, coarseSolver, useStaticCondensation); gmgSolver->setAztecOutput(AztecOutputLevel); gmgSolver->setUseConjugateGradient(true); gmgSolver->gmgOperator()->setSmootherType(GMGOperator::IFPACK_ADDITIVE_SCHWARZ); gmgSolver->gmgOperator()->setSmootherOverlap(smootherOverlap); fineSolver = Teuchos::rcp( gmgSolver ); } else { fineSolver = coarseSolver; } // if (rank==0) cout << "experimentally starting by solving with MUMPS on the fine mesh.\n"; // solution->solve( Teuchos::rcp( new MumpsSolver) ); solution->solve(fineSolver); #ifdef HAVE_EPETRAEXT_HDF5 ostringstream dir_name; dir_name << "poissonCavityFlow_k" << k; HDF5Exporter exporter(mesh,dir_name.str()); exporter.exportSolution(solution,varFactory,0); #endif #ifdef HAVE_AMESOS_MUMPS if (useMumps) coarseSolver = Teuchos::rcp( new MumpsSolver(512, true) ); #endif solution->reportTimings(); if (useGMGSolver) gmgSolver->gmgOperator()->reportTimings(); for (int refIndex=0; refIndex < refCount; refIndex++) { double energyError = solution->energyErrorTotal(); GlobalIndexType numFluxDofs = mesh->numFluxDofs(); if (rank==0) { cout << "Before refinement " << refIndex << ", energy error = " << energyError; cout << " (using " << numFluxDofs << " trace degrees of freedom)." << endl; } bool printToConsole = printRefinementDetails && (rank==0); refinementStrategy.refine(printToConsole); if (useStaticCondensation) { CondensedDofInterpreter* condensedDofInterpreter = dynamic_cast<CondensedDofInterpreter*>(solution->getDofInterpreter().get()); if (condensedDofInterpreter != NULL) { condensedDofInterpreter->reinitialize(); } } GlobalIndexType fineDofs = mesh->globalDofCount(); GlobalIndexType coarseDofs = k0Mesh->globalDofCount(); if (rank==0) { cout << "After refinement, coarse mesh has " << k0Mesh->numActiveElements() << " elements and " << coarseDofs << " dofs.\n"; cout << " Fine mesh has " << mesh->numActiveElements() << " elements and " << fineDofs << " dofs.\n"; } if (!use3D) { ostringstream fineMeshLocation, coarseMeshLocation; fineMeshLocation << "poissonFineMesh_k" << k << "_ref" << refIndex; GnuPlotUtil::writeComputationalMeshSkeleton(fineMeshLocation.str(), mesh, true); // true: label cells coarseMeshLocation << "poissonCoarseMesh_k" << k << "_ref" << refIndex; GnuPlotUtil::writeComputationalMeshSkeleton(coarseMeshLocation.str(), k0Mesh, true); // true: label cells } if (useGMGSolver) // create fresh fineSolver now that the meshes have changed: { #ifdef HAVE_AMESOS_MUMPS if (useMumps) coarseSolver = Teuchos::rcp( new MumpsSolver(512, true) ); #endif double tol = max(relativeTol * energyError, minTol); int maxIters = gmgMaxIterations; BCPtr zeroBCs = bc->copyImposingZero(); gmgSolver = new GMGSolver(zeroBCs, k0Mesh, graphNorm, mesh, solution->getDofInterpreter(), solution->getPartitionMap(), maxIters, tol, coarseSolver, useStaticCondensation); gmgSolver->setAztecOutput(AztecOutputLevel); gmgSolver->setUseDiagonalScaling(useDiagonalScaling); fineSolver = Teuchos::rcp( gmgSolver ); } solution->solve(fineSolver); solution->reportTimings(); if (useGMGSolver) gmgSolver->gmgOperator()->reportTimings(); #ifdef HAVE_EPETRAEXT_HDF5 exporter.exportSolution(solution,varFactory,refIndex+1); #endif } double energyErrorTotal = solution->energyErrorTotal(); GlobalIndexType numFluxDofs = mesh->numFluxDofs(); GlobalIndexType numGlobalDofs = mesh->numGlobalDofs(); if (rank==0) { cout << "Final mesh has " << mesh->numActiveElements() << " elements and " << numFluxDofs << " trace dofs ("; cout << numGlobalDofs << " total dofs, including fields).\n"; cout << "Final energy error: " << energyErrorTotal << endl; } #ifdef HAVE_EPETRAEXT_HDF5 exporter.exportSolution(solution,varFactory,0); #endif if (!use3D) { GnuPlotUtil::writeComputationalMeshSkeleton("poissonRefinedMesh", mesh, true); } coarseSolver = Teuchos::rcp((Solver*) NULL); // without this when useMumps = true and running on one rank, we see a crash on exit, which may have to do with MPI being finalized before coarseSolver is deleted. return 0; }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI Teuchos::GlobalMPISession mpiSession(&argc, &argv,0); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif int commRank = Teuchos::GlobalMPISession::getRank(); Comm.Barrier(); // set breakpoint here to allow debugger attachment to other MPI processes than the one you automatically attached to. Teuchos::CommandLineProcessor cmdp(false,true); // false: don't throw exceptions; true: do return errors for unrecognized options // problem parameters: int spaceDim = 2; double epsilon = 1e-2; int numRefs = 0; int k = 2, delta_k = 2; int numXElems = 1; bool useConformingTraces = true; string solverChoice = "KLU"; string coarseSolverChoice = "KLU"; // often this beats SuperLU_Dist as coarse solver (true on BG/Q with 6000 3D elements on 256 ranks) double solverTolerance = 1e-6; string norm = "CoupledRobust"; cmdp.setOption("spaceDim", &spaceDim, "spatial dimension"); cmdp.setOption("polyOrder",&k,"polynomial order for field variable u"); cmdp.setOption("delta_k", &delta_k, "test space polynomial order enrichment"); cmdp.setOption("numRefs",&numRefs,"number of refinements"); cmdp.setOption("numXElems",&numXElems,"number of elements in x direction"); cmdp.setOption("epsilon", &epsilon, "epsilon"); cmdp.setOption("norm", &norm, "norm"); cmdp.setOption("conformingTraces", "nonconformingTraces", &useConformingTraces, "use conforming traces"); cmdp.setOption("coarseSolver", &coarseSolverChoice, "KLU, SuperLU"); cmdp.setOption("solver", &solverChoice, "KLU, SuperLU, MUMPS, GMG-Direct, GMG-ILU, GMG-IC"); cmdp.setOption("solverTolerance", &solverTolerance, "iterative solver tolerance"); if (cmdp.parse(argc,argv) != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) { #ifdef HAVE_MPI MPI_Finalize(); #endif return -1; } FunctionPtr beta; FunctionPtr beta_x = Function::constant(1); FunctionPtr beta_y = Function::constant(2); FunctionPtr beta_z = Function::constant(3); if (spaceDim == 1) beta = beta_x; else if (spaceDim == 2) beta = Function::vectorize(beta_x, beta_y); else if (spaceDim == 3) beta = Function::vectorize(beta_x, beta_y, beta_z); ConvectionDiffusionFormulation form(spaceDim, useConformingTraces, beta, epsilon); // Define right hand side RHSPtr rhs = RHS::rhs(); // Set up boundary conditions BCPtr bc = BC::bc(); VarPtr uhat = form.uhat(); VarPtr tc = form.tc(); SpatialFilterPtr inflowX = SpatialFilter::matchingX(-1); SpatialFilterPtr inflowY = SpatialFilter::matchingY(-1); SpatialFilterPtr inflowZ = SpatialFilter::matchingZ(-1); SpatialFilterPtr outflowX = SpatialFilter::matchingX(1); SpatialFilterPtr outflowY = SpatialFilter::matchingY(1); SpatialFilterPtr outflowZ = SpatialFilter::matchingZ(1); FunctionPtr zero = Function::zero(); FunctionPtr one = Function::constant(1); FunctionPtr x = Function::xn(1); FunctionPtr y = Function::yn(1); FunctionPtr z = Function::zn(1); if (spaceDim == 1) { bc->addDirichlet(tc, inflowX, -one); bc->addDirichlet(uhat, outflowX, zero); } if (spaceDim == 2) { bc->addDirichlet(tc, inflowX, -1*.5*(one-y)); bc->addDirichlet(uhat, outflowX, zero); bc->addDirichlet(tc, inflowY, -2*.5*(one-x)); bc->addDirichlet(uhat, outflowY, zero); } if (spaceDim == 3) { bc->addDirichlet(tc, inflowX, -1*.25*(one-y)*(one-z)); bc->addDirichlet(uhat, outflowX, zero); bc->addDirichlet(tc, inflowY, -2*.25*(one-x)*(one-z)); bc->addDirichlet(uhat, outflowY, zero); bc->addDirichlet(tc, inflowZ, -3*.25*(one-x)*(one-y)); bc->addDirichlet(uhat, outflowZ, zero); } // Build mesh vector<double> x0 = vector<double>(spaceDim,-1.0); double width = 2.0; vector<double> dimensions; vector<int> elementCounts; for (int d=0; d<spaceDim; d++) { dimensions.push_back(width); elementCounts.push_back(numXElems); } MeshPtr mesh = MeshFactory::rectilinearMesh(form.bf(), dimensions, elementCounts, k+1, delta_k, x0); MeshPtr k0Mesh = Teuchos::rcp( new Mesh (mesh->getTopology()->deepCopy(), form.bf(), 1, delta_k) ); mesh->registerObserver(k0Mesh); // Set up solution SolutionPtr soln = Solution::solution(form.bf(), mesh, bc, rhs, form.ip(norm)); double threshold = 0.20; RefinementStrategy refStrategy(soln, threshold); ostringstream refName; refName << "confusion" << spaceDim << "D_" << norm << "_" << epsilon << "_k" << k << "_" << solverChoice; // HDF5Exporter exporter(mesh,refName.str()); Teuchos::RCP<Time> solverTime = Teuchos::TimeMonitor::getNewCounter("Solve Time"); if (commRank == 0) Solver::printAvailableSolversReport(); map<string, SolverPtr> solvers; solvers["KLU"] = Solver::getSolver(Solver::KLU, true); SolverPtr superluSolver = Solver::getSolver(Solver::SuperLUDist, true); solvers["SuperLU"] = superluSolver; int maxIters = 2000; bool useStaticCondensation = false; int azOutput = 20; // print residual every 20 CG iterations ofstream dataFile(refName.str()+".txt"); dataFile << "ref\t " << "elements\t " << "dofs\t " << "error\t " << "solvetime\t" << "iterations\t " << endl; for (int refIndex=0; refIndex <= numRefs; refIndex++) { solverTime->start(true); Teuchos::RCP<GMGSolver> gmgSolver; if (solverChoice[0] == 'G') { gmgSolver = Teuchos::rcp( new GMGSolver(soln, k0Mesh, maxIters, solverTolerance, solvers[coarseSolverChoice], useStaticCondensation)); gmgSolver->setAztecOutput(azOutput); if (solverChoice == "GMG-Direct") gmgSolver->gmgOperator().setSchwarzFactorizationType(GMGOperator::Direct); if (solverChoice == "GMG-ILU") gmgSolver->gmgOperator().setSchwarzFactorizationType(GMGOperator::ILU); if (solverChoice == "GMG-IC") gmgSolver->gmgOperator().setSchwarzFactorizationType(GMGOperator::IC); soln->solve(gmgSolver); } else soln->condensedSolve(solvers[solverChoice]); double solveTime = solverTime->stop(); double energyError = soln->energyErrorTotal(); if (commRank == 0) { // if (refIndex > 0) // refStrategy.printRefinementStatistics(refIndex-1); if (solverChoice[0] == 'G') { cout << "Refinement: " << refIndex << " \tElements: " << mesh->numActiveElements() << " \tDOFs: " << mesh->numGlobalDofs() << " \tEnergy Error: " << energyError << " \tSolve Time: " << solveTime << " \tIteration Count: " << gmgSolver->iterationCount() << endl; dataFile << refIndex << " " << mesh->numActiveElements() << " " << mesh->numGlobalDofs() << " " << energyError << " " << solveTime << " " << gmgSolver->iterationCount() << endl; } else { cout << "Refinement: " << refIndex << " \tElements: " << mesh->numActiveElements() << " \tDOFs: " << mesh->numGlobalDofs() << " \tEnergy Error: " << energyError << " \tSolve Time: " << solveTime << endl; dataFile << refIndex << " " << mesh->numActiveElements() << " " << mesh->numGlobalDofs() << " " << energyError << " " << solveTime << endl; } } // exporter.exportSolution(soln, refIndex); if (refIndex != numRefs) refStrategy.refine(); } dataFile.close(); return 0; }