예제 #1
0
NOX::Abstract::Group::ReturnType 
LOCA::DerivUtils::computeDwtJnDx(LOCA::MultiContinuation::AbstractGroup& grp,
				 const NOX::Abstract::MultiVector& w,
				 const NOX::Abstract::Vector& nullVector,
				 NOX::Abstract::MultiVector& result) const
{
  string callingFunction = 
    "LOCA::DerivUtils::computeDwtJnDx()";
  NOX::Abstract::Group::ReturnType status, finalStatus;

  // Vector to store w^T*J
  Teuchos::RCP<NOX::Abstract::MultiVector> wtJ = 
    w.clone(NOX::ShapeCopy);
  
  // Compute base w^T*J
  finalStatus = grp.computeJacobian();
  globalData->locaErrorCheck->checkReturnType(finalStatus, callingFunction);

  status = grp.applyJacobianTransposeMultiVector(w, *wtJ);
  finalStatus = 
    globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus,
							   callingFunction);
  
  // Copy original solution vector
  Teuchos::RCP<NOX::Abstract::Vector> Xvec = 
    grp.getX().clone(NOX::DeepCopy);

  // Perturb solution vector in direction of nullVector, return perturbation
  double eps = perturbXVec(grp, *Xvec, nullVector);

  // Fill perturbed w^T*J vector
  finalStatus = grp.computeJacobian();
  globalData->locaErrorCheck->checkReturnType(finalStatus, callingFunction);
    
  status = grp.applyJacobianTransposeMultiVector(w, result);
  finalStatus = 
    globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							   finalStatus,
							   callingFunction);

  // Difference perturbed and base vector 
  result.update(-1.0, *wtJ, 1.0);
  result.scale(1.0/eps);
  
  // Restore original solution vector
  grp.setX(*Xvec);

  return finalStatus;
}
NOX::Abstract::Group::ReturnType
LOCA::MultiContinuation::ConstraintInterfaceMVDX::addDX(
                      Teuchos::ETransp transb,
                  double alpha,
                      const NOX::Abstract::MultiVector::DenseMatrix& b,
                  double beta,
                  NOX::Abstract::MultiVector& result_x) const
{
  if (!isDXZero()) {
    const NOX::Abstract::MultiVector* dgdx = getDX();
    result_x.update(transb, alpha, *dgdx, b, beta);
  }
  else
    result_x.scale(beta);

  return NOX::Abstract::Group::Ok;
}
void
LOCA::BorderedSolver::HouseholderQR::computeHouseholderVector(
              int col,
              const NOX::Abstract::MultiVector::DenseMatrix& A1,
              const NOX::Abstract::MultiVector& A2,
              NOX::Abstract::MultiVector::DenseMatrix& V1,
              NOX::Abstract::MultiVector& V2,
              double& beta)
{
  double houseP = A1(col,col);

  V1(0,0) = 1.0;
  V2[0] = A2[col];

  double sigma = A2[col].innerProduct(A2[col]);
  for (int i=col+1; i<A1.numRows(); i++)
    sigma += A1(i,col)*A1(i,col);

  if (sigma == 0.0)
    beta = 0.0;
  else {
    double mu = sqrt(houseP*houseP + sigma);
    if (houseP <= 0.0)
      houseP = houseP - mu;
    else
      houseP = -sigma / (houseP + mu);
    beta = 2.0*houseP*houseP/(sigma + houseP*houseP);

    V2.scale(1.0/houseP);
    for (int i=1; i<V1.numRows(); i++)
      V1(i,0) = A1(i+col,col) / houseP;
  }


  return;
}
NOX::Abstract::Group::ReturnType
LOCA::MultiContinuation::CompositeConstraint::addDX(
		              Teuchos::ETransp transb,
			      double alpha, 
	                      const NOX::Abstract::MultiVector::DenseMatrix& b,
			      double beta,
			      NOX::Abstract::MultiVector& result_x) const
{
  std::string callingFunction = 
    "LOCA::MultiContinuation::CompositeConstraint::addDX()";
  NOX::Abstract::Group::ReturnType status;
  NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok;

  // First scale result_x
  result_x.scale(beta);

  // If dg/dx is zero for every constraint, result_x = beta * result_x
  if (isDXZero())
    return finalStatus;

  Teuchos::RCP<NOX::Abstract::MultiVector::DenseMatrix> b_sub;
  Teuchos::RCP<NOX::Abstract::MultiVector> result_x_sub;
  int num_rows;
  int num_cols = result_x.numVectors();
  for (int j=0; j<numConstraintObjects; j++) {
      
    if (!constraintPtrs[j]->isDXZero()) {

      // Create a sub view of rows indices[j][0] -- indices[j][end],
      // of b or b^T
      num_rows = constraintPtrs[j]->numConstraints();
      if (transb == Teuchos::NO_TRANS) {
	b_sub = 
	  Teuchos::rcp(new NOX::Abstract::MultiVector::DenseMatrix(
							       Teuchos::View,
							       b,
							       num_rows,
							       num_cols,
							       indices[j][0],
							       0));
      }
      else {
	b_sub = 
	  Teuchos::rcp(new NOX::Abstract::MultiVector::DenseMatrix(
							       Teuchos::View,
							       b,
							       num_cols,
							       num_rows,
							       0,
							       indices[j][0]));
      }
	
      // Compute result_x = result_x + alpha*(dg/dx)_j*op(b)_j
      status = constraintPtrs[j]->addDX(transb, alpha, *b_sub, 1.0, 
					result_x);
      finalStatus = 
	globalData->locaErrorCheck->combineAndCheckReturnTypes(
							     status, 
							     finalStatus,
							     callingFunction);
    }

  }

  return finalStatus;
}