diff --git a/DistrictEnergy/DHRunLPModel.cs b/DistrictEnergy/DHRunLPModel.cs
index 54f2448..3a9a9b3 100644
--- a/DistrictEnergy/DHRunLPModel.cs
+++ b/DistrictEnergy/DHRunLPModel.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using DistrictEnergy.Helpers;
@@ -50,27 +50,39 @@ public DHRunLPModel()
new Dictionary<(int, LoadTypes, AbstractDistrictLoad), double>();
///
- /// Exported Energy. Subject To LargeNumber Cost.
+ /// Exports
///
- public Dictionary<(int, LoadTypes), Variable> E = new Dictionary<(int, LoadTypes), Variable>();
+ public Dictionary<(int, Exportable), Variable> E =
+ new Dictionary<(int, Exportable), Variable>();
///The only instance of the DHRunLPModel command.
public static DHRunLPModel Instance { get; private set; }
+ public Solver LpModel { get; private set; }
+
public override string EnglishName => "DHRunLPModel";
protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
- Main();
- return Result.Success;
+ return Main();
}
- private void Main()
+ private Result Main()
{
ClearVariables();
DHSimulateDistrictEnergy.Instance.PreSolve();
// Create the linear solver with the CBC backend.
- var solver = Solver.CreateSolver("SimpleLP", "GLOP_LINEAR_PROGRAMMING");
+ try
+ {
+ LpModel = Solver.CreateSolver("SimpleLP", "GLOP_LINEAR_PROGRAMMING");
+ }
+ catch (Exception e)
+ {
+ RhinoApp.WriteLine(e.Message);
+ return Result.Failure;
+ }
+
+ RhinoApp.WriteLine("Created Solver");
// Define Model Variables. Here each variable is the supply power of each available supply module
int timeSteps = (int) DistrictControl.PlanningSettings.TimeSteps; // Number of Time Steps
@@ -83,8 +95,8 @@ private void Main()
{
for (var t = 0; t < timeSteps * dt; t += dt)
{
- P[(t, supplymodule)] = solver.MakeNumVar(0.0, double.PositiveInfinity,
- string.Format($"P_{t}_{supplymodule.Name}"));
+ P[(t, supplymodule)] = LpModel.MakeNumVar(0.0, double.PositiveInfinity,
+ string.Format($"P_{t:0000}_{supplymodule.Name}"));
}
}
@@ -98,12 +110,9 @@ private void Main()
{
for (var t = 0; t < timeSteps * dt; t += dt)
{
- Qin[(t, supplymodule)] =
- solver.MakeNumVar(0.0, supplymodule.MaxChargingRate, $"StoIn_{t}_{supplymodule.Name}");
- Qout[(t, supplymodule)] =
- solver.MakeNumVar(0.0, supplymodule.MaxDischargingRate, $"StoOut_{t}_{supplymodule.Name}");
- S[(t, supplymodule)] =
- solver.MakeNumVar(0.0, supplymodule.Capacity, $"StoState_{t}_{supplymodule.Name}");
+ Qin[(t, supplymodule)] = LpModel.MakeNumVar(0.0, supplymodule.MaxChargingRate, $"StoIn_{t:0000}_{supplymodule.Name}");
+ Qout[(t, supplymodule)] = LpModel.MakeNumVar(0.0, supplymodule.MaxDischargingRate, $"StoOut_{t:0000}_{supplymodule.Name}");
+ S[(t, supplymodule)] = LpModel.MakeNumVar(0.0, supplymodule.Capacity, $"StoState_{t:0000}_{supplymodule.Name}");
}
}
@@ -111,17 +120,10 @@ private void Main()
RhinoApp.WriteLine(
$"Computed {Qin.Count + Qout.Count + S.Count} S variables in {watch.ElapsedMilliseconds} milliseconds");
- // Exports (per supply module)
- for (var t = 0; t < timeSteps * dt; t += dt)
- {
- E[(t, LoadTypes.Elec)] = solver.MakeNumVar(0.0, double.PositiveInfinity, $"Export{t}_Electricity");
- E[(t, LoadTypes.Cooling)] = solver.MakeNumVar(0.0, double.PositiveInfinity, $"Export{t}_Cooling");
- E[(t, LoadTypes.Heating)] = solver.MakeNumVar(0.0, double.PositiveInfinity, $"Export{t}_Heating");
- }
- RhinoApp.WriteLine("Number of variables = " + solver.NumVariables());
+ RhinoApp.WriteLine("Number of variables = " + LpModel.NumVariables());
- foreach (var load in DistrictControl.Instance.ListOfDistrictLoads)
+ foreach (var load in DistrictControl.Instance.ListOfDistrictLoads.OfType())
{
for (int t = 0; t < timeSteps * dt; t += dt)
{
@@ -129,6 +131,14 @@ private void Main()
}
}
+ foreach (var load in DistrictControl.Instance.ListOfDistrictLoads.OfType())
+ {
+ for (int t = 0; t < timeSteps * dt; t += dt)
+ {
+ E[(t, load)] = LpModel.MakeNumVar(0, double.PositiveInfinity, $"E_{t:0000}_{load.Name}");
+ }
+ }
+
// Set Load Balance Constraints
foreach (LoadTypes loadTypes in Enum.GetValues(typeof(LoadTypes)))
{
@@ -136,16 +146,17 @@ private void Main()
{
for (int i = 0; i < timeSteps * dt; i += dt)
{
- solver.Add(P.Where(k => k.Key.Item2.ConversionMatrix.ContainsKey(loadTypes) && k.Key.Item1 == i)
- .Select(k => k.Value * k.Key.Item2.ConversionMatrix[loadTypes]).ToArray().Sum() -
- Qin.Where(k => k.Key.Item2.OutputType == loadTypes && k.Key.Item1 == i)
- .Select(x => x.Value).ToArray()
- .Sum() +
- Qout.Where(k => k.Key.Item2.OutputType == loadTypes && k.Key.Item1 == i)
- .Select(x => x.Value).ToArray()
- .Sum() ==
- Load.Where(x => x.Key.Item2 == loadTypes && x.Key.Item1 == i).Select(o => o.Value)
- .Sum() + E[(i, loadTypes)]);
+ LpModel.Add(
+ P.Where(k => k.Key.Item2.ConversionMatrix.ContainsKey(loadTypes) && k.Key.Item1 == i)
+ .Select(k => k.Value * k.Key.Item2.ConversionMatrix[loadTypes]).ToArray().Sum() -
+ Qin.Where(k => k.Key.Item2.OutputType == loadTypes && k.Key.Item1 == i)
+ .Select(x => x.Value).ToArray()
+ .Sum() +
+ Qout.Where(k => k.Key.Item2.OutputType == loadTypes && k.Key.Item1 == i)
+ .Select(x => x.Value).ToArray()
+ .Sum() ==
+ Load.Where(x => x.Key.Item2 == loadTypes && x.Key.Item1 == i).Select(o => o.Value).Sum() +
+ E.Where(x => x.Key.Item2.LoadType == loadTypes && x.Key.Item1 == i).Select(o => o.Value).ToArray().Sum());
}
}
@@ -153,16 +164,18 @@ private void Main()
{
for (int i = 0; i < timeSteps * dt; i += dt)
{
- solver.Add(P.Where(k => k.Key.Item2.ConversionMatrix.ContainsKey(loadTypes) && k.Key.Item1 == i)
- .Select(k => k.Value * k.Key.Item2.ConversionMatrix[loadTypes]).ToArray().Sum() -
- Qin.Where(k => k.Key.Item2.OutputType == loadTypes && k.Key.Item1 == i)
- .Select(x => x.Value).ToArray()
- .Sum() +
- Qout.Where(k => k.Key.Item2.OutputType == loadTypes && k.Key.Item1 == i)
- .Select(x => x.Value).ToArray()
- .Sum() ==
- Load.Where(x => x.Key.Item2 == loadTypes && x.Key.Item1 == i).Select(o => o.Value)
- .Sum() + E[(i, loadTypes)]);
+ LpModel.Add(
+ P.Where(k => k.Key.Item2.ConversionMatrix.ContainsKey(loadTypes) && k.Key.Item1 == i)
+ .Select(k => k.Value * k.Key.Item2.ConversionMatrix[loadTypes]).ToArray().Sum() -
+ Qin.Where(k => k.Key.Item2.OutputType == loadTypes && k.Key.Item1 == i)
+ .Select(x => x.Value).ToArray()
+ .Sum() +
+ Qout.Where(k => k.Key.Item2.OutputType == loadTypes && k.Key.Item1 == i)
+ .Select(x => x.Value).ToArray()
+ .Sum() ==
+ Load.Where(x => x.Key.Item2 == loadTypes && x.Key.Item1 == i).Select(o => o.Value)
+ .Sum()+
+ E.Where(x => x.Key.Item2.LoadType == loadTypes && x.Key.Item1 == i).Select(o => o.Value).ToArray().Sum());
}
}
@@ -170,16 +183,18 @@ private void Main()
{
for (int i = 0; i < timeSteps * dt; i += dt)
{
- solver.Add(P.Where(k => k.Key.Item2.ConversionMatrix.ContainsKey(loadTypes) && k.Key.Item1 == i)
- .Select(k => k.Value * k.Key.Item2.ConversionMatrix[loadTypes]).ToArray().Sum() -
- Qin.Where(k => k.Key.Item2.OutputType == loadTypes && k.Key.Item1 == i)
- .Select(x => x.Value).ToArray()
- .Sum() +
- Qout.Where(k => k.Key.Item2.OutputType == loadTypes && k.Key.Item1 == i)
- .Select(x => x.Value).ToArray()
- .Sum() ==
- Load.Where(x => x.Key.Item2 == loadTypes && x.Key.Item1 == i).Select(o => o.Value)
- .Sum() + E[(i, loadTypes)]);
+ LpModel.Add(
+ P.Where(k => k.Key.Item2.ConversionMatrix.ContainsKey(loadTypes) && k.Key.Item1 == i)
+ .Select(k => k.Value * k.Key.Item2.ConversionMatrix[loadTypes]).ToArray().Sum() -
+ Qin.Where(k => k.Key.Item2.OutputType == loadTypes && k.Key.Item1 == i)
+ .Select(x => x.Value).ToArray()
+ .Sum() +
+ Qout.Where(k => k.Key.Item2.OutputType == loadTypes && k.Key.Item1 == i)
+ .Select(x => x.Value).ToArray()
+ .Sum() ==
+ Load.Where(x => x.Key.Item2 == loadTypes && x.Key.Item1 == i).Select(o => o.Value)
+ .Sum()+
+ E.Where(x => x.Key.Item2.LoadType == loadTypes && x.Key.Item1 == i).Select(o => o.Value).ToArray().Sum());
}
}
@@ -187,31 +202,29 @@ private void Main()
{
for (int i = 0; i < timeSteps * dt; i += dt)
{
- solver.Add(P.Where(k => k.Key.Item2.ConversionMatrix.ContainsKey(loadTypes) && k.Key.Item1 == i)
- .Select(k => k.Value * k.Key.Item2.ConversionMatrix[loadTypes]).ToArray()
- .Sum() ==
- 0);
+ LpModel.Add(
+ P.Where(k => k.Key.Item2.ConversionMatrix.ContainsKey(loadTypes) && k.Key.Item1 == i)
+ .Select(k => k.Value * k.Key.Item2.ConversionMatrix[loadTypes]).ToArray()
+ .Sum() ==
+ 0);
}
}
}
// Capacity Constraints
- foreach (var inputFlow in P.Where(x =>
+ LinearExpr TotalDemand(LoadTypes loadType1, int t)
+ {
+ return Load.Where(x => x.Key.Item2 == loadType1 && x.Key.Item1 == t).Select(o => o.Value).Sum() +
+ E.Where(x => x.Key.Item2.LoadType == loadType1 && x.Key.Item1 == t).Select(o => o.Value).ToArray().Sum();
+ }
+
+ foreach (var inputFlow in P.Where(x => x.Key.Item2.Capacity != Double.PositiveInfinity).Where(x =>
x.Key.Item2.OutputType == LoadTypes.Elec || x.Key.Item2.OutputType == LoadTypes.Heating ||
x.Key.Item2.OutputType == LoadTypes.Cooling))
{
var loadType = inputFlow.Key.Item2.OutputType;
var i = inputFlow.Key.Item1;
- solver.Add(inputFlow.Value * inputFlow.Key.Item2.ConversionMatrix[loadType] <=
- inputFlow.Key.Item2.CapacityFactor *
- (
- P.Where(k => k.Key.Item2.ConversionMatrix.ContainsKey(loadType) && k.Key.Item1 == i)
- .Select(k => k.Value * k.Key.Item2.ConversionMatrix[loadType]).ToArray().Sum() +
- Qin.Where(k => k.Key.Item2.OutputType == loadType && k.Key.Item1 == i)
- .Select(x => x.Value).ToArray().Sum() -
- Qout.Where(k => k.Key.Item2.OutputType == loadType && k.Key.Item1 == i)
- .Select(x => x.Value).ToArray().Sum() +
- Load.Where(x => x.Key.Item2 == loadType && x.Key.Item1 == i).Select(o => o.Value).Sum())
+ LpModel.Add(inputFlow.Value * inputFlow.Key.Item2.ConversionMatrix[loadType] <= inputFlow.Key.Item2.CapacityFactor * TotalDemand(loadType, i)
);
}
@@ -220,49 +233,51 @@ private void Main()
{
for (int t = 0; t < timeSteps * dt; t += dt)
{
- solver.Add(P[(t, solarSupply)] == solarSupply.SolarAvailableInput.ToList().GetRange(t, dt).Sum() *
+ LpModel.Add(P[(t, solarSupply)] == solarSupply.SolarAvailableInput.ToList().GetRange(t, dt).Sum() *
solarSupply.AvailableArea);
}
}
- // Todo: Add wind constraints
+ // Solar & Wind Constraints
+ foreach (var windTurbine in DistrictControl.Instance.ListOfPlantSettings.OfType())
+ {
+ for (int t = 0; t < timeSteps * dt; t += dt)
+ {
+ LpModel.Add(P[(t, windTurbine)] == windTurbine.Power(t, dt) * windTurbine.NumWnd);
+ }
+ }
// Storage Rules
foreach (var storage in DistrictControl.Instance.ListOfPlantSettings.OfType())
{
- // solver.Add(S[(0, storage)]
- // == (1 - storage.StoredStandingLosses) *
- // S.Where(k => k.Key.Item2 == storage).Select(o => o.Value).Skip(1).First() +
- // storage.ChargingEfficiency * Qin[(0, storage)] -
- // (1 / storage.DischargingEfficiency) * Qout[(0, storage)]);
// storage content initial <= final, both variable
- // Todo: Why Skip first timestep
- solver.Add(S.Where(x => x.Key.Item2 == storage).Select(o => o.Value).Skip(1).First() <=
- S.Where(x => x.Key.Item2 == storage).Select(o => o.Value).Last());
+ // Must skip first timestep
+ LpModel.Add(S.Where(x => x.Key.Item2 == storage).Select(o => o.Value).Skip(1).First() <=
+ S.Where(x => x.Key.Item2 == storage).Select(o => o.Value).Last());
// 'storage content initial == and final >= storage.init * capacity'
- solver.Add(
+ LpModel.Add(
S.Where(x => x.Key.Item2 == storage).Select(o => o.Value).First() == storage.StartingCapacity);
// Storage Balance Rule
for (int t = dt; t < timeSteps * dt; t += dt)
{
- solver.Add(S[(t, storage)] ==
- (1 - storage.StorageStandingLosses) *
- S[(t - dt, storage)] +
- storage.ChargingEfficiency * Qin[(t, storage)] -
- (1 / storage.DischargingEfficiency) * Qout[(t, storage)]);
+ LpModel.Add(S[(t, storage)] ==
+ (1 - storage.StorageStandingLosses) *
+ S[(t - dt, storage)] +
+ storage.ChargingEfficiency * Qin[(t, storage)] -
+ (1 / storage.DischargingEfficiency) * Qout[(t, storage)]);
}
}
- RhinoApp.WriteLine("Number of constraints = " + solver.NumConstraints());
+ RhinoApp.WriteLine("Number of constraints = " + LpModel.NumConstraints());
// Set the Objective Function
- var objective = solver.Objective();
+ var objective = LpModel.Objective();
foreach (var supplymodule in DistrictControl.Instance.ListOfPlantSettings.OfType())
{
- for (int t = dt; t < timeSteps * dt; t += dt)
+ for (int t = 0; t < timeSteps * dt; t += dt)
{
objective.SetCoefficient(P[(t, supplymodule)],
supplymodule.F * DistrictEnergy.Settings.AnnuityFactor / dt + supplymodule.V);
@@ -271,33 +286,37 @@ private void Main()
foreach (var storage in DistrictControl.Instance.ListOfPlantSettings.OfType())
{
- for (int t = dt; t < timeSteps * dt; t += dt)
+ for (int t = 0; t < timeSteps * dt; t += dt)
{
objective.SetCoefficient(S[(t, storage)],
storage.F * DistrictEnergy.Settings.AnnuityFactor / dt + storage.V);
}
}
- foreach (var variable in E)
+ foreach (var exportable in DistrictControl.Instance.ListOfDistrictLoads.OfType())
{
- objective.SetCoefficient(variable.Value, UmiContext.Current.ProjectSettings.ElectricityDollars);
+ for (int t = 0; t < timeSteps * dt; t += dt)
+ {
+ objective.SetCoefficient(E[(t, exportable)],
+ exportable.F * DistrictEnergy.Settings.AnnuityFactor / dt + exportable.V);
+ }
}
objective.SetMinimization();
- var lp = solver.ExportModelAsLpFormat(false);
- solver.EnableOutput();
- var resultStatus = solver.Solve();
+ var lp = LpModel.ExportModelAsLpFormat(false);
+ LpModel.EnableOutput();
+ var resultStatus = LpModel.Solve();
// Check that the problem has an optimal solution.
if (resultStatus != Solver.ResultStatus.OPTIMAL)
{
RhinoApp.WriteLine("The problem does not have an optimal solution!");
- return;
+ return Result.Failure;
}
RhinoApp.WriteLine("Solution:");
- RhinoApp.WriteLine("Optimal objective value = " + solver.Objective().Value());
+ RhinoApp.WriteLine("Optimal objective value = " + LpModel.Objective().Value());
foreach (var plant in DistrictControl.Instance.ListOfPlantSettings.OfType())
{
@@ -310,6 +329,15 @@ private void Main()
RhinoApp.WriteLine($"{plant.Name} = {cap} Peak ; {energy} Annum");
}
+ foreach (var plant in DistrictControl.Instance.ListOfDistrictLoads.OfType())
+ {
+ var solutionValues = E.Where(o => o.Key.Item2.Name == plant.Name).Select(v => v.Value.SolutionValue());
+ var cap = solutionValues.Max();
+ var energy = solutionValues.Sum();
+ plant.Input = solutionValues.ToArray();
+ RhinoApp.WriteLine($"{plant.Name} = {cap} Peak ; {energy} Annum");
+ }
+
foreach (var storage in DistrictControl.Instance.ListOfPlantSettings.OfType())
{
storage.Output = Qout.Where(x => x.Key.Item2 == storage).Select(v => v.Value.SolutionValue())
@@ -322,19 +350,13 @@ private void Main()
$"{storage.Name} = Qin {storage.Input.Sum()}; Qout {storage.Output.Sum()}; Storage Balance {storage.Input.Sum() - storage.Output.Sum()}");
}
- // Write Exports
- foreach (LoadTypes loadTypes in Enum.GetValues(typeof(LoadTypes)))
- {
- var sum = E.Where(o => o.Key.Item2 == loadTypes).Select(x => x.Value.SolutionValue()).ToArray().Sum();
- if (sum > 0) RhinoApp.WriteLine($"Export_{loadTypes} = {sum}");
- }
-
RhinoApp.WriteLine("\nAdvanced usage:");
- RhinoApp.WriteLine("Problem solved in " + solver.WallTime() + " milliseconds");
- RhinoApp.WriteLine("Problem solved in " + solver.Iterations() + " iterations");
- RhinoApp.WriteLine("Problem solved in " + solver.Nodes() + " branch-and-bound nodes");
+ RhinoApp.WriteLine("Problem solved in " + LpModel.WallTime() + " milliseconds");
+ RhinoApp.WriteLine("Problem solved in " + LpModel.Iterations() + " iterations");
+ RhinoApp.WriteLine("Problem solved in " + LpModel.Nodes() + " branch-and-bound nodes");
OnCompletion(new SimulationCompleted() {TimeSteps = timeSteps, Period = dt});
+ return Result.Success;
}
private void ClearVariables()
@@ -344,7 +366,6 @@ private void ClearVariables()
Qout.Clear();
S.Clear();
Load.Clear();
- E.Clear();
}
public event EventHandler Completion;
diff --git a/DistrictEnergy/DHSimulateDistrictEnergy.cs b/DistrictEnergy/DHSimulateDistrictEnergy.cs
index 61ecf09..90193f8 100644
--- a/DistrictEnergy/DHSimulateDistrictEnergy.cs
+++ b/DistrictEnergy/DHSimulateDistrictEnergy.cs
@@ -435,26 +435,32 @@ private double[] GetHourlyElectricalLoadProfile(List contextObjects)
private IEnumerable GetHourlyLocationSolarRadiation(UmiContext context)
{
- RhinoApp.WriteLine("Calculating Solar Radiation on horizontal surface");
+ RhinoApp.WriteLine("Calculating Solar Radiation on horizontal surfaces...");
var a = new EPWeatherData();
a.GetRawData(context.WeatherFilePath);
- return a.HourlyWeatherDataRawList.Select(b => (double) b.GHorRadiation / 1000.0); // from Wh to kWh
+ var radiation = a.HourlyWeatherDataRawList.Select(b => (double) b.GHorRadiation / 1000.0);
+ RhinoApp.WriteLine("Completed Solar Radiation");
+ return radiation; // from Wh to kWh
}
private IEnumerable GetHourlyLocationWind(UmiContext context)
{
- RhinoApp.WriteLine("Calculating wind for location");
+ RhinoApp.WriteLine("Calculating wind for location...");
var a = new EPWeatherData();
a.GetRawData(context.WeatherFilePath);
- return a.HourlyWeatherDataRawList.Select(b => (double) b.WindSpeed); // m/s
+ var wind = a.HourlyWeatherDataRawList.Select(b => (double) b.WindSpeed);
+ RhinoApp.WriteLine("Completed wind");
+ return wind; // m/s
}
private IEnumerable GetHourlyLocationAmbiantTemp(UmiContext context)
{
- RhinoApp.WriteLine("Calculating temp for location");
+ RhinoApp.WriteLine("Calculating temperature for location...");
var a = new EPWeatherData();
a.GetRawData(context.WeatherFilePath);
- return a.HourlyWeatherDataRawList.Select(b => (double) b.DB); // C
+ var temp = a.HourlyWeatherDataRawList.Select(b => (double) b.DB);
+ RhinoApp.WriteLine("Completed temperature");
+ return temp; // C
}
///
diff --git a/DistrictEnergy/DistrictControl.xaml.cs b/DistrictEnergy/DistrictControl.xaml.cs
index 5d9fb61..edadf61 100644
--- a/DistrictEnergy/DistrictControl.xaml.cs
+++ b/DistrictEnergy/DistrictControl.xaml.cs
@@ -37,7 +37,7 @@ public DistrictControl()
new SolarThermalCollector(),
new WindTurbine(),
new GridElectricity(),
- new GridGas()
+ new GridGas(),
};
ListOfDistrictLoads = new ObservableCollection()
{
@@ -46,6 +46,9 @@ public DistrictControl()
new ElectricityLoads(),
new PipeNetwork(LoadTypes.Heating, "Heating Losses"),
new PipeNetwork(LoadTypes.Cooling, "Cooling Losses"),
+ new ElectricityExport(),
+ new CoolingExport(),
+ new HeatingExport()
};
PlanningSettings = new PlanningSettings();
DistrictSettings = new DistrictSettings();
diff --git a/DistrictEnergy/DistrictEnergy.csproj b/DistrictEnergy/DistrictEnergy.csproj
index 71adea9..35d34c5 100644
--- a/DistrictEnergy/DistrictEnergy.csproj
+++ b/DistrictEnergy/DistrictEnergy.csproj
@@ -50,11 +50,14 @@
..\packages\Dragablz.0.0.3.203\lib\net45\Dragablz.dll
+
+ ..\packages\RhinoCommon.6.25.20114.5271\lib\net45\Eto.dll
+
..\packages\FSharp.Core.4.5.2\lib\net45\FSharp.Core.dll
-
- ..\packages\Google.OrTools.7.5.7466\lib\net452\Google.OrTools.dll
+
+ ..\packages\Google.OrTools.7.6.7691\lib\net452\Google.OrTools.dll
..\packages\Google.Protobuf.3.11.2\lib\net45\Google.Protobuf.dll
@@ -83,9 +86,11 @@
True
-
- ..\packages\RhinoCommon.6.24.20079.23341\lib\net45\RhinoCommon.dll
- False
+
+ ..\packages\RhinoCommon.6.25.20114.5271\lib\net45\Rhino.UI.dll
+
+
+ ..\packages\RhinoCommon.6.25.20114.5271\lib\net45\RhinoCommon.dll
@@ -127,10 +132,16 @@
+
+
+
+
+
+
@@ -181,6 +192,7 @@
+
@@ -211,6 +223,9 @@
AnAdditionalLoadsView.xaml
+
+ ExportView.xaml
+
ACustomModuleView.xaml
@@ -260,6 +275,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile
@@ -386,9 +405,9 @@
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
+
+
-
-
+
+
\ No newline at end of file
diff --git a/DistrictEnergy/Helpers/LoadTypes.cs b/DistrictEnergy/Helpers/LoadTypes.cs
index 2ca3a57..a97c59f 100644
--- a/DistrictEnergy/Helpers/LoadTypes.cs
+++ b/DistrictEnergy/Helpers/LoadTypes.cs
@@ -11,6 +11,8 @@ public enum LoadTypes
GridGas,
SolarRadiation,
Wind,
- Custom
+ Custom,
+ GridHeat,
+ GridCool
}
}
diff --git a/DistrictEnergy/Networks/Loads/AbstractDistrictLoad.cs b/DistrictEnergy/Networks/Loads/AbstractDistrictLoad.cs
index 6ab8aa0..d407dbf 100644
--- a/DistrictEnergy/Networks/Loads/AbstractDistrictLoad.cs
+++ b/DistrictEnergy/Networks/Loads/AbstractDistrictLoad.cs
@@ -18,7 +18,7 @@ namespace DistrictEnergy.Networks.Loads
{
public abstract class AbstractDistrictLoad
{
- public Guid Id { get; set; } = Guid.NewGuid();
+ public abstract Guid Id { get; set; }
public abstract LoadTypes LoadType { get; set; }
public abstract double[] Input { get; set; }
public abstract SolidColorBrush Fill { get; set; }
diff --git a/DistrictEnergy/Networks/Loads/AdditionalLoads.cs b/DistrictEnergy/Networks/Loads/AdditionalLoads.cs
index 4229bb7..5fc40eb 100644
--- a/DistrictEnergy/Networks/Loads/AdditionalLoads.cs
+++ b/DistrictEnergy/Networks/Loads/AdditionalLoads.cs
@@ -16,7 +16,7 @@
namespace DistrictEnergy.Networks.Loads
{
- class AdditionalLoads : AbstractDistrictLoad, IBaseLoad
+ class AdditionalLoads : BaseLoad
{
public AdditionalLoads(LoadTypes loadType)
{
@@ -24,6 +24,7 @@ public AdditionalLoads(LoadTypes loadType)
}
public override double[] Input { get; set; }
+ public override Guid Id { get; set; } = Guid.NewGuid();
public override LoadTypes LoadType { get; set; }
public override SolidColorBrush Fill { get; set; }
public override string Name { get; set; }
diff --git a/DistrictEnergy/Networks/Loads/CoolingLoads.cs b/DistrictEnergy/Networks/Loads/CoolingLoads.cs
index 4db651f..eed035c 100644
--- a/DistrictEnergy/Networks/Loads/CoolingLoads.cs
+++ b/DistrictEnergy/Networks/Loads/CoolingLoads.cs
@@ -3,6 +3,7 @@
using System.Linq;
using System.Windows.Media;
using DistrictEnergy.Helpers;
+using DistrictEnergy.Networks.ThermalPlants;
using LiveCharts.Defaults;
using Rhino;
using Umi.Core;
@@ -10,7 +11,7 @@
namespace DistrictEnergy.Networks.Loads
{
- class CoolingLoads : AbstractDistrictLoad, IBaseLoad
+ class CoolingLoads : BaseLoad
{
public CoolingLoads()
{
@@ -18,6 +19,7 @@ public CoolingLoads()
}
public override double[] Input { get; set; }
+ public override Guid Id { get; set; } = Guid.NewGuid();
public override LoadTypes LoadType { get; set; } = LoadTypes.Cooling;
public override SolidColorBrush Fill { get; set; } = new SolidColorBrush(Color.FromRgb(0, 140, 218));
public override string Name { get; set; } = "Cooling Load";
diff --git a/DistrictEnergy/Networks/Loads/ElectricityLoads.cs b/DistrictEnergy/Networks/Loads/ElectricityLoads.cs
index 52185ab..b166f4b 100644
--- a/DistrictEnergy/Networks/Loads/ElectricityLoads.cs
+++ b/DistrictEnergy/Networks/Loads/ElectricityLoads.cs
@@ -1,19 +1,22 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Windows.Media;
using DistrictEnergy.Helpers;
+using DistrictEnergy.Networks.ThermalPlants;
using LiveCharts.Defaults;
using Rhino;
using Umi.Core;
namespace DistrictEnergy.Networks.Loads
{
- class ElectricityLoads : AbstractDistrictLoad, IBaseLoad
+ class ElectricityLoads : BaseLoad
{
public ElectricityLoads()
{
}
+ public override Guid Id { get; set; } = Guid.NewGuid();
public override LoadTypes LoadType { get; set; } = LoadTypes.Elec;
public override SolidColorBrush Fill { get; set; } = new SolidColorBrush(Color.FromRgb(173, 221, 67));
public override string Name { get; set; } = "Electricity Load";
diff --git a/DistrictEnergy/Networks/Loads/HeatingLoads.cs b/DistrictEnergy/Networks/Loads/HeatingLoads.cs
index aded1d2..e838fa9 100644
--- a/DistrictEnergy/Networks/Loads/HeatingLoads.cs
+++ b/DistrictEnergy/Networks/Loads/HeatingLoads.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Windows.Media;
using DistrictEnergy.Helpers;
+using DistrictEnergy.Networks.ThermalPlants;
using LiveCharts.Defaults;
using Rhino;
using Umi.Core;
@@ -9,13 +10,14 @@
namespace DistrictEnergy.Networks.Loads
{
- class HeatingLoads : AbstractDistrictLoad, IBaseLoad
+ class HeatingLoads : BaseLoad
{
public HeatingLoads()
{
}
+ public override Guid Id { get; set; } = Guid.NewGuid();
public override LoadTypes LoadType { get; set; } = LoadTypes.Heating;
public override SolidColorBrush Fill { get; set; } = new SolidColorBrush(Color.FromRgb(235, 45, 45));
public override string Name { get; set; } = "Heating Load";
diff --git a/DistrictEnergy/Networks/Loads/PipeNetwork.cs b/DistrictEnergy/Networks/Loads/PipeNetwork.cs
index 055736c..2ea21a5 100644
--- a/DistrictEnergy/Networks/Loads/PipeNetwork.cs
+++ b/DistrictEnergy/Networks/Loads/PipeNetwork.cs
@@ -6,12 +6,13 @@
using System.Windows.Media;
using Deedle.Vectors;
using DistrictEnergy.Helpers;
+using DistrictEnergy.Networks.ThermalPlants;
using LiveCharts.Defaults;
using Umi.Core;
namespace DistrictEnergy.Networks.Loads
{
- internal class PipeNetwork : AbstractDistrictLoad
+ internal class PipeNetwork : BaseLoad
{
public PipeNetwork(LoadTypes loadType, string name)
{
@@ -66,6 +67,7 @@ private double[] CalcInput()
return final;
}
+ public override Guid Id { get; set; } = Guid.NewGuid();
public override LoadTypes LoadType { get; set; }
public double RelativeLoss { get; set; }
}
diff --git a/DistrictEnergy/Networks/ThermalPlants/AbsorptionChiller.cs b/DistrictEnergy/Networks/ThermalPlants/AbsorptionChiller.cs
index 405628e..e5adb90 100644
--- a/DistrictEnergy/Networks/ThermalPlants/AbsorptionChiller.cs
+++ b/DistrictEnergy/Networks/ThermalPlants/AbsorptionChiller.cs
@@ -13,12 +13,6 @@ internal class AbsorptionChiller : Dispatchable
{
public AbsorptionChiller()
{
- ConversionMatrix = new Dictionary()
- {
- {LoadTypes.Cooling, CCOP_ABS},
- {LoadTypes.Heating, -1}
-
- };
}
///
@@ -64,7 +58,12 @@ private double CalcCapacity()
public override LoadTypes OutputType { get; } = LoadTypes.Cooling;
public override LoadTypes InputType => LoadTypes.Heating;
public override double CapacityFactor => OFF_ABS;
- public override Dictionary ConversionMatrix { get; set; }
+ public override Dictionary ConversionMatrix => new Dictionary()
+ {
+ {LoadTypes.Cooling, CCOP_ABS},
+ {LoadTypes.Heating, -1}
+
+ };
public override List Input { get; set; }
public override List Output { get; set; }
public override double Efficiency => ConversionMatrix[OutputType];
diff --git a/DistrictEnergy/Networks/ThermalPlants/BaseLoad.cs b/DistrictEnergy/Networks/ThermalPlants/BaseLoad.cs
new file mode 100644
index 0000000..0d7a180
--- /dev/null
+++ b/DistrictEnergy/Networks/ThermalPlants/BaseLoad.cs
@@ -0,0 +1,12 @@
+using System.Collections.Generic;
+using DistrictEnergy.Helpers;
+using DistrictEnergy.Networks.Loads;
+using LiveCharts.Defaults;
+
+namespace DistrictEnergy.Networks.ThermalPlants
+{
+ public abstract class BaseLoad : AbstractDistrictLoad, IBaseLoad
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/DistrictEnergy/Networks/ThermalPlants/CombinedHeatNPower.cs b/DistrictEnergy/Networks/ThermalPlants/CombinedHeatNPower.cs
index 51bb557..bc5f337 100644
--- a/DistrictEnergy/Networks/ThermalPlants/CombinedHeatNPower.cs
+++ b/DistrictEnergy/Networks/ThermalPlants/CombinedHeatNPower.cs
@@ -13,12 +13,6 @@ public class CombinedHeatNPower : Dispatchable
{
public CombinedHeatNPower()
{
- ConversionMatrix = new Dictionary()
- {
- {LoadTypes.Elec, EFF_CHP},
- {LoadTypes.Heating, HREC_CHP},
- {LoadTypes.Gas, -1}
- };
}
///
@@ -89,7 +83,12 @@ private double CalcCapacity()
public override LoadTypes OutputType => TMOD_CHP;
public override LoadTypes InputType => LoadTypes.Gas;
public override double CapacityFactor => OFF_CHP;
- public override Dictionary ConversionMatrix { get; set; }
+ public override Dictionary ConversionMatrix => new Dictionary()
+ {
+ {LoadTypes.Elec, EFF_CHP},
+ {LoadTypes.Heating, HREC_CHP},
+ {LoadTypes.Gas, -1}
+ };
public override List Input { get; set; }
public override List Output { get; set; }
public override double Efficiency => ConversionMatrix[OutputType];
diff --git a/DistrictEnergy/Networks/ThermalPlants/CoolingExport.cs b/DistrictEnergy/Networks/ThermalPlants/CoolingExport.cs
new file mode 100644
index 0000000..8cfeb3f
--- /dev/null
+++ b/DistrictEnergy/Networks/ThermalPlants/CoolingExport.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Windows.Media;
+using DistrictEnergy.Helpers;
+using DistrictEnergy.Networks.Loads;
+using LiveCharts.Defaults;
+using Umi.Core;
+
+namespace DistrictEnergy.Networks.ThermalPlants
+{
+ internal class CoolingExport : Exportable
+ {
+ public CoolingExport()
+ {
+ }
+
+ public override Guid Id { get; set; } = Guid.NewGuid();
+ public override LoadTypes LoadType { get; set; } = LoadTypes.Cooling;
+ public override double[] Input { get; set; } = new double[8760];
+ public override double F { get; set; } = 0;
+ public override double V { get; set; } = 0.15;
+
+ public override SolidColorBrush Fill { get; set; } =
+ new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF6161"));
+
+ public override string Name { get; set; } = "Cooling Export";
+
+ public override void GetUmiLoads(List contextObjects)
+ {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/DistrictEnergy/Networks/ThermalPlants/CustomCoolingSupplyModule.cs b/DistrictEnergy/Networks/ThermalPlants/CustomCoolingSupplyModule.cs
index 9d21c25..32b5c59 100644
--- a/DistrictEnergy/Networks/ThermalPlants/CustomCoolingSupplyModule.cs
+++ b/DistrictEnergy/Networks/ThermalPlants/CustomCoolingSupplyModule.cs
@@ -10,10 +10,6 @@ internal class CustomCoolingSupplyModule : CustomEnergySupplyModule
{
public CustomCoolingSupplyModule()
{
- ConversionMatrix = new Dictionary()
- {
- {LoadTypes.Cooling, 1}
- };
}
public double ComputeHeatBalance(double demand, int i)
@@ -30,7 +26,10 @@ public double ComputeHeatBalance(double demand, int i)
public override LoadTypes OutputType => LoadTypes.Cooling;
public override LoadTypes InputType => LoadTypes.Custom;
public override double CapacityFactor => 1;
- public override Dictionary ConversionMatrix { get; set; }
+ public override Dictionary ConversionMatrix => new Dictionary()
+ {
+ {LoadTypes.Cooling, 1}
+ };
public override List Input { get; set; }
public override List Output { get; set; }
public override double F { get; set; }
diff --git a/DistrictEnergy/Networks/ThermalPlants/CustomElectricitySupplyModule.cs b/DistrictEnergy/Networks/ThermalPlants/CustomElectricitySupplyModule.cs
index 388e862..8142834 100644
--- a/DistrictEnergy/Networks/ThermalPlants/CustomElectricitySupplyModule.cs
+++ b/DistrictEnergy/Networks/ThermalPlants/CustomElectricitySupplyModule.cs
@@ -10,16 +10,15 @@ internal class CustomElectricitySupplyModule : CustomEnergySupplyModule
public CustomElectricitySupplyModule()
{
- ConversionMatrix = new Dictionary()
- {
- {LoadTypes.Elec, 1}
- };
}
public override LoadTypes OutputType => LoadTypes.Elec;
public override LoadTypes InputType => LoadTypes.Custom;
public override double CapacityFactor => 1;
- public override Dictionary ConversionMatrix { get; set; }
+ public override Dictionary ConversionMatrix => new Dictionary()
+ {
+ {LoadTypes.Elec, 1}
+ };
public override List Input { get; set; }
public override List Output { get; set; }
public override double F { get; set; }
diff --git a/DistrictEnergy/Networks/ThermalPlants/CustomEnergySupplyModule.cs b/DistrictEnergy/Networks/ThermalPlants/CustomEnergySupplyModule.cs
index 446d874..da6c260 100644
--- a/DistrictEnergy/Networks/ThermalPlants/CustomEnergySupplyModule.cs
+++ b/DistrictEnergy/Networks/ThermalPlants/CustomEnergySupplyModule.cs
@@ -106,7 +106,7 @@ public override SolidColorBrush Fill
public override double CapacityFactor { get; }
public Color Color { get; set; } = Color.FromRgb(200, 1, 0);
- public abstract override Dictionary ConversionMatrix { get; set; }
+ public abstract override Dictionary ConversionMatrix { get; }
public abstract override double Efficiency { get; }
public double ComputeHeatBalance(double demand, double chiller, double solar, int i)
diff --git a/DistrictEnergy/Networks/ThermalPlants/CustomHeatingSupplyModule.cs b/DistrictEnergy/Networks/ThermalPlants/CustomHeatingSupplyModule.cs
index 93113b5..9681402 100644
--- a/DistrictEnergy/Networks/ThermalPlants/CustomHeatingSupplyModule.cs
+++ b/DistrictEnergy/Networks/ThermalPlants/CustomHeatingSupplyModule.cs
@@ -8,16 +8,15 @@ internal class CustomHeatingSupplyModule : CustomEnergySupplyModule
{
public CustomHeatingSupplyModule()
{
- ConversionMatrix = new Dictionary()
- {
- {LoadTypes.Heating, 1}
- };
}
public override LoadTypes OutputType => LoadTypes.Heating;
public override LoadTypes InputType => LoadTypes.Custom;
public override double CapacityFactor => 1;
- public override Dictionary ConversionMatrix { get; set; }
+ public override Dictionary ConversionMatrix => new Dictionary()
+ {
+ {LoadTypes.Heating, 1}
+ };
public override List Input { get; set; }
public override List Output { get; set; }
public override double F { get; set; }
diff --git a/DistrictEnergy/Networks/ThermalPlants/Dispatchable.cs b/DistrictEnergy/Networks/ThermalPlants/Dispatchable.cs
index 936eeda..b6add14 100644
--- a/DistrictEnergy/Networks/ThermalPlants/Dispatchable.cs
+++ b/DistrictEnergy/Networks/ThermalPlants/Dispatchable.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media;
+using Deedle;
using DistrictEnergy.Helpers;
using LiveCharts.Defaults;
using Newtonsoft.Json;
@@ -17,7 +18,7 @@ public abstract class Dispatchable : IThermalPlantSettings
public abstract string Name { get; set; }
public abstract Guid Id { get; set; }
public abstract LoadTypes OutputType { get; }
- public abstract Dictionary ConversionMatrix { get; set; }
+ public abstract Dictionary ConversionMatrix { get; }
public abstract List Input { get; set; }
public abstract List Output { get; set; }
public abstract double Efficiency { get; }
@@ -45,6 +46,16 @@ public FixedCost(IThermalPlantSettings plant, byte alpha = 255)
Cost = plant.Output.Max() * DistrictControl.PlanningSettings.AnnuityFactor * plant.F /
(8760 / DistrictControl.PlanningSettings.TimeSteps);
}
+
+ public FixedCost(Exportable plant, byte alpha = 255)
+ {
+ var color = plant.Fill.Color;
+ Fill = new SolidColorBrush(Color.FromArgb(alpha, color.R, color.G, color.B));
+ Name = plant.Name + " Fixed Cost";
+ if (plant.Input != null)
+ Cost = plant.Input.Max() * DistrictControl.PlanningSettings.AnnuityFactor * plant.F /
+ (8760 / DistrictControl.PlanningSettings.TimeSteps);
+ }
}
public class VariableCost : GraphCost
@@ -63,6 +74,15 @@ public VariableCost(IThermalPlantSettings plant, byte alpha = 255)
if (plant.Output != null)
Cost = plant.Output.Select(x => x.Value * plant.V).Sum();
}
+
+ public VariableCost(Exportable plant, byte alpha = 255)
+ {
+ var color = plant.Fill.Color;
+ Fill = new SolidColorBrush(Color.FromArgb(alpha, color.R, color.G, color.B));
+ Name = plant.Name + " Variable Cost";
+ if (plant.Input != null)
+ Cost = plant.Input.Select(x => x * plant.V).Sum();
+ }
}
public class GraphCost
diff --git a/DistrictEnergy/Networks/ThermalPlants/ElectricChiller.cs b/DistrictEnergy/Networks/ThermalPlants/ElectricChiller.cs
index 0d3f178..efae8b4 100644
--- a/DistrictEnergy/Networks/ThermalPlants/ElectricChiller.cs
+++ b/DistrictEnergy/Networks/ThermalPlants/ElectricChiller.cs
@@ -12,11 +12,6 @@ internal class ElectricChiller : Dispatchable
{
public ElectricChiller()
{
- ConversionMatrix = new Dictionary()
- {
- {LoadTypes.Cooling, CCOP_ECH},
- {LoadTypes.Elec, -1}
- };
}
///
@@ -34,7 +29,11 @@ public ElectricChiller()
public override LoadTypes OutputType => LoadTypes.Cooling;
public override LoadTypes InputType => LoadTypes.Elec;
public override double CapacityFactor => 1;
- public override Dictionary ConversionMatrix { get; set; }
+ public override Dictionary ConversionMatrix => new Dictionary()
+ {
+ {LoadTypes.Cooling, CCOP_ECH},
+ {LoadTypes.Elec, -1}
+ };
public override List Input { get; set; }
public override List Output { get; set; }
public override double Efficiency => ConversionMatrix[OutputType];
diff --git a/DistrictEnergy/Networks/ThermalPlants/ElectricHeatPump.cs b/DistrictEnergy/Networks/ThermalPlants/ElectricHeatPump.cs
index 9f645ab..01de9b6 100644
--- a/DistrictEnergy/Networks/ThermalPlants/ElectricHeatPump.cs
+++ b/DistrictEnergy/Networks/ThermalPlants/ElectricHeatPump.cs
@@ -13,12 +13,6 @@ public class ElectricHeatPump : Dispatchable
{
public ElectricHeatPump()
{
- ConversionMatrix = new Dictionary()
- {
- {LoadTypes.Heating, HCOP_EHP},
- {LoadTypes.Cooling, (1-1/HCOP_EHP)}, // TODO Add Switch for Use Evaporator or Not
- {LoadTypes.Elec, -1}
- };
}
///
@@ -59,7 +53,12 @@ private double CalcCapacity()
public override LoadTypes OutputType => LoadTypes.Heating;
public override LoadTypes InputType => LoadTypes.Elec;
public override double CapacityFactor => OFF_EHP;
- public override Dictionary ConversionMatrix { get; set; }
+ public override Dictionary ConversionMatrix => new Dictionary()
+ {
+ {LoadTypes.Heating, HCOP_EHP },
+ {LoadTypes.Cooling, UseEhpEvap == 0? 0 : (1-1/HCOP_EHP)},
+ {LoadTypes.Elec, -1}
+ };
public override List Input { get; set; }
public override List Output { get; set; }
public override double Efficiency => ConversionMatrix[OutputType];
diff --git a/DistrictEnergy/Networks/ThermalPlants/ElectricityExport.cs b/DistrictEnergy/Networks/ThermalPlants/ElectricityExport.cs
new file mode 100644
index 0000000..c9e6b4b
--- /dev/null
+++ b/DistrictEnergy/Networks/ThermalPlants/ElectricityExport.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Windows.Media;
+using DistrictEnergy.Helpers;
+using DistrictEnergy.Networks.Loads;
+using LiveCharts.Defaults;
+using Umi.Core;
+
+namespace DistrictEnergy.Networks.ThermalPlants
+{
+ internal class ElectricityExport : Exportable
+ {
+ public ElectricityExport()
+ {
+ }
+
+ public override Guid Id { get; set; } = Guid.NewGuid();
+ public override LoadTypes LoadType { get; set; } = LoadTypes.Elec;
+ public override double[] Input { get; set; } = new double[8760];
+ public override double F { get; set; } = 0;
+ public override double V { get; set; } = 0.15;
+
+ public override SolidColorBrush Fill { get; set; } =
+ new SolidColorBrush((Color) ColorConverter.ConvertFromString("#FF6161"));
+
+ public override string Name { get; set; } = "Electricity Export";
+ public override void GetUmiLoads(List contextObjects)
+ {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/DistrictEnergy/Networks/ThermalPlants/Exportable.cs b/DistrictEnergy/Networks/ThermalPlants/Exportable.cs
new file mode 100644
index 0000000..ee8e97d
--- /dev/null
+++ b/DistrictEnergy/Networks/ThermalPlants/Exportable.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Windows.Media;
+using DistrictEnergy.Helpers;
+using DistrictEnergy.Networks.Loads;
+using LiveCharts.Defaults;
+
+namespace DistrictEnergy.Networks.ThermalPlants
+{
+ public abstract class Exportable : AbstractDistrictLoad
+ {
+ public abstract double F { get; set; }
+ public abstract double V { get; set; }
+ public GraphCost FixedCost => new FixedCost(this);
+ public GraphCost VariableCost => new VariableCost(this, 200);
+ public double TotalCost => FixedCost.Cost + VariableCost.Cost;
+ }
+}
\ No newline at end of file
diff --git a/DistrictEnergy/Networks/ThermalPlants/GridElectricity.cs b/DistrictEnergy/Networks/ThermalPlants/GridElectricity.cs
index 7e03e40..c5be781 100644
--- a/DistrictEnergy/Networks/ThermalPlants/GridElectricity.cs
+++ b/DistrictEnergy/Networks/ThermalPlants/GridElectricity.cs
@@ -13,10 +13,6 @@ internal class GridElectricity : Dispatchable
{
public GridElectricity()
{
- ConversionMatrix = new Dictionary()
- {
- {LoadTypes.Elec, 1}
- };
}
[DataMember] [DefaultValue(0)] public override double F { get; set; } = 0;
@@ -39,7 +35,10 @@ public override double V
public override LoadTypes OutputType => LoadTypes.Elec;
public override LoadTypes InputType => LoadTypes.GridElec;
public override double CapacityFactor => 1;
- public override Dictionary ConversionMatrix { get; set; }
+ public override Dictionary ConversionMatrix => new Dictionary()
+ {
+ {LoadTypes.Elec, 1}
+ };
public override List Input { get; set; }
public override List Output { get; set; }
public override double Efficiency => ConversionMatrix[OutputType];
diff --git a/DistrictEnergy/Networks/ThermalPlants/GridGas.cs b/DistrictEnergy/Networks/ThermalPlants/GridGas.cs
index 741b6cc..d8b4fd1 100644
--- a/DistrictEnergy/Networks/ThermalPlants/GridGas.cs
+++ b/DistrictEnergy/Networks/ThermalPlants/GridGas.cs
@@ -13,10 +13,6 @@ internal class GridGas : Dispatchable
{
public GridGas()
{
- ConversionMatrix = new Dictionary()
- {
- {LoadTypes.Gas, 1}
- };
}
[DataMember] [DefaultValue(0)] public override double F { get; set; } = 0;
@@ -37,7 +33,10 @@ public override double V
public override LoadTypes OutputType => LoadTypes.Gas;
public override LoadTypes InputType => LoadTypes.GridGas;
public override double CapacityFactor => 1;
- public override Dictionary ConversionMatrix { get; set; }
+ public override Dictionary ConversionMatrix => new Dictionary()
+ {
+ {LoadTypes.Gas, 1}
+ };
public override List Input { get; set; }
public override List Output { get; set; }
public override double Efficiency => ConversionMatrix[OutputType];
diff --git a/DistrictEnergy/Networks/ThermalPlants/HeatingExport.cs b/DistrictEnergy/Networks/ThermalPlants/HeatingExport.cs
new file mode 100644
index 0000000..506836e
--- /dev/null
+++ b/DistrictEnergy/Networks/ThermalPlants/HeatingExport.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Windows.Media;
+using DistrictEnergy.Helpers;
+using DistrictEnergy.Networks.Loads;
+using LiveCharts.Defaults;
+using Umi.Core;
+
+namespace DistrictEnergy.Networks.ThermalPlants
+{
+ internal class HeatingExport : Exportable
+ {
+ public HeatingExport()
+ {
+ }
+
+ public override Guid Id { get; set; } = Guid.NewGuid();
+ public override LoadTypes LoadType { get; set; } = LoadTypes.Heating;
+ public override double[] Input { get; set; } = new double[8760];
+ public override double F { get; set; } = 0;
+ public override double V { get; set; } = 0.15;
+
+ public override SolidColorBrush Fill { get; set; } =
+ new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF6161"));
+
+ public override string Name { get; set; } = "Heating Export";
+ public override void GetUmiLoads(List contextObjects)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/DistrictEnergy/Networks/ThermalPlants/IThermalPlantSettings.cs b/DistrictEnergy/Networks/ThermalPlants/IThermalPlantSettings.cs
index d8c8840..d3e20ca 100644
--- a/DistrictEnergy/Networks/ThermalPlants/IThermalPlantSettings.cs
+++ b/DistrictEnergy/Networks/ThermalPlants/IThermalPlantSettings.cs
@@ -44,7 +44,7 @@ public interface IThermalPlantSettings
Guid Id { get; set; }
LoadTypes OutputType { get; }
- [JsonIgnore] Dictionary ConversionMatrix { get; set; }
+ [JsonIgnore] Dictionary ConversionMatrix { get; }
///
/// Input Energy to the Supply Module per period
diff --git a/DistrictEnergy/Networks/ThermalPlants/IWind.cs b/DistrictEnergy/Networks/ThermalPlants/IWind.cs
new file mode 100644
index 0000000..96740fe
--- /dev/null
+++ b/DistrictEnergy/Networks/ThermalPlants/IWind.cs
@@ -0,0 +1,13 @@
+using Newtonsoft.Json;
+
+namespace DistrictEnergy.Networks.ThermalPlants
+{
+ ///
+ /// Interface for Supply Modules Using Solar as input
+ ///
+ internal interface IWind : IThermalPlantSettings
+ {
+ double NumWnd { get; }
+ double Power(int t = 0, int dt = 8760);
+ }
+}
\ No newline at end of file
diff --git a/DistrictEnergy/Networks/ThermalPlants/NatGasBoiler.cs b/DistrictEnergy/Networks/ThermalPlants/NatGasBoiler.cs
index 8d87bd6..d4f889a 100644
--- a/DistrictEnergy/Networks/ThermalPlants/NatGasBoiler.cs
+++ b/DistrictEnergy/Networks/ThermalPlants/NatGasBoiler.cs
@@ -12,11 +12,6 @@ public class NatGasBoiler : Dispatchable
{
public NatGasBoiler()
{
- ConversionMatrix = new Dictionary()
- {
- {LoadTypes.Heating, EFF_NGB},
- {LoadTypes.Gas, -1}
- };
}
///
/// Heating efficiency (%)
@@ -32,7 +27,11 @@ public NatGasBoiler()
public override LoadTypes OutputType => LoadTypes.Heating;
public override LoadTypes InputType => LoadTypes.Gas;
public override double CapacityFactor => 1;
- public override Dictionary ConversionMatrix { get; set; }
+ public override Dictionary ConversionMatrix => new Dictionary()
+ {
+ {LoadTypes.Heating, EFF_NGB},
+ {LoadTypes.Gas, -1}
+ };
public override List Input { get; set; }
public override List Output { get; set; }
public override double Efficiency => ConversionMatrix[OutputType];
diff --git a/DistrictEnergy/Networks/ThermalPlants/PhotovoltaicArray.cs b/DistrictEnergy/Networks/ThermalPlants/PhotovoltaicArray.cs
index 3abad07..7b2c850 100644
--- a/DistrictEnergy/Networks/ThermalPlants/PhotovoltaicArray.cs
+++ b/DistrictEnergy/Networks/ThermalPlants/PhotovoltaicArray.cs
@@ -13,10 +13,6 @@ internal class PhotovoltaicArray : Dispatchable, ISolar
{
public PhotovoltaicArray()
{
- ConversionMatrix = new Dictionary()
- {
- {LoadTypes.Elec, EFF_PV * UTIL_PV * (1 - LOSS_PV)}
- };
}
///
@@ -62,7 +58,10 @@ private double CalcCapacity()
public override Guid Id { get; set; } = Guid.NewGuid();
public override LoadTypes OutputType => LoadTypes.Elec;
public override LoadTypes InputType => LoadTypes.SolarRadiation;
- public override Dictionary ConversionMatrix { get; set; }
+ public override Dictionary ConversionMatrix => new Dictionary()
+ {
+ {LoadTypes.Elec, EFF_PV * UTIL_PV * (1 - LOSS_PV)}
+ };
public override List Input { get; set; }
public override List Output { get; set; }
public override double Efficiency => ConversionMatrix[OutputType];
diff --git a/DistrictEnergy/Networks/ThermalPlants/SolarThermalCollector.cs b/DistrictEnergy/Networks/ThermalPlants/SolarThermalCollector.cs
index 2fe3222..563945d 100644
--- a/DistrictEnergy/Networks/ThermalPlants/SolarThermalCollector.cs
+++ b/DistrictEnergy/Networks/ThermalPlants/SolarThermalCollector.cs
@@ -14,10 +14,6 @@ public class SolarThermalCollector : Dispatchable, ISolar
{
public SolarThermalCollector()
{
- ConversionMatrix = new Dictionary()
- {
- {LoadTypes.Heating, EFF_SHW * (1 - LOSS_SHW) * UTIL_SHW}
- };
}
///
@@ -72,7 +68,10 @@ private double CalcCapacity()
public override LoadTypes OutputType => LoadTypes.Heating;
public override LoadTypes InputType => LoadTypes.SolarRadiation;
- public override Dictionary ConversionMatrix { get; set; }
+ public override Dictionary ConversionMatrix => new Dictionary()
+ {
+ {LoadTypes.Heating, EFF_SHW * (1 - LOSS_SHW) * UTIL_SHW}
+ };
public override List Input { get; set; }
public override List Output { get; set; }
public override double Efficiency => ConversionMatrix[LoadTypes.Heating];
diff --git a/DistrictEnergy/Networks/ThermalPlants/WindTurbine.cs b/DistrictEnergy/Networks/ThermalPlants/WindTurbine.cs
index c43e2db..f36698d 100644
--- a/DistrictEnergy/Networks/ThermalPlants/WindTurbine.cs
+++ b/DistrictEnergy/Networks/ThermalPlants/WindTurbine.cs
@@ -3,21 +3,18 @@
using System.ComponentModel;
using System.Linq;
using System.Runtime.Serialization;
+using System.Threading;
using System.Windows.Media;
using DistrictEnergy.Helpers;
using LiveCharts.Defaults;
namespace DistrictEnergy.Networks.ThermalPlants
{
- internal class WindTurbine : Dispatchable
+ internal class WindTurbine : Dispatchable, IWind
{
public WindTurbine()
{
- ConversionMatrix = new Dictionary()
- {
- {LoadTypes.Elec, (1-LOSS_WND)}
- };
}
///
/// Target offset as percent of annual energy (%)
@@ -81,10 +78,20 @@ private double CalcCapacity()
public override LoadTypes OutputType => LoadTypes.Elec;
public override LoadTypes InputType => LoadTypes.Wind;
- public override Dictionary ConversionMatrix { get; set; }
+ public override Dictionary ConversionMatrix => new Dictionary()
+ {
+ {LoadTypes.Elec, (1-LOSS_WND)}
+ };
public override List Input { get; set; }
public override List Output { get; set; }
public override double Efficiency => ConversionMatrix[OutputType];
public override SolidColorBrush Fill { get; set; } = new SolidColorBrush(Color.FromRgb(192, 244, 66));
+
+ public List WindAvailableInput(int t=0, int dt=8760)
+ {
+ return DHSimulateDistrictEnergy.Instance.DistrictDemand.WindN.ToList().GetRange(t, dt);
+ }
+ public double Power(int t = 0, int dt = 8760) => WindAvailableInput(t, dt).Where(w => w > CIN_WND && w < COUT_WND).Select(w => 0.6375 * ROT_WND * Math.Pow(w, 3) / 1000).Sum() * (1 - LOSS_WND);
+ public double NumWnd => Math.Ceiling(Capacity / Power() ); // Divide by 1000 because equation spits out Wh
}
}
\ No newline at end of file
diff --git a/DistrictEnergy/Properties/AssemblyInfo.cs b/DistrictEnergy/Properties/AssemblyInfo.cs
index fbdb763..d85c0ff 100644
--- a/DistrictEnergy/Properties/AssemblyInfo.cs
+++ b/DistrictEnergy/Properties/AssemblyInfo.cs
@@ -24,7 +24,7 @@
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: AssemblyProduct("DistricEnergyPlugIn")]
-[assembly: AssemblyVersion("2.0.3.*")]
+[assembly: AssemblyVersion("2.0.4.*")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
diff --git a/DistrictEnergy/ViewModels/CostsViewModel.cs b/DistrictEnergy/ViewModels/CostsViewModel.cs
index 9b6d46e..766102f 100644
--- a/DistrictEnergy/ViewModels/CostsViewModel.cs
+++ b/DistrictEnergy/ViewModels/CostsViewModel.cs
@@ -99,6 +99,31 @@ private void UpdateCostsChart(object sender, EventArgs e)
TotalCost += supplyModule.TotalCost;
}
+ foreach (var supplyModule in DistrictControl.Instance.ListOfDistrictLoads.OfType())
+ {
+ if (supplyModule.FixedCost.Cost > 0)
+ {
+ SeriesCollection.Add(new PieSeries
+ {
+ Title = supplyModule.FixedCost.Name,
+ Values = new ChartValues { supplyModule.FixedCost.Cost },
+ LabelPoint = CostLabelPointFormatter,
+ Fill = supplyModule.FixedCost.Fill
+ });
+ }
+ if (supplyModule.VariableCost.Cost > 0)
+ {
+ SeriesCollection.Add(new PieSeries
+ {
+ Title = supplyModule.VariableCost.Name,
+ Values = new ChartValues { supplyModule.VariableCost.Cost },
+ LabelPoint = CostLabelPointFormatter,
+ Fill = supplyModule.VariableCost.Fill
+ });
+ }
+ TotalCost += supplyModule.TotalCost;
+ }
+
NormalizedTotalCost = TotalCost / FloorArea;
}
diff --git a/DistrictEnergy/ViewModels/ExportViewModel.cs b/DistrictEnergy/ViewModels/ExportViewModel.cs
new file mode 100644
index 0000000..d8e143e
--- /dev/null
+++ b/DistrictEnergy/ViewModels/ExportViewModel.cs
@@ -0,0 +1,68 @@
+using System;
+using System.ComponentModel;
+using System.Runtime.CompilerServices;
+using System.Windows.Media;
+using DistrictEnergy.Annotations;
+using DistrictEnergy.Networks.ThermalPlants;
+
+namespace DistrictEnergy.ViewModels
+{
+ public class ExportViewModel : INotifyPropertyChanged
+ {
+ private Color _color;
+ private double _f;
+
+ public ExportViewModel(Exportable plant)
+ {
+ Plant = plant;
+ }
+
+ public Exportable Plant { get; set; }
+
+ public string Name => Plant.Name;
+
+ public Color Color
+ {
+ get => Plant.Fill.Color;
+ set
+ {
+ if (value.Equals(_color)) return;
+ _color = value;
+ OnPropertyChanged();
+ Plant.Fill = new SolidColorBrush(_color);
+ }
+ }
+
+ public double F
+ {
+ get => Plant.F;
+ set
+ {
+ if (value.Equals(_f)) return;
+ _f = value;
+ OnPropertyChanged();
+ Plant.F = value;
+ }
+ }
+
+ public double V
+ {
+ get => Plant.V;
+ set
+ {
+ if (value.Equals(_f)) return;
+ _f = value;
+ OnPropertyChanged();
+ Plant.V = value;
+ }
+ }
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ [NotifyPropertyChangedInvocator]
+ protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+}
\ No newline at end of file
diff --git a/DistrictEnergy/ViewModels/PlantSettingsViewModel.cs b/DistrictEnergy/ViewModels/PlantSettingsViewModel.cs
index db30332..011c72b 100644
--- a/DistrictEnergy/ViewModels/PlantSettingsViewModel.cs
+++ b/DistrictEnergy/ViewModels/PlantSettingsViewModel.cs
@@ -98,6 +98,7 @@ private void LoadSettings(UmiContext context)
{
DistrictControl.Instance.ListOfPlantSettings.Add(new GridGas());
}
+
}
OnPropertyChanged(string.Empty);
diff --git a/DistrictEnergy/Views/ExportView.xaml b/DistrictEnergy/Views/ExportView.xaml
new file mode 100644
index 0000000..1930654
--- /dev/null
+++ b/DistrictEnergy/Views/ExportView.xaml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DistrictEnergy/Views/ExportView.xaml.cs b/DistrictEnergy/Views/ExportView.xaml.cs
new file mode 100644
index 0000000..7f7e890
--- /dev/null
+++ b/DistrictEnergy/Views/ExportView.xaml.cs
@@ -0,0 +1,19 @@
+using System.Windows.Controls;
+using DistrictEnergy.Networks.Loads;
+using DistrictEnergy.Networks.ThermalPlants;
+using DistrictEnergy.ViewModels;
+
+namespace DistrictEnergy.Views
+{
+ ///
+ /// Interaction logic for ExportView.xaml
+ ///
+ public partial class ExportView : UserControl
+ {
+ public ExportView(Exportable export)
+ {
+ InitializeComponent();
+ DataContext = new ExportViewModel(export);
+ }
+ }
+}
diff --git a/DistrictEnergy/Views/PlantSettings/NetworkView.xaml b/DistrictEnergy/Views/PlantSettings/NetworkView.xaml
index 28d1a89..014e8d9 100644
--- a/DistrictEnergy/Views/PlantSettings/NetworkView.xaml
+++ b/DistrictEnergy/Views/PlantSettings/NetworkView.xaml
@@ -57,6 +57,7 @@
+
@@ -119,6 +120,7 @@
Foreground="#FF969696"
ToolTip="Computed Annuity Payment Factor" />
+
diff --git a/DistrictEnergy/Views/PlantSettings/NetworkView.xaml.cs b/DistrictEnergy/Views/PlantSettings/NetworkView.xaml.cs
index 0c544b7..f131ed1 100644
--- a/DistrictEnergy/Views/PlantSettings/NetworkView.xaml.cs
+++ b/DistrictEnergy/Views/PlantSettings/NetworkView.xaml.cs
@@ -1,5 +1,9 @@
-using System.Windows.Controls;
+using System.Linq;
+using System.Windows.Controls;
+using DistrictEnergy.Networks.ThermalPlants;
using DistrictEnergy.ViewModels;
+using Umi.RhinoServices.Context;
+using Umi.RhinoServices.UmiEvents;
namespace DistrictEnergy.Views.PlantSettings
{
@@ -12,6 +16,15 @@ public NetworkView()
{
InitializeComponent();
DataContext = new NetworkViewModel();
+ UmiEventSource.Instance.ProjectOpened += LoadThis;
+ }
+
+ private void LoadThis(object sender, UmiContext e)
+ {
+ foreach (var export in DistrictControl.Instance.ListOfDistrictLoads.OfType())
+ {
+ Exports.Children.Add(new ExportView(export));
+ }
}
}
}
diff --git a/DistrictEnergy/app.config b/DistrictEnergy/app.config
index 557095a..0176e5d 100644
--- a/DistrictEnergy/app.config
+++ b/DistrictEnergy/app.config
@@ -6,6 +6,10 @@
+
+
+
+
\ No newline at end of file
diff --git a/DistrictEnergy/data/rcpsp.proto b/DistrictEnergy/data/rcpsp.proto
index 113d54c..a82265d 100644
--- a/DistrictEnergy/data/rcpsp.proto
+++ b/DistrictEnergy/data/rcpsp.proto
@@ -11,7 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-// RCPSP problem.
+// RCPSP: Resource-Constrained Project Scheduling Problem.
//
// The problem description is as follows:
//
diff --git a/DistrictEnergy/linear_solver/linear_solver.proto b/DistrictEnergy/linear_solver/linear_solver.proto
index 6a70b35..2fe00b6 100644
--- a/DistrictEnergy/linear_solver/linear_solver.proto
+++ b/DistrictEnergy/linear_solver/linear_solver.proto
@@ -402,19 +402,16 @@ message MPModelRequest {
GLOP_LINEAR_PROGRAMMING = 2; // Recommended default for LP models.
CLP_LINEAR_PROGRAMMING = 0;
GLPK_LINEAR_PROGRAMMING = 1;
- GUROBI_LINEAR_PROGRAMMING = 6; // Commercial, needs a valid license.
+ GUROBI_LINEAR_PROGRAMMING = 6; // Commercial, needs a valid license.
XPRESS_LINEAR_PROGRAMMING = 101; // Commercial, needs a valid license.
- CPLEX_LINEAR_PROGRAMMING = 10; // Commercial, needs a valid
- // license.
+ CPLEX_LINEAR_PROGRAMMING = 10; // Commercial, needs a valid license.
SCIP_MIXED_INTEGER_PROGRAMMING = 3; // Recommended default for MIP models.
GLPK_MIXED_INTEGER_PROGRAMMING = 4;
CBC_MIXED_INTEGER_PROGRAMMING = 5;
GUROBI_MIXED_INTEGER_PROGRAMMING = 7; // Commercial, needs a valid license.
- XPRESS_MIXED_INTEGER_PROGRAMMING =
- 102; // Commercial, needs a valid license.
- CPLEX_MIXED_INTEGER_PROGRAMMING = 11; // Commercial, needs a
- // valid license.
+ XPRESS_MIXED_INTEGER_PROGRAMMING = 102; // Commercial, needs a valid license.
+ CPLEX_MIXED_INTEGER_PROGRAMMING = 11; // Commercial, needs a valid license.
BOP_INTEGER_PROGRAMMING = 12;
// WARNING: This solver will currently interpret all variables as integer,
diff --git a/DistrictEnergy/packages.config b/DistrictEnergy/packages.config
index 61fe4c3..755e7b2 100644
--- a/DistrictEnergy/packages.config
+++ b/DistrictEnergy/packages.config
@@ -4,10 +4,10 @@
-
-
-
-
+
+
+
+
@@ -16,12 +16,11 @@
-
-
-
+
+
\ No newline at end of file
diff --git a/DistrictEnergy/sat/cp_model.proto b/DistrictEnergy/sat/cp_model.proto
index d525fca..54e871c 100644
--- a/DistrictEnergy/sat/cp_model.proto
+++ b/DistrictEnergy/sat/cp_model.proto
@@ -175,7 +175,8 @@ message ReservoirConstraintProto {
// For now, we ignore node indices with no incident arc. All the other nodes
// must have exactly one incoming and one outgoing selected arc (i.e. literal at
// true). All the selected arcs that are not self-loops must form a single
-// circuit.
+// circuit. Note that multi-arcs are allowed, but only one of them will be true
+// at the same time. Multi-self loop are disallowed though.
message CircuitConstraintProto {
repeated int32 tails = 3;
repeated int32 heads = 4;
@@ -320,11 +321,11 @@ message ConstraintProto {
// TODO(user): Remove int_min in favor of lin_min.
IntegerArgumentProto int_min = 10;
- // The lin_max constraint forces the target to equal the minimum of all
+ // The lin_min constraint forces the target to equal the minimum of all
// linear expressions.
LinearArgumentProto lin_min = 28;
- // The int_min constraint forces the target to equal the product of all
+ // The int_prod constraint forces the target to equal the product of all
// variables.
IntegerArgumentProto int_prod = 11;
@@ -511,6 +512,21 @@ message CpModelProto {
// try to return a solution "close" to this assignment in case of multiple
// optimal solutions.
PartialVariableAssignment solution_hint = 6;
+
+ // A list of literals. The model will be solved assuming all these literals
+ // are true. Compared to just fixing the domain of these literals, using this
+ // mechanism is slower but allows in case the model is INFEASIBLE to get a
+ // potentially small subset of them that can be used to explain the
+ // infeasibility.
+ //
+ // Think (IIS), except when you are only concerned by the provided
+ // assumptions. This is powerful as it allows to group a set of logicially
+ // related constraint under only one enforcement literal which can potentially
+ // give you a good and interpretable explanation for infeasiblity.
+ //
+ // Such infeasibility explanation will be available in the
+ // sufficient_assumptions_for_infeasibility response field.
+ repeated int32 assumptions = 7;
}
// The status returned by a solver trying to solve a CpModelProto.
@@ -540,7 +556,7 @@ enum CpSolverStatus {
//
// TODO(user): support returning multiple solutions. Look at the Stubby
// streaming API as we probably wants to get them as they are found.
-// Next id: 23
+// Next id: 24
message CpSolverResponse {
// The status of the solve.
CpSolverStatus status = 1;
@@ -586,6 +602,21 @@ message CpSolverResponse {
// sub-optimal feasible ones.
repeated IntegerVariableProto tightened_variables = 21;
+ // A subset of the model "assumptions" field. This will only be filled if the
+ // status is INFEASIBLE. This subset of assumption will be enough to still get
+ // an infeasible problem.
+ //
+ // This is related to what is called the irreducible inconsistent subsystem or
+ // IIS. Except one is only concerned by the provided assumptions. There is
+ // also no guarantee that we return an irreducible (aka minimal subset).
+ // However, this is based on SAT explanation and there is a good chance it is
+ // not too large.
+ //
+ // If you really want a minimal subset, a possible way to get one is by
+ // changing your model to minimize the number of assumptions at false, but
+ // this is likely an harder problem to solve.
+ repeated int32 sufficient_assumptions_for_infeasibility = 23;
+
// This will be true iff the solver was asked to find all solutions to a
// satisfiability problem (or all optimal solutions to an optimization
// problem), and it was successful in doing so.
diff --git a/DistrictEnergy/sat/sat_parameters.proto b/DistrictEnergy/sat/sat_parameters.proto
index fd7ed28..ed88477 100644
--- a/DistrictEnergy/sat/sat_parameters.proto
+++ b/DistrictEnergy/sat/sat_parameters.proto
@@ -21,7 +21,7 @@ option java_multiple_files = true;
// Contains the definitions for all the sat algorithm parameters and their
// default values.
//
-// NEXT TAG: 152
+// NEXT TAG: 159
message SatParameters {
// ==========================================================================
// Branching and polarity
@@ -365,8 +365,8 @@ message SatParameters {
// ==========================================================================
// During presolve, only try to perform the bounded variable elimination (BVE)
- // of a variable x if the number of occurences of x times the number of
- // occurences of not(x) is not greater than this parameter.
+ // of a variable x if the number of occurrences of x times the number of
+ // occurrences of not(x) is not greater than this parameter.
optional int32 presolve_bve_threshold = 54 [default = 500];
// During presolve, we apply BVE only if this weight times the number of
@@ -416,6 +416,10 @@ message SatParameters {
// If true, the automaton constraints are expanded.
optional bool expand_automaton_constraints = 143 [default = true];
+ // If true, the positive table constraints are expanded.
+ // Note that currently, negative table constraints are always expanded.
+ optional bool expand_table_constraints = 158 [default = true];
+
// During presolve, we use a maximum clique heuristic to merge together
// no-overlap constraints or at most one constraints. This code can be slow,
// so we have a limit in place on the number of explored nodes in the
@@ -569,6 +573,11 @@ message SatParameters {
// have a cut generator.
optional int32 max_all_diff_cut_size = 148 [default = 7];
+ // For the lin max constraints, generates the cuts described in "Strong
+ // mixed-integer programming formulations for trained neural networks" by Ross
+ // Anderson et. (https://arxiv.org/pdf/1811.01988.pdf)
+ optional bool add_lin_max_cuts = 152 [default = true];
+
// In the integer rounding procedure used for MIR and Gomory cut, the maximum
// "scaling" we use (must be positive). The lower this is, the lower the
// integer coefficients of the cut will be. Note that cut generated by lower
@@ -590,13 +599,25 @@ message SatParameters {
// constraints during current call. Orthogonality is defined as 1 -
// cosine(vector angle between constraints). A value of zero disable this
// feature.
- optional double min_orthogonality_for_lp_constraints = 115 [default = 0.0];
+ optional double min_orthogonality_for_lp_constraints = 115 [default = 0.05];
+
+ // Max number of time we perform cut generation and resolve the LP at level 0.
+ optional int32 max_cut_rounds_at_level_zero = 154 [default = 1];
// If a constraint/cut in LP is not active for that many consecutive OPTIMAL
// solves, remove it from the LP. Note that it might be added again later if
// it become violated by the current LP solution.
optional int32 max_consecutive_inactive_count = 121 [default = 100];
+ // These parameters are similar to sat clause management activity parameters.
+ // They are effective only if the number of generated cuts exceed the storage
+ // limit. Default values are based on a few experiments on miplib instances.
+ optional double cut_max_active_count_value = 155 [default = 1e10];
+ optional double cut_active_count_decay = 156 [default = 0.8];
+
+ // Target number of constraints to remove during cleanup.
+ optional int32 cut_cleanup_target = 157 [default = 1000];
+
// Add that many lazy contraints (or cuts) at once in the LP. Note that at the
// beginning of the solve, we do add more than this.
optional int32 new_constraints_batch_size = 122 [default = 50];
@@ -638,6 +659,10 @@ message SatParameters {
}
optional SearchBranching search_branching = 82 [default = AUTOMATIC_SEARCH];
+ // When we try to follow the hint, we do a FIXED_SEARCH using the hint until
+ // this number of conflict is reached.
+ optional int32 hint_conflict_limit = 153 [default = 10];
+
// All the "exploit_*" parameters below work in the same way: when branching
// on an IntegerVariable, these parameters affect the value the variable is
// branched on. Currently the first heuristic that triggers win in the order
@@ -731,19 +756,16 @@ message SatParameters {
optional int32 num_search_workers = 100 [default = 1];
// Experimental. If this is true, then we interleave all our major search
- // strategy and distribute the work amongst num_search_workers. This also
- // work with just one worker, in which case the solver is deterministic even
- // if deterministic_parallel_search is false.
+ // strategy and distribute the work amongst num_search_workers.
+ //
+ // The search is deterministic (independently of num_search_workers!), and we
+ // schedule and wait for interleave_batch_size task to be completed before
+ // synchronizing and scheduling the next batch of tasks.
optional bool interleave_search = 136 [default = false];
+ optional int32 interleave_batch_size = 134 [default = 1];
// Temporary parameter until the memory usage is more optimized.
- optional bool reduce_memory_usage_in_interleave_mode = 141 [default = true];
-
- // Make the parallelization deterministic. Currently, this only work with
- // use_lns_only().
- //
- // TODO(user): make it work without use_lns_only().
- optional bool deterministic_parallel_search = 134 [default = false];
+ optional bool reduce_memory_usage_in_interleave_mode = 141 [default = false];
// Allows objective sharing between workers.
optional bool share_objective_bounds = 113 [default = true];
diff --git a/SetupProject/DistrictPlugInInstaller.wixproj b/SetupProject/DistrictPlugInInstaller.wixproj
index 7cc3de0..c40aa73 100644
--- a/SetupProject/DistrictPlugInInstaller.wixproj
+++ b/SetupProject/DistrictPlugInInstaller.wixproj
@@ -6,7 +6,7 @@
3.10
2a10a76b-558f-424d-965b-d2c84703cee0
2.0
- DistrictPluginInstaller-4.433-2020-dev-2.0.3
+ DistrictPluginInstaller-4.433-2020-dev-2.0.4
Package
DistrictPlugInInstaller