/** \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); }
/** \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); }