NOX::Abstract::Group::ReturnType LOCA::Pitchfork::MooreSpence::ExtendedGroup::computeDfDpMulti( const vector<int>& paramIDs, NOX::Abstract::MultiVector& dfdp, bool isValid_F) { string callingFunction = "LOCA::Pitchfork::MooreSpence::ExtendedGroup::computeDfDpMulti()"; NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok; NOX::Abstract::Group::ReturnType status; // Cast dfdp to pitchfork vector LOCA::Pitchfork::MooreSpence::ExtendedMultiVector& pf_dfdp = dynamic_cast<LOCA::Pitchfork::MooreSpence::ExtendedMultiVector&>(dfdp); // Compute df/dp // Note: the first column of fMultiVec stores f + sigma*psi, not f, // so we always need to recompute f. This changes the first column // of fMultiVec back to f status = grpPtr->computeDfDpMulti(paramIDs, *pf_dfdp.getXMultiVec(), false); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Change the first column back to f + sigma*psi double sigma = xVec->getSlack(); pf_dfdp.getColumn(0)->getXVec()->update(sigma, *asymVec, 1.0); // Compute d(Jn)/dp status = grpPtr->computeDJnDpMulti(paramIDs, *(xVec->getNullVec()), *pf_dfdp.getNullMultiVec(), isValid_F); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Set parameter components if (!isValid_F) { pf_dfdp.getScalar(0,0) = grpPtr->innerProduct(*(xVec->getXVec()), *asymVec); pf_dfdp.getScalar(1,0) = lTransNorm(*(xVec->getNullVec())); } for (int i=0; i<dfdp.numVectors()-1; i++) { pf_dfdp.getScalar(0,i+1) = 0.0; pf_dfdp.getScalar(1,i+1) = 0.0; } return finalStatus; }
NOX::Abstract::Group::ReturnType LOCA::Pitchfork::MooreSpence::ExtendedGroup::computeF() { if (isValidF) return NOX::Abstract::Group::Ok; string callingFunction = "LOCA::Pitchfork::MooreSpence::ExtendedGroup::computeF()"; NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok; NOX::Abstract::Group::ReturnType status; double sigma = xVec->getSlack(); // Compute underlying F if (!grpPtr->isF()) { status = grpPtr->computeF(); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); } fVec->getXVec()->update(1.0, grpPtr->getF(), sigma, *asymVec, 0.0); // Compute underlying Jacobian if (!grpPtr->isJacobian()) { status = grpPtr->computeJacobian(); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); } // Compute J*n status = grpPtr->applyJacobian(*(xVec->getNullVec()), *(fVec->getNullVec())); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Compute <x,psi> fVec->getSlack() = grpPtr->innerProduct(*(xVec->getXVec()), *asymVec); // Compute phi^T*n fVec->getBifParam() = lTransNorm(*(xVec->getNullVec())) - 1.0; isValidF = true; return finalStatus; }
void LOCA::Pitchfork::MooreSpence::ExtendedGroup::init(bool perturbSoln, double perturbSize) { xVec->getBifParam() = getBifParam(); // Rescale length vector so that the normalization condition is met double lVecDotNullVec = lTransNorm(*(xVec->getNullVec())); if (fabs(lVecDotNullVec) < 1.0e-8) { globalData->locaErrorCheck->throwError( "LOCA::Pitchfork::MooreSpence::ExtendedGroup::init()", "null vector cannot be orthogonal to length-scaling vector: "); } if (globalData->locaUtils->isPrintType(NOX::Utils::StepperDetails)) { globalData->locaUtils->out() << "\tIn LOCA::Pitchfork::MooreSpence::ExtendedGroup::init(), " << "scaling null vector by:" << globalData->locaUtils->sciformat(1.0 / lVecDotNullVec) << std::endl; } xVec->getNullVec()->scale(1.0/lVecDotNullVec); // Rescale asymmetric vector to have unit length double psi_norm = sqrt( grpPtr->innerProduct(*asymVec, *asymVec) ); if (globalData->locaUtils->isPrintType(NOX::Utils::StepperDetails)) { globalData->locaUtils->out() << "\tIn LOCA::Pitchfork::MooreSpence::ExtendedGroup::init(), " << "scaling asymmetric vector by:" << globalData->locaUtils->sciformat(1.0 / psi_norm) << std::endl; } asymVec->scale(1.0 / psi_norm); if (perturbSoln) { if (globalData->locaUtils->isPrintType(NOX::Utils::StepperDetails)) { globalData->locaUtils->out() << "\tIn LOCA::Pitchfork::MooreSpence::ExtendedGroup::init(), " << "applying random perturbation to initial solution of size: " << globalData->locaUtils->sciformat(perturbSize) << endl; } Teuchos::RCP<NOX::Abstract::Vector> perturb = xVec->getXVec()->clone(NOX::ShapeCopy); perturb->random(); perturb->scale(*(xVec->getXVec())); xVec->getXVec()->update(perturbSize, *perturb, 1.0); grpPtr->setX(*(xVec->getXVec())); } }
NOX::Abstract::Group::ReturnType LOCA::TurningPoint::MooreSpence::ExtendedGroup::computeF() { if (isValidF) return NOX::Abstract::Group::Ok; string callingFunction = "LOCA::TurningPoint::MooreSpence::ExtendedGroup::computeF()"; NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok; NOX::Abstract::Group::ReturnType status; // Compute underlying F if (!grpPtr->isF()) { status = grpPtr->computeF(); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); } *(fVec->getXVec()) = grpPtr->getF(); // Compute underlying Jacobian if (!grpPtr->isJacobian()) { status = grpPtr->computeJacobian(); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); } // Compute J*n status = grpPtr->applyJacobian(*(xVec->getNullVec()), *(fVec->getNullVec())); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Compute phi^T*n fVec->getBifParam() = lTransNorm(*(xVec->getNullVec())) - 1.0; isValidF = true; return finalStatus; }
void LOCA::TurningPoint::MooreSpence::ExtendedGroup::init(bool perturbSoln, double perturbSize) { xVec->getBifParam() = getBifParam(); // Rescale null vector scaleNullVector(*lengthVec); // Rescale length vector so that the normalization condition is met double lVecDotNullVec = lTransNorm(*(xVec->getNullVec())); if (lVecDotNullVec == 0.0) { globalData->locaErrorCheck->throwError( "LOCA::TurningPoint::MooreSpence::ExtendedGroup::init()", "null vector can be orthogonal to length-scaling vector"); } if (globalData->locaUtils->isPrintType(NOX::Utils::StepperDetails)) { globalData->locaUtils->out() << "\tIn LOCA::TurningPoint::MooreSpence::ExtendedGroup::init(), " << "scaling null vector by:" << globalData->locaUtils->sciformat(1.0 / lVecDotNullVec) << std::endl; } xVec->getNullVec()->scale(1.0/lVecDotNullVec); if (perturbSoln) { if (globalData->locaUtils->isPrintType(NOX::Utils::StepperDetails)) { globalData->locaUtils->out() << "\tIn LOCA::TurningPoint::MooreSpence::ExtendedGroup::init(), " << "applying random perturbation to initial solution of size: " << globalData->locaUtils->sciformat(perturbSize) << endl; } Teuchos::RCP<NOX::Abstract::Vector> perturb = xVec->getXVec()->clone(NOX::ShapeCopy); perturb->random(); perturb->scale(*(xVec->getXVec())); xVec->getXVec()->update(perturbSize, *perturb, 1.0); grpPtr->setX(*(xVec->getXVec())); } }
NOX::Abstract::Group::ReturnType LOCA::TurningPoint::MooreSpence::ExtendedGroup::computeDfDpMulti( const vector<int>& paramIDs, NOX::Abstract::MultiVector& dfdp, bool isValid_F) { string callingFunction = "LOCA::TurningPoint::MooreSpence::ExtendedGroup::computeDfDpMulti()"; NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok; NOX::Abstract::Group::ReturnType status; // Cast dfdp to TP vector LOCA::TurningPoint::MooreSpence::ExtendedMultiVector& tp_dfdp = dynamic_cast<LOCA::TurningPoint::MooreSpence::ExtendedMultiVector&>(dfdp); // Compute df/dp status = grpPtr->computeDfDpMulti(paramIDs, *tp_dfdp.getXMultiVec(), isValid_F); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Compute d(Jn)/dp status = grpPtr->computeDJnDpMulti(paramIDs, *(xVec->getNullVec()), *tp_dfdp.getNullMultiVec(), isValid_F); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Set parameter components if (!isValid_F) tp_dfdp.getScalar(0,0) = lTransNorm(*(xVec->getNullVec())); for (int i=0; i<dfdp.numVectors()-1; i++) tp_dfdp.getScalar(0,i+1) = 0.0; return finalStatus; }
void LOCA::TurningPoint::MooreSpence::ExtendedGroup::preProcessContinuationStep( LOCA::Abstract::Iterator::StepStatus stepStatus) { // Rescale length vector so that the normalization condition is met double lVecDotNullVec = lTransNorm(*(xVec->getNullVec())); if (lVecDotNullVec == 0.0) { globalData->locaErrorCheck->throwError( "LOCA::TurningPoint::MooreSpence::ExtendedGroup::preProcessContinuationStep()", "null vector can be orthogonal to length-scaling vector"); } if (globalData->locaUtils->isPrintType(NOX::Utils::StepperDetails)) { globalData->locaUtils->out() << "\tIn LOCA::TurningPoint::MooreSpence::ExtendedGroup::preProcessContinuationStep(), " << "scaling null vector by:" << globalData->locaUtils->sciformat(1.0 / lVecDotNullVec) << std::endl; } if (updateVectorsEveryContinuationStep) { xVec->getNullVec()->scale(1.0/lVecDotNullVec); } grpPtr->preProcessContinuationStep(stepStatus); }
NOX::Abstract::Group::ReturnType LOCA::TurningPoint::MooreSpence::ExtendedGroup::applyJacobianMultiVector( const NOX::Abstract::MultiVector& input, NOX::Abstract::MultiVector& result) const { string callingFunction = "LOCA::TurningPoint::MooreSpence::ExtendedGroup::applyJacobianMultiVector()"; NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok; NOX::Abstract::Group::ReturnType status; if (!isJacobian()) { globalData->locaErrorCheck->throwError(callingFunction, "Called with invalid Jacobian!"); } // Cast vectors to TP vectors const LOCA::TurningPoint::MooreSpence::ExtendedMultiVector& tp_input = dynamic_cast<const LOCA::TurningPoint::MooreSpence::ExtendedMultiVector&>(input); LOCA::TurningPoint::MooreSpence::ExtendedMultiVector& tp_result = dynamic_cast<LOCA::TurningPoint::MooreSpence::ExtendedMultiVector&>(result); // Get constant references to input vector components Teuchos::RCP<const NOX::Abstract::MultiVector> input_x = tp_input.getXMultiVec(); Teuchos::RCP<const NOX::Abstract::MultiVector> input_null = tp_input.getNullMultiVec(); Teuchos::RCP<const NOX::Abstract::MultiVector::DenseMatrix> input_param = tp_input.getScalars(); // Get non-constant references to result vector components Teuchos::RCP<NOX::Abstract::MultiVector> result_x = tp_result.getXMultiVec(); Teuchos::RCP<NOX::Abstract::MultiVector> result_null = tp_result.getNullMultiVec(); Teuchos::RCP<NOX::Abstract::MultiVector::DenseMatrix> result_param = tp_result.getScalars(); // Temporary vector Teuchos::RCP<NOX::Abstract::MultiVector> tmp = input_null->clone(NOX::ShapeCopy); // verify underlying Jacobian is valid if (!grpPtr->isJacobian()) { status = grpPtr->computeJacobian(); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); } // compute J*x status = grpPtr->applyJacobianMultiVector(*input_x, *result_x); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // compute J*x + p*dR/dp result_x->update(Teuchos::NO_TRANS, 1.0, *(dfdpMultiVec->getXMultiVec()), *input_param, 1.0); // compute J*y status = grpPtr->applyJacobianMultiVector(*input_null, *result_null); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // compute J*y + p*dJy/dp result_null->update(Teuchos::NO_TRANS, 1.0, *(dfdpMultiVec->getNullMultiVec()), *input_param, 1.0); // compute (dJy/dx)*x status = grpPtr->computeDJnDxaMulti(*(xVec->getNullVec()), *(fVec->getNullVec()), *input_x, *tmp); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // compute (dJy/dx)*x + J*y + p*dJy/dp result_null->update(1.0, *tmp, 1.0); // compute l^T*y lTransNorm(*input_null, *result_param); return finalStatus; }