Пример #1
0
 /** Set up the augmented system and solve it for a given right hand
  *  side.  If desired (i.e. if check_NegEVals is true), then the
  *  solution is only computed if the number of negative eigenvalues
  *  matches numberOfNegEVals.
  *
  *  The return value is the return value of the linear solver object.
  */
 virtual ESymSolverStatus Solve(
   const SymMatrix* W,
   double W_factor,
   const Vector* D_x,
   double delta_x,
   const Vector* D_s,
   double delta_s,
   const Matrix* J_c,
   const Vector* D_c,
   double delta_c,
   const Matrix* J_d,
   const Vector* D_d,
   double delta_d,
   const Vector& rhs_x,
   const Vector& rhs_s,
   const Vector& rhs_c,
   const Vector& rhs_d,
   Vector& sol_x,
   Vector& sol_s,
   Vector& sol_c,
   Vector& sol_d,
   bool check_NegEVals,
   Index numberOfNegEVals)
 {
   std::vector<SmartPtr<const Vector> > rhs_xV(1);
   rhs_xV[0] = &rhs_x;
   std::vector<SmartPtr<const Vector> > rhs_sV(1);
   rhs_sV[0] = &rhs_s;
   std::vector<SmartPtr<const Vector> > rhs_cV(1);
   rhs_cV[0] = &rhs_c;
   std::vector<SmartPtr<const Vector> > rhs_dV(1);
   rhs_dV[0] = &rhs_d;
   std::vector<SmartPtr<Vector> > sol_xV(1);
   sol_xV[0] = &sol_x;
   std::vector<SmartPtr<Vector> > sol_sV(1);
   sol_sV[0] = &sol_s;
   std::vector<SmartPtr<Vector> > sol_cV(1);
   sol_cV[0] = &sol_c;
   std::vector<SmartPtr<Vector> > sol_dV(1);
   sol_dV[0] = &sol_d;
   return MultiSolve(W, W_factor, D_x, delta_x, D_s, delta_s, J_c, D_c, delta_c,
                     J_d, D_d, delta_d, rhs_xV, rhs_sV, rhs_cV, rhs_dV,
                     sol_xV, sol_sV, sol_cV, sol_dV, check_NegEVals,
                     numberOfNegEVals);
 }
