예제 #1
0
void
LOCA::MultiContinuation::ExtendedGroup::projectToDraw(
			    const LOCA::MultiContinuation::ExtendedVector& x, 
			    double *px) const
{
  // first numParams components are the parameters
  for (int i=0; i<numParams; i++)
    px[i] = x.getScalar(i);

  // fill remaining solution components
  grpPtr->projectToDraw(*x.getXVec(), px+numParams);
}
double
LOCA::MultiContinuation::ConstrainedGroup::getNormNewtonSolveResidual() const 
{
  std::string callingFunction = 
    "LOCA::MultiContinuation::ConstrainedGroup::getNormNewtonSolveResidual()";
  NOX::Abstract::Group::ReturnType finalStatus;
  LOCA::MultiContinuation::ExtendedVector residual = *fVec;
  
  finalStatus = applyJacobian(*newtonVec, residual);
  globalData->locaErrorCheck->checkReturnType(finalStatus, callingFunction);

  residual = residual.update(1.0, *fVec, 1.0);
  return residual.norm();
}
예제 #3
0
void
LOCA::MultiPredictor::AbstractStrategy::setPredictorOrientation(
	      bool baseOnSecant, 
	      const vector<double>& stepSize,
	      const LOCA::MultiContinuation::ExtendedGroup& grp,
	      const LOCA::MultiContinuation::ExtendedVector& prevXVec,
	      const LOCA::MultiContinuation::ExtendedVector& xVec,
	      LOCA::MultiContinuation::ExtendedVector& secant,
	      LOCA::MultiContinuation::ExtendedMultiVector& tangent)
{
  // If orientation is not based on a secant vector (i.e., first or last
  // steps in a continuation run) make parameter component of predictor
  // positive
  if (!baseOnSecant) {
    for (int i=0; i<tangent.numVectors(); i++) 
      if (tangent.getScalar(i,i) < 0.0)
	tangent[i].scale(-1.0);
    return;
  }

  // compute secant
  secant.update(1.0, xVec, -1.0, prevXVec, 0.0);

  for (int i=0; i<tangent.numVectors(); i++)
    if (grp.computeScaledDotProduct(secant, tangent[i])*stepSize[i] < 0.0)
      tangent[i].scale(-1.0);
}
NOX::Abstract::Group::ReturnType 
LOCA::MultiPredictor::Constant::compute(
	      bool baseOnSecant, const std::vector<double>& stepSize,
	      LOCA::MultiContinuation::ExtendedGroup& grp,
	      const LOCA::MultiContinuation::ExtendedVector& prevXVec,
	      const LOCA::MultiContinuation::ExtendedVector& xVec)
{
  if (globalData->locaUtils->isPrintType(NOX::Utils::StepperDetails))
    globalData->locaUtils->out() << 
      "\n\tCalling Predictor with method: Constant" << std::endl;

  // Number of continuation parameters
  int numParams = stepSize.size();

  if (!initialized) {

    // Allocate predictor vector
    predictor = Teuchos::rcp_dynamic_cast<LOCA::MultiContinuation::ExtendedMultiVector>(xVec.createMultiVector(numParams, NOX::ShapeCopy));
    
    // Allocate secant
    secant = Teuchos::rcp_dynamic_cast<LOCA::MultiContinuation::ExtendedVector>(xVec.clone(NOX::ShapeCopy));

    initialized = true;
  }

  predictor->init(0.0);
  for (int i=0; i<numParams; i++)
    predictor->getScalar(i,i) = 1.0;

  // Set orientation based on parameter change
  setPredictorOrientation(baseOnSecant, stepSize, grp, prevXVec, 
			  xVec, *secant, *predictor);

  return NOX::Abstract::Group::Ok;
}
NOX::Abstract::Group::ReturnType 
LOCA::MultiPredictor::Secant::compute(
	      bool baseOnSecant, const std::vector<double>& stepSize,
	      LOCA::MultiContinuation::ExtendedGroup& grp,
	      const LOCA::MultiContinuation::ExtendedVector& prevXVec,
	      const LOCA::MultiContinuation::ExtendedVector& xVec)
{
  if (globalData->locaUtils->isPrintType(NOX::Utils::StepperDetails))
    globalData->locaUtils->out() << 
      "\n\tCalling Predictor with method: Secant" << std::endl;

  // Number of continuation parameters
  int numParams = stepSize.size();

  if (!initialized) {

    // Allocate predictor vector
    predictor = Teuchos::rcp_dynamic_cast<LOCA::MultiContinuation::ExtendedMultiVector>(xVec.createMultiVector(numParams, NOX::ShapeCopy));
    
    // Allocate secant
    secant = Teuchos::rcp_dynamic_cast<LOCA::MultiContinuation::ExtendedVector>(xVec.clone(NOX::ShapeCopy));
    
    initialized = true;
  }

  // Use first step predictor if this is the first step
  if (isFirstStep && !isFirstStepComputed) {
    isFirstStepComputed = true;
    return firstStepPredictor->compute(baseOnSecant, stepSize, grp, 
				       prevXVec, xVec);
  }

  if (isFirstStep && isFirstStepComputed)
    isFirstStep = false;
   
  // Compute x - xold
  (*predictor)[0].update(1.0, xVec, -1.0, prevXVec, 0.0);
  
  for (int i=0; i<numParams; i++) {
    
    (*predictor)[i] = (*predictor)[0];

    // Rescale so parameter component = 1
    (*predictor)[i].scale(1.0/fabs(predictor->getScalar(i,i)));

    // Set off-diagonal elements to 0
    for (int j=0; j<numParams; j++)
      if (i != j)
	predictor->getScalar(i,j) = 0.0;
  }
  
  // Set orientation based on parameter change
  setPredictorOrientation(baseOnSecant, stepSize, grp, prevXVec, 
			  xVec, *secant, *predictor);
  
  return NOX::Abstract::Group::Ok;
}
예제 #6
0
NOX::Abstract::Group::ReturnType 
LOCA::StepSize::Adaptive::computeStepSize(
		     LOCA::MultiContinuation::AbstractStrategy& curGroup,
		     const LOCA::MultiContinuation::ExtendedVector& predictor,
		     const NOX::Solver::Generic& solver,
		     const LOCA::Abstract::Iterator::StepStatus& stepStatus,
		     const LOCA::Stepper& stepper,
		     double& stepSize) 
{
  // If this is the first step, set step size to initial value
  if (isFirstStep) {
    double dpds = predictor.getScalar(0);
    if (dpds != 0.0) {
      LOCA::StepSize::Constant::startStepSize /= dpds;
      LOCA::StepSize::Constant::maxStepSize /= dpds;
      LOCA::StepSize::Constant::minStepSize /= dpds;
    }
    LOCA::StepSize::Constant::isFirstStep = false;
    stepSize = LOCA::StepSize::Constant::startStepSize;
    prevStepSize = 0.0;
  }
  else {
  
    // A failed nonlinear solve cuts the step size in half
    if (stepStatus == LOCA::Abstract::Iterator::Unsuccessful) {
      stepSize *= LOCA::StepSize::Constant::failedFactor;    
    }
    else {

      double ds_ratio = curGroup.getStepSizeScaleFactor();
      LOCA::StepSize::Constant::startStepSize *= ds_ratio;
      LOCA::StepSize::Constant::maxStepSize *= ds_ratio;
      LOCA::StepSize::Constant::minStepSize *= ds_ratio;
      
      // Get number of nonlinear iterations in last step
      double numNonlinearSteps = 
	static_cast<double>(solver.getNumIterations());

      // Save successful stepsize as previous
      prevStepSize = stepSize;

      // adapive step size control
      double factor = (maxNonlinearSteps - numNonlinearSteps) 
               	      / (maxNonlinearSteps);

      stepSize *= (1.0 + agrValue * factor * factor);

      stepSize *= ds_ratio;
    } 
  }

  // Clip step size to be within prescribed bounds
  NOX::Abstract::Group::ReturnType res = clipStepSize(stepSize);

  return res;
}
예제 #7
0
void
LOCA::MultiContinuation::ExtendedGroup::scaleTangent()
{
  LOCA::MultiContinuation::ExtendedVector *v;

  scaledTangentMultiVec = tangentMultiVec;

  // Only scale the tangent if it is scalable
  if (predictor->isTangentScalable()) {

    for (int i=0; i<numParams; i++) {
      v = 
	dynamic_cast<LOCA::MultiContinuation::ExtendedVector*>(&scaledTangentMultiVec[i]);
      grpPtr->scaleVector(*(v->getXVec()));
      grpPtr->scaleVector(*(v->getXVec()));
    }

  }
}
예제 #8
0
NOX::Abstract::Group::ReturnType
LOCA::StepSize::Constant::computeStepSize(
             LOCA::MultiContinuation::AbstractStrategy& curGroup,
             const LOCA::MultiContinuation::ExtendedVector& predictor,
             const NOX::Solver::Generic& solver,
             const LOCA::Abstract::Iterator::StepStatus& stepStatus,
//             const LOCA::Stepper& stepper,
             const LOCA::Abstract::Iterator& stepper,
             double& stepSize)
{

  // If this is the first step, set step size to initial value adjusted
  // to predicted change in parameter
  if (isFirstStep) {
    double dpds = predictor.getScalar(0);
    if (dpds != 0.0) {
      startStepSize /= dpds;
      maxStepSize /= dpds;
      minStepSize /= dpds;
    }
    stepSize = startStepSize;
    isFirstStep = false;
    prevStepSize = 0.0;
  }
  else {

    // Step size remains constant, unless...
    // A failed nonlinear solve cuts the step size by failedFactor
    if (stepStatus == LOCA::Abstract::Iterator::Unsuccessful) {
      stepSize *= failedFactor;
    }
    else {

      double ds_ratio = curGroup.getStepSizeScaleFactor();
      startStepSize *= ds_ratio;
      maxStepSize *= ds_ratio;
      minStepSize *= ds_ratio;

      prevStepSize = stepSize;
      stepSize *= ds_ratio;

      // For constant step size, the step size may still have been
      // reduced by a solver failure.  We then increase the step size
      // by a factor of cube-root-2 until back to the original step size

      if (stepSize != startStepSize) {

        stepSize *= successFactor;

        if (startStepSize > 0.0)
          stepSize = NOX_MIN(stepSize, startStepSize);
        else
          stepSize = NOX_MAX(stepSize, startStepSize);
     }
    }
  }

  // Clip step size to be within prescribed bounds
  NOX::Abstract::Group::ReturnType res = clipStepSize(stepSize);

  return res;
}