From 757ef488f752dc57dfbc63c7cc2b06781bc572e0 Mon Sep 17 00:00:00 2001 From: Naud Loomans <38351577+naudloomans@users.noreply.github.com> Date: Thu, 5 Feb 2026 13:55:14 +0100 Subject: [PATCH 1/2] Updates on stookdagen, ventilation, and increased irradiance to JEA_Building and avgc data --- Zero_engine.alpx | 2 +- _alp/Agents/EnergyModel/Code/Functions.java | 2 +- _alp/Agents/GCHouse/Levels/Level.level.xml | 12 ++++- _alp/Classes/Class.J_EABuilding.java | 21 +++++++-- _alp/Classes/Class.J_EAStorageHeat.java | 4 ++ .../Class.J_HeatingFunctionLibrary.java | 20 +++++++- .../Class.J_HeatingManagementSimple.java | 46 +++++++++++-------- _alp/Classes/Class.J_HeatingPreferences.java | 10 +++- 8 files changed, 89 insertions(+), 28 deletions(-) diff --git a/Zero_engine.alpx b/Zero_engine.alpx index 0fee2ff..d95ecf3 100644 --- a/Zero_engine.alpx +++ b/Zero_engine.alpx @@ -1,7 +1,7 @@ 1658477103134 diff --git a/_alp/Agents/EnergyModel/Code/Functions.java b/_alp/Agents/EnergyModel/Code/Functions.java index d7e5cd9..ae5bdda 100644 --- a/_alp/Agents/EnergyModel/Code/Functions.java +++ b/_alp/Agents/EnergyModel/Code/Functions.java @@ -205,7 +205,7 @@ double f_initializeForecasts() {/*ALCODESTART::1671636439933*/ -pf_ambientTemperature_degC = new J_ProfileForecaster(null, pp_ambientTemperature_degC, p_forecastTime_h, p_timeVariables.getT_h(), p_timeParameters.getTimeStep_h()); +pf_ambientTemperature_degC = new J_ProfileForecaster(null, pp_ambientTemperature_degC, 24, p_timeVariables.getT_h(), p_timeParameters.getTimeStep_h()); c_forecasts.add(pf_ambientTemperature_degC); pf_PVProduction35DegSouth_fr = new J_ProfileForecaster(null, pp_PVProduction35DegSouth_fr, p_forecastTime_h, p_timeVariables.getT_h(), p_timeParameters.getTimeStep_h()); diff --git a/_alp/Agents/GCHouse/Levels/Level.level.xml b/_alp/Agents/GCHouse/Levels/Level.level.xml index df8d4be..81de126 100644 --- a/_alp/Agents/GCHouse/Levels/Level.level.xml +++ b/_alp/Agents/GCHouse/Levels/Level.level.xml @@ -188,7 +188,7 @@ true LINEAR - Min + Building temp 1765380741625 my_dataset -2448096 @@ -197,6 +197,16 @@ NONE 1.0 + + Amb temp + 1770221619232 + my_dataset1 + -9728477 + energyModel.pp_ambientTemperature_degC.getCurrentValue() + true + NONE + 1.0 + 288 3 false diff --git a/_alp/Classes/Class.J_EABuilding.java b/_alp/Classes/Class.J_EABuilding.java index 61b7fdc..8a113d1 100644 --- a/_alp/Classes/Class.J_EABuilding.java +++ b/_alp/Classes/Class.J_EABuilding.java @@ -7,6 +7,7 @@ public class J_EABuilding extends zero_engine.J_EAStorageHeat implements Seriali private double solarAbsorptionFactor_m2; private double solarRadiation_Wpm2 = 0; + private double windowVentilation_fr; //Slider scaling factor private double lossScalingFactor_fr = 1; @@ -30,7 +31,7 @@ public J_EABuilding() { /** * Constructor initializing the fields */ - public J_EABuilding(I_AssetOwner owner, double capacityHeat_kW, double lossFactor_WpK, J_TimeParameters timeParameters, double initialTemperature_degC, double heatCapacity_JpK, double solarAbsorptionFactor_m2 ) { + public J_EABuilding(I_AssetOwner owner, double capacityHeat_kW, double lossFactor_WpK, J_TimeParameters timeParameters, double initialTemperature_degC, double heatCapacity_JpK, double solarAbsorptionFactor_m2) { this.setOwner(owner); this.timeParameters = timeParameters; this.capacityHeat_kW = capacityHeat_kW; @@ -63,7 +64,12 @@ public double solarHeating() { } - @Override + public double ventilationLoss( double lossPower_kW) { + double ventilationLoss_kW = this.windowVentilation_fr * lossPower_kW; + return ventilationLoss_kW; + } + + @Override public J_FlowPacket f_updateAllFlows(double powerFraction_fr, J_TimeVariables timeVariables) { if (powerFraction_fr > 1) { traceln("JEABuilding capacityHeat_kW is too low! "+ capacityHeat_kW); @@ -77,15 +83,18 @@ public void operate(double powerFraction_fr, J_TimeVariables timeVariables) { throw new RuntimeException("Cooling of the J_EABuilding is not yet supported."); } + double baseloadElectricityDemand_kW = 0; + double electricityToHeatConversion_fr = 0; double lossPower_kW = calculateLoss(); // Heat exchange with environment through convection + double ventilationLoss_kW = ventilationLoss(lossPower_kW); double solarHeating_kW = solarHeating(); // Heat influx from sunlight - this.energyUse_kW = lossPower_kW - solarHeating_kW; + this.energyUse_kW = lossPower_kW + ventilationLoss_kW - solarHeating_kW; this.energyUsed_kWh += max(0, this.energyUse_kW * this.timeParameters.getTimeStep_h()); // Only heat loss! Not heat gain when outside is hotter than inside! this.ambientEnergyAbsorbed_kWh += max(0, -this.energyUse_kW * this.timeParameters.getTimeStep_h()); // Only heat gain from outside air and/or solar irradiance! double inputPower_kW = powerFraction_fr * this.capacityHeat_kW; // positive power means lowering the buffer temperature! - double deltaEnergy_kWh = (solarHeating_kW - lossPower_kW)* this.timeParameters.getTimeStep_h(); + double deltaEnergy_kWh = (solarHeating_kW - (lossPower_kW + ventilationLoss_kW))* this.timeParameters.getTimeStep_h(); if (this.interiorDelayTime_h != 0.0) { deltaEnergy_kWh += getInteriorHeatRelease( inputPower_kW * this.timeParameters.getTimeStep_h() ); } @@ -133,6 +142,10 @@ public void setLossFactor_WpK( double lossFactor_WpK) { this.lossFactor_WpK = lossFactor_WpK; } + public void setWindowVentilation_fr( double ventilation_fr) { + this.windowVentilation_fr = ventilation_fr; + } + public void setLossScalingFactor_fr( double lossScalingFactor_fr) { this.lossScalingFactor_fr = lossScalingFactor_fr; } diff --git a/_alp/Classes/Class.J_EAStorageHeat.java b/_alp/Classes/Class.J_EAStorageHeat.java index e5b5d97..3b3e364 100644 --- a/_alp/Classes/Class.J_EAStorageHeat.java +++ b/_alp/Classes/Class.J_EAStorageHeat.java @@ -195,6 +195,10 @@ public double getLossFactor_WpK() { return lossFactor_WpK; } + public double getAmbientTemperature_degC() { + return ambientTemperature_degC; + } + public OL_AmbientTempType getAmbientTempType() { return this.ambientTempType; } diff --git a/_alp/Classes/Class.J_HeatingFunctionLibrary.java b/_alp/Classes/Class.J_HeatingFunctionLibrary.java index 7fb9b71..7cb9deb 100644 --- a/_alp/Classes/Class.J_HeatingFunctionLibrary.java +++ b/_alp/Classes/Class.J_HeatingFunctionLibrary.java @@ -2,7 +2,16 @@ * J_HeatingFunctionLibrary */ public abstract class J_HeatingFunctionLibrary { - + public static double heatingDaysSetpoint_degC = 18; + public static double heatLossByWindowVentilationMultiplier = 5; + /* + public void setHeatingDaysSetpoint_degC(double value) { + this.heatingDaysSetpoint_degC = value; + } + public double getHeatingDaysSetpoint_degC() { + return this.heatingDaysSetpoint_degC; + }*/ + public static double managePTAndHotWaterHeatBuffer(J_EAStorageHeat hotWaterBuffer, List ptAssets, double hotWaterDemand_kW, J_TimeVariables timeVariables, GridConnection gc){ //Calculate the pt production double ptProduction_kW = 0; @@ -67,6 +76,15 @@ public static double manageHotWaterHeatBuffer(J_EAStorageHeat hotWaterBuffer, d return hotWaterDemandFromHeatingAsset_kW; } + + public static void setWindowVentilation_fr( J_EABuilding dwelling, double windowOpenSetpoint_degc) { + double windowVentilation_fr = 0; + + if( dwelling.getCurrentTemperature() > windowOpenSetpoint_degc && dwelling.getAmbientTemperature_degC() < dwelling.getCurrentTemperature() ) { + windowVentilation_fr = heatLossByWindowVentilationMultiplier; + } + dwelling.setWindowVentilation_fr(windowVentilation_fr); + } } diff --git a/_alp/Classes/Class.J_HeatingManagementSimple.java b/_alp/Classes/Class.J_HeatingManagementSimple.java index 40f5cc5..1f23358 100644 --- a/_alp/Classes/Class.J_HeatingManagementSimple.java +++ b/_alp/Classes/Class.J_HeatingManagementSimple.java @@ -62,29 +62,39 @@ public void manageHeating(J_TimeVariables timeVariables) { double heatingAssetPower_kW = 0; - if(this.building != null) { - double buildingHeatingDemand_kW = 0; + if(this.building != null) { + double buildingHeatingDemand_kW = 0; double buildingTemp_degC = building.getCurrentTemperature(); double timeOfDay_h = timeVariables.getTimeOfDay_h(); - if (timeOfDay_h < heatingPreferences.getStartOfDayTime_h() || timeOfDay_h >= heatingPreferences.getStartOfNightTime_h()) { - if (buildingTemp_degC < heatingPreferences.getNightTimeSetPoint_degC()) { - // Nighttime and building temperature too low - buildingHeatingDemand_kW = (heatingPreferences.getNightTimeSetPoint_degC() - buildingTemp_degC) * this.building.heatCapacity_JpK / 3.6e6 / timeParameters.getTimeStep_h(); - } - else { - // Nighttime and building temperature acceptable - } + J_HeatingFunctionLibrary.setWindowVentilation_fr(this.building, heatingPreferences.getWindowOpenSetpoint_degc() ); + + //Stookdagen approximation > boven 18 graden is niet verwarmen + double avgTemp24h_degC = gc.energyModel.pf_ambientTemperature_degC.getForecast(); + if(avgTemp24h_degC > J_HeatingFunctionLibrary.heatingDaysSetpoint_degC) { + buildingHeatingDemand_kW = max(0,J_HeatingFunctionLibrary.heatingDaysSetpoint_degC - buildingTemp_degC) * this.building.heatCapacity_JpK / 3.6e6 / timeParameters.getTimeStep_h(); } + ///On heating days else { - if (buildingTemp_degC < heatingPreferences.getDayTimeSetPoint_degC()) { - // Daytime and building temperature too low - buildingHeatingDemand_kW = (heatingPreferences.getDayTimeSetPoint_degC() - buildingTemp_degC) * this.building.heatCapacity_JpK / 3.6e6 / timeParameters.getTimeStep_h(); - } - else { - // Daytime and building temperature acceptable - } + if (timeOfDay_h < heatingPreferences.getStartOfDayTime_h() || timeOfDay_h >= heatingPreferences.getStartOfNightTime_h()) { + + if (buildingTemp_degC < heatingPreferences.getNightTimeSetPoint_degC()) { + // Nighttime and building temperature too low + buildingHeatingDemand_kW = (heatingPreferences.getNightTimeSetPoint_degC() - buildingTemp_degC) * this.building.heatCapacity_JpK / 3.6e6 / timeParameters.getTimeStep_h(); + } + else { + // Nighttime and building temperature acceptable + } + } + else { + if (buildingTemp_degC < heatingPreferences.getDayTimeSetPoint_degC()) { + // Daytime and building temperature too low + buildingHeatingDemand_kW = (heatingPreferences.getDayTimeSetPoint_degC() - buildingTemp_degC) * this.building.heatCapacity_JpK / 3.6e6 / timeParameters.getTimeStep_h(); + } + else { + // Daytime and building temperature acceptable + } + } } - heatingAssetPower_kW = min(heatingAsset.getOutputCapacity_kW(),buildingHeatingDemand_kW + heatDemand_kW); // minimum not strictly needed as asset will limit power by itself. Could be used later if we notice demand is higher than capacity of heating asset. double heatIntoBuilding_kW = max(0, heatingAssetPower_kW - heatDemand_kW); // Will lead to energy(heat) imbalance when heatDemand_kW is larger than heating asset capacity. gc.f_updateFlexAssetFlows(building, heatIntoBuilding_kW / building.getCapacityHeat_kW(), timeVariables); diff --git a/_alp/Classes/Class.J_HeatingPreferences.java b/_alp/Classes/Class.J_HeatingPreferences.java index 74b0105..0be5fc7 100644 --- a/_alp/Classes/Class.J_HeatingPreferences.java +++ b/_alp/Classes/Class.J_HeatingPreferences.java @@ -10,6 +10,7 @@ public class J_HeatingPreferences { private double startOfNightTime_h = 23; private double dayTimeSetPoint_degC = 20; private double nightTimeSetPoint_degC = 18; + private double windowOpenSetpoint_degC = 25; private double maxComfortTemperature_degC = dayTimeSetPoint_degC + 3; private double minComfortTemperature_degC = dayTimeSetPoint_degC - 2; @@ -17,7 +18,7 @@ public class J_HeatingPreferences { public J_HeatingPreferences() { } - public J_HeatingPreferences(double startOfDayTime_h, double startOfNightTime_h, double dayTimeSetPoint_degC, double nightTimeSetPoint_degC, double maxComfortTemperature_degC, double minComfortTemperature_degC) { + public J_HeatingPreferences(double startOfDayTime_h, double startOfNightTime_h, double dayTimeSetPoint_degC, double nightTimeSetPoint_degC, double maxComfortTemperature_degC, double minComfortTemperature_degC, double windowOpenSetpoint_degC) { this.startOfDayTime_h = startOfDayTime_h; this.startOfNightTime_h = startOfNightTime_h; @@ -25,6 +26,7 @@ public J_HeatingPreferences(double startOfDayTime_h, double startOfNightTime_h, this.nightTimeSetPoint_degC = nightTimeSetPoint_degC; this.maxComfortTemperature_degC = maxComfortTemperature_degC; this.minComfortTemperature_degC = minComfortTemperature_degC; + this.windowOpenSetpoint_degC = windowOpenSetpoint_degC; } //Setters @@ -66,6 +68,9 @@ public double getMaxComfortTemperature_degC() { public double getMinComfortTemperature_degC() { return this.minComfortTemperature_degC; } + public double getWindowOpenSetpoint_degc() { + return this.windowOpenSetpoint_degC; + } public double getCurrentPreferedTemperatureSetpoint_degC(double timeOfDay_h) { if (timeOfDay_h < getStartOfDayTime_h() || timeOfDay_h >= getStartOfNightTime_h()) { @@ -84,7 +89,8 @@ public String toString() { ", DayTimeSetPoint_degC = " + this.dayTimeSetPoint_degC + ", NightTimeSetPoint_degC = " + this.nightTimeSetPoint_degC + ", MaxComfortTemperature_degC = " + this.maxComfortTemperature_degC + - ", MinComfortTemperature_degC = " + this.minComfortTemperature_degC; + ", MinComfortTemperature_degC = " + this.minComfortTemperature_degC + + ", WindowOpenSetpoint_degC = " + this.windowOpenSetpoint_degC; } } \ No newline at end of file From f0f7a5ca0e37deb393fdf9a83504619d38ad1818 Mon Sep 17 00:00:00 2001 From: Naud Loomans <38351577+naudloomans@users.noreply.github.com> Date: Thu, 5 Feb 2026 13:56:58 +0100 Subject: [PATCH 2/2] Update from main --- _alp/Classes/J_EABuilding.java | 287 +++++++++++++++++++++++++++++++++ 1 file changed, 287 insertions(+) create mode 100644 _alp/Classes/J_EABuilding.java diff --git a/_alp/Classes/J_EABuilding.java b/_alp/Classes/J_EABuilding.java new file mode 100644 index 0000000..c0fb90e --- /dev/null +++ b/_alp/Classes/J_EABuilding.java @@ -0,0 +1,287 @@ +/** + * J_EABuilding + */ +//import com.fasterxml.jackson.annotation.JsonTypeName; +//@JsonTypeName("J_EABuilding") +public class J_EABuilding extends zero_engine.J_EAStorageHeat implements Serializable { + + private double solarAbsorptionFactor_m2; + private double solarRadiation_Wpm2 = 0; + private double windowVentilation_fr; + + //Slider scaling factor + private double lossScalingFactor_fr = 1; + + // Optional Interior/Exterior Heat buffers + private double interiorDelayTime_h; + private double[] interiorReleaseSchedule_kWh; + private double[] interiorReleaseScheduleStored_kWh; + private int interiorReleaseScheduleIndex; + private double exteriorDelayTime_h; + private double[] exteriorReleaseSchedule_kWh; + private double[] exteriorReleaseScheduleStored_kWh; + private int exteriorReleaseScheduleIndex; + + /** + * Default constructor + */ + public J_EABuilding() { + } + + /** + * Constructor initializing the fields + */ + public J_EABuilding(I_AssetOwner owner, double capacityHeat_kW, double lossFactor_WpK, J_TimeParameters timeParameters, double initialTemperature_degC, double heatCapacity_JpK, double solarAbsorptionFactor_m2) { + this.setOwner(owner); + this.timeParameters = timeParameters; + this.capacityHeat_kW = capacityHeat_kW; + this.lossFactor_WpK = lossFactor_WpK; + this.initialTemperature_degC = initialTemperature_degC; + this.temperature_degC = initialTemperature_degC; + this.heatCapacity_JpK = heatCapacity_JpK; + this.ambientTempType = OL_AmbientTempType.AMBIENT_AIR; + this.solarAbsorptionFactor_m2 = solarAbsorptionFactor_m2; + this.energyAssetType = OL_EnergyAssetType.BUILDINGTHERMALS; + if (lossFactor_WpK < 0) { + throw new RuntimeException(String.format("Exception: J_EABuilding with negative lossfactor! %s", lossFactor_WpK)); + } + + this.activeProductionEnergyCarriers.add(OL_EnergyCarriers.HEAT); + this.activeConsumptionEnergyCarriers.add(OL_EnergyCarriers.HEAT); + this.assetFlowCategory = OL_AssetFlowCategories.spaceHeating_kW; + registerEnergyAsset(timeParameters); + } + + @Override + public double calculateLoss() { + double heatLoss_kW = (this.lossFactor_WpK * ( this.temperature_degC - this.ambientTemperature_degC ) / 1000) * lossScalingFactor_fr; + return heatLoss_kW; + } + + public double solarHeating() { + double solarHeating_kW = this.solarAbsorptionFactor_m2 * this.solarRadiation_Wpm2 / 1000; + return solarHeating_kW; + + } + + public double ventilationLoss( double lossPower_kW) { + double ventilationLoss_kW = this.windowVentilation_fr * lossPower_kW; + return ventilationLoss_kW; + } + + @Override + public J_FlowPacket f_updateAllFlows(double powerFraction_fr, J_TimeVariables timeVariables) { + if (powerFraction_fr > 1) { + traceln("JEABuilding capacityHeat_kW is too low! "+ capacityHeat_kW); + } + return super.f_updateAllFlows(powerFraction_fr, timeVariables); + } + + @Override + public void operate(double powerFraction_fr, J_TimeVariables timeVariables) { + + if (DoubleCompare.lessThanZero(powerFraction_fr)) { + throw new RuntimeException("Cooling of the J_EABuilding is not yet supported."); + } + double lossPower_kW = calculateLoss(); // Heat exchange with environment through convection + double ventilationLoss_kW = ventilationLoss(lossPower_kW); + double solarHeating_kW = solarHeating(); // Heat influx from sunlight + this.energyUse_kW = lossPower_kW + ventilationLoss_kW - solarHeating_kW; + this.energyUsed_kWh += max(0, this.energyUse_kW * this.timeParameters.getTimeStep_h()); // Only heat loss! Not heat gain when outside is hotter than inside! + this.ambientEnergyAbsorbed_kWh += max(0, -this.energyUse_kW * this.timeParameters.getTimeStep_h()); // Only heat gain from outside air and/or solar irradiance! + + double inputPower_kW = powerFraction_fr * this.capacityHeat_kW; // positive power means lowering the buffer temperature! + + double deltaEnergy_kWh = (solarHeating_kW - (lossPower_kW + ventilationLoss_kW))* this.timeParameters.getTimeStep_h(); + if (this.interiorDelayTime_h != 0.0) { + deltaEnergy_kWh += getInteriorHeatRelease( inputPower_kW * this.timeParameters.getTimeStep_h() ); + } + else { + deltaEnergy_kWh += inputPower_kW * this.timeParameters.getTimeStep_h(); // to check the request with the energy currently in storage + } + updateStateOfCharge( deltaEnergy_kWh ); + + this.heatCharged_kWh += inputPower_kW * this.timeParameters.getTimeStep_h(); + + this.flowsMap.put(OL_EnergyCarriers.HEAT, inputPower_kW); + + if (this.assetFlowCategory != null) { + assetFlowsMap.put(this.assetFlowCategory, inputPower_kW); + } + } + + @Override + public String toString() { + return + this.getClass().toString() + " " + + "energyUsed_kWh (heat losses) = " + this.energyUsed_kWh + "kWh, " + + "temp = " + this.temperature_degC + ", " + + "lossFactor_WpK = " + this.lossFactor_WpK + ", "+ + "heatCapacity_JpK = " + this.heatCapacity_JpK; + } + + @Override + protected void updateStateOfCharge( double deltaEnergy_kWh ) { + double tempDelta_degC = deltaEnergy_kWh / (this.heatCapacity_JpK / 3.6E6 ); + this.temperature_degC += tempDelta_degC; + } + + @Override + public double getCurrentTemperature() { + return this.temperature_degC; + } + + @Override + public double getLossFactor_WpK() { + return this.lossFactor_WpK; + } + + public void setLossFactor_WpK( double lossFactor_WpK) { + this.lossFactor_WpK = lossFactor_WpK; + } + + public void setWindowVentilation_fr( double ventilation_fr) { + this.windowVentilation_fr = ventilation_fr; + } + + public void setLossScalingFactor_fr( double lossScalingFactor_fr) { + this.lossScalingFactor_fr = lossScalingFactor_fr; + } + + public double getLossScalingFactor_fr() { + return this.lossScalingFactor_fr; + } + + @Override + public void storeStatesAndReset() { + // Each energy asset that has some states should overwrite this function! + this.energyUsedStored_kWh = this.energyUsed_kWh; + this.ambientEnergyAbsorbedStored_kWh = this.ambientEnergyAbsorbed_kWh; + this.energyUsed_kWh = 0.0; + this.ambientEnergyAbsorbed_kWh = 0.0; + this.temperatureStored_degC = this.temperature_degC; + this.temperature_degC = this.initialTemperature_degC; + if (this.interiorReleaseSchedule_kWh != null) { + this.interiorReleaseScheduleStored_kWh = this.interiorReleaseSchedule_kWh; + Arrays.fill(this.interiorReleaseSchedule_kWh, 0.0); + } + if (this.exteriorReleaseSchedule_kWh != null) { + this.exteriorReleaseScheduleStored_kWh = this.exteriorReleaseSchedule_kWh; + Arrays.fill(this.exteriorReleaseSchedule_kWh, 0.0); + } + clear(); + } + + @Override + public void restoreStates() { + // Each energy asset that has some states should overwrite this function! + this.energyUsed_kWh = this.energyUsedStored_kWh; + this.ambientEnergyAbsorbed_kWh = this.ambientEnergyAbsorbedStored_kWh; + this.temperature_degC = this.temperatureStored_degC; + this.interiorReleaseSchedule_kWh = this.interiorReleaseScheduleStored_kWh; + this.exteriorReleaseSchedule_kWh = this.exteriorReleaseScheduleStored_kWh; + } + + /*@Override //Storage assets limiteren de opname van warmte niet met 1. Dat is nodig voor de buffer. Die kan wel maximaal zijn capaciteit leverern, maar kan meer opnemen. @Gillis is dat logisch of willen we andere oplossing? + public double[] operateBounded(double ratioOfCapacity) { + double limitedRatioOfCapacity = max(-1, ratioOfCapacity); + double[] arr = operate(limitedRatioOfCapacity); + return arr; + }*/ + + @Override + public void updateAmbientTemperature(double currentAmbientTemperature_degC) { // TODO: Hoe zorgen we dat we deze niet vergeten aan te roepen?? + this.ambientTemperature_degC = currentAmbientTemperature_degC; + } + + public void updateSolarRadiation(double solarRadiation_Wpm2) { // TODO: Hoe zorgen we dat we deze niet vergeten aan te roepen?? + this.solarRadiation_Wpm2 = solarRadiation_Wpm2; + } + + + // Methods for Optional Heat Buffer + // Interior heat buffer may represent the radiator or floor heating. Typical delay is 0.5 or 3 hours respectively. + public void addInteriorHeatBuffer(double delayTime_h) { + this.interiorDelayTime_h = delayTime_h; + this.interiorReleaseSchedule_kWh = new double[ (int)(delayTime_h / this.timeParameters.getTimeStep_h()) ]; + this.interiorReleaseScheduleIndex = 0; + } + + // Exterior heat buffer may represent the walls and roof of the building. Typical delay is 8 hours. + public void addExteriorHeatBuffer(double delayTime_h) { + this.exteriorDelayTime_h = delayTime_h; + this.exteriorReleaseSchedule_kWh = new double[ (int)(delayTime_h / this.timeParameters.getTimeStep_h()) ]; + this.exteriorReleaseScheduleIndex = 0; + } + + private double getInteriorHeatRelease(double heatAbsorbed_kWh) { + // Distribute the added energy evenly over the release schedule + //traceln("Interior schedule before: " + Arrays.toString(this.interiorReleaseSchedule_kWh)); + for (int x = 0; x < this.interiorReleaseSchedule_kWh.length; x++) { + this.interiorReleaseSchedule_kWh[x] += heatAbsorbed_kWh / this.interiorReleaseSchedule_kWh.length; + } + // Store the current value + double heatReleased_kWh = this.interiorReleaseSchedule_kWh[this.interiorReleaseScheduleIndex]; + // Reset the current value + this.interiorReleaseSchedule_kWh[this.interiorReleaseScheduleIndex] = 0; + // Shift over the index + this.interiorReleaseScheduleIndex++; + this.interiorReleaseScheduleIndex = this.interiorReleaseScheduleIndex % this.interiorReleaseSchedule_kWh.length; + //traceln("Interior schedule after: " + Arrays.toString(this.interiorReleaseSchedule_kWh)); + + return heatReleased_kWh; + } + + private double getExteriorHeatRelease(double heatAbsorbed_kWh) { + // Distribute the added energy evenly over the release schedule + for (int x = 0; x < this.exteriorReleaseSchedule_kWh.length; x++) { + this.exteriorReleaseSchedule_kWh[x] += heatAbsorbed_kWh / this.exteriorReleaseSchedule_kWh.length; + } + // Store the current value + double heatReleased_kWh = this.exteriorReleaseSchedule_kWh[this.exteriorReleaseScheduleIndex]; + // Reset the current value + this.exteriorReleaseSchedule_kWh[this.exteriorReleaseScheduleIndex] = 0; + // Shift over the index + this.exteriorReleaseScheduleIndex++; + this.exteriorReleaseScheduleIndex = this.exteriorReleaseScheduleIndex % this.exteriorReleaseSchedule_kWh.length; + + return heatReleased_kWh; + } + + @Override + public double getRemainingHeatStorageHeat_kWh() { + double remainingHeatStorageHeat_kWh = super.getRemainingHeatStorageHeat_kWh(); + remainingHeatStorageHeat_kWh += getRemainingHeatBufferHeat_kWh(); + return remainingHeatStorageHeat_kWh; + } + + public double getRemainingHeatBufferHeat_kWh() { + double remainingHeatBufferHeat_kWh = 0; + if( this.interiorDelayTime_h != 0.0) { + for (int x = 0; x < this.interiorReleaseSchedule_kWh.length; x++) { + remainingHeatBufferHeat_kWh += this.interiorReleaseSchedule_kWh[x]; + } + } + if( this.exteriorDelayTime_h != 0.0) { + for (int x = 0; x < this.exteriorReleaseSchedule_kWh.length; x++) { + remainingHeatBufferHeat_kWh += this.exteriorReleaseSchedule_kWh[x]; + } + } + return remainingHeatBufferHeat_kWh; + } + + public boolean hasHeatBuffer() { + if (this.exteriorDelayTime_h != 0 || this.interiorDelayTime_h != 0) { + return true; + } + else { + return false; + } + } + /** + * 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; +} +