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

Expose writing problem files to file #51

Merged
merged 7 commits into from
Jan 10, 2025
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.vscode/

*.jl.*.cov
*.jl.cov
*.jl.mem
Expand Down
4 changes: 3 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "IESopt"
uuid = "ed3f0a38-8ad9-4cf8-877e-929e8d190fe9"
version = "2.2.2"
version = "2.3.0"

[deps]
ArgCheck = "dce04be8-c92d-5529-be00-80e4d2c0e197"
Expand All @@ -27,6 +27,7 @@ Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca"
RelocatableFolders = "05181044-ff0b-4ac5-8273-598c1e38db00"
RuntimeGeneratedFunctions = "7e49a35a-f44a-4d26-94aa-eba1b4ca6b47"
SHA = "ea8e919c-243c-51af-8825-aaa63cd721ce"
Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb"
TestItems = "1c621080-faea-4a02-84b6-bbd5e436b8fe"
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
Expand Down Expand Up @@ -79,6 +80,7 @@ ProgressMeter = "1.10"
RelocatableFolders = "1.0.1"
RuntimeGeneratedFunctions = "0.5.13"
SCIP = "0.11.14, 0.12"
SHA = "0.7.0"
Suppressor = "0.2"
TestItems = "1.0.0"
YAML = "0.4"
Expand Down
119 changes: 119 additions & 0 deletions src/IESopt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,125 @@ function build!(model::JuMP.Model)
return nothing
end

"""
write_to_file(model::JuMP.Model, filename::String; format::JuMP.MOI.FileFormats.FileFormat = JuMP.MOI.FileFormats.FORMAT_AUTOMATIC, kwargs...)

Write the given IESopt model to a file with the specified filename and format.

Be aware, that this function will overwrite any existing file with the same name!

# Arguments
- `model::JuMP.Model`: The IESopt model to be written to a file.
- `filename::String`: The name of the file to which the model should be written. Note that if the format is set to
`FORMAT_AUTOMATIC`, the the file extension will be forced to lower case to allow detection.
- `format::JuMP.MOI.FileFormats.FileFormat` (optional): The format in which the model should be written. The default is
`JuMP.MOI.FileFormats.FORMAT_AUTOMATIC`; if left as that, it will try to automatically determine the format based on
the file extension.

All additional keyword arguments are passed to the `JuMP.write_to_file` function.

# Returns
- `String`: The absolute path to the file to which the model was written.

# Example
```julia
import IESopt

model = IESopt.generate!("config.iesopt.yaml")
IESopt.write_to_file(model, "model.lp")
```
"""
function write_to_file(
model::JuMP.Model,
filename::String;
format::JuMP.MOI.FileFormats.FileFormat=JuMP.MOI.FileFormats.FORMAT_AUTOMATIC,
kwargs...,
)
if format == JuMP.MOI.FileFormats.FORMAT_AUTOMATIC
fn, ext = splitext(filename)
filename = "$(fn)$(lowercase(ext))"
end

JuMP.write_to_file(model, filename; format, kwargs...)

@debug "[write_to_file] Model written to file" filename
return abspath(filename)
end

"""
write_to_file(model::JuMP.Model)

Write the given IESopt model to a file for later use. The filename and location is based on the model's scenario name,
and will be written to the general "results" path that is configured.

# Arguments
- `model::JuMP.Model`: The IESopt model to be written to a file.

# Returns
- `String`: The absolute path to the file to which the model was written.

# Example
```julia
import IESopt

model = IESopt.generate!("config.iesopt.yaml")
IESopt.write_to_file(model)
```
"""
function write_to_file(model::JuMP.Model)
folder = @config(model, paths.results)
scenario = @config(model, general.name.scenario)

filename = normpath(folder, "$(scenario).iesopt.mps")
mkpath(dirname(filename))

return write_to_file(model, filename)
end

@testitem "write_to_file" tags = [:unittest] begin
import IESopt.JuMP
import IESopt.SHA

