Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/gurobi_optimods/opf/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def solve_opf(
opftype = "ac"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would remove aclocal and introduce acreclocal and acpolarlocal which are the same, but with the difference that for rec we use

        useef = True
        usejabr = False
        polar = False

and for polar we use

        useef = False
        usejabr = False
        polar = True

useef = True
usejabr = False
polar = False
default_solver_params = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would change the settings to

"OptimalityTarget": 1
"SolutionLimit": 1

We have to set a solution limit for the case when we have branch switching, because then we have binaries in the model.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't OptimalityTarget 1 throw an error for a MIP?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, it would. We would need to do something else when we have branch switching on.

"Presolve": 0,
"SolutionLimit": 1,
Expand All @@ -89,18 +90,28 @@ def solve_opf(
opftype = "ac"
useef = True
usejabr = True
polar = False
default_solver_params = {"MIPGap": 1e-3, "OptimalityTol": 1e-3}
# Exact polar AC
elif opftype.lower() == "acpolar":
opftype = "ac"
useef = False
usejabr = False
polar = True
default_solver_params = {"MIPGap": 1e-3, "OptimalityTol": 1e-3}
# AC relaxation using the JABR inequality
elif opftype.lower() == "acrelax":
opftype = "ac"
useef = False
usejabr = True
polar = False
default_solver_params = {"MIPGap": 1e-3, "OptimalityTol": 1e-3}
# DC linear approximation (ef & jabr are irrelevant)
elif opftype.lower() == "dc":
opftype = "dc"
useef = False
usejabr = False
polar = False
default_solver_params = {"MIPGap": 1e-4, "OptimalityTol": 1e-4}
else:
raise ValueError(f"Unknown opftype '{opftype}'")
Expand All @@ -115,8 +126,8 @@ def solve_opf(
branchswitching=branch_switching,
usemipstart=use_mip_start,
minactivebranches=min_active_branches,
polar=False,
ivtype="aggressive",
polar=polar,
ivtype="aggressive", # ignored, no IV formulation used
useactivelossineqs=False,
)

Expand Down
8 changes: 8 additions & 0 deletions tests/opf/test_solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,14 @@ def test_ac_branchswitching_infeasible(self):
with self.assertRaisesRegex(ValueError, "Infeasible model"):
solve_opf(self.case, opftype="AC", branch_switching=True)

def test_ac_polar(self):
kwargs = dict(
opftype="acpolar",
solver_params={"MIPGap": 2e-2, "TimeLimit": 60},
)
solution = solve_opf(self.case, **kwargs)
self.assertLess(solution["f"], 18000)


class TestComputeVoltageAnglesBug(unittest.TestCase):
# Reordering the buses on input (which does not change the network
Expand Down