1 | #region License Information
|
---|
2 | /* HeuristicLab
|
---|
3 | * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
|
---|
4 | *
|
---|
5 | * This file is part of HeuristicLab.
|
---|
6 | *
|
---|
7 | * HeuristicLab is free software: you can redistribute it and/or modify
|
---|
8 | * it under the terms of the GNU General Public License as published by
|
---|
9 | * the Free Software Foundation, either version 3 of the License, or
|
---|
10 | * (at your option) any later version.
|
---|
11 | *
|
---|
12 | * HeuristicLab is distributed in the hope that it will be useful,
|
---|
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
15 | * GNU General Public License for more details.
|
---|
16 | *
|
---|
17 | * You should have received a copy of the GNU General Public License
|
---|
18 | * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
|
---|
19 | */
|
---|
20 | #endregion
|
---|
21 |
|
---|
22 | using System;
|
---|
23 | using System.Collections.Generic;
|
---|
24 | using HeuristicLab.Common;
|
---|
25 | using HeuristicLab.Core;
|
---|
26 | using HeuristicLab.Data;
|
---|
27 | using HeuristicLab.Parameters;
|
---|
28 | using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
|
---|
29 | using YamlDotNet.RepresentationModel;
|
---|
30 | using HEAL.Attic;
|
---|
31 |
|
---|
32 | namespace HeuristicLab.BioBoost.Data {
|
---|
33 | [StorableType("AFFEC6E6-4373-41FD-B43E-139449409C98")]
|
---|
34 | [Item("Conversion", "Describes a conversion process including storage.")]
|
---|
35 | public class Conversion : DataItem {
|
---|
36 |
|
---|
37 | #region Parameters
|
---|
38 | public IValueParameter<StringValue> LabelParameter { get { return (IValueParameter<StringValue>)Parameters["Label"]; } }
|
---|
39 | public IValueParameter<StringValue> FeedstockParameter { get { return (IValueParameter<StringValue>)Parameters["Feedstock"]; } }
|
---|
40 | public IValueParameter<DoubleValue> CostParameter { get { return (IValueParameter<DoubleValue>)Parameters["Cost"]; } }
|
---|
41 | public IValueParameter<DoubleValue> DesignCapacityParameter { get { return (IValueParameter<DoubleValue>)Parameters["DesignCapacity"]; } }
|
---|
42 | public IValueParameter<DoubleValue> ConstructionParameter { get { return (IValueParameter<DoubleValue>)Parameters["Construction"]; } }
|
---|
43 | public IValueParameter<DoubleValue> MinConstructionParameter { get { return (IValueParameter<DoubleValue>)Parameters["MinConstruction"]; } }
|
---|
44 | public IValueParameter<DoubleValue> MaintenanceParameter { get { return (IValueParameter<DoubleValue>)Parameters["Maintenance"]; } }
|
---|
45 | public IValueParameter<DoubleValue> MinMaintenanceParameter { get { return (IValueParameter<DoubleValue>)Parameters["MinMaintenance"]; } }
|
---|
46 | public IValueParameter<DoubleValue> ConstructionScalingExponentParameter { get { return (IValueParameter<DoubleValue>)Parameters["ConstructionScalingExponent"]; } }
|
---|
47 | public IValueParameter<DoubleValue> MaintenanceScalingExponentParameter { get { return (IValueParameter<DoubleValue>)Parameters["MaintenanceScalingExponent"]; } }
|
---|
48 | public IValueParameter<DoubleValue> SafetyStockParameter { get { return (IValueParameter<DoubleValue>)Parameters["SafetyStock"]; } }
|
---|
49 | public IValueParameter<DoubleValue> DryMatterLossParameter { get { return (IValueParameter<DoubleValue>)Parameters["DryMatterLoss"]; } }
|
---|
50 | public IValueParameter<LogisticAction> StorageParameter { get { return (IValueParameter<LogisticAction>)Parameters["Storage"]; } }
|
---|
51 | public IValueParameter<DoubleValue> UtilizationFactorParameter { get { return (IValueParameter<DoubleValue>)Parameters["UtilizationFactor"]; } }
|
---|
52 | public IValueParameter<ValueParameterCollection> ProductsParameter { get { return (IValueParameter<ValueParameterCollection>)Parameters["Products"]; } }
|
---|
53 | public IValueParameter<ValueParameterCollection> ConstructionEmissionsParameter { get { return (IValueParameter<ValueParameterCollection>)Parameters["ConstructionEmissions"]; } }
|
---|
54 | public IValueParameter<ValueParameterCollection> AvailableCapacitiesParameter { get { return (IValueParameter<ValueParameterCollection>)Parameters["AvailableCapacities"]; } }
|
---|
55 | public IValueParameter<ValueParameterCollection> MaxCapacitiesParameter { get { return (IValueParameter<ValueParameterCollection>)Parameters["MaxCapacities"]; } }
|
---|
56 | public IValueParameter<DoubleValue> AvailableMaintenanceFactorParameter { get { return (IValueParameter<DoubleValue>)Parameters["AvailableMaintenanceFactor"]; } }
|
---|
57 | public IValueParameter<DoubleValue> MinCapacityParameter { get { return (IValueParameter<DoubleValue>) Parameters["MinCapacity"]; } }
|
---|
58 | public IValueParameter<StringValue> MainProductParameter { get { return (IValueParameter<StringValue>)Parameters["MainProduct"]; } }
|
---|
59 | public IValueParameter<DoubleValue> MainProductConversionRateParameter { get { return (IValueParameter<DoubleValue>)Parameters["MainProductConversionRate"]; } }
|
---|
60 | #endregion
|
---|
61 |
|
---|
62 | #region Parameter Values
|
---|
63 | public string Label { get { return LabelParameter.Value.Value; } }
|
---|
64 | public string Feedstock { get { return FeedstockParameter.Value.Value; } }
|
---|
65 | public string MainProduct { get { return MainProductParameter.Value.Value; } set { MainProductParameter.Value.Value = value; }
|
---|
66 | }
|
---|
67 |
|
---|
68 | public double Cost { get { return CostParameter.Value.Value; } set { CostParameter.Value.Value = value; } }
|
---|
69 |
|
---|
70 | public double DesignCapacity { get { return DesignCapacityParameter.Value.Value; } }
|
---|
71 | public double Construction { get { return ConstructionParameter.Value.Value; } }
|
---|
72 | public double MinConstruction { get { return MinConstructionParameter.Value.Value; } }
|
---|
73 | public double Maintenance { get { return MaintenanceParameter.Value.Value; } }
|
---|
74 | public double MinMaintenance { get { return MinMaintenanceParameter.Value.Value; } }
|
---|
75 | public double ConstructionScalingExponent { get { return ConstructionScalingExponentParameter.Value.Value; } }
|
---|
76 | public double MaintenanceScalingExponent { get { return MaintenanceScalingExponentParameter.Value.Value; } }
|
---|
77 | public double SafetyStock { get { return SafetyStockParameter.Value.Value; } }
|
---|
78 | public double DryMatterLoss { get { return DryMatterLossParameter.Value.Value; } }
|
---|
79 | public double UtilizationFactor { get { return UtilizationFactorParameter.Value.Value; } }
|
---|
80 | public LogisticAction Storage { get { return StorageParameter.Value; } }
|
---|
81 | public ValueParameterCollection Products { get { return ProductsParameter.Value; } }
|
---|
82 | public ValueParameterCollection ConstructionEmissions { get { return ConstructionEmissionsParameter.Value; } }
|
---|
83 | public ValueParameterCollection MaxCapacities { get { return MaxCapacitiesParameter.Value; } }
|
---|
84 | public ValueParameterCollection AvailableCapacities { get { return AvailableCapacitiesParameter.Value; } }
|
---|
85 | public double AvailableMaintenanceFactor { get { return AvailableMaintenanceFactorParameter.Value.Value; } }
|
---|
86 | public double MainProductConversionRate {
|
---|
87 | get { return MainProductConversionRateParameter.Value.Value; }
|
---|
88 | set { MainProductConversionRateParameter.Value = new DoubleValue(value); }
|
---|
89 | }
|
---|
90 |
|
---|
91 | public double MinCapacity {
|
---|
92 | get {
|
---|
93 | double minCapacity = MinCapacityParameter.Value.Value;
|
---|
94 | if (minCapacity == 0d)
|
---|
95 | minCapacity = MinCapacityParameter.Value.Value = GetInferredMinCapacity();
|
---|
96 | return minCapacity;
|
---|
97 | }
|
---|
98 | }
|
---|
99 |
|
---|
100 | private double GetInferredMinCapacity() {
|
---|
101 | if (MinConstructionParameter.Value != null && // reconstruct from MinConstruction
|
---|
102 | ConstructionParameter.Value != null &&
|
---|
103 | DesignCapacityParameter.Value != null &&
|
---|
104 | ConstructionScalingExponentParameter.Value != null)
|
---|
105 | return Math.Pow(MinConstruction / Construction, 1 / ConstructionScalingExponent) * DesignCapacity;
|
---|
106 | if (MinMaintenanceParameter.Value != null && // reconstruct from MinMaintenance
|
---|
107 | MaintenanceParameter.Value != null &&
|
---|
108 | MaintenanceScalingExponentParameter.Value != null &&
|
---|
109 | DesignCapacityParameter.Value != null)
|
---|
110 | return Math.Pow(MinMaintenance / Maintenance, 1 / MaintenanceScalingExponent) * DesignCapacity;
|
---|
111 | throw new IndexOutOfRangeException("MinCapacity is not available and could be reconstructed from other parameters.");
|
---|
112 | }
|
---|
113 |
|
---|
114 | #endregion
|
---|
115 |
|
---|
116 | #region Construction & Cloning
|
---|
117 | public Conversion() {
|
---|
118 | Parameters.Add(new ValueParameter<StringValue>("Label", "The label/name of this conversion."));
|
---|
119 | Parameters.Add(new ValueParameter<StringValue>("Feedstock", "The product used as feedstock (@target)."));
|
---|
120 | Parameters.Add(new ValueParameter<DoubleValue>("Cost", "The conversion cost [EUR/t]."));
|
---|
121 | Parameters.Add(new ValueParameter<DoubleValue>("Construction", "The amortized construction costs [EUR/a]"));
|
---|
122 | Parameters.Add(new ValueParameter<DoubleValue>("Maintenance", "The amortized operation and maintenance costs [EUR/a]"));
|
---|
123 | Parameters.Add(new ValueParameter<DoubleValue>("DesignCapacity", "The yearly turnover of feedstock [t/a]."));
|
---|
124 | Parameters.Add(new ValueParameter<DoubleValue>("MinConstruction", "The minimum construction costs [EUR/a]"));
|
---|
125 | Parameters.Add(new ValueParameter<DoubleValue>("MinMaintenance", "The minimum maintenance costs [EUR/a]"));
|
---|
126 | Parameters.Add(new ValueParameter<DoubleValue>("ConstructionScalingExponent", "The exponent used for up- and downsising construction costs.", new DoubleValue(0.86)));
|
---|
127 | Parameters.Add(new ValueParameter<DoubleValue>("MaintenanceScalingExponent", "The exponent used for up- and downscaling maintenance costs.", new DoubleValue(0.91)));
|
---|
128 | Parameters.Add(new ValueParameter<DoubleValue>("SafetyStock", "The number of days feedstock needs to be stored on average."));
|
---|
129 | Parameters.Add(new ValueParameter<DoubleValue>("DryMatterLoss", "The percentage of feedstock that is lost due to shrinkage.", new DoubleValue(0.0)));
|
---|
130 | Parameters.Add(new ValueParameter<DoubleValue>("UtilizationFactor", "Assumed utilization of a plant.", new DoubleValue(0.7)));
|
---|
131 | Parameters.Add(new ValueParameter<LogisticAction>("Storage", "Description of storage cost components [EUR/t/a]"));
|
---|
132 | Parameters.Add(new ValueParameter<ValueParameterCollection>("Products", "The list and amounts of products created by the conversion."));
|
---|
133 | Parameters.Add(new ValueParameter<ValueParameterCollection>("ConstructionEmissions", "The set of amortized emissions and amounts [t/a]"));
|
---|
134 | Parameters.Add(new ValueParameter<ValueParameterCollection>("AvailableCapacities", "Dictionary of regions with their free capacities of this conversion type."));
|
---|
135 | Parameters.Add(new ValueParameter<ValueParameterCollection>("MaxCapacities", "Dictionary of regions (or 'Default') with their maximum allows capapcity for this conversion type."));
|
---|
136 | Parameters.Add(new ValueParameter<DoubleValue>("AvailableMaintenanceFactor", "Scaling factor for maintenance costs when using free capacities."));
|
---|
137 | Parameters.Add(new ValueParameter<DoubleValue>("MinCapacity", "Minimum capacity to be reasonably build."));
|
---|
138 | Parameters.Add(new ValueParameter<StringValue>("MainProduct", "The main output product created during this conversion process."));
|
---|
139 | Parameters.Add(new ValueParameter<DoubleValue>("MainProductConversionRate", "The conversion rate of the main output product. (This value is automatically calculated)"));
|
---|
140 | RegisterEventHandlers();
|
---|
141 | }
|
---|
142 |
|
---|
143 | [StorableConstructor]
|
---|
144 | protected Conversion(StorableConstructorFlag _) : base(_) { }
|
---|
145 |
|
---|
146 | [StorableHook(HookType.AfterDeserialization)]
|
---|
147 | private void AfterDeserialization() {
|
---|
148 | if (!Parameters.ContainsKey("AvailableCapacities"))
|
---|
149 | Parameters.Add(new ValueParameter<ValueParameterCollection>("AvailableCapacities", "Dictionary of regions with their free capacities of this conversion type."));
|
---|
150 | if (!Parameters.ContainsKey("MaxCapacities"))
|
---|
151 | Parameters.Add(new ValueParameter<ValueParameterCollection>("MaxCapacities", "Dictionary of regions (or 'Default') with their maximum allows capapcity for this conversion type."));
|
---|
152 | if (!Parameters.ContainsKey("AvailableMaintenanceFactor"))
|
---|
153 | Parameters.Add(new ValueParameter<DoubleValue>("AvailableMaintenanceFactor", "Scaling factor for maintenance costs when using free capacities."));
|
---|
154 | if (!Parameters.ContainsKey("DryMatterLoss"))
|
---|
155 | Parameters.Add(new ValueParameter<DoubleValue>("DryMatterLoss", "The percentage of feedstock that is lost due to shrinkage.", new DoubleValue(0.0)));
|
---|
156 | if (!Parameters.ContainsKey("MinCapacity"))
|
---|
157 | Parameters.Add(new ValueParameter<DoubleValue>("MinCapacity", "Minimum capacity to be reasonably build.", new DoubleValue(GetInferredMinCapacity())));
|
---|
158 | if (!Parameters.ContainsKey("MainProduct"))
|
---|
159 | Parameters.Add(new ValueParameter<StringValue>("MainProduct", "The main output product created during this conversion process."));
|
---|
160 | if (!Parameters.ContainsKey("MainProductConversionRate"))
|
---|
161 | Parameters.Add(new ValueParameter<DoubleValue>("MainProductConversionRate", "The conversion rate of the main output product. (This value is automatically calculated)"));
|
---|
162 | RegisterEventHandlers();
|
---|
163 | }
|
---|
164 |
|
---|
165 | protected Conversion(Conversion orig, Cloner cloner)
|
---|
166 | : base(orig, cloner) {
|
---|
167 | RegisterEventHandlers();
|
---|
168 | }
|
---|
169 | public override IDeepCloneable Clone(Cloner cloner) {
|
---|
170 | return new Conversion(this, cloner);
|
---|
171 | }
|
---|
172 | #endregion
|
---|
173 |
|
---|
174 | protected override void Parse(YamlMappingNode node) {
|
---|
175 | base.Parse(node);
|
---|
176 | MaybeDetermineMainProductConversionRate();
|
---|
177 | }
|
---|
178 |
|
---|
179 | private void MaybeDetermineMainProductConversionRate() {
|
---|
180 | if (MainProductParameter.Value != null &&
|
---|
181 | (MainProductConversionRateParameter.Value == null || MainProductConversionRate == 0))
|
---|
182 | MainProductConversionRate = ((DoubleValue) Products[MainProduct].Value).Value;
|
---|
183 | }
|
---|
184 |
|
---|
185 | public override void CollectParameterValues(System.Collections.Generic.IDictionary<string, IItem> values) {
|
---|
186 | var tmpDict = new Dictionary<string, IItem>();
|
---|
187 | base.CollectParameterValues(tmpDict);
|
---|
188 | foreach (var entry in tmpDict) {
|
---|
189 | if (entry.Key == "Label") continue;
|
---|
190 | if (entry.Key == "Feedstock") continue;
|
---|
191 | values.Add("Conversion " + Label + "." + Feedstock + "." + entry.Key, entry.Value);
|
---|
192 | }
|
---|
193 | }
|
---|
194 |
|
---|
195 | private void RegisterEventHandlers() {
|
---|
196 | // when the HL value is changed
|
---|
197 | LabelParameter.ValueChanged += (sender, args) => {
|
---|
198 | UpdateName();
|
---|
199 | LabelParameter.Value.ValueChanged += (s, a) => { UpdateName(); };
|
---|
200 | };
|
---|
201 | // when the HL value's value is changed
|
---|
202 | LabelParameter.Value.ValueChanged += (sender, args) => { UpdateName(); };
|
---|
203 | }
|
---|
204 |
|
---|
205 | private void UpdateName() {
|
---|
206 | this.Name = ItemName + ": " + Label;
|
---|
207 | }
|
---|
208 |
|
---|
209 | public override bool IsEquivalentTo(DataItem other) {
|
---|
210 | var c = other as Conversion;
|
---|
211 | if (c == null) return false;
|
---|
212 | return c.Label == Label;
|
---|
213 | }
|
---|
214 |
|
---|
215 | public void MaybeInferMainProduct(Dictionary<string, double> prices) {
|
---|
216 | if (MainProductParameter.Value != null) { return; }
|
---|
217 | string mainProductName = null;
|
---|
218 | double mainProductRevenue = 0;
|
---|
219 | foreach (var product in Products) {
|
---|
220 | double price = 0;
|
---|
221 | if (prices.TryGetValue(product.Name, out price) && product.Value is ValueParameter<DoubleValue>) {
|
---|
222 | var doubleValue = (IValueParameter<DoubleValue>)product;
|
---|
223 | var revenue = price*doubleValue.Value.Value;
|
---|
224 | if (mainProductName == null && revenue > 0 || revenue > mainProductRevenue) {
|
---|
225 | mainProductName = product.Name;
|
---|
226 | mainProductRevenue = revenue;
|
---|
227 | }
|
---|
228 | }
|
---|
229 | }
|
---|
230 | if (mainProductName != null) {
|
---|
231 | MainProduct = MainProduct;
|
---|
232 | MaybeDetermineMainProductConversionRate();
|
---|
233 | }
|
---|
234 | }
|
---|
235 | }
|
---|
236 | }
|
---|