/** \brief Pass in an already constructed inverse operator. Update * the inverse operator based on the new source operator. * * Pass in an already constructed inverse operator. Update * the inverse operator based on the new source operator. * * \params[in] source Source operator to be inverted. * \params[in,out] dest Pre constructed inverse operator to be * rebuilt using the <code>source</code> * object. */ void PreconditionerInverseFactory::rebuildInverse(const LinearOp & source,InverseLinearOp & dest) const { Teko_DEBUG_MSG("BEGIN PreconditionerInverseFactory::rebuildInverse",10); RCP<Thyra::PreconditionerBase<double> > prec = Teuchos::rcp_dynamic_cast<Teko::PreconditionerLinearOp<double> >(dest)->getNonconstPreconditioner(); precFactory_->initializePrec(Thyra::defaultLinearOpSource(source),&*prec); Teko_DEBUG_MSG("END PreconditionerInverseFactory::rebuildInverse",10); }
/** returns an (approximate) inverse of the diagonal blocks of A * where A is closely related to the original source for invD0 and invD1 */ void InvFactoryDiagStrategy::getInvD(const BlockedLinearOp & A,BlockPreconditionerState & state,std::vector<LinearOp> & invDiag) const { Teko_DEBUG_SCOPE("InvFactoryDiagStrategy::getInvD",10); // loop over diagonals, build an inverse operator for each int diagCnt = A->productRange()->numBlocks(); int invCnt = invDiagFact_.size(); Teko_DEBUG_MSG("# diags = " << diagCnt << ", # inverses = " << invCnt,6); const std::string opPrefix = "JacobiDiagOp"; if(diagCnt<=invCnt) { for(int i=0;i<diagCnt;i++) invDiag.push_back(buildInverse(*invDiagFact_[i],getBlock(i,i,A),state,opPrefix,i)); } else { for(int i=0;i<invCnt;i++) invDiag.push_back(buildInverse(*invDiagFact_[i],getBlock(i,i,A),state,opPrefix,i)); for(int i=invCnt;i<diagCnt;i++) invDiag.push_back(buildInverse(*defaultInvFact_,getBlock(i,i,A),state,opPrefix,i)); } }
LinearOp ModALPreconditionerFactory::buildPreconditionerOperator(BlockedLinearOp & alOp, BlockPreconditionerState & state) const { Teko_DEBUG_SCOPE("ModALPreconditionerFactory::buildPreconditionerOperator()", 10); Teko_DEBUG_EXPR(Teuchos::Time timer("")); Teko_DEBUG_EXPR(Teuchos::Time totalTimer("")); Teko_DEBUG_EXPR(totalTimer.start()); // Only for 2D or 3D problems. int dim = blockRowCount(alOp) - 1; TEUCHOS_ASSERT(dim == 2 || dim == 3); // Build what is necessary for the state object. Teko_DEBUG_EXPR(timer.start(true)); invOpsStrategy_->buildState(alOp, state); Teko_DEBUG_EXPR(timer.stop()); Teko_DEBUG_MSG("ModALPreconditionerFactory::buildPreconditionerOperator():BuildStateTime = " << timer.totalElapsedTime(), 2); // Extract inverse operators from strategy Teko_DEBUG_EXPR(timer.start(true)); LinearOp invA11p = invOpsStrategy_->getInvA11p(state); LinearOp invA22p = invOpsStrategy_->getInvA22p(state); LinearOp invA33p; if(dim == 3) { invA33p = invOpsStrategy_->getInvA33p(state); } // The inverse of S can be built from strategy, // or just a diagonal matrix. ModALPrecondState * modALState = dynamic_cast<ModALPrecondState*>(&state); TEUCHOS_ASSERT(modALState != NULL); LinearOp invS; if(modALState->isStabilized_) { invS = invOpsStrategy_->getInvS(state); } else { invS = scale(modALState->gamma_, modALState->invPressureMassMatrix_); } Teko_DEBUG_EXPR(timer.stop()); Teko_DEBUG_MSG("ModALPrecFact::buildPreconditionerOperator(): GetInvTime = " << timer.totalElapsedTime(), 2); // Build diagonal operations. std::vector<LinearOp> invDiag; invDiag.resize(dim + 1); invDiag[0] = invA11p; invDiag[1] = invA22p; if(dim == 2) { invDiag[2] = scale(-1.0, invS); } else if(dim == 3) { invDiag[2] = invA33p; invDiag[3] = scale(-1.0, invS); } // Get the upper triangular matrix. BlockedLinearOp U = getUpperTriBlocks(alOp); Teko_DEBUG_EXPR(totalTimer.stop()); Teko_DEBUG_MSG("ModALPrecFact::buildPreconditionerOperator TotalTime = " << totalTimer.totalElapsedTime(), 2); // Create the preconditioner return createBlockUpperTriInverseOp(U, invDiag, "Modified AL preconditioner-Upper"); }