Move tests to a separate package; update GitHub CI and docs

This commit is contained in:
2023-02-15 11:53:28 -06:00
parent a8e4491ea3
commit 22d73c9ded
33 changed files with 463 additions and 520 deletions

19
test/Project.toml Normal file
View File

@@ -0,0 +1,19 @@
name = "RELOGT"
uuid = "a6dae211-05d8-42ed-9081-b88c982fc90a"
authors = ["Alinson S. Xavier <git@axavier.org>"]
version = "0.1.0"
[deps]
Cbc = "9961bab8-2fa3-5c5a-9d89-47fab24efd76"
GZip = "92fee26a-97fe-5a0c-ad85-20a5f3185b63"
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
JuliaFormatter = "98e50ef6-434e-11e9-1051-2b60c6c9e899"
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
RELOG = "a2afcdf7-cf04-4913-85f9-c0d81ddf2008"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
[compat]
JuliaFormatter = "1"

358
test/fixtures/s1.json vendored Normal file
View File

@@ -0,0 +1,358 @@
{
"parameters": {
"time horizon (years)": 2,
"distance metric": "driving"
},
"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": {
"latitude (deg)": 7.0,
"longitude (deg)": 7.0,
"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
]
}
},
"disposal limit (tonne)": [
1.0,
1.0
],
"disposal cost ($/tonne)": [
-1000,
-1000
]
},
"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
]
}
}
}
}
}
}
}

BIN
test/fixtures/s1.zip vendored Normal file

Binary file not shown.

347
test/fixtures/s2.json vendored Normal file
View File

@@ -0,0 +1,347 @@
{
"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": {
"location": "2018-us-county:17043",
"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
]
}
}
}
}
}
}
}

950
test/fixtures/solutions/s1.json vendored Normal file
View File

