SmartPtr<IpoptAlgorithm> AlgorithmBuilder::BuildBasicAlgorithm(const Journalist& jnlst, const OptionsList& options, const std::string& prefix) { DBG_START_FUN("AlgorithmBuilder::BuildBasicAlgorithm", dbg_verbosity); bool mehrotra_algorithm; options.GetBoolValue("mehrotra_algorithm", mehrotra_algorithm, prefix); // Create the convergence check SmartPtr<ConvergenceCheck> convCheck = new OptimalityErrorConvergenceCheck(); // Create the solvers that will be used by the main algorithm SmartPtr<SparseSymLinearSolverInterface> SolverInterface; std::string linear_solver; options.GetStringValue("linear_solver", linear_solver, prefix); bool use_custom_solver = false; if (linear_solver=="ma27") { #ifndef COINHSL_HAS_MA27 # ifdef HAVE_LINEARSOLVERLOADER SolverInterface = new Ma27TSolverInterface(); if (!LSL_isMA27available()) { char buf[256]; int rc = LSL_loadHSL(NULL, buf, 255); if (rc) { std::string errmsg; errmsg = "Selected linear solver MA27 not available.\nTried to obtain MA27 from shared library \""; errmsg += LSL_HSLLibraryName(); errmsg += "\", but the following error occured:\n"; errmsg += buf; THROW_EXCEPTION(OPTION_INVALID, errmsg.c_str()); } } # else THROW_EXCEPTION(OPTION_INVALID, "Support for MA27 has not been compiled into Ipopt."); # endif #else SolverInterface = new Ma27TSolverInterface(); #endif } else if (linear_solver=="ma57") { #ifndef COINHSL_HAS_MA57 # ifdef HAVE_LINEARSOLVERLOADER SolverInterface = new Ma57TSolverInterface(); if (!LSL_isMA57available()) { char buf[256]; int rc = LSL_loadHSL(NULL, buf, 255); if (rc) { std::string errmsg; errmsg = "Selected linear solver MA57 not available.\nTried to obtain MA57 from shared library \""; errmsg += LSL_HSLLibraryName(); errmsg += "\", but the following error occured:\n"; errmsg += buf; THROW_EXCEPTION(OPTION_INVALID, errmsg.c_str()); } } # else THROW_EXCEPTION(OPTION_INVALID, "Support for MA57 has not been compiled into Ipopt."); # endif #else SolverInterface = new Ma57TSolverInterface(); #endif } else if (linear_solver=="ma77") { #ifndef COINHSL_HAS_MA77 # ifdef HAVE_LINEARSOLVERLOADER SolverInterface = new Ma77SolverInterface(); if (!LSL_isMA77available()) { char buf[256]; int rc = LSL_loadHSL(NULL, buf, 255); if (rc) { std::string errmsg; errmsg = "Selected linear solver HSL_MA77 not available.\nTried to obtain HSL_MA77 from shared library \""; errmsg += LSL_HSLLibraryName(); errmsg += "\", but the following error occured:\n"; errmsg += buf; THROW_EXCEPTION(OPTION_INVALID, errmsg.c_str()); } } # else THROW_EXCEPTION(OPTION_INVALID, "Support for HSL_MA77 has not been compiled into Ipopt."); # endif #else SolverInterface = new Ma77SolverInterface(); #endif } else if (linear_solver=="ma86") { #ifndef COINHSL_HAS_MA86 # ifdef HAVE_LINEARSOLVERLOADER SolverInterface = new Ma86SolverInterface(); if (!LSL_isMA86available()) { char buf[256]; int rc = LSL_loadHSL(NULL, buf, 255); if (rc) { std::string errmsg; errmsg = "Selected linear solver HSL_MA86 not available.\nTried to obtain HSL_MA86 from shared library \""; errmsg += LSL_HSLLibraryName(); errmsg += "\", but the following error occured:\n"; errmsg += buf; THROW_EXCEPTION(OPTION_INVALID, errmsg.c_str()); } } # else THROW_EXCEPTION(OPTION_INVALID, "Support for HSL_MA86 has not been compiled into Ipopt."); # endif #else SolverInterface = new Ma86SolverInterface(); #endif } else if (linear_solver=="pardiso") { #ifndef HAVE_PARDISO # ifdef HAVE_LINEARSOLVERLOADER SolverInterface = new PardisoSolverInterface(); char buf[256]; int rc = LSL_loadPardisoLib(NULL, buf, 255); if (rc) { std::string errmsg; errmsg = "Selected linear solver Pardiso not available.\nTried to obtain Pardiso from shared library \""; errmsg += LSL_PardisoLibraryName(); errmsg += "\", but the following error occured:\n"; errmsg += buf; THROW_EXCEPTION(OPTION_INVALID, errmsg.c_str()); } # else THROW_EXCEPTION(OPTION_INVALID, "Support for Pardiso has not been compiled into Ipopt."); # endif #else SolverInterface = new PardisoSolverInterface(); #endif } else if (linear_solver=="ma97") { #ifndef COINHSL_HAS_MA97 # ifdef HAVE_LINEARSOLVERLOADER SolverInterface = new Ma97SolverInterface(); if (!LSL_isMA97available()) { char buf[256]; int rc = LSL_loadHSL(NULL, buf, 255); if (rc) { std::string errmsg; errmsg = "Selected linear solver HSL_MA97 not available.\nTried to obtain HSL_MA97 from shared library \""; errmsg += LSL_HSLLibraryName(); errmsg += "\", but the following error occured:\n"; errmsg += buf; THROW_EXCEPTION(OPTION_INVALID, errmsg.c_str()); } } # else THROW_EXCEPTION(OPTION_INVALID, "Support for HSL_MA97 has not been compiled into Ipopt."); # endif #else SolverInterface = new Ma97SolverInterface(); #endif } else if (linear_solver=="wsmp") { #ifdef HAVE_WSMP bool wsmp_iterative; options.GetBoolValue("wsmp_iterative", wsmp_iterative, prefix); if (wsmp_iterative) { SolverInterface = new IterativeWsmpSolverInterface(); } else { SolverInterface = new WsmpSolverInterface(); } #else THROW_EXCEPTION(OPTION_INVALID, "Selected linear solver WSMP not available."); #endif } else if (linear_solver=="mumps") { #ifdef COIN_HAS_MUMPS SolverInterface = new MumpsSolverInterface(); #else THROW_EXCEPTION(OPTION_INVALID, "Selected linear solver MUMPS not available."); #endif } else if (linear_solver=="custom") { ASSERT_EXCEPTION(IsValid(custom_solver_), OPTION_INVALID, "Selected linear solver CUSTOM not available."); use_custom_solver = true; } SmartPtr<AugSystemSolver> AugSolver; if (use_custom_solver) { AugSolver = custom_solver_; } else { SmartPtr<TSymScalingMethod> ScalingMethod; std::string linear_system_scaling; if (!options.GetStringValue("linear_system_scaling", linear_system_scaling, prefix)) { // By default, don't use mc19 for non-HSL solvers, or HSL_MA97 if (linear_solver!="ma27" && linear_solver!="ma57" && linear_solver!="ma77" && linear_solver!="ma86") { linear_system_scaling="none"; } } if (linear_system_scaling=="mc19") { #ifndef COINHSL_HAS_MC19 # ifdef HAVE_LINEARSOLVERLOADER ScalingMethod = new Mc19TSymScalingMethod(); if (!LSL_isMC19available()) { char buf[256]; int rc = LSL_loadHSL(NULL, buf, 255); if (rc) { std::string errmsg; errmsg = "Selected linear system scaling method MC19 not available.\n"; errmsg += buf; THROW_EXCEPTION(OPTION_INVALID, errmsg.c_str()); } } # else THROW_EXCEPTION(OPTION_INVALID, "Support for MC19 has not been compiled into Ipopt."); # endif #else ScalingMethod = new Mc19TSymScalingMethod(); #endif } else if (linear_system_scaling=="slack-based") { ScalingMethod = new SlackBasedTSymScalingMethod(); } SmartPtr<SymLinearSolver> ScaledSolver = new TSymLinearSolver(SolverInterface, ScalingMethod); AugSolver = new StdAugSystemSolver(*ScaledSolver); } Index enum_int; options.GetEnumValue("hessian_approximation", enum_int, prefix); HessianApproximationType hessian_approximation = HessianApproximationType(enum_int); if (hessian_approximation==LIMITED_MEMORY) { std::string lm_aug_solver; options.GetStringValue("limited_memory_aug_solver", lm_aug_solver, prefix); if (lm_aug_solver == "sherman-morrison") { AugSolver = new LowRankAugSystemSolver(*AugSolver); } else if (lm_aug_solver == "extended") { Index lm_history; options.GetIntegerValue("limited_memory_max_history", lm_history, prefix); Index max_rank; std::string lm_type; options.GetStringValue("limited_memory_update_type", lm_type, prefix); if (lm_type == "bfgs") { max_rank = 2*lm_history; } else if (lm_type == "sr1") { max_rank = lm_history; } else { THROW_EXCEPTION(OPTION_INVALID, "Unknown value for option \"limited_memory_update_type\"."); } AugSolver = new LowRankSSAugSystemSolver(*AugSolver, max_rank); } else { THROW_EXCEPTION(OPTION_INVALID, "Unknown value for option \"limited_memory_aug_solver\"."); } } SmartPtr<PDPerturbationHandler> pertHandler; std::string lsmethod; options.GetStringValue("line_search_method", lsmethod, prefix); if (lsmethod=="cg-penalty") { pertHandler = new CGPerturbationHandler(); } else { pertHandler = new PDPerturbationHandler(); } SmartPtr<PDSystemSolver> PDSolver = new PDFullSpaceSolver(*AugSolver, *pertHandler); // Create the object for initializing the iterates Initialization // object. We include both the warm start and the defaut // initializer, so that the warm start options can be activated // without having to rebuild the algorithm SmartPtr<EqMultiplierCalculator> EqMultCalculator = new LeastSquareMultipliers(*AugSolver); SmartPtr<IterateInitializer> WarmStartInitializer = new WarmStartIterateInitializer(); SmartPtr<IterateInitializer> IterInitializer = new DefaultIterateInitializer(EqMultCalculator, WarmStartInitializer, AugSolver); SmartPtr<RestorationPhase> resto_phase; SmartPtr<RestoConvergenceCheck> resto_convCheck; // We only need a restoration phase object if we use the filter // line search if (lsmethod=="filter" || lsmethod=="penalty") { // Solver for the restoration phase SmartPtr<AugSystemSolver> resto_AugSolver = new AugRestoSystemSolver(*AugSolver); SmartPtr<PDPerturbationHandler> resto_pertHandler = new PDPerturbationHandler(); SmartPtr<PDSystemSolver> resto_PDSolver = new PDFullSpaceSolver(*resto_AugSolver, *resto_pertHandler); // Convergence check in the restoration phase if (lsmethod=="filter") { resto_convCheck = new RestoFilterConvergenceCheck(); } else if (lsmethod=="penalty") { resto_convCheck = new RestoPenaltyConvergenceCheck(); } // Line search method for the restoration phase SmartPtr<RestoRestorationPhase> resto_resto = new RestoRestorationPhase(); SmartPtr<BacktrackingLSAcceptor> resto_LSacceptor; std::string resto_lsacceptor; options.GetStringValue("line_search_method", resto_lsacceptor, "resto."+prefix); if (resto_lsacceptor=="filter") { resto_LSacceptor = new FilterLSAcceptor(GetRawPtr(resto_PDSolver)); } else if (resto_lsacceptor=="cg-penalty") { resto_LSacceptor = new CGPenaltyLSAcceptor(GetRawPtr(resto_PDSolver)); } else if (resto_lsacceptor=="penalty") { resto_LSacceptor = new PenaltyLSAcceptor(GetRawPtr(resto_PDSolver)); } SmartPtr<LineSearch> resto_LineSearch = new BacktrackingLineSearch(resto_LSacceptor, GetRawPtr(resto_resto), GetRawPtr(resto_convCheck)); // Create the mu update that will be used by the restoration phase // algorithm SmartPtr<MuUpdate> resto_MuUpdate; std::string resto_smuupdate; if (!options.GetStringValue("mu_strategy", resto_smuupdate, "resto."+prefix)) { // Change default for quasi-Newton option (then we use adaptive) Index enum_int; if (options.GetEnumValue("hessian_approximation", enum_int, prefix)) { HessianApproximationType hessian_approximation = HessianApproximationType(enum_int); if (hessian_approximation==LIMITED_MEMORY) { resto_smuupdate = "adaptive"; } } } std::string resto_smuoracle; std::string resto_sfixmuoracle; if (resto_smuupdate=="adaptive" ) { options.GetStringValue("mu_oracle", resto_smuoracle, "resto."+prefix); options.GetStringValue("fixed_mu_oracle", resto_sfixmuoracle, "resto."+prefix); } if (resto_smuupdate=="monotone" ) { resto_MuUpdate = new MonotoneMuUpdate(GetRawPtr(resto_LineSearch)); } else if (resto_smuupdate=="adaptive") { SmartPtr<MuOracle> resto_MuOracle; if (resto_smuoracle=="loqo") { resto_MuOracle = new LoqoMuOracle(); } else if (resto_smuoracle=="probing") { resto_MuOracle = new ProbingMuOracle(resto_PDSolver); } else if (resto_smuoracle=="quality-function") { resto_MuOracle = new QualityFunctionMuOracle(resto_PDSolver); } SmartPtr<MuOracle> resto_FixMuOracle; if (resto_sfixmuoracle=="loqo") { resto_FixMuOracle = new LoqoMuOracle(); } else if (resto_sfixmuoracle=="probing") { resto_FixMuOracle = new ProbingMuOracle(resto_PDSolver); } else if (resto_sfixmuoracle=="quality-function") { resto_FixMuOracle = new QualityFunctionMuOracle(resto_PDSolver); } else { resto_FixMuOracle = NULL; } resto_MuUpdate = new AdaptiveMuUpdate(GetRawPtr(resto_LineSearch), resto_MuOracle, resto_FixMuOracle); } // Initialization of the iterates for the restoration phase SmartPtr<EqMultiplierCalculator> resto_EqMultCalculator = new LeastSquareMultipliers(*resto_AugSolver); SmartPtr<IterateInitializer> resto_IterInitializer = new RestoIterateInitializer(resto_EqMultCalculator); // Create the object for the iteration output during restoration SmartPtr<OrigIterationOutput> resto_OrigIterOutput = NULL; // new OrigIterationOutput(); SmartPtr<IterationOutput> resto_IterOutput = new RestoIterationOutput(resto_OrigIterOutput); // Get the Hessian updater for the restoration phase SmartPtr<HessianUpdater> resto_HessUpdater; switch (hessian_approximation) { case EXACT: resto_HessUpdater = new ExactHessianUpdater(); break; case LIMITED_MEMORY: // ToDo This needs to be replaced! resto_HessUpdater = new LimMemQuasiNewtonUpdater(true); break; } // Put together the overall restoration phase IP algorithm SmartPtr<SearchDirectionCalculator> resto_SearchDirCalc; if (resto_lsacceptor=="cg-penalty") { resto_SearchDirCalc = new CGSearchDirCalculator(GetRawPtr(resto_PDSolver)); } else { resto_SearchDirCalc = new PDSearchDirCalculator(GetRawPtr(resto_PDSolver)); } SmartPtr<IpoptAlgorithm> resto_alg = new IpoptAlgorithm(resto_SearchDirCalc, GetRawPtr(resto_LineSearch), GetRawPtr(resto_MuUpdate), GetRawPtr(resto_convCheck), resto_IterInitializer, resto_IterOutput, resto_HessUpdater, resto_EqMultCalculator); // Set the restoration phase resto_phase = new MinC_1NrmRestorationPhase(*resto_alg, EqMultCalculator); } // Create the line search to be used by the main algorithm SmartPtr<BacktrackingLSAcceptor> LSacceptor; if (lsmethod=="filter") { LSacceptor = new FilterLSAcceptor(GetRawPtr(PDSolver)); } else if (lsmethod=="cg-penalty") { LSacceptor = new CGPenaltyLSAcceptor(GetRawPtr(PDSolver)); } else if (lsmethod=="penalty") { LSacceptor = new PenaltyLSAcceptor(GetRawPtr(PDSolver)); } SmartPtr<LineSearch> lineSearch = new BacktrackingLineSearch(LSacceptor, GetRawPtr(resto_phase), convCheck); // The following cross reference is not good: We have to store a // pointer to the lineSearch object in resto_convCheck as a // non-SmartPtr to make sure that things are properly deleted when // the IpoptAlgorithm return by the Builder is destructed. if (IsValid(resto_convCheck)) { resto_convCheck->SetOrigLSAcceptor(*LSacceptor); } // Create the mu update that will be used by the main algorithm SmartPtr<MuUpdate> MuUpdate; std::string smuupdate; if (!options.GetStringValue("mu_strategy", smuupdate, prefix)) { // Change default for quasi-Newton option (then we use adaptive) Index enum_int; if (options.GetEnumValue("hessian_approximation", enum_int, prefix)) { HessianApproximationType hessian_approximation = HessianApproximationType(enum_int); if (hessian_approximation==LIMITED_MEMORY) { smuupdate = "adaptive"; } } if (mehrotra_algorithm) smuupdate = "adaptive"; } ASSERT_EXCEPTION(!mehrotra_algorithm || smuupdate=="adaptive", OPTION_INVALID, "If mehrotra_algorithm=yes, mu_strategy must be \"adaptive\"."); std::string smuoracle; std::string sfixmuoracle; if (smuupdate=="adaptive" ) { if (!options.GetStringValue("mu_oracle", smuoracle, prefix)) { if (mehrotra_algorithm) smuoracle = "probing"; } options.GetStringValue("fixed_mu_oracle", sfixmuoracle, prefix); ASSERT_EXCEPTION(!mehrotra_algorithm || smuoracle=="probing", OPTION_INVALID, "If mehrotra_algorithm=yes, mu_oracle must be \"probing\"."); } if (smuupdate=="monotone" ) { MuUpdate = new MonotoneMuUpdate(GetRawPtr(lineSearch)); } else if (smuupdate=="adaptive") { SmartPtr<MuOracle> muOracle; if (smuoracle=="loqo") { muOracle = new LoqoMuOracle(); } else if (smuoracle=="probing") { muOracle = new ProbingMuOracle(PDSolver); } else if (smuoracle=="quality-function") { muOracle = new QualityFunctionMuOracle(PDSolver); } SmartPtr<MuOracle> FixMuOracle; if (sfixmuoracle=="loqo") { FixMuOracle = new LoqoMuOracle(); } else if (sfixmuoracle=="probing") { FixMuOracle = new ProbingMuOracle(PDSolver); } else if (sfixmuoracle=="quality-function") { FixMuOracle = new QualityFunctionMuOracle(PDSolver); } else { FixMuOracle = NULL; } MuUpdate = new AdaptiveMuUpdate(GetRawPtr(lineSearch), muOracle, FixMuOracle); } // Create the object for the iteration output SmartPtr<IterationOutput> IterOutput = new OrigIterationOutput(); // Get the Hessian updater for the main algorithm SmartPtr<HessianUpdater> HessUpdater; switch (hessian_approximation) { case EXACT: HessUpdater = new ExactHessianUpdater(); break; case LIMITED_MEMORY: // ToDo This needs to be replaced! HessUpdater = new LimMemQuasiNewtonUpdater(false); break; } // Create the main algorithm SmartPtr<SearchDirectionCalculator> SearchDirCalc; if (lsmethod=="cg-penalty") { SearchDirCalc = new CGSearchDirCalculator(GetRawPtr(PDSolver)); } else { SearchDirCalc = new PDSearchDirCalculator(GetRawPtr(PDSolver)); } SmartPtr<IpoptAlgorithm> alg = new IpoptAlgorithm(SearchDirCalc, GetRawPtr(lineSearch), MuUpdate, convCheck, IterInitializer, IterOutput, HessUpdater, EqMultCalculator); return alg; }
SmartPtr<SymLinearSolver> AlgorithmBuilder::SymLinearSolverFactory( const Journalist& jnlst, const OptionsList& options, const std::string& prefix ) { SmartPtr<SparseSymLinearSolverInterface> SolverInterface; std::string linear_solver; options.GetStringValue("linear_solver", linear_solver, prefix); if( linear_solver == "ma27" ) { #ifndef COINHSL_HAS_MA27 # ifdef HAVE_LINEARSOLVERLOADER SolverInterface = new Ma27TSolverInterface(); if (!LSL_isMA27available()) { char buf[256]; int rc = LSL_loadHSL(NULL, buf, 255); if (rc) { std::string errmsg; errmsg = "Selected linear solver MA27 not available.\nTried to obtain MA27 from shared library \""; errmsg += LSL_HSLLibraryName(); errmsg += "\", but the following error occured:\n"; errmsg += buf; THROW_EXCEPTION(OPTION_INVALID, errmsg.c_str()); } } # else THROW_EXCEPTION(OPTION_INVALID, "Support for MA27 has not been compiled into Ipopt."); # endif #else SolverInterface = new Ma27TSolverInterface(); #endif } else if( linear_solver == "ma57" ) { #ifndef COINHSL_HAS_MA57 # ifdef HAVE_LINEARSOLVERLOADER SolverInterface = new Ma57TSolverInterface(); if (!LSL_isMA57available()) { char buf[256]; int rc = LSL_loadHSL(NULL, buf, 255); if (rc) { std::string errmsg; errmsg = "Selected linear solver MA57 not available.\nTried to obtain MA57 from shared library \""; errmsg += LSL_HSLLibraryName(); errmsg += "\", but the following error occured:\n"; errmsg += buf; THROW_EXCEPTION(OPTION_INVALID, errmsg.c_str()); } } # else THROW_EXCEPTION(OPTION_INVALID, "Support for MA57 has not been compiled into Ipopt."); # endif #else SolverInterface = new Ma57TSolverInterface(); #endif } else if( linear_solver == "ma77" ) { #ifndef COINHSL_HAS_MA77 # ifdef HAVE_LINEARSOLVERLOADER SolverInterface = new Ma77SolverInterface(); if (!LSL_isMA77available()) { char buf[256]; int rc = LSL_loadHSL(NULL, buf, 255); if (rc) { std::string errmsg; errmsg = "Selected linear solver HSL_MA77 not available.\nTried to obtain HSL_MA77 from shared library \""; errmsg += LSL_HSLLibraryName(); errmsg += "\", but the following error occured:\n"; errmsg += buf; THROW_EXCEPTION(OPTION_INVALID, errmsg.c_str()); } } # else THROW_EXCEPTION(OPTION_INVALID, "Support for HSL_MA77 has not been compiled into Ipopt."); # endif #else SolverInterface = new Ma77SolverInterface(); #endif } else if( linear_solver == "ma86" ) { #ifndef COINHSL_HAS_MA86 # ifdef HAVE_LINEARSOLVERLOADER SolverInterface = new Ma86SolverInterface(); if (!LSL_isMA86available()) { char buf[256]; int rc = LSL_loadHSL(NULL, buf, 255); if (rc) { std::string errmsg; errmsg = "Selected linear solver HSL_MA86 not available.\nTried to obtain HSL_MA86 from shared library \""; errmsg += LSL_HSLLibraryName(); errmsg += "\", but the following error occured:\n"; errmsg += buf; THROW_EXCEPTION(OPTION_INVALID, errmsg.c_str()); } } # else THROW_EXCEPTION(OPTION_INVALID, "Support for HSL_MA86 has not been compiled into Ipopt."); # endif #else SolverInterface = new Ma86SolverInterface(); #endif } else if( linear_solver == "pardiso" ) { #ifndef HAVE_PARDISO # ifdef HAVE_LINEARSOLVERLOADER SolverInterface = new PardisoSolverInterface(); char buf[256]; int rc = LSL_loadPardisoLib(NULL, buf, 255); if (rc) { std::string errmsg; errmsg = "Selected linear solver Pardiso not available.\nTried to obtain Pardiso from shared library \""; errmsg += LSL_PardisoLibraryName(); errmsg += "\", but the following error occured:\n"; errmsg += buf; THROW_EXCEPTION(OPTION_INVALID, errmsg.c_str()); } # else THROW_EXCEPTION(OPTION_INVALID, "Support for Pardiso has not been compiled into Ipopt."); # endif #else SolverInterface = new PardisoSolverInterface(); #endif } else if( linear_solver == "ma97" ) { #ifndef COINHSL_HAS_MA97 # ifdef HAVE_LINEARSOLVERLOADER SolverInterface = new Ma97SolverInterface(); if (!LSL_isMA97available()) { char buf[256]; int rc = LSL_loadHSL(NULL, buf, 255); if (rc) { std::string errmsg; errmsg = "Selected linear solver HSL_MA97 not available.\nTried to obtain HSL_MA97 from shared library \""; errmsg += LSL_HSLLibraryName(); errmsg += "\", but the following error occured:\n"; errmsg += buf; THROW_EXCEPTION(OPTION_INVALID, errmsg.c_str()); } } # else THROW_EXCEPTION(OPTION_INVALID, "Support for HSL_MA97 has not been compiled into Ipopt."); # endif #else SolverInterface = new Ma97SolverInterface(); #endif } else if( linear_solver == "wsmp" ) { #ifdef HAVE_WSMP bool wsmp_iterative; options.GetBoolValue("wsmp_iterative", wsmp_iterative, prefix); if (wsmp_iterative) { SolverInterface = new IterativeWsmpSolverInterface(); } else { SolverInterface = new WsmpSolverInterface(); } #else THROW_EXCEPTION(OPTION_INVALID, "Selected linear solver WSMP not available."); #endif } else if( linear_solver == "mumps" ) { #ifdef COIN_HAS_MUMPS SolverInterface = new MumpsSolverInterface(); #else THROW_EXCEPTION(OPTION_INVALID, "Selected linear solver MUMPS not available."); #endif } else if( linear_solver == "custom" ) { SolverInterface = NULL; } SmartPtr<TSymScalingMethod> ScalingMethod; std::string linear_system_scaling; if( !options.GetStringValue("linear_system_scaling", linear_system_scaling, prefix) ) { // By default, don't use mc19 for non-HSL solvers, or HSL_MA97 if( linear_solver != "ma27" && linear_solver != "ma57" && linear_solver != "ma77" && linear_solver != "ma86" ) { linear_system_scaling = "none"; } } if( linear_system_scaling == "mc19" ) { #ifndef COINHSL_HAS_MC19 # ifdef HAVE_LINEARSOLVERLOADER ScalingMethod = new Mc19TSymScalingMethod(); if (!LSL_isMC19available()) { char buf[256]; int rc = LSL_loadHSL(NULL, buf, 255); if (rc) { std::string errmsg; errmsg = "Selected linear system scaling method MC19 not available.\n"; errmsg += buf; THROW_EXCEPTION(OPTION_INVALID, errmsg.c_str()); } } # else THROW_EXCEPTION(OPTION_INVALID, "Support for MC19 has not been compiled into Ipopt."); # endif #else ScalingMethod = new Mc19TSymScalingMethod(); #endif } else if( linear_system_scaling == "slack-based" ) { ScalingMethod = new SlackBasedTSymScalingMethod(); } SmartPtr<SymLinearSolver> ScaledSolver = new TSymLinearSolver(SolverInterface, ScalingMethod); return ScaledSolver; }