NOX::StatusTest::StatusType N_NLS_NOX::Stagnation::checkStatus(const NOX::Solver::Generic& problem) { status = NOX::StatusTest::Unconverged; // First time through we don't do anything but reset the counters int niters = problem.getNumIterations(); if (niters == 0) { numSteps = 0; lastIteration = 0; convRate = 1.0; //minConvRate = 1.0; // Don't reset this. Xyce solver never does. normFInit = problem.getSolutionGroup().getNormF(); return NOX::StatusTest::Unconverged; } // Make sure we have not already counted the last nonlinear iteration. // This protects against multiple calls to checkStatus() in between // nonlinear iterations. bool isCounted = false; if (niters == lastIteration) { isCounted = true; } else lastIteration = niters; // Compute the convergenc rate and set counter appropriately if (!isCounted) { convRate = problem.getSolutionGroup().getNormF() / problem.getPreviousSolutionGroup().getNormF(); if (fabs(convRate - 1.0) <= tolerance) { if ((numSteps == 0) || (convRate < minConvRate)) minConvRate = convRate; ++numSteps ; } else numSteps = 0; } if (numSteps >= maxSteps) { double initConvRate = problem.getSolutionGroup().getNormF()/normFInit; if ((initConvRate <= 0.9) && (minConvRate <= 1.0)) { status = NOX::StatusTest::Converged; } else status = NOX::StatusTest::Failed; } return status; }
void GenericEpetraProblem::outputResults(const NOX::Solver::Generic& solver, Teuchos::ParameterList& printParams) { // Output the parameter list NOX::Utils utils(printParams); if (utils.isPrintType(NOX::Utils::Parameters)) { cout << endl << "Final Parameters" << endl << "****************" << endl; solver.getList().print(cout); cout << endl; } // Get the Epetra_Vector with the final solution from the solver const NOX::Epetra::Group& finalGroup = dynamic_cast<const NOX::Epetra::Group&>(solver.getSolutionGroup()); const Epetra_Vector& finalSolution = (dynamic_cast<const NOX::Epetra::Vector&> (finalGroup.getX())).getEpetraVector(); // Print solution char file_name[25]; FILE *ifp; int NumMyElements = finalSolution.Map().NumMyElements(); (void) sprintf(file_name, "output.%d",finalSolution.Map().Comm().MyPID()); ifp = fopen(file_name, "w"); for (int i=0; i<NumMyElements; i++) fprintf(ifp,"%d %E\n",finalSolution.Map().MinMyGID()+i,finalSolution[i]); fclose(ifp); }
void BroydenOperator::runPostIterate( const NOX::Solver::Generic & solver) { // Get and update using the solver object. if( solver.getNumIterations() > 0 ) { // To consistently compute changes to the step and the yield, eg effects of // linesearch or other globalizations, we need to get and subtract the old and // new solution states and corresponding residuals const Abstract::Group & oldSolnGrp = solver.getPreviousSolutionGroup(); const Abstract::Group & solnGrp = solver.getSolutionGroup(); // Set the Step vector *workVec = solnGrp.getX(); workVec->update(-1.0, oldSolnGrp.getX(), 1.0); setStepVector( *workVec ); // Set the Yield vector *workVec = solnGrp.getF(); workVec->update(-1.0, oldSolnGrp.getF(), 1.0); setYieldVector( *workVec ); // Use of these updated vectors occurs when computeJacobian or computePreconditioner // gets called } prePostOperator.runPostIterate( solver ); return; }
void runPostSolve(const NOX::Solver::Generic& solver) { TEUCHOS_ASSERT(m_lof!=Teuchos::null); const NOX::Abstract::Vector& x = solver.getSolutionGroup().getX(); const NOX::Thyra::Vector* n_th_x = dynamic_cast<const NOX::Thyra::Vector*>(&x); TEUCHOS_TEST_FOR_EXCEPTION(n_th_x == NULL, std::runtime_error, "Failed to dynamic_cast to NOX::Thyra::Vector!") Teuchos::RCP<const Thyra::VectorBase<double> > th_x = n_th_x->getThyraRCPVector(); // initialize the assembly container panzer::AssemblyEngineInArgs ae_inargs; ae_inargs.container_ = m_lof->buildLinearObjContainer(); ae_inargs.ghostedContainer_ = m_lof->buildGhostedLinearObjContainer(); ae_inargs.alpha = 0.0; ae_inargs.beta = 1.0; ae_inargs.evaluate_transient_terms = false; // initialize the ghosted container m_lof->initializeGhostedContainer(panzer::LinearObjContainer::X,*ae_inargs.ghostedContainer_); { // initialize the x vector const Teuchos::RCP<panzer::ThyraObjContainer<double> > thyraContainer = Teuchos::rcp_dynamic_cast<panzer::ThyraObjContainer<double> >(ae_inargs.container_,true); thyraContainer->set_x_th(Teuchos::rcp_const_cast<Thyra::VectorBase<double> >(th_x)); } m_response_library->addResponsesToInArgs<panzer::Traits::Residual>(ae_inargs); m_response_library->evaluate<panzer::Traits::Residual>(ae_inargs); // write to disk m_mesh->writeToExodus(0.0); }
NOX::StatusTest::StatusType LOCA::Continuation::StatusTest::ParameterResidualNorm::checkStatus( const NOX::Solver::Generic& problem) { // Get solution groups from solver const NOX::Abstract::Group& soln = problem.getSolutionGroup(); // Cast soln group to continuation group (for parameter step) const LOCA::Continuation::ExtendedGroup* conGroupPtr = dynamic_cast<const LOCA::Continuation::ExtendedGroup*>(&soln); // Check that group is a continuation group, return converged if not if (conGroupPtr == NULL) { paramResidualNorm = 0.0; return NOX::StatusTest::Converged; } // Get residual vector const LOCA::Continuation::ExtendedVector& f = dynamic_cast<const LOCA::Continuation::ExtendedVector&>(soln.getF()); paramResidualNorm = fabs(f.getParam()) / (rtol*fabs(conGroupPtr->getStepSize()) + atol); if (paramResidualNorm < tol) status = NOX::StatusTest::Converged; else status = NOX::StatusTest::Unconverged; return status; }
NOX::StatusTest::StatusType NOX::StatusTest::NormF:: checkStatus(const NOX::Solver::Generic& problem, NOX::StatusTest::CheckType checkType) { if (checkType == NOX::StatusTest::None) { normF = 0.0; status = Unevaluated; } else { normF = computeNorm( problem.getSolutionGroup() ); status = ((normF != -1) && (normF < trueTolerance)) ? Converged : Unconverged; } return status; }
NOX::StatusTest::StatusType LOCA::Bifurcation::PitchforkBord::StatusTest::ParameterUpdateNorm::checkStatus( const NOX::Solver::Generic& problem) { // Get solution groups from solver const NOX::Abstract::Group& soln = problem.getSolutionGroup(); const NOX::Abstract::Group& oldsoln = problem.getPreviousSolutionGroup(); // Cast soln group to pitchfork group const LOCA::Bifurcation::PitchforkBord::ExtendedGroup* pfGroupPtr = dynamic_cast<const LOCA::Bifurcation::PitchforkBord::ExtendedGroup*>(&soln); // Check that group is a pitchfork group, return converged if not if (pfGroupPtr == NULL) { paramUpdateNorm = 0.0; return NOX::StatusTest::Converged; } // Get solution vectors const LOCA::Bifurcation::PitchforkBord::ExtendedVector& x = dynamic_cast<const LOCA::Bifurcation::PitchforkBord::ExtendedVector&>(soln.getX()); const LOCA::Bifurcation::PitchforkBord::ExtendedVector& xold = dynamic_cast<const LOCA::Bifurcation::PitchforkBord::ExtendedVector&>(oldsoln.getX()); // On the first iteration, the old and current solution are the same so // we should return the test as unconverged until there is a valid // old solution (i.e. the number of iterations is greater than zero). int niters = problem.getNumIterations(); if (niters == 0) { paramUpdateNorm = 1.0e+12; status = NOX::StatusTest::Unconverged; return status; } paramUpdateNorm = fabs(x.getBifParam() - xold.getBifParam()) / (rtol*fabs(x.getBifParam()) + atol); if (paramUpdateNorm < tol) status = NOX::StatusTest::Converged; else status = NOX::StatusTest::Unconverged; return status; }
StatusType NormWRMS:: checkStatus(const NOX::Solver::Generic& problem, NOX::StatusTest::CheckType checkType) { if (checkType == NOX::StatusTest::None) { status = Unevaluated; value = 1.0e+12; return status; } status = Unconverged; const Abstract::Group& soln = problem.getSolutionGroup(); const Abstract::Group& oldsoln = problem.getPreviousSolutionGroup(); const Abstract::Vector& x = soln.getScaledX(); // On the first iteration, the old and current solution are the same so // we should return the test as unconverged until there is a valid // old solution (i.e. the number of iterations is greater than zero). int niters = problem.getNumIterations(); if (niters == 0) { status = Unconverged; value = 1.0e+12; return status; } // **** Begin check for convergence criteria #1 **** // Create the working vectors if this is the first time this // operator is called. if (Teuchos::is_null(u)) u = x.clone(NOX::ShapeCopy); if (Teuchos::is_null(v)) v = x.clone(NOX::ShapeCopy); // Create the weighting vector u = RTOL |x| + ATOL // |x| is evaluated at the old time step v->abs(oldsoln.getScaledX()); if (atolIsScalar) { u->init(1.0); u->update(rtol, *v, atol); } else { u->update(rtol, *v, 1.0, *atolVec, 0.0); } // v = 1/u (elementwise) v->reciprocal(*u); // u = x - oldx (i.e., the update) u->update(1.0, x, -1.0, oldsoln.getScaledX(), 0.0); // u = Cp * u @ v (where @ represents an elementwise multiply) u->scale(*v); // Turn off implicit scaling of norm if the vector supports it Teuchos::RCP<NOX::Abstract::ImplicitWeighting> iw_u; iw_u = Teuchos::rcp_dynamic_cast<NOX::Abstract::ImplicitWeighting>(u,false); bool saved_status = false; if (nonnull(iw_u) && m_disable_implicit_weighting) { saved_status = iw_u->getImplicitWeighting(); iw_u->setImplicitWeighting(false); } // tmp = factor * sqrt (u * u / N) value = u->norm() * factor / sqrt(static_cast<double>(u->length())); // Set the implicit scaling back to original value if (nonnull(iw_u) && m_disable_implicit_weighting) iw_u->setImplicitWeighting(saved_status); StatusType status1 = Unconverged; if (value < tolerance) status1 = Converged; // **** Begin check for convergence criteria #2 **** StatusType status2 = Unconverged; // Determine if the Generic solver is a LineSearchBased solver // If it is not then return a "Converged" status const Solver::Generic* test = 0; test = dynamic_cast<const Solver::LineSearchBased*>(&problem); if (test == 0) { status2 = Converged; } else { printCriteria2Info = true; computedStepSize = (dynamic_cast<const Solver::LineSearchBased*>(&problem))->getStepSize(); if (computedStepSize >= alpha) status2 = Converged; } // **** Begin check for convergence criteria #3 **** // First time through, make sure the output parameter list exists. // Since the list is const, a sublist call to a non-existent sublist // throws an error. Therefore we have to check the existence of each // sublist before we call it. const Teuchos::ParameterList& p = problem.getList(); if (niters == 1) { if (p.isSublist("Direction")) { if (p.sublist("Direction").isSublist("Newton")) { if (p.sublist("Direction").sublist("Newton").isSublist("Linear Solver")) { if (p.sublist("Direction").sublist("Newton").sublist("Linear Solver").isSublist("Output")) { const Teuchos::ParameterList& list = p.sublist("Direction").sublist("Newton").sublist("Linear Solver").sublist("Output"); if (Teuchos::isParameterType<double>(list, "Achieved Tolerance")) { printCriteria3Info = true; } } } } } } StatusType status3 = Converged; if (printCriteria3Info) { achievedTol = const_cast<Teuchos::ParameterList&>(problem.getList()). sublist("Direction").sublist("Newton").sublist("Linear Solver"). sublist("Output").get("Achieved Tolerance", -1.0); status3 = (achievedTol <= beta) ? Converged : Unconverged; } // Determine status of test if ((status1 == Converged) && (status2 == Converged) && (status3 == Converged)) status = Converged; return status; }
NOX::StatusTest::StatusType LOCA::Bifurcation::TPBord::StatusTest::NullVectorNormWRMS::checkStatus( const NOX::Solver::Generic& problem) { // Get solution groups from solver const NOX::Abstract::Group& soln = problem.getSolutionGroup(); const NOX::Abstract::Group& oldsoln = problem.getPreviousSolutionGroup(); // Cast soln group to turning point group const LOCA::Bifurcation::TPBord::ExtendedGroup* tpGroupPtr = dynamic_cast<const LOCA::Bifurcation::TPBord::ExtendedGroup*>(&soln); // Check that group is a turning point group, return converged if not if (tpGroupPtr == NULL) { normWRMS = 0.0; return NOX::StatusTest::Converged; } // Get solution vectors const LOCA::Bifurcation::TPBord::ExtendedVector& x = dynamic_cast<const LOCA::Bifurcation::TPBord::ExtendedVector&>(soln.getX()); const LOCA::Bifurcation::TPBord::ExtendedVector& xold = dynamic_cast<const LOCA::Bifurcation::TPBord::ExtendedVector&>(oldsoln.getX()); // Get null vectors const NOX::Abstract::Vector& y = x.getNullVec(); const NOX::Abstract::Vector& yold = xold.getNullVec(); // temporary vectors NOX::Abstract::Vector *u = y.clone(NOX::ShapeCopy); NOX::Abstract::Vector *v = yold.clone(NOX::ShapeCopy); // On the first iteration, the old and current solution are the same so // we should return the test as unconverged until there is a valid // old solution (i.e. the number of iterations is greater than zero). int niters = problem.getNumIterations(); if (niters == 0) { normWRMS = 1.0e+12; status = NOX::StatusTest::Unconverged; return status; } // Fill vector with 1's u->init(1.0); // Compute |y| v->abs(y); // Overwrite u with rtol*|y| + atol u->update(rtol, *v, atol); // Overwrite v with 1/(rtol*|y| + atol) v->reciprocal(*u); // Overwrite u with y-yold u->update(1.0, y, -1.0, yold, 0.0); // Overwrite u with (y-yold)/(rtol*|y| + atol) u->scale(*v); // Compute sqrt( (y-yold)/(rtol*|y| + atol) ) / sqrt(N) normWRMS = u->norm() / sqrt(static_cast<double>(u->length())); if (normWRMS < tol) status = NOX::StatusTest::Converged; else status = NOX::StatusTest::Unconverged; delete u; delete v; return status; }