void 
LOCA::Extended::MultiVector::multiply(
			    double alpha, 
			    const LOCA::Extended::MultiVector& y,
			    NOX::Abstract::MultiVector::DenseMatrix& b) const
{
  // Verify dimensions are consistent
  if (y.numMultiVecRows != numMultiVecRows || y.numColumns != b.numRows() ||
      y.numScalarRows != numScalarRows || numColumns != b.numCols()) 
    globalData->locaErrorCheck->throwError(
  "LOCA::Extended::MultiVector::multiply()",
  "Size of supplied multivector/matrix is incompatible with this multivector");

  // Zero out b
  b.putScalar(0.0);

  // Create temporary matrix to hold product for each multivec
  NOX::Abstract::MultiVector::DenseMatrix tmp(b);

  // Compute and sum products for each multivec
  for (int i=0; i<numMultiVecRows; i++) {
    multiVectorPtrs[i]->multiply(alpha, *(y.multiVectorPtrs[i]), tmp);
    b += tmp;
  }

  // Compute and add in product for scalars
  if (numScalarRows > 0)
    b.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, alpha, *y.scalarsPtr,
	       *scalarsPtr, 1.0);

}
Beispiel #2
0
void
LOCA::Homotopy::DeflatedGroup::
extractParameterComponent(bool use_transpose,
			  const NOX::Abstract::MultiVector& v,
			  NOX::Abstract::MultiVector::DenseMatrix& v_p) const
{
  // cast v to an extended multi-vec
  const LOCA::MultiContinuation::ExtendedMultiVector& mc_v = 
    dynamic_cast<const LOCA::MultiContinuation::ExtendedMultiVector&>(v);
  
  // get solution and parameter components
  Teuchos::RCP<const NOX::Abstract::MultiVector> mc_v_x =
    mc_v.getXMultiVec();
  Teuchos::RCP<const NOX::Abstract::MultiVector::DenseMatrix> mc_v_p =
    mc_v.getScalars();

  // If the underlying system isn't bordered, we're done
  if (!isBordered) {
    if (!use_transpose)
      v_p.assign(*mc_v_p);
    else
      for (int j=0; j<v_p.numCols(); j++)
	for (int i=0; i<v_p.numRows(); i++)
	  v_p(i,j) = (*mc_v_p)(j,i);
    return;
  }

  int w = bordered_grp->getBorderedWidth();
  if (!use_transpose) {
    // Split v_p into 2 block rows, the top to store mc_v_x_p and the bottom
    // to store mc_v_p
    int num_cols = v_p.numCols();
    NOX::Abstract::MultiVector::DenseMatrix v_p_1(Teuchos::View, v_p,
						  w, num_cols, 0, 0);
    NOX::Abstract::MultiVector::DenseMatrix v_p_2(Teuchos::View, v_p,
						  1, num_cols, w, 0);

    // Decompose mc_v_x
    bordered_grp->extractParameterComponent(use_transpose,*mc_v_x, v_p_1);
    v_p_2.assign(*mc_v_p);
  }
  else {
    // Split v_p into 2 block columns, the first to store mc_v_x_p^t and the 
    // the second to store mc_v_p^T
    int num_rows = v_p.numRows();
    NOX::Abstract::MultiVector::DenseMatrix v_p_1(Teuchos::View, v_p,
						  num_rows, w, 0, 0);
    NOX::Abstract::MultiVector::DenseMatrix v_p_2(Teuchos::View, v_p,
						  num_rows, 1, 0, w);

    // Decompose mc_v_x
    bordered_grp->extractParameterComponent(use_transpose,*mc_v_x, v_p_1);
    for (int j=0; j<1; j++)
      for (int i=0; i<num_rows; i++)
	v_p_2(i,j) = (*mc_v_p)(j,i);
  }
}
NOX::Abstract::Group::ReturnType
LOCA::MultiContinuation::CompositeConstraint::multiplyDX(
		      double alpha, 
		      const NOX::Abstract::MultiVector& input_x,
	              NOX::Abstract::MultiVector::DenseMatrix& result_p) const
{
  std::string callingFunction = 
    "LOCA::MultiContinuation::CompositeConstraint::multiplyDX()";
  NOX::Abstract::Group::ReturnType status;
  NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok;

  // If dg/dx is zero for every constraint, result_p is zero
  if (isDXZero()) {
    result_p.putScalar(0.0);
    return finalStatus;
  }

  Teuchos::RCP<NOX::Abstract::MultiVector::DenseMatrix> result_p_sub;
  int num_rows;
  int num_cols = result_p.numCols();
  for (int i=0; i<numConstraintObjects; i++) {

    num_rows = constraintPtrs[i]->numConstraints();

    // if dg/dx is zero for this constraint, set corresponding entries of
    // result_p to zero
    if (constraintPtrs[i]->isDXZero()) {
      for (int j=0; j<num_rows; j++)
	for (int k=0; k<num_cols; k++)
	  result_p(indices[i][j],k) = 0.0;
    }
    else {

      // Create a sub view of rows indices[i][0] -- indices[i][end] 
      // of result_p 
      result_p_sub = 
	Teuchos::rcp(new NOX::Abstract::MultiVector::DenseMatrix(Teuchos::View,
								 result_p,
								 num_rows,
								 num_cols,
								 indices[i][0],
								 0));

      status = constraintPtrs[i]->multiplyDX(alpha, input_x, 
					     *result_p_sub);
      finalStatus = 
	globalData->locaErrorCheck->combineAndCheckReturnTypes(
							     status, 
							     finalStatus,
							     callingFunction);
    }

  }

  return finalStatus;
}
void
LOCA::BorderedSolver::HouseholderQR::applyCompactWY(
                const NOX::Abstract::MultiVector::DenseMatrix& Y1,
                const NOX::Abstract::MultiVector& Y2,
                const NOX::Abstract::MultiVector::DenseMatrix& T,
                NOX::Abstract::MultiVector::DenseMatrix& X1,
                NOX::Abstract::MultiVector& X2,
                bool isZeroX1, bool isZeroX2,
                bool useTranspose) const
{
  if (isZeroX1 && isZeroX2) {
    X1.putScalar(0.0);
    X2.init(0.0);
    return;
  }

  int m = Y2.numVectors();

  Teuchos::ETransp T_flag;
  if (useTranspose)
    T_flag = Teuchos::TRANS;
  else
    T_flag = Teuchos::NO_TRANS;

  NOX::Abstract::MultiVector::DenseMatrix tmp(m, X2.numVectors());

  // Compute Y1^T*X1 + Y2^T*X2
  if (!isZeroX2)
    X2.multiply(1.0, Y2, tmp);

  // Opportunity for optimization here since Y1 is a lower-triangular
  // matrix with unit diagonal
  if (!isZeroX2 && !isZeroX1)
    tmp.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, Y1, X1, 1.0);
  else if (!isZeroX1)
    tmp.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, Y1, X1, 0.0);

  // Compute op(T)*(Y1^T*X1 + Y2^T*X2)
  dblas.TRMM(Teuchos::LEFT_SIDE, Teuchos::UPPER_TRI, T_flag,
         Teuchos::NON_UNIT_DIAG, tmp.numRows(), tmp.numCols(), 1.0,
         T.values(), T.numRows(), tmp.values(), tmp.numRows());

  // Compute X1 = X1 + Y1*op(T)*(Y1^T*X1 + Y2^T*X2)
  // Opportunity for optimization here since Y1 is a lower-triangular
  // matrix with unit diagonal
  if (isZeroX1)
    X1.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, Y1, tmp, 0.0);
  else
    X1.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, Y1, tmp, 1.0);

  // Compute X2 = X2 + Y1*op(T)*(Y1^T*X1 + Y2^T*X2)
  if (isZeroX2)
    X2.update(Teuchos::NO_TRANS, 1.0, Y2, tmp, 0.0);
  else
    X2.update(Teuchos::NO_TRANS, 1.0, Y2, tmp, 1.0);
}
Beispiel #5
0
NOX::Abstract::Group::ReturnType 
LOCA::BorderedSolver::Nested::applyInverseTranspose(
			      Teuchos::ParameterList& params,
			      const NOX::Abstract::MultiVector* F,
			      const NOX::Abstract::MultiVector::DenseMatrix* G,
			      NOX::Abstract::MultiVector& X,
			      NOX::Abstract::MultiVector::DenseMatrix& Y) const
{
  bool isZeroF = (F == NULL);
  bool isZeroG = (G == NULL);

  if (isZeroF && isZeroG) {
    X.init(0.0);
    Y.putScalar(0.0);
  }

  int num_cols = X.numVectors();  
  Teuchos::RCP<NOX::Abstract::MultiVector> FF;
  if (!isZeroF) 
    FF = unbordered_grp->getX().createMultiVector(num_cols);
  NOX::Abstract::MultiVector::DenseMatrix GG(myWidth, num_cols);  
  GG.putScalar(0.0);
  
  if (!isZeroF) {
    NOX::Abstract::MultiVector::DenseMatrix GG1(Teuchos::View, GG,
						underlyingWidth, num_cols, 
						0, 0);
    grp->extractSolutionComponent(*F, *FF);
    grp->extractParameterComponent(false, *F, GG1);
  }
  if (!isZeroG) {
    NOX::Abstract::MultiVector::DenseMatrix GG2(Teuchos::View, GG,
						numConstraints, num_cols, 
						underlyingWidth, 0);
    GG2.assign(*G);
  }

  Teuchos::RCP<NOX::Abstract::MultiVector> XX = 
    unbordered_grp->getX().createMultiVector(num_cols);
  NOX::Abstract::MultiVector::DenseMatrix YY(myWidth, num_cols);
  NOX::Abstract::MultiVector::DenseMatrix YY1(Teuchos::View, YY,
					      underlyingWidth, num_cols, 
					      0, 0);
  NOX::Abstract::MultiVector::DenseMatrix YY2(Teuchos::View, YY,
					      numConstraints, num_cols, 
					      underlyingWidth, 0);

  NOX::Abstract::Group::ReturnType status = 
    solver->applyInverseTranspose(params, FF.get(), &GG, *XX, YY);

  Y.assign(YY2);
  grp->loadNestedComponents(*XX, YY1, X);

  return status;
}
NOX::Abstract::Group::ReturnType
LOCA::TurningPoint::MinimallyAugmented::Constraint::
computeDP(const std::vector<int>& paramIDs, 
	  NOX::Abstract::MultiVector::DenseMatrix& dgdp, 
	  bool isValidG)
{
  std::string callingFunction = 
    "LOCA::TurningPoint::MinimallyAugmented::Constraint::computeDP()";
  NOX::Abstract::Group::ReturnType status;
  NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok;

  // Compute sigma, w and v if necessary
  if (!isValidConstraints) {
    status = computeConstraints();
    finalStatus = 
      globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							     finalStatus,
							     callingFunction);
  }

  // Compute -(w^T*J*v)_p
  status = grpPtr->computeDwtJnDp(paramIDs, (*w_vector)[0], (*v_vector)[0], 
				  dgdp, false);
  finalStatus = 
      globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							     finalStatus,
							     callingFunction);
  dgdp.scale(-1.0/sigma_scale);

  // Set the first column of dgdp
  dgdp(0,0) = constraints(0,0);

  return finalStatus;
}
Beispiel #7
0
int 
NOX::TestCompare::testMatrix(
		 const NOX::Abstract::MultiVector::DenseMatrix& mat, 
		 const NOX::Abstract::MultiVector::DenseMatrix& mat_expected, 
		 double rtol, double atol, 
		 const std::string& name)
{
  bool passed;

  NOX::Abstract::MultiVector::DenseMatrix tmp(mat_expected.numRows(),
					      mat_expected.numCols());

  for (int j=0; j<mat_expected.numCols(); j++)
    for (int i=0; i<mat_expected.numRows(); i++)
      tmp(i,j) = fabs(mat(i,j)-mat_expected(i,j)) / 
	(atol + rtol * fabs(mat_expected(i,j)));
 
  double inf_norm = tmp.normInf();

  if (inf_norm < 1)
    passed = true;
  else
    passed = false;

  if (utils.isPrintType(NOX::Utils::TestDetails)) {
    os << std::endl
	 << "\tChecking " << name << ":  ";
    if (passed)
      os << "Passed." << std::endl;
    else
      os << "Failed." << std::endl;
    os << "\t\tComputed norm:        " << utils.sciformat(inf_norm) 
       << std::endl
       << "\t\tRelative Tolerance:   " << utils.sciformat(rtol) 
       << std::endl
       << "\t\tAbsolute Tolerance:   " << utils.sciformat(rtol) 
       << std::endl;
  }

  if (passed)
    return 0;
  else
    return 1;
}
LOCA::MultiContinuation::ExtendedMultiVector::ExtendedMultiVector(
		     const Teuchos::RCP<LOCA::GlobalData>& global_data,
		     const NOX::Abstract::MultiVector& xVec,
		     const NOX::Abstract::MultiVector::DenseMatrix& params) :
  LOCA::Extended::MultiVector(global_data, xVec.numVectors(), 1, 
			      params.numRows())
{
  LOCA::Extended::MultiVector::setMultiVectorPtr(0, xVec.clone(NOX::DeepCopy));
  LOCA::Extended::MultiVector::getScalars()->assign(params);
}
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;
}
Beispiel #10
0
void
LOCA::Hopf::MinimallyAugmented::ExtendedGroup::
fillC(NOX::Abstract::MultiVector::DenseMatrix& C) const
{
  string callingFunction = 
    "LOCA::Hopf::MinimallyAugmented::ExtendedGroup::fillC";

  Teuchos::RCP<const NOX::Abstract::MultiVector::DenseMatrix> my_C = 
    dfdpMultiVec->getScalars();

  // If the underlying system isn't bordered, we're done
  if (!isBordered) {
    C.assign(*my_C);
    return;
  }

  Teuchos::RCP<const NOX::Abstract::MultiVector> my_B = 
    Teuchos::rcp(constraintsPtr->getDX(),false);

  Teuchos::RCP<const NOX::Abstract::MultiVector> my_A = 
    dfdpMultiVec->getXMultiVec();
  
  // Create views for underlying group
  int w = bordered_grp->getBorderedWidth();
  NOX::Abstract::MultiVector::DenseMatrix underlyingC(Teuchos::View, C,
						      w, w, 0, 0);

  // Combine blocks in underlying group
  bordered_grp->fillC(underlyingC);

  // Create views for my blocks
  NOX::Abstract::MultiVector::DenseMatrix my_A_p(Teuchos::View, C,
						 w, 2, 0, w);
  NOX::Abstract::MultiVector::DenseMatrix my_B_p(Teuchos::View, C,
						 2, w, w, 0);
  NOX::Abstract::MultiVector::DenseMatrix my_CC(Teuchos::View, C,
						2, 2, w, w);

  // Extract solution component from my_A and store in my_A_p
  bordered_grp->extractParameterComponent(false, *my_A, my_A_p);

  // Extract solution component from my_B and store in my_B_p
  bordered_grp->extractParameterComponent(true, *my_B, my_B_p);

  // Copy in my_C
  my_CC.assign(*my_C);
}
Beispiel #11
0
void
LOCA::Homotopy::DeflatedGroup::
fillC(NOX::Abstract::MultiVector::DenseMatrix& C) const
{
  string callingFunction = 
    "LOCA::Homotopy::DeflatedGroup::fillC";

  Teuchos::RCP<const NOX::Abstract::MultiVector::DenseMatrix> my_C = 
    minusOne;

  // If the underlying system isn't bordered, we're done
  if (!isBordered) {
    C.assign(*my_C);
    return;
  }

  Teuchos::RCP<const NOX::Abstract::MultiVector> my_B = 
    totalDistMultiVec;

  Teuchos::RCP<const NOX::Abstract::MultiVector> my_A = 
    underlyingF;
  
  // Create views for underlying group
  int w = bordered_grp->getBorderedWidth();
  NOX::Abstract::MultiVector::DenseMatrix underlyingC(Teuchos::View, C,
						      w, w, 0, 0);

  // Combine blocks in underlying group
  bordered_grp->fillC(underlyingC);

  // Create views for my blocks
  NOX::Abstract::MultiVector::DenseMatrix my_A_p(Teuchos::View, C,
						 w, 1, 0, w);
  NOX::Abstract::MultiVector::DenseMatrix my_B_p(Teuchos::View, C,
						 1, w, w, 0);
  NOX::Abstract::MultiVector::DenseMatrix my_CC(Teuchos::View, C,
						1, 1, w, w);

  // Extract solution component from my_A and store in my_A_p
  bordered_grp->extractParameterComponent(false, *my_A, my_A_p);

  // Extract solution component from my_B and store in my_B_p
  bordered_grp->extractParameterComponent(true, *my_B, my_B_p);

  // Copy in my_C
  my_CC.assign(*my_C);
}
Beispiel #12
0
NOX::Abstract::Group::ReturnType
LOCA::Hopf::MinimallyAugmented::Constraint::
computeDOmega(NOX::Abstract::MultiVector::DenseMatrix& domega)
{
  string callingFunction = 
    "LOCA::Hopf::MinimallyAugmented::Constraint::computeDOmega()";
  NOX::Abstract::Group::ReturnType status;
  NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok;

  // Compute sigma, w and v if necessary
  if (!isValidConstraints) {
    status = computeConstraints();
    finalStatus = 
      globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							     finalStatus,
							     callingFunction);
  }

  // Compute mass matrix M
  status = grpPtr->computeShiftedMatrix(0.0, 1.0);
  finalStatus = 
    globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							   finalStatus,
							   callingFunction);

  // Compute M*v
  Teuchos::RCP<NOX::Abstract::MultiVector> tmp_vector =
    v_vector->clone(NOX::ShapeCopy);
  status = grpPtr->applyShiftedMatrixMultiVector(*v_vector, *tmp_vector);
  finalStatus = 
    globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							   finalStatus,
							   callingFunction);

  // Compute u^T*M*v
  NOX::Abstract::MultiVector::DenseMatrix tmp_mat(2,2);
  tmp_vector->multiply(1.0, *w_vector, tmp_mat);

  // Compute domega
  domega(0,0) =   tmp_mat(0,1) - tmp_mat(1,0);
  domega(1,0) = -(tmp_mat(0,0) + tmp_mat(1,1));

  domega.scale(1.0/sigma_scale);

  return finalStatus;
}
NOX::Abstract::Group::ReturnType
LOCA::MultiContinuation::ConstraintInterfaceMVDX::multiplyDX(
               double alpha,
               const NOX::Abstract::MultiVector& input_x,
               NOX::Abstract::MultiVector::DenseMatrix& result_p) const
{


  if (!isDXZero()) {
    const NOX::Abstract::MultiVector* dgdx = getDX();
    input_x.multiply(alpha, *dgdx, result_p);
  }
  else
    result_p.putScalar(0.0);

  return NOX::Abstract::Group::Ok;
}
Beispiel #14
0
NOX::Abstract::Group::ReturnType
LOCA::Hopf::MinimallyAugmented::Constraint::
computeDP(const vector<int>& paramIDs, 
	  NOX::Abstract::MultiVector::DenseMatrix& dgdp, 
	  bool isValidG)
{
  string callingFunction = 
    "LOCA::Hopf::MinimallyAugmented::Constraint::computeDP()";
  NOX::Abstract::Group::ReturnType status;
  NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok;

  // Compute sigma, w and v if necessary
  if (!isValidConstraints) {
    status = computeConstraints();
    finalStatus = 
      globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							     finalStatus,
							     callingFunction);
  }

  // Compute -(w^T*J*v)_p
  NOX::Abstract::MultiVector::DenseMatrix dgdp_real(Teuchos::View, dgdp,
						    1, paramIDs.size()+1,
						    0, 0);
  NOX::Abstract::MultiVector::DenseMatrix dgdp_imag(Teuchos::View, dgdp,
						    1, paramIDs.size()+1,
						    1, 0);
  status = grpPtr->computeDwtCeDp(paramIDs, 
				  (*w_vector)[0], (*w_vector)[1],
				  (*v_vector)[0], (*v_vector)[1],
				  omega, 
				  dgdp_real, dgdp_imag, false);
  finalStatus = 
      globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							     finalStatus,
							     callingFunction);
  dgdp.scale(-1.0/sigma_scale);

  // Set the first column of dgdp
  dgdp(0,0) = constraints(0,0);
  dgdp(1,0) = constraints(1,0);

  return finalStatus;
}
Beispiel #15
0
NOX::Abstract::Group::ReturnType 
LOCA::BorderedSolver::Nested::applyTranspose(
			  const NOX::Abstract::MultiVector& X,
			  const NOX::Abstract::MultiVector::DenseMatrix& Y,
			  NOX::Abstract::MultiVector& U,
			  NOX::Abstract::MultiVector::DenseMatrix& V) const
{
  int num_cols = X.numVectors();
  Teuchos::RCP<NOX::Abstract::MultiVector> XX = 
    unbordered_grp->getX().createMultiVector(num_cols);
  Teuchos::RCP<NOX::Abstract::MultiVector> UU = 
    unbordered_grp->getX().createMultiVector(num_cols);
  NOX::Abstract::MultiVector::DenseMatrix YY(myWidth, num_cols);
  NOX::Abstract::MultiVector::DenseMatrix VV(myWidth, num_cols);
  NOX::Abstract::MultiVector::DenseMatrix YY1(Teuchos::View, YY,
					      underlyingWidth, num_cols, 
					      0, 0);
  NOX::Abstract::MultiVector::DenseMatrix YY2(Teuchos::View, YY,
					      numConstraints, num_cols, 
					      underlyingWidth, 0);
  NOX::Abstract::MultiVector::DenseMatrix VV1(Teuchos::View, VV,
					      underlyingWidth, num_cols, 
					      0, 0);
  NOX::Abstract::MultiVector::DenseMatrix VV2(Teuchos::View, VV,
					      numConstraints, num_cols, 
					      underlyingWidth, 0);
  
  grp->extractSolutionComponent(X, *XX);
  grp->extractParameterComponent(false, X, YY1);
  YY2.assign(Y);

  NOX::Abstract::Group::ReturnType status = 
    solver->applyTranspose(*XX, YY, *UU, VV);

  V.assign(VV2);
  grp->loadNestedComponents(*UU, VV1, U);

  return status;
}
// =============================================================================
// Compute result_p = alpha * dg/dx * input_x.
NOX::Abstract::Group::ReturnType
Ginla::FDM::Constraint::MinDist::
multiplyDX ( double                                    alpha,
             const NOX::Abstract::MultiVector        & input_x,
             NOX::Abstract::MultiVector::DenseMatrix & result_p
           ) const
{ 
  TEUCHOS_ASSERT( komplex_.is_valid_ptr() && !komplex_.is_null() );
  
  TEUCHOS_ASSERT_EQUALITY( result_p.numCols(), input_x.numVectors() );
  
  for ( int k=0; k<input_x.numVectors(); k++ )
  {
      const Epetra_Vector & xE =
              Teuchos::dyn_cast<const NOX::Epetra::Vector>( input_x[0] ).getEpetraVector();
      Teuchos::RCP<ComplexVector> xPsi = komplex_->real2complex( xE );

      result_p(0,k) = alpha * std::imag( psiRef_->dot(*xPsi) );
  }
  
  return NOX::Abstract::Group::Ok;
}
void
LOCA::BorderedSolver::HouseholderQR::applyCompactWY(
             const NOX::Abstract::MultiVector::DenseMatrix& Y1,
             const NOX::Abstract::MultiVector& Y2,
             const NOX::Abstract::MultiVector::DenseMatrix& T,
             const NOX::Abstract::MultiVector::DenseMatrix* input1,
             const NOX::Abstract::MultiVector* input2,
             NOX::Abstract::MultiVector::DenseMatrix& result1,
             NOX::Abstract::MultiVector& result2,
             bool useTranspose) const
{
  bool isZeroX1 = (input1 == NULL);
  bool isZeroX2 = (input2 == NULL);

  if (!isZeroX1)
    result1.assign(*input1);
  if (!isZeroX2)
    result2 = *input2;

  applyCompactWY(Y1, Y2, T, result1, result2, isZeroX1, isZeroX2,
         useTranspose);
}
void
LOCA::BorderedSolver::HouseholderQR::applyHouseholderVector(
               const NOX::Abstract::MultiVector::DenseMatrix& V1,
               const NOX::Abstract::MultiVector& V2,
               double beta,
               NOX::Abstract::MultiVector::DenseMatrix& A1,
               NOX::Abstract::MultiVector& A2)
{
  int nColsA = A2.numVectors();

  // Compute u = V2^T * A2
  NOX::Abstract::MultiVector::DenseMatrix u(1, nColsA);
  A2.multiply(1.0, V2, u);

  // Compute u = u + V1^T * A_P
  u.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, V1, A1, 1.0);

  // Compute A1 = A1 - b*V1*u
  A1.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, -beta, V1, u, 1.0);

  // Compute A2 = A2 - b*V2*u
  A2.update(Teuchos::NO_TRANS, -beta, V2, u, 1.0);
}
Beispiel #19
0
void
LOCA::Homotopy::DeflatedGroup::
loadNestedComponents(const NOX::Abstract::MultiVector& v_x,
		     const NOX::Abstract::MultiVector::DenseMatrix& v_p,
		     NOX::Abstract::MultiVector& v) const
{
  // cast X to an extended multi-vec
  LOCA::MultiContinuation::ExtendedMultiVector& mc_v = 
    dynamic_cast<LOCA::MultiContinuation::ExtendedMultiVector&>(v);

  // get solution and parameter components
  Teuchos::RCP<NOX::Abstract::MultiVector> mc_v_x =
    mc_v.getXMultiVec();
  Teuchos::RCP<NOX::Abstract::MultiVector::DenseMatrix> mc_v_p =
    mc_v.getScalars();

  // If the underlying system isn't bordered, we're done
  if (!isBordered) {
    *mc_v_x = v_x;
    mc_v_p->assign(v_p);
    return;
  }

  // split v_p
  int num_cols = v_p.numCols();
  int w = bordered_grp->getBorderedWidth();
  NOX::Abstract::MultiVector::DenseMatrix v_p_1(Teuchos::View, v_p,
						w, num_cols, 0, 0);
  NOX::Abstract::MultiVector::DenseMatrix v_p_2(Teuchos::View, v_p,
						1, num_cols, w, 0);

  // load v_x, v_p_1 into mc_v_x
  bordered_grp->loadNestedComponents(v_x, v_p_1, *mc_v_x);

  // load v_p_2 into mc_v_p
  mc_v_p->assign(v_p_2);
}
NOX::Abstract::Group::ReturnType
LOCA::MultiContinuation::CompositeConstraint::computeDP(
		                const std::vector<int>& paramIDs, 
		                NOX::Abstract::MultiVector::DenseMatrix& dgdp, 
				bool isValidG)
{
   std::string callingFunction = 
    "LOCA::MultiContinuation::CompositeConstraint::computeDP()";
  NOX::Abstract::Group::ReturnType status;
  NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok;

  Teuchos::RCP<NOX::Abstract::MultiVector::DenseMatrix> dgdp_sub;
  int num_rows;
  int num_cols = dgdp.numCols();
  for (int i=0; i<numConstraintObjects; i++) {

    // Create a sub view of rows indices[i][0] -- indices[i][end] of dgdp
    num_rows = indices[i][constraintPtrs[i]->numConstraints()-1] - 
      indices[i][0] + 1;
    dgdp_sub = 
      Teuchos::rcp(new NOX::Abstract::MultiVector::DenseMatrix(Teuchos::View,
							       dgdp,
							       num_rows,
							       num_cols,
							       indices[i][0],
							       0));

    status = constraintPtrs[i]->computeDP(paramIDs, *dgdp_sub, isValidG);
    finalStatus = 
      globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							     finalStatus,
							     callingFunction);
  }

  return finalStatus;
}
void
NOX::Thyra::MultiVector::
multiply(double alpha,
     const NOX::Abstract::MultiVector& y,
     NOX::Abstract::MultiVector::DenseMatrix& b) const
{
  const NOX::Thyra::MultiVector& yy =
    dynamic_cast<const NOX::Thyra::MultiVector&>(y);

  int m = b.numRows();
  int n = b.numCols();
  Teuchos::RCP< ::Thyra::MultiVectorBase<double> > bb =
    ::Thyra::createMembersView(
      yy.thyraMultiVec->domain(),
      RTOpPack::SubMultiVectorView<double>(0, m, 0, n,
        Teuchos::arcp(b.values(), 0, b.stride()*b.numCols(), false),
        b.stride()
        )
      );

  ::Thyra::apply(*yy.thyraMultiVec, ::Thyra::CONJTRANS, *thyraMultiVec,
                   bb.ptr(), alpha, 0.0);
}
void
LOCA::MultiContinuation::ConstrainedGroup::fillC(
	                     NOX::Abstract::MultiVector::DenseMatrix& C) const
{
  std::string callingFunction = 
    "LOCA::MultiContinuation::ConstrainedGroup::fillC";

  Teuchos::RCP<const NOX::Abstract::MultiVector::DenseMatrix> my_C = 
    dfdpMultiVec->getScalars();

  // If the underlying system isn't bordered, we're done
  if (!isBordered) {
    C.assign(*my_C);
    return;
  }

  bool isZeroB = constraintsPtr->isDXZero();
  Teuchos::RCP<const NOX::Abstract::MultiVector> my_B;

  if (!isZeroB) {
    Teuchos::RCP<const LOCA::MultiContinuation::ConstraintInterfaceMVDX> constraints_mvdx = Teuchos::rcp_dynamic_cast<const LOCA::MultiContinuation::ConstraintInterfaceMVDX>(constraintsPtr);
    if (constraints_mvdx == Teuchos::null)
      globalData->locaErrorCheck->throwError(
				callingFunction,
				std::string("Constraints object must be of type") +
				std::string("ConstraintInterfaceMVDX"));

    my_B = Teuchos::rcp(constraints_mvdx->getDX(),false);
  }

  Teuchos::RCP<const NOX::Abstract::MultiVector> my_A = 
    dfdpMultiVec->getXMultiVec();
  
  // Create views for underlying group
  int w = bordered_grp->getBorderedWidth();
  NOX::Abstract::MultiVector::DenseMatrix underlyingC(Teuchos::View, C,
						      w, w, 0, 0);

  // Combine blocks in underlying group
  bordered_grp->fillC(underlyingC);

  // Create views for my blocks
  NOX::Abstract::MultiVector::DenseMatrix my_A_p(Teuchos::View, C,
						 w, numParams, 0, w);
  NOX::Abstract::MultiVector::DenseMatrix my_B_p(Teuchos::View, C,
						 numParams, w, w, 0);
  NOX::Abstract::MultiVector::DenseMatrix my_CC(Teuchos::View, C,
						numParams, numParams, w, w);

  // Extract solution component from my_A and store in my_A_p
  bordered_grp->extractParameterComponent(false, *my_A, my_A_p);

  // Extract solution component from my_B and store in my_B_p
  if (isZeroB)
    my_B_p.putScalar(0.0);
  else
    bordered_grp->extractParameterComponent(true, *my_B, my_B_p);

  // Copy in my_C
  my_CC.assign(*my_C);
}
NOX::Abstract::Group::ReturnType 
LOCA::BorderedSolver::LowerTriangularBlockElimination::
solve(Teuchos::ParameterList& params,
      const LOCA::BorderedSolver::AbstractOperator& op,
      const LOCA::MultiContinuation::ConstraintInterface& B,
      const NOX::Abstract::MultiVector::DenseMatrix& C,
      const NOX::Abstract::MultiVector* F,
      const NOX::Abstract::MultiVector::DenseMatrix* G,
      NOX::Abstract::MultiVector& X,
      NOX::Abstract::MultiVector::DenseMatrix& Y) const
{
  string callingFunction = 
    "LOCA::BorderedSolver::LowerTriangularBlockElimination::solve()";
  NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok;
  NOX::Abstract::Group::ReturnType status;

  // Determine if X or Y is zero
  bool isZeroF = (F == NULL);
  bool isZeroG = (G == NULL);
  bool isZeroB = B.isDXZero();
  bool isZeroX = isZeroF;
  bool isZeroY = isZeroG && (isZeroB  || isZeroX);

  // First compute X
  if (isZeroX)
    X.init(0.0);
  else {
    // Solve X = J^-1 F, note F must be nonzero
    status = op.applyInverse(params, *F, X);
    finalStatus = 
      globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							     finalStatus,
							     callingFunction);
  }

  // Now compute Y
  if (isZeroY)
    Y.putScalar(0.0);
  else {
    // Compute G - B^T*X and store in Y
    if (isZeroG) 
      B.multiplyDX(-1.0, X, Y);
    else {
      Y.assign(*G);
      if (!isZeroB && !isZeroX) {
	NOX::Abstract::MultiVector::DenseMatrix T(Y.numRows(),Y.numCols());
	B.multiplyDX(1.0, X, T);
	Y -= T;
      }
    }

    // Overwrite Y with Y = C^-1 * (G - B^T*X)
    NOX::Abstract::MultiVector::DenseMatrix M(C);
    int *ipiv = new int[M.numRows()];
    Teuchos::LAPACK<int,double> L;
    int info;
    L.GETRF(M.numRows(), M.numCols(), M.values(), M.stride(), ipiv, &info);
    if (info != 0) {
      status = NOX::Abstract::Group::Failed;
      finalStatus = 
	globalData->locaErrorCheck->combineAndCheckReturnTypes(
							      status, 
							      finalStatus,
							      callingFunction);
    }
    L.GETRS('N', M.numRows(), Y.numCols(), M.values(), M.stride(), ipiv, 
	    Y.values(), Y.stride(), &info);
    delete [] ipiv;
    if (info != 0) {
      status = NOX::Abstract::Group::Failed;
      finalStatus = 
	globalData->locaErrorCheck->combineAndCheckReturnTypes(
							     status, 
							     finalStatus,
							     callingFunction);
    }
  }

  return finalStatus;
}
// Solves Hopf equations via classic Salinger bordering
// The first m columns of input_x, input_y, input_z store the RHS, the
// next column stores df/dp, (Jy-wBz)_p and (Jz+wBy)_p respectively, the
// last column of input_y and input_z store Bz and -By respectively.  Note 
// input_x has m+1 columns, input_y and input_z have m+2, and input_w and
// input_p have m columns.  result_x, result_y, result_z, result_w and 
// result_param have the same dimensions as their input counterparts
NOX::Abstract::Group::ReturnType 
LOCA::Hopf::MooreSpence::SalingerBordering::solveContiguous(
		      Teuchos::ParameterList& params,
		      const NOX::Abstract::MultiVector& input_x,
		      const NOX::Abstract::MultiVector& input_y,
		      const NOX::Abstract::MultiVector& input_z,
		      const NOX::Abstract::MultiVector::DenseMatrix& input_w,
		      const NOX::Abstract::MultiVector::DenseMatrix& input_p,
		      NOX::Abstract::MultiVector& result_x,
		      NOX::Abstract::MultiVector& result_y,
		      NOX::Abstract::MultiVector& result_z,
		      NOX::Abstract::MultiVector::DenseMatrix& result_w,
	              NOX::Abstract::MultiVector::DenseMatrix& result_p) const
{
  std::string callingFunction = 
    "LOCA::Hopf::MooreSpence::SalingerBordering::solveContiguous()";
  NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok;
  NOX::Abstract::Group::ReturnType status;

  int m = input_x.numVectors()-1;
  std::vector<int> index_input(m);
  std::vector<int> index_dp(1);
  std::vector<int> index_B(1);
  std::vector<int> index_ip(m+1);
  for (int i=0; i<m; i++) {
    index_input[i] = i;
    index_ip[i] = i;
  }
  index_ip[m] = m;
  index_dp[0] = m;
  index_B[0] = m+1;

  // verify underlying Jacobian is valid
  if (!group->isJacobian()) {
    status = group->computeJacobian();
    finalStatus = 
      globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							     finalStatus,
							     callingFunction);
  }
  
  // compute [A b] = J^-1 [F df/dp]
  status = group->applyJacobianInverseMultiVector(params, input_x, result_x);
  finalStatus = 
    globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus,
							   callingFunction);
  Teuchos::RCP<NOX::Abstract::MultiVector> A = 
    result_x.subView(index_input);
  Teuchos::RCP<NOX::Abstract::MultiVector> b = 
    result_x.subView(index_dp);

  // verify underlying complex matrix is valid
   if (!group->isComplex()) {
    status = group->computeComplex(w);
    finalStatus = 
      globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							     finalStatus,
							     callingFunction);
  }

  // compute (J+iwB)(y+iz)_x [A b]
  Teuchos::RCP<NOX::Abstract::MultiVector> tmp_real = 
    result_y.clone(NOX::ShapeCopy);
  Teuchos::RCP<NOX::Abstract::MultiVector> tmp_real_sub =
    tmp_real->subView(index_ip);
  Teuchos::RCP<NOX::Abstract::MultiVector> tmp_imag = 
    result_y.clone(NOX::ShapeCopy);
  Teuchos::RCP<NOX::Abstract::MultiVector> tmp_imag_sub =
    tmp_imag->subView(index_ip);
  tmp_real->init(0.0);
  tmp_imag->init(0.0);
  status = group->computeDCeDxa(*yVector, *zVector, w, result_x,
				*CeRealVector, *CeImagVector, *tmp_real_sub,
				*tmp_imag_sub);
  finalStatus = 
    globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus,
							   callingFunction);

  // compute [G+iH d(J+iwB)(y+iz)/dp iB(y+iz)] - [(J+iwB)_x[A b] 0+i0]
  tmp_real->update(1.0, input_y, -1.0);
  tmp_imag->update(1.0, input_z, -1.0);

  // verify underlying complex matrix is valid
  if (!group->isComplex()) {
    status = group->computeComplex(w);
    finalStatus = 
      globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							     finalStatus,
							     callingFunction);
  }

  // compute [C+iD e+if g+ih] = (J+iwB)^-1 (tmp_real + i tmp_imag)
  status = group->applyComplexInverseMultiVector(params, *tmp_real, *tmp_imag,
						 result_y, result_z);
  finalStatus = 
    globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus,
							   callingFunction);
  Teuchos::RCP<NOX::Abstract::MultiVector> C = 
    result_y.subView(index_input);
  Teuchos::RCP<NOX::Abstract::MultiVector> D = 
    result_z.subView(index_input);
  Teuchos::RCP<NOX::Abstract::MultiVector> e = 
    result_y.subView(index_dp);
  Teuchos::RCP<NOX::Abstract::MultiVector> f = 
    result_z.subView(index_dp);
  Teuchos::RCP<NOX::Abstract::MultiVector> g = 
    result_y.subView(index_B);
  Teuchos::RCP<NOX::Abstract::MultiVector> h = 
    result_z.subView(index_B);

  // compute lambda = ((phi^T h)(phi^T C-u) - (phi^T g)(phi^T D-v)) /
  //                  ((phi^T h)(phi^T e)-(phi^T g)(phi^T f))
  NOX::Abstract::MultiVector::DenseMatrix ltC(1,m);
  NOX::Abstract::MultiVector::DenseMatrix ltD(1,m);
  double lte = hopfGroup->lTransNorm((*e)[0]);
  double ltf = hopfGroup->lTransNorm((*f)[0]);
  double ltg = hopfGroup->lTransNorm((*g)[0]);
  double lth = hopfGroup->lTransNorm((*h)[0]);
  double denom = lth*lte - ltg*ltf;
  hopfGroup->lTransNorm(*C, ltC); 
  ltC -= input_w; 
  ltC.scale(lth);
  hopfGroup->lTransNorm(*D, ltD); 
  ltD -= input_p; 
  result_p.assign(ltD);
  result_p.scale(-ltg);
  result_p += ltC;
  result_p.scale(1.0/denom);

  // compute omega = (phi^T D-v - (phi^T f)lambda)/(phi^T h)
  result_w.assign(result_p);
  result_w.scale(-ltf);
  result_w += ltD;
  result_w.scale(1.0/lth);

  // compute A = A - b*lambda (remember A is a sub-view of result_x)
  A->update(Teuchos::NO_TRANS, -1.0, *b, result_p, 1.0);

  // compute C = C - e*lambda - g*omega (remember C is a sub-view of result_y)
  C->update(Teuchos::NO_TRANS, -1.0, *e, result_p, 1.0);
  C->update(Teuchos::NO_TRANS, -1.0, *g, result_w, 1.0);

  // compute D = D - f*lambda - h*omega (remember D is a sub-view of result_z)
  D->update(Teuchos::NO_TRANS, -1.0, *f, result_p, 1.0);
  D->update(Teuchos::NO_TRANS, -1.0, *h, result_w, 1.0);

  return finalStatus;
}
void
LOCA::BorderedSolver::HouseholderQR::computeQR(
                const NOX::Abstract::MultiVector::DenseMatrix& C,
                const NOX::Abstract::MultiVector& B,
                bool use_c_transpose,
                NOX::Abstract::MultiVector::DenseMatrix& Y1,
                NOX::Abstract::MultiVector& Y2,
                NOX::Abstract::MultiVector::DenseMatrix& T,
                NOX::Abstract::MultiVector::DenseMatrix& R)
{
  double beta;
  int m = B.numVectors();

  // Initialize
  Y1.putScalar(0.0);
  T.putScalar(0.0);
  Y2 = B;
  if (use_c_transpose) {
    for (int i=0; i<m; i++)
      for (int j=0; j<m; j++)
    R(i,j) = C(j,i);        // Copy transpose of C into R
  }
  else
    R.assign(C);

  // A temporary vector
  Teuchos::RCP<NOX::Abstract::MultiVector> v2 = Y2.clone(1);

  Teuchos::RCP<NOX::Abstract::MultiVector::DenseMatrix> v1;
  Teuchos::RCP<NOX::Abstract::MultiVector> h2;
  Teuchos::RCP<NOX::Abstract::MultiVector::DenseMatrix> h1;
  Teuchos::RCP<NOX::Abstract::MultiVector> y2;
  Teuchos::RCP<NOX::Abstract::MultiVector::DenseMatrix> y1;
  Teuchos::RCP<NOX::Abstract::MultiVector::DenseMatrix> z;
  std::vector<int> h_idx;
  std::vector<int> y_idx;
  y_idx.reserve(m);

  for (int i=0; i<m; i++) {

    // Create view of column i of Y1 starting at row i
    v1 =
      Teuchos::rcp(new NOX::Abstract::MultiVector::DenseMatrix(Teuchos::View,
                                   Y1,
                                   m-i,
                                   1, i, i));

    // Create view of columns i through m-1 of Y2
    h_idx.resize(m-i);
    for (unsigned int j=0; j<h_idx.size(); j++)
      h_idx[j] = i+j;
    h2 = Y2.subView(h_idx);

    // Create view of columns i thru m-1 of R, starting at row i
    h1 =
      Teuchos::rcp(new NOX::Abstract::MultiVector::DenseMatrix(Teuchos::View,
                                   R,
                                   m-i,
                                   m-i,
                                   i, i));

    if (i > 0) {

      // Create view of columns 0 through i-1 of Y2
      y_idx.push_back(i-1);
      y2 = Y2.subView(y_idx);

      // Create view of columns 0 through i-1 of Y1, starting at row i
      y1 =
    Teuchos::rcp(new NOX::Abstract::MultiVector::DenseMatrix(Teuchos::View,
                                 Y1,
                                 m-i,
                                 i, i, 0));

      // Create view of column i, row 0 through i-1 of T
      z =
    Teuchos::rcp(new NOX::Abstract::MultiVector::DenseMatrix(Teuchos::View,
                                 T,
                                 i,
                                 1,
                                 0, i));
    }

    // Compute Householder Vector
    computeHouseholderVector(i, R, Y2, *v1, *v2, beta);

    // Apply Householder reflection
    applyHouseholderVector(*v1, *v2, beta, *h1, *h2);

    // Copy v2 into Y2
    Y2[i] = (*v2)[0];

    T(i,i) = -beta;

    if (i > 0) {

      // Compute z = y2^T * v2
      v2->multiply(1.0, *y2, *z);

      // Compute z = -beta * (z + y1^T * v1)
      z->multiply(Teuchos::TRANS, Teuchos::NO_TRANS, -beta, *y1, *v1, -beta);

      // Compute z = T * z
      dblas.TRMV(Teuchos::UPPER_TRI, Teuchos::NO_TRANS, Teuchos::NON_UNIT_DIAG,
         i, T.values(), m, z->values(), 1);

    }
  }

}