|
17 | 17 |
|
18 | 18 | from pyomo.common import Executable
|
19 | 19 | from pyomo.common.config import ConfigValue, document_kwargs_from_configdict, ConfigDict
|
20 |
| -from pyomo.common.errors import PyomoException, DeveloperError |
| 20 | +from pyomo.common.errors import ( |
| 21 | + PyomoException, |
| 22 | + DeveloperError, |
| 23 | + InfeasibleConstraintException, |
| 24 | +) |
21 | 25 | from pyomo.common.tempfiles import TempfileManager
|
22 | 26 | from pyomo.common.timing import HierarchicalTimer
|
23 | 27 | from pyomo.core.base.var import _GeneralVarData
|
@@ -314,15 +318,19 @@ def solve(self, model, **kwds):
|
314 | 318 | ) as row_file, open(basename + '.col', 'w') as col_file:
|
315 | 319 | timer.start('write_nl_file')
|
316 | 320 | self._writer.config.set_value(config.writer_config)
|
317 |
| - nl_info = self._writer.write( |
318 |
| - model, |
319 |
| - nl_file, |
320 |
| - row_file, |
321 |
| - col_file, |
322 |
| - symbolic_solver_labels=config.symbolic_solver_labels, |
323 |
| - ) |
| 321 | + try: |
| 322 | + nl_info = self._writer.write( |
| 323 | + model, |
| 324 | + nl_file, |
| 325 | + row_file, |
| 326 | + col_file, |
| 327 | + symbolic_solver_labels=config.symbolic_solver_labels, |
| 328 | + ) |
| 329 | + proven_infeasible = False |
| 330 | + except InfeasibleConstraintException: |
| 331 | + proven_infeasible = True |
324 | 332 | timer.stop('write_nl_file')
|
325 |
| - if len(nl_info.variables) > 0: |
| 333 | + if not proven_infeasible and len(nl_info.variables) > 0: |
326 | 334 | # Get a copy of the environment to pass to the subprocess
|
327 | 335 | env = os.environ.copy()
|
328 | 336 | if nl_info.external_function_libraries:
|
@@ -361,11 +369,20 @@ def solve(self, model, **kwds):
|
361 | 369 | timer.stop('subprocess')
|
362 | 370 | # This is the stuff we need to parse to get the iterations
|
363 | 371 | # and time
|
364 |
| - iters, ipopt_time_nofunc, ipopt_time_func, ipopt_total_time = ( |
365 |
| - self._parse_ipopt_output(ostreams[0]) |
366 |
| - ) |
367 |
| - |
368 |
| - if len(nl_info.variables) == 0: |
| 372 | + ( |
| 373 | + iters, |
| 374 | + ipopt_time_nofunc, |
| 375 | + ipopt_time_func, |
| 376 | + ipopt_total_time, |
| 377 | + ) = self._parse_ipopt_output(ostreams[0]) |
| 378 | + |
| 379 | + if proven_infeasible: |
| 380 | + results = Results() |
| 381 | + results.termination_condition = TerminationCondition.provenInfeasible |
| 382 | + results.solution_loader = SolSolutionLoader(None, None) |
| 383 | + results.iteration_count = 0 |
| 384 | + results.timing_info.total_seconds = 0 |
| 385 | + elif len(nl_info.variables) == 0: |
369 | 386 | if len(nl_info.eliminated_vars) == 0:
|
370 | 387 | results = Results()
|
371 | 388 | results.termination_condition = TerminationCondition.emptyModel
|
@@ -457,7 +474,7 @@ def solve(self, model, **kwds):
|
457 | 474 | )
|
458 | 475 |
|
459 | 476 | results.solver_configuration = config
|
460 |
| - if len(nl_info.variables) > 0: |
| 477 | + if not proven_infeasible and len(nl_info.variables) > 0: |
461 | 478 | results.solver_log = ostreams[0].getvalue()
|
462 | 479 |
|
463 | 480 | # Capture/record end-time / wall-time
|
|
0 commit comments