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 #include "NOX_Multiphysics_Solver_FixedPointBased.H"
00040 #include "NOX_Abstract_Vector.H"
00041 #include "NOX_Abstract_Group.H"
00042 #include "NOX_Common.H"
00043 #include "NOX_Utils.H"
00044 #include "NOX_GlobalData.H"
00045 #include "NOX_LineSearch_Generic.H"
00046 #include "NOX_LineSearch_Factory.H"
00047 #include "NOX_Direction_Generic.H"
00048 #include "NOX_Direction_Factory.H"
00049
00050 NOX::Multiphysics::Solver::FixedPointBased::
00051 FixedPointBased(const Teuchos::RCP< vector<Teuchos::RCP<NOX::Solver::Generic> > >& solvers,
00052 const Teuchos::RCP<NOX::Multiphysics::DataExchange::Interface>& i,
00053 const Teuchos::RCP<NOX::StatusTest::Generic>& t,
00054 const Teuchos::RCP<Teuchos::ParameterList>& p) :
00055 solveType( JACOBI ),
00056 solversVecPtr(solvers),
00057 dataExInterface(i),
00058 globalDataPtr(Teuchos::rcp(new NOX::GlobalData(p))),
00059 utilsPtr(globalDataPtr->getUtils()),
00060 solnPtr( Teuchos::rcp(new Group(solvers, t, p)) ),
00061 testPtr(t),
00062 paramsPtr(p),
00063 prePostOperator(utilsPtr, paramsPtr->sublist("Solver Options"))
00064 {
00065 init();
00066 }
00067
00068
00069
00070 void
00071 NOX::Multiphysics::Solver::FixedPointBased::init()
00072 {
00073
00074 nIter = 0;
00075 status = NOX::StatusTest::Unconverged;
00076
00077
00078
00079
00080
00081 if (Teuchos::isParameterType<int>(*paramsPtr, "Status Test Check Type")) {
00082 checkType = static_cast<NOX::StatusTest::CheckType>
00083 (paramsPtr->sublist("Solver Options").get("Status Test Check Type",
00084 int(0)));
00085 }
00086 else {
00087 checkType = static_cast<NOX::StatusTest::CheckType>
00088 (paramsPtr->sublist("Solver Options").get("Status Test Check Type",
00089 NOX::StatusTest::Minimal));
00090 }
00091
00092
00093 std::string solveTypeName = paramsPtr->sublist("Solver Options").get( "Fixed Point Iteration Type", "Seidel" );
00094 if( "Jacobi" == solveTypeName )
00095 solveType = JACOBI;
00096 else if( "Seidel" == solveTypeName )
00097 solveType = SEIDEL;
00098 else
00099 {
00100 utilsPtr->out() << "NOX::Multiphysics::Solver::FixedPointBased::step - "
00101 << "Invalid Solver Method " << solveTypeName << endl;
00102 throw "NOX Error";
00103 }
00104
00105
00106 if (utilsPtr->isPrintType(NOX::Utils::Parameters))
00107 {
00108 utilsPtr->out() << "\n" << NOX::Utils::fill(72) << "\n";
00109 utilsPtr->out() << "\n-- Parameters Passed to Fixed-Point Coupling Solver --\n\n";
00110 paramsPtr->print(utilsPtr->out(),5);
00111 }
00112
00113 }
00114
00115 bool
00116 NOX::Multiphysics::Solver::FixedPointBased::reset(
00117 const Teuchos::RCP<vector<Teuchos::RCP<NOX::Solver::Generic> > >& solvers,
00118 const Teuchos::RCP<NOX::Multiphysics::DataExchange::Interface>& i,
00119 const Teuchos::RCP<NOX::StatusTest::Generic>& t,
00120 const Teuchos::RCP<Teuchos::ParameterList>& p)
00121 {
00122 solversVecPtr = solvers;
00123 globalDataPtr = Teuchos::rcp(new NOX::GlobalData(p));
00124 solnPtr = Teuchos::rcp( new NOX::Multiphysics::Group(solvers, t, p) );
00125 testPtr = t;
00126 paramsPtr = p;
00127 utilsPtr = globalDataPtr->getUtils();
00128 prePostOperator.reset(utilsPtr, paramsPtr->sublist("Solver Options"));
00129
00130 init();
00131
00132 return false;
00133 }
00134
00135 void
00136 NOX::Multiphysics::Solver::FixedPointBased::reset(
00137 const NOX::Abstract::Vector& initialGuess,
00138 const Teuchos::RCP<NOX::StatusTest::Generic>& t)
00139 {
00140 std::string msg = "Error - NOX::Multiphysics::Solver::FixedPointBased::reset() - this reset method is not valid for a Multiphysics Solver!";
00141 TEST_FOR_EXCEPTION(true, std::logic_error, msg);
00142 }
00143
00144 void
00145 NOX::Multiphysics::Solver::FixedPointBased::reset(
00146 const NOX::Abstract::Vector& initialGuess)
00147 {
00148 std::string msg = "Error - NOX::Multiphysics::Solver::FixedPointBased::reset() - this reset method is not valid for a Multiphysics Solver!";
00149 TEST_FOR_EXCEPTION(true, std::logic_error, msg);
00150 }
00151
00152 NOX::Multiphysics::Solver::FixedPointBased::~FixedPointBased()
00153 {
00154
00155 }
00156
00157
00158 NOX::StatusTest::StatusType
00159 NOX::Multiphysics::Solver::FixedPointBased::getStatus()
00160 {
00161 return status;
00162 }
00163
00164 NOX::StatusTest::StatusType
00165 NOX::Multiphysics::Solver::FixedPointBased::step()
00166 {
00167 prePostOperator.runPreIterate(*this);
00168
00169
00170 if (nIter == 0)
00171 {
00172
00173 dataExInterface->exchangeAllData();
00174 NOX::Abstract::Group::ReturnType rtype = solnPtr->computeF();
00175 if (rtype != NOX::Abstract::Group::Ok)
00176 {
00177 utilsPtr->out() << "NOX::Multiphysics::Solver::FixedPointBased::step - "
00178 << "Unable to compute F" << endl;
00179 throw "NOX Error";
00180 }
00181
00182
00183 status = testPtr->checkStatus(*this, checkType);
00184 if ((status == NOX::StatusTest::Converged) && (utilsPtr->isPrintType(NOX::Utils::Warning)))
00185 utilsPtr->out() << "Warning: NOX::Multiphysics::Solver::FixedPointBased::step() - "
00186 << "The solution passed into the solver (either "
00187 << "through constructor or reset method) "
00188 << "is already converged! The solver wil not "
00189 << "attempt to solve this system since status is "
00190 << "flagged as converged." << endl;
00191
00192 printUpdate();
00193 }
00194
00195
00196 if (status != NOX::StatusTest::Unconverged)
00197 {
00198 prePostOperator.runPostIterate(*this);
00199 return status;
00200 }
00201
00202
00203 NOX::Abstract::Group& soln = *solnPtr;
00204 NOX::StatusTest::Generic& test = *testPtr;
00205
00206 NOX::StatusTest::StatusType status = NOX::StatusTest::Unconverged;
00207
00208 vector<Teuchos::RCP<NOX::Solver::Generic> >::iterator iter = (*solversVecPtr).begin(),
00209 iter_end = (*solversVecPtr).end() ;
00210
00211 for( int i = 0; iter_end != iter; ++iter, ++i )
00212 {
00213 status = NOX::StatusTest::Unconverged;
00214
00215
00216 if( SEIDEL == solveType )
00217 dataExInterface->exchangeDataTo(i);
00218
00219
00220 const_cast<NOX::Abstract::Group&>((*iter)->getSolutionGroup()).setX((*iter)->getSolutionGroup().getX());
00221
00222 const Teuchos::RCP<NOX::Abstract::Group> sameGrp =
00223 Teuchos::rcp( const_cast<NOX::Abstract::Group*>(&(*iter)->getSolutionGroup()), false );
00224
00225 (*iter)->reset( sameGrp->getX() );
00226
00227 status = (*iter)->solve();
00228
00229
00230 }
00231
00232
00233 NOX::Abstract::Group::ReturnType rtype = soln.computeF();
00234 if (rtype != NOX::Abstract::Group::Ok)
00235 {
00236 utilsPtr->out() << "NOX::Multiphysics::Solver::FixedPointBased::step - unable to compute F" << endl;
00237 status = NOX::StatusTest::Failed;
00238 prePostOperator.runPostIterate(*this);
00239 return status;
00240 }
00241
00242
00243 nIter ++;
00244
00245
00246 dataExInterface->exchangeAllData();
00247 for( iter = (*solversVecPtr).begin(); iter_end != iter; ++iter )
00248
00249 const_cast<NOX::Abstract::Group&>((*iter)->getSolutionGroup()).setX((*iter)->getSolutionGroup().getX());
00250 rtype = solnPtr->computeF();
00251 if (rtype != NOX::Abstract::Group::Ok)
00252 {
00253 utilsPtr->out() << "NOX::Multiphysics::Solver::FixedPointBased::step - "
00254 << "Unable to compute F" << endl;
00255 throw "NOX Error";
00256 }
00257
00258
00259 status = test.checkStatus(*this, checkType);
00260
00261 prePostOperator.runPostIterate(*this);
00262
00263
00264 return status;
00265 }
00266
00267 NOX::StatusTest::StatusType
00268 NOX::Multiphysics::Solver::FixedPointBased::solve()
00269 {
00270 prePostOperator.runPreSolve(*this);
00271
00272
00273 while (status == NOX::StatusTest::Unconverged)
00274 {
00275 status = step();
00276 printUpdate();
00277 }
00278
00279 Teuchos::ParameterList& outputParams = paramsPtr->sublist("Output");
00280 outputParams.set("Nonlinear Iterations", nIter);
00281 outputParams.set("2-Norm of Residual", solnPtr->getNormF());
00282
00283 prePostOperator.runPostSolve(*this);
00284
00285 return status;
00286 }
00287
00288 const NOX::Abstract::Group &
00289 NOX::Multiphysics::Solver::FixedPointBased::getSolutionGroup() const
00290 {
00291 return *solnPtr;
00292 }
00293
00294 const NOX::Abstract::Group&
00295 NOX::Multiphysics::Solver::FixedPointBased::getPreviousSolutionGroup() const
00296 {
00297 utilsPtr->out() << "NOX::Multiphysics::Solver::FixedPointBased::getPreviousSolutionGroup - "
00298 << "Old group not available. This method is not currently supported." << endl;
00299 throw "NOX Error";
00300 }
00301
00302 int NOX::Multiphysics::Solver::FixedPointBased::getNumIterations() const
00303 {
00304 return nIter;
00305 }
00306
00307 const Teuchos::ParameterList&
00308 NOX::Multiphysics::Solver::FixedPointBased::getList() const
00309 {
00310 return *paramsPtr;
00311 }
00312
00313
00314 void NOX::Multiphysics::Solver::FixedPointBased::printUpdate()
00315 {
00316 double normSoln = 0;
00317
00318
00319
00320 if ((status == NOX::StatusTest::Unconverged) &&
00321 (utilsPtr->isPrintType(NOX::Utils::OuterIterationStatusTest)))
00322 {
00323 utilsPtr->out() << NOX::Utils::fill(72) << "\n";
00324 utilsPtr->out() << "-- Status Test Results --\n";
00325 testPtr->print(utilsPtr->out());
00326 utilsPtr->out() << NOX::Utils::fill(72) << "\n";
00327 }
00328
00329
00330 if (utilsPtr->isPrintType(NOX::Utils::OuterIteration))
00331 normSoln = solnPtr->getNormF();
00332
00333
00334 if (utilsPtr->isPrintType(NOX::Utils::OuterIteration))
00335 {
00336 utilsPtr->out() << "\n" << NOX::Utils::fill(72) << "\n";
00337 utilsPtr->out() << "-- Fixed-point Solver Step " << nIter << " -- \n";
00338 utilsPtr->out() << "Fixed-point ||F|| = " << utilsPtr->sciformat(normSoln);
00339 if (status == NOX::StatusTest::Converged)
00340 utilsPtr->out() << " (Converged!)";
00341 if (status == NOX::StatusTest::Failed)
00342 utilsPtr->out() << " (Failed!)";
00343 utilsPtr->out() << "\n" << NOX::Utils::fill(72) << "\n" << endl;
00344 }
00345
00346
00347 if ((status != NOX::StatusTest::Unconverged) &&
00348 (utilsPtr->isPrintType(NOX::Utils::OuterIteration)))
00349 {
00350 utilsPtr->out() << NOX::Utils::fill(72) << "\n";
00351 utilsPtr->out() << "-- Final Status Test Results --\n";
00352 testPtr->print(utilsPtr->out());
00353 utilsPtr->out() << NOX::Utils::fill(72) << "\n";
00354 }
00355 }