From 6a13a2ac330bef93d9a85068468b266b7cc13ada Mon Sep 17 00:00:00 2001 From: Erik van Velzen Date: Thu, 30 Jan 2025 14:01:43 +0100 Subject: [PATCH] Refactor diesel tractor I am aware that this is nitpicking and doesn't solve any fundamental issue. --- _alp/Classes/Class.J_EADieselTractor.java | 129 +++++++++++++++------- 1 file changed, 92 insertions(+), 37 deletions(-) diff --git a/_alp/Classes/Class.J_EADieselTractor.java b/_alp/Classes/Class.J_EADieselTractor.java index eb93a8f..b47d26d 100644 --- a/_alp/Classes/Class.J_EADieselTractor.java +++ b/_alp/Classes/Class.J_EADieselTractor.java @@ -1,25 +1,45 @@ import java.util.*; -/** - * J_EADieselTractor - */ public class J_EADieselTractor extends J_EA implements Serializable { - Double[] dieselConsumptionPerWeek; - Double yearlyDieselConsumption_l; - - /** - * Default constructor - */ - public J_EADieselTractor() { - } - + final double[] dieselConsumptionPerWeek_L; + final double workDayStart_h = 6; + final double workDayEnd_h = 17; + /** - * Constructor initializing the fields + * @param parentAgent + * @param yearlyDieselConsumption_l diesel consumption of a single tractor for a whole year + * @param dieselConsumptionPerWeek profile of a year of diesel consumption. + * Usually expressed in L per ha per week for a specific crop or mix of crops. + * For our purpose the unit doesn't matter. + * @param timeStep_h */ - public J_EADieselTractor(Agent parentAgent, Double yearlyDieselConsumption_l, Double[] dieselConsumptionPerWeek, double timeStep_h) { + public J_EADieselTractor(Agent parentAgent, double yearlyDieselConsumption_L, double[] dieselConsumptionPerWeek, double timeStep_h) { + if (parentAgent == null) { + throw new RuntimeException("Diesel tractor missing parent agent"); + } + + if (yearlyDieselConsumption_L <= 100.0) { + throw new RuntimeException( + String.format("Diesel tractor fuel usage conspicuously low: %d L", yearlyDieselConsumption_L) + ); + } + + if (dieselConsumptionPerWeek == null) { + throw new RuntimeException("Tractor diesel consumption profile is null"); + } + + if (dieselConsumptionPerWeek.length != 52) { + throw new RuntimeException( + String.format("Tractor diesel consumption profile has %d weeks instead of 52", dieselConsumptionPerWeek.length) + ); + } + + if (timeStep_h <= 0.0) { + throw new RuntimeException("Tractor timestep is off"); + } + this.parentAgent = parentAgent; - this.yearlyDieselConsumption_l = yearlyDieselConsumption_l; - this.dieselConsumptionPerWeek = dieselConsumptionPerWeek; + this.dieselConsumptionPerWeek_L = calculateDieselConsumptionPerWeek_L(yearlyDieselConsumption_L, dieselConsumptionPerWeek); this.timestep_h = timeStep_h; this.activeConsumptionEnergyCarriers.add(OL_EnergyCarriers.DIESEL); @@ -39,33 +59,55 @@ public void f_updateAllFlows(double t_h) { @Override public void operate(double t_h) { - double timeOfDay = t_h % 24; - if (timeOfDay < 6 || timeOfDay > 17) { + if (!shouldWork(t_h)) { this.flowsMap.clear(); return; } - if (parentAgent instanceof GridConnection) { - if (!((GridConnection)parentAgent).energyModel.b_isWeekday) { - this.flowsMap.clear(); - return; - } - } - // TODO: Extract this calculation from operate and only do this once a week and store dieselPerTimeStep - int week = (int)(t_h / 168); - double weeklyDieselConsumption_l = this.dieselConsumptionPerWeek[week] / Arrays.stream(dieselConsumptionPerWeek).mapToDouble(f -> f.doubleValue()).sum() * this.yearlyDieselConsumption_l; - double weeklyDieselConsumption_kWh = weeklyDieselConsumption_l * 9.7; - int totalWorkTimeSteps = roundToInt(5 * (17 - 6) / this.timestep_h); - double dieselPerTimeStep_kW = weeklyDieselConsumption_l / totalWorkTimeSteps; - this.flowsMap.put(OL_EnergyCarriers.DIESEL, dieselPerTimeStep_kW); - this.energyUse_kW = dieselPerTimeStep_kW; - this.energyUsed_kWh += this.energyUse_kW * this.timestep_h; + double dieselPerTimeStep_L = dieselConsumptionPerTimeStep_L(t_h); + double dieselPerTimeStep_kWh = dieselPerTimeStep_L * 9.7; + + this.flowsMap.put(OL_EnergyCarriers.DIESEL, dieselPerTimeStep_kWh); + this.energyUse_kW = dieselPerTimeStep_kWh / this.timestep_h; + this.energyUsed_kWh += dieselPerTimeStep_kWh; } + private static double[] calculateDieselConsumptionPerWeek_L(double yearlyDieselConsumption_l, double[] weekProfile) { + var profileSum = Arrays.stream(weekProfile).sum(); + + return Arrays.stream(weekProfile) + .map(weekValue -> yearlyDieselConsumption_l * weekValue / profileSum) + .toArray(); + } - @Override - public String toString() { - return super.toString(); + private boolean shouldWork(double currentStep_h) { + return isWorkTime(currentStep_h) && isWorkDay(); + } + + private boolean isWorkTime(double currentStep_h) { + double timeOfDay = currentStep_h % 24; + + return timeOfDay >= workDayStart_h && timeOfDay < workDayEnd_h; + } + + private boolean isWorkDay() { + return ((GridConnection)parentAgent).energyModel.b_isWeekday; + } + + private double workHoursPerWeek() { + return 5 * (workDayEnd_h - workDayStart_h); + } + + private int workTimeStepsPerWeek() { + return roundToInt(workHoursPerWeek() / this.timestep_h); + } + + private double dieselConsumptionPerTimeStep_L(double currentStep_h) { + int week = (int)(currentStep_h / (7 * 24)); + + double thisWeekDieselConsumption_L = this.dieselConsumptionPerWeek_L[week]; + + return thisWeekDieselConsumption_L / workTimeStepsPerWeek(); } /** @@ -73,5 +115,18 @@ public String toString() { * It needs to be changed when this class gets changed */ private static final long serialVersionUID = 1L; +} + + + + + + + + + + + + + -} \ No newline at end of file