Skip to content

Commit 3cf7534

Browse files
committed
limit shared column generation; allow nonlinear objectives, but print a warning
1 parent da70843 commit 3cf7534

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

Diff for: mpisppy/opt/fwph.py

+18-8
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,14 @@ def fw_prep(self):
106106
self._cache_nonant_var_swap_qp()
107107
self._setup_shared_column_generation()
108108

109-
number_initial_column_tries = self.options.get("FW_initialization_attempts", 20)
109+
number_initial_column_tries = self.options.get("FW_initialization_attempts", 10)
110110
if self.FW_options["FW_iter_limit"] == 1 and number_initial_column_tries < 1:
111-
global_toc(f"{self.__class__.__name__}: Warning: FWPH needs an initial shared column if FW_iter_limit == 1. Increasing FW_iter_limit to 2 to ensure convergence")
111+
global_toc(f"{self.__class__.__name__}: Warning: FWPH needs an initial shared column if FW_iter_limit == 1. Increasing FW_iter_limit to 2 to ensure convergence", self.cylinder_rank == 0)
112112
self.FW_options["FW_iter_limit"] = 2
113113
if self.FW_options["FW_iter_limit"] == 1 or number_initial_column_tries > 0:
114114
number_points = self._generate_shared_column(number_initial_column_tries)
115115
if number_points == 0 and self.FW_options["FW_iter_limit"] == 1:
116-
global_toc(f"{self.__class__.__name__}: Warning: FWPH failed to find an initial feasible solution. Increasing FW_iter_limit to 2 to ensure convergence")
116+
global_toc(f"{self.__class__.__name__}: Warning: FWPH failed to find an initial feasible solution. Increasing FW_iter_limit to 2 to ensure convergence", self.cylinder_rank == 0)
117117
self.FW_options["FW_iter_limit"] = 2
118118

119119
self._reenable_W()
@@ -199,7 +199,7 @@ def fwph_main(self, finalize=True):
199199

200200

201201
# add a shared column
202-
shared_columns = self.options.get("FWPH_shared_columns_per_iteration", 1)
202+
shared_columns = self.options.get("FWPH_shared_columns_per_iteration", 0)
203203
if shared_columns > 0:
204204
self.mpicomm.Barrier()
205205
self._disable_W()
@@ -499,18 +499,28 @@ def _conv_diff(self):
499499
[diff, MPI.DOUBLE], [recv, MPI.DOUBLE], op=MPI.SUM)
500500
return recv
501501

502-
def _attach_nonant_objective(self, mip):
502+
def _attach_nonant_objective(self, mip, _print_warning=[True]):
503503
""" Extract the parts of the objective function which involve nonants.
504-
Adds to mip._mpisspy_model.nonant_obj_part
504+
Adds to mip._mpisppy_model.nonant_obj_part
505505
506506
Args:
507507
mip (Pyomo ConcreteModel): MIP model for a scenario or bundle.
508508
"""
509509
obj = find_active_objective(mip)
510510
repn = generate_standard_repn(obj.expr, compute_values=False, quadratic=False)
511+
nonant_var_ids = mip._mpisppy_data.varid_to_nonant_index
511512
if len(repn.nonlinear_vars) > 0:
512-
raise ValueError("FWPH does not support models with nonlinear objective functions")
513-
nonant_var_ids = {id(v) for v in mip._mpisppy_data.nonant_vars.values()}
513+
# hopefull a small number
514+
nonlinear_vars = {id(v) for v in repn.nonlinear_vars}
515+
for v in repn.nonlinear_vars:
516+
if id(v) in nonant_var_ids:
517+
raise RuntimeError("FWPH does not support models where the nonants "
518+
"participate nonlinearly in the objective function")
519+
global_toc("Using FWPH with nonlinear recourse cost. "
520+
"Simplicial decomposition iterates may not return vertices!",
521+
(self.cylinder_rank==0 and _print_warning[0])
522+
)
523+
_print_warning[0] = False
514524
linear_coefs = []
515525
linear_vars = []
516526
for coef, var in zip(repn.linear_coefs, repn.linear_vars):

0 commit comments

Comments
 (0)