/** 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); }
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; }