00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include "Teko_DiagnosticPreconditionerFactory.hpp"
00049
00050 #include "Teko_PreconditionerInverseFactory.hpp"
00051 #include "Teko_DiagnosticLinearOp.hpp"
00052
00053 #include "Teuchos_TimeMonitor.hpp"
00054
00055 namespace Teko {
00056
00058 DiagnosticPreconditionerFactory::DiagnosticPreconditionerFactory()
00059 : outputStream_(Teko::getOutputStream()), invFactory_(Teuchos::null), diagString_("<label me!>"), printResidual_(false)
00060 { }
00061
00065 DiagnosticPreconditionerFactory::DiagnosticPreconditionerFactory(const Teuchos::RCP<Teko::InverseFactory> & invFactory, const std::string & label,
00066 const Teuchos::RCP<std::ostream> & os,bool printResidual)
00067 : outputStream_(Teko::getOutputStream()), invFactory_(invFactory), diagString_(label), printResidual_(printResidual)
00068 {
00069 initTimers(diagString_);
00070
00071 if(os!=Teuchos::null)
00072 outputStream_ = os;
00073 }
00074
00075 DiagnosticPreconditionerFactory::~DiagnosticPreconditionerFactory()
00076 {
00077
00078 if(buildTimer_==Teuchos::null || rebuildTimer_==Teuchos::null) {
00079
00080
00081
00082 return;
00083 }
00084
00085 double initBuildTime = totalInitialBuildTime();
00086 int initBuilds = numInitialBuilds();
00087
00088 double initRebuildTime = totalRebuildTime();
00089 int initRebuilds = numRebuilds();
00090
00091 (*outputStream_) << "DiagnosticPreconditionerFactory \"" << diagString_ << "\":\n";
00092
00093
00094 (*outputStream_) << " build elapsed = " << initBuildTime << ", "
00095 << "num builds = " << initBuilds << ", ";
00096 if(initBuilds>0)
00097 (*outputStream_) << "timer/app = " << initBuildTime / double(initBuilds) << "\n";
00098 else
00099 (*outputStream_) << "timer/app = " << "none" << "\n";
00100
00101
00102 (*outputStream_) << " rebuild elapsed = " << initRebuildTime << ", "
00103 << "num rebuilds = " << initRebuilds << ", ";
00104 if(initRebuilds>0)
00105 (*outputStream_) << "timer/app = " << initRebuildTime / double(initRebuilds) << "\n";
00106 else
00107 (*outputStream_) << "timer/app = " << "none" << "\n";
00108
00109
00110 (*outputStream_) << " total elapsed = " << initRebuildTime+initBuildTime << ", "
00111 << "num rebuilds = " << initRebuilds+initBuilds << ", ";
00112 if(initBuilds+initRebuilds>0)
00113 (*outputStream_) << "timer/app = " << (initRebuildTime+initBuildTime) / double(initRebuilds+initBuilds) << std::endl;
00114 else
00115 (*outputStream_) << "timer/app = " << "none" << std::endl;
00116 }
00117
00121 LinearOp DiagnosticPreconditionerFactory::buildPreconditionerOperator(LinearOp & lo,PreconditionerState & state) const
00122 {
00123 using Teuchos::RCP;
00124 using Teuchos::rcp_dynamic_cast;
00125
00126 TEUCHOS_TEST_FOR_EXCEPTION(invFactory_==Teuchos::null,std::runtime_error,
00127 "ERROR: Teko::DiagnosticPreconditionerFactory::buildPreconditionerOperator requires that an "
00128 << "inverse factory has been set. Currently it is null!");
00129
00130 TEUCHOS_TEST_FOR_EXCEPTION(buildTimer_==Teuchos::null || rebuildTimer_==Teuchos::null,std::runtime_error,
00131 "ERROR: Teko::DiagnosticPreconditionerFactory::buildPreconditionerOperator requires that "
00132 << "the timers be initialized. Currently they are null! (label = \"" << diagString_ << "\")");
00133
00134
00135 ModifiableLinearOp & diagOp_ptr = state.getModifiableOp("diagnosticOp");
00136
00137 if(diagOp_ptr==Teuchos::null) {
00138 ModifiableLinearOp invOp;
00139 {
00140
00141 Teuchos::TimeMonitor monitor(*buildTimer_,false);
00142
00143 invOp = Teko::buildInverse(*invFactory_,lo);
00144 }
00145
00146
00147 if(printResidual_)
00148 diagOp_ptr = createDiagnosticLinearOp(outputStream_,lo,invOp,diagString_);
00149 else
00150 diagOp_ptr = createDiagnosticLinearOp(outputStream_,invOp,diagString_);
00151 }
00152 else {
00153 RCP<DiagnosticLinearOp> diagOp = rcp_dynamic_cast<DiagnosticLinearOp>(diagOp_ptr);
00154
00155
00156 if(printResidual_)
00157 diagOp->setForwardOp(lo);
00158
00159 ModifiableLinearOp invOp = diagOp->getModifiableOp();
00160 {
00161
00162 Teuchos::TimeMonitor monitor(*rebuildTimer_,false);
00163
00164 Teko::rebuildInverse(*invFactory_,lo,invOp);
00165 }
00166 }
00167
00168 return diagOp_ptr.getConst();
00169 }
00170
00174 void DiagnosticPreconditionerFactory::initializeFromParameterList(const Teuchos::ParameterList & settings)
00175 {
00176 TEUCHOS_TEST_FOR_EXCEPTION(not settings.isParameter("Inverse Factory"),std::runtime_error,
00177 "Parameter \"Inverse Factory\" is required by a Teko::DiagnosticPreconditionerFactory");
00178 TEUCHOS_TEST_FOR_EXCEPTION(not settings.isParameter("Descriptive Label"),std::runtime_error,
00179 "Parameter \"Descriptive Label\" is required by a Teko::DiagnosticPreconditionerFactory");
00180
00181
00182 std::string invName = settings.get<std::string>("Inverse Factory");
00183 diagString_ = settings.get<std::string>("Descriptive Label");
00184
00185
00186 Teuchos::RCP<const InverseLibrary> il = getInverseLibrary();
00187 invFactory_ = il->getInverseFactory(invName);
00188 TEUCHOS_TEST_FOR_EXCEPTION(invFactory_==Teuchos::null,std::runtime_error,
00189 "ERROR: \"Inverse Factory\" = " << invName
00190 << " could not be found");
00191
00192 if(settings.isParameter("Print Residual"))
00193 printResidual_ = settings.get<bool>("Print Residual");
00194
00195
00196 initTimers(diagString_);
00197 }
00198
00202 Teuchos::RCP<Teuchos::ParameterList> DiagnosticPreconditionerFactory::getRequestedParameters() const
00203 {
00204 TEUCHOS_TEST_FOR_EXCEPTION(invFactory_==Teuchos::null,std::runtime_error,
00205 "ERROR: Teko::DiagnosticPreconditionerFactory::getRequestedParameters requires that a "
00206 << "preconditioner factory has been set. Currently it is null!");
00207
00208 return invFactory_->getRequestedParameters();
00209 }
00210
00213 bool DiagnosticPreconditionerFactory::updateRequestedParameters(const Teuchos::ParameterList & pl)
00214 {
00215 TEUCHOS_TEST_FOR_EXCEPTION(invFactory_==Teuchos::null,std::runtime_error,
00216 "ERROR: Teko::DiagnosticPreconditionerFactory::updateRequestedParameters requires that a "
00217 << "preconditioner factory has been set. Currently it is null!");
00218
00219 return invFactory_->updateRequestedParameters(pl);
00220 }
00221
00222 void DiagnosticPreconditionerFactory::initTimers(const std::string & str)
00223 {
00224 buildTimer_ = Teuchos::rcp(new Teuchos::Time(str+" buildTimer"));
00225 rebuildTimer_ = Teuchos::rcp(new Teuchos::Time(str+" rebuildTimer"));
00226 }
00227
00228 }