IFPACK  Development
 All Classes Files Functions Variables Enumerations Friends
Ifpack_Condest.cpp
00001 /*@HEADER
00002 // ***********************************************************************
00003 //
00004 //       Ifpack: Object-Oriented Algebraic Preconditioner Package
00005 //                 Copyright (2002) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 //@HEADER
00041 */
00042 
00043 #include "Ifpack_ConfigDefs.h"
00044 #include "Ifpack_Condest.h"
00045 #include "Ifpack_CondestType.h"
00046 #include "Ifpack_Preconditioner.h"
00047 #include "Epetra_Vector.h"
00048 #include "Epetra_LinearProblem.h"
00049 #include "Epetra_Map.h"
00050 #include "Epetra_RowMatrix.h"
00051 #ifdef HAVE_IFPACK_AZTECOO
00052 #include "AztecOO.h"
00053 #endif
00054 
00055 double Ifpack_Condest(const Ifpack_Preconditioner& IFP,
00056               const Ifpack_CondestType CT,
00057               const int MaxIters,
00058               const double Tol,
00059               Epetra_RowMatrix* Matrix)
00060 {
00061   double ConditionNumberEstimate = -1.0;
00062 
00063   if (CT == Ifpack_Cheap) {
00064 
00065     // Create a vector with all values equal to one
00066     Epetra_Vector Ones(IFP.OperatorDomainMap());
00067     Ones.PutScalar(1.0);
00068     // Create the vector of results
00069     Epetra_Vector OnesResult(IFP.OperatorRangeMap());
00070     // Compute the effect of the solve on the vector of ones
00071     IFPACK_CHK_ERR(IFP.ApplyInverse(Ones, OnesResult)); 
00072     // Make all values non-negative
00073     IFPACK_CHK_ERR(OnesResult.Abs(OnesResult)); 
00074     // Get the maximum value across all processors
00075     IFPACK_CHK_ERR(OnesResult.MaxValue(&ConditionNumberEstimate)); 
00076 
00077   }
00078   else if (CT == Ifpack_CG) {
00079 
00080 #ifdef HAVE_IFPACK_AZTECOO
00081     if (Matrix == 0)
00082       Matrix = (Epetra_RowMatrix*)&(IFP.Matrix());
00083 
00084     Epetra_Vector LHS(IFP.OperatorDomainMap());
00085     LHS.PutScalar(0.0);
00086     Epetra_Vector RHS(IFP.OperatorRangeMap());
00087     RHS.Random();
00088     Epetra_LinearProblem Problem;
00089     Problem.SetOperator(Matrix);
00090     Problem.SetLHS(&LHS);
00091     Problem.SetRHS(&RHS);
00092 
00093     AztecOO Solver(Problem);
00094     Solver.SetAztecOption(AZ_output,AZ_none);
00095     Solver.SetAztecOption(AZ_solver,AZ_cg_condnum);
00096     Solver.Iterate(MaxIters,Tol);
00097 
00098     const double* status = Solver.GetAztecStatus();
00099     ConditionNumberEstimate = status[AZ_condnum];
00100 #endif
00101 
00102   } else if (CT == Ifpack_GMRES) {
00103 
00104 #ifdef HAVE_IFPACK_AZTECOO
00105     if (Matrix == 0)
00106       Matrix = (Epetra_RowMatrix*)&(IFP.Matrix());
00107 
00108     Epetra_Vector LHS(IFP.OperatorDomainMap());
00109     LHS.PutScalar(0.0);
00110     Epetra_Vector RHS(IFP.OperatorRangeMap());
00111     RHS.Random();
00112     Epetra_LinearProblem Problem;
00113     Problem.SetOperator(Matrix);
00114     Problem.SetLHS(&LHS);
00115     Problem.SetRHS(&RHS);
00116 
00117     AztecOO Solver(Problem);
00118     Solver.SetAztecOption(AZ_solver,AZ_gmres_condnum);
00119     Solver.SetAztecOption(AZ_output,AZ_none);
00120     // the following can be problematic for large problems,
00121     // but any restart would destroy useful information about
00122     // the condition number.
00123     Solver.SetAztecOption(AZ_kspace,MaxIters);
00124     Solver.Iterate(MaxIters,Tol);
00125 
00126     const double* status = Solver.GetAztecStatus();
00127     ConditionNumberEstimate = status[AZ_condnum];
00128 #endif
00129   }
00130 
00131   return(ConditionNumberEstimate);
00132 
00133 }
 All Classes Files Functions Variables Enumerations Friends