diff --git a/Zero_engine.alpx b/Zero_engine.alpx index 52ebee94..2778c986 100644 --- a/Zero_engine.alpx +++ b/Zero_engine.alpx @@ -971,7 +971,7 @@ + diff --git a/_alp/Agents/EnergyModel/Code/Functions.java b/_alp/Agents/EnergyModel/Code/Functions.java index 8d01fd37..756982fc 100644 --- a/_alp/Agents/EnergyModel/Code/Functions.java +++ b/_alp/Agents/EnergyModel/Code/Functions.java @@ -401,8 +401,8 @@ null, roundToDecimal( a.v_electricityImported_kWh-a.v_electricityExported_kWh, 2 {/*ALCODESTART::1664952601107*/ b_isDaytime = t_h % 24 > 6 && t_h % 24 < 18; b_isWeekday = (t_h+(v_dayOfWeek1jan-1)*24) % (24*7) < (24*5); -b_isSummerWeek = t_h >= p_startHourSummerWeek && t_h < p_startHourSummerWeek + 24*7; -b_isWinterWeek = t_h >= p_startHourWinterWeek && t_h < p_startHourWinterWeek + 24*7; +b_isSummerWeek = (t_h % 8760) >= p_startHourSummerWeek && (t_h % 8760) < p_startHourSummerWeek + 24*7; +b_isWinterWeek = (t_h % 8760) >= p_startHourWinterWeek && (t_h % 8760) < p_startHourWinterWeek + 24*7; b_isLastTimeStepOfDay = t_h % 24 == (24-p_timeStep_h); t_hourOfDay = t_h % 24; // Assumes modelrun starts at midnight. @@ -1255,8 +1255,6 @@ null, roundToDecimal( a.v_electricityImported_kWh-a.v_electricityExported_kWh, 2 traceln("Energy export: "+ v_totalEnergyExport_MWh + " MWh"); // *** Total energy balance *** -//double electricityProduced_MWh = 0; -//double totalDistanceTrucks_km = 0; double deltaThermalEnergySinceStart_MWh = 0; double totalAmbientHeating_MWh = 0; double totalEnergyCurtailed_MWh = 0; @@ -1266,18 +1264,8 @@ null, roundToDecimal( a.v_electricityImported_kWh-a.v_electricityExported_kWh, 2 double totalHeatProduced_MWh = 0; for (J_EA e : c_energyAssets) { if (((GridConnection) e.getParentAgent()).v_isActive ) { - double EnergyUsed_kWh = e.getEnergyUsed_kWh(); - //double electricityProduced_kWh = 0; - - //energyConsumed_MWh += max(0,EnergyUsed_kWh)/1000; - //energyProduced_MWh +=max(0,-EnergyUsed_kWh)/1000; if (EnergyUsed_kWh > 0) { - - /*if (e instanceof J_EAConversionCurtailer || e instanceof J_EAConversionCurtailerHeat) { - totalEnergyProduced_MWh -= EnergyUsed_kWh/1000; - totalEnergyCurtailed_MWh += EnergyUsed_kWh/1000; - } else */ if( e instanceof J_EAConversionGasCHP ) { totalEnergyUsed_MWh += EnergyUsed_kWh/1000; //electricityProduced_kWh = ((J_EAConversionGasCHP)e).getElectricityProduced_kWh(); @@ -1291,9 +1279,6 @@ null, roundToDecimal( a.v_electricityImported_kWh-a.v_electricityExported_kWh, 2 deltaThermalEnergySinceStart_MWh += ((J_EABuilding)e).getRemainingHeatBufferHeat_kWh() / 1000; } } else { - /*if( e.energyAssetType == OL_EnergyAssetType.PHOTOVOLTAIC || e.energyAssetType == OL_EnergyAssetType.WINDMILL){ - electricityProduced_MWh -= EnergyUsed_kWh/1000; - }*/ totalEnergyProduced_MWh -= EnergyUsed_kWh/1000; if ( e instanceof J_EABuilding ) { traceln("Building has produced more energy than it has used?? Is lossfactor too low?"); @@ -1314,16 +1299,10 @@ null, roundToDecimal( a.v_electricityImported_kWh-a.v_electricityExported_kWh, 2 } double v_totalDeltaStoredEnergy_MWh = v_batteryStoredEnergyDeltaSinceStart_MWh + deltaThermalEnergySinceStart_MWh; // Positive number means more energy stored at the end of the simulation. - - -//traceln("Trucks have traveled " + totalDistanceTrucks_km + " km"); - //Total selfconsumption, selfsufficiency - v_totalEnergySelfConsumed_MWh = v_totalEnergyConsumed_MWh - (v_totalEnergyImport_MWh + max(0,-v_totalDeltaStoredEnergy_MWh)); // Putting positive delta-stored energy here assumes this energy was imported as opposed to self-produced. Putting negative delta-stored energy here assumes this energy was self-consumed, as opposed to exported. //v_totalSelfConsumedEnergy_MWh = totalEnergyUsed_MWh - (v_totalImportedEnergy_MWh + max(0,-v_totalDeltaStoredEnergy_MWh)); // Putting positive delta-stored energy here assumes this energy was imported as opposed to self-produced. Putting negative delta-stored energy here assumes this energy was self-consumed, as opposed to exported. - // Export and production-based selfconsumption if ( v_totalEnergyProduced_MWh > 0 ){ v_modelSelfConsumption_fr = v_totalEnergySelfConsumed_MWh / v_totalEnergyProduced_MWh; @@ -1351,8 +1330,8 @@ null, roundToDecimal( a.v_electricityImported_kWh-a.v_electricityExported_kWh, 2 // Remaining difference due to different temps of houses start vs end? traceln(""); for (OL_EnergyCarriers EC : v_activeEnergyCarriers) { - traceln("Import " + EC.toString() + ": " + v_rapidRunData.am_totalBalanceAccumulators_kW.get(EC).getIntegralPos_kWh()/1000 + " MWh"); - traceln("Export " + EC.toString() + ": " + v_rapidRunData.am_totalBalanceAccumulators_kW.get(EC).getIntegralNeg_kWh()/1000 + " MWh"); + traceln("Import " + EC.toString() + ": " + v_rapidRunData.getTotalImport_MWh(EC) + " MWh"); + traceln("Export " + EC.toString() + ": " + v_rapidRunData.getTotalExport_MWh(EC) + " MWh"); } traceln(""); @@ -1377,36 +1356,6 @@ null, roundToDecimal( a.v_electricityImported_kWh-a.v_electricityExported_kWh, 2 } -/* -traceln( "import electricity: " + v_totalElectricityImport_MWh + " MWh"); -traceln( "export electricity: " + v_totalElectricityExport_MWh + " MWh"); -traceln( "nett import methane: " + (v_totalMethaneImport_MWh-v_totalMethaneExport_MWh) + " MWh"); -traceln( "import diesel: " + v_totalDieselImport_MWh + " MWh"); -traceln( "nett import hydrogen: " + (v_totalHydrogenImport_MWh-v_totalHydrogenExport_MWh) + " MWh"); -*/ - -/*// intStream.parallel experiment works to extract daytime consumption! Now benchmark performance... -double daytimeEnergyUsed_MWh = IntStream.range(0, a_annualDaytimeIdxs.length).parallel().mapToDouble(idx -> a_annualEnergyConsumption_kW[idx]*a_annualDaytimeIdxs[idx]).sum()*p_timeStep_h/1000; -traceln("v_daytimeEnergyUsed_MWh: %s, daytimeEnergyUsed_MWh: %s", v_daytimeEnergyUsed_MWh, daytimeEnergyUsed_MWh); -*/ -/*for (int i = 0; i<365; i++) { // Check if accumulator with signal resolution different from timestep still gives consistent results - if (abs(data_annualElectricityDemand_MWh.getY(i) - acc_annualDailyElectricityDemand_MWh.getTimeSeries()[i]) > 0.0001) { - traceln("Dataset and accumulator don't agree about daily electricity demand on day no. %s, dataset value: %s, accumulator value: %s", i, data_annualElectricityDemand_MWh.getY(i), acc_annualDailyElectricityDemand_MWh.getTimeSeries()[i]); - } -}*/ - -/*if ( abs(acc_annualElectricityBalanceDownsampled_kW.getIntegral()-acc_annualElectricityBalance_kW.getIntegral()) > 0.1 ) { // Check if reduced resolution accumulator gives same integral result! - traceln("Accumulators with different signal resolution DON'T agree on integral: full-res integral: %s, low-res integral: %s", acc_annualElectricityBalanceDownsampled_kW.getIntegral(), acc_annualElectricityBalance_kW.getIntegral()); -} else { - traceln("Accumulators with different signal resolution AGREE on integral: full-res integral: %s, low-res integral: %s", acc_annualElectricityBalanceDownsampled_kW.getIntegral(), acc_annualElectricityBalance_kW.getIntegral()); -}*/ - -//double nettElectricityArray_kWh = Arrays.stream( a_annualElectricityBalance_kW ).sum() * p_timeStep_h / 1000; -//double nettElectricityAccumulator_kWh = acc_annualElectricityBalance_kW.getSum() * p_timeStep_h / 1000; -//double importElectricityAccumulator_kWh = acc_annualElectricityBalance_kW.getSumPos() * p_timeStep_h / 1000; -//traceln("Test ZeroAccumulator: importElectricityAccumulator_kWh: %s kWh, nettElectricityAccumulator_kWh: %s kWh", importElectricityAccumulator_kWh, nettElectricityAccumulator_kWh); - - /*ALCODEEND*/} double f_resetAnnualValues() diff --git a/_alp/Agents/GCUtility/Code/Functions.java b/_alp/Agents/GCUtility/Code/Functions.java index c1370805..4689376d 100644 --- a/_alp/Agents/GCUtility/Code/Functions.java +++ b/_alp/Agents/GCUtility/Code/Functions.java @@ -14,8 +14,8 @@ case BALANCE: f_batteryManagementBalance(p_batteryAsset.getCurrentStateOfCharge()); break; - case SIMPLE: - f_batteryManagementSimple(); + case SELF_CONSUMPTION: + f_batteryManagementSelfConsumption(); break; case PRICE: f_batteryManagementPrice(p_batteryAsset.getCurrentStateOfCharge()); diff --git a/_alp/Agents/GridConnection/Code/Functions.java b/_alp/Agents/GridConnection/Code/Functions.java index 4b7f73bf..db06ebbe 100644 --- a/_alp/Agents/GridConnection/Code/Functions.java +++ b/_alp/Agents/GridConnection/Code/Functions.java @@ -1917,7 +1917,19 @@ else if (j_ea.energyAssetType == OL_EnergyAssetType.CHP) { } } break; - case PRICE: + case MARKETPRICE: + 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.curtailElectricityProduction( - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY)); + if (!(fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) < 0.0)) { + break; + } + } + } + } + break; + case NODALPRICING: // Prevent feedin when nodal price is negative double priceTreshold_eur = -0.0; if(l_parentNodeElectric.getConnectedAgent().v_currentTotalNodalPrice_eurpkWh < priceTreshold_eur) { @@ -2514,28 +2526,12 @@ else if (flowsMap.get(EC) > 0){ /*ALCODEEND*/} -double f_batteryManagementSimple() +double f_batteryManagementSelfConsumption() {/*ALCODESTART::1725629047745*/ -//traceln("Battery storage capacity: " + ((J_EAStorageElectric)p_batteryAsset.j_ea).getStorageCapacity_kWh()); if (p_batteryAsset.getStorageCapacity_kWh() != 0){ - - double safetyMargin_fr = 0.95; // fraction of connection capacity that we use - double power_fr = 0; - double capacityElectric_kW = p_batteryAsset.getCapacityElectric_kW(); - - if (fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) > v_liveConnectionMetaData.contractedFeedinCapacity_kW * safetyMargin_fr) { - // discharge - double dischargeNeeded_kW = fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) - v_liveConnectionMetaData.contractedFeedinCapacity_kW * safetyMargin_fr; - power_fr = - dischargeNeeded_kW / capacityElectric_kW; - } - else if (fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY) < v_liveConnectionMetaData.contractedDeliveryCapacity_kW * safetyMargin_fr) { - // charge - double chargeAvailable_kW = v_liveConnectionMetaData.contractedDeliveryCapacity_kW * safetyMargin_fr - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY); - power_fr = chargeAvailable_kW / capacityElectric_kW; - } - - - p_batteryAsset.v_powerFraction_fr = max(-1,min(1, power_fr)); + double chargeSetpoint_kW = - fm_currentBalanceFlows_kW.get(OL_EnergyCarriers.ELECTRICITY); + // limit charging power to battery max power. + p_batteryAsset.v_powerFraction_fr = max(-1,min(1, chargeSetpoint_kW / p_batteryAsset.getCapacityElectric_kW())); } /*ALCODEEND*/} diff --git a/_alp/Agents/GridConnection/Code/Functions.xml b/_alp/Agents/GridConnection/Code/Functions.xml index 981fbab0..b3e60b62 100644 --- a/_alp/Agents/GridConnection/Code/Functions.xml +++ b/_alp/Agents/GridConnection/Code/Functions.xml @@ -729,9 +729,9 @@ VOID double 1725629047745 - - 1230 - 820 + + 920 + 260