source: branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost/3.3/Data/Conversion.cs @ 13069

Last change on this file since 13069 was 13069, checked in by gkronber, 7 years ago

#2499: imported source code for HeuristicLab.BioBoost from private repository with some changes

File size: 14.4 KB
Line 
1using System;
2using System.Collections.Generic;
3using HeuristicLab.Common;
4using HeuristicLab.Core;
5using HeuristicLab.Data;
6using HeuristicLab.Parameters;
7using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
8using YamlDotNet.RepresentationModel;
9
10namespace HeuristicLab.BioBoost.Data {
11  [StorableClass]
12  [Item("Conversion", "Describes a conversion process including storage.")]
13  public class Conversion : DataItem {
14
15    #region Parameters
16    public IValueParameter<StringValue> LabelParameter { get { return (IValueParameter<StringValue>)Parameters["Label"]; } }
17    public IValueParameter<StringValue> FeedstockParameter { get { return (IValueParameter<StringValue>)Parameters["Feedstock"]; } }
18    public IValueParameter<DoubleValue> CostParameter { get { return (IValueParameter<DoubleValue>)Parameters["Cost"]; } }
19    public IValueParameter<DoubleValue> DesignCapacityParameter { get { return (IValueParameter<DoubleValue>)Parameters["DesignCapacity"]; } }
20    public IValueParameter<DoubleValue> ConstructionParameter { get { return (IValueParameter<DoubleValue>)Parameters["Construction"]; } }
21    public IValueParameter<DoubleValue> MinConstructionParameter { get { return (IValueParameter<DoubleValue>)Parameters["MinConstruction"]; } }
22    public IValueParameter<DoubleValue> MaintenanceParameter { get { return (IValueParameter<DoubleValue>)Parameters["Maintenance"]; } }
23    public IValueParameter<DoubleValue> MinMaintenanceParameter { get { return (IValueParameter<DoubleValue>)Parameters["MinMaintenance"]; } }
24    public IValueParameter<DoubleValue> ConstructionScalingExponentParameter { get { return (IValueParameter<DoubleValue>)Parameters["ConstructionScalingExponent"]; } }
25    public IValueParameter<DoubleValue> MaintenanceScalingExponentParameter { get { return (IValueParameter<DoubleValue>)Parameters["MaintenanceScalingExponent"]; } }
26    public IValueParameter<DoubleValue> SafetyStockParameter { get { return (IValueParameter<DoubleValue>)Parameters["SafetyStock"]; } }
27    public IValueParameter<DoubleValue> DryMatterLossParameter { get { return (IValueParameter<DoubleValue>)Parameters["DryMatterLoss"]; } }
28    public IValueParameter<LogisticAction> StorageParameter { get { return (IValueParameter<LogisticAction>)Parameters["Storage"]; } }
29    public IValueParameter<DoubleValue> UtilizationFactorParameter { get { return (IValueParameter<DoubleValue>)Parameters["UtilizationFactor"]; } }
30    public IValueParameter<ValueParameterCollection> ProductsParameter { get { return (IValueParameter<ValueParameterCollection>)Parameters["Products"]; } }
31    public IValueParameter<ValueParameterCollection> ConstructionEmissionsParameter { get { return (IValueParameter<ValueParameterCollection>)Parameters["ConstructionEmissions"]; } }
32    public IValueParameter<ValueParameterCollection> AvailableCapacitiesParameter { get { return (IValueParameter<ValueParameterCollection>)Parameters["AvailableCapacities"]; } }
33    public IValueParameter<ValueParameterCollection> MaxCapacitiesParameter { get { return (IValueParameter<ValueParameterCollection>)Parameters["MaxCapacities"]; } }
34    public IValueParameter<DoubleValue> AvailableMaintenanceFactorParameter { get { return (IValueParameter<DoubleValue>)Parameters["AvailableMaintenanceFactor"]; } }
35    public IValueParameter<DoubleValue> MinCapacityParameter { get { return (IValueParameter<DoubleValue>) Parameters["MinCapacity"]; } }
36    public IValueParameter<StringValue> MainProductParameter { get { return (IValueParameter<StringValue>)Parameters["MainProduct"]; } }
37    public IValueParameter<DoubleValue> MainProductConversionRateParameter { get { return (IValueParameter<DoubleValue>)Parameters["MainProductConversionRate"]; } }
38    #endregion
39
40    #region Parameter Values
41    public string Label { get { return LabelParameter.Value.Value; } }
42    public string Feedstock { get { return FeedstockParameter.Value.Value; } }
43    public string MainProduct { get { return MainProductParameter.Value.Value; } set { MainProductParameter.Value.Value = value; }
44    }
45
46    public double Cost { get { return CostParameter.Value.Value; } set { CostParameter.Value.Value = value; } }
47
48    public double DesignCapacity { get { return DesignCapacityParameter.Value.Value; } }
49    public double Construction { get { return ConstructionParameter.Value.Value; } }
50    public double MinConstruction { get { return MinConstructionParameter.Value.Value; } }
51    public double Maintenance { get { return MaintenanceParameter.Value.Value; } }
52    public double MinMaintenance { get { return MinMaintenanceParameter.Value.Value; } }
53    public double ConstructionScalingExponent { get { return ConstructionScalingExponentParameter.Value.Value; } }
54    public double MaintenanceScalingExponent { get { return MaintenanceScalingExponentParameter.Value.Value; } }
55    public double SafetyStock { get { return SafetyStockParameter.Value.Value; } }
56    public double DryMatterLoss { get { return DryMatterLossParameter.Value.Value; } }
57    public double UtilizationFactor { get { return UtilizationFactorParameter.Value.Value; } }
58    public LogisticAction Storage { get { return StorageParameter.Value; } }
59    public ValueParameterCollection Products { get { return ProductsParameter.Value; } }
60    public ValueParameterCollection ConstructionEmissions { get { return ConstructionEmissionsParameter.Value; } }
61    public ValueParameterCollection MaxCapacities { get { return MaxCapacitiesParameter.Value; } }
62    public ValueParameterCollection AvailableCapacities { get { return AvailableCapacitiesParameter.Value; } }
63    public double AvailableMaintenanceFactor { get { return AvailableMaintenanceFactorParameter.Value.Value; } }
64    public double MainProductConversionRate {
65      get { return MainProductConversionRateParameter.Value.Value; }
66      set { MainProductConversionRateParameter.Value = new DoubleValue(value); }
67    }
68
69    public double MinCapacity {
70      get {
71        double minCapacity = MinCapacityParameter.Value.Value;
72        if (minCapacity == 0d)
73          minCapacity = MinCapacityParameter.Value.Value = GetInferredMinCapacity();
74        return minCapacity;
75      }
76    }
77
78    private double GetInferredMinCapacity() {
79      if (MinConstructionParameter.Value != null && // reconstruct from MinConstruction
80          ConstructionParameter.Value != null &&
81          DesignCapacityParameter.Value != null &&
82          ConstructionScalingExponentParameter.Value != null)
83        return Math.Pow(MinConstruction / Construction, 1 / ConstructionScalingExponent) * DesignCapacity;
84      if (MinMaintenanceParameter.Value != null && // reconstruct from MinMaintenance
85          MaintenanceParameter.Value != null &&
86          MaintenanceScalingExponentParameter.Value != null &&
87          DesignCapacityParameter.Value != null)
88        return Math.Pow(MinMaintenance / Maintenance, 1 / MaintenanceScalingExponent) * DesignCapacity;
89      throw new IndexOutOfRangeException("MinCapacity is not available and could be reconstructed from other parameters.");
90    }
91
92    #endregion
93
94    #region Construction & Cloning
95    public Conversion() {
96      Parameters.Add(new ValueParameter<StringValue>("Label", "The label/name of this conversion."));
97      Parameters.Add(new ValueParameter<StringValue>("Feedstock", "The product used as feedstock (@target)."));
98      Parameters.Add(new ValueParameter<DoubleValue>("Cost", "The conversion cost [EUR/t]."));
99      Parameters.Add(new ValueParameter<DoubleValue>("Construction", "The amortized construction costs [EUR/a]"));
100      Parameters.Add(new ValueParameter<DoubleValue>("Maintenance", "The amortized operation and maintenance costs [EUR/a]"));
101      Parameters.Add(new ValueParameter<DoubleValue>("DesignCapacity", "The yearly turnover of feedstock [t/a]."));
102      Parameters.Add(new ValueParameter<DoubleValue>("MinConstruction", "The minimum construction costs [EUR/a]"));
103      Parameters.Add(new ValueParameter<DoubleValue>("MinMaintenance", "The minimum maintenance costs [EUR/a]"));
104      Parameters.Add(new ValueParameter<DoubleValue>("ConstructionScalingExponent", "The exponent used for up- and downsising construction costs.", new DoubleValue(0.86)));
105      Parameters.Add(new ValueParameter<DoubleValue>("MaintenanceScalingExponent", "The exponent used for up- and downscaling maintenance costs.", new DoubleValue(0.91)));
106      Parameters.Add(new ValueParameter<DoubleValue>("SafetyStock", "The number of days feedstock needs to be stored on average."));
107      Parameters.Add(new ValueParameter<DoubleValue>("DryMatterLoss", "The percentage of feedstock that is lost due to shrinkage.", new DoubleValue(0.0)));
108      Parameters.Add(new ValueParameter<DoubleValue>("UtilizationFactor", "Assumed utilization of a plant.", new DoubleValue(0.7)));
109      Parameters.Add(new ValueParameter<LogisticAction>("Storage", "Description of storage cost components [EUR/t/a]"));
110      Parameters.Add(new ValueParameter<ValueParameterCollection>("Products", "The list and amounts of products created by the conversion."));
111      Parameters.Add(new ValueParameter<ValueParameterCollection>("ConstructionEmissions", "The set of amortized emissions and amounts [t/a]"));
112      Parameters.Add(new ValueParameter<ValueParameterCollection>("AvailableCapacities", "Dictionary of regions with their free capacities of this conversion type."));
113      Parameters.Add(new ValueParameter<ValueParameterCollection>("MaxCapacities", "Dictionary of regions (or 'Default') with their maximum allows capapcity for this conversion type."));
114      Parameters.Add(new ValueParameter<DoubleValue>("AvailableMaintenanceFactor", "Scaling factor for maintenance costs when using free capacities."));
115      Parameters.Add(new ValueParameter<DoubleValue>("MinCapacity", "Minimum capacity to be reasonably build."));
116      Parameters.Add(new ValueParameter<StringValue>("MainProduct", "The main output product created during this conversion process."));
117      Parameters.Add(new ValueParameter<DoubleValue>("MainProductConversionRate", "The conversion rate of the main output product. (This value is automatically calculated)"));
118      RegisterEventHandlers();
119    }
120
121    [StorableConstructor]
122    protected Conversion(bool isDeserializing) : base(isDeserializing) { }
123
124    [StorableHook(HookType.AfterDeserialization)]
125    private void AfterDeserialization() {
126      if (!Parameters.ContainsKey("AvailableCapacities"))
127        Parameters.Add(new ValueParameter<ValueParameterCollection>("AvailableCapacities", "Dictionary of regions with their free capacities of this conversion type."));
128      if (!Parameters.ContainsKey("MaxCapacities"))
129        Parameters.Add(new ValueParameter<ValueParameterCollection>("MaxCapacities", "Dictionary of regions (or 'Default') with their maximum allows capapcity for this conversion type."));
130      if (!Parameters.ContainsKey("AvailableMaintenanceFactor"))
131        Parameters.Add(new ValueParameter<DoubleValue>("AvailableMaintenanceFactor", "Scaling factor for maintenance costs when using free capacities."));
132      if (!Parameters.ContainsKey("DryMatterLoss"))
133        Parameters.Add(new ValueParameter<DoubleValue>("DryMatterLoss", "The percentage of feedstock that is lost due to shrinkage.", new DoubleValue(0.0)));
134      if (!Parameters.ContainsKey("MinCapacity"))
135        Parameters.Add(new ValueParameter<DoubleValue>("MinCapacity", "Minimum capacity to be reasonably build.", new DoubleValue(GetInferredMinCapacity())));
136      if (!Parameters.ContainsKey("MainProduct"))
137        Parameters.Add(new ValueParameter<StringValue>("MainProduct", "The main output product created during this conversion process."));
138      if (!Parameters.ContainsKey("MainProductConversionRate"))
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    protected Conversion(Conversion orig, Cloner cloner)
144      : base(orig, cloner) {
145      RegisterEventHandlers();
146    }
147    public override IDeepCloneable Clone(Cloner cloner) {
148      return new Conversion(this, cloner);
149    }
150    #endregion
151
152    protected override void Parse(YamlMappingNode node) {
153      base.Parse(node);
154      MaybeDetermineMainProductConversionRate();
155    }
156
157    private void MaybeDetermineMainProductConversionRate() {
158      if (MainProductParameter.Value != null &&
159          (MainProductConversionRateParameter.Value == null || MainProductConversionRate == 0))
160        MainProductConversionRate = ((DoubleValue) Products[MainProduct].Value).Value;
161    }
162
163    public override void CollectParameterValues(System.Collections.Generic.IDictionary<string, IItem> values) {
164      var tmpDict = new Dictionary<string, IItem>();
165      base.CollectParameterValues(tmpDict);
166      foreach (var entry in tmpDict) {
167        if (entry.Key == "Label") continue;
168        if (entry.Key == "Feedstock") continue;
169        values.Add("Conversion " + Label + "." + Feedstock + "." + entry.Key, entry.Value);
170      }
171    }
172
173    private void RegisterEventHandlers() {
174      // when the HL value is changed
175      LabelParameter.ValueChanged += (sender, args) => {
176        UpdateName();
177        LabelParameter.Value.ValueChanged += (s, a) => { UpdateName(); };
178      };
179      // when the HL value's value is changed
180      LabelParameter.Value.ValueChanged += (sender, args) => { UpdateName(); };
181    }
182
183    private void UpdateName() {
184      this.Name = ItemName + ": " + Label;
185    }
186
187    public override bool IsEquivalentTo(DataItem other) {
188      var c = other as Conversion;
189      if (c == null) return false;
190      return c.Label == Label;
191    }
192
193    public void MaybeInferMainProduct(Dictionary<string, double> prices) {
194      if (MainProductParameter.Value != null) { return; }
195      string mainProductName = null;
196      double mainProductRevenue = 0;
197      foreach (var product in Products) {
198        double price = 0;
199        if (prices.TryGetValue(product.Name, out price) && product.Value is ValueParameter<DoubleValue>) {
200          var doubleValue = (IValueParameter<DoubleValue>)product;
201          var revenue = price*doubleValue.Value.Value;
202          if (mainProductName == null && revenue > 0 || revenue > mainProductRevenue) {
203            mainProductName = product.Name;
204            mainProductRevenue = revenue;
205          }
206        }
207      }
208      if (mainProductName != null) {
209        MainProduct = MainProduct;
210        MaybeDetermineMainProductConversionRate();
211      }
212    }
213  }
214}
Note: See TracBrowser for help on using the repository browser.