PlayaILUKPreconditionerFactory.hpp

00001 /* @HEADER@ */
00002 //   
00003 /* @HEADER@ */
00004 
00005 #ifndef PLAYA_ILUKPRECONDITIONERFACTORY_HPP
00006 #define PLAYA_ILUKPRECONDITIONERFACTORY_HPP
00007 
00008 #include "PlayaDefs.hpp"
00009 #include "PlayaPreconditionerFactoryBase.hpp"
00010 #include "PlayaLinearOperatorDecl.hpp"
00011 #include "Teuchos_ParameterList.hpp"
00012 #include "PlayaILUFactorizableOp.hpp"
00013 #include "PlayaLinearSolverBaseDecl.hpp"
00014 
00015 namespace Playa
00016 {
00017   using namespace Teuchos;
00018 
00022   template <class Scalar>
00023   class ILUKPreconditionerFactory
00024     : public PreconditionerFactoryBase<Scalar>
00025   {
00026   public:
00028     ILUKPreconditionerFactory(const ParameterList& params)
00029       : fillLevels_(1),
00030         overlapFill_(0),
00031         relaxationValue_(0.0),
00032         relativeThreshold_(1.0),
00033         absoluteThreshold_(0.0),
00034         leftOrRight_(Right)
00035     {
00036       LinearSolverBase<Scalar>::template setParameter<int>(params, &fillLevels_, 
00037                                                   "Graph Fill");
00038 
00039       LinearSolverBase<Scalar>::template setParameter<int>(params, &overlapFill_, 
00040                                                   "Overlap");
00041 
00042       LinearSolverBase<Scalar>::template setParameter<double>(params, &relaxationValue_, 
00043                                                      "Relaxation");
00044 
00045       LinearSolverBase<Scalar>::template setParameter<double>(params, &absoluteThreshold_, 
00046                                                      "Absolute Threshold");
00047 
00048       LinearSolverBase<Scalar>::template setParameter<double>(params, &relativeThreshold_, 
00049                                                      "Relative Threshold");
00050 
00051       bool isLeft = false;
00052 
00053       LinearSolverBase<Scalar>::template setParameter<bool>(params, &isLeft, "Left");
00054 
00055       if (isLeft) leftOrRight_ = Left;
00056       
00057     }
00058 
00059 
00061     virtual ~ILUKPreconditionerFactory(){;}
00062 
00063     
00065     virtual Preconditioner <Scalar>
00066     createPreconditioner(const LinearOperator<Scalar>& A) const 
00067     {
00068       /* In order for ILU factorization to work, the operator A must
00069        * implement the ILUFactorizableOp interface. We cast A's pointer
00070        * to a ILUFactorizableOp ptr. If the cast fails, throw a spoke. */
00071       
00072       const ILUFactorizableOp<Scalar>* fop 
00073         = dynamic_cast<const ILUFactorizableOp<Scalar>*>(A.ptr().get());
00074 
00075       TEUCHOS_TEST_FOR_EXCEPTION(fop==0, std::runtime_error,
00076                          "ILUKPreconditionerFactory attempted to "
00077                          "create an ILU preconditioner for an operator type "
00078                          "that does not implement the ILUFactorizableOp "
00079                          "interface. The op is " << A.description());
00080 
00081       
00082       /* Now we can delegate the construction of the ILU factors to 
00083       * the factorizable op. */
00084       Preconditioner<Scalar> P;
00085       fop->getILUKPreconditioner(fillLevels_,
00086                                  overlapFill_,
00087                                  relaxationValue_,
00088                                  relativeThreshold_,
00089                                  absoluteThreshold_,
00090                                  leftOrRight_,
00091                                  P);
00092       /* Return the preconditioner */
00093       return P;
00094     }
00095 
00096     /* Handleable boilerplate */
00097     GET_RCP(PreconditionerFactoryBase<Scalar>);
00098   private:
00099 
00100     int fillLevels_;
00101     int overlapFill_;
00102     Scalar relaxationValue_;
00103     Scalar relativeThreshold_;
00104     Scalar absoluteThreshold_;
00105     LeftOrRight leftOrRight_;
00106   };
00107 
00108 
00109 }
00110 
00111 #endif

doxygen