check_hash(f, h) =
open(f, "r") do io
return true
# TODO: Files are (YAML?) not deterministic => hashes may change
# return bytes2hex(SHA.sha1(read(io, String))) == h
end

model = generate!(String(Assets.get_path("examples", "01_basic_single_node.iesopt.yaml")))

comparisons = [
(fn="test_write_to_file.iesopt.lp", hash="15f3782fa4f38d814d0b247853d4a166c1d7e486"),
(fn="test_write_to_file.iesopt.LP", hash="15f3782fa4f38d814d0b247853d4a166c1d7e486"),
(fn="test_write_to_file.lp", hash="15f3782fa4f38d814d0b247853d4a166c1d7e486"),
(fn="test_write_to_file.iesopt.MPS", hash="2214cbf5df222484d0842043b89f4e5581882f7d"),
]

# Test various file names.
for c in comparisons
target = normpath(tempdir(), c.fn)
file = write_to_file(model, target)
@test isfile(file)
@test check_hash(file, c.hash)
rm(file)
end

# Test writing to custom file format (including keeping case).
file =
write_to_file(model, normpath(tempdir(), "test_write_to_file.IESOPT"); format=JuMP.MOI.FileFormats.FORMAT_MOF)
@test isfile(file)
@test endswith(file, ".IESOPT")
@test check_hash(file, "789a1df6f7a2fc587f80e590dff4e3a88a4e0e8f")
rm(file)

# Test automatically determining the filename.
file = write_to_file(model)
@test isfile(file)
@test check_hash(file, "2214cbf5df222484d0842043b89f4e5581882f7d")
rm(file)
end

