Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}