int meibo_input(LPMYDATA lp)
{
	int index = index_input();
	if (index == -1) return -1;

	LPMYDATA lp_target = lp + index;

	printf("-- INPUT [%d]--\n", index);
	printf("your name:");
	gets(lp_target->name);
	printf("your email:");
	gets(lp_target->email);
}
int meibo_output(LPMYDATA lp)
{
	int index = index_input();
	if (index == -1) return -1;

	LPMYDATA lp_target = lp + index;

	printf("-- OUTPUT [%d]--\n", index);

	if (strcmp(lp_target->name ,"") == 0) {
		printf("NO DATA\n");
		return -1;
	}

	printf("name  : %s\n", lp_target->name);
	printf("email : %s\n", lp_target->email);
}
// Solves turning point equations via classic Salinger bordering
// The first m columns of input_x and input_null store the RHS while
// the last column stores df/dp, d(Jn)/dp respectively.  Note however
// input_param has only m columns (not m+1).  result_x, result_null,
// are result_param have the same dimensions as their input counterparts
NOX::Abstract::Group::ReturnType 
LOCA::TurningPoint::MooreSpence::PhippsBordering::solveTransposeContiguous(
		  Teuchos::ParameterList& params,
		  const NOX::Abstract::MultiVector& input_x,
		  const NOX::Abstract::MultiVector& input_null,
	          const NOX::Abstract::MultiVector::DenseMatrix& input_param,
		  NOX::Abstract::MultiVector& result_x,
		  NOX::Abstract::MultiVector& result_null,
	          NOX::Abstract::MultiVector::DenseMatrix& result_param) const
{
  std::string callingFunction = 
    "LOCA::TurningPoint::MooreSpence::PhippsBordering::solveTransposeContiguous()";
  NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok;
  NOX::Abstract::Group::ReturnType status;

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

  NOX::Abstract::MultiVector::DenseMatrix tmp_mat_1(1, m+1);
  NOX::Abstract::MultiVector::DenseMatrix tmp_mat_2(1, m+2);

  // Create view of first m+1 columns of input_null, result_null
  Teuchos::RCP<NOX::Abstract::MultiVector> input_null_view = 
      input_null.subView(index_input_dp);
  Teuchos::RCP<NOX::Abstract::MultiVector> result_null_view = 
      result_null.subView(index_input_dp);

  // verify underlying Jacobian is valid
  if (!group->isJacobian()) {
    status = group->computeJacobian();
    finalStatus = 
      globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							     finalStatus,
							     callingFunction);
  }

  // Solve  |J^T v||A B| = |G -phi|
  //        |u^T 0||a b|   |0   0 |
  status =
    transposeBorderedSolver->applyInverseTranspose(params, 
						   input_null_view.get(), 
						   NULL, 
						   *result_null_view, 
						   tmp_mat_1);
  finalStatus = 
    globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus,
							   callingFunction);
  Teuchos::RCP<NOX::Abstract::MultiVector> A = 
    result_null.subView(index_input);
  Teuchos::RCP<NOX::Abstract::MultiVector> B = 
    result_null.subView(index_dp);
  double b = tmp_mat_1(0,m);

  // compute (Jv)_x^T[A B u]
  result_null[m+1] = *uVector;
  Teuchos::RCP<NOX::Abstract::MultiVector> tmp = 
    result_null.clone(NOX::ShapeCopy);
  status = group->computeDwtJnDxMulti(result_null, *nullVector, *tmp);
  finalStatus = 
    globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							   finalStatus,
							   callingFunction);

  // compute [F 0 0] - (Jv)_x^T[A B u]
  tmp->update(1.0, input_x, -1.0);

  // verify underlying Jacobian is valid
  if (!group->isJacobian()) {
    status = group->computeJacobian();
    finalStatus = 
      globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							     finalStatus,
							     callingFunction);
  }

  // Solve  |J^T v||C D E| = |F - (Jv)_x^T A  -(Jv)_x^T B  -(Jv)_x^T u|
  //        |u^T 0||c d e|   |         0             0            0   |
  status = 
    transposeBorderedSolver->applyInverseTranspose(params, 
						   tmp.get(), 
						   NULL, 
						   result_x,
						   tmp_mat_2);
  finalStatus = 
    globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus,
							   callingFunction);
  Teuchos::RCP<NOX::Abstract::MultiVector> C = 
    result_x.subView(index_input);
  Teuchos::RCP<NOX::Abstract::MultiVector> D = 
    result_x.subView(index_dp);
  Teuchos::RCP<NOX::Abstract::MultiVector> E = 
    result_x.subView(index_null);
  double d = tmp_mat_2(0, m);
  double e = tmp_mat_2(0, m+1);

  // compute (Jv)_p^T*[A B u]
  NOX::Abstract::MultiVector::DenseMatrix t1(1,m+2);
  result_null.multiply(1.0, *dJndp, t1);

  // compute f_p^T*[C D E]
  NOX::Abstract::MultiVector::DenseMatrix t2(1,m+2);
  result_x.multiply(1.0, *dfdp, t2);

  // compute f_p^T*u
  double fptu = uVector->innerProduct((*dfdp)[0]);

  // Fill coefficient arrays
  double M[9];
  M[0] = st;   M[1] =  -e;   M[2] = t1(0,m+1) + t2(0,m+1);
  M[3] = 0.0;  M[4] =   st;  M[5] = fptu;
  M[6] = -b;   M[7] =  -d;   M[8] = t1(0,m) + t2(0,m);

  // Compute RHS
  double *R = new double[3*m];
  for (int i=0; i<m; i++) {
    R[3*i]   = tmp_mat_1(0,i);
    R[3*i+1] = tmp_mat_2(0,i);
    R[3*i+2] = result_param(0,i) - t1(0,i) - t2(0,i);
  }

  // Solve M*P = R
  int three = 3;
  int piv[3];
  int info;
  Teuchos::LAPACK<int,double> L;
  L.GESV(three, m, M, three, piv, R, three, &info);
  if (info != 0) {
    globalData->locaErrorCheck->throwError(
				    callingFunction,
				    "Solve of 3x3 coefficient matrix failed!");
    return NOX::Abstract::Group::Failed;
  }

  NOX::Abstract::MultiVector::DenseMatrix alpha(1,m);
  NOX::Abstract::MultiVector::DenseMatrix beta(1,m);
  for (int i=0; i<m; i++) {
    alpha(0,i)        = R[3*i];
    beta(0,i)         = R[3*i+1];
    result_param(0,i) = R[3*i+2];
  }

  // compute A = A + B*z + alpha*u (remember A is a sub-view of result_null)
  A->update(Teuchos::NO_TRANS, 1.0, *B, result_param, 1.0);
  A->update(Teuchos::NO_TRANS, 1.0, *uMultiVector, alpha, 1.0);

  // compute C = C + D*z + alpha*E + beta*u 
  // (remember C is a sub-view of result_x)
  C->update(Teuchos::NO_TRANS, 1.0, *D, result_param, 1.0);
  C->update(Teuchos::NO_TRANS, 1.0, *E, alpha, 1.0);
  C->update(Teuchos::NO_TRANS, 1.0, *uMultiVector, beta, 1.0);

  delete [] R;

  return finalStatus;
}
// Solves turning point equations via Phipps modified bordering
// The first m columns of input_x and input_null store the RHS while
// the last column stores df/dp, d(Jn)/dp respectively.  Note however
// input_param has only m columns (not m+1).  result_x, result_null,
// are result_param have the same dimensions as their input counterparts
NOX::Abstract::Group::ReturnType 
LOCA::TurningPoint::MooreSpence::PhippsBordering::solveContiguous(
		  Teuchos::ParameterList& params,
		  const NOX::Abstract::MultiVector& input_x,
		  const NOX::Abstract::MultiVector& input_null,
	          const NOX::Abstract::MultiVector::DenseMatrix& input_param,
		  NOX::Abstract::MultiVector& result_x,
		  NOX::Abstract::MultiVector& result_null,
	          NOX::Abstract::MultiVector::DenseMatrix& result_param) const
{
  std::string callingFunction = 
    "LOCA::TurningPoint::MooreSpence::PhippsBordering::solveContiguous()";
  NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok;
  NOX::Abstract::Group::ReturnType status;

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

  NOX::Abstract::MultiVector::DenseMatrix tmp_mat_1(1, m+1);
  NOX::Abstract::MultiVector::DenseMatrix tmp_mat_2(1, m+2);

  // Create view of first m+1 columns of input_x, result_x
  Teuchos::RCP<NOX::Abstract::MultiVector> input_x_view = 
      input_x.subView(index_input_dp);
  Teuchos::RCP<NOX::Abstract::MultiVector> result_x_view = 
      result_x.subView(index_input_dp);

  // verify underlying Jacobian is valid
  if (!group->isJacobian()) {
    status = group->computeJacobian();
    finalStatus = 
      globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							     finalStatus,
							     callingFunction);
  }
  
  // Solve  |J   u||A B| = |F df/dp|
  //        |v^T 0||a b|   |0   0  |
  status = borderedSolver->applyInverse(params, input_x_view.get(), NULL, 
					*result_x_view, tmp_mat_1);
  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);
  double b = tmp_mat_1(0,m);

  // compute (Jv)_x[A B v]
  result_x[m+1] = *nullVector;
  Teuchos::RCP<NOX::Abstract::MultiVector> tmp = 
    result_x.clone(NOX::ShapeCopy);
  status = group->computeDJnDxaMulti(*nullVector, *JnVector, result_x,
				     *tmp);
  finalStatus = 
    globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus,
							   callingFunction);

  // compute (Jv)_x[A B v] - [G d(Jn)/dp 0]
  tmp->update(-1.0, input_null, 1.0);

  // verify underlying Jacobian is valid
  if (!group->isJacobian()) {
    status = group->computeJacobian();
    finalStatus = 
      globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							     finalStatus,
							     callingFunction);
  }

  // Solve  |J   u||C D E| = |(Jv)_x A - G  (Jv)_x B - d(Jv)/dp  (Jv)_x v|
  //        |v^T 0||c d e|   |         0             0               0   |
  status = borderedSolver->applyInverse(params, tmp.get(), NULL, result_null,
					tmp_mat_2);
  finalStatus = 
    globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus,
							   callingFunction);
  Teuchos::RCP<NOX::Abstract::MultiVector> C = 
    result_null.subView(index_input);
  Teuchos::RCP<NOX::Abstract::MultiVector> D = 
    result_null.subView(index_dp);
  Teuchos::RCP<NOX::Abstract::MultiVector> E = 
    result_null.subView(index_null);
  double d = tmp_mat_2(0, m);
  double e = tmp_mat_2(0, m+1);

  // Fill coefficient arrays
  double M[9];
  M[0] = s;   M[1] =  e;  M[2] = -tpGroup->lTransNorm((*E)[0]);
  M[3] = 0.0; M[4] =  s;  M[5] =  tpGroup->lTransNorm(*nullVector);
  M[6] = b;   M[7] = -d;  M[8] =  tpGroup->lTransNorm((*D)[0]);

  // compute h + phi^T C
  tpGroup->lTransNorm(*C, result_param);
  result_param += input_param;

  double *R = new double[3*m];
  for (int i=0; i<m; i++) {
    R[3*i]   =  tmp_mat_1(0,i);
    R[3*i+1] = -tmp_mat_2(0,i);
    R[3*i+2] =  result_param(0,i);
  }

  // Solve M*P = R
  int three = 3;
  int piv[3];
  int info;
  Teuchos::LAPACK<int,double> L;
  L.GESV(three, m, M, three, piv, R, three, &info);
  if (info != 0) {
    globalData->locaErrorCheck->throwError(
				    callingFunction,
				    "Solve of 3x3 coefficient matrix failed!");
    return NOX::Abstract::Group::Failed;
  }

  NOX::Abstract::MultiVector::DenseMatrix alpha(1,m);
  NOX::Abstract::MultiVector::DenseMatrix beta(1,m);
  for (int i=0; i<m; i++) {
    alpha(0,i)        = R[3*i];
    beta(0,i)         = R[3*i+1];
    result_param(0,i) = R[3*i+2];
  }

  // compute A = A - B*z + v*alpha (remember A is a sub-view of result_x)
  A->update(Teuchos::NO_TRANS, -1.0, *B, result_param, 1.0);
  A->update(Teuchos::NO_TRANS, 1.0, *nullMultiVector, alpha, 1.0);

  // compute C = -C + d*z - E*alpha + v*beta 
  // (remember C is a sub-view of result_null)
  C->update(Teuchos::NO_TRANS, 1.0, *D, result_param, -1.0);
  C->update(Teuchos::NO_TRANS, -1.0, *E, alpha, 1.0);
  C->update(Teuchos::NO_TRANS, 1.0, *nullMultiVector, beta, 1.0);

  delete [] R;

  return finalStatus;
}
NOX::Abstract::Group::ReturnType 
LOCA::TurningPoint::MooreSpence::PhippsBordering::solveTranspose(
	   Teuchos::ParameterList& params,
	   const LOCA::TurningPoint::MooreSpence::ExtendedMultiVector& input,
           LOCA::TurningPoint::MooreSpence::ExtendedMultiVector& result) const
{
  std::string callingFunction = 
    "LOCA::TurningPoint::MooreSpence::PhippsBordering::solveTranspose()";
  NOX::Abstract::Group::ReturnType status;
  
  // Get components of input
  Teuchos::RCP<const NOX::Abstract::MultiVector> input_x = 
    input.getXMultiVec();
  Teuchos::RCP<const NOX::Abstract::MultiVector> input_null = 
    input.getNullMultiVec();
  Teuchos::RCP<const NOX::Abstract::MultiVector::DenseMatrix> input_param = input.getScalars();

  // Get components of result
  Teuchos::RCP<NOX::Abstract::MultiVector> result_x = 
    result.getXMultiVec();
  Teuchos::RCP<NOX::Abstract::MultiVector> result_null = 
    result.getNullMultiVec();
  Teuchos::RCP<NOX::Abstract::MultiVector::DenseMatrix> result_param = 
    result.getScalars();

  int m = input.numVectors();

  std::vector<int> index_input(m);
  for (int i=0; i<m; i++)
    index_input[i] = i;
  
  // Create new multivectors with m+2 columns
  // First m columns store input_x, input_null, result_x, result_null
  // respectively, next column stores 0, -phi, J^-T tmp , -J^-T phi
  // respectively, last column is for solving (Jv)_x^T u
  Teuchos::RCP<NOX::Abstract::MultiVector> cont_input_x = 
    input_x->clone(m+2);
  Teuchos::RCP<NOX::Abstract::MultiVector> cont_input_null = 
    input_null->clone(m+2);
  
  Teuchos::RCP<NOX::Abstract::MultiVector> cont_result_x = 
    result_x->clone(m+2);
  Teuchos::RCP<NOX::Abstract::MultiVector> cont_result_null = 
    result_null->clone(m+2);
  
  // Set first m columns to input_x
  cont_input_x->setBlock(*input_x, index_input);

  // Set last two columns to 0
  (*cont_input_x)[m].init(0);
  (*cont_input_x)[m+1].init(0);
  
    // Set first m columns to input_null
  cont_input_null->setBlock(*input_null, index_input);
  
  // Set next column to -phi
  Teuchos::RCP<NOX::Abstract::Vector> phi = tpGroup->getLengthVector();
  (*cont_input_null)[m].update(-1.0, *phi, 0.0);
  
  // Set last column to 0
  (*cont_input_null)[m].init(0);
  
  // Initialize result multivectors to 0
  cont_result_x->init(0.0);
  cont_result_null->init(0.0);
    
  // Solve
  status = solveTransposeContiguous(params, *cont_input_x, *cont_input_null, 
				    *input_param, *cont_result_x, 
				    *cont_result_null, 
				    *result_param);
  
  // Create views of first m columns for result_x, result_null
  Teuchos::RCP<NOX::Abstract::MultiVector> cont_result_x_view = 
    cont_result_x->subView(index_input);
  Teuchos::RCP<NOX::Abstract::MultiVector> cont_result_null_view = 
    cont_result_null->subView(index_input);
  
  // Copy first m columns back into result_x, result_null
  *result_x = *cont_result_x_view;
  *result_null = *cont_result_null_view;

   return status;
}
// 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;
}
NOX::Abstract::Group::ReturnType 
LOCA::Hopf::MooreSpence::SalingerBordering::solve(
	   Teuchos::ParameterList& params,
	   const LOCA::Hopf::MooreSpence::ExtendedMultiVector& input,
           LOCA::Hopf::MooreSpence::ExtendedMultiVector& result) const
{
  std::string callingFunction = 
    "LOCA::Hopf::MooreSpence::SalingerBordering::solve()";
  NOX::Abstract::Group::ReturnType status;
  
  // Get components of input
  Teuchos::RCP<const NOX::Abstract::MultiVector> input_x = 
    input.getXMultiVec();
  Teuchos::RCP<const NOX::Abstract::MultiVector> input_y = 
    input.getRealEigenMultiVec();
  Teuchos::RCP<const NOX::Abstract::MultiVector> input_z = 
    input.getImagEigenMultiVec();
  Teuchos::RCP<const NOX::Abstract::MultiVector::DenseMatrix> input_w 
    = input.getFrequencies();
  Teuchos::RCP<const NOX::Abstract::MultiVector::DenseMatrix> input_p 
    = input.getBifParams();

  // Get components of result
  Teuchos::RCP<NOX::Abstract::MultiVector> result_x = 
    result.getXMultiVec();
  Teuchos::RCP<NOX::Abstract::MultiVector> result_y = 
    result.getRealEigenMultiVec();
  Teuchos::RCP<NOX::Abstract::MultiVector> result_z = 
    result.getImagEigenMultiVec();
  Teuchos::RCP<NOX::Abstract::MultiVector::DenseMatrix> result_w = 
    result.getFrequencies();
  Teuchos::RCP<NOX::Abstract::MultiVector::DenseMatrix> result_p = 
    result.getBifParams();

  int m = input.numVectors();

  std::vector<int> index_input(m);
  for (int i=0; i<m; i++)
    index_input[i] = i;
  
  // Create new multivectors with m+2 columns
  // First m columns store input_x, input_y, input_z, result_x, result_y, 
  // and result_z respectively, next column stores df/dp, (Jy-wBz)_p, 
  // (Jz+wBy)_p, J^-1 dfdp, C^-1 (Jy-wBz)_p, C^-1 (Jz+wBy)_p
  // respectively.  Last column stores -Bz, By C^-1 (-Bz) and C^-1 (By)
  Teuchos::RCP<NOX::Abstract::MultiVector> cont_input_x = 
    input_x->clone(m+1);
  Teuchos::RCP<NOX::Abstract::MultiVector> cont_input_y = 
    input_y->clone(m+2);
  Teuchos::RCP<NOX::Abstract::MultiVector> cont_input_z = 
    input_z->clone(m+2);
  
  Teuchos::RCP<NOX::Abstract::MultiVector> cont_result_x = 
    result_x->clone(m+1);
  Teuchos::RCP<NOX::Abstract::MultiVector> cont_result_y = 
    result_y->clone(m+2);
  Teuchos::RCP<NOX::Abstract::MultiVector> cont_result_z = 
    result_y->clone(m+2);
  
  // Set first m columns to input_x
  cont_input_x->setBlock(*input_x, index_input);

  // Set last column to dfdp
  (*cont_input_x)[m] = *dfdp;
  
  // Set first m columns to input_y
  cont_input_y->setBlock(*input_y, index_input);
  
  // Set next column to (Jy-wBz)_p
  (*cont_input_y)[m] = *dCedpReal;

  // Set last column to -Bz
  (*cont_input_y)[m+1] = *minusBzVector;

  // Set first m columns to input_z
  cont_input_z->setBlock(*input_z, index_input);
  
  // Set next column to (Jz+wBy)_p
  (*cont_input_z)[m] = *dCedpImag;

  // Set last column to By
  (*cont_input_z)[m+1] = *ByVector;
  
  // Initialize result multivectors to 0
  cont_result_x->init(0.0);
  cont_result_y->init(0.0);
  cont_result_z->init(0.0);
    
  // Solve
  status = solveContiguous(params, *cont_input_x, *cont_input_y, *cont_input_z,
			   *input_w, *input_p, *cont_result_x, *cont_result_y,
			   *cont_result_z, *result_w, *result_p);
  
  // Create views of first m columns for result_x, result_y, result_z
  Teuchos::RCP<NOX::Abstract::MultiVector> cont_result_x_view = 
    cont_result_x->subView(index_input);
  Teuchos::RCP<NOX::Abstract::MultiVector> cont_result_y_view = 
    cont_result_y->subView(index_input);
  Teuchos::RCP<NOX::Abstract::MultiVector> cont_result_z_view = 
    cont_result_z->subView(index_input);
  
  // Copy first m columns back into result_x, result_null
  *result_x = *cont_result_x_view;
  *result_y = *cont_result_y_view;
  *result_z = *cont_result_z_view;

   return status;
}
NOX::Abstract::Group::ReturnType
LOCA::TurningPoint::MooreSpence::PhippsBordering::solve(
    Teuchos::ParameterList& params,
    const LOCA::TurningPoint::MooreSpence::ExtendedMultiVector& input,
    LOCA::TurningPoint::MooreSpence::ExtendedMultiVector& result) const
{
    string callingFunction =
        "LOCA::TurningPoint::MooreSpence::PhippsBordering::solve()";
    NOX::Abstract::Group::ReturnType status;

    // Get components of input
    Teuchos::RCP<const NOX::Abstract::MultiVector> input_x =
        input.getXMultiVec();
    Teuchos::RCP<const NOX::Abstract::MultiVector> input_null =
        input.getNullMultiVec();
    Teuchos::RCP<const NOX::Abstract::MultiVector::DenseMatrix> input_param = input.getScalars();

    // Get components of result
    Teuchos::RCP<NOX::Abstract::MultiVector> result_x =
        result.getXMultiVec();
    Teuchos::RCP<NOX::Abstract::MultiVector> result_null =
        result.getNullMultiVec();
    Teuchos::RCP<NOX::Abstract::MultiVector::DenseMatrix> result_param =
        result.getScalars();

    int m = input.numVectors();
    vector<int> index_input(m);
    for (int i=0; i<m; i++)
        index_input[i] = i;

    // Create new multivectors with m+2 columns
    // First m columns store input_x, input_null, result_x, result_null
    // respectively, next column stores dfdp, dJndp, J^-1 dfdp, J^-1 dJndp
    // respectively.  Last column is for solving (Jv)_x v
    Teuchos::RCP<NOX::Abstract::MultiVector> cont_input_x =
        input_x->clone(m+2);
    Teuchos::RCP<NOX::Abstract::MultiVector> cont_input_null =
        input_null->clone(m+2);

    Teuchos::RCP<NOX::Abstract::MultiVector> cont_result_x =
        result_x->clone(m+2);
    Teuchos::RCP<NOX::Abstract::MultiVector> cont_result_null =
        result_null->clone(m+2);

    // Set first m columns to input_x
    cont_input_x->setBlock(*input_x, index_input);

    // Set column m+1 to dfdp
    (*cont_input_x)[m] = (*dfdp)[0];

    // Initialize column m+2 to 0
    (*cont_input_x)[m+1].init(0.0);

    // Set first m columns to input_null
    cont_input_null->setBlock(*input_null, index_input);

    // Set column m+1 to dJndp
    (*cont_input_null)[m] = (*dJndp)[0];

    // Initialize column m+2 to 0
    (*cont_input_null)[m+1].init(0.0);

    // Initialize result multivectors to 0
    cont_result_x->init(0.0);
    cont_result_null->init(0.0);

    // Solve
    status = solveContiguous(params, *cont_input_x, *cont_input_null,
                             *input_param, *cont_result_x, *cont_result_null,
                             *result_param);

    // Create views of first m columns for result_x, result_null
    Teuchos::RCP<NOX::Abstract::MultiVector> cont_result_x_view =
        cont_result_x->subView(index_input);
    Teuchos::RCP<NOX::Abstract::MultiVector> cont_result_null_view =
        cont_result_null->subView(index_input);

    // Copy first m columns back into result_x, result_null
    *result_x = *cont_result_x_view;
    *result_null = *cont_result_null_view;

    return status;
}
Beispiel #9
0
// Solves pitchfork equations via Phipps modified bordering
// The first m columns of input_x and input_null store the RHS,
// column m+1 stores df/dp, d(Jn)/dp, column m+2 stores psi and 0,
// and the last column provides space for solving (Jv_x) v.  Note however
// input_param has only m columns.  result_x, result_null,
// are result_param have the same dimensions as their input counterparts
NOX::Abstract::Group::ReturnType 
LOCA::Pitchfork::MooreSpence::PhippsBordering::solveContiguous(
		  Teuchos::ParameterList& params,
		  const NOX::Abstract::MultiVector& input_x,
		  const NOX::Abstract::MultiVector& input_null,
		  const NOX::Abstract::MultiVector::DenseMatrix& input_slack,
	          const NOX::Abstract::MultiVector::DenseMatrix& input_param,
		  NOX::Abstract::MultiVector& result_x,
		  NOX::Abstract::MultiVector& result_null,
		  NOX::Abstract::MultiVector::DenseMatrix& result_slack,
	          NOX::Abstract::MultiVector::DenseMatrix& result_param) const
{
  string callingFunction = 
    "LOCA::Pitchfork::MooreSpence::PhippsBordering::solveContiguous()";
  NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok;
  NOX::Abstract::Group::ReturnType status;

  int m = input_x.numVectors()-3;
  vector<int> index_input(m);
  vector<int> index_input_dp(m+2);
  vector<int> index_null(1);
  vector<int> index_dp(1);
  vector<int> index_s(1);
  for (int i=0; i<m; i++) {
    index_input[i] = i;
    index_input_dp[i] = i;
  }
  index_input_dp[m] = m;
  index_input_dp[m+1] = m+1;
  index_dp[0] = m;
  index_s[0] = m+1;
  index_null[0] = m+2;

  NOX::Abstract::MultiVector::DenseMatrix tmp_mat_1(1, m+2);
  NOX::Abstract::MultiVector::DenseMatrix tmp_mat_2(1, m+3);

  // Create view of first m+2 columns of input_x, result_x
  Teuchos::RCP<NOX::Abstract::MultiVector> input_x_view = 
      input_x.subView(index_input_dp);
  Teuchos::RCP<NOX::Abstract::MultiVector> result_x_view = 
      result_x.subView(index_input_dp);

  // verify underlying Jacobian is valid
  if (!group->isJacobian()) {
    status = group->computeJacobian();
    finalStatus = 
      globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							     finalStatus,
							     callingFunction);
  }
  
  // Solve  |J   u||A B C| = |F df/dp psi|
  //        |v^T 0||a b c|   |0   0    0 |
  status = borderedSolver->applyInverse(params, input_x_view.get(), NULL, 
					*result_x_view, tmp_mat_1);
  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);
  Teuchos::RCP<NOX::Abstract::MultiVector> C = 
    result_x.subView(index_s);
  double b = tmp_mat_1(0,m);
  double c = tmp_mat_1(0,m+1);

  // compute (Jv)_x[A B C v]
  result_x[m+2] = *nullVector;
  Teuchos::RCP<NOX::Abstract::MultiVector> tmp = 
    result_x.clone(NOX::ShapeCopy);
  status = group->computeDJnDxaMulti(*nullVector, *JnVector, result_x,
				     *tmp);
  finalStatus = 
    globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus,
							   callingFunction);

  // compute [G d(Jn)/dp 0 0] - (Jv)_x[A B C v]
  tmp->update(1.0, input_null, -1.0);

  // verify underlying Jacobian is valid
  if (!group->isJacobian()) {
    status = group->computeJacobian();
    finalStatus = 
      globalData->locaErrorCheck->combineAndCheckReturnTypes(status, 
							     finalStatus,
							     callingFunction);
  }

  // Solve  |J   u||D E K L| = |G-(Jv)_xA  d(Jv)/dp-(Jv)_xB  -(Jv)_xC -(Jv)_xv|
  //        |v^T 0||d e k l|   |    0             0              0        0   |
  status = borderedSolver->applyInverse(params, tmp.get(), NULL, result_null,
					tmp_mat_2);
  finalStatus = 
    globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus,
							   callingFunction);
  Teuchos::RCP<NOX::Abstract::MultiVector> D = 
    result_null.subView(index_input);
  Teuchos::RCP<NOX::Abstract::MultiVector> E = 
    result_null.subView(index_dp);
  Teuchos::RCP<NOX::Abstract::MultiVector> K = 
    result_null.subView(index_s);
  Teuchos::RCP<NOX::Abstract::MultiVector> L = 
    result_null.subView(index_null);
  double e = tmp_mat_2(0, m);
  double k = tmp_mat_2(0, m+1);
  double l = tmp_mat_2(0, m+2);

  double ltE = pfGroup->lTransNorm((*E)[0]);
  double ltK = pfGroup->lTransNorm((*K)[0]);
  double ltL = pfGroup->lTransNorm((*L)[0]);
  double ltv = pfGroup->lTransNorm(*nullVector);
  double ipv = group->innerProduct(*nullVector, *asymVector);
  double ipB = group->innerProduct((*B)[0], *asymVector);
  double ipC = group->innerProduct((*C)[0], *asymVector);

  // Fill coefficient arrays
  double M[16];
  M[0]  = sigma; M[1]  = -l;     M[2]  =  ipv; M[3]  =  ltL;
  M[4]  = 0.0;   M[5]  =  sigma; M[6]  =  0.0; M[7]  =  ltv;
  M[8]  = b;     M[9]  =  e;     M[10] = -ipB; M[11] = -ltE;
  M[12] = c;     M[13] =  k;     M[14] = -ipC; M[15] = -ltK;

  // compute s - <A,psi>
  NOX::Abstract::MultiVector::DenseMatrix tmp_mat_3(1, m);
  group->innerProduct(*asymMultiVector, *A, tmp_mat_3);
  tmp_mat_3 -= input_slack;
  tmp_mat_3.scale(-1.0);

  // compute h - phi^T D
  NOX::Abstract::MultiVector::DenseMatrix tmp_mat_4(1, m);
  pfGroup->lTransNorm(*D, tmp_mat_4);
  tmp_mat_4 -= input_param;
  tmp_mat_4.scale(-1.0);

  double *R = new double[4*m];
  for (int i=0; i<m; i++) {
    R[4*i]   = tmp_mat_1(0,i);
    R[4*i+1] = tmp_mat_2(0,i);
    R[4*i+2] = tmp_mat_3(0,i);
    R[4*i+3] = tmp_mat_4(0,i);
  }

  // Solve M*P = R
  int piv[4];
  int info;
  Teuchos::LAPACK<int,double> dlapack;
  dlapack.GESV(4, m, M, 4, piv, R, 4, &info);
  if (info != 0) {
    globalData->locaErrorCheck->throwError(
				    callingFunction,
				    "Solve of 4x4 coefficient matrix failed!");
    return NOX::Abstract::Group::Failed;
  }

  NOX::Abstract::MultiVector::DenseMatrix alpha(1,m);
  NOX::Abstract::MultiVector::DenseMatrix beta(1,m);
  for (int i=0; i<m; i++) {
    alpha(0,i)        = R[4*i];
    beta(0,i)         = R[4*i+1];
    result_param(0,i) = R[4*i+2];
    result_slack(0,i) = R[4*i+3];
  }

  // compute A = A - B*z -C*w + v*alpha (remember A is a sub-view of result_x)
  A->update(Teuchos::NO_TRANS, -1.0, *B, result_param, 1.0);
  A->update(Teuchos::NO_TRANS, -1.0, *C, result_slack, 1.0);
  A->update(Teuchos::NO_TRANS, 1.0, *nullMultiVector, alpha, 1.0);

  // compute D = D - E*z - K*w + L*alpha + v*beta 
  // (remember D is a sub-view of result_null)
  D->update(Teuchos::NO_TRANS, -1.0, *E, result_param, 1.0);
  D->update(Teuchos::NO_TRANS, -1.0, *K, result_slack, 1.0);
  D->update(Teuchos::NO_TRANS, 1.0, *L, alpha, 1.0);
  D->update(Teuchos::NO_TRANS, 1.0, *nullMultiVector, beta, 1.0);

  delete [] R;

  return finalStatus;
}