composition: fixed output

feature/composition2
Alinson S. Xavier 2 years ago
parent ae62ca1028
commit f74713185d
Signed by: isoron
GPG Key ID: 0DA8E4B9E1109DCA

1
.gitignore vendored

@ -16,3 +16,4 @@ run.jl
relog-web-legacy relog-web-legacy
.vscode .vscode
jobs jobs
**/tmp

@ -64,20 +64,18 @@
### Centers ### Centers
| Key | Type | Description | | Key | Type | Description |
| :------------------------------ | ------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | :------------------------------ | ------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `latitude (deg)` | `float` | The latitude of the center. | | `latitude (deg)` | `float` | The latitude of the center. |
| `longitude (deg)` | `float` | The longitude of the center. | | `longitude (deg)` | `float` | The longitude of the center. |
| `input` | `str` | The name of the product this center takes as input. May be `null` if the center accept no input product. | | `input` | `str` | The name of the product this center takes as input. May be `null` if the center accept no input product. |
| `outputs` | `vec(str)` | List of output products collected by the center. May be `[]` if none. | | `outputs` | `vec(str)` | List of output products collected by the center. May be `[]` if none. |
| `fixed output (tonne)` | `dict(str, mat(float, T, C))` | Dictionary mapping the name of each output product $p$ to a matrix $M$, where $M_{t,c}$ is the amount (in tonne) of output product component $c$ produced by the center at time $t$, regardless of how much input material the center received. | | `fixed output (tonne)` | `dict(str, mat(float, T, C))` | Dictionary mapping the name of each output product $p$ to a matrix $M$, where $M_{t,c}$ is the amount (in tonne) of output product component $c$ produced by the center at time $t$, regardless of how much input material the center received. |
| `variable output (tonne/tonne)` | `dict(str,mat(float, T, M, N))` | Dictionary mapping the name of each output product $p$ to a $(T \times m \times n)$ matrix $M$ that describes the amount (in tonnes) of output product component produced by the center, depending on how much input material the center received in prior years, where $T$ is the number of years, $m$ is the number of components of $p$ and $n$ is the number of components of the input product. For example, assume a 4-year simulation, and suppose both input product `P1` and output product `P2` have two components. If this field equals `{"P2": []} | | `variable output (tonne/tonne)` | `dict(str,mat(float, T, M, N))` | Dictionary mapping the name of each output product $p$ to a $(T \times m \times n)$ matrix $M$ that describes the amount (in tonnes) of output product component produced by the center, depending on how much input material the center received in prior years, where $T$ is the number of years, $m$ is the number of components of $p$ and $n$ is the number of components of the input product. |
| `revenue ($/tonne)` | `vec(float, T)` | Revenue generated by each tonne of input material sent to the center. If the center accepts no input, this should be `null` |
to the amount of output generated, for each tonne of input material, and for each year after the input is received. For example, in a 4-year simulation, if this field equals to `{"P1": [0.1, 0.3, 0.6, 0.0]}` and the center receives 1.0, 2.0, 3.0 and 4.0 tonnes of input material in years 1, 2, 3 and 4, then the center will produce $1.0 * 0.1 = 0.1$ of P1 in the first year, $1.0 * 0.3 + 2.0 * 0.1 = 0.5$ the second year, $1.0 * 0.6 + 2.0 * 0.3 + 3.0 * 0.1 = 1.5$ in the third year, and $2.0 * 0.6 + 3.0 * 0.3 + 4.0 * 0.1 = 2.5$ in the final year. | | `collection cost ($/tonne)` | `dict(str,vec(float,T))` | Dictionary mapping the name of each output product to the cost of collecting one tonne of the product. |
| `revenue ($/tonne)` | | Revenue generated by each tonne of input material sent to the center. If the center accepts no input, this should be `null` | | `operating cost ($)` | `vec(float,T)` | Fixed cost to operate the center for one year, regardless of amount of product received or generated. |
| `collection cost ($/tonne)` | | Dictionary mapping the name of each output product to the cost of collecting one tonne of the product. | | `disposal limit (tonne)` | `dict(str,vec(float,T))` | Dictionary mapping the name of each output product to the maximum disposal amount allower per year of the product at the center. Entry may be `null` if unlimited. |
| `operating cost ($)` | | Fixed cost to operate the center for one year, regardless of amount of product received or generated. | | `disposal cost ($/tonne)` | `dict(str,vec(float,T))` | Dictionary mapping the name of each output product to the cost to dispose one tonne of the product at the center. |
| `disposal limit (tonne)` | | Dictionary mapping the name of each output product to the maximum disposal amount allower per year of the product at the center. Entry may be `null` if unlimited. |
| `disposal cost ($/tonne)` | | Dictionary mapping the name of each output product to the cost to dispose one tonne of the product at the center. |
```json ```json
{ {
@ -198,20 +196,21 @@ to the amount of output generated, for each tonne of input material, and for eac
### Plants ### Plants
| Key | Description | | Key | | Description |
| :----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | :----------------------------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `latitude (deg)` | The latitude of the plant, in degrees. | | `latitude (deg)` | `float` | The latitude of the plant, in degrees. |
| `longitude (deg)` | The longitude of the plant, in degrees. | | `longitude (deg)` | `float` | The longitude of the plant, in degrees. |
| `input mix (%)` | Dictionary mapping the name of each input product to the amount required (as a percentage). Must sum to 100%. | | `input mix (%)` | `dict(str,float)` | Dictionary mapping the name of each input product to the amount required (as a percentage). Must sum to 100%. |
| `output (tonne)` | Dictionary mapping the name of each output product to the amount produced (in tonne) for one tonne of input mix. | | `output (tonne/tonne)` | `dict(str,dict(str,mat(float, T, M, N)))` | Dictionary of matrices describing the component outputs. |
| `processing emissions (tonne)` | A dictionary mapping the name of each greenhouse gas, produced to process each tonne of input, to the amount of gas produced (in tonne). | | `processing emissions (tonne)` | `dict(str,vec(float,T))` | A dictionary mapping the name of each greenhouse gas, produced to process each tonne of input, to the amount of gas produced (in tonne). |
| `storage cost ($/tonne)` | Dictionary mapping the name of each input product to the cost of storing the product for one year at the plant for later processing. | | `storage cost ($/tonne)` | `dict(str,vec(float,T))` | Dictionary mapping the name of each input product to the cost of storing the product for one year at the plant for later processing. |
| `storage limit (tonne)` | Dictionary mapping the name of each input product to the maximum amount allowed in storage at any time. May be `null` if unlimited. | | `storage limit (tonne)` | | Dictionary mapping the name of each input product to the maximum amount allowed in storage at any time. May be `null` if unlimited. |
| `disposal cost ($/tonne)` | Dictionary mapping the name of each output product to the cost of disposing it at the plant. | | `disposal cost ($/tonne)` | | Dictionary mapping the name of each output product to the cost of disposing it at the plant. |
| `disposal limit (tonne)` | Dictionary mapping the name of each output product to the maximum amount allowed to be disposed of at the plant. May be `null` if unlimited. | | `disposal limit (tonne)` | | Dictionary mapping the name of each output product to the maximum amount allowed to be disposed of at the plant. May be `null` if unlimited. |
| `capacities` | List describing what plant sizes are allowed, and their characteristics. | | `capacities` | | List describing what plant sizes are allowed, and their characteristics. |
The entries in the `capacities` list should be dictionaries with the following keys: The entries in the `capacities` list should be dictionaries with the following
keys:
| Key | Description | | Key | Description |
| :---------------------------------- | :-------------------------------------------------------------------------------------------------- | | :---------------------------------- | :-------------------------------------------------------------------------------------------------- |

@ -22,7 +22,8 @@ function parse(json)::Instance
tr_cost = timeseries(pdict["transportation cost (\$/km/tonne)"]) tr_cost = timeseries(pdict["transportation cost (\$/km/tonne)"])
tr_energy = timeseries(pdict["transportation energy (J/km/tonne)"]) tr_energy = timeseries(pdict["transportation energy (J/km/tonne)"])
tr_emissions = timeseries(pdict["transportation emissions (tonne/km/tonne)"]) tr_emissions = timeseries(pdict["transportation emissions (tonne/km/tonne)"])
prod = Product(; name, tr_cost, tr_energy, tr_emissions) components = pdict["components"]
prod = Product(; name, tr_cost, tr_energy, tr_emissions, components)
push!(products, prod) push!(products, prod)
products_by_name[name] = prod products_by_name[name] = prod
end end
@ -45,7 +46,19 @@ function parse(json)::Instance
p => [v === nothing ? null_val : v for v in timeseries(cdict[key][p.name])] p => [v === nothing ? null_val : v for v in timeseries(cdict[key][p.name])]
for p in outputs for p in outputs
) )
fixed_output = prod_dict("fixed output (tonne)", 0.0) to_array(x) = vcat(x'...)
prepend_time_dimension(x) = to_array(repeat([x], time_horizon))
fixed_output = Dict()
for p in outputs
m = to_array(cdict["fixed output (tonne)"][p.name])
if ndims(m) == 1
m = prepend_time_dimension(m)
end
@assert size(m) == (time_horizon, length(p.components))
fixed_output[p] = m
end
var_output = prod_dict("variable output (tonne/tonne)", 0.0) var_output = prod_dict("variable output (tonne/tonne)", 0.0)
collection_cost = prod_dict("collection cost (\$/tonne)", 0.0) collection_cost = prod_dict("collection cost (\$/tonne)", 0.0)
disposal_limit = prod_dict("disposal limit (tonne)", Inf) disposal_limit = prod_dict("disposal limit (tonne)", Inf)

@ -5,6 +5,7 @@ Base.@kwdef struct Product
tr_cost::Vector{Float64} tr_cost::Vector{Float64}
tr_energy::Vector{Float64} tr_energy::Vector{Float64}
tr_emissions::OrderedDict{String,Vector{Float64}} tr_emissions::OrderedDict{String,Vector{Float64}}
components::Vector{String}
end end
Base.@kwdef struct Center Base.@kwdef struct Center
@ -13,7 +14,7 @@ Base.@kwdef struct Center
longitude::Float64 longitude::Float64
input::Union{Product,Nothing} input::Union{Product,Nothing}
outputs::Vector{Product} outputs::Vector{Product}
fixed_output::OrderedDict{Product,Vector{Float64}} fixed_output::OrderedDict{Product,Array{Float64,2}}
var_output::OrderedDict{Product,Vector{Float64}} var_output::OrderedDict{Product,Vector{Float64}}
revenue::Vector{Float64} revenue::Vector{Float64}
collection_cost::OrderedDict{Product,Vector{Float64}} collection_cost::OrderedDict{Product,Vector{Float64}}

@ -269,7 +269,10 @@ function build_model(instance::Instance; optimizer, variable_names::Bool = false
sum( sum(
z_input[c.name, t-offset] * c.var_output[m][offset+1] for z_input[c.name, t-offset] * c.var_output[m][offset+1] for
offset = 0:min(M - 1, t - 1) offset = 0:min(M - 1, t - 1)
) + c.fixed_output[m][t] ) + sum(
c.fixed_output[m][t,mi]
for mi in 1:length(m.components)
)
) )
end end

@ -32,7 +32,7 @@ function run_boat_example()
nail_factory = dict( nail_factory = dict(
"input" => nothing, "input" => nothing,
"outputs" => ["Nail"], "outputs" => ["Nail"],
"fixed output (tonne)" => dict("Nail" => 1), "fixed output (tonne)" => dict("Nail" => [1]),
"variable output (tonne/tonne)" => dict("Nail" => 0), "variable output (tonne/tonne)" => dict("Nail" => 0),
"revenue (\$/tonne)" => nothing, "revenue (\$/tonne)" => nothing,
"collection cost (\$/tonne)" => dict("Nail" => 1000), "collection cost (\$/tonne)" => dict("Nail" => 1000),
@ -44,7 +44,7 @@ function run_boat_example()
forest = dict( forest = dict(
"input" => nothing, "input" => nothing,
"outputs" => ["Wood"], "outputs" => ["Wood"],
"fixed output (tonne)" => dict("Wood" => 100), "fixed output (tonne)" => dict("Wood" => [[100], [100], [100], [100], [100]]),
"variable output (tonne/tonne)" => dict("Wood" => 0), "variable output (tonne/tonne)" => dict("Wood" => 0),
"revenue (\$/tonne)" => nothing, "revenue (\$/tonne)" => nothing,
"collection cost (\$/tonne)" => dict("Wood" => 250), "collection cost (\$/tonne)" => dict("Wood" => 250),
@ -56,7 +56,7 @@ function run_boat_example()
retail = dict( retail = dict(
"input" => "NewBoat", "input" => "NewBoat",
"outputs" => ["UsedBoat"], "outputs" => ["UsedBoat"],
"fixed output (tonne)" => dict("UsedBoat" => 0), "fixed output (tonne)" => dict("UsedBoat" => [[0], [0], [0], [0], [0]]),
"variable output (tonne/tonne)" => dict("UsedBoat" => [0.10, 0.25, 0.10]), "variable output (tonne/tonne)" => dict("UsedBoat" => [0.10, 0.25, 0.10]),
"revenue (\$/tonne)" => 12_000, "revenue (\$/tonne)" => 12_000,
"collection cost (\$/tonne)" => dict("UsedBoat" => 100), "collection cost (\$/tonne)" => dict("UsedBoat" => 100),
@ -69,6 +69,7 @@ function run_boat_example()
"transportation cost (\$/km/tonne)" => 0.30, "transportation cost (\$/km/tonne)" => 0.30,
"transportation energy (J/km/tonne)" => 7_500, "transportation energy (J/km/tonne)" => 7_500,
"transportation emissions (tonne/km/tonne)" => dict("CO2" => 2.68), "transportation emissions (tonne/km/tonne)" => dict("CO2" => 2.68),
"components" => ["1"],
) )
boat_factory = dict( boat_factory = dict(
@ -121,10 +122,8 @@ function run_boat_example()
"initial capacity (tonne)" => 0, "initial capacity (tonne)" => 0,
) )
lat_lon_dict(city_location) = dict( lat_lon_dict(city_location) =
"latitude (deg)" => city_location[1], dict("latitude (deg)" => city_location[1], "longitude (deg)" => city_location[2])
"longitude (deg)" => city_location[2],
)
data = dict( data = dict(
"parameters" => parameters, "parameters" => parameters,
@ -132,36 +131,29 @@ function run_boat_example()
dict("Nail" => prod, "Wood" => prod, "NewBoat" => prod, "UsedBoat" => prod), dict("Nail" => prod, "Wood" => prod, "NewBoat" => prod, "UsedBoat" => prod),
"centers" => merge( "centers" => merge(
dict( dict(
"NailFactory ($city_name)" => merge( "NailFactory ($city_name)" =>
nail_factory, merge(nail_factory, lat_lon_dict(city_location)) for
lat_lon_dict(city_location) (city_name, city_location) in cities_b
) for (city_name, city_location) in cities_b
), ),
dict( dict(
"Forest ($city_name)" => merge( "Forest ($city_name)" => merge(forest, lat_lon_dict(city_location))
forest, for (city_name, city_location) in cities_b
lat_lon_dict(city_location)
) for (city_name, city_location) in cities_b
), ),
dict( dict(
"Retail ($city_name)" => merge( "Retail ($city_name)" => merge(retail, lat_lon_dict(city_location))
retail, for (city_name, city_location) in cities_a
lat_lon_dict(city_location)
) for (city_name, city_location) in cities_a
), ),
), ),
"plants" => merge( "plants" => merge(
dict( dict(
"BoatFactory ($city_name)" => merge( "BoatFactory ($city_name)" =>
boat_factory, merge(boat_factory, lat_lon_dict(city_location)) for
lat_lon_dict(city_location) (city_name, city_location) in cities_a
) for (city_name, city_location) in cities_a
), ),
dict( dict(
"RecyclingPlant ($city_name)" => merge( "RecyclingPlant ($city_name)" =>
recycling_plant, merge(recycling_plant, lat_lon_dict(city_location)) for
lat_lon_dict(city_location) (city_name, city_location) in cities_a
) for (city_name, city_location) in cities_a
), ),
), ),
) )

@ -12,28 +12,40 @@
"transportation energy (J/km/tonne)": 7500, "transportation energy (J/km/tonne)": 7500,
"transportation emissions (tonne/km/tonne)": { "transportation emissions (tonne/km/tonne)": {
"CO2": 2.68 "CO2": 2.68
} },
"components": [
"1"
]
}, },
"Wood": { "Wood": {
"transportation cost ($/km/tonne)": 0.3, "transportation cost ($/km/tonne)": 0.3,
"transportation energy (J/km/tonne)": 7500, "transportation energy (J/km/tonne)": 7500,
"transportation emissions (tonne/km/tonne)": { "transportation emissions (tonne/km/tonne)": {
"CO2": 2.68 "CO2": 2.68
} },
"components": [
"1"
]
}, },
"NewBoat": { "NewBoat": {
"transportation cost ($/km/tonne)": 0.3, "transportation cost ($/km/tonne)": 0.3,
"transportation energy (J/km/tonne)": 7500, "transportation energy (J/km/tonne)": 7500,
"transportation emissions (tonne/km/tonne)": { "transportation emissions (tonne/km/tonne)": {
"CO2": 2.68 "CO2": 2.68
} },
"components": [
"1"
]
}, },
"UsedBoat": { "UsedBoat": {
"transportation cost ($/km/tonne)": 0.3, "transportation cost ($/km/tonne)": 0.3,
"transportation energy (J/km/tonne)": 7500, "transportation energy (J/km/tonne)": 7500,
"transportation emissions (tonne/km/tonne)": { "transportation emissions (tonne/km/tonne)": {
"CO2": 2.68 "CO2": 2.68
} },
"components": [
"1"
]
} }
}, },
"centers": { "centers": {
@ -43,7 +55,9 @@
"Nail" "Nail"
], ],
"fixed output (tonne)": { "fixed output (tonne)": {
"Nail": 1 "Nail": [
1
]
}, },
"variable output (tonne/tonne)": { "variable output (tonne/tonne)": {
"Nail": 0 "Nail": 0
@ -68,7 +82,9 @@
"Nail" "Nail"
], ],
"fixed output (tonne)": { "fixed output (tonne)": {
"Nail": 1 "Nail": [
1
]
}, },
"variable output (tonne/tonne)": { "variable output (tonne/tonne)": {
"Nail": 0 "Nail": 0
@ -93,7 +109,9 @@
"Nail" "Nail"
], ],
"fixed output (tonne)": { "fixed output (tonne)": {
"Nail": 1 "Nail": [
1
]
}, },
"variable output (tonne/tonne)": { "variable output (tonne/tonne)": {
"Nail": 0 "Nail": 0
@ -118,7 +136,23 @@
"Wood" "Wood"
], ],
"fixed output (tonne)": { "fixed output (tonne)": {
"Wood": 100 "Wood": [
[
100
],
[
100
],
[
100
],
[
100
],
[
100
]
]
}, },
"variable output (tonne/tonne)": { "variable output (tonne/tonne)": {
"Wood": 0 "Wood": 0
@ -143,7 +177,23 @@
"Wood" "Wood"
], ],
"fixed output (tonne)": { "fixed output (tonne)": {
"Wood": 100 "Wood": [
[
100
],
[
100
],
[
100
],
[
100
],
[
100
]
]
}, },
"variable output (tonne/tonne)": { "variable output (tonne/tonne)": {
"Wood": 0 "Wood": 0
@ -168,7 +218,23 @@
"Wood" "Wood"
], ],
"fixed output (tonne)": { "fixed output (tonne)": {
"Wood": 100 "Wood": [
[
100
],
[
100
],
[
100
],
[
100
],
[
100
]
]
}, },
"variable output (tonne/tonne)": { "variable output (tonne/tonne)": {
"Wood": 0 "Wood": 0
@ -193,7 +259,23 @@
"UsedBoat" "UsedBoat"
], ],
"fixed output (tonne)": { "fixed output (tonne)": {
"UsedBoat": 0 "UsedBoat": [
[
0
],
[
0
],
[
0
],
[
0
],
[
0
]
]
}, },
"variable output (tonne/tonne)": { "variable output (tonne/tonne)": {
"UsedBoat": [ "UsedBoat": [
@ -222,7 +304,23 @@
"UsedBoat" "UsedBoat"
], ],
"fixed output (tonne)": { "fixed output (tonne)": {
"UsedBoat": 0 "UsedBoat": [
[
0
],
[
0
],
[
0
],
[
0
],
[
0
]
]
}, },
"variable output (tonne/tonne)": { "variable output (tonne/tonne)": {
"UsedBoat": [ "UsedBoat": [
@ -251,7 +349,23 @@
"UsedBoat" "UsedBoat"
], ],
"fixed output (tonne)": { "fixed output (tonne)": {
"UsedBoat": 0 "UsedBoat": [
[
0
],
[
0
],
[
0
],
[
0
],
[
0
]
]
}, },
"variable output (tonne/tonne)": { "variable output (tonne/tonne)": {
"UsedBoat": [ "UsedBoat": [
@ -280,7 +394,23 @@
"UsedBoat" "UsedBoat"
], ],
"fixed output (tonne)": { "fixed output (tonne)": {
"UsedBoat": 0 "UsedBoat": [
[
0
],
[
0
],
[
0
],
[
0
],
[
0
]
]
}, },
"variable output (tonne/tonne)": { "variable output (tonne/tonne)": {
"UsedBoat": [ "UsedBoat": [
@ -309,7 +439,23 @@
"UsedBoat" "UsedBoat"
], ],
"fixed output (tonne)": { "fixed output (tonne)": {
"UsedBoat": 0 "UsedBoat": [
[
0
],
[
0
],
[
0
],
[
0
],
[
0
]
]
}, },
"variable output (tonne/tonne)": { "variable output (tonne/tonne)": {
"UsedBoat": [ "UsedBoat": [
@ -338,7 +484,23 @@
"UsedBoat" "UsedBoat"
], ],
"fixed output (tonne)": { "fixed output (tonne)": {
"UsedBoat": 0 "UsedBoat": [
[
0
],
[
0
],
[
0
],
[
0
],
[
0
]
]
}, },
"variable output (tonne/tonne)": { "variable output (tonne/tonne)": {
"UsedBoat": [ "UsedBoat": [
@ -367,7 +529,23 @@
"UsedBoat" "UsedBoat"
], ],
"fixed output (tonne)": { "fixed output (tonne)": {
"UsedBoat": 0 "UsedBoat": [
[
0
],
[
0
],
[
0
],
[
0
],
[
0
]
]
}, },
"variable output (tonne/tonne)": { "variable output (tonne/tonne)": {
"UsedBoat": [ "UsedBoat": [
@ -396,7 +574,23 @@
"UsedBoat" "UsedBoat"
], ],
"fixed output (tonne)": { "fixed output (tonne)": {
"UsedBoat": 0 "UsedBoat": [
[
0
],
[
0
],
[
0
],
[
0
],
[
0
]
]
}, },
"variable output (tonne/tonne)": { "variable output (tonne/tonne)": {
"UsedBoat": [ "UsedBoat": [
@ -425,7 +619,23 @@
"UsedBoat" "UsedBoat"
], ],
"fixed output (tonne)": { "fixed output (tonne)": {
"UsedBoat": 0 "UsedBoat": [
[
0
],
[
0
],
[
0
],
[
0
],
[
0
]
]
}, },
"variable output (tonne/tonne)": { "variable output (tonne/tonne)": {
"UsedBoat": [ "UsedBoat": [
@ -454,7 +664,23 @@
"UsedBoat" "UsedBoat"
], ],
"fixed output (tonne)": { "fixed output (tonne)": {
"UsedBoat": 0 "UsedBoat": [
[
0
],
[
0
],
[
0
],
[
0
],
[
0
]
]
}, },
"variable output (tonne/tonne)": { "variable output (tonne/tonne)": {
"UsedBoat": [ "UsedBoat": [

@ -11,7 +11,8 @@
"transportation emissions (tonne/km/tonne)": { "transportation emissions (tonne/km/tonne)": {
"CO2": 0.052, "CO2": 0.052,
"CH4": [0.003, 0.003, 0.003, 0.003] "CH4": [0.003, 0.003, 0.003, 0.003]
} },
"components": ["1", "2"]
}, },
"P2": { "P2": {
"transportation cost ($/km/tonne)": [0.015, 0.015, 0.015, 0.015], "transportation cost ($/km/tonne)": [0.015, 0.015, 0.015, 0.015],
@ -19,7 +20,8 @@
"transportation emissions (tonne/km/tonne)": { "transportation emissions (tonne/km/tonne)": {
"CO2": [0.052, 0.052, 0.052, 0.052], "CO2": [0.052, 0.052, 0.052, 0.052],
"CH4": [0.003, 0.003, 0.003, 0.003] "CH4": [0.003, 0.003, 0.003, 0.003]
} },
"components": ["1"]
}, },
"P3": { "P3": {
"transportation cost ($/km/tonne)": [0.015, 0.015, 0.015, 0.015], "transportation cost ($/km/tonne)": [0.015, 0.015, 0.015, 0.015],
@ -27,7 +29,8 @@
"transportation emissions (tonne/km/tonne)": { "transportation emissions (tonne/km/tonne)": {
"CO2": [0.052, 0.052, 0.052, 0.052], "CO2": [0.052, 0.052, 0.052, 0.052],
"CH4": [0.003, 0.003, 0.003, 0.003] "CH4": [0.003, 0.003, 0.003, 0.003]
} },
"components": ["1"]
}, },
"P4": { "P4": {
"transportation cost ($/km/tonne)": [0.015, 0.015, 0.015, 0.015], "transportation cost ($/km/tonne)": [0.015, 0.015, 0.015, 0.015],
@ -35,7 +38,8 @@
"transportation emissions (tonne/km/tonne)": { "transportation emissions (tonne/km/tonne)": {
"CO2": [0.052, 0.052, 0.052, 0.052], "CO2": [0.052, 0.052, 0.052, 0.052],
"CH4": [0.003, 0.003, 0.003, 0.003] "CH4": [0.003, 0.003, 0.003, 0.003]
} },
"components": ["1"]
} }
}, },
"centers": { "centers": {
@ -45,11 +49,11 @@
"input": "P1", "input": "P1",
"outputs": ["P2", "P3"], "outputs": ["P2", "P3"],
"fixed output (tonne)": { "fixed output (tonne)": {
"P2": [100, 50, 0, 0], "P2": [[100], [50], [0], [0]],
"P3": [20, 10, 0, 0] "P3": [[20], [10], [0], [0]]
}, },
"variable output (tonne/tonne)": { "variable output (tonne/tonne)": {
"P2": [0.20, 0.25, 0.12], "P2": [0.2, 0.25, 0.12],
"P3": [0.25, 0.25, 0.25] "P3": [0.25, 0.25, 0.25]
}, },
"revenue ($/tonne)": 12.0, "revenue ($/tonne)": 12.0,
@ -76,7 +80,12 @@
"P1": 0 "P1": 0
}, },
"fixed output (tonne)": { "fixed output (tonne)": {
"P1": [50, 60, 70, 80] "P1": [
[50, 5],
[60, 6],
[70, 7],
[80, 8]
]
}, },
"revenue ($/tonne)": null, "revenue ($/tonne)": null,
"collection cost ($/tonne)": { "collection cost ($/tonne)": {

@ -0,0 +1,650 @@
{
"parameters": {
"time horizon (years)": 5,
"building period (years)": [1],
"distance metric": "Euclidean"
},
"products": {
"Waste": {
"transportation cost ($/km/tonne)": 0.3,
"transportation energy (J/km/tonne)": 7500,
"transportation emissions (tonne/km/tonne)": {
"CO2": 2.68
},
"components": ["Film", "Paper", "Cardboard"]
},
"Film Bale": {
"transportation cost ($/km/tonne)": 0.3,
"transportation energy (J/km/tonne)": 7500,
"transportation emissions (tonne/km/tonne)": {
"CO2": 2.68
},
"components": ["Film", "Paper", "Cardboard"]
},
"Cardboard Bale": {
"transportation cost ($/km/tonne)": 0.3,
"transportation energy (J/km/tonne)": 7500,
"transportation emissions (tonne/km/tonne)": {
"CO2": 2.68
},
"components": ["Film", "Paper", "Cardboard"]
}
},
"centers": {
"Collection Center (Chicago)": {
"input": null,
"outputs": ["Waste"],
"fixed output (tonne)": {
"Waste": [20, 100, 100]
},
"variable output (tonne/tonne)": {},
"revenue ($/tonne)": null,
"collection cost ($/tonne)": {
"Waste": 10
},
"operating cost ($)": 0,
"disposal limit (tonne)": {
"Waste": null
},
"disposal cost ($/tonne)": {
"Waste": 0
},
"latitude (deg)": 41.881832,
"longitude (deg)": -87.623177
},
"Collection Center (Phoenix)": {
"input": null,
"outputs": ["Waste"],
"fixed output (tonne)": {
"Waste": [20, 100, 100]
},
"variable output (tonne/tonne)": {},
"revenue ($/tonne)": null,
"collection cost ($/tonne)": {
"Waste": 10
},
"operating cost ($)": 0,
"disposal limit (tonne)": {
"Waste": null
},
"disposal cost ($/tonne)": {
"Waste": 0
},
"latitude (deg)": 33.448376,
"longitude (deg)": -112.074036
},
"Collection Center (Dallas)": {
"input": null,
"outputs": ["Waste"],
"fixed output (tonne)": {
"Waste": [20, 100, 100]
},
"variable output (tonne/tonne)": {},
"revenue ($/tonne)": null,
"collection cost ($/tonne)": {
"Waste": 10
},
"operating cost ($)": 0,
"disposal limit (tonne)": {
"Waste": null
},
"disposal cost ($/tonne)": {
"Waste": 0
},
"latitude (deg)": 32.776664,
"longitude (deg)": -96.796988
}
},
"plants": {
"RecyclingPlant (Chicago)": {
"input mix (%)": {
"Waste": 100
},
"output (tonne)": {
"Film Bale": {
"Waste": [
[0.98, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.02]
]
},
"Cardboard Bale": {
"Waste": [
[0.0, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.75]
]
}
},
"processing emissions (tonne)": {
"CO2": 5
},
"storage cost ($/tonne)": {
"Waste": 500
},
"storage limit (tonne)": {
"Waste": 5
},
"disposal cost ($/tonne)": {
"Film Bale": -10,
"Cardboard Bale": -10
},
"disposal limit (tonne)": {
"Film Bale": null,
"Cardboard Bale": null
},
"capacities": [
{
"size (tonne)": 500,
"opening cost ($)": 100000,
"fixed operating cost ($)": 250000,
"variable operating cost ($/tonne)": 5
},
{
"size (tonne)": 1000,
"opening cost ($)": 2000000,
"fixed operating cost ($)": 500000,
"variable operating cost ($/tonne)": 5
}
],
"initial capacity (tonne)": 0,
"latitude (deg)": 41.881832,
"longitude (deg)": -87.623177
},
"RecyclingPlant (New York City)": {
"input mix (%)": {
"Waste": 100
},
"output (tonne)": {
"Film Bale": {
"Waste": [
[0.98, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.02]
]
},
"Cardboard Bale": {
"Waste": [
[0.0, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.75]
]
}
},
"processing emissions (tonne)": {
"CO2": 5
},
"storage cost ($/tonne)": {
"Waste": 500
},
"storage limit (tonne)": {
"Waste": 5
},
"disposal cost ($/tonne)": {
"Film Bale": -10,
"Cardboard Bale": -10
},
"disposal limit (tonne)": {
"Film Bale": null,
"Cardboard Bale": null
},
"capacities": [
{
"size (tonne)": 500,
"opening cost ($)": 100000,
"fixed operating cost ($)": 250000,
"variable operating cost ($/tonne)": 5
},
{
"size (tonne)": 1000,
"opening cost ($)": 2000000,
"fixed operating cost ($)": 500000,
"variable operating cost ($/tonne)": 5
}
],
"initial capacity (tonne)": 0,
"latitude (deg)": 40.712776,
"longitude (deg)": -74.005974
},
"RecyclingPlant (Los Angeles)": {
"input mix (%)": {
"Waste": 100
},
"output (tonne)": {
"Film Bale": {
"Waste": [
[0.98, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.02]
]
},
"Cardboard Bale": {
"Waste": [
[0.0, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.75]
]
}
},
"processing emissions (tonne)": {
"CO2": 5
},
"storage cost ($/tonne)": {
"Waste": 500
},
"storage limit (tonne)": {
"Waste": 5
},
"disposal cost ($/tonne)": {
"Film Bale": -10,
"Cardboard Bale": -10
},
"disposal limit (tonne)": {
"Film Bale": null,
"Cardboard Bale": null
},
"capacities": [
{
"size (tonne)": 500,
"opening cost ($)": 100000,
"fixed operating cost ($)": 250000,
"variable operating cost ($/tonne)": 5
},
{
"size (tonne)": 1000,
"opening cost ($)": 2000000,
"fixed operating cost ($)": 500000,
"variable operating cost ($/tonne)": 5
}
],
"initial capacity (tonne)": 0,
"latitude (deg)": 34.052235,
"longitude (deg)": -118.243683
},
"RecyclingPlant (Houston)": {
"input mix (%)": {
"Waste": 100
},
"output (tonne)": {
"Film Bale": {
"Waste": [
[0.98, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.02]
]
},
"Cardboard Bale": {
"Waste": [
[0.0, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.75]
]
}
},
"processing emissions (tonne)": {
"CO2": 5
},
"storage cost ($/tonne)": {
"Waste": 500
},
"storage limit (tonne)": {
"Waste": 5
},
"disposal cost ($/tonne)": {
"Film Bale": -10,
"Cardboard Bale": -10
},
"disposal limit (tonne)": {
"Film Bale": null,
"Cardboard Bale": null
},
"capacities": [
{
"size (tonne)": 500,
"opening cost ($)": 100000,
"fixed operating cost ($)": 250000,
"variable operating cost ($/tonne)": 5
},
{
"size (tonne)": 1000,
"opening cost ($)": 2000000,
"fixed operating cost ($)": 500000,
"variable operating cost ($/tonne)": 5
}
],
"initial capacity (tonne)": 0,
"latitude (deg)": 29.760427,
"longitude (deg)": -95.369804
},
"RecyclingPlant (Phoenix)": {
"input mix (%)": {
"Waste": 100
},
"output (tonne)": {
"Film Bale": {
"Waste": [
[0.98, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.02]
]
},
"Cardboard Bale": {
"Waste": [
[0.0, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.75]
]
}
},
"processing emissions (tonne)": {
"CO2": 5
},
"storage cost ($/tonne)": {
"Waste": 500
},
"storage limit (tonne)": {
"Waste": 5
},
"disposal cost ($/tonne)": {
"Film Bale": -10,
"Cardboard Bale": -10
},
"disposal limit (tonne)": {
"Film Bale": null,
"Cardboard Bale": null
},
"capacities": [
{
"size (tonne)": 500,
"opening cost ($)": 100000,
"fixed operating cost ($)": 250000,
"variable operating cost ($/tonne)": 5
},
{
"size (tonne)": 1000,
"opening cost ($)": 2000000,
"fixed operating cost ($)": 500000,
"variable operating cost ($/tonne)": 5
}
],
"initial capacity (tonne)": 0,
"latitude (deg)": 33.448376,
"longitude (deg)": -112.074036
},
"RecyclingPlant (Philadelphia)": {
"input mix (%)": {
"Waste": 100
},
"output (tonne)": {
"Film Bale": {
"Waste": [
[0.98, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.02]
]
},
"Cardboard Bale": {
"Waste": [
[0.0, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.75]
]
}
},
"processing emissions (tonne)": {
"CO2": 5
},
"storage cost ($/tonne)": {
"Waste": 500
},
"storage limit (tonne)": {
"Waste": 5
},
"disposal cost ($/tonne)": {
"Film Bale": -10,
"Cardboard Bale": -10
},
"disposal limit (tonne)": {
"Film Bale": null,
"Cardboard Bale": null
},
"capacities": [
{
"size (tonne)": 500,
"opening cost ($)": 100000,
"fixed operating cost ($)": 250000,
"variable operating cost ($/tonne)": 5
},
{
"size (tonne)": 1000,
"opening cost ($)": 2000000,
"fixed operating cost ($)": 500000,
"variable operating cost ($/tonne)": 5
}
],
"initial capacity (tonne)": 0,
"latitude (deg)": 39.952583,
"longitude (deg)": -75.165222
},
"RecyclingPlant (San Antonio)": {
"input mix (%)": {
"Waste": 100
},
"output (tonne)": {
"Film Bale": {
"Waste": [
[0.98, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.02]
]
},
"Cardboard Bale": {
"Waste": [
[0.0, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.75]
]
}
},
"processing emissions (tonne)": {
"CO2": 5
},
"storage cost ($/tonne)": {
"Waste": 500
},
"storage limit (tonne)": {
"Waste": 5
},
"disposal cost ($/tonne)": {
"Film Bale": -10,
"Cardboard Bale": -10
},
"disposal limit (tonne)": {
"Film Bale": null,
"Cardboard Bale": null
},
"capacities": [
{
"size (tonne)": 500,
"opening cost ($)": 100000,
"fixed operating cost ($)": 250000,
"variable operating cost ($/tonne)": 5
},
{
"size (tonne)": 1000,
"opening cost ($)": 2000000,
"fixed operating cost ($)": 500000,
"variable operating cost ($/tonne)": 5
}
],
"initial capacity (tonne)": 0,
"latitude (deg)": 29.424122,
"longitude (deg)": -98.493629
},
"RecyclingPlant (San Diego)": {
"input mix (%)": {
"Waste": 100
},
"output (tonne)": {
"Film Bale": {
"Waste": [
[0.98, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.02]
]
},
"Cardboard Bale": {
"Waste": [
[0.0, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.75]
]
}
},
"processing emissions (tonne)": {
"CO2": 5
},
"storage cost ($/tonne)": {
"Waste": 500
},
"storage limit (tonne)": {
"Waste": 5
},
"disposal cost ($/tonne)": {
"Film Bale": -10,
"Cardboard Bale": -10
},
"disposal limit (tonne)": {
"Film Bale": null,
"Cardboard Bale": null
},
"capacities": [
{
"size (tonne)": 500,
"opening cost ($)": 100000,
"fixed operating cost ($)": 250000,
"variable operating cost ($/tonne)": 5
},
{
"size (tonne)": 1000,
"opening cost ($)": 2000000,
"fixed operating cost ($)": 500000,
"variable operating cost ($/tonne)": 5
}
],
"initial capacity (tonne)": 0,
"latitude (deg)": 32.715736,
"longitude (deg)": -117.161087
},
"RecyclingPlant (Dallas)": {
"input mix (%)": {
"Waste": 100
},
"output (tonne)": {
"Film Bale": {
"Waste": [
[0.98, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.02]
]
},
"Cardboard Bale": {
"Waste": [
[0.0, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.75]
]
}
},
"processing emissions (tonne)": {
"CO2": 5
},
"storage cost ($/tonne)": {
"Waste": 500
},
"storage limit (tonne)": {
"Waste": 5
},
"disposal cost ($/tonne)": {
"Film Bale": -10,
"Cardboard Bale": -10
},
"disposal limit (tonne)": {
"Film Bale": null,
"Cardboard Bale": null
},
"capacities": [
{
"size (tonne)": 500,
"opening cost ($)": 100000,
"fixed operating cost ($)": 250000,
"variable operating cost ($/tonne)": 5
},
{
"size (tonne)": 1000,
"opening cost ($)": 2000000,
"fixed operating cost ($)": 500000,
"variable operating cost ($/tonne)": 5
}
],
"initial capacity (tonne)": 0,
"latitude (deg)": 32.776664,
"longitude (deg)": -96.796988
},
"RecyclingPlant (San Jose)": {
"input mix (%)": {
"Waste": 100
},
"output (tonne)": {
"Film Bale": {
"Waste": [
[0.98, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.02]
]
},
"Cardboard Bale": {
"Waste": [
[0.0, 0.0, 0.0],
[0.0, 0.02, 0.0],
[0.0, 0.0, 0.75]
]
}
},
"processing emissions (tonne)": {
"CO2": 5
},
"storage cost ($/tonne)": {
"Waste": 500
},
"storage limit (tonne)": {
"Waste": 5
},
"disposal cost ($/tonne)": {
"Film Bale": -10,
"Cardboard Bale": -10
},
"disposal limit (tonne)": {
"Film Bale": null,
"Cardboard Bale": null
},
"capacities": [
{
"size (tonne)": 500,
"opening cost ($)": 100000,
"fixed operating cost ($)": 250000,
"variable operating cost ($/tonne)": 5
},
{
"size (tonne)": 1000,
"opening cost ($)": 2000000,
"fixed operating cost ($)": 500000,
"variable operating cost ($/tonne)": 5
}
],
"initial capacity (tonne)": 0,
"latitude (deg)": 37.338208,
"longitude (deg)": -121.886329
}
}
}

@ -32,4 +32,7 @@ function format()
JuliaFormatter.format("$basedir/../fixtures", verbose = true) JuliaFormatter.format("$basedir/../fixtures", verbose = true)
return return
end end
export format, runtests
end # module RELOGT end # module RELOGT

@ -18,6 +18,7 @@ function instance_parse_test_1()
@test p1.tr_energy == [0.12, 0.12, 0.12, 0.12] @test p1.tr_energy == [0.12, 0.12, 0.12, 0.12]
@test p1.tr_emissions == @test p1.tr_emissions ==
Dict("CO2" => [0.052, 0.052, 0.052, 0.052], "CH4" => [0.003, 0.003, 0.003, 0.003]) Dict("CO2" => [0.052, 0.052, 0.052, 0.052], "CH4" => [0.003, 0.003, 0.003, 0.003])
@test p1.components == ["1", "2"]
@test instance.products_by_name["P1"] === p1 @test instance.products_by_name["P1"] === p1
p2 = instance.products[2] p2 = instance.products[2]
p3 = instance.products[3] p3 = instance.products[3]
@ -30,7 +31,7 @@ function instance_parse_test_1()
@test c1.longitude == -87.623 @test c1.longitude == -87.623
@test c1.input === p1 @test c1.input === p1
@test c1.outputs == [p2, p3] @test c1.outputs == [p2, p3]
@test c1.fixed_output == Dict(p2 => [100, 50, 0, 0], p3 => [20, 10, 0, 0]) @test c1.fixed_output == Dict(p2 => [100; 50; 0; 0;;], p3 => [20; 10; 0; 0;;])
@test c1.var_output == Dict(p2 => [0.2, 0.25, 0.12], p3 => [0.25, 0.25, 0.25]) @test c1.var_output == Dict(p2 => [0.2, 0.25, 0.12], p3 => [0.25, 0.25, 0.25])
@test c1.revenue == [12.0, 12.0, 12.0, 12.0] @test c1.revenue == [12.0, 12.0, 12.0, 12.0]
@test c1.operating_cost == [150.0, 150.0, 150.0, 150.0] @test c1.operating_cost == [150.0, 150.0, 150.0, 150.0]

@ -11,7 +11,6 @@ function model_build_test()
z_input = model[:z_input] z_input = model[:z_input]
x = model[:x] x = model[:x]
obj = objective_function(model) obj = objective_function(model)
# print(model)
@test obj.terms[y["L1", "C3", "P4", 1]] == ( @test obj.terms[y["L1", "C3", "P4", 1]] == (
111.118 * 0.015 # transportation 111.118 * 0.015 # transportation
@ -98,6 +97,7 @@ function model_build_test()
"eq_z_collected[C1,P2,3] : -0.12 z_input[C1,1] - 0.25 z_input[C1,2] - 0.2 z_input[C1,3] + z_collected[C1,P2,3] = 0" "eq_z_collected[C1,P2,3] : -0.12 z_input[C1,1] - 0.25 z_input[C1,2] - 0.2 z_input[C1,3] + z_collected[C1,P2,3] = 0"
@test repr(model[:eq_z_collected]["C1", "P2", 4]) == @test repr(model[:eq_z_collected]["C1", "P2", 4]) ==
"eq_z_collected[C1,P2,4] : -0.12 z_input[C1,2] - 0.25 z_input[C1,3] - 0.2 z_input[C1,4] + z_collected[C1,P2,4] = 0" "eq_z_collected[C1,P2,4] : -0.12 z_input[C1,2] - 0.25 z_input[C1,3] - 0.2 z_input[C1,4] + z_collected[C1,P2,4] = 0"
@test repr(model[:eq_z_collected]["C2", "P1", 1]) == "eq_z_collected[C2,P1,1] : z_collected[C2,P1,1] = 55"
# Centers: Collected products must be disposed or sent # Centers: Collected products must be disposed or sent
@test repr(model[:eq_balance]["C1", "P2", 1]) == @test repr(model[:eq_balance]["C1", "P2", 1]) ==

Loading…
Cancel
Save