/** \brief Function that is called to build the preconditioner
  *        for the linear operator that is passed in.
  */
LinearOp DiagonallyScaledPreconditionerFactory::buildPreconditionerOperator(LinearOp & lo,PreconditionerState & state) const
{
   using Teuchos::RCP;
   using Teuchos::rcp_dynamic_cast;
   Teko_DEBUG_SCOPE("DiagonallyScaledPreconditionerFactory::buildPreconditionerOperator",10);

   TEST_FOR_EXCEPTION(invFactory_==Teuchos::null,std::runtime_error,
                      "ERROR: Teko::DiagonallyScaledPreconditionerFactory::buildPreconditionerOperator requires that an "
                   << "inverse factory has been set. Currently it is null!");

   // get diagonal matrix
   LinearOp invD = getInvDiagonalOp(lo,Teko::AbsRowSum);

   // M = A * invD
   ModifiableLinearOp & M = state.getModifiableOp("op_M");
   if(scalingType_==COLUMN_SCALING)
      M = explicitMultiply(lo,invD,M);
   else
      M = explicitMultiply(invD,lo,M);

   // build inverse operator
   ModifiableLinearOp & invM = state.getModifiableOp("op_invM");
   if(invM==Teuchos::null)
      invM = buildInverse(*invFactory_,M);
   else
      rebuildInverse(*invFactory_,M,invM);

   // return invD * invM
   if(scalingType_==COLUMN_SCALING)
      return multiply(invD,invM.getConst());
   else
      return multiply(invM.getConst(),invD);
}
コード例 #2
0
/** \brief Function that is called to build the preconditioner
  *        for the linear operator that is passed in.
  */
LinearOp IterativePreconditionerFactory::buildPreconditionerOperator(LinearOp & lo,PreconditionerState & state) const
{
   TEUCHOS_TEST_FOR_EXCEPTION(precFactory_==Teuchos::null,std::runtime_error,
                      "ERROR: Teko::IterativePreconditionerFactory::buildPreconditionerOperator requires that a "
                   << "preconditioner factory has been set. Currently it is null!");

   // build user specified preconditioner
   ModifiableLinearOp & invP = state.getModifiableOp("prec");
   if(invP==Teuchos::null)
      invP = Teko::buildInverse(*precFactory_,lo);
   else
      Teko::rebuildInverse(*precFactory_,lo,invP);

   // // no repititions are required
   // if(correctionNum_==0) return invP;

   // now build correction operator
   LinearOp I = Thyra::identity(lo->range(),"I");
   LinearOp AiP = multiply(lo,invP.getConst(),"AiP");
   LinearOp correction = add(I,scale(-1.0,AiP)); // I - A * iPA

   LinearOp resMap = I; // will map r_n to r_{n+1}
   for(unsigned int i=0;i<correctionNum_;i++) 
      resMap = add(I,multiply(resMap,correction)); // resMap = I + resMap*(I-A*iP)
   
   // iP = (I-A*iP)^{correctionNum}
   return multiply(invP.getConst(),resMap);
}