Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug fixes #17

Merged
merged 6 commits into from
Sep 11, 2024
Merged
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
26 changes: 15 additions & 11 deletions src/IESopt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -562,17 +562,21 @@
# Logging solver output.
if _iesopt_config(model).optimization.solver.log
# todo: replace this with a more general approach
log_file = abspath(_iesopt_config(model).paths.results, "$(_iesopt_config(model).names.scenario).solverlog")
rm(log_file; force=true)
if JuMP.solver_name(model) == "Gurobi"
@info "Logging solver output" log_file
JuMP.set_attribute(model, "LogFile", log_file)
elseif JuMP.solver_name(model) == "HiGHS"
@info "Logging solver output" log_file
JuMP.set_attribute(model, "log_file", log_file)
else
# todo: support MOA here
@error "Logging solver output is currently only supported for Gurobi and HiGHS"
try
log_file = abspath(_iesopt_config(model).paths.results, "$(_iesopt_config(model).names.scenario).solverlog")
rm(log_file; force=true)
if JuMP.solver_name(model) == "Gurobi"
@info "Logging solver output" log_file
JuMP.set_attribute(model, "LogFile", log_file)

Check warning on line 570 in src/IESopt.jl

View check run for this annotation

Codecov / codecov/patch

src/IESopt.jl#L569-L570

Added lines #L569 - L570 were not covered by tests
elseif JuMP.solver_name(model) == "HiGHS"
@info "Logging solver output" log_file
JuMP.set_attribute(model, "log_file", log_file)
else
# todo: support MOA here
@error "Logging solver output is currently only supported for Gurobi and HiGHS"
end
catch
@error "Failed to setup solver log file"

Check warning on line 579 in src/IESopt.jl

View check run for this annotation

Codecov / codecov/patch

src/IESopt.jl#L579

Added line #L579 was not covered by tests
end
end

