Added quarter based simulation with efficiency and capacity parameters.

This commit is contained in:
2026-04-14 22:20:01 +02:00
parent 3a0647aff2
commit 47d835d336
6 changed files with 147 additions and 80 deletions

View File

@@ -1,3 +1,4 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using BattSim.Models;
@@ -5,39 +6,59 @@ namespace BattSim.Services
{
public static class BatterySimulator
{
public static List<BatteryDayResult> SimulateBattery(EnergyData[] data, double batteryCapacity)
public static SimulatedBatteryEnergyData[] SimulateBattery(EnergyData[] energyData, double batteryCapacity, double efficiency)
{
var results = new List<BatteryDayResult>();
double remainingEnergy = 0;
var results = new List<SimulatedBatteryEnergyData>();
double batteryCharge = 0;
foreach (var day in data)
foreach (var e in energyData)
{
// // Charge battery from production
// var chargedEnergy = System.Math.Min(day.TotalProduction, batteryCapacity);
// var excessProduction = day.TotalProduction - chargedEnergy;
var simulatedBatteryEnergyData = new SimulatedBatteryEnergyData(e);
// Simulate charging the battery based on production
double excessProduction = batteryCharge + e.Production - batteryCapacity;
batteryCharge = double.Min(batteryCharge + e.Production, batteryCapacity);
simulatedBatteryEnergyData.SimulatedProduction = double.Max(excessProduction, 0);
// // Use battery for consumption
// var usedEnergy = System.Math.Min(chargedEnergy + remainingEnergy, day.TotalConsumption);
// var remainingAfterUse = chargedEnergy + remainingEnergy - usedEnergy;
// // Calculate reduced values
// var reducedConsumption = System.Math.Min(usedEnergy, day.TotalConsumption);
// var reducedProduction = day.TotalProduction - chargedEnergy;
// results.Add(new BatteryDayResult
// {
// Date = day.Date,
// ChargedEnergy = chargedEnergy,
// UsedEnergy = usedEnergy,
// RemainingEnergy = remainingAfterUse,
// ReducedConsumption = reducedConsumption,
// ReducedProduction = reducedProduction
// });
// remainingEnergy = remainingAfterUse;
// Simulate discharging the battery based on consumption
double availableEnergy = batteryCharge * efficiency;
double deficit = e.Consumption - availableEnergy;
double energyDrawn = Math.Min(e.Consumption, availableEnergy);
batteryCharge = batteryCharge - (energyDrawn / efficiency); // Adjust for loss
simulatedBatteryEnergyData.SimulatedConsumption = Math.Max(deficit, 0);
// Register the current charge
simulatedBatteryEnergyData.BatteryCharge = batteryCharge;
results.Add(simulatedBatteryEnergyData);
}
return results;
return results.ToArray();
}
public static SimulatedBatteryEnergyData[] GenerateDailyData(SimulatedBatteryEnergyData[] simulationData)
{
var simulationDataCopy = (SimulatedBatteryEnergyData[]) simulationData.Clone();
var dailySimulationData = new ConcurrentDictionary<DateOnly, SimulatedBatteryEnergyData>();
Parallel.ForEach(simulationDataCopy, simulationPoint =>
{
var date = DateOnly.FromDateTime(simulationPoint.Time);
// Use AddOrUpdate to avoid double lookup
dailySimulationData.AddOrUpdate(
date,
new SimulatedBatteryEnergyData(simulationPoint), // If key doesn't exist, add this value
(_, existing) =>
{
// If key exists, aggregate the values
existing.Consumption += simulationPoint.Consumption;
existing.Production += simulationPoint.Production;
existing.SimulatedConsumption += simulationPoint.SimulatedConsumption;
existing.SimulatedProduction += simulationPoint.SimulatedProduction;
existing.BatteryCharge = double.Max(existing.BatteryCharge, simulationPoint.BatteryCharge);
return existing;
}
);
});
return dailySimulationData.Values.ToArray();
}
}
}