"""
optimize!(model::JuMP.Model; kwargs...)

Expand Down
1 change: 1 addition & 0 deletions src/imports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import JSON
import CSV
import DataFrames
import ZipFile
import SHA

# Used in Benders/Stochastic.
import Printf
Expand Down
47 changes: 23 additions & 24 deletions test/Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
version = "1.11.0"

[[deps.BenchmarkTools]]
deps = ["JSON", "Logging", "Printf", "Profile", "Statistics", "UUIDs"]
git-tree-sha1 = "f1dff6729bc61f4d49e140da1af55dcd1ac97b2f"
deps = ["Compat", "JSON", "Logging", "Printf", "Profile", "Statistics", "UUIDs"]
git-tree-sha1 = "e38fbc49a620f5d0b660d7f543db1009fe0f8336"
uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
version = "1.5.0"
version = "1.6.0"

[[deps.Bzip2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "8873e196c2eb87962a2048b3b8e08946535864a1"
uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0"
version = "1.0.8+2"
version = "1.0.8+4"

[[deps.CodeTracking]]
deps = ["InteractiveUtils", "UUIDs"]
Expand All @@ -42,9 +42,9 @@ version = "1.3.6"

[[deps.CodecBzip2]]
deps = ["Bzip2_jll", "TranscodingStreams"]
git-tree-sha1 = "e7c529cc31bb85b97631b922fa2e6baf246f5905"
git-tree-sha1 = "84990fa864b7f2b4901901ca12736e45ee79068c"
uuid = "523fee87-0ab8-5b00-afb7-3ecf72e48cfd"
version = "0.8.4"
version = "0.8.5"

[[deps.CodecZlib]]
deps = ["TranscodingStreams", "Zlib_jll"]
Expand Down Expand Up @@ -125,15 +125,15 @@ version = "0.10.38"

[[deps.HiGHS]]
deps = ["HiGHS_jll", "MathOptInterface", "PrecompileTools", "SparseArrays"]
git-tree-sha1 = "5360ef81c3952f29624ec75ad0045d079c6379f3"
git-tree-sha1 = "b07cf87cb3bcbd65d1d3fcf4143d4a44abe33d20"
uuid = "87dc4568-4c63-4d18-b0c0-bb2238e4078b"
version = "1.12.2"
version = "1.13.0"

[[deps.HiGHS_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Zlib_jll"]
git-tree-sha1 = "cc963ae42b15ccd2536fb7a6254c0328b404347c"
git-tree-sha1 = "26694f04567e584b054b9f33a810cec52adafa38"
uuid = "8fd58aa0-07eb-5a78-9b36-339c94fd15ea"
version = "1.8.1+0"
version = "1.9.0+0"

[[deps.InteractiveUtils]]
deps = ["Markdown"]
Expand Down Expand Up @@ -161,9 +161,9 @@ version = "0.9.12"

[[deps.JLLWrappers]]
deps = ["Artifacts", "Preferences"]
git-tree-sha1 = "be3dc50a92e5a386872a493a10050136d4703f9b"
git-tree-sha1 = "a007feb38b422fbdab534406aeca1b86823cb4d6"
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
version = "1.6.1"
version = "1.7.0"

[[deps.JSON]]
deps = ["Dates", "Mmap", "Parsers", "Unicode"]
Expand All @@ -173,9 +173,9 @@ version = "0.21.4"

[[deps.JuMP]]
deps = ["LinearAlgebra", "MacroTools", "MathOptInterface", "MutableArithmetics", "OrderedCollections", "PrecompileTools", "Printf", "SparseArrays"]
git-tree-sha1 = "866dd0bf0474f0d5527c2765c71889762ba90a27"
git-tree-sha1 = "02b6e65736debc1f47b40b0f7d5dfa0217ee1f09"
uuid = "4076af6c-e467-56ae-b986-b466b2749572"
version = "1.23.5"
version = "1.23.6"

[deps.JuMP.extensions]
JuMPDimensionalDataExt = "DimensionalData"
Expand Down Expand Up @@ -225,9 +225,9 @@ version = "1.11.0"

[[deps.LogExpFunctions]]
deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"]
git-tree-sha1 = "a2d09619db4e765091ee5c6ffe8872849de0feea"
git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f"
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
version = "0.3.28"
version = "0.3.29"

[deps.LogExpFunctions.extensions]
LogExpFunctionsChainRulesCoreExt = "ChainRulesCore"
Expand All @@ -250,10 +250,9 @@ uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b"
version = "3.1.0"

[[deps.MacroTools]]
deps = ["Markdown", "Random"]
git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df"
git-tree-sha1 = "72aebe0b5051e5143a079a4685a46da330a40472"
uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
version = "0.5.13"
version = "0.5.15"

[[deps.Markdown]]
deps = ["Base64"]
Expand Down Expand Up @@ -306,10 +305,10 @@ uuid = "05823500-19ac-5b8b-9628-191a04bc5112"
version = "0.8.1+2"

[[deps.OpenSpecFun_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1"
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"]
git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335"
uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e"
version = "0.5.5+0"
version = "0.5.6+0"

[[deps.OrderedCollections]]
git-tree-sha1 = "12f1439c4f986bb868acda6ea33ebc78e19b95ad"
Expand Down Expand Up @@ -374,9 +373,9 @@ version = "1.11.0"

[[deps.SpecialFunctions]]
deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"]
git-tree-sha1 = "2f5d4697f21388cbe1ff299430dd169ef97d7e14"
git-tree-sha1 = "64cca0c26b4f31ba18f13f6c12af7c85f478cfde"
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
version = "2.4.0"
version = "2.5.0"

[deps.SpecialFunctions.extensions]
SpecialFunctionsChainRulesCoreExt = "ChainRulesCore"
Expand Down
6 changes: 6 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,9 @@ include("src/examples.jl")

@run_package_tests verbose = true filter = ti -> (:examples in ti.tags)
end

try
# Clean up output files after testing is done.
rm(normpath(IESopt.Assets.get_path("examples"), "out"); force=true, recursive=true)
catch
end
6 changes: 0 additions & 6 deletions test/src/examples.jl
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,3 @@ end
@test minimum(setpoint) ≈ -4.65 atol = 0.01
@test maximum(setpoint) ≈ 3.58 atol = 0.01
end

try
# Clean up output files after testing is done.
rm(normpath(IESopt.Assets.get_path("examples"), "out"); force=true, recursive=true)
catch
end
Loading