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(); }
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; }
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; }
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())); } } }
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; }