linopy icon indicating copy to clipboard operation
linopy copied to clipboard

Refactoring of linopy solvers to object oriented architecture

Open daniel-rdt opened this issue 1 year ago • 2 comments

In this PR the solvers.py file is refactored to an object-oriented architecture. For this, a Solver superclass is introduced, as well as subclasses for each of the implemented solvers. A given problem can now be solved from a problem file without a linopy model using a specified solver. To solve a problem, for each Solver subclass the method solve_problem_file() is implemented. The implementation is based on the following logic suggested by @FabianHofmann in https://github.com/PyPSA/linopy/issues/198#issuecomment-1805530802:

class Solver:
    def __init__(self, **kwargs):
        ....

    def solve_problem(self):
        raise NotImplementedError

class SolverA(Solver):
    ....
    def solve_problem(self, problem_fn):
        # Implementation of the solve method for SolverA
        ...
        return Result(status, solution)

class SolverB(Solver):
    ....
    def solve_problem(self, problem_fn):
        # Implementation of the solve method for SolverB
        ...
        return Result(status, solution)
....

To solve a problem directly from a problem file, for example using linopy's Gurobi solver interface:

import linopy
from pathlib import Path

problem_file = Path("path/to/problem.lp")

gurobi = linopy.solvers.Gurobi()
gurobi.solve_problem(problem_fn=problem_file)

For direct execution using a linopy model, the method set_direct_model used that adds the model to the Solver instance:

....
solver = solver_class()
solver.set_direct_model(model=model)
result = solver.solve_problem()

Two unit tests (test_solver_classes_from_problem_file and test_solver_classes_direct) were also added to test the functionality of the solver classes from a problem file and directly from a model. @finozzifa, any feedback on this is welcome.

daniel-rdt avatar Sep 20 '24 08:09 daniel-rdt