int powerMethod (double & lambda, Epetra_CrsMatrix& A, const int niters, const double tolerance, const bool verbose) { // In the power iteration, z = A*q. Thus, q must be in the domain // of A, and z must be in the range of A. The residual vector is of // course in the range of A. Epetra_Vector q (A.OperatorDomainMap ()); Epetra_Vector z (A.OperatorRangeMap ()); Epetra_Vector resid (A.OperatorRangeMap ()); Epetra_Flops* counter = A.GetFlopCounter(); if (counter != 0) { q.SetFlopCounter(A); z.SetFlopCounter(A); resid.SetFlopCounter(A); } // Initialize the starting vector z with random data. z.Random(); double normz, residual; int ierr = 1; for (int iter = 0; iter < niters; ++iter) { z.Norm2 (&normz); // normz := ||z||_2 q.Scale (1.0/normz, z); // q := z / normz A.Multiply(false, q, z); // z := A * q q.Dot(z, &lambda); // lambda := dot (q, z) // Compute the residual vector and display status output every // 100 iterations, or if we have reached the maximum number of // iterations. if (iter % 100 == 0 || iter + 1 == niters) { resid.Update (1.0, z, -lambda, q, 0.0); // resid := A*q - lambda*q resid.Norm2 (&residual); // residual := ||resid||_2 if (verbose) cout << "Iter = " << iter << " Lambda = " << lambda << " Residual of A*q - lambda*q = " << residual << endl; } if (residual < tolerance) { // We've converged! ierr = 0; break; } } return ierr; }
// ================================================ ====== ==== ==== == = // Constructor ML_Epetra::ML_RefMaxwell_11_Operator::ML_RefMaxwell_11_Operator(const Epetra_CrsMatrix& SM_Matrix, //S+M const Epetra_CrsMatrix& D0_Matrix, //T or D0 const Epetra_CrsMatrix& M0inv_Matrix, //M0^{-1} const Epetra_CrsMatrix& M1_Matrix): //M1(1) SM_Matrix_(&SM_Matrix),Addon_Matrix_(0),D0T_Matrix_(0) { Label_=new char [80]; strcpy(Label_,"ML_RefMaxwell_11_Operator"); Comm_ = &(SM_Matrix_->Comm()); DomainMap_ = &(SM_Matrix_->OperatorDomainMap()); RangeMap_ = &(SM_Matrix_->OperatorRangeMap()); /* Transpose D0 */ #ifdef MANUALLY_TRANSPOSE_D0 D0_Matrix_Transposer_= new EpetraExt::RowMatrix_Transpose((Epetra_Map*)&M0inv_Matrix.OperatorRangeMap()); D0T_Matrix_= dynamic_cast<Epetra_CrsMatrix*>( & ((*D0_Matrix_Transposer_)((Epetra_CrsMatrix&)D0_Matrix))); D0T_Matrix_= dynamic_cast<Epetra_CrsMatrix*>(ModifyEpetraMatrixColMap(*D0T_Matrix_,D0T_Matrix_Trans_,"D0T",false)); #endif /* Build the Epetra_Multi_CrsMatrix */ Addon_Matrix_=new Epetra_CrsMatrix*[5]; Addon_Matrix_[0]=Addon_Matrix_[4]=(Epetra_CrsMatrix*)&M1_Matrix; Addon_Matrix_[1]=(Epetra_CrsMatrix*)&D0_Matrix; #ifdef MANUALLY_TRANSPOSE_D0 Addon_Matrix_[3]=D0T_Matrix_; #else Addon_Matrix_[3]=(Epetra_CrsMatrix*)&D0_Matrix;//HAQ #endif Addon_Matrix_[2]=(Epetra_CrsMatrix*)&M0inv_Matrix; Addon_=new Epetra_Multi_CrsMatrix(5,Addon_Matrix_); }/*end Constructor*/
int main(int argc, char *argv[]) { MPI_Init(&argc,&argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); Epetra_MpiComm SerialComm(MPI_COMM_SELF); if (Comm.MyPID() == 0) { ParameterList GaleriList; GaleriList.set("nx", 10); GaleriList.set("ny", 10); GaleriList.set("mx", 1); GaleriList.set("my", 1); Epetra_Map* Map = CreateMap("Cartesian2D", SerialComm, GaleriList); Epetra_CrsMatrix* A = CreateCrsMatrix("Laplace2D", Map, GaleriList); Epetra_Vector LHS(A->OperatorDomainMap()); Epetra_Vector RHS(A->OperatorRangeMap()); LHS.PutScalar(0.0); RHS.Random(); Epetra_LinearProblem problem(A, &LHS, &RHS); AztecOO solver(problem); ParameterList MLList; ML_Epetra::SetDefaults("SA",MLList); MLList.set("ML output", 0); ML_Epetra::MultiLevelPreconditioner* MLPrec = new ML_Epetra::MultiLevelPreconditioner(*A, MLList); solver.SetPrecOperator(MLPrec); solver.SetAztecOption(AZ_solver, AZ_cg_condnum); solver.SetAztecOption(AZ_output, 32); solver.Iterate(500, 1e-12); // destroy the preconditioner delete MLPrec; delete A; delete Map; } MPI_Finalize(); return(0); } // main driver
int main(int argc, char *argv[]) { #ifdef HAVE_MPI MPI_Init(&argc,&argv); Epetra_MpiComm comm (MPI_COMM_WORLD); #else Epetra_SerialComm comm; #endif int MyPID = comm.MyPID(); bool verbose = false; bool verbose1 = false; // Check if we should print results to standard out if (argc > 1) { if ((argv[1][0] == '-') && (argv[1][1] == 'v')) { verbose1 = true; if (MyPID==0) verbose = true; } } if (verbose1) cout << comm << endl; // Uncomment the next three lines to debug in mpi mode //int tmp; //if (MyPID==0) cin >> tmp; //comm.Barrier(); Epetra_CrsMatrix * A; EPETRA_CHK_ERR(EpetraExt::MatlabFileToCrsMatrix("A.dat", comm, A)); Epetra_Vector x(A->OperatorDomainMap()); Epetra_Vector b(A->OperatorRangeMap()); x.Random(); A->Apply(x,b); // Generate RHS from x Epetra_Vector xx(x); // Copy x to xx for later use Epetra_LinearProblem problem(A, &x, &b); // Construct a solver object for this problem AztecOO solver(problem); solver.SetAztecOption(AZ_precond, AZ_none); if (!verbose1) solver.SetAztecOption(AZ_output, AZ_none); solver.SetAztecOption(AZ_kspace, A->NumGlobalRows()); AztecOO_Operator AOpInv(&solver, A->NumGlobalRows()); Epetra_InvOperator AInvOp(&AOpInv); EPETRA_CHK_ERR(EpetraExt::OperatorToMatlabFile("Ainv.dat", AInvOp)); comm.Barrier(); Epetra_CrsMatrix * AInv; EPETRA_CHK_ERR(EpetraExt::MatlabFileToCrsMatrix("Ainv.dat", comm, AInv)); EPETRA_CHK_ERR(AInv->Apply(b,x)); EPETRA_CHK_ERR(x.Update(1.0, xx, -1.0)); double residual = 0.0; EPETRA_CHK_ERR(x.Norm2(&residual)); if (verbose) cout << "Norm of difference between computed x and exact x = " << residual << endl; int ierr = checkValues(residual,0.0,"Norm of difference between computed A1x1 and A1x1 from file", verbose); delete A; delete AInv; #ifdef HAVE_MPI MPI_Finalize() ; #endif return(ierr); }
int main(int argc, char *argv[]) { #ifdef EPETRA_MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif Epetra_Time Time(Comm); // Create the linear problem using the class `Trilinos_Util::CrsMatrixGallery.' // Various matrix examples are supported; please refer to the // Trilinos tutorial for more details. // create Aztec stuff int proc_config[AZ_PROC_SIZE], options[AZ_OPTIONS_SIZE]; #ifdef ML_MPI /* get number of processors and the name of this processor */ AZ_set_proc_config(proc_config, MPI_COMM_WORLD); int proc = proc_config[AZ_node]; int nprocs = proc_config[AZ_N_procs]; #else AZ_set_proc_config(proc_config, AZ_NOT_MPI); int proc = 0; int nprocs = 1; #endif // read in the matrix size FILE *fp = fopen("ExampleMatrices/cantilever2D/data_matrix.txt","r"); int leng; fscanf(fp,"%d",&leng); int num_PDE_eqns=2; int N_grid_pts = leng/num_PDE_eqns; // make a linear distribution of the matrix respecting the blocks size int leng1 = leng/nprocs; int leng2 = leng-leng1*nprocs; if (proc >= leng2) { leng2 += (proc*leng1); } else { leng1++; leng2 = proc*leng1; } int N_update = leng1; int* update = new int[N_update+1]; int i; double *val=NULL; int *bindx=NULL; for (i=0; i<N_update; i++) update[i] = i+leng2; // create the Epetra_CrSMatrix Epetra_Map* StandardMap = new Epetra_Map(leng,N_update,update,0,Comm); Epetra_CrsMatrix* A = new Epetra_CrsMatrix(Copy,*StandardMap,1); AZ_input_msr_matrix("ExampleMatrices/cantilever2D/data_matrix.txt", update, &val, &bindx, N_update, proc_config); for (i=0; i<leng; i++) { int row = update[i]; A->SumIntoGlobalValues(row,1,&(val[i]),&row); A->SumIntoGlobalValues(row,bindx[i+1]-bindx[i],&(val[bindx[i]]),&(bindx[bindx[i]])); } A->TransformToLocal(); // create solution and right-hand side (MultiVectors are fine as well) Epetra_Vector* LHS = new Epetra_Vector(A->OperatorDomainMap()); Epetra_Vector* RHS = new Epetra_Vector(A->OperatorRangeMap()); LHS->Random(); RHS->Random(); // build the epetra linear problem Epetra_LinearProblem Problem(A, LHS, RHS); // Construct a solver object for this problem AztecOO solver(Problem); // =========================== begin of ML part =========================== // create a parameter list for ML options ParameterList MLList; // set defaults for classic smoothed aggregation ML_Epetra::SetDefaults("SA",MLList); MLList.set("aggregation: damping factor", 0.0); // number of relaxation sweeps MLList.set("adaptive: max sweeps", 10); // number of additional null space vectors to compute MLList.set("adaptive: num vectors",2); #if 1 ML_Epetra::MultiLevelPreconditioner* MLPrec = new ML_Epetra::MultiLevelPreconditioner(dynamic_cast<Epetra_RowMatrix&>(*A), MLList, false); // need to allocate and fill the null space (also the // default one, as in this case). This vector is no longer // needed after a call to ComputeAdaptivePreconditioner(). int NullSpaceSize = 2; vector<double> NullSpace((NullSpaceSize*A->NumMyRows())); for (i = 0 ; i < A->NumMyRows() ; ++i) { NullSpace[i] = 1.0; ++i; NullSpace[i] = 0.0; } for (i = A->NumMyRows() ; i < 2*A->NumMyRows() ; ++i) { NullSpace[i] = 0.0; ++i; NullSpace[i] = 1.0; } MLPrec->ComputeAdaptivePreconditioner(NullSpaceSize,&NullSpace[0]); #else ML_Epetra::MultiLevelPreconditioner* MLPrec = new ML_Epetra::MultiLevelPreconditioner(dynamic_cast<Epetra_RowMatrix&>(*A), MLList); #endif // tell AztecOO to use this preconditioner, then solve solver.SetPrecOperator(MLPrec); // =========================== end of ML part ============================= solver.SetAztecOption(AZ_solver, AZ_gmres); solver.SetAztecOption(AZ_output, 32); // solve with 500 iterations and 1e-12 tolerance solver.Iterate(1550, 1e-5); delete MLPrec; // compute the real residual double residual, diff; if( Comm.MyPID()==0 ) { cout << "||b-Ax||_2 = " << residual << endl; cout << "||x_exact - x||_2 = " << diff << endl; cout << "Total Time = " << Time.ElapsedTime() << endl; } #ifdef EPETRA_MPI MPI_Finalize(); #endif return(0); }