From 69368c26767759130b1e864b29742e4921876691 Mon Sep 17 00:00:00 2001 From: GillisHommen Date: Tue, 27 Jan 2026 20:01:49 +0100 Subject: [PATCH 1/9] Refactor of J_EAProfile, J_EAConsumption and J_EAProduction Work in progres... --- Zero_engine.alpx | 25 ++--- .../Agents/GridConnection/Code/Functions.java | 2 +- _alp/Classes/Class.J_EAConsumption.java | 31 ++++--- .../Class.J_EAPetroleumFuelTractor.java | 4 +- _alp/Classes/Class.J_EAProduction.java | 25 ++--- _alp/Classes/Class.J_EAProfile.java | 92 +++++++++++++++---- _alp/Classes/Class.J_ProfilePointer.java | 8 +- 7 files changed, 121 insertions(+), 66 deletions(-) diff --git a/Zero_engine.alpx b/Zero_engine.alpx index fa93de14..e7720227 100644 --- a/Zero_engine.alpx +++ b/Zero_engine.alpx @@ -779,35 +779,26 @@ 1718560423698 - - true + - - diff --git a/_alp/Agents/GridConnection/Code/Functions.java b/_alp/Agents/GridConnection/Code/Functions.java index 0a91a5f1..a7bac78a 100644 --- a/_alp/Agents/GridConnection/Code/Functions.java +++ b/_alp/Agents/GridConnection/Code/Functions.java @@ -178,7 +178,7 @@ c_hydrogenVehicles.forEach(v -> v.f_updateAllFlows()); c_consumptionAssets.forEach(c -> c.f_updateAllFlows()); c_productionAssets.forEach(p -> p.f_updateAllFlows()); -c_profileAssets.forEach(p -> p.f_updateProfileFlows(energyModel.t_h)); +c_profileAssets.forEach(p -> p.f_updateAllFlows()); /*ALCODEEND*/} double f_resetStates() diff --git a/_alp/Classes/Class.J_EAConsumption.java b/_alp/Classes/Class.J_EAConsumption.java index 4ce872f7..aec6e8b4 100644 --- a/_alp/Classes/Class.J_EAConsumption.java +++ b/_alp/Classes/Class.J_EAConsumption.java @@ -1,12 +1,12 @@ /** * J_EAConsumption */ -public class J_EAConsumption extends zero_engine.J_EA implements Serializable { - protected J_ProfilePointer profilePointer; +public class J_EAConsumption extends zero_engine.J_EAProfile implements Serializable { + //protected J_ProfilePointer profilePointer; public double yearlyDemand_kWh; - protected OL_EnergyCarriers energyCarrier; - private double consumptionScaling_fr = 1; - public double loadLoad_kWh = 0; + //protected OL_EnergyCarriers energyCarrier; + //private double consumptionScaling_fr = 1; + //public double loadLoad_kWh = 0; //private J_profilePointer profilePointer; /** * Default constructor @@ -26,14 +26,16 @@ public J_EAConsumption(Agent parentAgent, OL_EnergyAssetType type, String name, this.energyAssetType = type; this.parentAgent = parentAgent; this.yearlyDemand_kWh = yearlyDemand_kWh; + if (profile.getProfileUnits() == OL_ProfileUnits.YEARLYTOTALFRACTION) { + this.profileUnitScaler_r = yearlyDemand_kWh; + this.profilePointer = profile; + } else { + throw new RuntimeException("Invalid OL_ProfileUnits type for J_EAConsumption!"); + } this.energyCarrier = energyCarrier; this.timestep_h = timestep_h; - if (profile == null) { - profilePointer = ((GridConnection)parentAgent).energyModel.f_findProfile(name); - } else { - profilePointer = profile; - } + this.activeConsumptionEnergyCarriers.add(this.energyCarrier); if (this.energyCarrier == OL_EnergyCarriers.ELECTRICITY) { @@ -61,14 +63,15 @@ public String getAssetName() { } public void setConsumptionScaling_fr(double consumptionScaling_fr) { - this.consumptionScaling_fr = consumptionScaling_fr; + this.profileScaling_fr = consumptionScaling_fr; } public double getConsumptionScaling_fr() { - return this.consumptionScaling_fr; + return this.profileScaling_fr; } - @Override + + /*@Override public void f_updateAllFlows(double v_powerFraction_fr) { throw new RuntimeException("J_EAConsumption.f_updateAllFlows() should be called without arguments!"); } @@ -100,7 +103,7 @@ public void operate(double ratioOfCapacity) { if (this.assetFlowCategory != null) { assetFlowsMap.put(this.assetFlowCategory, consumption_kW); } - } + }*/ public J_ProfilePointer getProfilePointer() { return this.profilePointer; diff --git a/_alp/Classes/Class.J_EAPetroleumFuelTractor.java b/_alp/Classes/Class.J_EAPetroleumFuelTractor.java index 1153c925..914e6a14 100644 --- a/_alp/Classes/Class.J_EAPetroleumFuelTractor.java +++ b/_alp/Classes/Class.J_EAPetroleumFuelTractor.java @@ -49,8 +49,8 @@ public J_EAPetroleumFuelTractor(Agent parentAgent, double yearlyPetroleumFuelCon } @Override - public void f_updateProfileFlows(double t_h) { - operate(t_h); + public void f_updateAllFlows() { + operate(((GridConnection)parentAgent).energyModel.t_h); // temporary ugly hack if (parentAgent instanceof GridConnection) { ((GridConnection)parentAgent).f_addFlows(flowsMap, this.energyUse_kW, assetFlowsMap, this); } diff --git a/_alp/Classes/Class.J_EAProduction.java b/_alp/Classes/Class.J_EAProduction.java index 0322c87b..4d5c62a3 100644 --- a/_alp/Classes/Class.J_EAProduction.java +++ b/_alp/Classes/Class.J_EAProduction.java @@ -1,7 +1,7 @@ /** * J_EAProduction */ -public class J_EAProduction extends zero_engine.J_EA implements Serializable { +public class J_EAProduction extends zero_engine.J_EAProfile implements Serializable { protected J_ProfilePointer profilePointer; protected OL_EnergyCarriers energyCarrier = OL_EnergyCarriers.ELECTRICITY; protected double totalEnergyCurtailed_kWh=0; @@ -20,6 +20,17 @@ public J_EAProduction() { public J_EAProduction(Agent parentAgent, OL_EnergyAssetType type, String name, OL_EnergyCarriers energyCarrier, double capacity_kW, double timestep_h, J_ProfilePointer profile) { this.parentAgent = parentAgent; this.energyAssetType = type; + this.energyAssetName = name; + this.energyCarrier = energyCarrier; + this.capacity_kW = capacity_kW; + + if (profile.getProfileUnits() == OL_ProfileUnits.NORMALIZEDPOWER) { + this.profileUnitScaler_r = capacity_kW; + this.profilePointer = profile; + } else { + throw new RuntimeException("Invalid OL_ProfileUnits type for J_EAProduction!"); + } + if (type == OL_EnergyAssetType.PHOTOVOLTAIC) { this.assetFlowCategory = OL_AssetFlowCategories.pvProductionElectric_kW; } else if (type == OL_EnergyAssetType.WINDMILL) { @@ -31,20 +42,10 @@ public J_EAProduction(Agent parentAgent, OL_EnergyAssetType type, String name, O } else { throw new RuntimeException("No valid OL_EnergyAssetType, cannot assign AssetFlowCategory!"); } - this.energyAssetName = name; - this.energyCarrier = energyCarrier; - this.capacity_kW = capacity_kW; this.timestep_h = timestep_h; //this.outputTemperature_degC = outputTemperature_degC; - if (profile == null) { - profilePointer = ((GridConnection)parentAgent).energyModel.f_findProfile(name); - } else { - profilePointer = profile; - } - if (profile == null) { - throw new RuntimeException("J_EAProduction needs to have valid profilePointer!"); - } + this.activeProductionEnergyCarriers.add(this.energyCarrier); registerEnergyAsset(); } diff --git a/_alp/Classes/Class.J_EAProfile.java b/_alp/Classes/Class.J_EAProfile.java index 8c45fe7a..8ca74f8d 100644 --- a/_alp/Classes/Class.J_EAProfile.java +++ b/_alp/Classes/Class.J_EAProfile.java @@ -2,14 +2,15 @@ * J_EAProfile */ public class J_EAProfile extends zero_engine.J_EA implements Serializable { - - public OL_EnergyCarriers energyCarrier = OL_EnergyCarriers.ELECTRICITY; - public double[] a_energyProfile_kWh; - private double profileTimestep_h; - private double profileStarTime_h = 0; - public double lostLoad_kWh = 0; - private double profileScaling_fr = 1; - private boolean enableProfileLooping = true; + protected J_ProfilePointer profilePointer; + protected double profileUnitScaler_r = 4.0; // This factor translates tablefunction data in kWh/qh, normalized power or consumption-fraction into power [kW]. To go from kWh/qh to kW, that is a factor 4. + protected OL_EnergyCarriers energyCarrier; // = OL_EnergyCarriers.ELECTRICITY; + //public double[] a_energyProfile_kWh; + //private double profileTimestep_h; + //private double profileStarTime_h = 0; + protected double lostLoad_kWh = 0; + protected double profileScaling_fr = 1; // This factor can be used to change the magnitude of the profile in this asset, for example when an energy-saving slider is operated. + //private boolean enableProfileLooping = true; /** * Default constructor @@ -20,7 +21,30 @@ public J_EAProfile() { /** * Constructor initializing the fields */ - public J_EAProfile(Agent parentAgent, OL_EnergyCarriers energyCarrier, double[] profile_kWh, OL_AssetFlowCategories assetCategory, double profileTimestep_h) { + /*public J_EAProfile(Agent parentAgent, OL_EnergyCarriers energyCarrier, double[] profile_kWh, OL_AssetFlowCategories assetCategory, double profileTimestep_h, double startTime_h) { + this(parentAgent, energyCarrier, profile_kWh, assetCategory, profileTimestep_h); + this.profileStarTime_h = startTime_h; + }*/ + + public J_EAProfile(Agent parentAgent, OL_EnergyCarriers energyCarrier, J_ProfilePointer profile, OL_AssetFlowCategories assetCategory, double timeStep_h) { + this.parentAgent= parentAgent; + this.energyCarrier = energyCarrier; + if (profile == null) { + throw new RuntimeException("Cannot create J_EAProfile without a valid ProfilePointer!"); + } else { + profilePointer = profile; + } + this.assetFlowCategory = assetCategory; + + this.timestep_h = timeStep_h; + + this.activeConsumptionEnergyCarriers.add(this.energyCarrier); + + registerEnergyAsset(); + } + + + /*public J_EAProfile(Agent parentAgent, OL_EnergyCarriers energyCarrier, double[] profile_kWh, OL_AssetFlowCategories assetCategory, double profileTimestep_h) { this.parentAgent= parentAgent; this.energyCarrier = energyCarrier; this.a_energyProfile_kWh = profile_kWh; @@ -41,25 +65,55 @@ public J_EAProfile(Agent parentAgent, OL_EnergyCarriers energyCarrier, double[] public void setStartTime_h(double startTime_h) { this.profileStarTime_h = startTime_h; - } + }*/ @Override public void f_updateAllFlows(double powerFraction_fr) { throw new RuntimeException("J_EAProfile.f_updateAllFlows(powerFraction_fr) not supperted for J_EAProfile! Use J_EAProfile.f_updateProfileFlows(t_h) instead!"); } - public void f_updateProfileFlows(double time_h) { + public void f_updateAllFlows() { + //operate(time_h-this.profileStarTime_h); + double profileValue = profilePointer.getCurrentValue(); + + double currentPower_kW = profileValue * this.profileUnitScaler_r * this.profileScaling_fr; + + this.energyUse_kW = currentPower_kW; + this.energyUsed_kWh += this.energyUse_kW * this.timestep_h; - operate(time_h-this.profileStarTime_h); + flowsMap.put(this.energyCarrier, currentPower_kW); + if (this.assetFlowCategory != null) { + assetFlowsMap.put(this.assetFlowCategory, currentPower_kW); + } + + //this.operate(ratioOfCapacity); + if (currentPower_kW==0.0) { // Skip when there is no consumption -> saves time? + if (parentAgent instanceof GridConnection) { + //((GridConnection)parentAgent).f_addFlows(arr, this); + ((GridConnection)parentAgent).f_addFlows(flowsMap, this.energyUse_kW, assetFlowsMap, this); + } - if (parentAgent instanceof GridConnection) { - ((GridConnection)parentAgent).f_addFlows(flowsMap, this.energyUse_kW, assetFlowsMap, this); - } - this.lastFlowsMap.cloneMap(flowsMap); + } + this.lastFlowsMap.cloneMap(this.flowsMap); this.lastEnergyUse_kW = this.energyUse_kW; this.clear(); } + @Override + public void operate(double ratioOfCapacity) { + /* + double currentPower_kW = ratioOfCapacity * this.yearlyDemand_kWh * this.consumptionScaling_fr; + + this.energyUse_kW = currentPower_kW; + this.energyUsed_kWh += this.energyUse_kW * this.timestep_h; + + flowsMap.put(this.energyCarrier, currentPower_kW); + if (this.assetFlowCategory != null) { + assetFlowsMap.put(this.assetFlowCategory, currentPower_kW); + }*/ + } + + /* Old J_EAProfile implementation @Override public void operate(double time_h) { if (enableProfileLooping && time_h >= a_energyProfile_kWh.length * profileTimestep_h) { @@ -81,7 +135,7 @@ public void operate(double time_h) { if (this.assetFlowCategory != null) { this.assetFlowsMap.put(this.assetFlowCategory, currentPower_kW); } - } + } */ public double getEnergyUsed_kWh() { return energyUsed_kWh; @@ -105,8 +159,8 @@ public void curtailElectricityConsumption(double curtailmentSetpoint_kW) { if (parentAgent instanceof GridConnection) { ((GridConnection)parentAgent).f_removeFlows(flowsMap, this.energyUse_kW, assetFlows_kW, this); } - } - + } + public double getProfileScaling_fr() { return profileScaling_fr; } diff --git a/_alp/Classes/Class.J_ProfilePointer.java b/_alp/Classes/Class.J_ProfilePointer.java index f17da140..4ff55da9 100644 --- a/_alp/Classes/Class.J_ProfilePointer.java +++ b/_alp/Classes/Class.J_ProfilePointer.java @@ -19,6 +19,7 @@ public class J_ProfilePointer implements Serializable { public String name = ""; private double currentValue = 0; private TableFunction tableFunction; + private OL_ProfileUnits profileUnits; /** * Default constructor @@ -27,9 +28,10 @@ public J_ProfilePointer() { } - public J_ProfilePointer(String name, TableFunction tableFunction) { + public J_ProfilePointer(String name, TableFunction tableFunction, OL_ProfileUnits profileUnits) { this.name = name; this.tableFunction = tableFunction; + this.profileUnits = profileUnits; } public void updateValue(double t_h) { @@ -56,6 +58,10 @@ public void setTableFunction(TableFunction tf) { this.tableFunction = tf; } + public OL_ProfileUnits getProfileUnits() { + return profileUnits; + } + @Override public String toString() { return "profile: " + this.name + " current value: " + this.currentValue; From 3070dcd72a36219870e78e973496ee04f84d1e9a Mon Sep 17 00:00:00 2001 From: GillisHommen Date: Thu, 29 Jan 2026 09:53:10 +0100 Subject: [PATCH 2/9] Intermediate save, engine compiles --- Zero_engine.alpx | 4 +++ ..._BatteryManagementPeakShavingForecast.java | 11 ++++--- _alp/Classes/Class.J_EAProfile.java | 32 +++++++++++++++++-- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/Zero_engine.alpx b/Zero_engine.alpx index e7720227..5394479f 100644 --- a/Zero_engine.alpx +++ b/Zero_engine.alpx @@ -800,6 +800,10 @@ 1769528326971 + 1722411204920 diff --git a/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java b/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java index 97a2fc45..465461d9 100644 --- a/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java +++ b/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java @@ -90,7 +90,8 @@ private double[] getNettoBalanceForecast_kW() { for(J_EAProfile elecConsumptionProfile : elecConsumptionProfiles) { if(elecConsumptionProfile != null){ - double[] tempNettoBalance_kW = ZeroMath.arrayMultiply(Arrays.copyOfRange(elecConsumptionProfile.a_energyProfile_kWh, startTimeDayIndex, endTimeDayIndex), elecConsumptionProfile.getProfileScaling_fr()/p_timestep_h); + //double[] tempNettoBalance_kW = ZeroMath.arrayMultiply(Arrays.copyOfRange(elecConsumptionProfile.a_energyProfile_kWh, startTimeDayIndex, endTimeDayIndex), elecConsumptionProfile.getProfileScaling_fr()/p_timestep_h); + double[] tempNettoBalance_kW = ZeroMath.arrayMultiply(Arrays.copyOfRange(elecConsumptionProfile.profilePointer.getAllValues(), startTimeDayIndex, endTimeDayIndex), elecConsumptionProfile.getProfileScaling_fr()*elecConsumptionProfile.getProfileUnitScaler_fr()/p_timestep_h); for (int i = 0; i < tempNettoBalance_kW.length; i++) { nettoBalanceTotal_kW[i] += tempNettoBalance_kW[i]; } @@ -98,7 +99,8 @@ private double[] getNettoBalanceForecast_kW() { } for(J_EAProfile elecHeatPumpProfile : elecHeatPumpProfiles) { if(elecHeatPumpProfile != null){ - double[] tempNettoBalance_kW = ZeroMath.arrayMultiply(Arrays.copyOfRange(elecHeatPumpProfile.a_energyProfile_kWh, startTimeDayIndex, endTimeDayIndex), elecHeatPumpProfile.getProfileScaling_fr()/p_timestep_h); + //double[] tempNettoBalance_kW = ZeroMath.arrayMultiply(Arrays.copyOfRange(elecHeatPumpProfile.a_energyProfile_kWh, startTimeDayIndex, endTimeDayIndex), elecHeatPumpProfile.getProfileScaling_fr()/p_timestep_h); + double[] tempNettoBalance_kW = ZeroMath.arrayMultiply(Arrays.copyOfRange(elecHeatPumpProfile.profilePointer.getAllValues(), startTimeDayIndex, endTimeDayIndex), elecHeatPumpProfile.getProfileScaling_fr()*elecHeatPumpProfile.getProfileUnitScaler_fr()); for (int i = 0; i < tempNettoBalance_kW.length; i++) { nettoBalanceTotal_kW[i] += tempNettoBalance_kW[i]; } @@ -106,7 +108,7 @@ private double[] getNettoBalanceForecast_kW() { } for(J_EAProfile elecEVProfile : elecEVProfiles) { if(elecEVProfile != null){ - double[] tempNettoBalance_kW = ZeroMath.arrayMultiply(Arrays.copyOfRange(elecEVProfile.a_energyProfile_kWh, startTimeDayIndex, endTimeDayIndex), elecEVProfile.getProfileScaling_fr()/p_timestep_h); + double[] tempNettoBalance_kW = ZeroMath.arrayMultiply(Arrays.copyOfRange(elecEVProfile.profilePointer.getAllValues(), startTimeDayIndex, endTimeDayIndex), elecEVProfile.getProfileScaling_fr()*elecEVProfile.getProfileUnitScaler_fr()); for (int i = 0; i < tempNettoBalance_kW.length; i++) { nettoBalanceTotal_kW[i] += tempNettoBalance_kW[i]; } @@ -114,7 +116,8 @@ private double[] getNettoBalanceForecast_kW() { } for(J_EAProfile surveyHeatDemandProfile : surveyHeatDemandProfiles) { if(surveyHeatDemandProfile != null){ - double[] heatPower_kW = ZeroMath.arrayMultiply(Arrays.copyOfRange(surveyHeatDemandProfile.a_energyProfile_kWh, startTimeDayIndex, endTimeDayIndex), surveyHeatDemandProfile.getProfileScaling_fr()/p_timestep_h); + //double[] heatPower_kW = ZeroMath.arrayMultiply(Arrays.copyOfRange(surveyHeatDemandProfile.a_energyProfile_kWh, startTimeDayIndex, endTimeDayIndex), surveyHeatDemandProfile.getProfileScaling_fr()/p_timestep_h); + double[] heatPower_kW = ZeroMath.arrayMultiply(Arrays.copyOfRange(surveyHeatDemandProfile.profilePointer.getAllValues(), startTimeDayIndex, endTimeDayIndex), surveyHeatDemandProfile.getProfileScaling_fr()*surveyHeatDemandProfile.getProfileUnitScaler_fr()); //traceln(heatPower_kW); double eta_r = parentGC.energyModel.avgc_data.p_avgEfficiencyHeatpump_fr; double outputTemperature_degC = parentGC.energyModel.avgc_data.p_avgOutputTemperatureElectricHeatpump_degC; diff --git a/_alp/Classes/Class.J_EAProfile.java b/_alp/Classes/Class.J_EAProfile.java index 8ca74f8d..80f9c291 100644 --- a/_alp/Classes/Class.J_EAProfile.java +++ b/_alp/Classes/Class.J_EAProfile.java @@ -1,3 +1,4 @@ +import zeroPackage.ZeroMath; /** * J_EAProfile */ @@ -33,6 +34,13 @@ public J_EAProfile(Agent parentAgent, OL_EnergyCarriers energyCarrier, J_Profile throw new RuntimeException("Cannot create J_EAProfile without a valid ProfilePointer!"); } else { profilePointer = profile; + if (profilePointer.getProfileUnits() == OL_ProfileUnits.KWHPQUARTERHOUR) { + profileUnitScaler_r = 4.0; + } else if (profilePointer.getProfileUnits() == OL_ProfileUnits.KW) { + profileUnitScaler_r = 1.0; + } else { + throw new RuntimeException("Unsupported ProfileUnits of profilePointer for J_EAProfile!"); + } } this.assetFlowCategory = assetCategory; @@ -161,14 +169,34 @@ public void curtailElectricityConsumption(double curtailmentSetpoint_kW) { } } + public double getProfileUnitScaler_fr() { + return this.profileUnitScaler_r; + } + public double getProfileScaling_fr() { - return profileScaling_fr; + return this.profileScaling_fr; } public void setProfileScaling_fr( double scaling_fr ) { this.profileScaling_fr = scaling_fr; } + public double getPeakPower_kW() { + return max(profilePointer.getAllValues()) * this.profileUnitScaler_r * this.profileScaling_fr; + } + + public double getBaseConsumption_kWh() { + double[] values = profilePointer.getAllValues(); + double[] arguments = profilePointer.getTableFunction().getArguments(); + double dataTimeStep_h = (arguments[arguments.length-1] - arguments[0])/arguments.length; + double baseConsumption_kWh = ZeroMath.arraySumPos(values) * dataTimeStep_h * this.profileUnitScaler_r; + return baseConsumption_kWh; + } + + public double getTotalConsumption_kWh() { + return this.getBaseConsumption_kWh() * this.profileScaling_fr; + } + public OL_EnergyCarriers getEnergyCarrier() { return this.energyCarrier; } @@ -177,7 +205,7 @@ public OL_EnergyCarriers getEnergyCarrier() { public String toString() { return "parentAgent = " + parentAgent +", Energy consumed = " + this.energyUsed_kWh + - "energyUsed_kWh (losses) = " + this.energyUsed_kWh + " "; + "assetFlowCategory = " + this.assetFlowCategory + " "; } /** From b0bf362188f694bb18926c1bb23cd899b0b3f5da Mon Sep 17 00:00:00 2001 From: GillisHommen Date: Thu, 29 Jan 2026 10:32:17 +0100 Subject: [PATCH 3/9] Updates to J_EAProfile, J_EAConsumption and J_EAProduction --- .../Class.J_BatteryManagementPeakShavingForecast.java | 4 ++-- _alp/Classes/Class.J_EAConsumption.java | 11 ++++++----- _alp/Classes/Class.J_EAProduction.java | 9 +++++---- _alp/Classes/Class.J_EAProfile.java | 6 +----- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java b/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java index 465461d9..9b85267e 100644 --- a/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java +++ b/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java @@ -139,14 +139,14 @@ private double[] getNettoBalanceForecast_kW() { double COP_r = eta_r * ( 273.15 + outputTemperature_degC ) / ( outputTemperature_degC - baseTemperature_degC ); //traceln(genericHeatDemandProfile.getProfilePointer().getValue(time)*genericHeatDemandProfile.yearlyDemand_kWh); - nettoBalanceTotal_kW[roundToInt((time-energyModel_time_h)/p_timestep_h)] += genericHeatDemandProfile.getProfilePointer().getValue(time)*genericHeatDemandProfile.yearlyDemand_kWh*genericHeatDemandProfile.getConsumptionScaling_fr() / COP_r; + nettoBalanceTotal_kW[roundToInt((time-energyModel_time_h)/p_timestep_h)] += genericHeatDemandProfile.getProfilePointer().getValue(time)*genericHeatDemandProfile.getYearlyDemand_kWh()*genericHeatDemandProfile.getConsumptionScaling_fr() / COP_r; } } } for(J_EAConsumption genericBuildingProfile : genericBuildingProfiles) { if(genericBuildingProfile != null){ //table function for(double time = energyModel_time_h; time < energyModel_time_h + 24; time += p_timestep_h){ - nettoBalanceTotal_kW[roundToInt((time-energyModel_time_h)/p_timestep_h)] += genericBuildingProfile.getProfilePointer().getValue(time)*genericBuildingProfile.yearlyDemand_kWh*genericBuildingProfile.getConsumptionScaling_fr(); + nettoBalanceTotal_kW[roundToInt((time-energyModel_time_h)/p_timestep_h)] += genericBuildingProfile.getProfilePointer().getValue(time)*genericBuildingProfile.getYearlyDemand_kWh()*genericBuildingProfile.getConsumptionScaling_fr(); } } } diff --git a/_alp/Classes/Class.J_EAConsumption.java b/_alp/Classes/Class.J_EAConsumption.java index aec6e8b4..69eb066c 100644 --- a/_alp/Classes/Class.J_EAConsumption.java +++ b/_alp/Classes/Class.J_EAConsumption.java @@ -2,12 +2,9 @@ * J_EAConsumption */ public class J_EAConsumption extends zero_engine.J_EAProfile implements Serializable { - //protected J_ProfilePointer profilePointer; - public double yearlyDemand_kWh; - //protected OL_EnergyCarriers energyCarrier; - //private double consumptionScaling_fr = 1; + + private double yearlyDemand_kWh; //public double loadLoad_kWh = 0; - //private J_profilePointer profilePointer; /** * Default constructor */ @@ -109,6 +106,10 @@ public J_ProfilePointer getProfilePointer() { return this.profilePointer; } + public double getYearlyDemand_kWh() { + return yearlyDemand_kWh; + } + @Override public String toString() { return diff --git a/_alp/Classes/Class.J_EAProduction.java b/_alp/Classes/Class.J_EAProduction.java index 4d5c62a3..25250642 100644 --- a/_alp/Classes/Class.J_EAProduction.java +++ b/_alp/Classes/Class.J_EAProduction.java @@ -2,8 +2,8 @@ * J_EAProduction */ public class J_EAProduction extends zero_engine.J_EAProfile implements Serializable { - protected J_ProfilePointer profilePointer; - protected OL_EnergyCarriers energyCarrier = OL_EnergyCarriers.ELECTRICITY; + //protected J_ProfilePointer profilePointer; + //protected OL_EnergyCarriers energyCarrier = OL_EnergyCarriers.ELECTRICITY; protected double totalEnergyCurtailed_kWh=0; //protected double outputTemperature_degC; protected double capacity_kW; @@ -98,7 +98,7 @@ public String getName() { } @Override - public void operate(double ratioOfCapacity) { + public void operate(double ratioOfCapacity) { ratioOfCapacity = profilePointer.getCurrentValue(); //if (ratioOfCapacity>0.0) { // Skip when there is no production -> saves time? @@ -112,6 +112,7 @@ public void operate(double ratioOfCapacity) { throw new RuntimeException("J_EAProduction operate override is called!"); } + /* @Override public void f_updateAllFlows(double v_powerFraction_fr) { throw new RuntimeException("J_EAProduction.f_updateAllFlows() should be called without arguments!"); @@ -136,7 +137,7 @@ public void f_updateAllFlows() { this.lastFlowsMap.cloneMap(this.flowsMap); this.lastEnergyUse_kW = this.energyUse_kW; this.clear(); - } + }*/ public double curtailEnergyCarrierProduction(OL_EnergyCarriers curtailedEnergyCarrier, double curtailmentAmount_kW) { // The curtailment setpoint is the requested amount of curtailment; requested reduction of production. (which may or may not be provided, depending on what the current production is) diff --git a/_alp/Classes/Class.J_EAProfile.java b/_alp/Classes/Class.J_EAProfile.java index 80f9c291..eb73358b 100644 --- a/_alp/Classes/Class.J_EAProfile.java +++ b/_alp/Classes/Class.J_EAProfile.java @@ -81,9 +81,7 @@ public void f_updateAllFlows(double powerFraction_fr) { } public void f_updateAllFlows() { - //operate(time_h-this.profileStarTime_h); double profileValue = profilePointer.getCurrentValue(); - double currentPower_kW = profileValue * this.profileUnitScaler_r * this.profileScaling_fr; this.energyUse_kW = currentPower_kW; @@ -95,12 +93,10 @@ public void f_updateAllFlows() { } //this.operate(ratioOfCapacity); - if (currentPower_kW==0.0) { // Skip when there is no consumption -> saves time? + if (currentPower_kW!=0.0) { // Skip when there is no consumption -> saves time? if (parentAgent instanceof GridConnection) { - //((GridConnection)parentAgent).f_addFlows(arr, this); ((GridConnection)parentAgent).f_addFlows(flowsMap, this.energyUse_kW, assetFlowsMap, this); } - } this.lastFlowsMap.cloneMap(this.flowsMap); this.lastEnergyUse_kW = this.energyUse_kW; From b5511cfa50f55d787e8560249d20b27923e7b7aa Mon Sep 17 00:00:00 2001 From: GillisHommen Date: Thu, 29 Jan 2026 11:21:22 +0100 Subject: [PATCH 4/9] Fixes after update from main J_EAProfile, J_EAConsumption and J_EAProduction manually 'ported' to new structure. --- ..._BatteryManagementPeakShavingForecast.java | 2 +- _alp/Classes/Class.J_EAConsumption.java | 15 ++--- _alp/Classes/Class.J_EAProduction.java | 61 +++++++++---------- _alp/Classes/Class.J_EAProfile.java | 56 ++++++++--------- 4 files changed, 66 insertions(+), 68 deletions(-) diff --git a/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java b/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java index 3c1b1c19..20385450 100644 --- a/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java +++ b/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java @@ -145,7 +145,7 @@ private double[] getNettoBalanceForecast_kW(J_TimeVariables timeVariables) { } for(J_EAConsumption genericBuildingProfile : genericBuildingProfiles) { if(genericBuildingProfile != null){ //table function - for(double time = energyModel_time_h; time < energyModel_time_h + 24; time += p_timestep_h){ + for(double time = energyModel_time_h; time < energyModel_time_h + 24; time += timeParameters.getTimeStep_h()){ nettoBalanceTotal_kW[roundToInt((time-energyModel_time_h)/timeParameters.getTimeStep_h())] += genericBuildingProfile.getProfilePointer().getValue(time)*genericBuildingProfile.getYearlyDemand_kWh()*genericBuildingProfile.getConsumptionScaling_fr(); } } diff --git a/_alp/Classes/Class.J_EAConsumption.java b/_alp/Classes/Class.J_EAConsumption.java index 69eb066c..43b9b75f 100644 --- a/_alp/Classes/Class.J_EAConsumption.java +++ b/_alp/Classes/Class.J_EAConsumption.java @@ -14,14 +14,16 @@ public J_EAConsumption() { /** * Constructor initializing the fields */ - public J_EAConsumption(Agent parentAgent, OL_EnergyAssetType type, String name, double yearlyDemand_kWh, OL_EnergyCarriers energyCarrier, double timestep_h, J_ProfilePointer profile) { + public J_EAConsumption(I_AssetOwner owner, OL_EnergyAssetType type, String name, double yearlyDemand_kWh, OL_EnergyCarriers energyCarrier, J_TimeParameters timeParameters, J_ProfilePointer profile) { /*if (yearlyDemand_kWh == 0.0) { throw new RuntimeException("Unable to construct J_EAConsumption: " + name + " because consumption is zero." ); }*/ - + this.setOwner(owner); + this.timeParameters = timeParameters; + this.energyAssetName = name; this.energyAssetType = type; - this.parentAgent = parentAgent; + this.yearlyDemand_kWh = yearlyDemand_kWh; if (profile.getProfileUnits() == OL_ProfileUnits.YEARLYTOTALFRACTION) { this.profileUnitScaler_r = yearlyDemand_kWh; @@ -31,8 +33,7 @@ public J_EAConsumption(Agent parentAgent, OL_EnergyAssetType type, String name, } this.energyCarrier = energyCarrier; - this.timestep_h = timestep_h; - + this.activeConsumptionEnergyCarriers.add(this.energyCarrier); if (this.energyCarrier == OL_EnergyCarriers.ELECTRICITY) { @@ -52,7 +53,7 @@ else if (this.energyCarrier == OL_EnergyCarriers.HEAT) { } } - registerEnergyAsset(); + registerEnergyAsset(timeParameters); } public String getAssetName() { @@ -114,7 +115,7 @@ public double getYearlyDemand_kWh() { public String toString() { return "type = " + this.getClass().toString() + " " + - "parentAgent = " + this.parentAgent +" " + + "owner = " + this.getOwner() +" " + "energyCarrier = " + this.energyCarrier + " " + "yearlyDemand_kWh = " + this.yearlyDemand_kWh; } diff --git a/_alp/Classes/Class.J_EAProduction.java b/_alp/Classes/Class.J_EAProduction.java index 25250642..c86317aa 100644 --- a/_alp/Classes/Class.J_EAProduction.java +++ b/_alp/Classes/Class.J_EAProduction.java @@ -17,8 +17,9 @@ public J_EAProduction() { /** * Constructor initializing the fields */ - public J_EAProduction(Agent parentAgent, OL_EnergyAssetType type, String name, OL_EnergyCarriers energyCarrier, double capacity_kW, double timestep_h, J_ProfilePointer profile) { - this.parentAgent = parentAgent; + public J_EAProduction(Agent parentAgent, OL_EnergyAssetType type, String name, OL_EnergyCarriers energyCarrier, double capacity_kW, J_TimeParameters timeParameters, J_ProfilePointer profile) { + I_AssetOwner owner; + this.timeParameters = timeParameters; this.energyAssetType = type; this.energyAssetName = name; this.energyCarrier = energyCarrier; @@ -43,32 +44,29 @@ public J_EAProduction(Agent parentAgent, OL_EnergyAssetType type, String name, O throw new RuntimeException("No valid OL_EnergyAssetType, cannot assign AssetFlowCategory!"); } - this.timestep_h = timestep_h; - //this.outputTemperature_degC = outputTemperature_degC; - this.activeProductionEnergyCarriers.add(this.energyCarrier); - registerEnergyAsset(); + registerEnergyAsset(timeParameters); } - public void setCapacityElectric_kW(double capacityElectric_kW) { + public void setCapacityElectric_kW(double capacityElectric_kW, GridConnection gc) { // Calculate the difference with the set and the previous capacity to update totals in GC, GN and EnergyModel if (energyCarrier == OL_EnergyCarriers.ELECTRICITY) { double difference_kW = capacityElectric_kW - this.capacity_kW; - if (this.energyAssetType == OL_EnergyAssetType.WINDMILL && this.parentAgent instanceof GridConnection) { - ((GridConnection) this.parentAgent).v_liveAssetsMetaData.totalInstalledWindPower_kW += difference_kW; - if (((GridConnection) this.parentAgent).p_parentNodeElectric != null) { - ((GridConnection) this.parentAgent).p_parentNodeElectric.f_updateTotalInstalledProductionAssets(OL_EnergyAssetType.WINDMILL, difference_kW, true); + if (this.energyAssetType == OL_EnergyAssetType.WINDMILL) { + gc.v_liveAssetsMetaData.totalInstalledWindPower_kW += difference_kW; + if (gc.p_parentNodeElectric != null) { + gc.p_parentNodeElectric.f_updateTotalInstalledProductionAssets(OL_EnergyAssetType.WINDMILL, difference_kW, true); } - ((GridConnection) this.parentAgent).c_parentCoops.forEach( coop -> coop.v_liveAssetsMetaData.totalInstalledWindPower_kW += difference_kW); - ((GridConnection) this.parentAgent).energyModel.v_liveAssetsMetaData.totalInstalledWindPower_kW += difference_kW; + gc.c_parentCoops.forEach( coop -> coop.v_liveAssetsMetaData.totalInstalledWindPower_kW += difference_kW); + gc.energyModel.v_liveAssetsMetaData.totalInstalledWindPower_kW += difference_kW; } - else if (this.energyAssetType == OL_EnergyAssetType.PHOTOVOLTAIC && this.parentAgent instanceof GridConnection) { - ((GridConnection) this.parentAgent).v_liveAssetsMetaData.totalInstalledPVPower_kW += difference_kW; - if (((GridConnection) this.parentAgent).p_parentNodeElectric != null) { - ((GridConnection) this.parentAgent).p_parentNodeElectric.f_updateTotalInstalledProductionAssets(OL_EnergyAssetType.PHOTOVOLTAIC, difference_kW, true); + else if (this.energyAssetType == OL_EnergyAssetType.PHOTOVOLTAIC) { + gc.v_liveAssetsMetaData.totalInstalledPVPower_kW += difference_kW; + if (gc.p_parentNodeElectric != null) { + gc.p_parentNodeElectric.f_updateTotalInstalledProductionAssets(OL_EnergyAssetType.PHOTOVOLTAIC, difference_kW, true); } - ((GridConnection) this.parentAgent).c_parentCoops.forEach( coop -> coop.v_liveAssetsMetaData.totalInstalledPVPower_kW += difference_kW); - ((GridConnection) this.parentAgent).energyModel.v_liveAssetsMetaData.totalInstalledPVPower_kW += difference_kW; + gc.c_parentCoops.forEach( coop -> coop.v_liveAssetsMetaData.totalInstalledPVPower_kW += difference_kW); + gc.energyModel.v_liveAssetsMetaData.totalInstalledPVPower_kW += difference_kW; } this.capacity_kW = capacityElectric_kW; @@ -98,7 +96,8 @@ public String getName() { } @Override - public void operate(double ratioOfCapacity) { + public void operate(J_TimeVariables timeVariables) { + /* ratioOfCapacity = profilePointer.getCurrentValue(); //if (ratioOfCapacity>0.0) { // Skip when there is no production -> saves time? @@ -110,6 +109,7 @@ public void operate(double ratioOfCapacity) { this.assetFlowsMap.put(this.assetFlowCategory, currentProduction_kW); //} throw new RuntimeException("J_EAProduction operate override is called!"); + */ } /* @@ -139,17 +139,17 @@ public void f_updateAllFlows() { this.clear(); }*/ - public double curtailEnergyCarrierProduction(OL_EnergyCarriers curtailedEnergyCarrier, double curtailmentAmount_kW) { // The curtailment setpoint is the requested amount of curtailment; requested reduction of production. (which may or may not be provided, depending on what the current production is) + public double curtailEnergyCarrierProduction(OL_EnergyCarriers curtailedEnergyCarrier, double curtailmentAmount_kW, GridConnection gc) { // The curtailment setpoint is the requested amount of curtailment; requested reduction of production. (which may or may not be provided, depending on what the current production is) if(this.energyCarrier != curtailedEnergyCarrier) { //new RuntimeException("Trying to curtail the wrong a production asset with the wrong energyCarrier"); return 0; } - double currentProduction_kW = -this.lastFlowsMap.get(curtailedEnergyCarrier); + double currentProduction_kW = -this.lastFlowsMap.get(curtailedEnergyCarrier ); double curtailmentPower_kW = max(0,min(currentProduction_kW, curtailmentAmount_kW)); // Can only curtail what was produced in the first place. - energyUsed_kWh += curtailmentPower_kW * timestep_h; // energyUsed_kWh is negative for production assets. Curtailment makes it 'less negative', so a positive number is added to energyUsed_kWh. - this.totalEnergyCurtailed_kWh += curtailmentPower_kW * timestep_h; + energyUsed_kWh += curtailmentPower_kW * this.timeParameters.getTimeStep_h(); // energyUsed_kWh is negative for production assets. Curtailment makes it 'less negative', so a positive number is added to energyUsed_kWh. + this.totalEnergyCurtailed_kWh += curtailmentPower_kW * this.timeParameters.getTimeStep_h(); J_FlowsMap curtailmentFlow = new J_FlowsMap(); curtailmentFlow.put(curtailedEnergyCarrier, -curtailmentPower_kW); // To remove production, a negative flow must be removed. Thus this flowmap with a negative flow will be sent to GC.f_removeFlows() J_ValueMap assetFlows_kW = new J_ValueMap(OL_AssetFlowCategories.class); @@ -159,9 +159,9 @@ public void f_updateAllFlows() { this.lastEnergyUse_kW += curtailmentPower_kW; // production is a negative flow, so to remove production, a positive value must be added to lastEnergyUse_kW. //traceln("Electricity production of asset %s curtailed by %s kW!", this, curtailmentPower_kW); - if (parentAgent instanceof GridConnection) { - ((GridConnection)parentAgent).f_removeFlows(curtailmentFlow, curtailedEnergyUse_kW, assetFlows_kW, this); - } + + gc.f_removeFlows(curtailmentFlow, curtailedEnergyUse_kW, assetFlows_kW, this); + clear(); return curtailmentPower_kW; @@ -185,16 +185,13 @@ public void storeStatesAndReset() { public String toString() { return "type = " + this.getClass().toString() + " " + - "parentAgent = " + parentAgent +" " + + "owner = " + this.getOwner() +" " + "capacity_kW = " + capacity_kW +" "+ "energyCarrier = " + energyCarrier +" "+ "energyProduced_kWh = " + (-this.energyUsed_kWh) + " "; } - public String getOwnerAgent() { - return parentAgent.agentInfo(); - } - + /*public double getCurrentTemperature() { return outputTemperature_degC; }*/ diff --git a/_alp/Classes/Class.J_EAProfile.java b/_alp/Classes/Class.J_EAProfile.java index eb73358b..bd3ecbe3 100644 --- a/_alp/Classes/Class.J_EAProfile.java +++ b/_alp/Classes/Class.J_EAProfile.java @@ -2,7 +2,7 @@ /** * J_EAProfile */ -public class J_EAProfile extends zero_engine.J_EA implements Serializable { +public class J_EAProfile extends zero_engine.J_EAFixed implements Serializable { protected J_ProfilePointer profilePointer; protected double profileUnitScaler_r = 4.0; // This factor translates tablefunction data in kWh/qh, normalized power or consumption-fraction into power [kW]. To go from kWh/qh to kW, that is a factor 4. protected OL_EnergyCarriers energyCarrier; // = OL_EnergyCarriers.ELECTRICITY; @@ -27,8 +27,8 @@ public J_EAProfile() { this.profileStarTime_h = startTime_h; }*/ - public J_EAProfile(Agent parentAgent, OL_EnergyCarriers energyCarrier, J_ProfilePointer profile, OL_AssetFlowCategories assetCategory, double timeStep_h) { - this.parentAgent= parentAgent; + public J_EAProfile(I_AssetOwner owner, OL_EnergyCarriers energyCarrier, J_ProfilePointer profile, OL_AssetFlowCategories assetCategory, J_TimeParameters timeParameters) { + this.setOwner(owner); this.energyCarrier = energyCarrier; if (profile == null) { throw new RuntimeException("Cannot create J_EAProfile without a valid ProfilePointer!"); @@ -43,12 +43,10 @@ public J_EAProfile(Agent parentAgent, OL_EnergyCarriers energyCarrier, J_Profile } } this.assetFlowCategory = assetCategory; - - this.timestep_h = timeStep_h; this.activeConsumptionEnergyCarriers.add(this.energyCarrier); - registerEnergyAsset(); + registerEnergyAsset(timeParameters); } @@ -74,37 +72,41 @@ public J_EAProfile(Agent parentAgent, OL_EnergyCarriers energyCarrier, J_Profile public void setStartTime_h(double startTime_h) { this.profileStarTime_h = startTime_h; }*/ - - @Override - public void f_updateAllFlows(double powerFraction_fr) { - throw new RuntimeException("J_EAProfile.f_updateAllFlows(powerFraction_fr) not supperted for J_EAProfile! Use J_EAProfile.f_updateProfileFlows(t_h) instead!"); - } - public void f_updateAllFlows() { + public J_FlowPacket f_updateAllFlows(J_TimeVariables timeVariables) { double profileValue = profilePointer.getCurrentValue(); double currentPower_kW = profileValue * this.profileUnitScaler_r * this.profileScaling_fr; this.energyUse_kW = currentPower_kW; - this.energyUsed_kWh += this.energyUse_kW * this.timestep_h; + this.energyUsed_kWh += this.energyUse_kW * this.timeParameters.getTimeStep_h(); flowsMap.put(this.energyCarrier, currentPower_kW); if (this.assetFlowCategory != null) { assetFlowsMap.put(this.assetFlowCategory, currentPower_kW); } - - //this.operate(ratioOfCapacity); - if (currentPower_kW!=0.0) { // Skip when there is no consumption -> saves time? - if (parentAgent instanceof GridConnection) { - ((GridConnection)parentAgent).f_addFlows(flowsMap, this.energyUse_kW, assetFlowsMap, this); - } - } + J_FlowsMap flowsMapCopy = new J_FlowsMap(); + J_ValueMap assetFlowsMapCopy = new J_ValueMap(OL_AssetFlowCategories.class); + J_FlowPacket flowPacket = new J_FlowPacket(flowsMapCopy.cloneMap(this.flowsMap), this.energyUse_kW, assetFlowsMapCopy.cloneMap(this.assetFlowsMap)); this.lastFlowsMap.cloneMap(this.flowsMap); this.lastEnergyUse_kW = this.energyUse_kW; this.clear(); + return flowPacket; } + /* + public J_FlowPacket f_updateAllFlows(J_TimeVariables timeVariables) { + operate(timeVariables); + J_FlowsMap flowsMapCopy = new J_FlowsMap(); + J_ValueMap assetFlowsMapCopy = new J_ValueMap(OL_AssetFlowCategories.class); + J_FlowPacket flowPacket = new J_FlowPacket(flowsMapCopy.cloneMap(this.flowsMap), this.energyUse_kW, assetFlowsMapCopy.cloneMap(this.assetFlowsMap)); + this.lastFlowsMap.cloneMap(this.flowsMap); + this.lastEnergyUse_kW = this.energyUse_kW; + this.clear(); + return flowPacket; + }*/ + @Override - public void operate(double ratioOfCapacity) { + public void operate(J_TimeVariables timeVariables) { /* double currentPower_kW = ratioOfCapacity * this.yearlyDemand_kWh * this.consumptionScaling_fr; @@ -145,11 +147,11 @@ public double getEnergyUsed_kWh() { return energyUsed_kWh; } - public void curtailElectricityConsumption(double curtailmentSetpoint_kW) { + public void curtailElectricityConsumption(double curtailmentSetpoint_kW, GridConnection gc) { double currentElectricityConsumption_kW = this.lastFlowsMap.get(OL_EnergyCarriers.ELECTRICITY); double curtailmentPower_kW = max(0,min(currentElectricityConsumption_kW, curtailmentSetpoint_kW)); - energyUsed_kWh -= curtailmentPower_kW * timestep_h; - lostLoad_kWh += curtailmentPower_kW * timestep_h; + energyUsed_kWh -= curtailmentPower_kW * this.timeParameters.getTimeStep_h(); + lostLoad_kWh += curtailmentPower_kW * this.timeParameters.getTimeStep_h(); J_FlowsMap flowsMap = new J_FlowsMap(); flowsMap.put(OL_EnergyCarriers.ELECTRICITY, curtailmentPower_kW); J_ValueMap assetFlows_kW = new J_ValueMap(OL_AssetFlowCategories.class); @@ -160,9 +162,7 @@ public void curtailElectricityConsumption(double curtailmentSetpoint_kW) { this.lastFlowsMap.put(OL_EnergyCarriers.ELECTRICITY, this.lastFlowsMap.get(OL_EnergyCarriers.ELECTRICITY) - curtailmentPower_kW); this.lastEnergyUse_kW -= curtailmentPower_kW; - if (parentAgent instanceof GridConnection) { - ((GridConnection)parentAgent).f_removeFlows(flowsMap, this.energyUse_kW, assetFlows_kW, this); - } + gc.f_removeFlows(flowsMap, this.energyUse_kW, assetFlows_kW, this); } public double getProfileUnitScaler_fr() { @@ -200,7 +200,7 @@ public OL_EnergyCarriers getEnergyCarrier() { @Override public String toString() { return - "parentAgent = " + parentAgent +", Energy consumed = " + this.energyUsed_kWh + + "owner = " + this.getOwner() +", Energy consumed = " + this.energyUsed_kWh + "assetFlowCategory = " + this.assetFlowCategory + " "; } From c6dcf15f3b9be433a4b7876fd5e1f270c4fbd759 Mon Sep 17 00:00:00 2001 From: GillisHommen Date: Thu, 29 Jan 2026 13:45:18 +0100 Subject: [PATCH 5/9] Engine runs correctly for Genius model Still need to refactor curtailment functions --- .../Agents/GridConnection/Code/Functions.java | 4 +- _alp/Classes/Class.J_EAProduction.java | 6 +- _alp/Classes/Class.J_EAProfile.java | 60 ++++++------------- 3 files changed, 24 insertions(+), 46 deletions(-) diff --git a/_alp/Agents/GridConnection/Code/Functions.java b/_alp/Agents/GridConnection/Code/Functions.java index 9f0c77be..d9e287cf 100644 --- a/_alp/Agents/GridConnection/Code/Functions.java +++ b/_alp/Agents/GridConnection/Code/Functions.java @@ -309,10 +309,10 @@ else if (productionAsset.energyAssetType == OL_EnergyAssetType.PHOTOTHERMAL){ energyModel.v_liveAssetsMetaData.totalInstalledBatteryStorageCapacity_MWh += capacity_MWh; } -} else if (j_ea instanceof J_EAProfile profileAsset) { - c_profileAssets.add(profileAsset); } else if (j_ea instanceof J_EAPetroleumFuelTractor tractor) { c_profileAssets.add(tractor); +} else if (j_ea instanceof J_EAProfile profileAsset) { + c_profileAssets.add(profileAsset); } else if (j_ea instanceof J_EAChargingSession chargingSession) { if(p_chargingManagement == null){ f_addChargingManagement(OL_ChargingAttitude.SIMPLE); diff --git a/_alp/Classes/Class.J_EAProduction.java b/_alp/Classes/Class.J_EAProduction.java index c86317aa..526d33ce 100644 --- a/_alp/Classes/Class.J_EAProduction.java +++ b/_alp/Classes/Class.J_EAProduction.java @@ -17,14 +17,14 @@ public J_EAProduction() { /** * Constructor initializing the fields */ - public J_EAProduction(Agent parentAgent, OL_EnergyAssetType type, String name, OL_EnergyCarriers energyCarrier, double capacity_kW, J_TimeParameters timeParameters, J_ProfilePointer profile) { - I_AssetOwner owner; + public J_EAProduction(I_AssetOwner owner, OL_EnergyAssetType type, String name, OL_EnergyCarriers energyCarrier, double capacity_kW, J_TimeParameters timeParameters, J_ProfilePointer profile) { + this.setOwner(owner); this.timeParameters = timeParameters; this.energyAssetType = type; this.energyAssetName = name; this.energyCarrier = energyCarrier; this.capacity_kW = capacity_kW; - + this.signScaler_r = -1.0; if (profile.getProfileUnits() == OL_ProfileUnits.NORMALIZEDPOWER) { this.profileUnitScaler_r = capacity_kW; this.profilePointer = profile; diff --git a/_alp/Classes/Class.J_EAProfile.java b/_alp/Classes/Class.J_EAProfile.java index bd3ecbe3..7c6c1b15 100644 --- a/_alp/Classes/Class.J_EAProfile.java +++ b/_alp/Classes/Class.J_EAProfile.java @@ -10,7 +10,8 @@ public class J_EAProfile extends zero_engine.J_EAFixed implements Serializable { //private double profileTimestep_h; //private double profileStarTime_h = 0; protected double lostLoad_kWh = 0; - protected double profileScaling_fr = 1; // This factor can be used to change the magnitude of the profile in this asset, for example when an energy-saving slider is operated. + protected double profileScaling_fr = 1.0; // This factor can be used to change the magnitude of the profile in this asset, for example when an energy-saving slider is operated. + protected double signScaler_r = 1.0; //private boolean enableProfileLooping = true; /** @@ -22,13 +23,10 @@ public J_EAProfile() { /** * Constructor initializing the fields */ - /*public J_EAProfile(Agent parentAgent, OL_EnergyCarriers energyCarrier, double[] profile_kWh, OL_AssetFlowCategories assetCategory, double profileTimestep_h, double startTime_h) { - this(parentAgent, energyCarrier, profile_kWh, assetCategory, profileTimestep_h); - this.profileStarTime_h = startTime_h; - }*/ public J_EAProfile(I_AssetOwner owner, OL_EnergyCarriers energyCarrier, J_ProfilePointer profile, OL_AssetFlowCategories assetCategory, J_TimeParameters timeParameters) { this.setOwner(owner); + this.timeParameters = timeParameters; this.energyCarrier = energyCarrier; if (profile == null) { throw new RuntimeException("Cannot create J_EAProfile without a valid ProfilePointer!"); @@ -48,41 +46,17 @@ public J_EAProfile(I_AssetOwner owner, OL_EnergyCarriers energyCarrier, J_Profil registerEnergyAsset(timeParameters); } - - - /*public J_EAProfile(Agent parentAgent, OL_EnergyCarriers energyCarrier, double[] profile_kWh, OL_AssetFlowCategories assetCategory, double profileTimestep_h) { - this.parentAgent= parentAgent; - this.energyCarrier = energyCarrier; - this.a_energyProfile_kWh = profile_kWh; - //this.profileType = profileType; - this.profileTimestep_h = profileTimestep_h; - this.assetFlowCategory = assetCategory; - - if (parentAgent instanceof GridConnection) { - this.timestep_h = ((GridConnection)parentAgent).energyModel.p_timeStep_h; - } else { - this.timestep_h = profileTimestep_h; - } - - this.activeConsumptionEnergyCarriers.add(this.energyCarrier); - - registerEnergyAsset(); - } - - public void setStartTime_h(double startTime_h) { - this.profileStarTime_h = startTime_h; - }*/ - + public J_FlowPacket f_updateAllFlows(J_TimeVariables timeVariables) { double profileValue = profilePointer.getCurrentValue(); - double currentPower_kW = profileValue * this.profileUnitScaler_r * this.profileScaling_fr; + double currentPower_kW = profileValue * this.profileUnitScaler_r * this.profileScaling_fr * this.signScaler_r; this.energyUse_kW = currentPower_kW; this.energyUsed_kWh += this.energyUse_kW * this.timeParameters.getTimeStep_h(); flowsMap.put(this.energyCarrier, currentPower_kW); if (this.assetFlowCategory != null) { - assetFlowsMap.put(this.assetFlowCategory, currentPower_kW); + assetFlowsMap.put(this.assetFlowCategory, Math.abs(currentPower_kW)); } J_FlowsMap flowsMapCopy = new J_FlowsMap(); J_ValueMap assetFlowsMapCopy = new J_ValueMap(OL_AssetFlowCategories.class); @@ -143,10 +117,6 @@ public void operate(double time_h) { } } */ - public double getEnergyUsed_kWh() { - return energyUsed_kWh; - } - public void curtailElectricityConsumption(double curtailmentSetpoint_kW, GridConnection gc) { double currentElectricityConsumption_kW = this.lastFlowsMap.get(OL_EnergyCarriers.ELECTRICITY); double curtailmentPower_kW = max(0,min(currentElectricityConsumption_kW, curtailmentSetpoint_kW)); @@ -165,6 +135,10 @@ public void curtailElectricityConsumption(double curtailmentSetpoint_kW, GridCon gc.f_removeFlows(flowsMap, this.energyUse_kW, assetFlows_kW, this); } + public J_ProfilePointer getProfilePointer() { + return this.profilePointer; + } + public double getProfileUnitScaler_fr() { return this.profileUnitScaler_r; } @@ -182,11 +156,15 @@ public double getPeakPower_kW() { } public double getBaseConsumption_kWh() { - double[] values = profilePointer.getAllValues(); - double[] arguments = profilePointer.getTableFunction().getArguments(); - double dataTimeStep_h = (arguments[arguments.length-1] - arguments[0])/arguments.length; - double baseConsumption_kWh = ZeroMath.arraySumPos(values) * dataTimeStep_h * this.profileUnitScaler_r; - return baseConsumption_kWh; + if (this.signScaler_r < 0) { + return 0.0; + } else { + double[] values = profilePointer.getAllValues(); + double[] arguments = profilePointer.getTableFunction().getArguments(); + double dataTimeStep_h = (arguments[arguments.length-1] - arguments[0])/arguments.length; + double baseConsumption_kWh = ZeroMath.arraySumPos(values) * dataTimeStep_h * this.profileUnitScaler_r; + return baseConsumption_kWh; + } } public double getTotalConsumption_kWh() { From 1cf2ce754a8f2c290afffd64641cfa2189a11e6b Mon Sep 17 00:00:00 2001 From: GillisHommen Date: Thu, 29 Jan 2026 17:31:59 +0100 Subject: [PATCH 6/9] Curtailment functions in J_EAProfile and J_EAProduction now both return flowpacket, f_removeFlows() accepts flowPacket. --- .../Agents/GridConnection/Code/Functions.java | 42 +++++++++++-------- _alp/Agents/GridConnection/Code/Functions.xml | 12 +----- .../Class.J_EAPetroleumFuelTractor.java | 15 +++++++ _alp/Classes/Class.J_EAProduction.java | 34 +++++++-------- _alp/Classes/Class.J_EAProfile.java | 11 ++--- _alp/Classes/Class.J_FlowsMap.java | 10 +++++ .../Class.J_HeatingFunctionLibrary.java | 4 +- _alp/Classes/Class.J_ValueMap.java | 10 +++++ 8 files changed, 86 insertions(+), 52 deletions(-) diff --git a/_alp/Agents/GridConnection/Code/Functions.java b/_alp/Agents/GridConnection/Code/Functions.java index d9e287cf..ef4a1245 100644 --- a/_alp/Agents/GridConnection/Code/Functions.java +++ b/_alp/Agents/GridConnection/Code/Functions.java @@ -123,6 +123,7 @@ } + /*ALCODEEND*/} double f_resetStates() @@ -606,7 +607,8 @@ else if (j_ea.energyAssetType == OL_EnergyAssetType.PHOTOTHERMAL){ // Keep feedin power within connection capacity if (fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) < - v_liveConnectionMetaData.contractedFeedinCapacity_kW) { // overproduction! for (J_EAProduction j_ea : c_productionAssets) { - j_ea.curtailEnergyCarrierProduction(OL_EnergyCarriers.ELECTRICITY, - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) - v_liveConnectionMetaData.contractedFeedinCapacity_kW, this); + J_FlowPacket flowPacket = j_ea.curtailEnergyCarrierProduction(OL_EnergyCarriers.ELECTRICITY, - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) - v_liveConnectionMetaData.contractedFeedinCapacity_kW, this); + f_removeFlows(flowPacket, j_ea); if (!(fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) < - v_liveConnectionMetaData.contractedFeedinCapacity_kW)) { break; } @@ -617,7 +619,8 @@ else if (j_ea.energyAssetType == OL_EnergyAssetType.PHOTOTHERMAL){ if(energyModel.pp_dayAheadElectricityPricing_eurpMWh.getCurrentValue() < 0.0) { if (fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) < 0.0) { // Feedin, bring to zero! for (J_EAProduction j_ea : c_productionAssets) { - j_ea.curtailEnergyCarrierProduction(OL_EnergyCarriers.ELECTRICITY, - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY), this); + J_FlowPacket flowPacket = j_ea.curtailEnergyCarrierProduction(OL_EnergyCarriers.ELECTRICITY, - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY), this); + f_removeFlows(flowPacket, j_ea); if (!(fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) < 0.0)) { break; } @@ -632,7 +635,8 @@ else if (j_ea.energyAssetType == OL_EnergyAssetType.PHOTOTHERMAL){ double v_currentPowerElectricitySetpoint_kW = fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) * max(0,1+(p_parentNodeElectric.v_currentTotalNodalPrice_eurpkWh-priceTreshold_eur)*5); for (J_EAProduction j_ea : c_productionAssets) { - j_ea.curtailEnergyCarrierProduction(OL_EnergyCarriers.ELECTRICITY, v_currentPowerElectricitySetpoint_kW - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY), this); + J_FlowPacket flowPacket = j_ea.curtailEnergyCarrierProduction(OL_EnergyCarriers.ELECTRICITY, v_currentPowerElectricitySetpoint_kW - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY), this); + f_removeFlows(flowPacket, j_ea); if (!(fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) < v_currentPowerElectricitySetpoint_kW)) { break; } @@ -703,37 +707,39 @@ else if (j_ea.energyAssetType == OL_EnergyAssetType.PHOTOTHERMAL){ } /*ALCODEEND*/} -double f_removeFlows(J_FlowsMap flowsMap,double energyUse_kW,J_ValueMap assetFlowsMap_kW,J_EA caller) +double f_removeFlows(J_FlowPacket flowPacket,J_EA caller) {/*ALCODESTART::1722512642645*/ -for (OL_EnergyCarriers EC : flowsMap.keySet()) { - fm_currentBalanceFlows_kW.addFlow(EC, -flowsMap.get(EC)); +for (OL_EnergyCarriers EC : flowPacket.flowsMap.keySet()) { + fm_currentBalanceFlows_kW.addFlow(EC, -flowPacket.flowsMap.get(EC)); - if (flowsMap.get(EC) < 0) { - fm_currentProductionFlows_kW.addFlow(EC, flowsMap.get(EC)); + if (flowPacket.flowsMap.get(EC) < 0) { + fm_currentProductionFlows_kW.addFlow(EC, flowPacket.flowsMap.get(EC)); } - else if (flowsMap.get(EC) > 0){ - fm_currentConsumptionFlows_kW.addFlow(EC, -flowsMap.get(EC)); + else if (flowPacket.flowsMap.get(EC) > 0){ + fm_currentConsumptionFlows_kW.addFlow(EC, -flowPacket.flowsMap.get(EC)); } } if (caller instanceof J_EAStorageElectric) { // Only allocate battery losses as consumption. Charging/discharging is neither production nor consumption. Do we need an element in flowsmap indicating power into storage?? - fm_currentConsumptionFlows_kW.addFlow(OL_EnergyCarriers.ELECTRICITY, max(0, energyUse_kW)); - v_currentFinalEnergyConsumption_kW += max(0, energyUse_kW); + fm_currentConsumptionFlows_kW.addFlow(OL_EnergyCarriers.ELECTRICITY, max(0, flowPacket.energyUse_kW)); + v_currentFinalEnergyConsumption_kW += max(0, flowPacket.energyUse_kW); } else { - double curtailment_kW = max(0, -energyUse_kW); - double lostLoad_kW = max(0, energyUse_kW); + double curtailment_kW = max(0, -flowPacket.energyUse_kW); + double lostLoad_kW = max(0, flowPacket.energyUse_kW); v_currentEnergyCurtailed_kW += curtailment_kW; v_currentPrimaryEnergyProduction_kW -= curtailment_kW; v_currentFinalEnergyConsumption_kW -= lostLoad_kW; } if ( caller instanceof J_EAConversionHeatPump ) { - v_currentPrimaryEnergyProductionHeatpumps_kW += energyUse_kW; -} -for(var AC : assetFlowsMap_kW.keySet()) { - fm_currentAssetFlows_kW.addFlow(AC, -assetFlowsMap_kW.get(AC)); + v_currentPrimaryEnergyProductionHeatpumps_kW += flowPacket.energyUse_kW; } +fm_currentAssetFlows_kW.removeFlows(flowPacket.assetFlowsMap); +/*for(var AC : flowPacket.assetFlowsMap.keySet()) { + fm_currentAssetFlows_kW.addFlow(AC, -flowPacket.assetFlowsMap.get(AC)); +}*/ + /*ALCODEEND*/} double f_fillLiveDataSets(J_TimeVariables timeVariables) diff --git a/_alp/Agents/GridConnection/Code/Functions.xml b/_alp/Agents/GridConnection/Code/Functions.xml index c1922893..cd685dd6 100644 --- a/_alp/Agents/GridConnection/Code/Functions.xml +++ b/_alp/Agents/GridConnection/Code/Functions.xml @@ -412,16 +412,8 @@ true true - - - - - - - - - - ]]> + + diff --git a/_alp/Classes/Class.J_EAPetroleumFuelTractor.java b/_alp/Classes/Class.J_EAPetroleumFuelTractor.java index 2dd08534..2c967eed 100644 --- a/_alp/Classes/Class.J_EAPetroleumFuelTractor.java +++ b/_alp/Classes/Class.J_EAPetroleumFuelTractor.java @@ -44,6 +44,21 @@ public J_EAPetroleumFuelTractor(I_AssetOwner owner, double yearlyPetroleumFuelCo registerEnergyAsset(timeParameters); } + @Override + public J_FlowPacket f_updateAllFlows(J_TimeVariables timeVariables) { + this.operate(timeVariables); + if (this.assetFlowCategory != null) { + assetFlowsMap.put(this.assetFlowCategory, Math.abs(energyUse_kW)); + } + J_FlowsMap flowsMapCopy = new J_FlowsMap(); + J_ValueMap assetFlowsMapCopy = new J_ValueMap(OL_AssetFlowCategories.class); + J_FlowPacket flowPacket = new J_FlowPacket(flowsMapCopy.cloneMap(this.flowsMap), this.energyUse_kW, assetFlowsMapCopy.cloneMap(this.assetFlowsMap)); + this.lastFlowsMap.cloneMap(this.flowsMap); + this.lastEnergyUse_kW = this.energyUse_kW; + this.clear(); + return flowPacket; + } + @Override public void operate(J_TimeVariables timeVariables) { if (!shouldWork(timeVariables)) { diff --git a/_alp/Classes/Class.J_EAProduction.java b/_alp/Classes/Class.J_EAProduction.java index 526d33ce..bcd099e4 100644 --- a/_alp/Classes/Class.J_EAProduction.java +++ b/_alp/Classes/Class.J_EAProduction.java @@ -6,7 +6,7 @@ public class J_EAProduction extends zero_engine.J_EAProfile implements Serializa //protected OL_EnergyCarriers energyCarrier = OL_EnergyCarriers.ELECTRICITY; protected double totalEnergyCurtailed_kWh=0; //protected double outputTemperature_degC; - protected double capacity_kW; + //protected double capacity_kW; /** * Default constructor @@ -23,7 +23,7 @@ public J_EAProduction(I_AssetOwner owner, OL_EnergyAssetType type, String name, this.energyAssetType = type; this.energyAssetName = name; this.energyCarrier = energyCarrier; - this.capacity_kW = capacity_kW; + //this.capacity_kW = capacity_kW; this.signScaler_r = -1.0; if (profile.getProfileUnits() == OL_ProfileUnits.NORMALIZEDPOWER) { this.profileUnitScaler_r = capacity_kW; @@ -51,7 +51,7 @@ public J_EAProduction(I_AssetOwner owner, OL_EnergyAssetType type, String name, public void setCapacityElectric_kW(double capacityElectric_kW, GridConnection gc) { // Calculate the difference with the set and the previous capacity to update totals in GC, GN and EnergyModel if (energyCarrier == OL_EnergyCarriers.ELECTRICITY) { - double difference_kW = capacityElectric_kW - this.capacity_kW; + double difference_kW = capacityElectric_kW - this.profileUnitScaler_r; if (this.energyAssetType == OL_EnergyAssetType.WINDMILL) { gc.v_liveAssetsMetaData.totalInstalledWindPower_kW += difference_kW; if (gc.p_parentNodeElectric != null) { @@ -69,7 +69,8 @@ else if (this.energyAssetType == OL_EnergyAssetType.PHOTOVOLTAIC) { gc.energyModel.v_liveAssetsMetaData.totalInstalledPVPower_kW += difference_kW; } - this.capacity_kW = capacityElectric_kW; + this.profileUnitScaler_r = capacityElectric_kW; + } else { throw new RuntimeException("Production assets energy carrier is not electricity!"); } @@ -77,7 +78,7 @@ else if (this.energyAssetType == OL_EnergyAssetType.PHOTOVOLTAIC) { public double getCapacityElectric_kW() { if (energyCarrier == OL_EnergyCarriers.ELECTRICITY) { - return this.capacity_kW; + return this.profileUnitScaler_r; } else { throw new RuntimeException("J_EAProduction is not electric!"); } @@ -85,7 +86,7 @@ public double getCapacityElectric_kW() { public double getCapacityHeat_kW() { if (energyCarrier == OL_EnergyCarriers.HEAT) { - return capacity_kW; + return profileUnitScaler_r; } else { throw new RuntimeException("J_EAProduction is not thermal!"); } @@ -139,14 +140,14 @@ public void f_updateAllFlows() { this.clear(); }*/ - public double curtailEnergyCarrierProduction(OL_EnergyCarriers curtailedEnergyCarrier, double curtailmentAmount_kW, GridConnection gc) { // The curtailment setpoint is the requested amount of curtailment; requested reduction of production. (which may or may not be provided, depending on what the current production is) + public J_FlowPacket curtailEnergyCarrierProduction(OL_EnergyCarriers curtailedEnergyCarrier, double curtailmentAmount_kW, GridConnection gc) { // The curtailment setpoint is the requested amount of curtailment; requested reduction of production. (which may or may not be provided, depending on what the current production is) - if(this.energyCarrier != curtailedEnergyCarrier) { + /*if(this.energyCarrier != curtailedEnergyCarrier) { //new RuntimeException("Trying to curtail the wrong a production asset with the wrong energyCarrier"); return 0; - } + }*/ - double currentProduction_kW = -this.lastFlowsMap.get(curtailedEnergyCarrier ); + double currentProduction_kW = max(0,-this.lastFlowsMap.get(curtailedEnergyCarrier)); double curtailmentPower_kW = max(0,min(currentProduction_kW, curtailmentAmount_kW)); // Can only curtail what was produced in the first place. energyUsed_kWh += curtailmentPower_kW * this.timeParameters.getTimeStep_h(); // energyUsed_kWh is negative for production assets. Curtailment makes it 'less negative', so a positive number is added to energyUsed_kWh. this.totalEnergyCurtailed_kWh += curtailmentPower_kW * this.timeParameters.getTimeStep_h(); @@ -158,13 +159,9 @@ public void f_updateAllFlows() { this.lastFlowsMap.addFlow(curtailedEnergyCarrier, curtailmentPower_kW); // production is a negative flow, so to remove production, a positive value must be added to lastFlows. this.lastEnergyUse_kW += curtailmentPower_kW; // production is a negative flow, so to remove production, a positive value must be added to lastEnergyUse_kW. - //traceln("Electricity production of asset %s curtailed by %s kW!", this, curtailmentPower_kW); - - gc.f_removeFlows(curtailmentFlow, curtailedEnergyUse_kW, assetFlows_kW, this); - - clear(); - - return curtailmentPower_kW; + //gc.f_removeFlows(curtailmentFlow, curtailedEnergyUse_kW, assetFlows_kW, this); + J_FlowPacket flowPacket = new J_FlowPacket(curtailmentFlow, curtailedEnergyUse_kW, assetFlows_kW); + return flowPacket; } public double getEnergyCurtailed_kWh() { @@ -186,8 +183,9 @@ public String toString() { return "type = " + this.getClass().toString() + " " + "owner = " + this.getOwner() +" " + - "capacity_kW = " + capacity_kW +" "+ + "capacity_kW = " + profileUnitScaler_r +" "+ "energyCarrier = " + energyCarrier +" "+ + "assetFlowCategory = " + this.assetFlowCategory + " " + "energyProduced_kWh = " + (-this.energyUsed_kWh) + " "; } diff --git a/_alp/Classes/Class.J_EAProfile.java b/_alp/Classes/Class.J_EAProfile.java index 7c6c1b15..2d2e1e5e 100644 --- a/_alp/Classes/Class.J_EAProfile.java +++ b/_alp/Classes/Class.J_EAProfile.java @@ -117,8 +117,8 @@ public void operate(double time_h) { } } */ - public void curtailElectricityConsumption(double curtailmentSetpoint_kW, GridConnection gc) { - double currentElectricityConsumption_kW = this.lastFlowsMap.get(OL_EnergyCarriers.ELECTRICITY); + public J_FlowPacket curtailElectricityConsumption(double curtailmentSetpoint_kW, GridConnection gc) { + double currentElectricityConsumption_kW = max(0,this.lastFlowsMap.get(OL_EnergyCarriers.ELECTRICITY)); double curtailmentPower_kW = max(0,min(currentElectricityConsumption_kW, curtailmentSetpoint_kW)); energyUsed_kWh -= curtailmentPower_kW * this.timeParameters.getTimeStep_h(); lostLoad_kWh += curtailmentPower_kW * this.timeParameters.getTimeStep_h(); @@ -127,12 +127,13 @@ public void curtailElectricityConsumption(double curtailmentSetpoint_kW, GridCon J_ValueMap assetFlows_kW = new J_ValueMap(OL_AssetFlowCategories.class); assetFlows_kW.put(this.assetFlowCategory, curtailmentPower_kW); - this.energyUse_kW = -curtailmentPower_kW; - this.lastFlowsMap.put(OL_EnergyCarriers.ELECTRICITY, this.lastFlowsMap.get(OL_EnergyCarriers.ELECTRICITY) - curtailmentPower_kW); this.lastEnergyUse_kW -= curtailmentPower_kW; - gc.f_removeFlows(flowsMap, this.energyUse_kW, assetFlows_kW, this); + //gc.f_removeFlows(flowsMap, this.energyUse_kW, assetFlows_kW, this); + J_FlowPacket flowPacket = new J_FlowPacket(flowsMap, curtailmentPower_kW, assetFlows_kW); + return flowPacket; + } public J_ProfilePointer getProfilePointer() { diff --git a/_alp/Classes/Class.J_FlowsMap.java b/_alp/Classes/Class.J_FlowsMap.java index 089050d1..e160e617 100644 --- a/_alp/Classes/Class.J_FlowsMap.java +++ b/_alp/Classes/Class.J_FlowsMap.java @@ -53,6 +53,16 @@ public final J_FlowsMap addFlows( J_FlowsMap f) { return this; } + public final J_FlowsMap removeFlows( J_FlowsMap f) { + int len = valuesArray.length; + for(int i=0; i 0) { if (remainingPTProduction_kW > 0) {//Heat (for now always curtail over produced heat!) for (J_EAProduction j_ea : ptAssets) { - remainingPTProduction_kW -= j_ea.curtailEnergyCarrierProduction( OL_EnergyCarriers.HEAT, remainingPTProduction_kW, gc); + J_FlowPacket flowPacket = j_ea.curtailEnergyCarrierProduction( OL_EnergyCarriers.HEAT, remainingPTProduction_kW, gc); + gc.f_removeFlows(flowPacket, j_ea); + remainingPTProduction_kW += flowPacket.energyUse_kW; if (remainingPTProduction_kW <= 0) { break; diff --git a/_alp/Classes/Class.J_ValueMap.java b/_alp/Classes/Class.J_ValueMap.java index 03c2856c..52200725 100644 --- a/_alp/Classes/Class.J_ValueMap.java +++ b/_alp/Classes/Class.J_ValueMap.java @@ -50,6 +50,16 @@ public final J_ValueMap addFlows( J_ValueMap f) { return this; } + public final J_ValueMap removeFlows( J_ValueMap f) { + int len = valuesArray.length; + for(int i=0; i Date: Thu, 29 Jan 2026 17:41:05 +0100 Subject: [PATCH 7/9] Completed refactor of curtailment functions to use FlowPacket. --- _alp/Agents/GridConnection/Code/Functions.java | 6 +++--- _alp/Classes/Class.J_EAProduction.java | 2 +- _alp/Classes/Class.J_EAProfile.java | 2 +- _alp/Classes/Class.J_HeatingFunctionLibrary.java | 4 ++-- .../Class.J_HeatingManagementBuildingHybridHeatPump.java | 5 +++-- ...Class.J_HeatingManagementBuildingWithPTBufferSimple.java | 6 ++++-- .../Class.J_HeatingManagementProfileWithPTBufferSimple.java | 5 +++-- 7 files changed, 17 insertions(+), 13 deletions(-) diff --git a/_alp/Agents/GridConnection/Code/Functions.java b/_alp/Agents/GridConnection/Code/Functions.java index ef4a1245..ce0840e2 100644 --- a/_alp/Agents/GridConnection/Code/Functions.java +++ b/_alp/Agents/GridConnection/Code/Functions.java @@ -607,7 +607,7 @@ else if (j_ea.energyAssetType == OL_EnergyAssetType.PHOTOTHERMAL){ // Keep feedin power within connection capacity if (fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) < - v_liveConnectionMetaData.contractedFeedinCapacity_kW) { // overproduction! for (J_EAProduction j_ea : c_productionAssets) { - J_FlowPacket flowPacket = j_ea.curtailEnergyCarrierProduction(OL_EnergyCarriers.ELECTRICITY, - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) - v_liveConnectionMetaData.contractedFeedinCapacity_kW, this); + J_FlowPacket flowPacket = j_ea.curtailEnergyCarrierProduction(OL_EnergyCarriers.ELECTRICITY, - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) - v_liveConnectionMetaData.contractedFeedinCapacity_kW); f_removeFlows(flowPacket, j_ea); if (!(fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) < - v_liveConnectionMetaData.contractedFeedinCapacity_kW)) { break; @@ -619,7 +619,7 @@ else if (j_ea.energyAssetType == OL_EnergyAssetType.PHOTOTHERMAL){ if(energyModel.pp_dayAheadElectricityPricing_eurpMWh.getCurrentValue() < 0.0) { if (fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) < 0.0) { // Feedin, bring to zero! for (J_EAProduction j_ea : c_productionAssets) { - J_FlowPacket flowPacket = j_ea.curtailEnergyCarrierProduction(OL_EnergyCarriers.ELECTRICITY, - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY), this); + J_FlowPacket flowPacket = j_ea.curtailEnergyCarrierProduction(OL_EnergyCarriers.ELECTRICITY, - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY)); f_removeFlows(flowPacket, j_ea); if (!(fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) < 0.0)) { break; @@ -635,7 +635,7 @@ else if (j_ea.energyAssetType == OL_EnergyAssetType.PHOTOTHERMAL){ double v_currentPowerElectricitySetpoint_kW = fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) * max(0,1+(p_parentNodeElectric.v_currentTotalNodalPrice_eurpkWh-priceTreshold_eur)*5); for (J_EAProduction j_ea : c_productionAssets) { - J_FlowPacket flowPacket = j_ea.curtailEnergyCarrierProduction(OL_EnergyCarriers.ELECTRICITY, v_currentPowerElectricitySetpoint_kW - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY), this); + J_FlowPacket flowPacket = j_ea.curtailEnergyCarrierProduction(OL_EnergyCarriers.ELECTRICITY, v_currentPowerElectricitySetpoint_kW - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY)); f_removeFlows(flowPacket, j_ea); if (!(fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) < v_currentPowerElectricitySetpoint_kW)) { break; diff --git a/_alp/Classes/Class.J_EAProduction.java b/_alp/Classes/Class.J_EAProduction.java index bcd099e4..e5ce819f 100644 --- a/_alp/Classes/Class.J_EAProduction.java +++ b/_alp/Classes/Class.J_EAProduction.java @@ -140,7 +140,7 @@ public void f_updateAllFlows() { this.clear(); }*/ - public J_FlowPacket curtailEnergyCarrierProduction(OL_EnergyCarriers curtailedEnergyCarrier, double curtailmentAmount_kW, GridConnection gc) { // The curtailment setpoint is the requested amount of curtailment; requested reduction of production. (which may or may not be provided, depending on what the current production is) + public J_FlowPacket curtailEnergyCarrierProduction(OL_EnergyCarriers curtailedEnergyCarrier, double curtailmentAmount_kW) { // The curtailment setpoint is the requested amount of curtailment; requested reduction of production. (which may or may not be provided, depending on what the current production is) /*if(this.energyCarrier != curtailedEnergyCarrier) { //new RuntimeException("Trying to curtail the wrong a production asset with the wrong energyCarrier"); diff --git a/_alp/Classes/Class.J_EAProfile.java b/_alp/Classes/Class.J_EAProfile.java index 2d2e1e5e..4222efc1 100644 --- a/_alp/Classes/Class.J_EAProfile.java +++ b/_alp/Classes/Class.J_EAProfile.java @@ -117,7 +117,7 @@ public void operate(double time_h) { } } */ - public J_FlowPacket curtailElectricityConsumption(double curtailmentSetpoint_kW, GridConnection gc) { + public J_FlowPacket curtailElectricityConsumption(double curtailmentSetpoint_kW) { double currentElectricityConsumption_kW = max(0,this.lastFlowsMap.get(OL_EnergyCarriers.ELECTRICITY)); double curtailmentPower_kW = max(0,min(currentElectricityConsumption_kW, curtailmentSetpoint_kW)); energyUsed_kWh -= curtailmentPower_kW * this.timeParameters.getTimeStep_h(); diff --git a/_alp/Classes/Class.J_HeatingFunctionLibrary.java b/_alp/Classes/Class.J_HeatingFunctionLibrary.java index 2154e628..7fb9b71f 100644 --- a/_alp/Classes/Class.J_HeatingFunctionLibrary.java +++ b/_alp/Classes/Class.J_HeatingFunctionLibrary.java @@ -38,9 +38,9 @@ else if(remainingPTProduction_kW > 0) { if (remainingPTProduction_kW > 0) {//Heat (for now always curtail over produced heat!) for (J_EAProduction j_ea : ptAssets) { - J_FlowPacket flowPacket = j_ea.curtailEnergyCarrierProduction( OL_EnergyCarriers.HEAT, remainingPTProduction_kW, gc); + J_FlowPacket flowPacket = j_ea.curtailEnergyCarrierProduction( OL_EnergyCarriers.HEAT, remainingPTProduction_kW); gc.f_removeFlows(flowPacket, j_ea); - remainingPTProduction_kW += flowPacket.energyUse_kW; + remainingPTProduction_kW += flowPacket.energyUse_kW; // Curtailed energyUse_kW will be a negative number when curtailing a production asset, hence the += ! if (remainingPTProduction_kW <= 0) { break; diff --git a/_alp/Classes/Class.J_HeatingManagementBuildingHybridHeatPump.java b/_alp/Classes/Class.J_HeatingManagementBuildingHybridHeatPump.java index 56b41b0a..3633c9be 100644 --- a/_alp/Classes/Class.J_HeatingManagementBuildingHybridHeatPump.java +++ b/_alp/Classes/Class.J_HeatingManagementBuildingHybridHeatPump.java @@ -120,8 +120,9 @@ else if(remainingPTProduction_kW > 0) { remainingPTProduction_kW = max(0, remainingPTProduction_kW - heatBufferCharge_kW); if (remainingPTProduction_kW > 0) {//Heat (for now always curtail over produced heat!) for (J_EAProduction j_ea : ptAssets) { - remainingPTProduction_kW -= j_ea.curtailEnergyCarrierProduction( OL_EnergyCarriers.HEAT, remainingPTProduction_kW, gc); - + J_FlowPacket flowPacket = j_ea.curtailEnergyCarrierProduction( OL_EnergyCarriers.HEAT, remainingPTProduction_kW); + gc.f_removeFlows(flowPacket, j_ea); + remainingPTProduction_kW += flowPacket.energyUse_kW; if (remainingPTProduction_kW <= 0) { break; } diff --git a/_alp/Classes/Class.J_HeatingManagementBuildingWithPTBufferSimple.java b/_alp/Classes/Class.J_HeatingManagementBuildingWithPTBufferSimple.java index 108d6146..ef16c55b 100644 --- a/_alp/Classes/Class.J_HeatingManagementBuildingWithPTBufferSimple.java +++ b/_alp/Classes/Class.J_HeatingManagementBuildingWithPTBufferSimple.java @@ -81,8 +81,10 @@ else if(remainingPTProduction_kW > 0) { remainingPTProduction_kW = max(0, remainingPTProduction_kW - heatBufferCharge_kW); if (remainingPTProduction_kW > 0) {//Heat (for now always curtail over produced heat!) for (J_EAProduction j_ea : ptAssets) { - remainingPTProduction_kW -= j_ea.curtailEnergyCarrierProduction( OL_EnergyCarriers.HEAT, remainingPTProduction_kW); - + + J_FlowPacket flowPacket = j_ea.curtailEnergyCarrierProduction( OL_EnergyCarriers.HEAT, remainingPTProduction_kW); + gc.f_removeFlows(flowPacket, j_ea); + remainingPTProduction_kW += flowPacket.energyUse_kW; if (remainingPTProduction_kW <= 0) { break; } diff --git a/_alp/Classes/Class.J_HeatingManagementProfileWithPTBufferSimple.java b/_alp/Classes/Class.J_HeatingManagementProfileWithPTBufferSimple.java index 90e36c1d..78ce4d46 100644 --- a/_alp/Classes/Class.J_HeatingManagementProfileWithPTBufferSimple.java +++ b/_alp/Classes/Class.J_HeatingManagementProfileWithPTBufferSimple.java @@ -81,8 +81,9 @@ else if(remainingPTProduction_kW > 0) { remainingPTProduction_kW = max(0, remainingPTProduction_kW - heatBufferCharge_kW); if (remainingPTProduction_kW > 0) {//Heat (for now always curtail over produced heat!) for (J_EAProduction j_ea : ptAssets) { - remainingPTProduction_kW -= j_ea.curtailEnergyCarrierProduction( OL_EnergyCarriers.HEAT, remainingPTProduction_kW); - + J_FlowPacket flowPacket = j_ea.curtailEnergyCarrierProduction( OL_EnergyCarriers.HEAT, remainingPTProduction_kW); + gc.f_removeFlows(flowPacket, j_ea); + remainingPTProduction_kW += flowPacket.energyUse_kW; if (remainingPTProduction_kW <= 0) { break; } From fbb240ce3d46bdc3ba441b59facfc895af71e045 Mon Sep 17 00:00:00 2001 From: GillisHommen Date: Tue, 3 Feb 2026 08:56:36 +0100 Subject: [PATCH 8/9] Remove tableFunction from profilePointer Now contains internal array, dataTimeStep_h and dataStartTime_h. Loader functions ensure correct dataformat. --- ..._BatteryManagementPeakShavingForecast.java | 4 +- _alp/Classes/Class.J_EAConsumption.java | 3 +- _alp/Classes/Class.J_EAProfile.java | 71 +++++-------------- _alp/Classes/Class.J_ProfilePointer.java | 48 +++++++++---- 4 files changed, 54 insertions(+), 72 deletions(-) diff --git a/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java b/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java index 20385450..531b2d31 100644 --- a/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java +++ b/_alp/Classes/Class.J_BatteryManagementPeakShavingForecast.java @@ -139,14 +139,14 @@ private double[] getNettoBalanceForecast_kW(J_TimeVariables timeVariables) { double COP_r = eta_r * ( 273.15 + outputTemperature_degC ) / ( outputTemperature_degC - baseTemperature_degC ); //traceln(genericHeatDemandProfile.getProfilePointer().getValue(time)*genericHeatDemandProfile.yearlyDemand_kWh); - nettoBalanceTotal_kW[roundToInt((time-energyModel_time_h)/timeParameters.getTimeStep_h())] += genericHeatDemandProfile.getProfilePointer().getValue(time)*genericHeatDemandProfile.getYearlyDemand_kWh()*genericHeatDemandProfile.getConsumptionScaling_fr() / COP_r; + nettoBalanceTotal_kW[roundToInt((time-energyModel_time_h)/timeParameters.getTimeStep_h())] += genericHeatDemandProfile.getProfilePointer().getValue(time)*genericHeatDemandProfile.getBaseConsumption_kWh()*genericHeatDemandProfile.getConsumptionScaling_fr() / COP_r; } } } for(J_EAConsumption genericBuildingProfile : genericBuildingProfiles) { if(genericBuildingProfile != null){ //table function for(double time = energyModel_time_h; time < energyModel_time_h + 24; time += timeParameters.getTimeStep_h()){ - nettoBalanceTotal_kW[roundToInt((time-energyModel_time_h)/timeParameters.getTimeStep_h())] += genericBuildingProfile.getProfilePointer().getValue(time)*genericBuildingProfile.getYearlyDemand_kWh()*genericBuildingProfile.getConsumptionScaling_fr(); + nettoBalanceTotal_kW[roundToInt((time-energyModel_time_h)/timeParameters.getTimeStep_h())] += genericBuildingProfile.getProfilePointer().getValue(time)*genericBuildingProfile.getBaseConsumption_kWh()*genericBuildingProfile.getConsumptionScaling_fr(); } } } diff --git a/_alp/Classes/Class.J_EAConsumption.java b/_alp/Classes/Class.J_EAConsumption.java index 43b9b75f..dccebc19 100644 --- a/_alp/Classes/Class.J_EAConsumption.java +++ b/_alp/Classes/Class.J_EAConsumption.java @@ -107,7 +107,8 @@ public J_ProfilePointer getProfilePointer() { return this.profilePointer; } - public double getYearlyDemand_kWh() { + @Override + public double getBaseConsumption_kWh() { return yearlyDemand_kWh; } diff --git a/_alp/Classes/Class.J_EAProfile.java b/_alp/Classes/Class.J_EAProfile.java index 4222efc1..57666771 100644 --- a/_alp/Classes/Class.J_EAProfile.java +++ b/_alp/Classes/Class.J_EAProfile.java @@ -6,14 +6,10 @@ public class J_EAProfile extends zero_engine.J_EAFixed implements Serializable { protected J_ProfilePointer profilePointer; protected double profileUnitScaler_r = 4.0; // This factor translates tablefunction data in kWh/qh, normalized power or consumption-fraction into power [kW]. To go from kWh/qh to kW, that is a factor 4. protected OL_EnergyCarriers energyCarrier; // = OL_EnergyCarriers.ELECTRICITY; - //public double[] a_energyProfile_kWh; - //private double profileTimestep_h; - //private double profileStarTime_h = 0; protected double lostLoad_kWh = 0; protected double profileScaling_fr = 1.0; // This factor can be used to change the magnitude of the profile in this asset, for example when an energy-saving slider is operated. protected double signScaler_r = 1.0; - //private boolean enableProfileLooping = true; - + /** * Default constructor */ @@ -67,55 +63,11 @@ public J_FlowPacket f_updateAllFlows(J_TimeVariables timeVariables) { return flowPacket; } - /* - public J_FlowPacket f_updateAllFlows(J_TimeVariables timeVariables) { - operate(timeVariables); - J_FlowsMap flowsMapCopy = new J_FlowsMap(); - J_ValueMap assetFlowsMapCopy = new J_ValueMap(OL_AssetFlowCategories.class); - J_FlowPacket flowPacket = new J_FlowPacket(flowsMapCopy.cloneMap(this.flowsMap), this.energyUse_kW, assetFlowsMapCopy.cloneMap(this.assetFlowsMap)); - this.lastFlowsMap.cloneMap(this.flowsMap); - this.lastEnergyUse_kW = this.energyUse_kW; - this.clear(); - return flowPacket; - }*/ - @Override public void operate(J_TimeVariables timeVariables) { - /* - double currentPower_kW = ratioOfCapacity * this.yearlyDemand_kWh * this.consumptionScaling_fr; - - this.energyUse_kW = currentPower_kW; - this.energyUsed_kWh += this.energyUse_kW * this.timestep_h; - - flowsMap.put(this.energyCarrier, currentPower_kW); - if (this.assetFlowCategory != null) { - assetFlowsMap.put(this.assetFlowCategory, currentPower_kW); - }*/ + throw new RuntimeException("J_EAProfile method operate() is not used!"); } - /* Old J_EAProfile implementation - @Override - public void operate(double time_h) { - if (enableProfileLooping && time_h >= a_energyProfile_kWh.length * profileTimestep_h) { - time_h = time_h % a_energyProfile_kWh.length * profileTimestep_h; - } else if ( (int)floor(time_h/profileTimestep_h) >= a_energyProfile_kWh.length ) { - traceln("Time out of upper bound for evaluating J_EAProfile power in profile asset %s!", this.energyAssetName); -// time_h = a_energyProfile_kWh.length * profileTimestep_h - 1; - throw new RuntimeException(String.format("Time out of upper bound for evaluating J_EAProfile power! Time is: %s", time_h)); - } - if ( time_h < 0 ) { - traceln("Time out of lower bound for evaluating J_EAProfile power in profile asset %s!", this.energyAssetName); - throw new RuntimeException(String.format("Time out of lower bound for evaluating J_EAProfile power! Time is: %s", time_h)); - } - - double currentPower_kW = this.profileScaling_fr * this.a_energyProfile_kWh[(int)floor(time_h/profileTimestep_h)]/profileTimestep_h; - this.energyUse_kW = currentPower_kW; - this.energyUsed_kWh += timestep_h * energyUse_kW; - this.flowsMap.put(this.energyCarrier, currentPower_kW); - if (this.assetFlowCategory != null) { - this.assetFlowsMap.put(this.assetFlowCategory, currentPower_kW); - } - } */ public J_FlowPacket curtailElectricityConsumption(double curtailmentSetpoint_kW) { double currentElectricityConsumption_kW = max(0,this.lastFlowsMap.get(OL_EnergyCarriers.ELECTRICITY)); @@ -152,8 +104,20 @@ public void setProfileScaling_fr( double scaling_fr ) { this.profileScaling_fr = scaling_fr; } - public double getPeakPower_kW() { - return max(profilePointer.getAllValues()) * this.profileUnitScaler_r * this.profileScaling_fr; + public double getPeakConsumptionPower_kW() { + if (this.signScaler_r < 0) { + return 0.0; + } else { + return max(profilePointer.getAllValues()) * this.profileUnitScaler_r * this.profileScaling_fr; + } + } + + public double getPeakProductionPower_kW() { + if (this.signScaler_r > 0) { + return 0.0; + } else { + return max(profilePointer.getAllValues()) * this.profileUnitScaler_r * this.profileScaling_fr; + } } public double getBaseConsumption_kWh() { @@ -161,8 +125,7 @@ public double getBaseConsumption_kWh() { return 0.0; } else { double[] values = profilePointer.getAllValues(); - double[] arguments = profilePointer.getTableFunction().getArguments(); - double dataTimeStep_h = (arguments[arguments.length-1] - arguments[0])/arguments.length; + double dataTimeStep_h = profilePointer.getDataTimeStep_h(); double baseConsumption_kWh = ZeroMath.arraySumPos(values) * dataTimeStep_h * this.profileUnitScaler_r; return baseConsumption_kWh; } diff --git a/_alp/Classes/Class.J_ProfilePointer.java b/_alp/Classes/Class.J_ProfilePointer.java index 4ff55da9..7d158b4e 100644 --- a/_alp/Classes/Class.J_ProfilePointer.java +++ b/_alp/Classes/Class.J_ProfilePointer.java @@ -7,7 +7,7 @@ import com.fasterxml.jackson.annotation.ObjectIdGenerators; @JsonAutoDetect( - fieldVisibility = Visibility.PROTECTED_AND_PUBLIC, // ✅ only public fields are serialized + fieldVisibility = Visibility.ANY, // also stores full profiles to file. Maybe arrange a way to 'skip' this? getterVisibility = Visibility.NONE, isGetterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, @@ -18,9 +18,14 @@ public class J_ProfilePointer implements Serializable { public String name = ""; private double currentValue = 0; - private TableFunction tableFunction; private OL_ProfileUnits profileUnits; + // Using internal array instead of tableFunction + private double[] a_profile; + private double dataTimeStep_h; + private double dataStartTime_h; // relative to 00:00h on jan 1st of simulation year + private boolean enableProfileLooping = true; + /** * Default constructor */ @@ -28,34 +33,47 @@ public J_ProfilePointer() { } - public J_ProfilePointer(String name, TableFunction tableFunction, OL_ProfileUnits profileUnits) { + public J_ProfilePointer(String name, double[] profile, double dataTimeStep_h, double dataStartTime_h, OL_ProfileUnits profileUnits) { this.name = name; - this.tableFunction = tableFunction; + this.a_profile = profile; + this.dataTimeStep_h = dataTimeStep_h; + this.dataStartTime_h = dataStartTime_h; this.profileUnits = profileUnits; } public void updateValue(double t_h) { - this.currentValue = this.tableFunction.get(t_h); + this.currentValue = this.getValue(t_h); } public double getCurrentValue() { return this.currentValue; } - public double getValue(double t_h) { - return this.tableFunction.get(t_h); + public double getValue(double time_h) { + //return this.tableFunction.get(t_h); + int index_n = (int)((time_h-dataStartTime_h)/dataTimeStep_h); + if (enableProfileLooping && index_n >= a_profile.length) { + index_n = index_n % a_profile.length; + } else if ( index_n >= a_profile.length ) { + traceln("Time out of upper bound for evaluating J_EAProfile power in profile %s!", this.name); +// time_h = a_energyProfile_kWh.length * profileTimestep_h - 1; + throw new RuntimeException(String.format("Time out of upper bound for evaluating J_EAProfile power! Time is: %s", time_h)); + } + if ( index_n < 0 ) { + traceln("Time out of lower bound for evaluating J_EAProfile power in profile %s!", this.name); + throw new RuntimeException(String.format("Time out of lower bound for evaluating J_EAProfile power! Time is: %s", time_h)); + } + double currentValue_kW = this.a_profile[index_n]; + return currentValue_kW; } - + public double[] getAllValues() { - return this.tableFunction.getValues(); - } - - public TableFunction getTableFunction() { - return tableFunction; + //return this.tableFunction.getValues(); + return this.a_profile; } - public void setTableFunction(TableFunction tf) { - this.tableFunction = tf; + public double getDataTimeStep_h() { + return dataTimeStep_h; } public OL_ProfileUnits getProfileUnits() { From 53ced44bfb6290bb31d96b508736fa6ef93f60ab Mon Sep 17 00:00:00 2001 From: GillisHommen Date: Tue, 3 Feb 2026 09:56:19 +0100 Subject: [PATCH 9/9] Added nullcheck on profileUnits in constructor of J_ProfilePointer --- _alp/Classes/Class.J_ProfilePointer.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/_alp/Classes/Class.J_ProfilePointer.java b/_alp/Classes/Class.J_ProfilePointer.java index 7d158b4e..ea0003f8 100644 --- a/_alp/Classes/Class.J_ProfilePointer.java +++ b/_alp/Classes/Class.J_ProfilePointer.java @@ -34,10 +34,13 @@ public J_ProfilePointer() { } public J_ProfilePointer(String name, double[] profile, double dataTimeStep_h, double dataStartTime_h, OL_ProfileUnits profileUnits) { + if (profileUnits == null) { + throw new RuntimeException("Attemtping to create J_ProfilePointer with null profileUnits!"); + } this.name = name; this.a_profile = profile; this.dataTimeStep_h = dataTimeStep_h; - this.dataStartTime_h = dataStartTime_h; + this.dataStartTime_h = dataStartTime_h; this.profileUnits = profileUnits; } @@ -85,10 +88,4 @@ public String toString() { return "profile: " + this.name + " current value: " + this.currentValue; } - /** - * This number is here for model snapshot storing purpose
- * It needs to be changed when this class gets changed - */ - private static final long serialVersionUID = 1L; - } \ No newline at end of file