Пример #2
0
ESymSolverStatus LowRankAugSystemSolver::SolveMultiVector(
   const Vector*                 D_x,
   double                        delta_x,
   const Vector*                 D_s,
   double                        delta_s,
   const Matrix&                 J_c,
   const Vector*                 D_c,
   double                        delta_c,
   const Matrix&                 J_d,
   const Vector*                 D_d,
   double                        delta_d,
   const Vector&                 proto_rhs_x,
   const Vector&                 proto_rhs_s,
   const Vector&                 proto_rhs_c,
   const Vector&                 proto_rhs_d,
   const MultiVectorMatrix&      V,
   const SmartPtr<const Matrix>& P_LM,
   SmartPtr<MultiVectorMatrix>&  V_x,
   SmartPtr<MultiVectorMatrix>&  Vtilde,
   SmartPtr<MultiVectorMatrix>&  Vtilde_x,
   bool                          check_NegEVals,
   Index                         numberOfNegEVals
   )
{
   DBG_START_METH("LowRankAugSystemSolver::SolveMultiVector",
      dbg_verbosity);

   ESymSolverStatus retval;

   Index nrhs = V.NCols();
   DBG_ASSERT(nrhs > 0);

   SmartPtr<MultiVectorMatrixSpace> V_xspace = new MultiVectorMatrixSpace(nrhs, *proto_rhs_x.OwnerSpace());
   V_x = V_xspace->MakeNewMultiVectorMatrix();

   // Create the right hand sides
   std::vector<SmartPtr<const Vector> > rhs_xV(nrhs);
   std::vector<SmartPtr<const Vector> > rhs_sV(nrhs);
   std::vector<SmartPtr<const Vector> > rhs_cV(nrhs);
   std::vector<SmartPtr<const Vector> > rhs_dV(nrhs);

   for( Index i = 0; i < nrhs; i++ )
   {
      if( IsNull(P_LM) )
      {
         rhs_xV[i] = V.GetVector(i);
         DBG_ASSERT(rhs_xV[i]->Dim() == proto_rhs_x.Dim());
      }
      else
      {
         SmartPtr<Vector> fullx = proto_rhs_x.MakeNew();
         P_LM->MultVector(1., *V.GetVector(i), 0., *fullx);
         rhs_xV[i] = ConstPtr(fullx);
      }
      V_x->SetVector(i, *rhs_xV[i]);
      SmartPtr<Vector> tmp;
      tmp = proto_rhs_s.MakeNew();
      tmp->Set(0.);
      rhs_sV[i] = ConstPtr(tmp);
      tmp = proto_rhs_c.MakeNew();
      tmp->Set(0.);
      rhs_cV[i] = ConstPtr(tmp);
      tmp = proto_rhs_d.MakeNew();
      tmp->Set(0.);
      rhs_dV[i] = ConstPtr(tmp);
   }

   // now get space for the solution
   std::vector<SmartPtr<Vector> > sol_xV(nrhs);
   std::vector<SmartPtr<Vector> > sol_sV(nrhs);
   std::vector<SmartPtr<Vector> > sol_cV(nrhs);
   std::vector<SmartPtr<Vector> > sol_dV(nrhs);
   for( Index i = 0; i < nrhs; i++ )
   {
      sol_xV[i] = proto_rhs_x.MakeNew();
      sol_sV[i] = proto_rhs_s.MakeNew();
      sol_cV[i] = proto_rhs_c.MakeNew();
      sol_dV[i] = proto_rhs_d.MakeNew();
   }

   // Call the actual augmented system solver to obtain Vtilde
   retval = aug_system_solver_->MultiSolve(GetRawPtr(Wdiag_), 1.0, D_x, delta_x, D_s, delta_s, &J_c, D_c, delta_c, &J_d,
      D_d, delta_d, rhs_xV, rhs_sV, rhs_cV, rhs_dV, sol_xV, sol_sV, sol_cV, sol_dV, check_NegEVals, numberOfNegEVals);

   if( aug_system_solver_->ProvidesInertia() )
   {
      num_neg_evals_ = aug_system_solver_->NumberOfNegEVals();
   }
   if( retval != SYMSOLVER_SUCCESS )
   {
      return retval;
   }

   // Pack the results into Vtilde
   if( IsNull(compound_sol_vecspace_) )
   {
      Index dimx = proto_rhs_x.Dim();
      Index dims = proto_rhs_s.Dim();
      Index dimc = proto_rhs_c.Dim();
      Index dimd = proto_rhs_d.Dim();
      Index dimtot = dimx + dims + dimc + dimd;
      SmartPtr<CompoundVectorSpace> vecspace = new CompoundVectorSpace(4, dimtot);
      vecspace->SetCompSpace(0, *proto_rhs_x.OwnerSpace());
      vecspace->SetCompSpace(1, *proto_rhs_s.OwnerSpace());
      vecspace->SetCompSpace(2, *proto_rhs_c.OwnerSpace());
      vecspace->SetCompSpace(3, *proto_rhs_d.OwnerSpace());
      compound_sol_vecspace_ = ConstPtr(vecspace);
   }
   SmartPtr<MultiVectorMatrixSpace> V1space = new MultiVectorMatrixSpace(nrhs, *compound_sol_vecspace_);
   Vtilde = V1space->MakeNewMultiVectorMatrix();
   Vtilde_x = V_xspace->MakeNewMultiVectorMatrix();
   for( Index i = 0; i < nrhs; i++ )
   {
      Vtilde_x->SetVector(i, *sol_xV[i]);
      SmartPtr<CompoundVector> cvec = compound_sol_vecspace_->MakeNewCompoundVector(false);
      cvec->SetCompNonConst(0, *sol_xV[i]);
      cvec->SetCompNonConst(1, *sol_sV[i]);
      cvec->SetCompNonConst(2, *sol_cV[i]);
      cvec->SetCompNonConst(3, *sol_dV[i]);
      Vtilde->SetVectorNonConst(i, *cvec);
   }

   return retval;
}