@@ -0,0 +1,950 @@
{
"Energy": {
"Plants (GJ)": [
568.6368,
521.2504
],
"Transportation (GJ)": [
3.120910400232,
2.860834533546
]
},
"Costs": {
"Variable operating ($)": [
216672.818,
216672.818
],
"Transportation ($)": [
714499.27483131,
714499.27483131
],
"Disposal ($)": [
-20.0,
-20.0
],
"Total ($)": [
939896.86883131,
931282.09283131
],
"Fixed operating ($)": [
130.0,
130.0
],
"Opening ($)": [
4500.0,
0.0
],
"Expansion ($)": [
4114.776,
0.0
]
},
"Plants": {
"F3": {
"L5": {
"Opening cost ($)": [
0.0,
0.0
],
"Emissions (tonne)": {},
"Expansion cost ($)": [
0.0,
0.0
],
"Longitude (deg)": 100.0,
"Energy (GJ)": [
0.0,
0.0
],
"Total output": {},
"Capacity (tonne)": [
15000.0,
15000.0
],
"Latitude (deg)": 100.0,
"Output": {
"Send": {},
"Dispose": {}
},
"Total input (tonne)": [
757.3824000000001,
757.3824000000001
],
"Fixed operating cost ($)": [
0.0,
0.0
],
"Input": {
"F2": {
"L4": {
"Distance (km)": 8811.73,
"Amount (tonne)": [
757.3824000000001,
757.3824000000001
],
"Transportation energy (J)": [
0.0,
0.0
],
"Transportation cost ($)": [
116792.36127216002,
116792.36127216002
],
"Longitude (deg)": 0.2,
"Variable operating cost ($)": [
-11360.736,
-11360.736
],
"Latitude (deg)": 0.75,
"Emissions (tonne)": {}
}
}
}
}
},
"F1": {
"L1": {
"Opening cost ($)": [
500.0,
0.0
],
"Emissions (tonne)": {
"CH4": [
3.0,
2.0
],
"CO2": [
52.0,
50.0
]
},
"Expansion cost ($)": [
750.0,
0.0
],
"Longitude (deg)": 0.0,
"Energy (GJ)": [
120.0,
110.0
],
"Total output": {
"P2": [
200.0,
200.0
],
"P3": [
500.0,
500.0
]
},
"Capacity (tonne)": [
1000.0,
1000.0
],
"Latitude (deg)": 0.0,
"Output": {
"Send": {
"P2": {
"F2": {
"L4": {
"Distance (km)": 85.87,
"Amount (tonne)": [
199.0,
199.0
],
"Longitude (deg)": 0.2,
"Latitude (deg)": 0.75
}
}
},
"P3": {
"F4": {
"L6": {
"Distance (km)": 6893.41,
"Amount (tonne)": [
499.0,
499.0
],
"Longitude (deg)": 50.0,
"Latitude (deg)": 50.0
}
}
}
},
"Dispose": {
"P2": {
"Amount (tonne)": [
1.0,
1.0
],
"Cost ($)": [
-10.0,
-10.0
]
},
"P3": {
"Amount (tonne)": [
1.0,
1.0
],
"Cost ($)": [
-10.0,
-10.0
]
}
}
},
"Total input (tonne)": [
1000.0,
1000.0
],
"Fixed operating cost ($)": [
30.0,
30.0
],
"Input": {
"Origin": {
"C3": {
"Distance (km)": 8889.75,
"Amount (tonne)": [
212.97000000000003,
212.97000000000003
],
"Transportation energy (J)": [
227190.00690000004,
208257.50632500005
],
"Transportation cost ($)": [
28398.750862500005,
28398.750862500005
],
"Longitude (deg)": 76.0,
"Variable operating cost ($)": [
6389.1,
6389.1
],
"Latitude (deg)": 84.0,
"Emissions (tonne)": {
"CH4": [
0.6389100000000001,
0.42594000000000004
],
"CO2": [
11.074440000000001,
10.648500000000002
]
}
},
"C7": {
"Distance (km)": 8526.39,
"Amount (tonne)": [
246.62,
246.62
],
"Transportation energy (J)": [
252333.396216,
231305.613198
],
"Transportation cost ($)": [
31541.674527,
31541.674527
],
"Longitude (deg)": 83.0,
"Variable operating cost ($)": [
7398.6,
7398.6
],
"Latitude (deg)": 30.0,
"Emissions (tonne)": {
"CH4": [
0.7398600000000001,
0.49324
],
"CO2": [
12.82424,
12.331000000000001
]
}
},
"C5": {
"Distance (km)": 9148.52,
"Amount (tonne)": [
510.3299999999999,
510.3299999999999
],
"Transportation energy (J)": [
560251.7053919999,
513564.0632759999
],
"Transportation cost ($)": [
70031.46317399999,
70031.46317399999
],
"Longitude (deg)": 92.0,
"Variable operating cost ($)": [
15309.899999999998,
15309.899999999998
],
"Latitude (deg)": 32.0,
"Emissions (tonne)": {
"CH4": [
1.5309899999999999,
1.02066
],
"CO2": [
26.537159999999997,
25.516499999999997
]
}
},
"C9": {
"Distance (km)": 8201.21,
"Amount (tonne)": [
30.08,
30.08
],
"Transportation energy (J)": [
29603.087615999993,
27136.163647999994
],
"Transportation cost ($)": [
3700.385951999999,
3700.385951999999
],
"Longitude (deg)": 52.0,
"Variable operating cost ($)": [
902.4,
902.4
],
"Latitude (deg)": 74.0,
"Emissions (tonne)": {
"CH4": [
0.09024,
0.06016
],
"CO2": [
1.5641599999999998,
1.504
]
}
}
}
}
},
"L2": {
"Opening cost ($)": [
999.9999999999999,
0.0
],
"Emissions (tonne)": {
"CH4": [
11.21592,
7.4772799999999995
],
"CO2": [
194.40928,
186.93200000000002
]
},
"Expansion cost ($)": [
3364.7759999999994,
0.0
],
"Longitude (deg)": 0.5,
"Energy (GJ)": [
448.6368,
411.2504
],
"Total output": {
"P2": [
747.728,
747.728
],
"P3": [
1869.32,
1869.32
]
},
"Capacity (tonne)": [
3738.6399999999994,
3738.6399999999994
],
"Latitude (deg)": 0.5,
"Output": {
"Send": {
"P2": {
"F2": {
"L4": {
"Distance (km)": 43.35,
"Amount (tonne)": [
747.728,
747.728
],
"Longitude (deg)": 0.2,
"Latitude (deg)": 0.75
}
}
},
"P3": {
"F4": {
"L6": {
"Distance (km)": 6828.89,
"Amount (tonne)": [
1869.32,
1869.32
],
"Longitude (deg)": 50.0,
"Latitude (deg)": 50.0
}
}
}
},
"Dispose": {}
},
"Total input (tonne)": [
3738.64,
3738.64
],
"Fixed operating cost ($)": [
50.0,
50.0
],
"Input": {
"Origin": {
"C1": {
"Distance (km)": 1017.44,
"Amount (tonne)": [
934.56,
934.56
],
"Transportation energy (J)": [
114103.047168,
104594.459904
],
"Transportation cost ($)": [
14262.880895999999,
14262.880895999999
],
"Longitude (deg)": 7.0,
"Variable operating cost ($)": [
46728.0,
46728.0
],
"Latitude (deg)": 7.0,
"Emissions (tonne)": {
"CH4": [
2.80368,
1.86912
],
"CO2": [
48.59712,
46.728
]
}
},
"C2": {
"Distance (km)": 2165.47,
"Amount (tonne)": [
198.95,
198.95
],
"Transportation energy (J)": [
51698.430779999995,
47390.228214999996
],
"Transportation cost ($)": [
6462.303847499999,
6462.303847499999
],
"Longitude (deg)": 19.0,
"Variable operating cost ($)": [
9947.5,
9947.5
],
"Latitude (deg)": 7.0,
"Emissions (tonne)": {
"CH4": [
0.59685,
0.3979
],
"CO2": [
10.3454,
9.9475
]
}
},
"C8": {
"Distance (km)": 5421.1,
"Amount (tonne)": [
706.17,
706.17
],
"Transportation energy (J)": [
459386.18243999995,
421104.00057
],
"Transportation cost ($)": [
57423.272805,
57423.272805
],
"Longitude (deg)": 40.0,
"Variable operating cost ($)": [
35308.5,
35308.5
],
"Latitude (deg)": 35.0,
"Emissions (tonne)": {
"CH4": [
2.11851,
1.41234
],
"CO2": [
36.720839999999995,
35.3085
]
}
},
"C6": {
"Distance (km)": 6595.52,
"Amount (tonne)": [
471.66,
471.66
],
"Transportation energy (J)": [
373301.15558400005,
342192.72595200007
],
"Transportation cost ($)": [
46662.64444800001,
46662.64444800001
],
"Longitude (deg)": 62.0,
"Variable operating cost ($)": [
23583.0,
23583.0
],
"Latitude (deg)": 14.0,
"Emissions (tonne)": {
"CH4": [
1.4149800000000001,
0.94332
],
"CO2": [
24.526320000000002,
23.583000000000002
]
}
},
"C10": {
"Distance (km)": 6014.13,
"Amount (tonne)": [
536.52,
536.52
],
"Transportation energy (J)": [
387204.123312,
354937.113036
],
"Transportation cost ($)": [
48400.515413999994,
48400.515413999994
],
"Longitude (deg)": 54.0,
"Variable operating cost ($)": [
26826.0,
26826.0
],
"Latitude (deg)": 22.0,
"Emissions (tonne)": {
"CH4": [
1.6095599999999999,
1.07304
],
"CO2": [
27.89904,
26.826
]
}
},
"C4": {
"Distance (km)": 2802.12,
"Amount (tonne)": [
352.19,
352.19
],
"Transportation energy (J)": [
118425.43713599998,
108556.65070799999
],
"Transportation cost ($)": [
14803.179642,
14803.179642
],
"Longitude (deg)": 16.0,
"Variable operating cost ($)": [
17609.5,
17609.5
],
"Latitude (deg)": 21.0,
"Emissions (tonne)": {
"CH4": [
1.05657,
0.70438
],
"CO2": [
18.313879999999997,
17.6095
]
}
},
"C7": {
"Distance (km)": 8469.86,
"Amount (tonne)": [
538.59,
538.59
],
"Transportation energy (J)": [
547413.827688,
501796.008714
],
"Transportation cost ($)": [
68426.728461,
68426.728461
],
"Longitude (deg)": 83.0,
"Variable operating cost ($)": [
26929.5,
26929.5
],
"Latitude (deg)": 30.0,
"Emissions (tonne)": {
"CH4": [
1.6157700000000002,
1.07718
],
"CO2": [
28.00668,
26.929500000000004
]
}
}
}
}
}
},
"F2": {
"L4": {
"Opening cost ($)": [
2999.9999999999995,
0.0
],
"Emissions (tonne)": {},
"Expansion cost ($)": [
0.0,
0.0
],
"Longitude (deg)": 0.2,
"Energy (GJ)": [
0.0,
0.0
],
"Total output": {
"P4": [
757.3824000000001,
757.3824000000001
],
"P3": [
47.336400000000005,
47.336400000000005
]
},
"Capacity (tonne)": [
10000.0,
10000.0
],
"Latitude (deg)": 0.75,
"Output": {
"Send": {
"P4": {
"F3": {
"L5": {
"Distance (km)": 8811.73,
"Amount (tonne)": [
757.3824000000001,
757.3824000000001
],
"Longitude (deg)": 100.0,
"Latitude (deg)": 100.0
}
}
},
"P3": {
"F4": {
"L6": {
"Distance (km)": 6824.63,
"Amount (tonne)": [
47.336400000000005,
47.336400000000005
],
"Longitude (deg)": 50.0,
"Latitude (deg)": 50.0
}
}
}
},
"Dispose": {}
},
"Total input (tonne)": [
946.728,
946.728
],
"Fixed operating cost ($)": [
50.0,
50.0
],
"Input": {
"F1": {
"L1": {
"Distance (km)": 85.87,
"Amount (tonne)": [
199.0,
199.0
],
"Transportation energy (J)": [
0.0,
0.0
],
"Transportation cost ($)": [
341.7626,
341.7626
],
"Longitude (deg)": 0.0,
"Variable operating cost ($)": [
9950.0,
9950.0
],
"Latitude (deg)": 0.0,
"Emissions (tonne)": {}
},
"L2": {
"Distance (km)": 43.35,
"Amount (tonne)": [
747.728,
747.728
],
"Transportation energy (J)": [
0.0,
0.0
],
"Transportation cost ($)": [
648.280176,
648.280176
],
"Longitude (deg)": 0.5,
"Variable operating cost ($)": [
37386.399999999994,
37386.399999999994
],
"Latitude (deg)": 0.5,
"Emissions (tonne)": {}
}
}
}
}
},
"F4": {
"L6": {
"Opening cost ($)": [
0.0,
0.0
],
"Emissions (tonne)": {},
"Expansion cost ($)": [
0.0,
0.0
],
"Longitude (deg)": 50.0,
"Energy (GJ)": [
0.0,
0.0
],
"Total output": {},
"Capacity (tonne)": [
10000.0,
10000.0
],
"Latitude (deg)": 50.0,
"Output": {
"Send": {},
"Dispose": {}
},
"Total input (tonne)": [
2415.6564,
2415.6564
],
"Fixed operating cost ($)": [
0.0,
0.0
],
"Input": {
"F1": {
"L1": {
"Distance (km)": 6893.41,
"Amount (tonne)": [
499.0,
499.0
],
"Transportation energy (J)": [
0.0,
0.0
],
"Transportation cost ($)": [
42997.644875000005,
42997.644875000005
],
"Longitude (deg)": 0.0,
"Variable operating cost ($)": [
-7485.0,
-7485.0
],
"Latitude (deg)": 0.0,
"Emissions (tonne)": {}
},
"L2": {
"Distance (km)": 6828.89,
"Amount (tonne)": [
1869.32,
1869.32
],
"Transportation energy (J)": [
0.0,
0.0
],
"Transportation cost ($)": [
159567.258185,
159567.258185
],
"Longitude (deg)": 0.5,
"Variable operating cost ($)": [
-28039.8,
-28039.8
],
"Latitude (deg)": 0.5,
"Emissions (tonne)": {}
}
},
"F2": {
"L4": {
"Distance (km)": 6824.63,
"Amount (tonne)": [
47.336400000000005,
47.336400000000005
],
"Transportation energy (J)": [
0.0,
0.0
],
"Transportation cost ($)": [
4038.1676941500004,
4038.1676941500004
],
"Longitude (deg)": 0.2,
"Variable operating cost ($)": [
-710.046,
-710.046
],
"Latitude (deg)": 0.75,
"Emissions (tonne)": {}
}
}
}
}
}
},
"Emissions": {
"Transportation (tonne)": {
"CH4": [
14.21592,
9.477279999999999
],
"CO2": [
246.40927999999994,
236.93200000000002
]
},
"Plants (tonne)": {
"CH4": [
14.21592,
9.47728
],
"CO2": [
246.40928,
236.93200000000002
]
}
},
"Products": {
"P1": {
"C1": {
"Marginal cost ($/tonne)": [
133.59,
134.49
]
},
"C2": {
"Marginal cost ($/tonne)": [
150.81,
151.71
]
},
"C3": {
"Marginal cost ($/tonne)": [
250.83,
251.73
]
},
"C8": {
"Marginal cost ($/tonne)": [
199.65,
200.55
]
},
"C6": {
"Marginal cost ($/tonne)": [
217.26,
218.16
]
},
"C10": {
"Marginal cost ($/tonne)": [
208.54,
209.44
]
},
"C4": {
"Marginal cost ($/tonne)": [
160.36,
161.26
]
},
"C5": {
"Marginal cost ($/tonne)": [
254.71,
255.61
]
},
"C7": {
"Marginal cost ($/tonne)": [
245.38,
246.28
]
},
"C9": {
"Marginal cost ($/tonne)": [
240.5,
241.4
]
}
}
}
}