Expand Down
7 changes: 5 additions & 2 deletions src/parser.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,11 @@ function _parse_model!(model::JuMP.Model, filename::String, global_parameters::D

# Construct the objectives container & add all registered objectives.
for (name, terms) in _iesopt_config(model).optimization.objective.functions
_iesopt(model).model.objectives[name] =
(terms=Set{JuMP.AffExpr}(), expr=JuMP.AffExpr(0.0), constants=Vector{Float64}())
_iesopt(model).model.objectives[name] = (
terms=Set{Union{JuMP.AffExpr, JuMP.VariableRef}}(),
expr=JuMP.AffExpr(0.0),
constants=Vector{Float64}(),
)
_iesopt(model).aux._obj_terms[name] = terms
end

Expand Down
31 changes: 30 additions & 1 deletion src/utils/logging.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,26 @@
Logging.min_enabled_level(filelogger::FileLogger) = Logging.Info
Logging.catch_exceptions(filelogger::FileLogger) = Logging.catch_exceptions(filelogger.logger)

function save_close_filelogger(model::JuMP.Model)
try
if _iesopt(model).logger isa LoggingExtras.TeeLogger
tl = _iesopt(model).logger
if length(tl.loggers) == 2
if tl.loggers[2] isa IESopt.FileLogger
if isopen(tl.loggers[2].logger.stream)
@info "Savely closing the file logger's iostream"
close(tl.loggers[2].logger.stream)
end
end
end
end
catch

Check warning on line 30 in src/utils/logging.jl

View check run for this annotation

Codecov / codecov/patch

src/utils/logging.jl#L30

Added line #L30 was not covered by tests
# TODO: maybe we can do something here?
end

return nothing
end

function _attach_logger!(model::JuMP.Model)
verbosity = _iesopt_config(model).verbosity

Expand All @@ -36,7 +56,16 @@
else
log_file = "$(_iesopt_config(model).names.scenario).log"
log_path = normpath(mkpath(_iesopt_config(model).paths.results), log_file)
_iesopt(model).logger = LoggingExtras.TeeLogger(logger, FileLogger(log_path))
try
_iesopt(model).logger = LoggingExtras.TeeLogger(logger, FileLogger(log_path))
catch
@error (

Check warning on line 62 in src/utils/logging.jl

View check run for this annotation

Codecov / codecov/patch

src/utils/logging.jl#L62

Added line #L62 was not covered by tests
"Could not create file logger, falling back to console logger only; if this happened after a " *
"previous model run, consider calling `save_close_filelogger(model)` after you are done with your " *
"previous model - before re-generating a new one - to properly release the log file handle"
)
_iesopt(model).logger = logger

Check warning on line 67 in src/utils/logging.jl

View check run for this annotation

Codecov / codecov/patch

src/utils/logging.jl#L67

Added line #L67 was not covered by tests
end
end
end

Expand Down
3 changes: 3 additions & 0 deletions test/src/basic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ end
model = JuMP.Model()
IESopt.generate!(model, joinpath(PATH_TESTFILES, "filesystem", fn); verbosity=false)
@test haskey(model.ext[:iesopt].input.noncore[:templates], "TestComp")
IESopt.save_close_filelogger(model)

# relative path
cd(PATH_TESTFILES)
model = JuMP.Model()
IESopt.generate!(model, joinpath("filesystem", fn); verbosity=false)
IESopt.save_close_filelogger(model)

# filename only
@test haskey(model.ext[:iesopt].input.noncore[:templates], "TestComp")
Expand All @@ -44,6 +46,7 @@ end
IESopt.generate!(model, fn; verbosity=false)
@test haskey(model.ext[:iesopt].input.noncore[:templates], "TestComp")
cd(PATH_CURRENT)
IESopt.save_close_filelogger(model)
end
end
end
Expand Down
11 changes: 11 additions & 0 deletions test/src/examples.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ function _test_example_default_solver(filename::String; obj::Float64, verbosity:
model = @suppress generate!(joinpath(PATH_EXAMPLES, filename); verbosity=verbosity, kwargs...)
@suppress optimize!(model)
@test JuMP.objective_value(model) ≈ obj atol = 0.1
IESopt.save_close_filelogger(model)
end
end

Expand Down Expand Up @@ -38,6 +39,7 @@ _test_example_default_solver("44_lossy_connections.iesopt.yaml"; obj=1233.75)
optimize!(model)
@test JuMP.value(model.ext[:iesopt].model.objectives["total_cost"].expr) ≈ 2975.0 atol = 0.05
@test sum(JuMP.value.(values(model.ext[:iesopt].aux.constraint_safety_expressions))) ≈ 1
IESopt.save_close_filelogger(model)
end

# NOTE: This example fails because it tries to read two snapshots from a CSV file containing only one row.
Expand All @@ -62,6 +64,7 @@ end
JuMP.value.(component(model, "create_gas").exp.value) .==
[9.375, 18.75, 22.5, 25.0, 25.0, 25.0, 12.5, 15.0, 25.0],
)
IESopt.save_close_filelogger(model)
end

# model = JuMP.direct_model(HiGHS.Optimizer())
Expand All @@ -76,6 +79,7 @@ end
@test all(JuMP.value.(component(model, "buy").exp.value) .≈ [10.0, 6.0, 6.0, 0.0, 7.0, 4.0])
obj_val_example_22 = JuMP.objective_value(model)
_test_example_default_solver("23_snapshots_from_csv.iesopt.yaml"; obj=obj_val_example_22)
IESopt.save_close_filelogger(model)
end

# model = generate!(joinpath(dir, "24_linearized_optimal_powerflow.iesopt.yaml"); verbosity=false)
Expand Down Expand Up @@ -106,6 +110,7 @@ end
@test JuMP.objective_value(model) ≈ -10.0
@test JuMP.value.(IESopt.component(model, "buy_id").exp.value) == [1, 0, 1, 0]
@test JuMP.value.(IESopt.component(model, "sell_id").exp.value) == [0, 1, 0, 1]
IESopt.save_close_filelogger(model)
end

# Disabled, because Benders needs to modify Decisions (which is currently not possible due to immutability).
Expand All @@ -129,6 +134,7 @@ end
@test JuMP.objective_value(model) ≈ 44376.75 atol = 0.01
@test sum(IESopt.extract_result(model, "plant_gas", "in:gas"; mode="value")) ≈ 986.15 atol = 0.01
@test sum(IESopt.extract_result(model, "electrolysis", "in:electricity"; mode="value")) ≈ 758.58 atol = 0.01
IESopt.save_close_filelogger(model)
end

@testset "47_disable_components" begin
Expand All @@ -155,6 +161,11 @@ end
@test JuMP.objective_value(model_coupled) <=
JuMP.objective_value(model_AT_DE) + JuMP.objective_value(model_CH) <=
JuMP.objective_value(model_individual)

IESopt.save_close_filelogger(model_coupled)
IESopt.save_close_filelogger(model_individual)
IESopt.save_close_filelogger(model_AT_DE)
IESopt.save_close_filelogger(model_CH)
end

# Clean up output files after testing is done.
Expand Down
Loading