Teko Version of the Day
Teko_LU2x2DiagonalStrategy.cpp
00001 /*
00002 // @HEADER
00003 // 
00004 // ***********************************************************************
00005 // 
00006 //      Teko: A package for block and physics based preconditioning
00007 //                  Copyright 2010 Sandia Corporation 
00008 //  
00009 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00010 // the U.S. Government retains certain rights in this software.
00011 //  
00012 // Redistribution and use in source and binary forms, with or without
00013 // modification, are permitted provided that the following conditions are
00014 // met:
00015 //  
00016 // 1. Redistributions of source code must retain the above copyright
00017 // notice, this list of conditions and the following disclaimer.
00018 //  
00019 // 2. Redistributions in binary form must reproduce the above copyright
00020 // notice, this list of conditions and the following disclaimer in the
00021 // documentation and/or other materials provided with the distribution.
00022 //  
00023 // 3. Neither the name of the Corporation nor the names of the
00024 // contributors may be used to endorse or promote products derived from
00025 // this software without specific prior written permission. 
00026 //  
00027 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00028 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00029 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00030 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00031 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00032 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00033 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00034 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00035 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
00036 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00037 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00038 //  
00039 // Questions? Contact Eric C. Cyr (eccyr@sandia.gov)
00040 // 
00041 // ***********************************************************************
00042 // 
00043 // @HEADER
00044 
00045 */
00046 
00047 #include "Teko_LU2x2DiagonalStrategy.hpp"
00048 
00049 #include "Teuchos_TimeMonitor.hpp"
00050 
00051 namespace Teko {
00052 
00053 using Teuchos::TimeMonitor;
00054 
00055 Teuchos::RCP<Teuchos::Time> LU2x2DiagonalStrategy::initTimer_;
00056 Teuchos::RCP<Teuchos::Time> LU2x2DiagonalStrategy::invSTimer_;
00057 Teuchos::RCP<Teuchos::Time> LU2x2DiagonalStrategy::invA00Timer_;
00058 Teuchos::RCP<Teuchos::Time> LU2x2DiagonalStrategy::opsTimer_;
00059 
00060 void LU2x2DiagonalStrategy::buildTimers()
00061 {
00062    if(initTimer_==Teuchos::null)
00063       initTimer_ = TimeMonitor::getNewTimer("LU2x2DiagonalStrategy::initializePrec");
00064 
00065    if(invSTimer_==Teuchos::null)
00066       invSTimer_ = TimeMonitor::getNewTimer("LU2x2DiagonalStrategy::initializePrec invS");
00067 
00068    if(invA00Timer_==Teuchos::null)
00069       invA00Timer_ = TimeMonitor::getNewTimer("LU2x2DiagonalStrategy::initializePrec invA00");
00070 
00071    if(opsTimer_==Teuchos::null)
00072       opsTimer_ = TimeMonitor::getNewTimer("LU2x2DiagonalStrategy::initializePrec buildOps");
00073 }
00074 
00075 LU2x2DiagonalStrategy::LU2x2DiagonalStrategy() 
00076    : a00InverseType_(Diagonal)
00077 { 
00078    buildTimers();
00079 }
00080 
00082 LU2x2DiagonalStrategy::LU2x2DiagonalStrategy(const Teuchos::RCP<InverseFactory> & invFA,
00083                                              const Teuchos::RCP<InverseFactory> & invS)
00084    : invFactoryA00_(invFA), invFactoryS_(invS), a00InverseType_(Diagonal)
00085 {
00086    buildTimers();
00087 }
00088 
00090 const Teko::LinearOp
00091 LU2x2DiagonalStrategy::getHatInvA00(const Teko::BlockedLinearOp & A,BlockPreconditionerState & state) const
00092 {
00093    initializeState(A,state);
00094 
00095    return state.getModifiableOp("invA00");
00096 }
00097 
00099 const Teko::LinearOp
00100 LU2x2DiagonalStrategy::getTildeInvA00(const Teko::BlockedLinearOp & A,BlockPreconditionerState & state) const
00101 {
00102    initializeState(A,state);
00103 
00104    return state.getModifiableOp("invA00");
00105 }
00106 
00108 const Teko::LinearOp
00109 LU2x2DiagonalStrategy::getInvS(const Teko::BlockedLinearOp & A,BlockPreconditionerState & state) const
00110 {
00111    initializeState(A,state);
00112 
00113    return state.getModifiableOp("invS");
00114 }
00115 
00116 void LU2x2DiagonalStrategy::initializeState(const Teko::BlockedLinearOp & A,BlockPreconditionerState & state) const
00117 {
00118    Teko_DEBUG_SCOPE("LU2x2DiagonalStrategy::initializeState",10);
00119 
00120    // no work to be done
00121    if(state.isInitialized())
00122       return;
00123 
00124    Teuchos::TimeMonitor timer(*initTimer_,true);
00125 
00126    // extract sub blocks
00127    LinearOp A00 = Teko::getBlock(0,0,A);
00128    LinearOp A01 = Teko::getBlock(0,1,A);
00129    LinearOp A10 = Teko::getBlock(1,0,A);
00130    LinearOp A11 = Teko::getBlock(1,1,A);
00131 
00132    // build the Schur complement
00134    ModifiableLinearOp & S = state.getModifiableOp("S");
00135    {
00136       Teko_DEBUG_SCOPE("Building S",5);
00137       Teuchos::TimeMonitor timer(*opsTimer_,true);
00138 
00139       LinearOp diagA00 = getInvDiagonalOp(A00,a00InverseType_);
00140    
00141       // build Schur-complement
00142       ModifiableLinearOp & triple = state.getModifiableOp("triple");
00143       triple = explicitMultiply(A10,diagA00,A01,triple);
00144       S = explicitAdd(scale(-1.0,A11),triple,S);
00145    }
00146 
00147    // build inverse S
00149    {
00150       Teko_DEBUG_SCOPE("Building inverse(S)",5);
00151       Teuchos::TimeMonitor timer(*invSTimer_,true);
00152 
00153       ModifiableLinearOp & invS = state.getModifiableOp("invS"); 
00154       if(invS==Teuchos::null)
00155          invS = buildInverse(*invFactoryS_,S);
00156       else
00157          rebuildInverse(*invFactoryS_,S,invS);
00158    }
00159 
00160    // build inverse A00
00162    {
00163       Teko_DEBUG_SCOPE("Building inverse(A00)",5);
00164       Teuchos::TimeMonitor timer(*invA00Timer_,true);
00165 
00166       ModifiableLinearOp & invA00 = state.getModifiableOp("invA00"); 
00167       *getOutputStream() << "(LU2x2) invA00 pointer = " << invA00 << std::endl;
00168       if(invA00==Teuchos::null)
00169          invA00 = buildInverse(*invFactoryA00_,A00);
00170       else
00171          rebuildInverse(*invFactoryA00_,A00,invA00);
00172    }
00173 
00174    // mark state as initialized
00175    state.setInitialized(true);
00176 }
00177 
00189 void LU2x2DiagonalStrategy::initializeFromParameterList(const Teuchos::ParameterList & pl,
00190                                                         const InverseLibrary & invLib)
00191 {
00192    Teko_DEBUG_SCOPE("LU2x2DiagonalStrategy::initializeFromParameterList",10);
00193 
00194    std::string invStr="Amesos", invA00Str="", invSStr="";
00195 
00196    // "parse" the parameter list
00197    if(pl.isParameter("Inverse Type"))
00198       invStr = pl.get<std::string>("Inverse Type");
00199    if(pl.isParameter("Inverse A00 Type"))
00200       invA00Str = pl.get<std::string>("Inverse A00 Type");
00201    if(pl.isParameter("Inverse Schur Type"))
00202       invSStr = pl.get<std::string>("Inverse Schur Type");
00203    if(pl.isParameter("Diagonal Type")) {
00204       std::string massInverseStr = pl.get<std::string>("Diagonal Type");
00205 
00206       // build inverse types
00207       a00InverseType_ = getDiagonalType(massInverseStr);
00208    }
00209 
00210    // set defaults as needed
00211    if(invA00Str=="") invA00Str = invStr;
00212    if(invSStr=="") invSStr = invStr;
00213 
00214    Teko_DEBUG_MSG_BEGIN(5)
00215       DEBUG_STREAM << "LU2x2 Diagonal Strategy Parameters: " << std::endl;
00216       DEBUG_STREAM << "   inv type   = \"" << invStr  << "\"" << std::endl;
00217       DEBUG_STREAM << "   inv A00 type = \"" << invA00Str << "\"" << std::endl;
00218       DEBUG_STREAM << "   inv S type = \"" << invSStr << "\"" << std::endl;
00219       DEBUG_STREAM << "LU2x2 Diagonal Strategy Parameter list: " << std::endl;
00220       pl.print(DEBUG_STREAM);
00221    Teko_DEBUG_MSG_END()
00222 
00223    // build velocity inverse factory
00224    invFactoryA00_ = invLib.getInverseFactory(invA00Str);
00225  
00226    if(invA00Str==invSStr)
00227       invFactoryS_ = invFactoryA00_;
00228    else
00229       invFactoryS_ = invLib.getInverseFactory(invSStr);
00230 }
00231 } // end namespace Teko
 All Classes Files Functions Variables