11
test/fixtures/solutions/s1.log vendored Normal file
View File

@@ -0,0 +1,11 @@
[ Info: Reading s1.json...
[ Info: Building graph...
[ Info: 2 time periods
[ Info: 6 process nodes
[ Info: 8 shipping nodes (plant)
[ Info: 10 shipping nodes (collection)
[ Info: 38 arcs
[ Info: Building optimization model...
[ Info: Optimizing MILP...
[ Info: Re-optimizing with integer variables fixed...
[ Info: Extracting solution...

View File

@@ -1,39 +0,0 @@
# Copyright (C) 2020 Argonne National Laboratory
# Written by Alinson Santos Xavier <axavier@anl.gov>
using RELOG
@testset "build_graph" begin
basedir = dirname(@__FILE__)
instance = RELOG.parsefile("$basedir/../../instances/s1.json")
graph = RELOG.build_graph(instance)
process_node_by_location_name =
Dict(n.location.location_name => n for n in graph.process_nodes)
@test length(graph.plant_shipping_nodes) == 8
@test length(graph.collection_shipping_nodes) == 10
@test length(graph.process_nodes) == 6
node = graph.collection_shipping_nodes[1]
@test node.location.name == "C1"
@test length(node.incoming_arcs) == 0
@test length(node.outgoing_arcs) == 2
@test node.outgoing_arcs[1].source.location.name == "C1"
@test node.outgoing_arcs[1].dest.location.plant_name == "F1"
@test node.outgoing_arcs[1].dest.location.location_name == "L1"
@test node.outgoing_arcs[1].values["distance"] == 1695.364
node = process_node_by_location_name["L1"]
@test node.location.plant_name == "F1"
@test node.location.location_name == "L1"
@test length(node.incoming_arcs) == 10
@test length(node.outgoing_arcs) == 2
node = process_node_by_location_name["L3"]
@test node.location.plant_name == "F2"
@test node.location.location_name == "L3"
@test length(node.incoming_arcs) == 2
@test length(node.outgoing_arcs) == 2
@test length(graph.arcs) == 38
end

View File

@@ -1,25 +0,0 @@
# RELOG: Reverse Logistics Optimization
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
using RELOG
@testset "KnnDrivingDistance" begin
# Euclidean distance between Chicago and Indianapolis
@test RELOG._calculate_distance(
41.866,
-87.656,
39.764,
-86.148,
RELOG.EuclideanDistance(),
) == 265.818
# Approximate driving distance between Chicago and Indianapolis
@test RELOG._calculate_distance(
41.866,
-87.656,
39.764,
-86.148,
RELOG.KnnDrivingDistance(),
) == 316.43
end

View File

@@ -1,53 +0,0 @@
# Copyright (C) 2020 Argonne National Laboratory
# Written by Alinson Santos Xavier <axavier@anl.gov>
using RELOG
@testset "compress" begin
basedir = dirname(@__FILE__)
instance = RELOG.parsefile("$basedir/../../instances/s1.json")
compressed = RELOG._compress(instance)
product_name_to_product = Dict(p.name => p for p in compressed.products)
location_name_to_facility = Dict()
for p in compressed.plants
location_name_to_facility[p.location_name] = p
end
for c in compressed.collection_centers
location_name_to_facility[c.name] = c
end
p1 = product_name_to_product["P1"]
p2 = product_name_to_product["P2"]
p3 = product_name_to_product["P3"]
c1 = location_name_to_facility["C1"]
l1 = location_name_to_facility["L1"]
@test compressed.time == 1
@test compressed.building_period == [1]
@test p1.name == "P1"
@test p1.transportation_cost [0.015]
@test p1.transportation_energy [0.115]
@test p1.transportation_emissions["CO2"] [0.051]
@test p1.transportation_emissions["CH4"] [0.0025]
@test c1.name == "C1"
@test c1.amount [1869.12]
@test l1.plant_name == "F1"
@test l1.location_name == "L1"
@test l1.energy [0.115]
@test l1.emissions["CO2"] [0.051]
@test l1.emissions["CH4"] [0.0025]
@test l1.sizes[1].opening_cost [500]
@test l1.sizes[2].opening_cost [1250]
@test l1.sizes[1].fixed_operating_cost [60]
@test l1.sizes[2].fixed_operating_cost [60]
@test l1.sizes[1].variable_operating_cost [30]
@test l1.sizes[2].variable_operating_cost [30]
@test l1.disposal_limit[p2] [2.0]
@test l1.disposal_limit[p3] [2.0]
@test l1.disposal_cost[p2] [-10.0]
@test l1.disposal_cost[p3] [-10.0]
end

View File

@@ -1,25 +0,0 @@
# RELOG: Reverse Logistics Optimization
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
using RELOG
@testset "geodb_query (2018-us-county)" begin
region = RELOG.geodb_query("2018-us-county:17043")
@test region.centroid.lat == 41.83956
@test region.centroid.lon == -88.08857
@test region.population == 922_921
end
# @testset "geodb_query (2018-us-zcta)" begin
# region = RELOG.geodb_query("2018-us-zcta:60439")
# @test region.centroid.lat == 41.68241
# @test region.centroid.lon == -87.98954
# end
@testset "geodb_query (us-state)" begin
region = RELOG.geodb_query("us-state:IL")
@test region.centroid.lat == 39.73939
@test region.centroid.lon == -89.50414
@test region.population == 12_671_821
end

View File

@@ -1,93 +0,0 @@
# Copyright (C) 2020 Argonne National Laboratory
# Written by Alinson Santos Xavier <axavier@anl.gov>
using RELOG
@testset "parse" begin
basedir = dirname(@__FILE__)
instance = RELOG.parsefile("$basedir/../../instances/s1.json")
centers = instance.collection_centers
plants = instance.plants
products = instance.products
location_name_to_plant = Dict(p.location_name => p for p in plants)
product_name_to_product = Dict(p.name => p for p in products)
@test length(centers) == 10
@test centers[1].name == "C1"
@test centers[1].latitude == 7
@test centers[1].latitude == 7
@test centers[1].longitude == 7
@test centers[1].amount == [934.56, 934.56]
@test centers[1].product.name == "P1"
@test length(plants) == 6
plant = location_name_to_plant["L1"]
@test plant.plant_name == "F1"
@test plant.location_name == "L1"
@test plant.input.name == "P1"
@test plant.latitude == 0
@test plant.longitude == 0
@test length(plant.sizes) == 2
@test plant.sizes[1].capacity == 250
@test plant.sizes[1].opening_cost == [500, 500]
@test plant.sizes[1].fixed_operating_cost == [30, 30]
@test plant.sizes[1].variable_operating_cost == [30, 30]
@test plant.sizes[2].capacity == 1000
@test plant.sizes[2].opening_cost == [1250, 1250]
@test plant.sizes[2].fixed_operating_cost == [30, 30]
@test plant.sizes[2].variable_operating_cost == [30, 30]
p1 = product_name_to_product["P1"]
@test p1.disposal_limit == [1.0, 1.0]
@test p1.disposal_cost == [-1000.0, -1000.0]
p2 = product_name_to_product["P2"]
@test p2.disposal_limit == [0.0, 0.0]
@test p2.disposal_cost == [0.0, 0.0]
p3 = product_name_to_product["P3"]
@test length(plant.output) == 2
@test plant.output[p2] == 0.2
@test plant.output[p3] == 0.5
@test plant.disposal_limit[p2] == [1, 1]
@test plant.disposal_limit[p3] == [1, 1]
@test plant.disposal_cost[p2] == [-10, -10]
@test plant.disposal_cost[p3] == [-10, -10]
plant = location_name_to_plant["L3"]
@test plant.location_name == "L3"
@test plant.input.name == "P2"
@test plant.latitude == 25
@test plant.longitude == 65
@test length(plant.sizes) == 2
@test plant.sizes[1].capacity == 1000.0
@test plant.sizes[1].opening_cost == [3000, 3000]
@test plant.sizes[1].fixed_operating_cost == [50, 50]
@test plant.sizes[1].variable_operating_cost == [50, 50]
@test plant.sizes[1] == plant.sizes[2]
p4 = product_name_to_product["P4"]
@test plant.output[p3] == 0.05
@test plant.output[p4] == 0.8
@test plant.disposal_limit[p3] == [1e8, 1e8]
@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 ErrorException RELOG.parsefile("$basedir/../fixtures/s1-wrong-length.json")
# end

View File

@@ -1,38 +0,0 @@
# Copyright (C) 2020 Argonne National Laboratory
# Written by Alinson Santos Xavier <axavier@anl.gov>
using RELOG, Cbc, JuMP, Printf, JSON, MathOptInterface.FileFormats
@testset "build" begin
basedir = dirname(@__FILE__)
instance = RELOG.parsefile("$basedir/../../instances/s1.json")
graph = RELOG.build_graph(instance)
model = RELOG.build_model(instance, graph, Cbc.Optimizer)
set_optimizer_attribute(model, "logLevel", 0)
process_node_by_location_name =
Dict(n.location.location_name => n for n in graph.process_nodes)
shipping_node_by_loc_and_prod_names = Dict(
(n.location.location_name, n.product.name) => n for n in graph.plant_shipping_nodes
)
@test length(model[:flow]) == 76
@test length(model[:plant_dispose]) == 16
@test length(model[:open_plant]) == 12
@test length(model[:capacity]) == 12
@test length(model[:expansion]) == 12
l1 = process_node_by_location_name["L1"]
v = model[:capacity][l1, 1]
@test lower_bound(v) == 0.0
@test upper_bound(v) == 1000.0
v = model[:expansion][l1, 1]
@test lower_bound(v) == 0.0
@test upper_bound(v) == 750.0
v = model[:plant_dispose][shipping_node_by_loc_and_prod_names["L1", "P2"], 1]
@test lower_bound(v) == 0.0
@test upper_bound(v) == 1.0
end

View File

@@ -1,13 +0,0 @@
# Copyright (C) 2020 Argonne National Laboratory
# Written by Alinson Santos Xavier <axavier@anl.gov>
using RELOG
basedir = @__DIR__
@testset "Resolve" begin
# Shoud not crash
filename = "$basedir/../../instances/s1.json"
solution_old, model_old = RELOG.solve(filename, return_model = true)
solution_new = RELOG.resolve(model_old, filename)
end

View File

@@ -1,70 +0,0 @@
# Copyright (C) 2020 Argonne National Laboratory
# Written by Alinson Santos Xavier <axavier@anl.gov>
using RELOG, Cbc, JuMP, Printf, JSON, MathOptInterface.FileFormats
basedir = dirname(@__FILE__)
@testset "solve (exact)" begin
solution_filename_a = tempname()
solution_filename_b = tempname()
solution = RELOG.solve("$basedir/../../instances/s1.json", output = solution_filename_a)
@test isfile(solution_filename_a)
RELOG.write(solution, solution_filename_b)
@test isfile(solution_filename_b)
@test "Costs" in keys(solution)
@test "Fixed operating (\$)" in keys(solution["Costs"])
@test "Transportation (\$)" in keys(solution["Costs"])
@test "Variable operating (\$)" in keys(solution["Costs"])
@test "Total (\$)" in keys(solution["Costs"])
@test "Plants" in keys(solution)
@test "F1" in keys(solution["Plants"])
@test "F2" in keys(solution["Plants"])
@test "F3" in keys(solution["Plants"])
@test "F4" in keys(solution["Plants"])
@test "Products" in keys(solution)
@test "P1" in keys(solution["Products"])
@test "C1" in keys(solution["Products"]["P1"])
@test "Dispose (tonne)" in keys(solution["Products"]["P1"]["C1"])
total_disposal =
sum([loc["Dispose (tonne)"] for loc in values(solution["Products"]["P1"])])
@test total_disposal == [1.0, 1.0]
end
@testset "solve (heuristic)" begin
# Should not crash
solution = RELOG.solve("$basedir/../../instances/s1.json", heuristic = true)
end
@testset "solve (infeasible)" begin
json = JSON.parsefile("$basedir/../../instances/s1.json")
for (location_name, location_dict) in json["products"]["P1"]["initial amounts"]
location_dict["amount (tonne)"] *= 1000
end
@test_throws ErrorException("No solution available") RELOG.solve(RELOG.parse(json))
end
@testset "solve (with storage)" begin
basedir = dirname(@__FILE__)
filename = "$basedir/../fixtures/storage.json"
instance = RELOG.parsefile(filename)
@test instance.plants[1].storage_limit == 50.0
@test instance.plants[1].storage_cost == [2.0, 1.5, 1.0]
solution = RELOG.solve(filename)
plant_dict = solution["Plants"]["mega plant"]["Chicago"]
@test plant_dict["Variable operating cost (\$)"] == [500.0, 0.0, 100.0]
@test plant_dict["Process (tonne)"] == [50.0, 0.0, 50.0]
@test plant_dict["Storage (tonne)"] == [50.0, 50.0, 0.0]
@test plant_dict["Storage cost (\$)"] == [100.0, 75.0, 0.0]
@test solution["Costs"]["Variable operating (\$)"] == [500.0, 0.0, 100.0]
@test solution["Costs"]["Storage (\$)"] == [100.0, 75.0, 0.0]
@test solution["Costs"]["Total (\$)"] == [600.0, 75.0, 100.0]
end

View File

@@ -1,21 +0,0 @@
# RELOG: Reverse Logistics Optimization
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
using RELOG, JSON, GZip
basedir = @__DIR__
@testset "Reports" begin
@testset "from solve" begin
solution = RELOG.solve("$basedir/../instances/s1.json")
tmp_filename = tempname()
# The following should not crash
RELOG.write_plant_emissions_report(solution, tmp_filename)
RELOG.write_plant_outputs_report(solution, tmp_filename)
RELOG.write_plants_report(solution, tmp_filename)
RELOG.write_products_report(solution, tmp_filename)
RELOG.write_transportation_emissions_report(solution, tmp_filename)
RELOG.write_transportation_report(solution, tmp_filename)
end
end

View File

@@ -1,22 +0,0 @@
# Copyright (C) 2020 Argonne National Laboratory
# Written by Alinson Santos Xavier <axavier@anl.gov>
using Test
@testset "RELOG" begin
@testset "Instance" begin
include("instance/compress_test.jl")
include("instance/geodb_test.jl")
include("instance/parse_test.jl")
end
@testset "Graph" begin
include("graph/build_test.jl")
include("graph/dist_test.jl")
end
@testset "Model" begin
include("model/build_test.jl")
include("model/solve_test.jl")
include("model/resolve_test.jl")
end
include("reports_test.jl")
end

51
test/src/RELOGT.jl Normal file
View File

@@ -0,0 +1,51 @@
module RELOGT
using Test
using JuliaFormatter
include("instance/compress_test.jl")
include("instance/geodb_test.jl")
include("instance/parse_test.jl")
include("graph/build_test.jl")
include("graph/dist_test.jl")
include("model/build_test.jl")
include("model/solve_test.jl")
include("model/resolve_test.jl")
include("reports_test.jl")
basedir = dirname(@__FILE__)
function fixture(path::String)::String
return "$basedir/../fixtures/$path"
end
function runtests()
@testset "RELOG" begin
@testset "instance" begin
instance_compress_test()
instance_geodb_test()
instance_parse_test()
end
@testset "graph" begin
graph_build_test()
graph_dist_test()
end
@testset "model" begin
model_build_test()
model_solve_test()
model_resolve_test()
end
reports_test()
end
return
end
function format()
JuliaFormatter.format(basedir, verbose = true)
JuliaFormatter.format("$basedir/../../src", verbose = true)
return
end
export runtests, format
end # module RELOGT

View File

@@ -0,0 +1,40 @@
# Copyright (C) 2020 Argonne National Laboratory
# Written by Alinson Santos Xavier <axavier@anl.gov>
using RELOG
function graph_build_test()
@testset "build_graph" begin
instance = RELOG.parsefile(fixture("s1.json"))
graph = RELOG.build_graph(instance)
process_node_by_location_name =
Dict(n.location.location_name => n for n in graph.process_nodes)
@test length(graph.plant_shipping_nodes) == 8
@test length(graph.collection_shipping_nodes) == 10
@test length(graph.process_nodes) == 6
node = graph.collection_shipping_nodes[1]
@test node.location.name == "C1"
@test length(node.incoming_arcs) == 0
@test length(node.outgoing_arcs) == 2
@test node.outgoing_arcs[1].source.location.name == "C1"
@test node.outgoing_arcs[1].dest.location.plant_name == "F1"
@test node.outgoing_arcs[1].dest.location.location_name == "L1"
@test node.outgoing_arcs[1].values["distance"] == 1695.364
node = process_node_by_location_name["L1"]
@test node.location.plant_name == "F1"
@test node.location.location_name == "L1"
@test length(node.incoming_arcs) == 10
@test length(node.outgoing_arcs) == 2
node = process_node_by_location_name["L3"]
@test node.location.plant_name == "F2"
@test node.location.location_name == "L3"
@test length(node.incoming_arcs) == 2
@test length(node.outgoing_arcs) == 2
@test length(graph.arcs) == 38
end
end

View File

@@ -0,0 +1,27 @@
# RELOG: Reverse Logistics Optimization
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
using RELOG
function graph_dist_test()
@testset "KnnDrivingDistance" begin
# Euclidean distance between Chicago and Indianapolis
@test RELOG._calculate_distance(
41.866,
-87.656,
39.764,
-86.148,
RELOG.EuclideanDistance(),
) == 265.818
# Approximate driving distance between Chicago and Indianapolis
@test RELOG._calculate_distance(
41.866,
-87.656,
39.764,
-86.148,
RELOG.KnnDrivingDistance(),
) == 316.43
end
end

View File

@@ -0,0 +1,54 @@
# Copyright (C) 2020 Argonne National Laboratory
# Written by Alinson Santos Xavier <axavier@anl.gov>
using RELOG
function instance_compress_test()
@testset "compress" begin
instance = RELOG.parsefile(fixture("s1.json"))
compressed = RELOG._compress(instance)
product_name_to_product = Dict(p.name => p for p in compressed.products)
location_name_to_facility = Dict()
for p in compressed.plants
location_name_to_facility[p.location_name] = p
end
for c in compressed.collection_centers
location_name_to_facility[c.name] = c
end
p1 = product_name_to_product["P1"]
p2 = product_name_to_product["P2"]
p3 = product_name_to_product["P3"]
c1 = location_name_to_facility["C1"]
l1 = location_name_to_facility["L1"]
@test compressed.time == 1
@test compressed.building_period == [1]
@test p1.name == "P1"
@test p1.transportation_cost [0.015]
@test p1.transportation_energy [0.115]
@test p1.transportation_emissions["CO2"] [0.051]
@test p1.transportation_emissions["CH4"] [0.0025]
@test c1.name == "C1"
@test c1.amount [1869.12]
@test l1.plant_name == "F1"
@test l1.location_name == "L1"
@test l1.energy [0.115]
@test l1.emissions["CO2"] [0.051]
@test l1.emissions["CH4"] [0.0025]
@test l1.sizes[1].opening_cost [500]
@test l1.sizes[2].opening_cost [1250]
@test l1.sizes[1].fixed_operating_cost [60]
@test l1.sizes[2].fixed_operating_cost [60]
@test l1.sizes[1].variable_operating_cost [30]
@test l1.sizes[2].variable_operating_cost [30]
@test l1.disposal_limit[p2] [2.0]
@test l1.disposal_limit[p3] [2.0]
@test l1.disposal_cost[p2] [-10.0]
@test l1.disposal_cost[p3] [-10.0]
end
end

View File

@@ -0,0 +1,27 @@
# RELOG: Reverse Logistics Optimization
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
using RELOG
function instance_geodb_test()
@testset "geodb_query (2018-us-county)" begin
region = RELOG.geodb_query("2018-us-county:17043")
@test region.centroid.lat == 41.83956
@test region.centroid.lon == -88.08857
@test region.population == 922_921
end
# @testset "geodb_query (2018-us-zcta)" begin
# region = RELOG.geodb_query("2018-us-zcta:60439")
# @test region.centroid.lat == 41.68241
# @test region.centroid.lon == -87.98954
# end
@testset "geodb_query (us-state)" begin
region = RELOG.geodb_query("us-state:IL")
@test region.centroid.lat == 39.73939
@test region.centroid.lon == -89.50414
@test region.population == 12_671_821
end
end

View File

@@ -0,0 +1,87 @@
# Copyright (C) 2020 Argonne National Laboratory
# Written by Alinson Santos Xavier <axavier@anl.gov>
using RELOG
function instance_parse_test()
@testset "parse" begin
instance = RELOG.parsefile(fixture("s1.json"))
centers = instance.collection_centers
plants = instance.plants
products = instance.products
location_name_to_plant = Dict(p.location_name => p for p in plants)
product_name_to_product = Dict(p.name => p for p in products)
@test length(centers) == 10
@test centers[1].name == "C1"
@test centers[1].latitude == 7
@test centers[1].latitude == 7
@test centers[1].longitude == 7
@test centers[1].amount == [934.56, 934.56]
@test centers[1].product.name == "P1"
@test length(plants) == 6
plant = location_name_to_plant["L1"]
@test plant.plant_name == "F1"
@test plant.location_name == "L1"
@test plant.input.name == "P1"
@test plant.latitude == 0
@test plant.longitude == 0
@test length(plant.sizes) == 2
@test plant.sizes[1].capacity == 250
@test plant.sizes[1].opening_cost == [500, 500]
@test plant.sizes[1].fixed_operating_cost == [30, 30]
@test plant.sizes[1].variable_operating_cost == [30, 30]
@test plant.sizes[2].capacity == 1000
@test plant.sizes[2].opening_cost == [1250, 1250]
@test plant.sizes[2].fixed_operating_cost == [30, 30]
@test plant.sizes[2].variable_operating_cost == [30, 30]
p1 = product_name_to_product["P1"]
@test p1.disposal_limit == [1.0, 1.0]
@test p1.disposal_cost == [-1000.0, -1000.0]
p2 = product_name_to_product["P2"]
@test p2.disposal_limit == [0.0, 0.0]
@test p2.disposal_cost == [0.0, 0.0]
p3 = product_name_to_product["P3"]
@test length(plant.output) == 2
@test plant.output[p2] == 0.2
@test plant.output[p3] == 0.5
@test plant.disposal_limit[p2] == [1, 1]
@test plant.disposal_limit[p3] == [1, 1]
@test plant.disposal_cost[p2] == [-10, -10]
@test plant.disposal_cost[p3] == [-10, -10]
plant = location_name_to_plant["L3"]
@test plant.location_name == "L3"
@test plant.input.name == "P2"
@test plant.latitude == 25
@test plant.longitude == 65
@test length(plant.sizes) == 2
@test plant.sizes[1].capacity == 1000.0
@test plant.sizes[1].opening_cost == [3000, 3000]
@test plant.sizes[1].fixed_operating_cost == [50, 50]
@test plant.sizes[1].variable_operating_cost == [50, 50]
@test plant.sizes[1] == plant.sizes[2]
p4 = product_name_to_product["P4"]
@test plant.output[p3] == 0.05
@test plant.output[p4] == 0.8
@test plant.disposal_limit[p3] == [1e8, 1e8]
@test plant.disposal_limit[p4] == [0, 0]
end
@testset "parse (geodb)" begin
instance = RELOG.parsefile(fixture("s2.json"))
centers = instance.collection_centers
@test centers[1].name == "C1"
@test centers[1].latitude == 41.83956
@test centers[1].longitude == -88.08857
end
end

View File

@@ -0,0 +1,40 @@
# Copyright (C) 2020 Argonne National Laboratory
# Written by Alinson Santos Xavier <axavier@anl.gov>
using RELOG, Cbc, JuMP, Printf, JSON, MathOptInterface.FileFormats
function model_build_test()
@testset "build" begin
instance = RELOG.parsefile(fixture("s1.json"))
graph = RELOG.build_graph(instance)
model = RELOG.build_model(instance, graph, Cbc.Optimizer)
set_optimizer_attribute(model, "logLevel", 0)
process_node_by_location_name =
Dict(n.location.location_name => n for n in graph.process_nodes)
shipping_node_by_loc_and_prod_names = Dict(
(n.location.location_name, n.product.name) => n for
n in graph.plant_shipping_nodes
)
@test length(model[:flow]) == 76
@test length(model[:plant_dispose]) == 16
@test length(model[:open_plant]) == 12
@test length(model[:capacity]) == 12
@test length(model[:expansion]) == 12
l1 = process_node_by_location_name["L1"]
v = model[:capacity][l1, 1]
@test lower_bound(v) == 0.0
@test upper_bound(v) == 1000.0
v = model[:expansion][l1, 1]
@test lower_bound(v) == 0.0
@test upper_bound(v) == 750.0
v = model[:plant_dispose][shipping_node_by_loc_and_prod_names["L1", "P2"], 1]
@test lower_bound(v) == 0.0
@test upper_bound(v) == 1.0
end
end

View File

@@ -0,0 +1,13 @@
# Copyright (C) 2020 Argonne National Laboratory
# Written by Alinson Santos Xavier <axavier@anl.gov>
using RELOG
function model_resolve_test()
@testset "Resolve" begin
# Shoud not crash
filename = fixture("s1.json")
solution_old, model_old = RELOG.solve(filename, return_model = true)
solution_new = RELOG.resolve(model_old, filename)
end
end

View File

@@ -0,0 +1,70 @@
# Copyright (C) 2020 Argonne National Laboratory
# Written by Alinson Santos Xavier <axavier@anl.gov>
using RELOG, Cbc, JuMP, Printf, JSON, MathOptInterface.FileFormats
function model_solve_test()
@testset "solve (exact)" begin
solution_filename_a = tempname()
solution_filename_b = tempname()
solution = RELOG.solve(fixture("s1.json"), output = solution_filename_a)
@test isfile(solution_filename_a)
RELOG.write(solution, solution_filename_b)
@test isfile(solution_filename_b)
@test "Costs" in keys(solution)
@test "Fixed operating (\$)" in keys(solution["Costs"])
@test "Transportation (\$)" in keys(solution["Costs"])
@test "Variable operating (\$)" in keys(solution["Costs"])
@test "Total (\$)" in keys(solution["Costs"])
@test "Plants" in keys(solution)
@test "F1" in keys(solution["Plants"])
@test "F2" in keys(solution["Plants"])
@test "F3" in keys(solution["Plants"])
@test "F4" in keys(solution["Plants"])
@test "Products" in keys(solution)
@test "P1" in keys(solution["Products"])
@test "C1" in keys(solution["Products"]["P1"])
@test "Dispose (tonne)" in keys(solution["Products"]["P1"]["C1"])
total_disposal =
sum([loc["Dispose (tonne)"] for loc in values(solution["Products"]["P1"])])
@test total_disposal == [1.0, 1.0]
end
@testset "solve (heuristic)" begin
# Should not crash
solution = RELOG.solve(fixture("s1.json"), heuristic = true)
end
@testset "solve (infeasible)" begin
json = JSON.parsefile(fixture("s1.json"))
for (location_name, location_dict) in json["products"]["P1"]["initial amounts"]
location_dict["amount (tonne)"] *= 1000
end
@test_throws ErrorException("No solution available") RELOG.solve(RELOG.parse(json))
end
@testset "solve (with storage)" begin
filename = fixture("storage.json")
instance = RELOG.parsefile(filename)
@test instance.plants[1].storage_limit == 50.0
@test instance.plants[1].storage_cost == [2.0, 1.5, 1.0]
solution = RELOG.solve(filename)
plant_dict = solution["Plants"]["mega plant"]["Chicago"]
@test plant_dict["Variable operating cost (\$)"] == [500.0, 0.0, 100.0]
@test plant_dict["Process (tonne)"] == [50.0, 0.0, 50.0]
@test plant_dict["Storage (tonne)"] == [50.0, 50.0, 0.0]
@test plant_dict["Storage cost (\$)"] == [100.0, 75.0, 0.0]
@test solution["Costs"]["Variable operating (\$)"] == [500.0, 0.0, 100.0]
@test solution["Costs"]["Storage (\$)"] == [100.0, 75.0, 0.0]
@test solution["Costs"]["Total (\$)"] == [600.0, 75.0, 100.0]
end
end

21
test/src/reports_test.jl Normal file
View File

@@ -0,0 +1,21 @@
# RELOG: Reverse Logistics Optimization
# Copyright (C) 2020, UChicago Argonne, LLC. All rights reserved.
# Released under the modified BSD license. See COPYING.md for more details.
using RELOG, JSON, GZip
function reports_test()
@testset "reports" begin
@testset "from solve" begin
solution = RELOG.solve(fixture("s1.json"))
tmp_filename = tempname()
# The following should not crash
RELOG.write_plant_emissions_report(solution, tmp_filename)
RELOG.write_plant_outputs_report(solution, tmp_filename)
RELOG.write_plants_report(solution, tmp_filename)
RELOG.write_products_report(solution, tmp_filename)
RELOG.write_transportation_emissions_report(solution, tmp_filename)
RELOG.write_transportation_report(solution, tmp_filename)
end
end
end