61 #include "Trilinos_Util.h"
62 #include "Ifpack_IlukGraph.h"
63 #include "Ifpack_CrsRiluk.h"
67 int Maxiter,
double Tolerance,
68 double *residual,
bool verbose);
70 int main(
int argc,
char *argv[]) {
73 MPI_Init(&argc,&argv);
81 int MyPID = Comm.
MyPID();
85 if (MyPID==0) verbose =
true;
87 if(argc < 2 && verbose) {
88 cerr <<
"Usage: " << argv[0]
89 <<
" HPC_filename [level_fill [level_overlap [absolute_threshold [ relative_threshold]]]]" << endl
91 <<
"HB_filename - filename and path of a Harwell-Boeing data set" << endl
92 <<
"level_fill - The amount of fill to use for ILU(k) preconditioner (default 0)" << endl
93 <<
"level_overlap - The amount of overlap used for overlapping Schwarz subdomains (default 0)" << endl
94 <<
"absolute_threshold - The minimum value to place on the diagonal prior to factorization (default 0.0)" << endl
95 <<
"relative_threshold - The relative amount to perturb the diagonal prior to factorization (default 1.0)" << endl << endl
96 <<
"To specify a non-default value for one of these parameters, you must specify all" << endl
97 <<
" preceding values but not any subsequent parameters. Example:" << endl
98 <<
"ifpackHpcSerialMsr.exe mymatrix.hpc 1 - loads mymatrix.hpc, uses level fill of one, all other values are defaults" << endl
106 if (MyPID==0) cin >> tmp;
115 Trilinos_Util_ReadHpc2Epetra(argv[1], Comm, map, A, x, b, xexact);
117 bool smallProblem =
false;
121 cout <<
"Original Matrix = " << endl << *A << endl;
130 cout <<
"Inf norm of Original Matrix = " << A->
NormInf() << endl
131 <<
"Inf norm of Original RHS = " << normb << endl;
136 double reduceInitTime = ReductionTimer.
ElapsedTime();
139 double reduceAnalyzeTime = ReductionTimer.
ElapsedTime() - reduceInitTime;
142 cout <<
"Singletons found" << endl;
144 cout <<
"Singletons not found" << endl;
149 double reduceConstructTime = ReductionTimer.
ElapsedTime() - reduceInitTime;
151 double totalReduceTime = ReductionTimer.
ElapsedTime();
154 cout <<
"\n\n****************************************************" << endl
155 <<
" Reduction init time (sec) = " << reduceInitTime<< endl
156 <<
" Reduction Analyze time (sec) = " << reduceAnalyzeTime << endl
157 <<
" Construct Reduced Problem time (sec) = " << reduceConstructTime << endl
158 <<
" Reduction Total time (sec) = " << totalReduceTime << endl<< endl;
170 cout <<
" Reduced Matrix = " << endl << *Ap << endl
171 <<
" LHS before sol = " << endl << *xp << endl
172 <<
" RHS = " << endl << *bp << endl;
176 double elapsed_time, total_flops, MFLOPs;
180 if (argc > 2) LevelFill = atoi(argv[2]);
181 if (verbose) cout <<
"Using Level Fill = " << LevelFill << endl;
183 if (argc > 3) Overlap = atoi(argv[3]);
184 if (verbose) cout <<
"Using Level Overlap = " << Overlap << endl;
185 double Athresh = 0.0;
186 if (argc > 4) Athresh = atof(argv[4]);
187 if (verbose) cout <<
"Using Absolute Threshold Value of = " << Athresh << endl;
189 double Rthresh = 1.0;
190 if (argc > 5) Rthresh = atof(argv[5]);
191 if (verbose) cout <<
"Using Relative Threshold Value of = " << Rthresh << endl;
193 Ifpack_IlukGraph * IlukGraph = 0;
194 Ifpack_CrsRiluk * ILUK = 0;
198 IlukGraph =
new Ifpack_IlukGraph(Ap->
Graph(), LevelFill, Overlap);
199 assert(IlukGraph->ConstructFilledGraph()==0);
201 if (verbose) cout <<
"Time to construct ILUK graph = " << elapsed_time << endl;
207 ILUK =
new Ifpack_CrsRiluk(*IlukGraph);
208 ILUK->SetFlopCounter(fact_counter);
209 ILUK->SetAbsoluteThreshold(Athresh);
210 ILUK->SetRelativeThreshold(Rthresh);
212 int initerr = ILUK->InitValues(*Ap);
214 cout << endl << Comm << endl <<
" InitValues error = " << initerr;
215 if (initerr==1) cout <<
" Zero diagonal found, warning error only";
216 cout << endl << endl;
218 assert(ILUK->Factor()==0);
220 total_flops = ILUK->Flops();
221 MFLOPs = total_flops/elapsed_time/1000000.0;
222 if (verbose) cout <<
"Time to compute preconditioner values = "
223 << elapsed_time << endl
224 <<
"MFLOPS for Factorization = " << MFLOPs << endl;
227 ILUK->Condest(
false, Condest);
229 if (verbose) cout <<
"Condition number estimate for this preconditioner = " << Condest << endl;
232 double Tolerance = 1.0E-8;
238 if (ILUK!=0) ILUK->SetFlopCounter(*Ap);
242 double normreducedb, normreduceda;
246 cout <<
"Inf norm of Reduced Matrix = " << normreduceda << endl
247 <<
"Inf norm of Reduced RHS = " << normreducedb << endl;
250 BiCGSTAB(*Ap, *xp, *bp, ILUK, Maxiter, Tolerance, &residual, verbose);
253 total_flops = counter.
Flops();
254 MFLOPs = total_flops/elapsed_time/1000000.0;
255 if (verbose) cout <<
"Time to compute solution = "
256 << elapsed_time << endl
257 <<
"Number of operations in solve = " << total_flops << endl
258 <<
"MFLOPS for Solve = " << MFLOPs<< endl << endl;
263 cout <<
" Reduced LHS after sol = " << endl << *xp << endl
264 <<
" Full LHS after sol = " << endl << *x << endl
265 <<
" Full Exact LHS = " << endl << *xexact << endl;
269 resid.
Update(1.0, *x, -1.0, *xexact, 0.0);
271 resid.
Norm2(&residual);
272 double normx, normxexact;
274 xexact->
Norm2(&normxexact);
277 cout <<
"2-norm of computed solution = " << normx << endl
278 <<
"2-norm of exact solution = " << normxexact << endl
279 <<
"2-norm of difference between computed and exact solution = " << residual << endl;
281 if (verbose1 && residual>1.0e-5) {
283 cout <<
"Difference between computed and exact solution appears large..." << endl
284 <<
"Computing norm of A times this difference. If this norm is small, then matrix is singular"
287 assert(A->
Multiply(
false, resid, bdiff)==0);
288 assert(bdiff.
Norm2(&residual)==0);
290 cout <<
"2-norm of A times difference between computed and exact solution = " << residual << endl;
294 cout <<
"********************************************************" << endl
295 <<
" Solving again with 2*Ax=2*b" << endl
296 <<
"********************************************************" << endl;
304 cout <<
"Inf norm of Original Matrix = " << norma << endl
305 <<
"Inf norm of Original RHS = " << normb << endl;
306 double updateReducedProblemTime = ReductionTimer.
ElapsedTime();
309 updateReducedProblemTime = ReductionTimer.
ElapsedTime() - updateReducedProblemTime;
311 cout <<
"\n\n****************************************************" << endl
312 <<
" Update Reduced Problem time (sec) = " << updateReducedProblemTime<< endl
313 <<
"****************************************************" << endl;
322 int initerr = ILUK->InitValues(*Ap);
324 cout << endl << Comm << endl <<
" InitValues error = " << initerr;
325 if (initerr==1) cout <<
" Zero diagonal found, warning error only";
326 cout << endl << endl;
328 assert(ILUK->Factor()==0);
330 total_flops = ILUK->Flops();
331 MFLOPs = total_flops/elapsed_time/1000000.0;
332 if (verbose) cout <<
"Time to compute preconditioner values = "
333 << elapsed_time << endl
334 <<
"MFLOPS for Factorization = " << MFLOPs << endl;
336 ILUK->Condest(
false, Condest);
338 if (verbose) cout <<
"Condition number estimate for this preconditioner = " << Condest << endl;
343 cout <<
"Inf norm of Reduced Matrix = " << normreduceda << endl
344 <<
"Inf norm of Reduced RHS = " << normreducedb << endl;
346 BiCGSTAB(*Ap, *xp, *bp, ILUK, Maxiter, Tolerance, &residual, verbose);
349 total_flops = counter.
Flops();
350 MFLOPs = total_flops/elapsed_time/1000000.0;
351 if (verbose) cout <<
"Time to compute solution = "
352 << elapsed_time << endl
353 <<
"Number of operations in solve = " << total_flops << endl
354 <<
"MFLOPS for Solve = " << MFLOPs<< endl << endl;
359 cout <<
" Reduced LHS after sol = " << endl << *xp << endl
360 <<
" Full LHS after sol = " << endl << *x << endl
361 <<
" Full Exact LHS = " << endl << *xexact << endl;
363 resid.
Update(1.0, *x, -1.0, *xexact, 0.0);
365 resid.
Norm2(&residual);
367 xexact->
Norm2(&normxexact);
370 cout <<
"2-norm of computed solution = " << normx << endl
371 <<
"2-norm of exact solution = " << normxexact << endl
372 <<
"2-norm of difference between computed and exact solution = " << residual << endl;
374 if (verbose1 && residual>1.0e-5) {
376 cout <<
"Difference between computed and exact solution appears large..." << endl
377 <<
"Computing norm of A times this difference. If this norm is small, then matrix is singular"
380 assert(A->
Multiply(
false, resid, bdiff)==0);
381 assert(bdiff.
Norm2(&residual)==0);
383 cout <<
"2-norm of A times difference between computed and exact solution = " << residual << endl;
389 if (ILUK!=0)
delete ILUK;
390 if (IlukGraph!=0)
delete IlukGraph;
404 double *residual,
bool verbose) {
418 r.Update(1.0, b, -1.0);
420 double r_norm, b_norm, scaled_r_norm, rhon, rhonm1 = 1.0;
421 double alpha = 1.0, omega = 1.0, sigma;
422 double omega_num, omega_den;
425 scaled_r_norm = r_norm/b_norm;
428 if (verbose) cout <<
"Initial residual = " << r_norm
429 <<
" Scaled residual = " << scaled_r_norm << endl;
432 for (
int i=0; i<Maxiter; i++) {
434 double beta = (rhon/rhonm1) * (alpha/omega);
441 double dtemp = - beta*omega;
443 p.Update(1.0, r, dtemp, v, beta);
447 M->Solve(
false, p, phat);
451 rtilde.Dot(v,&sigma);
458 s.Update(-alpha, v, 1.0, r, 0.0);
462 M->Solve(
false, s, shat);
465 r.Dot(s, &omega_num);
466 r.Dot(r, &omega_den);
467 omega = omega_num / omega_den;
472 x.
Update(alpha, phat, omega, shat, 1.0);
473 r.Update(1.0, s, -omega);
476 scaled_r_norm = r_norm/b_norm;
479 if (verbose) cout <<
"Iter "<< i <<
" residual = " << r_norm
480 <<
" Scaled residual = " << scaled_r_norm << endl;
482 if (r_norm < Tolerance)
break;
498 cout <<
"Full System characteristics:" << endl << endl
499 <<
" Dimension = " << fnrows << endl
500 <<
" Number of nonzeros = " <<fnnz << endl
501 <<
" Maximum Number of Row Entries = " << fmaxentries << endl << endl
502 <<
"Reduced System characteristics:" << endl << endl
506 <<
"Singleton information: " << endl
507 <<
" Total number of singletons = " << filter.
NumSingletons() << endl
508 <<
" Number of rows with single entries = " << filter.
NumRowSingletons() << endl
509 <<
" Number of columns with single entries " << endl
510 <<
" (that were not already counted as " << endl
512 <<
"Ratios: " << endl
513 <<
" Percent reduction in dimension = " << filter.
RatioOfDimensions()*100.0 << endl
514 <<
" Percent reduction in nonzero count = " << filter.
RatioOfNonzeros()*100.0 << endl << endl;
void SetFlopCounter(const Epetra_Flops &FlopCounter_in)
Set the internal Epetra_Flops() pointer.
int NumGlobalElements() const
Number of elements across all processors.
Epetra_Map: A class for partitioning vectors and matrices.
virtual const Epetra_Map & RowMatrixRowMap() const =0
Returns the Epetra_Map object associated with the rows of this matrix.
Epetra_MultiVector * GetLHS() const
Get a pointer to the left-hand-side X.
Epetra_MultiVector * GetRHS() const
Get a pointer to the right-hand-side B.
int Multiply(bool TransA, const Epetra_Vector &x, Epetra_Vector &y) const
Returns the result of a Epetra_CrsMatrix multiplied by a Epetra_Vector x in y.
double ElapsedTime(void) const
Epetra_Time elapsed time function.
int NumGlobalRows() const
Returns the number of global matrix rows.
int PutScalar(double ScalarConstant)
Initialize all values in a multi-vector with constant value.
void BiCGSTAB(Epetra_CrsMatrix &A, Epetra_Vector &x, Epetra_Vector &b, Ifpack_CrsRiluk *M, int Maxiter, double Tolerance, bool verbose)
double NormInf() const
Returns the infinity norm of the global matrix.
Epetra_Vector: A class for constructing and using dense vectors on a parallel computer.
int MyPID() const
Return my process ID.
Epetra_MpiComm: The Epetra MPI Communication Class.
virtual int NumGlobalNonzeros() const =0
Returns the number of nonzero entries in the global matrix.
int GlobalMaxNumEntries() const
Returns the maximum number of nonzero entries across all rows on all processors.
virtual int MyPID() const =0
Return my process ID.
Epetra_Time: The Epetra Timing Class.
const Epetra_Map & RowMap() const
Returns the Epetra_Map object associated with the rows of this matrix.
virtual int SumAll(double *PartialSums, double *GlobalSums, int Count) const =0
Epetra_Comm Global Sum function.
virtual int MaxNumEntries() const =0
Returns the maximum of NumMyRowEntries() over all rows.
int Scale(double ScalarValue)
Scale the current values of a multi-vector, this = ScalarValue*this.
int Statistics(const Epetra_CrsSingletonFilter &filter)
int NormInf(double *Result) const
Compute Inf-norm of each vector in multi-vector.
int NumGlobalNonzeros() const
Returns the number of nonzero entries in the global matrix.
const Epetra_Comm & Comm() const
Access function for Epetra_Comm communicator.
Epetra_SerialComm: The Epetra Serial Communication Class.
Epetra_Flops: The Epetra Floating Point Operations Class.
double Flops() const
Returns the number of floating point operations with this object and resets the count.
int Update(double ScalarA, const Epetra_MultiVector &A, double ScalarThis)
Update multi-vector values with scaled values of A, this = ScalarThis*this + ScalarA*A.
Epetra_RowMatrix * GetMatrix() const
Get a pointer to the matrix A.
void Barrier() const
Epetra_SerialComm Barrier function.
Epetra_CrsMatrix: A class for constructing and using real-valued double-precision sparse compressed r...
int Norm2(double *Result) const
Compute 2-norm of each vector in multi-vector.
int main(int argc, char *argv[])
Epetra_LinearProblem: The Epetra Linear Problem Class.
const Epetra_CrsGraph & Graph() const
Returns a reference to the Epetra_CrsGraph object associated with this matrix.
int Scale(double ScalarConstant)
Multiply all values in the matrix by a constant value (in place: A <- ScalarConstant * A)...
virtual int NumGlobalRows() const =0
Returns the number of global matrix rows.
const Epetra_BlockMap & Map() const
Returns the address of the Epetra_BlockMap for this multi-vector.