diff --git a/instances/s2.json b/instances/s2.json new file mode 100644 index 0000000..1f41a5e --- /dev/null +++ b/instances/s2.json @@ -0,0 +1,348 @@ +{ + "parameters": { + "time horizon (years)": 2 + }, + "products": { + "P1": { + "transportation cost ($/km/tonne)": [ + 0.015, + 0.015 + ], + "transportation energy (J/km/tonne)": [ + 0.12, + 0.11 + ], + "transportation emissions (tonne/km/tonne)": { + "CO2": [ + 0.052, + 0.050 + ], + "CH4": [ + 0.003, + 0.002 + ] + }, + "initial amounts": { + "C1": { + "location": "2018-us-county:17043", + "amount (tonne)": [ + 934.56, + 934.56 + ] + }, + "C2": { + "latitude (deg)": 7.0, + "longitude (deg)": 19.0, + "amount (tonne)": [ + 198.95, + 198.95 + ] + }, + "C3": { + "latitude (deg)": 84.0, + "longitude (deg)": 76.0, + "amount (tonne)": [ + 212.97, + 212.97 + ] + }, + "C4": { + "latitude (deg)": 21.0, + "longitude (deg)": 16.0, + "amount (tonne)": [ + 352.19, + 352.19 + ] + }, + "C5": { + "latitude (deg)": 32.0, + "longitude (deg)": 92.0, + "amount (tonne)": [ + 510.33, + 510.33 + ] + }, + "C6": { + "latitude (deg)": 14.0, + "longitude (deg)": 62.0, + "amount (tonne)": [ + 471.66, + 471.66 + ] + }, + "C7": { + "latitude (deg)": 30.0, + "longitude (deg)": 83.0, + "amount (tonne)": [ + 785.21, + 785.21 + ] + }, + "C8": { + "latitude (deg)": 35.0, + "longitude (deg)": 40.0, + "amount (tonne)": [ + 706.17, + 706.17 + ] + }, + "C9": { + "latitude (deg)": 74.0, + "longitude (deg)": 52.0, + "amount (tonne)": [ + 30.08, + 30.08 + ] + }, + "C10": { + "latitude (deg)": 22.0, + "longitude (deg)": 54.0, + "amount (tonne)": [ + 536.52, + 536.52 + ] + } + } + }, + "P2": { + "transportation cost ($/km/tonne)": [ + 0.02, + 0.02 + ] + }, + "P3": { + "transportation cost ($/km/tonne)": [ + 0.0125, + 0.0125 + ] + }, + "P4": { + "transportation cost ($/km/tonne)": [ + 0.0175, + 0.0175 + ] + } + }, + "plants": { + "F1": { + "input": "P1", + "outputs (tonne/tonne)": { + "P2": 0.2, + "P3": 0.5 + }, + "energy (GJ/tonne)": [ + 0.12, + 0.11 + ], + "emissions (tonne/tonne)": { + "CO2": [ + 0.052, + 0.050 + ], + "CH4": [ + 0.003, + 0.002 + ] + }, + "locations": { + "L1": { + "latitude (deg)": 0.0, + "longitude (deg)": 0.0, + "disposal": { + "P2": { + "cost ($/tonne)": [ + -10.0, + -10.0 + ], + "limit (tonne)": [ + 1.0, + 1.0 + ] + }, + "P3": { + "cost ($/tonne)": [ + -10.0, + -10.0 + ], + "limit (tonne)": [ + 1.0, + 1.0 + ] + } + }, + "capacities (tonne)": { + "250.0": { + "opening cost ($)": [ + 500.0, + 500.0 + ], + "fixed operating cost ($)": [ + 30.0, + 30.0 + ], + "variable operating cost ($/tonne)": [ + 30.0, + 30.0 + ] + }, + "1000.0": { + "opening cost ($)": [ + 1250.0, + 1250.0 + ], + "fixed operating cost ($)": [ + 30.0, + 30.0 + ], + "variable operating cost ($/tonne)": [ + 30.0, + 30.0 + ] + } + } + }, + "L2": { + "latitude (deg)": 0.5, + "longitude (deg)": 0.5, + "capacities (tonne)": { + "0.0": { + "opening cost ($)": [ + 1000, + 1000 + ], + "fixed operating cost ($)": [ + 50.0, + 50.0 + ], + "variable operating cost ($/tonne)": [ + 50.0, + 50.0 + ] + }, + "10000.0": { + "opening cost ($)": [ + 10000, + 10000 + ], + "fixed operating cost ($)": [ + 50.0, + 50.0 + ], + "variable operating cost ($/tonne)": [ + 50.0, + 50.0 + ] + } + } + } + } + }, + "F2": { + "input": "P2", + "outputs (tonne/tonne)": { + "P3": 0.05, + "P4": 0.80 + }, + "locations": { + "L3": { + "latitude (deg)": 25.0, + "longitude (deg)": 65.0, + "disposal": { + "P3": { + "cost ($/tonne)": [ + 100.0, + 100.0 + ] + } + }, + "capacities (tonne)": { + "1000.0": { + "opening cost ($)": [ + 3000, + 3000 + ], + "fixed operating cost ($)": [ + 50.0, + 50.0 + ], + "variable operating cost ($/tonne)": [ + 50.0, + 50.0 + ] + } + } + }, + "L4": { + "latitude (deg)": 0.75, + "longitude (deg)": 0.20, + "capacities (tonne)": { + "10000": { + "opening cost ($)": [ + 3000, + 3000 + ], + "fixed operating cost ($)": [ + 50.0, + 50.0 + ], + "variable operating cost ($/tonne)": [ + 50.0, + 50.0 + ] + } + } + } + } + }, + "F3": { + "input": "P4", + "locations": { + "L5": { + "latitude (deg)": 100.0, + "longitude (deg)": 100.0, + "capacities (tonne)": { + "15000": { + "opening cost ($)": [ + 0.0, + 0.0 + ], + "fixed operating cost ($)": [ + 0.0, + 0.0 + ], + "variable operating cost ($/tonne)": [ + -15.0, + -15.0 + ] + } + } + } + } + }, + "F4": { + "input": "P3", + "locations": { + "L6": { + "latitude (deg)": 50.0, + "longitude (deg)": 50.0, + "capacities (tonne)": { + "10000": { + "opening cost ($)": [ + 0.0, + 0.0 + ], + "fixed operating cost ($)": [ + 0.0, + 0.0 + ], + "variable operating cost ($/tonne)": [ + -15.0, + -15.0 + ] + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/docs/format.md b/src/docs/format.md index 21f1d80..4733144 100644 --- a/src/docs/format.md +++ b/src/docs/format.md @@ -182,6 +182,7 @@ The keys in the `capacities (tonne)` dictionary should be the amounts (in tonnes } ``` + ### Current limitations * Each plant can only be opened exactly once. After open, the plant remains open until the end of the simulation. diff --git a/src/instance/parse.jl b/src/instance/parse.jl index 249dc7d..cd587c1 100644 --- a/src/instance/parse.jl +++ b/src/instance/parse.jl @@ -53,6 +53,11 @@ function parse(json)::Instance # Create collection centers if "initial amounts" in keys(product_dict) for (center_name, center_dict) in product_dict["initial amounts"] + if "location" in keys(center_dict) + point = geodb_query(center_dict["location"]) + center_dict["latitude (deg)"] = point.lat + center_dict["longitude (deg)"] = point.lon + end center = CollectionCenter( length(collection_centers) + 1, center_name, diff --git a/src/schemas/input.json b/src/schemas/input.json index ace5c8d..fd46ec0 100644 --- a/src/schemas/input.json +++ b/src/schemas/input.json @@ -12,7 +12,9 @@ "Parameters": { "type": "object", "properties": { - "time horizon (years)": { "type": "number" } + "time horizon (years)": { + "type": "number" + } }, "required": [ "time horizon (years)" @@ -23,17 +25,27 @@ "additionalProperties": { "type": "object", "properties": { - "input": { "type": "string" }, + "input": { + "type": "string" + }, "outputs (tonne/tonne)": { "type": "object", - "additionalProperties": { "type": "number" } + "additionalProperties": { + "type": "number" + } + }, + "energy (GJ/tonne)": { + "$ref": "#/definitions/TimeSeries" }, - "energy (GJ/tonne)": { "$ref": "#/definitions/TimeSeries" }, "emissions (tonne/tonne)": { "type": "object", - "additionalProperties": { "$ref": "#/definitions/TimeSeries" } + "additionalProperties": { + "$ref": "#/definitions/TimeSeries" + } }, - "locations": { "$ref": "#/definitions/PlantLocation" } + "locations": { + "$ref": "#/definitions/PlantLocation" + } }, "required": [ "input", @@ -46,15 +58,26 @@ "additionalProperties": { "type": "object", "properties": { - "latitude (deg)": { "type": "number" }, - "longitude (deg)": { "type": "number" }, + "location": { + "type": "string" + }, + "latitude (deg)": { + "type": "number" + }, + "longitude (deg)": { + "type": "number" + }, "disposal": { "type": "object", "additionalProperties": { "type": "object", "properties": { - "cost ($/tonne)": { "$ref": "#/definitions/TimeSeries" }, - "limit (tonne)": { "$ref": "#/definitions/TimeSeries" } + "cost ($/tonne)": { + "$ref": "#/definitions/TimeSeries" + }, + "limit (tonne)": { + "$ref": "#/definitions/TimeSeries" + } }, "required": [ "cost ($/tonne)" @@ -64,22 +87,32 @@ "storage": { "type": "object", "properties": { - "cost ($/tonne)": { "$ref": "#/definitions/TimeSeries" }, - "limit (tonne)": { "type": "number" } + "cost ($/tonne)": { + "$ref": "#/definitions/TimeSeries" + }, + "limit (tonne)": { + "type": "number" + } }, "required": [ "cost ($/tonne)", "limit (tonne)" ] - }, + }, "capacities (tonne)": { "type": "object", "additionalProperties": { "type": "object", "properties": { - "variable operating cost ($/tonne)": { "$ref": "#/definitions/TimeSeries" }, - "fixed operating cost ($)": { "$ref": "#/definitions/TimeSeries" }, - "opening cost ($)": { "$ref": "#/definitions/TimeSeries" } + "variable operating cost ($/tonne)": { + "$ref": "#/definitions/TimeSeries" + }, + "fixed operating cost ($)": { + "$ref": "#/definitions/TimeSeries" + }, + "opening cost ($)": { + "$ref": "#/definitions/TimeSeries" + } }, "required": [ "variable operating cost ($/tonne)", @@ -87,11 +120,9 @@ "opening cost ($)" ] } - } + } }, "required": [ - "latitude (deg)", - "longitude (deg)", "capacities (tonne)" ] } @@ -101,13 +132,20 @@ "additionalProperties": { "type": "object", "properties": { - "latitude (deg)": { "type": "number" }, - "longitude (deg)": { "type": "number" }, - "amount (tonne)": { "$ref": "#/definitions/TimeSeries" } + "location": { + "type": "string" + }, + "latitude (deg)": { + "type": "number" + }, + "longitude (deg)": { + "type": "number" + }, + "amount (tonne)": { + "$ref": "#/definitions/TimeSeries" + } }, "required": [ - "latitude (deg)", - "longitude (deg)", "amount (tonne)" ] } @@ -117,25 +155,39 @@ "additionalProperties": { "type": "object", "properties": { - "transportation cost ($/km/tonne)": { "$ref": "#/definitions/TimeSeries" }, - "transportation energy (J/km/tonne)": { "$ref": "#/definitions/TimeSeries" }, + "transportation cost ($/km/tonne)": { + "$ref": "#/definitions/TimeSeries" + }, + "transportation energy (J/km/tonne)": { + "$ref": "#/definitions/TimeSeries" + }, "transportation emissions (tonne/km/tonne)": { "type": "object", - "additionalProperties": { "$ref": "#/definitions/TimeSeries" } + "additionalProperties": { + "$ref": "#/definitions/TimeSeries" + } }, - "initial amounts": { "$ref": "#/definitions/InitialAmount" } + "initial amounts": { + "$ref": "#/definitions/InitialAmount" + } }, "required": [ "transportation cost ($/km/tonne)" ] - } + } } }, "type": "object", "properties": { - "parameters": { "$ref": "#/definitions/Parameters" }, - "plants": { "$ref": "#/definitions/Plant" }, - "products": { "$ref": "#/definitions/Product" } + "parameters": { + "$ref": "#/definitions/Parameters" + }, + "plants": { + "$ref": "#/definitions/Plant" + }, + "products": { + "$ref": "#/definitions/Product" + } }, "required": [ "parameters", diff --git a/test/instance/parse_test.jl b/test/instance/parse_test.jl index c23d8d3..a3da6ca 100644 --- a/test/instance/parse_test.jl +++ b/test/instance/parse_test.jl @@ -70,6 +70,16 @@ using RELOG @test plant.disposal_limit[p4] == [0, 0] end +@testset "parse (geodb)" begin + basedir = dirname(@__FILE__) + instance = RELOG.parsefile("$basedir/../../instances/s2.json") + + centers = instance.collection_centers + @test centers[1].name == "C1" + @test centers[1].latitude == 41.83956 + @test centers[1].longitude == -88.08857 +end + @testset "parse (invalid)" begin basedir = dirname(@__FILE__) @test_throws String RELOG.parsefile("$basedir/../fixtures/s1-wrong-length.json")