예제 #1
0
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;
}
예제 #2
0
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);
}
예제 #3
0
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;
}
예제 #6
0
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;
}
예제 #9
0
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;
}