diff --git a/.bashrc b/.bashrc
new file mode 100755
index 00000000..e69de29b
diff --git a/.gitignore b/.gitignore
index 3a6fb92c..5ad1217c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,4 +5,5 @@
*/.project
*/.settings
facedb.lck
-doxygenDoc
\ No newline at end of file
+doxygenDoc
+*/.Rapp.history
\ No newline at end of file
diff --git a/emlab-generation/.gitignore b/emlab-generation/.gitignore
index 2bccf602..9d9d5d04 100644
--- a/emlab-generation/.gitignore
+++ b/emlab-generation/.gitignore
@@ -2,3 +2,4 @@
*.log
log.roo
facedb.properties
+/target/
diff --git a/emlab-generation/.settings/org.eclipse.jdt.core.prefs b/emlab-generation/.settings/org.eclipse.jdt.core.prefs
index 62f2a6ac..496aa72b 100644
--- a/emlab-generation/.settings/org.eclipse.jdt.core.prefs
+++ b/emlab-generation/.settings/org.eclipse.jdt.core.prefs
@@ -9,6 +9,10 @@ org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
diff --git a/emlab-generation/.settings/org.eclipse.jdt.ui.prefs b/emlab-generation/.settings/org.eclipse.jdt.ui.prefs
index 12da70c5..912ea7cc 100644
--- a/emlab-generation/.settings/org.eclipse.jdt.ui.prefs
+++ b/emlab-generation/.settings/org.eclipse.jdt.ui.prefs
@@ -78,10 +78,12 @@ sp_cleanup.always_use_blocks=true
sp_cleanup.always_use_parentheses_in_expressions=false
sp_cleanup.always_use_this_for_non_static_field_access=false
sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_functional_interfaces=false
sp_cleanup.convert_to_enhanced_for_loop=false
sp_cleanup.correct_indentation=true
sp_cleanup.format_source_code=true
-sp_cleanup.format_source_code_changes_only=true
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.insert_inferred_type_arguments=false
sp_cleanup.make_local_variable_final=false
sp_cleanup.make_parameters_final=false
sp_cleanup.make_private_fields_final=true
@@ -89,7 +91,7 @@ sp_cleanup.make_type_abstract_if_missing_method=false
sp_cleanup.make_variable_declarations_final=true
sp_cleanup.never_use_blocks=false
sp_cleanup.never_use_parentheses_in_expressions=true
-sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.on_save_use_additional_actions=false
sp_cleanup.organize_imports=true
sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
@@ -97,6 +99,7 @@ sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_redundant_type_arguments=false
sp_cleanup.remove_trailing_whitespaces=true
sp_cleanup.remove_trailing_whitespaces_all=true
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
@@ -110,10 +113,13 @@ sp_cleanup.remove_unused_private_methods=true
sp_cleanup.remove_unused_private_types=true
sp_cleanup.sort_members=false
sp_cleanup.sort_members_all=false
+sp_cleanup.use_anonymous_class_creation=false
sp_cleanup.use_blocks=false
sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_lambda=false
sp_cleanup.use_parentheses_in_expressions=false
sp_cleanup.use_this_for_non_static_field_access=false
sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
sp_cleanup.use_this_for_non_static_method_access=false
sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
+sp_cleanup.use_type_arguments=false
diff --git a/emlab-generation/.springBeans b/emlab-generation/.springBeans
new file mode 100644
index 00000000..7e2d7ea4
--- /dev/null
+++ b/emlab-generation/.springBeans
@@ -0,0 +1,15 @@
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/emlab-generation/queries-Ranalysis.properties b/emlab-generation/queries-Ranalysis.properties
index bb8edd63..12b65fdc 100644
--- a/emlab-generation/queries-Ranalysis.properties
+++ b/emlab-generation/queries-Ranalysis.properties
@@ -831,4 +831,16 @@ segmentID=s.out('SEGMENTLOAD_SEGMENT').collect{it.segmentID}[0]
hours=s.out('SEGMENTLOAD_SEGMENT').collect{it.lengthInHours}[0]
finalResult.add([tick, s.baseLoad*growthfactor, market, segmentID, hours])
}
-return finalResult",
\ No newline at end of file
+return finalResult",
+
+"TABLE_FinancialReports", "DecarbonizationModel", "financialReports=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.FinancialPowerPlantReport']].filter{it.time==tick};
+finalResult = [];
+columnNames=['tick', 'spotMarketRevenue', 'capacityMarketRevenue', 'strategicReserveRevenue', 'co2HedgingRevenue', 'overallRevenue','commodityCosts','co2Costs','variableCosts','fixedCosts','fullLoadHours','production','powerPlantName','technology','location','powerPlantOwner','operationalStatus','firstYearOfPowerPlantOperation','nominalCapacity','investedCapital'];
+finalResult.add(columnNames);
+for(v in financialReports){
+firstYearOfOperation=v.out('FINANCIALREPORT_POWERPLANT').constructionStartTime.next()+v.out('FINANCIALREPORT_POWERPLANT').actualPermittime.next()+v.out('FINANCIALREPORT_POWERPLANT').actualLeadtime.next()
+powerPlantSize=v.out('FINANCIALREPORT_POWERPLANT').actualNominalCapacity.next()
+actualInvestedCapital=v.out('FINANCIALREPORT_POWERPLANT').actualInvestedCapital.next()
+finalResult.add([v.time, v.spotMarketRevenue, v.capacityMarketRevenue, v.strategicReserveRevenue, v.co2HedgingRevenue, v.overallRevenue, v.commodityCosts, v.co2Costs, v.variableCosts, v.fixedCosts, v.fullLoadHours, v.production, v.out('FINANCIALREPORT_POWERPLANT').name.next(),v.out('FINANCIALREPORT_POWERPLANT').out('TECHNOLOGY').name.next(),v.out('FINANCIALREPORT_POWERPLANT').out('LOCATION').name.next(),v.out('FINANCIALREPORT_POWERPLANT').out('POWERPLANT_OWNER').name.next(),v.powerPlantStatus,firstYearOfOperation,powerPlantSize,actualInvestedCapital]);
+};
+return finalResult;",
diff --git a/emlab-generation/queries-Ranalysis.properties.orig b/emlab-generation/queries-Ranalysis.properties.orig
new file mode 100644
index 00000000..603f909c
--- /dev/null
+++ b/emlab-generation/queries-Ranalysis.properties.orig
@@ -0,0 +1,870 @@
+"CapacityinMW", "PowerGeneratingTechnology", "capacity= v.in().filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"CapacityinMWinA", "PowerGeneratingTechnology", "capacity = v.in('TECHNOLOGY').as('x').out('LOCATION').out('REGION').filter{it.name=='Country A'}.back('x').filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"CapacityinMWinB", "PowerGeneratingTechnology", "capacity = v.in('TECHNOLOGY').as('x').out('LOCATION').out('REGION').filter{it.name=='Country B'}.back('x').filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"PeakDemandPerZoneInMW", "ElectricitySpotMarket", "topsegments = v.out('SEGMENT_LOAD').max{it.baseLoad}.baseLoad;
+try{growthfactors = v.out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+growthfactors=v.out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+adjustedTopSegments = topsegments*growthfactors;
+return [v.outE('ZONE').inV.collect{it.name}[0], adjustedTopSegments]",
+
+"TotalOperationalCapacityPerZoneInMW", "Zone", "t = new Table();
+pp = v.in('REGION').in('LOCATION')
+pp.filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.as('powerPlantCapacity').out('TECHNOLOGY').as('peakSegmentDependentAvailability').table(t){it.actualNominalCapacity}{it.peakSegmentDependentAvailability}.cap().next();
+capacitySum = 0; for (row in t){capacitySum += row.getColumn('powerPlantCapacity') * row.getColumn('peakSegmentDependentAvailability')}
+return [v.name, capacitySum]",
+
+"TotalConsumptioninMWh", "DecarbonizationModel", "segmentloads = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']];
+productionsum = 0;
+for(segmentload in segmentloads){
+ //productionsum += segmentload.baseLoad;
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ productionsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+}
+return productionsum;",
+
+"CO2BankedCertificates", "DecarbonizationModel", "agents = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationAgent']];
+ co2Allowances=0;
+ for(agent in agents){if(agent.co2Allowances!=null) co2Allowances+=agent.co2Allowances}; return co2Allowances",
+
+<<<<<<< HEAD
+"MarketStabilityReserve", "Government", "return v.stabilityReserve",
+=======
+"MarketStabilityReserve", "Government", "result = 0
+if(v.stabilityReserve==null){}
+else result = v.stabilityReserve
+return result",
+>>>>>>> Jorn/feature/historicalCVar
+
+"MsrUpperTriggerinTonPA", "Government", "try{cap = v.out('STABILITY_RESERVE_UPPER_TRIGGER').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('STABILITY_RESERVE_UPPER_TRIGGER').timeSeries.next()[tick.toInteger()]}
+model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
+msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
+if(msrActive){
+ return cap
+} else{
+ return 'NA'
+}",
+
+"MsrAddingPercentage", "Government", "try{cap = v.out('STABILITY_RESERVE_ADDING_PERCENTAGE').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('STABILITY_RESERVE_ADDING_PERCENTAGE').timeSeries.next()[tick.toInteger()]}
+model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
+msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
+if(msrActive){
+ return cap
+} else{
+ return 'NA'
+}",
+
+"MsrLowerTriggerinTonPA", "Government", "try{cap = v.out('STABILITY_RESERVE_LOWER_TRIGGER').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('STABILITY_RESERVE_LOWER_TRIGGER').timeSeries.next()[tick.toInteger()]}
+model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
+msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
+if(msrActive){
+ return cap
+} else{
+ return 'NA'
+}",
+
+"MsrReleaseQuantityTonPA", "Government", "try{cap = v.out('STABILITY_RESERVE_RELEASE_QUANTITY').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('STABILITY_RESERVE_RELEASE_QUANTITY').timeSeries.next()[tick.toInteger()]}
+model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
+msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
+if(msrActive){
+ return cap
+} else{
+ return 'NA'
+}",
+
+"CO2CapinTonpA", "Government", "try{cap = v.out('CO2CAP_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap = v.out('CO2CAP_TREND').timeSeries.next()[tick.toInteger()];}
+return ['CO2_cap', cap]",
+
+"OriginalCO2CapinTonpA", "Government", "cap=0
+try{cap = v.out('CO2CAP_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('CO2CAP_TREND').timeSeries.next()[tick.toInteger()];}
+try{capReduction = v.out('CO2CAPADJUSTMENT_TIMESERIES').timeSeries.next()[tick.toInteger()]} catch(Exception e){
+ capReduction=0
+}
+return ['OriginalCO2Cap', cap+capReduction]",
+
+"CO2CapReductioninTonpA", "Government", "try{capReduction = v.out('CO2CAPADJUSTMENT_TIMESERIES').timeSeries.next()[tick.toInteger()]} catch(Exception e){
+ capReduction=0}
+return ['Co2CapReductioninTonpA', capReduction]",
+
+"NationalMinCO2PriceinEURpTon", "NationalGovernment","try{price = v.out('MINCO2PRICE_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('MINCO2PRICE_TREND').timeSeries.next()[tick.toInteger()];}
+return [v.out('GOVERNED_ZONE').collect{it.name}[0], price];",
+
+"NationalGovernmentCash", "NationalGovernment","
+<<<<<<< HEAD
+return [v.out('GOVERNED_ZONE').collect{it.name}[0], v.cash];",
+=======
+cash = v.cash
+if (cash==null) cash=0
+return [v.out('GOVERNED_ZONE').collect{it.name}[0], cash];",
+>>>>>>> Jorn/feature/historicalCVar
+
+"EUGovernmentCash", "Government","
+return v.cash;",
+
+"SpotMarketCash", "ElectricitySpotMarket","
+return [v.name, v.cash];",
+
+"GenerationinMWh", "PowerGeneratingTechnology", "sum = 0;
+ppdps = v.in('TECHNOLOGY').in('POWERPLANT_DISPATCHPLAN').filter{it.time==tick && it.status>=2 && it.forecast==false};
+for(ppdp in ppdps){
+ totalAmount = ppdp.getProperty('acceptedAmount') + ppdp.getProperty('capacityLongTermContract');
+ hoursInSegment = ppdp.out('SEGMENT_DISPATCHPLAN').next().getProperty('lengthInHours');
+ production = totalAmount * hoursInSegment;
+ sum = sum + production;
+}
+return [v.name, sum]",
+
+"CO2Auction", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==false}
+if(!point.hasNext()){price = 0} else {price=point.next().getProperty('price')}
+return price",
+
+"MsrEmergencyTrigger", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==false}
+if(!point.hasNext()){emergencyTrigger=false} else {emergencyTrigger=point.next().getProperty('emergencyTriggerActivated')}
+return emergencyTrigger",
+
+"MsrEmergencyTriggerOutflow", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==false}
+if(!point.hasNext()){outflow = 0} else {outflow=point.next().getProperty('emergencyTriggerOutflow')}
+return outflow",
+
+"Forc_CO2Auction", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}
+if(!point.hasNext()){price = 0} else {price=point.next().getProperty('price')}
+return price",
+
+"Avg_El_PricesinEURpMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+[v.name, cp.sum{it.price * it.volume} / cp.sum{it.volume}];
+",
+
+"Forc_Avg_El_PricesinEURpMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}.toList();
+[v.name, cp.sum{it.price * it.volume} / cp.sum{it.volume}];
+",
+
+"NationalTotalProductioninMWh", "Zone", "powerplants = v.in('REGION').in('LOCATION')
+return [v.name, powerplants.in('POWERPLANT_DISPATCHPLAN').filter{it.forecast==false}.sum{f.determineProductionOfDispatchPlanInMWh(it, tick)}]",
+
+"Total_EnergyServedinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false};
+return [v.name, cp.sum{it.volume}];
+",
+
+"Total_DemandinMWh", "Zone", "segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandsum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+return [v.name, demandsum];
+",
+
+"WelfareLossThroughENS", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+energyServed = cp.sum{it.volume};
+segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandSum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandSum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+energyNotServed = demandSum - energyServed;
+voll = v.in('ZONE').next().valueOfLostLoad
+return [v.name, energyNotServed*voll];
+",
+
+"EnergyNotServedinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+energyServed = cp.sum{it.volume};
+segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandSum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandSum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+energyNotServed = demandSum - energyServed;
+return [v.name, energyNotServed];
+",
+
+"Forc_Total_DemandinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}.toList();
+<<<<<<< HEAD
+[v.name, cp.sum{it.volume}];
+=======
+totalDemand = cp.sum{it.volume}
+if(totalDemand==null) totalDemand=0
+[v.name, totalDemand];
+>>>>>>> Jorn/feature/historicalCVar
+",
+
+"CO2Emissions_inTonpA", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).filter{it.status>=1 && it.forecast==false}.collect();
+co2Emissions = 0
+for(plan in ppdps){
+fuelMix=plan.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX').collect()
+singleEmission=0
+ for(fuelMixElement in fuelMix){
+ //fuelMixElement=fuelMix[1]
+ share=fuelMixElement.share
+ co2Density=fuelMixElement.out('SUBSTANCE').collect{it.co2Density}[0]*(1-plan.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.co2CaptureEffciency}[0])
+ singleEmission+=share*co2Density
+ }
+ co2Emissions+=plan.acceptedAmount*singleEmission*plan.out('SEGMENT_DISPATCHPLAN').collect{it.lengthInHours}[0]
+}
+return co2Emissions",
+
+"Forc_CO2Emissions_inTonpA", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick+3).filter{it.status>=1 && it.forecast==true}.collect();
+co2Emissions = 0
+for(plan in ppdps){
+fuelMix=plan.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX').collect()
+singleEmission=0
+ for(fuelMixElement in fuelMix){
+ //fuelMixElement=fuelMix[1]
+ share=fuelMixElement.share
+ co2Density=fuelMixElement.out('SUBSTANCE').collect{it.co2Density}[0]*(1-plan.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.co2CaptureEffciency}[0])
+ singleEmission+=share*co2Density
+ }
+ co2Emissions+=plan.acceptedAmount*singleEmission*plan.out('SEGMENT_DISPATCHPLAN').collect{it.lengthInHours}[0]
+}
+return co2Emissions",
+
+"EUCO2PriceFloor", "Government", "try{price = v.out('MINCO2PRICE_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('MINCO2PRICE_TREND').timeSeries.next()[tick.toInteger()];};
+return ['EU CO2 price floor', price];",
+
+"CO2Tax", "Government", "try{price = v.out('CO2TAX_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('CO2TAX_TREND').timeSeries.next()[tick.toInteger()];}
+return price",
+
+"FuelPricesPerGJ", "DecarbonizationModel", "fuels = g.idx('__types__')[[className:'emlab.gen.domain.technology.Substance']].filter{it.name != 'Electricity' && it.name != 'CO2'}
+result = []
+for(v in fuels){
+ price = v.in('SUBSTANCE_MARKET').in('MARKET_POINT').filter{it.time == tick}.collect{it.price};
+ density = v.energyDensity;
+ inGJ = price[0] / density;
+ result.add([v.name,inGJ]);}
+ return result",
+
+"ProducerCash", "EnergyProducer", "[v.name, v.cash]",
+
+"AggregateFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0]) {
+ //totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;
+",
+
+"CountryAProdFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;
+",
+
+"CountryBProdFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;",
+
+"PriceInEURperMWh", "DecarbonizationModel", "results = []
+points = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+for(scp in points){
+ results.add(['Segment ' + scp.out('MARKET_POINT').out('ZONE').name.next() + ' ' + scp.out('SEGMENT_POINT').segmentID.next(), scp.price])
+}
+return results",
+
+"ShortagesInHoursUnserved", "DecarbonizationModel", "powerplants = g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']].filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}
+production= powerplants.in('POWERPLANT_DISPATCHPLAN').sum{f.determineProductionOfDispatchPlanInMWh(it, tick)};
+segmentloads = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']]
+productionsum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ productionsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+}
+return (production-productionsum)/productionsum*8760;",
+
+"ProducerCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"CountryAProdCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"CountryBProdCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"TABLE_SegmentClearingPoints", "DecarbonizationModel", "points = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+finalResult = []
+headers=['tick','volume','price','market','segmentID','segmentLength','interconectorFlow','demand','energynotserved']
+finalResult.add(headers)
+for(v in points){
+market=v.out('MARKET_POINT')
+segment=v.out('SEGMENT_POINT').next()
+segmentId=segment.segmentID
+segmentLoad=market.out('SEGMENT_LOAD').as('x').out('SEGMENTLOAD_SEGMENT').filter{it.segmentID==segmentId}.back('x').next();
+//return segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]
+//return segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').next().timeSeries[tick.toInteger()]
+growthfactor=1
+try{growthfactor = segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').next().timeSeries[tick.toInteger()]}
+//}
+//return segmentLoad
+demandLevel=segmentLoad.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentLoad.baseLoad * growthfactor;
+ finalResult.add([v.time, v.volume, v.price, v.out('MARKET_POINT').collect{it.name}[0], v.out('SEGMENT_POINT').collect{it.segmentID}[0], v.out('SEGMENT_POINT').collect{it.lengthInHours}[0],v.interconnectorFlow,demandLevel,demandLevel-v.volume])
+}
+return finalResult;
+",
+
+"TABLE_ClearingPoints", "DecarbonizationModel", "points = g.idx('__types__')[[className:'emlab.gen.domain.market.ClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+finalResult = []
+headers=['tick','volume','price',',market']
+finalResult.add(headers)
+for(v in points){
+finalResult.add([v.time, v.volume, v.price, v.out('MARKET_POINT').collect{it.name}[0]])
+}
+return finalResult",
+
+"TABLE_InitialPowerPlants", "DecarbonizationModel", "if(tick<1){
+powerPlants=g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']];
+finalResult = [];
+columnNames=['Name', 'Technology', 'Location', 'Age', 'Owner', 'Capacity', 'Efficiency']
+finalResult.add(columnNames)
+for(p in powerPlants){
+name = p.name
+technology = p.out('TECHNOLOGY').collect{it.name}[0]
+location = p.out('LOCATION').collect{it.name}[0]
+age = -p.constructionStartTime-p.actualLeadtime-p.actualPermittime
+owner = p.out('POWERPLANT_OWNER').collect{it.name}[0]
+capacity = p.actualNominalCapacity
+efficiency = p.actualEfficiency
+finalResult.add([name,technology,location,age,owner,capacity,efficiency])
+}
+return finalResult
+}",
+
+"TABLE_PowerPlantDispatchPlans", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].filter{it.time==tick && it.forecast==false};
+finalResult = [];
+columnNames=['tick','bidder', 'market','volume', 'price', 'bidWithoutCO2', 'technology', 'status', 'segmentID']
+commodities=g.idx('__types__')[[className:'emlab.gen.domain.market.CommodityMarket']].out('SUBSTANCE_MARKET').sort{it.name}.toList();
+for(c in commodities) columnNames.add(c.name)
+finalResult.add(columnNames)
+for(v in ppdps){
+result=[];
+tick=v.time; bidWithoutCO2=v.bidWithoutCO2; volume=v.amount; technology=v.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.name}[0]; status=v.status;
+price=v.price;
+segment=v.out('SEGMENT_DISPATCHPLAN').collect{it}[0];
+bidder=v.in('BIDDER').collect{it.name}[0];
+market=v.out('BIDDINGMARKET').collect{it.name}[0];
+segmentID=segment.segmentID;
+tempResult=[tick,bidder,market,volume, price, bidWithoutCO2, technology, status, segmentID]
+for (c in commodities) tempResult.add(0)
+fuelMix=v.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX');
+for(element in fuelMix){
+substanceName=element.out('SUBSTANCE').collect{it.name}[0];
+index = columnNames.findIndexOf{it == substanceName}
+share=element.share;
+tempResult[index]=share
+//return result
+}
+finalResult.add(tempResult);
+}
+return finalResult;",
+
+<<<<<<< HEAD
+"TABLE_DemandLevels", "DecarbonizationModel", "segmentLoads=ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']];
+=======
+"TABLE_DemandLevels", "DecarbonizationModel", "segmentLoads=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']];
+>>>>>>> Jorn/feature/historicalCVar
+finalResult = [];
+columnNames=['tick', 'volume', 'market', 'segmentID', 'hours']
+finalResult.add(columnNames)
+for(s in segmentLoads){
+market= s.in('SEGMENT_LOAD').collect{it.name}[0]
+try{growthfactor = s.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+<<<<<<< HEAD
+growthfactor=s.out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+=======
+growthfactor=s.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+>>>>>>> Jorn/feature/historicalCVar
+segmentID=s.out('SEGMENTLOAD_SEGMENT').collect{it.segmentID}[0]
+hours=s.out('SEGMENTLOAD_SEGMENT').collect{it.lengthInHours}[0]
+finalResult.add([tick, s.baseLoad*growthfactor, market, segmentID, hours])
+}
+<<<<<<< HEAD
+return finalResult",
+=======
+return finalResult",
+
+"TABLE_FinancialReports", "DecarbonizationModel", "financialReports=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.FinancialPowerPlantReport']].filter{it.time==tick};
+finalResult = [];
+columnNames=['tick', 'spotMarketRevenue', 'capacityMarketRevenue', 'strategicReserveRevenue', 'co2HedgingRevenue', 'overallRevenue','commodityCosts','co2Costs','variableCosts','fixedCosts','fullLoadHours','production','powerPlantName','technology','location','powerPlantOwner','operationalStatus','firstYearOfPowerPlantOperation','nominalCapacity','investedCapital'];
+finalResult.add(columnNames);
+for(v in financialReports){
+firstYearOfOperation=v.out('FINANCIALREPORT_POWERPLANT').constructionStartTime.next()+v.out('FINANCIALREPORT_POWERPLANT').actualPermittime.next()+v.out('FINANCIALREPORT_POWERPLANT').actualLeadtime.next()
+powerPlantSize=v.out('FINANCIALREPORT_POWERPLANT').actualNominalCapacity.next()
+actualInvestedCapital=v.out('FINANCIALREPORT_POWERPLANT').actualInvestedCapital.next()
+finalResult.add([v.time, v.spotMarketRevenue, v.capacityMarketRevenue, v.strategicReserveRevenue, v.co2HedgingRevenue, v.overallRevenue, v.commodityCosts, v.co2Costs, v.variableCosts, v.fixedCosts, v.fullLoadHours, v.production, v.out('FINANCIALREPORT_POWERPLANT').name.next(),v.out('FINANCIALREPORT_POWERPLANT').out('TECHNOLOGY').name.next(),v.out('FINANCIALREPORT_POWERPLANT').out('LOCATION').name.next(),v.out('FINANCIALREPORT_POWERPLANT').out('POWERPLANT_OWNER').name.next(),v.powerPlantStatus,firstYearOfOperation,powerPlantSize,actualInvestedCapital]);
+};
+return finalResult;",
+>>>>>>> Jorn/feature/historicalCVar
diff --git a/emlab-generation/queries.properties b/emlab-generation/queries.properties
index 1d5c147a..33c25833 100644
--- a/emlab-generation/queries.properties
+++ b/emlab-generation/queries.properties
@@ -38,62 +38,10 @@ return productionsum;",
"MarketStabilityReserve", "Government", "return v.stabilityReserve",
-"MsrUpperTriggerinTonPA", "Government", "try{cap = v.out('STABILITY_RESERVE_UPPER_TRIGGER').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
-cap=v.out('STABILITY_RESERVE_UPPER_TRIGGER').timeSeries.next()[tick.toInteger()]}
-model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
-msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
-if(msrActive){
- return cap
-} else{
- return 'NA'
-}",
-
-"MsrAddingPercentage", "Government", "try{cap = v.out('STABILITY_RESERVE_ADDING_PERCENTAGE').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
-cap=v.out('STABILITY_RESERVE_ADDING_PERCENTAGE').timeSeries.next()[tick.toInteger()]}
-model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
-msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
-if(msrActive){
- return cap
-} else{
- return 'NA'
-}",
-
-"MsrLowerTriggerinTonPA", "Government", "try{cap = v.out('STABILITY_RESERVE_LOWER_TRIGGER').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
-cap=v.out('STABILITY_RESERVE_LOWER_TRIGGER').timeSeries.next()[tick.toInteger()]}
-model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
-msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
-if(msrActive){
- return cap
-} else{
- return 'NA'
-}",
-
-"MsrReleaseQuantityTonPA", "Government", "try{cap = v.out('STABILITY_RESERVE_RELEASE_QUANTITY').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
-cap=v.out('STABILITY_RESERVE_RELEASE_QUANTITY').timeSeries.next()[tick.toInteger()]}
-model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
-msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
-if(msrActive){
- return cap
-} else{
- return 'NA'
-}",
-
"CO2CapinTonpA", "Government", "try{cap = v.out('CO2CAP_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
cap = v.out('CO2CAP_TREND').timeSeries.next()[tick.toInteger()];}
return ['CO2_cap', cap]",
-"OriginalCO2CapinTonpA", "Government", "cap=0
-try{cap = v.out('CO2CAP_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
-cap=v.out('CO2CAP_TREND').timeSeries.next()[tick.toInteger()];}
-try{capReduction = v.out('CO2CAPADJUSTMENT_TIMESERIES').timeSeries.next()[tick.toInteger()]} catch(Exception e){
- capReduction=0
-}
-return ['OriginalCO2Cap', cap+capReduction]",
-
-"CO2CapReductioninTonpA", "Government", "try{capReduction = v.out('CO2CAPADJUSTMENT_TIMESERIES').timeSeries.next()[tick.toInteger()]} catch(Exception e){
- capReduction=0}
-return ['Co2CapReductioninTonpA', capReduction]",
-
"NationalMinCO2PriceinEURpTon", "NationalGovernment","try{price = v.out('MINCO2PRICE_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
price = v.out('MINCO2PRICE_TREND').timeSeries.next()[tick.toInteger()];}
return [v.out('GOVERNED_ZONE').collect{it.name}[0], price];",
@@ -131,15 +79,7 @@ return [v.name, sum]",
if(!point.hasNext()){price = 0} else {price=point.next().getProperty('price')}
return price",
-"MsrEmergencyTrigger", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==false}
-if(!point.hasNext()){emergencyTrigger=false} else {emergencyTrigger=point.next().getProperty('emergencyTriggerActivated')}
-return emergencyTrigger",
-
-"MsrEmergencyTriggerOutflow", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==false}
-if(!point.hasNext()){outflow = 0} else {outflow=point.next().getProperty('emergencyTriggerOutflow')}
-return outflow",
-
-"Forc_CO2Auction", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}
+"Forc_CO2Auction", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==true}
if(!point.hasNext()){price = 0} else {price=point.next().getProperty('price')}
return price",
diff --git a/emlab-generation/queries.properties.BACKUP.21167.properties b/emlab-generation/queries.properties.BACKUP.21167.properties
new file mode 100644
index 00000000..7c8c41a0
--- /dev/null
+++ b/emlab-generation/queries.properties.BACKUP.21167.properties
@@ -0,0 +1,887 @@
+"CapacityinMW", "PowerGeneratingTechnology", "capacity= v.in().filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"CapacityinMWinA", "PowerGeneratingTechnology", "capacity = v.in('TECHNOLOGY').as('x').out('LOCATION').out('REGION').filter{it.name=='Country A'}.back('x').filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"CapacityinMWinB", "PowerGeneratingTechnology", "capacity = v.in('TECHNOLOGY').as('x').out('LOCATION').out('REGION').filter{it.name=='Country B'}.back('x').filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"PeakDemandPerZoneInMW", "ElectricitySpotMarket", "topsegments = v.out('SEGMENT_LOAD').max{it.baseLoad}.baseLoad;
+try{growthfactors = v.out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+growthfactors=v.out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+adjustedTopSegments = topsegments*growthfactors;
+return [v.outE('ZONE').inV.collect{it.name}[0], adjustedTopSegments]",
+
+"TotalOperationalCapacityPerZoneInMW", "Zone", "t = new Table();
+pp = v.in('REGION').in('LOCATION')
+pp.filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.as('powerPlantCapacity').out('TECHNOLOGY').as('peakSegmentDependentAvailability').table(t){it.actualNominalCapacity}{it.peakSegmentDependentAvailability}.cap().next();
+capacitySum = 0; for (row in t){capacitySum += row.getColumn('powerPlantCapacity') * row.getColumn('peakSegmentDependentAvailability')}
+return [v.name, capacitySum]",
+
+"TotalConsumptioninMWh", "DecarbonizationModel", "segmentloads = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']];
+productionsum = 0;
+for(segmentload in segmentloads){
+ //productionsum += segmentload.baseLoad;
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ productionsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+}
+return productionsum;",
+
+"CO2BankedCertificates", "DecarbonizationModel", "agents = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationAgent']];
+ co2Allowances=0;
+ for(agent in agents){if(agent.co2Allowances!=null) co2Allowances+=agent.co2Allowances}; return co2Allowances",
+
+
+"MsrUpperTriggerinTonPA", "Government", "try{cap = v.out('STABILITY_RESERVE_UPPER_TRIGGER').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('STABILITY_RESERVE_UPPER_TRIGGER').timeSeries.next()[tick.toInteger()]}
+model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
+msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
+if(msrActive){
+ return cap
+} else{
+ return 'NA'
+}",
+
+"MsrAddingPercentage", "Government", "try{cap = v.out('STABILITY_RESERVE_ADDING_PERCENTAGE').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('STABILITY_RESERVE_ADDING_PERCENTAGE').timeSeries.next()[tick.toInteger()]}
+model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
+msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
+if(msrActive){
+ return cap
+} else{
+ return 'NA'
+}",
+
+"MsrLowerTriggerinTonPA", "Government", "try{cap = v.out('STABILITY_RESERVE_LOWER_TRIGGER').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('STABILITY_RESERVE_LOWER_TRIGGER').timeSeries.next()[tick.toInteger()]}
+model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
+msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
+if(msrActive){
+ return cap
+} else{
+ return 'NA'
+}",
+
+"MsrReleaseQuantityTonPA", "Government", "try{cap = v.out('STABILITY_RESERVE_RELEASE_QUANTITY').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('STABILITY_RESERVE_RELEASE_QUANTITY').timeSeries.next()[tick.toInteger()]}
+model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
+msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
+if(msrActive){
+ return cap
+} else{
+ return 'NA'
+}",
+
+"CO2CapinTonpA", "Government", "try{cap = v.out('CO2CAP_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap = v.out('CO2CAP_TREND').timeSeries.next()[tick.toInteger()];}
+return ['CO2_cap', cap]",
+
+"OriginalCO2CapinTonpA", "Government", "cap=0
+try{cap = v.out('CO2CAP_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('CO2CAP_TREND').timeSeries.next()[tick.toInteger()];}
+try{capReduction = v.out('CO2CAPADJUSTMENT_TIMESERIES').timeSeries.next()[tick.toInteger()]} catch(Exception e){
+ capReduction=0
+}
+return ['OriginalCO2Cap', cap+capReduction]",
+
+"CO2CapReductioninTonpA", "Government", "try{capReduction = v.out('CO2CAPADJUSTMENT_TIMESERIES').timeSeries.next()[tick.toInteger()]} catch(Exception e){
+ capReduction=0}
+return ['Co2CapReductioninTonpA', capReduction]",
+
+"NationalMinCO2PriceinEURpTon", "NationalGovernment","try{price = v.out('MINCO2PRICE_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('MINCO2PRICE_TREND').timeSeries.next()[tick.toInteger()];}
+return [v.out('GOVERNED_ZONE').collect{it.name}[0], price];",
+
+"NationalGovernmentCash", "NationalGovernment","
+cash = v.cash
+if (cash==null) cash=0
+return [v.out('GOVERNED_ZONE').collect{it.name}[0], cash];",
+
+"EUGovernmentCash", "Government","
+return v.cash;",
+
+"SpotMarketCash", "ElectricitySpotMarket","
+return [v.name, v.cash];",
+
+"GenerationinMWh", "PowerGeneratingTechnology", "sum = 0;
+ppdps = v.in('TECHNOLOGY').in('POWERPLANT_DISPATCHPLAN').filter{it.time==tick && it.status>=2 && it.forecast==false};
+for(ppdp in ppdps){
+ totalAmount = ppdp.getProperty('acceptedAmount') + ppdp.getProperty('capacityLongTermContract');
+ hoursInSegment = ppdp.out('SEGMENT_DISPATCHPLAN').next().getProperty('lengthInHours');
+ production = totalAmount * hoursInSegment;
+ sum = sum + production;
+}
+return [v.name, sum]",
+
+"GenerationinMWhPerProducer", "EnergyProducer", "sum = 0;
+ppdps = v.out('BIDDER').filter{it.__type__.contains('PowerPlantDispatchPlan')}.filter{it.time==tick && it.status>=2 && it.forecast==false};
+for(ppdp in ppdps){
+ totalAmount = ppdp.getProperty('acceptedAmount') + ppdp.getProperty('capacityLongTermContract');
+ hoursInSegment = ppdp.out('SEGMENT_DISPATCHPLAN').next().getProperty('lengthInHours');
+ production = totalAmount * hoursInSegment;
+ sum = sum + production;
+}
+return [v.name, sum]",
+
+"CO2Auction", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==false}
+if(!point.hasNext()){price = 0} else {price=point.next().getProperty('price')}
+return price",
+
+<<<<<<< HEAD
+=======
+"MsrEmergencyTrigger", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==false}
+if(!point.hasNext()){emergencyTrigger=false} else {emergencyTrigger=point.next().getProperty('emergencyTriggerActivated')}
+return emergencyTrigger",
+
+"MsrEmergencyTriggerOutflow", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==false}
+if(!point.hasNext()){outflow = 0} else {outflow=point.next().getProperty('emergencyTriggerOutflow')}
+return outflow",
+>>>>>>> Jorn/feature/historicalCVar
+
+"Forc_CO2Auction", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}
+if(!point.hasNext()){price = 0} else {price=point.next().getProperty('price')}
+return price",
+
+"Avg_El_PricesinEURpMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+[v.name, cp.sum{it.price * it.volume} / cp.sum{it.volume}];
+",
+
+"Forc_Avg_El_PricesinEURpMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}.toList();
+[v.name, cp.sum{it.price * it.volume} / cp.sum{it.volume}];
+",
+
+"NationalTotalProductioninMWh", "Zone", "powerplants = v.in('REGION').in('LOCATION')
+return [v.name, powerplants.in('POWERPLANT_DISPATCHPLAN').filter{it.forecast==false}.sum{f.determineProductionOfDispatchPlanInMWh(it, tick)}]",
+
+"Total_EnergyServedinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false};
+return [v.name, cp.sum{it.volume}];
+",
+
+"Total_DemandinMWh", "Zone", "segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandsum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+return [v.name, demandsum];
+",
+
+"EnergyNotServedinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+energyServed = cp.sum{it.volume};
+segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandSum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandSum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+energyNotServed = demandSum - energyServed;
+return [v.name, energyNotServed];
+",
+
+"Forc_Total_DemandinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}.toList();
+<<<<<<< HEAD
+totalDemand = cp.sum{it.volume}
+if(totalDemand==null) totalDemand=0
+[v.name, totalDemand];
+=======
+[v.name, cp.sum{it.volume}];
+>>>>>>> Jorn/feature/historicalCVar
+",
+
+"CO2Emissions_inTonpA", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).filter{it.status>=1 && it.forecast==false}.collect();
+co2Emissions = 0
+for(plan in ppdps){
+fuelMix=plan.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX').collect()
+singleEmission=0
+ for(fuelMixElement in fuelMix){
+ //fuelMixElement=fuelMix[1]
+ share=fuelMixElement.share
+ co2Density=fuelMixElement.out('SUBSTANCE').collect{it.co2Density}[0]*(1-plan.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.co2CaptureEffciency}[0])
+ singleEmission+=share*co2Density
+ }
+ co2Emissions+=plan.acceptedAmount*singleEmission*plan.out('SEGMENT_DISPATCHPLAN').collect{it.lengthInHours}[0]
+}
+return co2Emissions",
+
+"Forc_CO2Emissions_inTonpA", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick+3).filter{it.status>=1 && it.forecast==true}.collect();
+co2Emissions = 0
+for(plan in ppdps){
+fuelMix=plan.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX').collect()
+singleEmission=0
+ for(fuelMixElement in fuelMix){
+ //fuelMixElement=fuelMix[1]
+ share=fuelMixElement.share
+ co2Density=fuelMixElement.out('SUBSTANCE').collect{it.co2Density}[0]*(1-plan.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.co2CaptureEffciency}[0])
+ singleEmission+=share*co2Density
+ }
+ co2Emissions+=plan.acceptedAmount*singleEmission*plan.out('SEGMENT_DISPATCHPLAN').collect{it.lengthInHours}[0]
+}
+return co2Emissions",
+
+"EUCO2PriceFloor", "Government", "try{price = v.out('MINCO2PRICE_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('MINCO2PRICE_TREND').timeSeries.next()[tick.toInteger()];};
+return ['EU CO2 price floor', price];",
+
+"CO2Tax", "Government", "try{price = v.out('CO2TAX_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('CO2TAX_TREND').timeSeries.next()[tick.toInteger()];}
+return price",
+
+"FuelPricesPerGJ", "DecarbonizationModel", "fuels = g.idx('__types__')[[className:'emlab.gen.domain.technology.Substance']].filter{it.name != 'Electricity' && it.name != 'CO2'}
+result = []
+for(v in fuels){
+ price = v.in('SUBSTANCE_MARKET').in('MARKET_POINT').filter{it.time == tick}.collect{it.price};
+ density = v.energyDensity;
+ inGJ = price[0] / density;
+ result.add([v.name,inGJ]);}
+ return result",
+
+"ProducerCash", "EnergyProducer", "[v.name, v.cash]",
+
+"AggregateFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0]) {
+ //totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;
+",
+
+"CountryAProdFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;
+",
+
+"CountryBProdFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;",
+
+"PriceInEURperMWh", "DecarbonizationModel", "results = []
+points = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+for(scp in points){
+ results.add(['Segment ' + scp.out('MARKET_POINT').out('ZONE').name.next() + ' ' + scp.out('SEGMENT_POINT').segmentID.next(), scp.price])
+}
+return results",
+
+"ShortagesInHoursUnserved", "DecarbonizationModel", "powerplants = g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']].filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}
+production= powerplants.in('POWERPLANT_DISPATCHPLAN').sum{f.determineProductionOfDispatchPlanInMWh(it, tick)};
+segmentloads = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']]
+productionsum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ productionsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+}
+return (production-productionsum)/productionsum*8760;",
+
+"ProducerCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"CountryAProdCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"CountryBProdCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"TABLE_SegmentClearingPoints", "DecarbonizationModel", "points = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+finalResult = []
+headers=['tick','volume','price','market','segmentID','segmentLength','interconectorFlow','demand','energynotserved']
+finalResult.add(headers)
+for(v in points){
+market=v.out('MARKET_POINT')
+segment=v.out('SEGMENT_POINT').next()
+segmentId=segment.segmentID
+segmentLoad=market.out('SEGMENT_LOAD').as('x').out('SEGMENTLOAD_SEGMENT').filter{it.segmentID==segmentId}.back('x').next();
+//return segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]
+//return segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').next().timeSeries[tick.toInteger()]
+growthfactor=1
+try{growthfactor = segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').next().timeSeries[tick.toInteger()]}
+//}
+//return segmentLoad
+demandLevel=segmentLoad.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentLoad.baseLoad * growthfactor;
+ finalResult.add([v.time, v.volume, v.price, v.out('MARKET_POINT').collect{it.name}[0], v.out('SEGMENT_POINT').collect{it.segmentID}[0], v.out('SEGMENT_POINT').collect{it.lengthInHours}[0],v.interconnectorFlow,demandLevel,demandLevel-v.volume])
+}
+return finalResult;
+",
+
+"TABLE_ClearingPoints", "DecarbonizationModel", "points = g.idx('__types__')[[className:'emlab.gen.domain.market.ClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+finalResult = []
+headers=['tick','volume','price',',market']
+finalResult.add(headers)
+for(v in points){
+finalResult.add([v.time, v.volume, v.price, v.out('MARKET_POINT').collect{it.name}[0]])
+}
+return finalResult",
+
+"TABLE_InitialPowerPlants", "DecarbonizationModel", "if(tick<1){
+powerPlants=g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']];
+finalResult = [];
+columnNames=['Name', 'Technology', 'Location', 'Age', 'Owner', 'Capacity', 'Efficiency']
+finalResult.add(columnNames)
+for(p in powerPlants){
+name = p.name
+technology = p.out('TECHNOLOGY').collect{it.name}[0]
+location = p.out('LOCATION').collect{it.name}[0]
+age = -p.constructionStartTime-p.actualLeadtime-p.actualPermittime
+owner = p.out('POWERPLANT_OWNER').collect{it.name}[0]
+capacity = p.actualNominalCapacity
+efficiency = p.actualEfficiency
+finalResult.add([name,technology,location,age,owner,capacity,efficiency])
+}
+return finalResult
+}",
+
+<<<<<<< HEAD
+"TABLE_PowerPlantDispatchPlans", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].filter{it.time==tick && it.forecast==false};
+finalResult = [];
+columnNames=['tick','bidder', 'market','volume', 'price', 'bidWithoutCO2', 'technology', 'status', 'segmentID']
+commodities=g.idx('__types__')[[className:'emlab.gen.domain.market.CommodityMarket']].out('SUBSTANCE_MARKET').sort{it.name}.toList();
+for(c in commodities) columnNames.add(c.name)
+finalResult.add(columnNames)
+for(v in ppdps){
+result=[];
+tick=v.time; bidWithoutCO2=v.bidWithoutCO2; volume=v.amount; technology=v.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.name}[0]; status=v.status;
+price=v.price;
+segment=v.out('SEGMENT_DISPATCHPLAN').collect{it}[0];
+bidder=v.in('BIDDER').collect{it.name}[0];
+market=v.out('BIDDINGMARKET').collect{it.name}[0];
+segmentID=segment.segmentID;
+tempResult=[tick,bidder,market,volume, price, bidWithoutCO2, technology, status, segmentID]
+for (c in commodities) tempResult.add(0)
+fuelMix=v.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX');
+for(element in fuelMix){
+substanceName=element.out('SUBSTANCE').collect{it.name}[0];
+index = columnNames.findIndexOf{it == substanceName}
+share=element.share;
+tempResult[index]=share
+//return result
+}
+finalResult.add(tempResult);
+}
+return finalResult;",
+
+"TABLE_DemandLevels", "DecarbonizationModel", "segmentLoads=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']];
+finalResult = [];
+columnNames=['tick', 'volume', 'market', 'segmentID', 'hours']
+finalResult.add(columnNames)
+for(s in segmentLoads){
+market= s.in('SEGMENT_LOAD').collect{it.name}[0]
+try{growthfactor = s.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+growthfactor=s.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+segmentID=s.out('SEGMENTLOAD_SEGMENT').collect{it.segmentID}[0]
+hours=s.out('SEGMENTLOAD_SEGMENT').collect{it.lengthInHours}[0]
+finalResult.add([tick, s.baseLoad*growthfactor, market, segmentID, hours])
+}
+return finalResult",
+
+
+"CapacityClearingPointPriceinEur", "DecarbonizationModel", "price = g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityClearingPoint']].filter{it.time==tick}.price;
+result=[]
+for(p in price) result.add(p)
+if(result.isEmpty()){return 0};
+return result[0]",
+
+"CapacityClearingPointVolumeinEur", "DecarbonizationModel", "volume = g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityClearingPoint']].filter{it.time==tick}.volume;
+result=[]
+for(vl in volume) result.add(vl)
+if(result.isEmpty()){return 0};
+return result[0]",
+
+"CapacityMarketShortageIndicator", "DecarbonizationModel", "price = g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).price;
+priceCap = g.idx('__types__')[[className:'emlab.gen.domain.agent.Regulator']].capacityMarketPriceCap;
+value = 0
+if (price == null) value = 0;
+if (price == priceCap) value = 1;
+else value = 0;
+return value",
+
+"ConsumerExpenditure", "ElectricitySpotMarket", "[v.name, -v.cash]",
+
+"TABLE_CapacityDispatchPlans", "DecarbonizationModel", "cdp=g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityDispatchPlan']].filter{it.time==tick};
+ finalResult = [];
+ columnNames=['tick','bidder', 'market','volume', 'price', 'technology', 'status']
+ finalResult.add(columnNames);
+ for (v in cdp){
+ tick=v.time;
+ volume=v.amount;
+ technology=v.out('CAPACITY_DISPATCHPLAN').out('TECHNOLOGY').collect{it.name}[0]; status=v.status;
+ price=v.price;
+ bidder=v.in('BIDDER').collect{it.name}[0];
+ market=v.out('BIDDINGMARKET').collect{it.name}[0];
+ tempResult=[tick,bidder,market,volume, price, technology, status]
+ finalResult.add(tempResult);
+ }
+ return finalResult;",
+
+=======
+"TABLE_FinancialReports", "DecarbonizationModel", "financialReports=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.FinancialPowerPlantReport']].filter{it.time==tick};
+finalResult = [];
+columnNames=['tick', 'spotMarketRevenue', 'capacityMarketRevenue', 'strategicReserveRevenue', 'co2HedgingRevenue', 'overallRevenue','commodityCosts','co2Costs','variableCosts','fixedCosts','fullLoadHours','production','powerPlantName','technology','location','powerPlantOwner','operationalStatus','firstYearOfPowerPlantOperation','nominalCapacity','investedCapital'];
+finalResult.add(columnNames);
+for(v in financialReports){
+firstYearOfOperation=v.out('FINANCIALREPORT_POWERPLANT').constructionStartTime.next()+v.out('FINANCIALREPORT_POWERPLANT').actualPermittime.next()+v.out('FINANCIALREPORT_POWERPLANT').actualLeadtime.next()
+powerPlantSize=v.out('FINANCIALREPORT_POWERPLANT').actualNominalCapacity.next()
+actualInvestedCapital=v.out('FINANCIALREPORT_POWERPLANT').actualInvestedCapital.next()
+finalResult.add([v.time, v.spotMarketRevenue, v.capacityMarketRevenue, v.strategicReserveRevenue, v.co2HedgingRevenue, v.overallRevenue, v.commodityCosts, v.co2Costs, v.variableCosts, v.fixedCosts, v.fullLoadHours, v.production, v.out('FINANCIALREPORT_POWERPLANT').name.next(),v.out('FINANCIALREPORT_POWERPLANT').out('TECHNOLOGY').name.next(),v.out('FINANCIALREPORT_POWERPLANT').out('LOCATION').name.next(),v.out('FINANCIALREPORT_POWERPLANT').out('POWERPLANT_OWNER').name.next(),v.powerPlantStatus,firstYearOfOperation,powerPlantSize,actualInvestedCapital]);
+};
+return finalResult;",
+>>>>>>> Jorn/feature/historicalCVar
diff --git a/emlab-generation/queries.properties.BASE.21167.properties b/emlab-generation/queries.properties.BASE.21167.properties
new file mode 100644
index 00000000..79b4eb8b
--- /dev/null
+++ b/emlab-generation/queries.properties.BASE.21167.properties
@@ -0,0 +1,725 @@
+"CapacityinMW", "PowerGeneratingTechnology", "capacity= v.in().filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"CapacityinMWinA", "PowerGeneratingTechnology", "capacity = v.in('TECHNOLOGY').as('x').out('LOCATION').out('REGION').filter{it.name=='Country A'}.back('x').filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"CapacityinMWinB", "PowerGeneratingTechnology", "capacity = v.in('TECHNOLOGY').as('x').out('LOCATION').out('REGION').filter{it.name=='Country B'}.back('x').filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"PeakDemandPerZoneInMW", "ElectricitySpotMarket", "topsegments = v.out('SEGMENT_LOAD').max{it.baseLoad}.baseLoad;
+try{growthfactors = v.out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+growthfactors=v.out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+adjustedTopSegments = topsegments*growthfactors;
+return [v.outE('ZONE').inV.collect{it.name}[0], adjustedTopSegments]",
+
+"TotalOperationalCapacityPerZoneInMW", "Zone", "t = new Table();
+pp = v.in('REGION').in('LOCATION')
+pp.filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.as('powerPlantCapacity').out('TECHNOLOGY').as('peakSegmentDependentAvailability').table(t){it.actualNominalCapacity}{it.peakSegmentDependentAvailability}.cap().next();
+capacitySum = 0; for (row in t){capacitySum += row.getColumn('powerPlantCapacity') * row.getColumn('peakSegmentDependentAvailability')}
+return [v.name, capacitySum]",
+
+"TotalConsumptioninMWh", "DecarbonizationModel", "segmentloads = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']];
+productionsum = 0;
+for(segmentload in segmentloads){
+ //productionsum += segmentload.baseLoad;
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ productionsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+}
+return productionsum;",
+
+"CO2BankedCertificates", "DecarbonizationModel", "agents = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationAgent']];
+ co2Allowances=0;
+ for(agent in agents){if(agent.co2Allowances!=null) co2Allowances+=agent.co2Allowances}; return co2Allowances",
+
+"MarketStabilityReserve", "Government", "return v.stabilityReserve",
+
+"CO2CapinTonpA", "Government", "try{cap = v.out('CO2CAP_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap = v.out('CO2CAP_TREND').timeSeries.next()[tick.toInteger()];}
+return ['CO2_cap', cap]",
+
+"NationalMinCO2PriceinEURpTon", "NationalGovernment","try{price = v.out('MINCO2PRICE_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('MINCO2PRICE_TREND').timeSeries.next()[tick.toInteger()];}
+return [v.out('GOVERNED_ZONE').collect{it.name}[0], price];",
+
+"NationalGovernmentCash", "NationalGovernment","
+return [v.out('GOVERNED_ZONE').collect{it.name}[0], v.cash];",
+
+"EUGovernmentCash", "Government","
+return v.cash;",
+
+"SpotMarketCash", "ElectricitySpotMarket","
+return [v.name, v.cash];",
+
+"GenerationinMWh", "PowerGeneratingTechnology", "sum = 0;
+ppdps = v.in('TECHNOLOGY').in('POWERPLANT_DISPATCHPLAN').filter{it.time==tick && it.status>=2 && it.forecast==false};
+for(ppdp in ppdps){
+ totalAmount = ppdp.getProperty('acceptedAmount') + ppdp.getProperty('capacityLongTermContract');
+ hoursInSegment = ppdp.out('SEGMENT_DISPATCHPLAN').next().getProperty('lengthInHours');
+ production = totalAmount * hoursInSegment;
+ sum = sum + production;
+}
+return [v.name, sum]",
+
+"CO2Auction", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==false}
+if(!point.hasNext()){price = 0} else {price=point.next().getProperty('price')}
+return price",
+
+"Forc_CO2Auction", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==true}
+if(!point.hasNext()){price = 0} else {price=point.next().getProperty('price')}
+return price",
+
+"Avg_El_PricesinEURpMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+[v.name, cp.sum{it.price * it.volume} / cp.sum{it.volume}];
+",
+
+"Forc_Avg_El_PricesinEURpMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}.toList();
+[v.name, cp.sum{it.price * it.volume} / cp.sum{it.volume}];
+",
+
+"NationalTotalProductioninMWh", "Zone", "powerplants = v.in('REGION').in('LOCATION')
+return [v.name, powerplants.in('POWERPLANT_DISPATCHPLAN').filter{it.forecast==false}.sum{f.determineProductionOfDispatchPlanInMWh(it, tick)}]",
+
+"Total_EnergyServedinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+[v.name, cp.sum{it.volume}];
+",
+
+"Total_DemandinMWh", "Zone", "segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandsum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+return [v.name, demandsum];
+",
+
+"WelfareLossThroughENS", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+energyServed = cp.sum{it.volume};
+segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandSum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandSum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+energyNotServed = demandSum - energyServed;
+voll = v.in('ZONE').next().valueOfLostLoad
+return [v.name, energyNotServed*voll];
+",
+
+"EnergyNotServedinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+energyServed = cp.sum{it.volume};
+segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandSum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandSum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+energyNotServed = demandSum - energyServed;
+return [v.name, energyNotServed];
+",
+
+"Forc_Total_DemandinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==true}.toList();
+[v.name, cp.sum{it.volume}];
+",
+
+"CO2Emissions_inTonpA", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).filter{it.status>=1 && it.forecast==false}.collect();
+co2Emissions = 0
+for(plan in ppdps){
+fuelMix=plan.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX').collect()
+singleEmission=0
+ for(fuelMixElement in fuelMix){
+ //fuelMixElement=fuelMix[1]
+ share=fuelMixElement.share
+ co2Density=fuelMixElement.out('SUBSTANCE').collect{it.co2Density}[0]*(1-plan.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.co2CaptureEffciency}[0])
+ singleEmission+=share*co2Density
+ }
+ co2Emissions+=plan.acceptedAmount*singleEmission*plan.out('SEGMENT_DISPATCHPLAN').collect{it.lengthInHours}[0]
+}
+return co2Emissions",
+
+"Forc_CO2Emissions_inTonpA", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick+3).filter{it.status>=1 && it.forecast==true}.collect();
+co2Emissions = 0
+for(plan in ppdps){
+fuelMix=plan.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX').collect()
+singleEmission=0
+ for(fuelMixElement in fuelMix){
+ //fuelMixElement=fuelMix[1]
+ share=fuelMixElement.share
+ co2Density=fuelMixElement.out('SUBSTANCE').collect{it.co2Density}[0]*(1-plan.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.co2CaptureEffciency}[0])
+ singleEmission+=share*co2Density
+ }
+ co2Emissions+=plan.acceptedAmount*singleEmission*plan.out('SEGMENT_DISPATCHPLAN').collect{it.lengthInHours}[0]
+}
+return co2Emissions",
+
+"EUCO2PriceFloor", "Government", "try{price = v.out('MINCO2PRICE_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('MINCO2PRICE_TREND').timeSeries.next()[tick.toInteger()];};
+return ['EU CO2 price floor', price];",
+
+"CO2Tax", "Government", "try{price = v.out('CO2TAX_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('CO2TAX_TREND').timeSeries.next()[tick.toInteger()];}
+return price",
+
+"FuelPricesPerGJ", "DecarbonizationModel", "fuels = g.idx('__types__')[[className:'emlab.gen.domain.technology.Substance']].filter{it.name != 'Electricity' && it.name != 'CO2'}
+result = []
+for(v in fuels){
+ price = v.in('SUBSTANCE_MARKET').in('MARKET_POINT').filter{it.time == tick}.collect{it.price};
+ density = v.energyDensity;
+ inGJ = price[0] / density;
+ result.add([v.name,inGJ]);}
+ return result",
+
+"ProducerCash", "EnergyProducer", "[v.name, v.cash]",
+
+"AggregateFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0]) {
+ //totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;
+",
+
+"CountryAProdFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;
+",
+
+"CountryBProdFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;",
+
+"PriceInEURperMWh", "DecarbonizationModel", "results = []
+points = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+for(scp in points){
+ results.add(['Segment ' + scp.out('MARKET_POINT').out('ZONE').name.next() + ' ' + scp.out('SEGMENT_POINT').segmentID.next(), scp.price])
+}
+return results",
+
+"ShortagesInHoursUnserved", "DecarbonizationModel", "powerplants = g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']].filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}
+production= powerplants.in('POWERPLANT_DISPATCHPLAN').sum{f.determineProductionOfDispatchPlanInMWh(it, tick)};
+segmentloads = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']]
+productionsum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ productionsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+}
+return (production-productionsum)/productionsum*8760;",
+
+"ProducerCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"CountryAProdCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"CountryBProdCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"TABLE_SegmentClearingPoints", "DecarbonizationModel", "points = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+finalResult = []
+headers=['tick','volume','price','market','segmentID','segmentLength','interconectorFlow','demand','energynotserved']
+finalResult.add(headers)
+for(v in points){
+market=v.out('MARKET_POINT')
+segment=v.out('SEGMENT_POINT').next()
+segmentId=segment.segmentID
+segmentLoad=market.out('SEGMENT_LOAD').as('x').out('SEGMENTLOAD_SEGMENT').filter{it.segmentID==segmentId}.back('x').next();
+//return segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]
+//return segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').next().timeSeries[tick.toInteger()]
+growthfactor=1
+try{growthfactor = segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').next().timeSeries[tick.toInteger()]}
+//}
+//return segmentLoad
+demandLevel=segmentLoad.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentLoad.baseLoad * growthfactor;
+ finalResult.add([v.time, v.volume, v.price, v.out('MARKET_POINT').collect{it.name}[0], v.out('SEGMENT_POINT').collect{it.segmentID}[0], v.out('SEGMENT_POINT').collect{it.lengthInHours}[0],v.interconnectorFlow,demandLevel,demandLevel-v.volume])
+}
+return finalResult;
+",
+
+"TABLE_ClearingPoints", "DecarbonizationModel", "points = g.idx('__types__')[[className:'emlab.gen.domain.market.ClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+finalResult = []
+headers=['tick','volume','price',',market']
+finalResult.add(headers)
+for(v in points){
+finalResult.add([v.time, v.volume, v.price, v.out('MARKET_POINT').collect{it.name}[0]])
+}
+return finalResult",
+
+"TABLE_InitialPowerPlants", "DecarbonizationModel", "if(tick<1){
+powerPlants=g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']];
+finalResult = [];
+columnNames=['Name', 'Technology', 'Location', 'Age', 'Owner', 'Capacity', 'Efficiency']
+finalResult.add(columnNames)
+for(p in powerPlants){
+name = p.name
+technology = p.out('TECHNOLOGY').collect{it.name}[0]
+location = p.out('LOCATION').collect{it.name}[0]
+age = -p.constructionStartTime-p.actualLeadtime-p.actualPermittime
+owner = p.out('POWERPLANT_OWNER').collect{it.name}[0]
+capacity = p.actualNominalCapacity
+efficiency = p.actualEfficiency
+finalResult.add([name,technology,location,age,owner,capacity,efficiency])
+}
+return finalResult
+}",
\ No newline at end of file
diff --git a/emlab-generation/queries.properties.LOCAL.21167.properties b/emlab-generation/queries.properties.LOCAL.21167.properties
new file mode 100644
index 00000000..3cf43b86
--- /dev/null
+++ b/emlab-generation/queries.properties.LOCAL.21167.properties
@@ -0,0 +1,809 @@
+"CapacityinMW", "PowerGeneratingTechnology", "capacity= v.in().filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"CapacityinMWinA", "PowerGeneratingTechnology", "capacity = v.in('TECHNOLOGY').as('x').out('LOCATION').out('REGION').filter{it.name=='Country A'}.back('x').filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"CapacityinMWinB", "PowerGeneratingTechnology", "capacity = v.in('TECHNOLOGY').as('x').out('LOCATION').out('REGION').filter{it.name=='Country B'}.back('x').filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"PeakDemandPerZoneInMW", "ElectricitySpotMarket", "topsegments = v.out('SEGMENT_LOAD').max{it.baseLoad}.baseLoad;
+try{growthfactors = v.out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+growthfactors=v.out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+adjustedTopSegments = topsegments*growthfactors;
+return [v.outE('ZONE').inV.collect{it.name}[0], adjustedTopSegments]",
+
+"TotalOperationalCapacityPerZoneInMW", "Zone", "t = new Table();
+pp = v.in('REGION').in('LOCATION')
+pp.filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.as('powerPlantCapacity').out('TECHNOLOGY').as('peakSegmentDependentAvailability').table(t){it.actualNominalCapacity}{it.peakSegmentDependentAvailability}.cap().next();
+capacitySum = 0; for (row in t){capacitySum += row.getColumn('powerPlantCapacity') * row.getColumn('peakSegmentDependentAvailability')}
+return [v.name, capacitySum]",
+
+"TotalConsumptioninMWh", "DecarbonizationModel", "segmentloads = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']];
+productionsum = 0;
+for(segmentload in segmentloads){
+ //productionsum += segmentload.baseLoad;
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ productionsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+}
+return productionsum;",
+
+"CO2BankedCertificates", "DecarbonizationModel", "agents = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationAgent']];
+ co2Allowances=0;
+ for(agent in agents){if(agent.co2Allowances!=null) co2Allowances+=agent.co2Allowances}; return co2Allowances",
+
+
+"CO2CapinTonpA", "Government", "try{cap = v.out('CO2CAP_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap = v.out('CO2CAP_TREND').timeSeries.next()[tick.toInteger()];}
+return ['CO2_cap', cap]",
+
+"OriginalCO2CapinTonpA", "Government", "cap=0
+try{cap = v.out('CO2CAP_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('CO2CAP_TREND').timeSeries.next()[tick.toInteger()];}
+try{capReduction = v.out('CO2CAPADJUSTMENT_TIMESERIES').timeSeries.next()[tick.toInteger()]} catch(Exception e){
+ capReduction=0
+}
+return ['OriginalCO2Cap', cap+capReduction]",
+
+"CO2CapReductioninTonpA", "Government", "try{capReduction = v.out('CO2CAPADJUSTMENT_TIMESERIES').timeSeries.next()[tick.toInteger()]} catch(Exception e){
+ capReduction=0}
+return ['Co2CapReductioninTonpA', capReduction]",
+
+"NationalMinCO2PriceinEURpTon", "NationalGovernment","try{price = v.out('MINCO2PRICE_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('MINCO2PRICE_TREND').timeSeries.next()[tick.toInteger()];}
+return [v.out('GOVERNED_ZONE').collect{it.name}[0], price];",
+
+"NationalGovernmentCash", "NationalGovernment","
+cash = v.cash
+if (cash==null) cash=0
+return [v.out('GOVERNED_ZONE').collect{it.name}[0], cash];",
+
+"EUGovernmentCash", "Government","
+return v.cash;",
+
+"SpotMarketCash", "ElectricitySpotMarket","
+return [v.name, v.cash];",
+
+"GenerationinMWh", "PowerGeneratingTechnology", "sum = 0;
+ppdps = v.in('TECHNOLOGY').in('POWERPLANT_DISPATCHPLAN').filter{it.time==tick && it.status>=2 && it.forecast==false};
+for(ppdp in ppdps){
+ totalAmount = ppdp.getProperty('acceptedAmount') + ppdp.getProperty('capacityLongTermContract');
+ hoursInSegment = ppdp.out('SEGMENT_DISPATCHPLAN').next().getProperty('lengthInHours');
+ production = totalAmount * hoursInSegment;
+ sum = sum + production;
+}
+return [v.name, sum]",
+
+"CO2Auction", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==false}
+if(!point.hasNext()){price = 0} else {price=point.next().getProperty('price')}
+return price",
+
+
+"Forc_CO2Auction", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}
+if(!point.hasNext()){price = 0} else {price=point.next().getProperty('price')}
+return price",
+
+"Avg_El_PricesinEURpMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+[v.name, cp.sum{it.price * it.volume} / cp.sum{it.volume}];
+",
+
+"Forc_Avg_El_PricesinEURpMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}.toList();
+[v.name, cp.sum{it.price * it.volume} / cp.sum{it.volume}];
+",
+
+"NationalTotalProductioninMWh", "Zone", "powerplants = v.in('REGION').in('LOCATION')
+return [v.name, powerplants.in('POWERPLANT_DISPATCHPLAN').filter{it.forecast==false}.sum{f.determineProductionOfDispatchPlanInMWh(it, tick)}]",
+
+"Total_EnergyServedinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false};
+return [v.name, cp.sum{it.volume}];
+",
+
+"Total_DemandinMWh", "Zone", "segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandsum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+return [v.name, demandsum];
+",
+
+"EnergyNotServedinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+energyServed = cp.sum{it.volume};
+segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandSum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandSum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+energyNotServed = demandSum - energyServed;
+return [v.name, energyNotServed];
+",
+
+"Forc_Total_DemandinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}.toList();
+totalDemand = cp.sum{it.volume}
+if(totalDemand==null) totalDemand=0
+[v.name, totalDemand];
+",
+
+"CO2Emissions_inTonpA", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).filter{it.status>=1 && it.forecast==false}.collect();
+co2Emissions = 0
+for(plan in ppdps){
+fuelMix=plan.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX').collect()
+singleEmission=0
+ for(fuelMixElement in fuelMix){
+ //fuelMixElement=fuelMix[1]
+ share=fuelMixElement.share
+ co2Density=fuelMixElement.out('SUBSTANCE').collect{it.co2Density}[0]*(1-plan.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.co2CaptureEffciency}[0])
+ singleEmission+=share*co2Density
+ }
+ co2Emissions+=plan.acceptedAmount*singleEmission*plan.out('SEGMENT_DISPATCHPLAN').collect{it.lengthInHours}[0]
+}
+return co2Emissions",
+
+"Forc_CO2Emissions_inTonpA", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick+3).filter{it.status>=1 && it.forecast==true}.collect();
+co2Emissions = 0
+for(plan in ppdps){
+fuelMix=plan.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX').collect()
+singleEmission=0
+ for(fuelMixElement in fuelMix){
+ //fuelMixElement=fuelMix[1]
+ share=fuelMixElement.share
+ co2Density=fuelMixElement.out('SUBSTANCE').collect{it.co2Density}[0]*(1-plan.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.co2CaptureEffciency}[0])
+ singleEmission+=share*co2Density
+ }
+ co2Emissions+=plan.acceptedAmount*singleEmission*plan.out('SEGMENT_DISPATCHPLAN').collect{it.lengthInHours}[0]
+}
+return co2Emissions",
+
+"EUCO2PriceFloor", "Government", "try{price = v.out('MINCO2PRICE_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('MINCO2PRICE_TREND').timeSeries.next()[tick.toInteger()];};
+return ['EU CO2 price floor', price];",
+
+"CO2Tax", "Government", "try{price = v.out('CO2TAX_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('CO2TAX_TREND').timeSeries.next()[tick.toInteger()];}
+return price",
+
+"FuelPricesPerGJ", "DecarbonizationModel", "fuels = g.idx('__types__')[[className:'emlab.gen.domain.technology.Substance']].filter{it.name != 'Electricity' && it.name != 'CO2'}
+result = []
+for(v in fuels){
+ price = v.in('SUBSTANCE_MARKET').in('MARKET_POINT').filter{it.time == tick}.collect{it.price};
+ density = v.energyDensity;
+ inGJ = price[0] / density;
+ result.add([v.name,inGJ]);}
+ return result",
+
+"ProducerCash", "EnergyProducer", "[v.name, v.cash]",
+
+"AggregateFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0]) {
+ //totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;
+",
+
+"CountryAProdFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;
+",
+
+"CountryBProdFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;",
+
+"PriceInEURperMWh", "DecarbonizationModel", "results = []
+points = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+for(scp in points){
+ results.add(['Segment ' + scp.out('MARKET_POINT').out('ZONE').name.next() + ' ' + scp.out('SEGMENT_POINT').segmentID.next(), scp.price])
+}
+return results",
+
+"ShortagesInHoursUnserved", "DecarbonizationModel", "powerplants = g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']].filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}
+production= powerplants.in('POWERPLANT_DISPATCHPLAN').sum{f.determineProductionOfDispatchPlanInMWh(it, tick)};
+segmentloads = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']]
+productionsum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ productionsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+}
+return (production-productionsum)/productionsum*8760;",
+
+"ProducerCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"CountryAProdCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"CountryBProdCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"TABLE_SegmentClearingPoints", "DecarbonizationModel", "points = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+finalResult = []
+headers=['tick','volume','price','market','segmentID','segmentLength','interconectorFlow','demand','energynotserved']
+finalResult.add(headers)
+for(v in points){
+market=v.out('MARKET_POINT')
+segment=v.out('SEGMENT_POINT').next()
+segmentId=segment.segmentID
+segmentLoad=market.out('SEGMENT_LOAD').as('x').out('SEGMENTLOAD_SEGMENT').filter{it.segmentID==segmentId}.back('x').next();
+//return segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]
+//return segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').next().timeSeries[tick.toInteger()]
+growthfactor=1
+try{growthfactor = segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').next().timeSeries[tick.toInteger()]}
+//}
+//return segmentLoad
+demandLevel=segmentLoad.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentLoad.baseLoad * growthfactor;
+ finalResult.add([v.time, v.volume, v.price, v.out('MARKET_POINT').collect{it.name}[0], v.out('SEGMENT_POINT').collect{it.segmentID}[0], v.out('SEGMENT_POINT').collect{it.lengthInHours}[0],v.interconnectorFlow,demandLevel,demandLevel-v.volume])
+}
+return finalResult;
+",
+
+"TABLE_ClearingPoints", "DecarbonizationModel", "points = g.idx('__types__')[[className:'emlab.gen.domain.market.ClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+finalResult = []
+headers=['tick','volume','price',',market']
+finalResult.add(headers)
+for(v in points){
+finalResult.add([v.time, v.volume, v.price, v.out('MARKET_POINT').collect{it.name}[0]])
+}
+return finalResult",
+
+"TABLE_InitialPowerPlants", "DecarbonizationModel", "if(tick<1){
+powerPlants=g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']];
+finalResult = [];
+columnNames=['Name', 'Technology', 'Location', 'Age', 'Owner', 'Capacity', 'Efficiency']
+finalResult.add(columnNames)
+for(p in powerPlants){
+name = p.name
+technology = p.out('TECHNOLOGY').collect{it.name}[0]
+location = p.out('LOCATION').collect{it.name}[0]
+age = -p.constructionStartTime-p.actualLeadtime-p.actualPermittime
+owner = p.out('POWERPLANT_OWNER').collect{it.name}[0]
+capacity = p.actualNominalCapacity
+efficiency = p.actualEfficiency
+finalResult.add([name,technology,location,age,owner,capacity,efficiency])
+}
+return finalResult
+}",
+
+"TABLE_PowerPlantDispatchPlans", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].filter{it.time==tick && it.forecast==false};
+finalResult = [];
+columnNames=['tick','bidder', 'market','volume', 'price', 'bidWithoutCO2', 'technology', 'status', 'segmentID']
+commodities=g.idx('__types__')[[className:'emlab.gen.domain.market.CommodityMarket']].out('SUBSTANCE_MARKET').sort{it.name}.toList();
+for(c in commodities) columnNames.add(c.name)
+finalResult.add(columnNames)
+for(v in ppdps){
+result=[];
+tick=v.time; bidWithoutCO2=v.bidWithoutCO2; volume=v.amount; technology=v.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.name}[0]; status=v.status;
+price=v.price;
+segment=v.out('SEGMENT_DISPATCHPLAN').collect{it}[0];
+bidder=v.in('BIDDER').collect{it.name}[0];
+market=v.out('BIDDINGMARKET').collect{it.name}[0];
+segmentID=segment.segmentID;
+tempResult=[tick,bidder,market,volume, price, bidWithoutCO2, technology, status, segmentID]
+for (c in commodities) tempResult.add(0)
+fuelMix=v.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX');
+for(element in fuelMix){
+substanceName=element.out('SUBSTANCE').collect{it.name}[0];
+index = columnNames.findIndexOf{it == substanceName}
+share=element.share;
+tempResult[index]=share
+//return result
+}
+finalResult.add(tempResult);
+}
+return finalResult;",
+
+"TABLE_DemandLevels", "DecarbonizationModel", "segmentLoads=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']];
+finalResult = [];
+columnNames=['tick', 'volume', 'market', 'segmentID', 'hours']
+finalResult.add(columnNames)
+for(s in segmentLoads){
+market= s.in('SEGMENT_LOAD').collect{it.name}[0]
+try{growthfactor = s.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+growthfactor=s.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+segmentID=s.out('SEGMENTLOAD_SEGMENT').collect{it.segmentID}[0]
+hours=s.out('SEGMENTLOAD_SEGMENT').collect{it.lengthInHours}[0]
+finalResult.add([tick, s.baseLoad*growthfactor, market, segmentID, hours])
+}
+return finalResult",
+
+
+"CapacityClearingPointPriceinEur", "DecarbonizationModel", "price = g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityClearingPoint']].filter{it.time==tick}.price;
+result=[]
+for(p in price) result.add(p)
+if(result.isEmpty()){return 0};
+return result[0]",
+
+"CapacityClearingPointVolumeinEur", "DecarbonizationModel", "volume = g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityClearingPoint']].filter{it.time==tick}.volume;
+result=[]
+for(vl in volume) result.add(vl)
+if(result.isEmpty()){return 0};
+return result[0]",
+
+"CapacityMarketShortageIndicator", "DecarbonizationModel", "price = g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).price;
+priceCap = g.idx('__types__')[[className:'emlab.gen.domain.agent.Regulator']].capacityMarketPriceCap;
+value = 0
+if (price == null) value = 0;
+if (price == priceCap) value = 1;
+else value = 0;
+return value",
+
+"ConsumerExpenditure", "ElectricitySpotMarket", "[v.name, -v.cash]",
+
+"TABLE_CapacityDispatchPlans", "DecarbonizationModel", "cdp=g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityDispatchPlan']].filter{it.time==tick};
+ finalResult = [];
+ columnNames=['tick','bidder', 'market','volume', 'price', 'technology', 'status']
+ finalResult.add(columnNames);
+ for (v in cdp){
+ tick=v.time;
+ volume=v.amount;
+ technology=v.out('CAPACITY_DISPATCHPLAN').out('TECHNOLOGY').collect{it.name}[0]; status=v.status;
+ price=v.price;
+ bidder=v.in('BIDDER').collect{it.name}[0];
+ market=v.out('BIDDINGMARKET').collect{it.name}[0];
+ tempResult=[tick,bidder,market,volume, price, technology, status]
+ finalResult.add(tempResult);
+ }
+ return finalResult;",
+
diff --git a/emlab-generation/queries.properties.REMOTE.21167.properties b/emlab-generation/queries.properties.REMOTE.21167.properties
new file mode 100644
index 00000000..d7ae0031
--- /dev/null
+++ b/emlab-generation/queries.properties.REMOTE.21167.properties
@@ -0,0 +1,807 @@
+"CapacityinMW", "PowerGeneratingTechnology", "capacity= v.in().filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"CapacityinMWinA", "PowerGeneratingTechnology", "capacity = v.in('TECHNOLOGY').as('x').out('LOCATION').out('REGION').filter{it.name=='Country A'}.back('x').filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"CapacityinMWinB", "PowerGeneratingTechnology", "capacity = v.in('TECHNOLOGY').as('x').out('LOCATION').out('REGION').filter{it.name=='Country B'}.back('x').filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"PeakDemandPerZoneInMW", "ElectricitySpotMarket", "topsegments = v.out('SEGMENT_LOAD').max{it.baseLoad}.baseLoad;
+try{growthfactors = v.out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+growthfactors=v.out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+adjustedTopSegments = topsegments*growthfactors;
+return [v.outE('ZONE').inV.collect{it.name}[0], adjustedTopSegments]",
+
+"TotalOperationalCapacityPerZoneInMW", "Zone", "t = new Table();
+pp = v.in('REGION').in('LOCATION')
+pp.filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.as('powerPlantCapacity').out('TECHNOLOGY').as('peakSegmentDependentAvailability').table(t){it.actualNominalCapacity}{it.peakSegmentDependentAvailability}.cap().next();
+capacitySum = 0; for (row in t){capacitySum += row.getColumn('powerPlantCapacity') * row.getColumn('peakSegmentDependentAvailability')}
+return [v.name, capacitySum]",
+
+"TotalConsumptioninMWh", "DecarbonizationModel", "segmentloads = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']];
+productionsum = 0;
+for(segmentload in segmentloads){
+ //productionsum += segmentload.baseLoad;
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ productionsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+}
+return productionsum;",
+
+"CO2BankedCertificates", "DecarbonizationModel", "agents = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationAgent']];
+ co2Allowances=0;
+ for(agent in agents){if(agent.co2Allowances!=null) co2Allowances+=agent.co2Allowances}; return co2Allowances",
+
+"MarketStabilityReserve", "Government", "return v.stabilityReserve",
+
+"MsrUpperTriggerinTonPA", "Government", "try{cap = v.out('STABILITY_RESERVE_UPPER_TRIGGER').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('STABILITY_RESERVE_UPPER_TRIGGER').timeSeries.next()[tick.toInteger()]}
+model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
+msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
+if(msrActive){
+ return cap
+} else{
+ return 'NA'
+}",
+
+"MsrAddingPercentage", "Government", "try{cap = v.out('STABILITY_RESERVE_ADDING_PERCENTAGE').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('STABILITY_RESERVE_ADDING_PERCENTAGE').timeSeries.next()[tick.toInteger()]}
+model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
+msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
+if(msrActive){
+ return cap
+} else{
+ return 'NA'
+}",
+
+"MsrLowerTriggerinTonPA", "Government", "try{cap = v.out('STABILITY_RESERVE_LOWER_TRIGGER').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('STABILITY_RESERVE_LOWER_TRIGGER').timeSeries.next()[tick.toInteger()]}
+model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
+msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
+if(msrActive){
+ return cap
+} else{
+ return 'NA'
+}",
+
+"MsrReleaseQuantityTonPA", "Government", "try{cap = v.out('STABILITY_RESERVE_RELEASE_QUANTITY').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('STABILITY_RESERVE_RELEASE_QUANTITY').timeSeries.next()[tick.toInteger()]}
+model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
+msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
+if(msrActive){
+ return cap
+} else{
+ return 'NA'
+}",
+
+"CO2CapinTonpA", "Government", "try{cap = v.out('CO2CAP_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap = v.out('CO2CAP_TREND').timeSeries.next()[tick.toInteger()];}
+return ['CO2_cap', cap]",
+
+"OriginalCO2CapinTonpA", "Government", "cap=0
+try{cap = v.out('CO2CAP_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('CO2CAP_TREND').timeSeries.next()[tick.toInteger()];}
+try{capReduction = v.out('CO2CAPADJUSTMENT_TIMESERIES').timeSeries.next()[tick.toInteger()]} catch(Exception e){
+ capReduction=0
+}
+return ['OriginalCO2Cap', cap+capReduction]",
+
+"CO2CapReductioninTonpA", "Government", "try{capReduction = v.out('CO2CAPADJUSTMENT_TIMESERIES').timeSeries.next()[tick.toInteger()]} catch(Exception e){
+ capReduction=0}
+return ['Co2CapReductioninTonpA', capReduction]",
+
+"NationalMinCO2PriceinEURpTon", "NationalGovernment","try{price = v.out('MINCO2PRICE_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('MINCO2PRICE_TREND').timeSeries.next()[tick.toInteger()];}
+return [v.out('GOVERNED_ZONE').collect{it.name}[0], price];",
+
+"NationalGovernmentCash", "NationalGovernment","
+return [v.out('GOVERNED_ZONE').collect{it.name}[0], v.cash];",
+
+"EUGovernmentCash", "Government","
+return v.cash;",
+
+"SpotMarketCash", "ElectricitySpotMarket","
+return [v.name, v.cash];",
+
+"GenerationinMWh", "PowerGeneratingTechnology", "sum = 0;
+ppdps = v.in('TECHNOLOGY').in('POWERPLANT_DISPATCHPLAN').filter{it.time==tick && it.status>=2 && it.forecast==false};
+for(ppdp in ppdps){
+ totalAmount = ppdp.getProperty('acceptedAmount') + ppdp.getProperty('capacityLongTermContract');
+ hoursInSegment = ppdp.out('SEGMENT_DISPATCHPLAN').next().getProperty('lengthInHours');
+ production = totalAmount * hoursInSegment;
+ sum = sum + production;
+}
+return [v.name, sum]",
+
+"GenerationinMWhPerProducer", "EnergyProducer", "sum = 0;
+ppdps = v.out('BIDDER').filter{it.__type__.contains('PowerPlantDispatchPlan')}.filter{it.time==tick && it.status>=2 && it.forecast==false};
+for(ppdp in ppdps){
+ totalAmount = ppdp.getProperty('acceptedAmount') + ppdp.getProperty('capacityLongTermContract');
+ hoursInSegment = ppdp.out('SEGMENT_DISPATCHPLAN').next().getProperty('lengthInHours');
+ production = totalAmount * hoursInSegment;
+ sum = sum + production;
+}
+return [v.name, sum]",
+
+"CO2Auction", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==false}
+if(!point.hasNext()){price = 0} else {price=point.next().getProperty('price')}
+return price",
+
+"MsrEmergencyTrigger", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==false}
+if(!point.hasNext()){emergencyTrigger=false} else {emergencyTrigger=point.next().getProperty('emergencyTriggerActivated')}
+return emergencyTrigger",
+
+"MsrEmergencyTriggerOutflow", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==false}
+if(!point.hasNext()){outflow = 0} else {outflow=point.next().getProperty('emergencyTriggerOutflow')}
+return outflow",
+
+"Forc_CO2Auction", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}
+if(!point.hasNext()){price = 0} else {price=point.next().getProperty('price')}
+return price",
+
+"Avg_El_PricesinEURpMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+[v.name, cp.sum{it.price * it.volume} / cp.sum{it.volume}];
+",
+
+"Forc_Avg_El_PricesinEURpMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}.toList();
+[v.name, cp.sum{it.price * it.volume} / cp.sum{it.volume}];
+",
+
+"NationalTotalProductioninMWh", "Zone", "powerplants = v.in('REGION').in('LOCATION')
+return [v.name, powerplants.in('POWERPLANT_DISPATCHPLAN').filter{it.forecast==false}.sum{f.determineProductionOfDispatchPlanInMWh(it, tick)}]",
+
+"Total_EnergyServedinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false};
+return [v.name, cp.sum{it.volume}];
+",
+
+"Total_DemandinMWh", "Zone", "segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandsum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+return [v.name, demandsum];
+",
+
+"WelfareLossThroughENS", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+energyServed = cp.sum{it.volume};
+segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandSum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandSum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+energyNotServed = demandSum - energyServed;
+voll = v.in('ZONE').next().valueOfLostLoad
+return [v.name, energyNotServed*voll];
+",
+
+"EnergyNotServedinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+energyServed = cp.sum{it.volume};
+segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandSum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandSum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+energyNotServed = demandSum - energyServed;
+return [v.name, energyNotServed];
+",
+
+"Forc_Total_DemandinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}.toList();
+[v.name, cp.sum{it.volume}];
+",
+
+"CO2Emissions_inTonpA", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).filter{it.status>=1 && it.forecast==false}.collect();
+co2Emissions = 0
+for(plan in ppdps){
+fuelMix=plan.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX').collect()
+singleEmission=0
+ for(fuelMixElement in fuelMix){
+ //fuelMixElement=fuelMix[1]
+ share=fuelMixElement.share
+ co2Density=fuelMixElement.out('SUBSTANCE').collect{it.co2Density}[0]*(1-plan.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.co2CaptureEffciency}[0])
+ singleEmission+=share*co2Density
+ }
+ co2Emissions+=plan.acceptedAmount*singleEmission*plan.out('SEGMENT_DISPATCHPLAN').collect{it.lengthInHours}[0]
+}
+return co2Emissions",
+
+"Forc_CO2Emissions_inTonpA", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick+3).filter{it.status>=1 && it.forecast==true}.collect();
+co2Emissions = 0
+for(plan in ppdps){
+fuelMix=plan.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX').collect()
+singleEmission=0
+ for(fuelMixElement in fuelMix){
+ //fuelMixElement=fuelMix[1]
+ share=fuelMixElement.share
+ co2Density=fuelMixElement.out('SUBSTANCE').collect{it.co2Density}[0]*(1-plan.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.co2CaptureEffciency}[0])
+ singleEmission+=share*co2Density
+ }
+ co2Emissions+=plan.acceptedAmount*singleEmission*plan.out('SEGMENT_DISPATCHPLAN').collect{it.lengthInHours}[0]
+}
+return co2Emissions",
+
+"EUCO2PriceFloor", "Government", "try{price = v.out('MINCO2PRICE_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('MINCO2PRICE_TREND').timeSeries.next()[tick.toInteger()];};
+return ['EU CO2 price floor', price];",
+
+"CO2Tax", "Government", "try{price = v.out('CO2TAX_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('CO2TAX_TREND').timeSeries.next()[tick.toInteger()];}
+return price",
+
+"FuelPricesPerGJ", "DecarbonizationModel", "fuels = g.idx('__types__')[[className:'emlab.gen.domain.technology.Substance']].filter{it.name != 'Electricity' && it.name != 'CO2'}
+result = []
+for(v in fuels){
+ price = v.in('SUBSTANCE_MARKET').in('MARKET_POINT').filter{it.time == tick}.collect{it.price};
+ density = v.energyDensity;
+ inGJ = price[0] / density;
+ result.add([v.name,inGJ]);}
+ return result",
+
+"ProducerCash", "EnergyProducer", "[v.name, v.cash]",
+
+"AggregateFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0]) {
+ //totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;
+",
+
+"CountryAProdFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;
+",
+
+"CountryBProdFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;",
+
+"PriceInEURperMWh", "DecarbonizationModel", "results = []
+points = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+for(scp in points){
+ results.add(['Segment ' + scp.out('MARKET_POINT').out('ZONE').name.next() + ' ' + scp.out('SEGMENT_POINT').segmentID.next(), scp.price])
+}
+return results",
+
+"ShortagesInHoursUnserved", "DecarbonizationModel", "powerplants = g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']].filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}
+production= powerplants.in('POWERPLANT_DISPATCHPLAN').sum{f.determineProductionOfDispatchPlanInMWh(it, tick)};
+segmentloads = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']]
+productionsum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ productionsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+}
+return (production-productionsum)/productionsum*8760;",
+
+"ProducerCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"CountryAProdCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"CountryBProdCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"TABLE_SegmentClearingPoints", "DecarbonizationModel", "points = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+finalResult = []
+headers=['tick','volume','price','market','segmentID','segmentLength','interconectorFlow','demand','energynotserved']
+finalResult.add(headers)
+for(v in points){
+market=v.out('MARKET_POINT')
+segment=v.out('SEGMENT_POINT').next()
+segmentId=segment.segmentID
+segmentLoad=market.out('SEGMENT_LOAD').as('x').out('SEGMENTLOAD_SEGMENT').filter{it.segmentID==segmentId}.back('x').next();
+//return segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]
+//return segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').next().timeSeries[tick.toInteger()]
+growthfactor=1
+try{growthfactor = segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').next().timeSeries[tick.toInteger()]}
+//}
+//return segmentLoad
+demandLevel=segmentLoad.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentLoad.baseLoad * growthfactor;
+ finalResult.add([v.time, v.volume, v.price, v.out('MARKET_POINT').collect{it.name}[0], v.out('SEGMENT_POINT').collect{it.segmentID}[0], v.out('SEGMENT_POINT').collect{it.lengthInHours}[0],v.interconnectorFlow,demandLevel,demandLevel-v.volume])
+}
+return finalResult;
+",
+
+"TABLE_ClearingPoints", "DecarbonizationModel", "points = g.idx('__types__')[[className:'emlab.gen.domain.market.ClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+finalResult = []
+headers=['tick','volume','price',',market']
+finalResult.add(headers)
+for(v in points){
+finalResult.add([v.time, v.volume, v.price, v.out('MARKET_POINT').collect{it.name}[0]])
+}
+return finalResult",
+
+"TABLE_InitialPowerPlants", "DecarbonizationModel", "if(tick<1){
+powerPlants=g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']];
+finalResult = [];
+columnNames=['Name', 'Technology', 'Location', 'Age', 'Owner', 'Capacity', 'Efficiency']
+finalResult.add(columnNames)
+for(p in powerPlants){
+name = p.name
+technology = p.out('TECHNOLOGY').collect{it.name}[0]
+location = p.out('LOCATION').collect{it.name}[0]
+age = -p.constructionStartTime-p.actualLeadtime-p.actualPermittime
+owner = p.out('POWERPLANT_OWNER').collect{it.name}[0]
+capacity = p.actualNominalCapacity
+efficiency = p.actualEfficiency
+finalResult.add([name,technology,location,age,owner,capacity,efficiency])
+}
+return finalResult
+}",
+
+"TABLE_FinancialReports", "DecarbonizationModel", "financialReports=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.FinancialPowerPlantReport']].filter{it.time==tick};
+finalResult = [];
+columnNames=['tick', 'spotMarketRevenue', 'capacityMarketRevenue', 'strategicReserveRevenue', 'co2HedgingRevenue', 'overallRevenue','commodityCosts','co2Costs','variableCosts','fixedCosts','fullLoadHours','production','powerPlantName','technology','location','powerPlantOwner','operationalStatus','firstYearOfPowerPlantOperation','nominalCapacity','investedCapital'];
+finalResult.add(columnNames);
+for(v in financialReports){
+firstYearOfOperation=v.out('FINANCIALREPORT_POWERPLANT').constructionStartTime.next()+v.out('FINANCIALREPORT_POWERPLANT').actualPermittime.next()+v.out('FINANCIALREPORT_POWERPLANT').actualLeadtime.next()
+powerPlantSize=v.out('FINANCIALREPORT_POWERPLANT').actualNominalCapacity.next()
+actualInvestedCapital=v.out('FINANCIALREPORT_POWERPLANT').actualInvestedCapital.next()
+finalResult.add([v.time, v.spotMarketRevenue, v.capacityMarketRevenue, v.strategicReserveRevenue, v.co2HedgingRevenue, v.overallRevenue, v.commodityCosts, v.co2Costs, v.variableCosts, v.fixedCosts, v.fullLoadHours, v.production, v.out('FINANCIALREPORT_POWERPLANT').name.next(),v.out('FINANCIALREPORT_POWERPLANT').out('TECHNOLOGY').name.next(),v.out('FINANCIALREPORT_POWERPLANT').out('LOCATION').name.next(),v.out('FINANCIALREPORT_POWERPLANT').out('POWERPLANT_OWNER').name.next(),v.powerPlantStatus,firstYearOfOperation,powerPlantSize,actualInvestedCapital]);
+};
+return finalResult;",
\ No newline at end of file
diff --git a/emlab-generation/queries.properties.orig b/emlab-generation/queries.properties.orig
new file mode 100644
index 00000000..7c8c41a0
--- /dev/null
+++ b/emlab-generation/queries.properties.orig
@@ -0,0 +1,887 @@
+"CapacityinMW", "PowerGeneratingTechnology", "capacity= v.in().filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"CapacityinMWinA", "PowerGeneratingTechnology", "capacity = v.in('TECHNOLOGY').as('x').out('LOCATION').out('REGION').filter{it.name=='Country A'}.back('x').filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"CapacityinMWinB", "PowerGeneratingTechnology", "capacity = v.in('TECHNOLOGY').as('x').out('LOCATION').out('REGION').filter{it.name=='Country B'}.back('x').filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"PeakDemandPerZoneInMW", "ElectricitySpotMarket", "topsegments = v.out('SEGMENT_LOAD').max{it.baseLoad}.baseLoad;
+try{growthfactors = v.out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+growthfactors=v.out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+adjustedTopSegments = topsegments*growthfactors;
+return [v.outE('ZONE').inV.collect{it.name}[0], adjustedTopSegments]",
+
+"TotalOperationalCapacityPerZoneInMW", "Zone", "t = new Table();
+pp = v.in('REGION').in('LOCATION')
+pp.filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.as('powerPlantCapacity').out('TECHNOLOGY').as('peakSegmentDependentAvailability').table(t){it.actualNominalCapacity}{it.peakSegmentDependentAvailability}.cap().next();
+capacitySum = 0; for (row in t){capacitySum += row.getColumn('powerPlantCapacity') * row.getColumn('peakSegmentDependentAvailability')}
+return [v.name, capacitySum]",
+
+"TotalConsumptioninMWh", "DecarbonizationModel", "segmentloads = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']];
+productionsum = 0;
+for(segmentload in segmentloads){
+ //productionsum += segmentload.baseLoad;
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ productionsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+}
+return productionsum;",
+
+"CO2BankedCertificates", "DecarbonizationModel", "agents = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationAgent']];
+ co2Allowances=0;
+ for(agent in agents){if(agent.co2Allowances!=null) co2Allowances+=agent.co2Allowances}; return co2Allowances",
+
+
+"MsrUpperTriggerinTonPA", "Government", "try{cap = v.out('STABILITY_RESERVE_UPPER_TRIGGER').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('STABILITY_RESERVE_UPPER_TRIGGER').timeSeries.next()[tick.toInteger()]}
+model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
+msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
+if(msrActive){
+ return cap
+} else{
+ return 'NA'
+}",
+
+"MsrAddingPercentage", "Government", "try{cap = v.out('STABILITY_RESERVE_ADDING_PERCENTAGE').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('STABILITY_RESERVE_ADDING_PERCENTAGE').timeSeries.next()[tick.toInteger()]}
+model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
+msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
+if(msrActive){
+ return cap
+} else{
+ return 'NA'
+}",
+
+"MsrLowerTriggerinTonPA", "Government", "try{cap = v.out('STABILITY_RESERVE_LOWER_TRIGGER').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('STABILITY_RESERVE_LOWER_TRIGGER').timeSeries.next()[tick.toInteger()]}
+model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
+msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
+if(msrActive){
+ return cap
+} else{
+ return 'NA'
+}",
+
+"MsrReleaseQuantityTonPA", "Government", "try{cap = v.out('STABILITY_RESERVE_RELEASE_QUANTITY').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('STABILITY_RESERVE_RELEASE_QUANTITY').timeSeries.next()[tick.toInteger()]}
+model = points = g.idx('__types__')[[className:'emlab.gen.domain.agent.DecarbonizationModel']].next()
+msrActive = model.stabilityReserveIsActive && (tick >= model.stabilityReserveFirstYearOfOperation)
+if(msrActive){
+ return cap
+} else{
+ return 'NA'
+}",
+
+"CO2CapinTonpA", "Government", "try{cap = v.out('CO2CAP_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap = v.out('CO2CAP_TREND').timeSeries.next()[tick.toInteger()];}
+return ['CO2_cap', cap]",
+
+"OriginalCO2CapinTonpA", "Government", "cap=0
+try{cap = v.out('CO2CAP_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap=v.out('CO2CAP_TREND').timeSeries.next()[tick.toInteger()];}
+try{capReduction = v.out('CO2CAPADJUSTMENT_TIMESERIES').timeSeries.next()[tick.toInteger()]} catch(Exception e){
+ capReduction=0
+}
+return ['OriginalCO2Cap', cap+capReduction]",
+
+"CO2CapReductioninTonpA", "Government", "try{capReduction = v.out('CO2CAPADJUSTMENT_TIMESERIES').timeSeries.next()[tick.toInteger()]} catch(Exception e){
+ capReduction=0}
+return ['Co2CapReductioninTonpA', capReduction]",
+
+"NationalMinCO2PriceinEURpTon", "NationalGovernment","try{price = v.out('MINCO2PRICE_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('MINCO2PRICE_TREND').timeSeries.next()[tick.toInteger()];}
+return [v.out('GOVERNED_ZONE').collect{it.name}[0], price];",
+
+"NationalGovernmentCash", "NationalGovernment","
+cash = v.cash
+if (cash==null) cash=0
+return [v.out('GOVERNED_ZONE').collect{it.name}[0], cash];",
+
+"EUGovernmentCash", "Government","
+return v.cash;",
+
+"SpotMarketCash", "ElectricitySpotMarket","
+return [v.name, v.cash];",
+
+"GenerationinMWh", "PowerGeneratingTechnology", "sum = 0;
+ppdps = v.in('TECHNOLOGY').in('POWERPLANT_DISPATCHPLAN').filter{it.time==tick && it.status>=2 && it.forecast==false};
+for(ppdp in ppdps){
+ totalAmount = ppdp.getProperty('acceptedAmount') + ppdp.getProperty('capacityLongTermContract');
+ hoursInSegment = ppdp.out('SEGMENT_DISPATCHPLAN').next().getProperty('lengthInHours');
+ production = totalAmount * hoursInSegment;
+ sum = sum + production;
+}
+return [v.name, sum]",
+
+"GenerationinMWhPerProducer", "EnergyProducer", "sum = 0;
+ppdps = v.out('BIDDER').filter{it.__type__.contains('PowerPlantDispatchPlan')}.filter{it.time==tick && it.status>=2 && it.forecast==false};
+for(ppdp in ppdps){
+ totalAmount = ppdp.getProperty('acceptedAmount') + ppdp.getProperty('capacityLongTermContract');
+ hoursInSegment = ppdp.out('SEGMENT_DISPATCHPLAN').next().getProperty('lengthInHours');
+ production = totalAmount * hoursInSegment;
+ sum = sum + production;
+}
+return [v.name, sum]",
+
+"CO2Auction", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==false}
+if(!point.hasNext()){price = 0} else {price=point.next().getProperty('price')}
+return price",
+
+<<<<<<< HEAD
+=======
+"MsrEmergencyTrigger", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==false}
+if(!point.hasNext()){emergencyTrigger=false} else {emergencyTrigger=point.next().getProperty('emergencyTriggerActivated')}
+return emergencyTrigger",
+
+"MsrEmergencyTriggerOutflow", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==false}
+if(!point.hasNext()){outflow = 0} else {outflow=point.next().getProperty('emergencyTriggerOutflow')}
+return outflow",
+>>>>>>> Jorn/feature/historicalCVar
+
+"Forc_CO2Auction", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}
+if(!point.hasNext()){price = 0} else {price=point.next().getProperty('price')}
+return price",
+
+"Avg_El_PricesinEURpMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+[v.name, cp.sum{it.price * it.volume} / cp.sum{it.volume}];
+",
+
+"Forc_Avg_El_PricesinEURpMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}.toList();
+[v.name, cp.sum{it.price * it.volume} / cp.sum{it.volume}];
+",
+
+"NationalTotalProductioninMWh", "Zone", "powerplants = v.in('REGION').in('LOCATION')
+return [v.name, powerplants.in('POWERPLANT_DISPATCHPLAN').filter{it.forecast==false}.sum{f.determineProductionOfDispatchPlanInMWh(it, tick)}]",
+
+"Total_EnergyServedinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false};
+return [v.name, cp.sum{it.volume}];
+",
+
+"Total_DemandinMWh", "Zone", "segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandsum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+return [v.name, demandsum];
+",
+
+"EnergyNotServedinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+energyServed = cp.sum{it.volume};
+segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandSum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandSum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+energyNotServed = demandSum - energyServed;
+return [v.name, energyNotServed];
+",
+
+"Forc_Total_DemandinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}.toList();
+<<<<<<< HEAD
+totalDemand = cp.sum{it.volume}
+if(totalDemand==null) totalDemand=0
+[v.name, totalDemand];
+=======
+[v.name, cp.sum{it.volume}];
+>>>>>>> Jorn/feature/historicalCVar
+",
+
+"CO2Emissions_inTonpA", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).filter{it.status>=1 && it.forecast==false}.collect();
+co2Emissions = 0
+for(plan in ppdps){
+fuelMix=plan.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX').collect()
+singleEmission=0
+ for(fuelMixElement in fuelMix){
+ //fuelMixElement=fuelMix[1]
+ share=fuelMixElement.share
+ co2Density=fuelMixElement.out('SUBSTANCE').collect{it.co2Density}[0]*(1-plan.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.co2CaptureEffciency}[0])
+ singleEmission+=share*co2Density
+ }
+ co2Emissions+=plan.acceptedAmount*singleEmission*plan.out('SEGMENT_DISPATCHPLAN').collect{it.lengthInHours}[0]
+}
+return co2Emissions",
+
+"Forc_CO2Emissions_inTonpA", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick+3).filter{it.status>=1 && it.forecast==true}.collect();
+co2Emissions = 0
+for(plan in ppdps){
+fuelMix=plan.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX').collect()
+singleEmission=0
+ for(fuelMixElement in fuelMix){
+ //fuelMixElement=fuelMix[1]
+ share=fuelMixElement.share
+ co2Density=fuelMixElement.out('SUBSTANCE').collect{it.co2Density}[0]*(1-plan.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.co2CaptureEffciency}[0])
+ singleEmission+=share*co2Density
+ }
+ co2Emissions+=plan.acceptedAmount*singleEmission*plan.out('SEGMENT_DISPATCHPLAN').collect{it.lengthInHours}[0]
+}
+return co2Emissions",
+
+"EUCO2PriceFloor", "Government", "try{price = v.out('MINCO2PRICE_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('MINCO2PRICE_TREND').timeSeries.next()[tick.toInteger()];};
+return ['EU CO2 price floor', price];",
+
+"CO2Tax", "Government", "try{price = v.out('CO2TAX_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('CO2TAX_TREND').timeSeries.next()[tick.toInteger()];}
+return price",
+
+"FuelPricesPerGJ", "DecarbonizationModel", "fuels = g.idx('__types__')[[className:'emlab.gen.domain.technology.Substance']].filter{it.name != 'Electricity' && it.name != 'CO2'}
+result = []
+for(v in fuels){
+ price = v.in('SUBSTANCE_MARKET').in('MARKET_POINT').filter{it.time == tick}.collect{it.price};
+ density = v.energyDensity;
+ inGJ = price[0] / density;
+ result.add([v.name,inGJ]);}
+ return result",
+
+"ProducerCash", "EnergyProducer", "[v.name, v.cash]",
+
+"AggregateFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0]) {
+ //totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;
+",
+
+"CountryAProdFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;
+",
+
+"CountryBProdFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;",
+
+"PriceInEURperMWh", "DecarbonizationModel", "results = []
+points = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+for(scp in points){
+ results.add(['Segment ' + scp.out('MARKET_POINT').out('ZONE').name.next() + ' ' + scp.out('SEGMENT_POINT').segmentID.next(), scp.price])
+}
+return results",
+
+"ShortagesInHoursUnserved", "DecarbonizationModel", "powerplants = g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']].filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}
+production= powerplants.in('POWERPLANT_DISPATCHPLAN').sum{f.determineProductionOfDispatchPlanInMWh(it, tick)};
+segmentloads = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']]
+productionsum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ productionsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+}
+return (production-productionsum)/productionsum*8760;",
+
+"ProducerCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"CountryAProdCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"CountryBProdCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"TABLE_SegmentClearingPoints", "DecarbonizationModel", "points = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+finalResult = []
+headers=['tick','volume','price','market','segmentID','segmentLength','interconectorFlow','demand','energynotserved']
+finalResult.add(headers)
+for(v in points){
+market=v.out('MARKET_POINT')
+segment=v.out('SEGMENT_POINT').next()
+segmentId=segment.segmentID
+segmentLoad=market.out('SEGMENT_LOAD').as('x').out('SEGMENTLOAD_SEGMENT').filter{it.segmentID==segmentId}.back('x').next();
+//return segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]
+//return segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').next().timeSeries[tick.toInteger()]
+growthfactor=1
+try{growthfactor = segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').next().timeSeries[tick.toInteger()]}
+//}
+//return segmentLoad
+demandLevel=segmentLoad.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentLoad.baseLoad * growthfactor;
+ finalResult.add([v.time, v.volume, v.price, v.out('MARKET_POINT').collect{it.name}[0], v.out('SEGMENT_POINT').collect{it.segmentID}[0], v.out('SEGMENT_POINT').collect{it.lengthInHours}[0],v.interconnectorFlow,demandLevel,demandLevel-v.volume])
+}
+return finalResult;
+",
+
+"TABLE_ClearingPoints", "DecarbonizationModel", "points = g.idx('__types__')[[className:'emlab.gen.domain.market.ClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+finalResult = []
+headers=['tick','volume','price',',market']
+finalResult.add(headers)
+for(v in points){
+finalResult.add([v.time, v.volume, v.price, v.out('MARKET_POINT').collect{it.name}[0]])
+}
+return finalResult",
+
+"TABLE_InitialPowerPlants", "DecarbonizationModel", "if(tick<1){
+powerPlants=g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']];
+finalResult = [];
+columnNames=['Name', 'Technology', 'Location', 'Age', 'Owner', 'Capacity', 'Efficiency']
+finalResult.add(columnNames)
+for(p in powerPlants){
+name = p.name
+technology = p.out('TECHNOLOGY').collect{it.name}[0]
+location = p.out('LOCATION').collect{it.name}[0]
+age = -p.constructionStartTime-p.actualLeadtime-p.actualPermittime
+owner = p.out('POWERPLANT_OWNER').collect{it.name}[0]
+capacity = p.actualNominalCapacity
+efficiency = p.actualEfficiency
+finalResult.add([name,technology,location,age,owner,capacity,efficiency])
+}
+return finalResult
+}",
+
+<<<<<<< HEAD
+"TABLE_PowerPlantDispatchPlans", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].filter{it.time==tick && it.forecast==false};
+finalResult = [];
+columnNames=['tick','bidder', 'market','volume', 'price', 'bidWithoutCO2', 'technology', 'status', 'segmentID']
+commodities=g.idx('__types__')[[className:'emlab.gen.domain.market.CommodityMarket']].out('SUBSTANCE_MARKET').sort{it.name}.toList();
+for(c in commodities) columnNames.add(c.name)
+finalResult.add(columnNames)
+for(v in ppdps){
+result=[];
+tick=v.time; bidWithoutCO2=v.bidWithoutCO2; volume=v.amount; technology=v.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.name}[0]; status=v.status;
+price=v.price;
+segment=v.out('SEGMENT_DISPATCHPLAN').collect{it}[0];
+bidder=v.in('BIDDER').collect{it.name}[0];
+market=v.out('BIDDINGMARKET').collect{it.name}[0];
+segmentID=segment.segmentID;
+tempResult=[tick,bidder,market,volume, price, bidWithoutCO2, technology, status, segmentID]
+for (c in commodities) tempResult.add(0)
+fuelMix=v.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX');
+for(element in fuelMix){
+substanceName=element.out('SUBSTANCE').collect{it.name}[0];
+index = columnNames.findIndexOf{it == substanceName}
+share=element.share;
+tempResult[index]=share
+//return result
+}
+finalResult.add(tempResult);
+}
+return finalResult;",
+
+"TABLE_DemandLevels", "DecarbonizationModel", "segmentLoads=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']];
+finalResult = [];
+columnNames=['tick', 'volume', 'market', 'segmentID', 'hours']
+finalResult.add(columnNames)
+for(s in segmentLoads){
+market= s.in('SEGMENT_LOAD').collect{it.name}[0]
+try{growthfactor = s.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+growthfactor=s.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+segmentID=s.out('SEGMENTLOAD_SEGMENT').collect{it.segmentID}[0]
+hours=s.out('SEGMENTLOAD_SEGMENT').collect{it.lengthInHours}[0]
+finalResult.add([tick, s.baseLoad*growthfactor, market, segmentID, hours])
+}
+return finalResult",
+
+
+"CapacityClearingPointPriceinEur", "DecarbonizationModel", "price = g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityClearingPoint']].filter{it.time==tick}.price;
+result=[]
+for(p in price) result.add(p)
+if(result.isEmpty()){return 0};
+return result[0]",
+
+"CapacityClearingPointVolumeinEur", "DecarbonizationModel", "volume = g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityClearingPoint']].filter{it.time==tick}.volume;
+result=[]
+for(vl in volume) result.add(vl)
+if(result.isEmpty()){return 0};
+return result[0]",
+
+"CapacityMarketShortageIndicator", "DecarbonizationModel", "price = g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).price;
+priceCap = g.idx('__types__')[[className:'emlab.gen.domain.agent.Regulator']].capacityMarketPriceCap;
+value = 0
+if (price == null) value = 0;
+if (price == priceCap) value = 1;
+else value = 0;
+return value",
+
+"ConsumerExpenditure", "ElectricitySpotMarket", "[v.name, -v.cash]",
+
+"TABLE_CapacityDispatchPlans", "DecarbonizationModel", "cdp=g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityDispatchPlan']].filter{it.time==tick};
+ finalResult = [];
+ columnNames=['tick','bidder', 'market','volume', 'price', 'technology', 'status']
+ finalResult.add(columnNames);
+ for (v in cdp){
+ tick=v.time;
+ volume=v.amount;
+ technology=v.out('CAPACITY_DISPATCHPLAN').out('TECHNOLOGY').collect{it.name}[0]; status=v.status;
+ price=v.price;
+ bidder=v.in('BIDDER').collect{it.name}[0];
+ market=v.out('BIDDINGMARKET').collect{it.name}[0];
+ tempResult=[tick,bidder,market,volume, price, technology, status]
+ finalResult.add(tempResult);
+ }
+ return finalResult;",
+
+=======
+"TABLE_FinancialReports", "DecarbonizationModel", "financialReports=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.FinancialPowerPlantReport']].filter{it.time==tick};
+finalResult = [];
+columnNames=['tick', 'spotMarketRevenue', 'capacityMarketRevenue', 'strategicReserveRevenue', 'co2HedgingRevenue', 'overallRevenue','commodityCosts','co2Costs','variableCosts','fixedCosts','fullLoadHours','production','powerPlantName','technology','location','powerPlantOwner','operationalStatus','firstYearOfPowerPlantOperation','nominalCapacity','investedCapital'];
+finalResult.add(columnNames);
+for(v in financialReports){
+firstYearOfOperation=v.out('FINANCIALREPORT_POWERPLANT').constructionStartTime.next()+v.out('FINANCIALREPORT_POWERPLANT').actualPermittime.next()+v.out('FINANCIALREPORT_POWERPLANT').actualLeadtime.next()
+powerPlantSize=v.out('FINANCIALREPORT_POWERPLANT').actualNominalCapacity.next()
+actualInvestedCapital=v.out('FINANCIALREPORT_POWERPLANT').actualInvestedCapital.next()
+finalResult.add([v.time, v.spotMarketRevenue, v.capacityMarketRevenue, v.strategicReserveRevenue, v.co2HedgingRevenue, v.overallRevenue, v.commodityCosts, v.co2Costs, v.variableCosts, v.fixedCosts, v.fullLoadHours, v.production, v.out('FINANCIALREPORT_POWERPLANT').name.next(),v.out('FINANCIALREPORT_POWERPLANT').out('TECHNOLOGY').name.next(),v.out('FINANCIALREPORT_POWERPLANT').out('LOCATION').name.next(),v.out('FINANCIALREPORT_POWERPLANT').out('POWERPLANT_OWNER').name.next(),v.powerPlantStatus,firstYearOfOperation,powerPlantSize,actualInvestedCapital]);
+};
+return finalResult;",
+>>>>>>> Jorn/feature/historicalCVar
diff --git a/emlab-generation/queriesOld.properties b/emlab-generation/queriesOld.properties
new file mode 100644
index 00000000..4fea9b91
--- /dev/null
+++ b/emlab-generation/queriesOld.properties
@@ -0,0 +1,771 @@
+"CapacityClearingPointPriceinEur", "DecarbonizationModel", "price = g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityClearingPoint']].filter{it.time==tick}.price;
+result=[]
+for(p in price) result.add(p)
+if(result.isEmpty()){return 0};
+return result[0]",
+
+"CapacityClearingPointVolumeinEur", "DecarbonizationModel", "volume = g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityClearingPoint']].filter{it.time==tick}.volume;
+result=[]
+for(vl in volume) result.add(vl)
+if(result.isEmpty()){return 0};
+return result[0]",
+
+"CapacityMarketShortageIndicator", "DecarbonizationModel", "price = g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).price;
+priceCap = g.idx('__types__')[[className:'emlab.gen.domain.agent.Regulator']].capacityMarketPriceCap;
+value = 0
+if (price == null) value = 0;
+if (price == priceCap) value = 1;
+else value = 0;
+return value",
+
+"ConsumerExpenditure", "ElectricitySpotMarket", "[v.name, -v.cash]",
+
+"TABLE_CapacityDispatchPlans", "DecarbonizationModel", "cdp=g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityDispatchPlan']].filter{it.time==tick};
+ finalResult = [];
+ columnNames=['tick','bidder', 'market','volume', 'price', 'technology', 'status']
+ finalResult.add(columnNames);
+ for (v in cdp){
+ tick=v.time;
+ volume=v.amount;
+ technology=v.out('CAPACITY_DISPATCHPLAN').out('TECHNOLOGY').collect{it.name}[0]; status=v.status;
+ price=v.price;
+ bidder=v.in('BIDDER').collect{it.name}[0];
+ market=v.out('BIDDINGMARKET').collect{it.name}[0];
+ tempResult=[tick,bidder,market,volume, price, technology, status]
+ finalResult.add(tempResult);
+ }
+ return finalResult;",
+
+
+"CapacityinMW", "PowerGeneratingTechnology", "capacity= v.in().filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"CapacityinMWinA", "PowerGeneratingTechnology", "capacity = v.in('TECHNOLOGY').as('x').out('LOCATION').out('REGION').filter{it.name=='Country A'}.back('x').filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"CapacityinMWinB", "PowerGeneratingTechnology", "capacity = v.in('TECHNOLOGY').as('x').out('LOCATION').out('REGION').filter{it.name=='Country B'}.back('x').filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity}
+if(capacity == null) capacity = 0
+[v.name, capacity]",
+
+"PeakDemandPerZoneInMW", "ElectricitySpotMarket", "topsegments = v.out('SEGMENT_LOAD').max{it.baseLoad}.baseLoad;
+try{growthfactors = v.out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+growthfactors=v.out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+adjustedTopSegments = topsegments*growthfactors;
+return [v.outE('ZONE').inV.collect{it.name}[0], adjustedTopSegments]",
+
+"TotalOperationalCapacityPerZoneInMW", "Zone", "t = new Table();
+pp = v.in('REGION').in('LOCATION')
+pp.filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.as('powerPlantCapacity').out('TECHNOLOGY').as('peakSegmentDependentAvailability').table(t){it.actualNominalCapacity}{it.peakSegmentDependentAvailability}.cap().next();
+capacitySum = 0; for (row in t){capacitySum += row.getColumn('powerPlantCapacity') * row.getColumn('peakSegmentDependentAvailability')}
+return [v.name, capacitySum]",
+
+"TotalConsumptioninMWh", "DecarbonizationModel", "segmentloads = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']];
+productionsum = 0;
+for(segmentload in segmentloads){
+ //productionsum += segmentload.baseLoad;
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ productionsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+}
+return productionsum;",
+
+
+
+"CO2CapinTonpA", "Government", "try{cap = v.out('CO2CAP_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+cap = v.out('CO2CAP_TREND').timeSeries.next()[tick.toInteger()];}
+return ['CO2_cap', cap]",
+
+"NationalMinCO2PriceinEURpTon", "NationalGovernment","try{price = v.out('MINCO2PRICE_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('MINCO2PRICE_TREND').timeSeries.next()[tick.toInteger()];}
+return [v.out('GOVERNED_ZONE').collect{it.name}[0], price];",
+
+"NationalGovernmentCash", "NationalGovernment","
+return [v.out('GOVERNED_ZONE').collect{it.name}[0], v.cash];",
+
+"EUGovernmentCash", "Government","
+return v.cash;",
+
+"SpotMarketCash", "ElectricitySpotMarket","
+return [v.name, v.cash];",
+
+"GenerationinMWh", "PowerGeneratingTechnology", "sum = 0;
+ppdps = v.in('TECHNOLOGY').in('POWERPLANT_DISPATCHPLAN').filter{it.time==tick && it.status>=2 && it.forecast==false};
+for(ppdp in ppdps){
+ totalAmount = ppdp.getProperty('acceptedAmount') + ppdp.getProperty('capacityLongTermContract');
+ hoursInSegment = ppdp.out('SEGMENT_DISPATCHPLAN').next().getProperty('lengthInHours');
+ production = totalAmount * hoursInSegment;
+ sum = sum + production;
+}
+return [v.name, sum]",
+
+"GenerationinMWhPerProducer", "EnergyProducer", "sum = 0;
+ppdps = v.out('BIDDER').filter{it.__type__.contains('PowerPlantDispatchPlan')}.filter{it.time==tick && it.status>=2 && it.forecast==false};
+for(ppdp in ppdps){
+ totalAmount = ppdp.getProperty('acceptedAmount') + ppdp.getProperty('capacityLongTermContract');
+ hoursInSegment = ppdp.out('SEGMENT_DISPATCHPLAN').next().getProperty('lengthInHours');
+ production = totalAmount * hoursInSegment;
+ sum = sum + production;
+}
+return [v.name, sum]",
+
+"CO2Auction", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick && it.forecast==false}
+if(!point.hasNext()){price = 0} else {price=point.next().getProperty('price')}
+return price",
+
+
+"Forc_CO2Auction", "CO2Auction", "point=v.in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}
+if(!point.hasNext()){price = 0} else {price=point.next().getProperty('price')}
+return price",
+
+"Avg_El_PricesinEURpMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+[v.name, cp.sum{it.price * it.volume} / cp.sum{it.volume}];
+",
+
+"Forc_Avg_El_PricesinEURpMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}.toList();
+[v.name, cp.sum{it.price * it.volume} / cp.sum{it.volume}];
+",
+
+"NationalTotalProductioninMWh", "Zone", "powerplants = v.in('REGION').in('LOCATION')
+return [v.name, powerplants.in('POWERPLANT_DISPATCHPLAN').filter{it.forecast==false}.sum{f.determineProductionOfDispatchPlanInMWh(it, tick)}]",
+
+"Total_EnergyServedinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false};
+return [v.name, cp.sum{it.volume}];
+",
+
+"Total_DemandinMWh", "Zone", "segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandsum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+return [v.name, demandsum];
+",
+
+"WelfareLossThroughENS", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+energyServed = cp.sum{it.volume};
+segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandSum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandSum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+energyNotServed = demandSum - energyServed;
+voll = v.in('ZONE').next().valueOfLostLoad
+return [v.name, energyNotServed*voll];
+",
+
+"EnergyNotServedinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick && it.forecast==false}.toList();
+energyServed = cp.sum{it.volume};
+segmentloads = v.in('ZONE').out('SEGMENT_LOAD')
+demandSum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ demandSum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+};
+energyNotServed = demandSum - energyServed;
+return [v.name, energyNotServed];
+",
+
+"Forc_Total_DemandinMWh", "Zone", "cp = v.in('ZONE').in('MARKET_POINT').filter{it.time==tick+3 && it.forecast==true}.toList();
+[v.name, cp.sum{it.volume}];
+",
+
+"CO2Emissions_inTonpA", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).filter{it.status>=1 && it.forecast==false}.collect();
+co2Emissions = 0
+for(plan in ppdps){
+fuelMix=plan.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX').collect()
+singleEmission=0
+ for(fuelMixElement in fuelMix){
+ //fuelMixElement=fuelMix[1]
+ share=fuelMixElement.share
+ co2Density=fuelMixElement.out('SUBSTANCE').collect{it.co2Density}[0]*(1-plan.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.co2CaptureEffciency}[0])
+ singleEmission+=share*co2Density
+ }
+ co2Emissions+=plan.acceptedAmount*singleEmission*plan.out('SEGMENT_DISPATCHPLAN').collect{it.lengthInHours}[0]
+}
+return co2Emissions",
+
+"Forc_CO2Emissions_inTonpA", "DecarbonizationModel", "ppdps=g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.PowerPlantDispatchPlan']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick+3).filter{it.status>=1 && it.forecast==true}.collect();
+co2Emissions = 0
+for(plan in ppdps){
+fuelMix=plan.out('POWERPLANT_DISPATCHPLAN').out('FUEL_MIX').collect()
+singleEmission=0
+ for(fuelMixElement in fuelMix){
+ //fuelMixElement=fuelMix[1]
+ share=fuelMixElement.share
+ co2Density=fuelMixElement.out('SUBSTANCE').collect{it.co2Density}[0]*(1-plan.out('POWERPLANT_DISPATCHPLAN').out('TECHNOLOGY').collect{it.co2CaptureEffciency}[0])
+ singleEmission+=share*co2Density
+ }
+ co2Emissions+=plan.acceptedAmount*singleEmission*plan.out('SEGMENT_DISPATCHPLAN').collect{it.lengthInHours}[0]
+}
+return co2Emissions",
+
+"EUCO2PriceFloor", "Government", "try{price = v.out('MINCO2PRICE_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('MINCO2PRICE_TREND').timeSeries.next()[tick.toInteger()];};
+return ['EU CO2 price floor', price];",
+
+"CO2Tax", "Government", "try{price = v.out('CO2TAX_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+price = v.out('CO2TAX_TREND').timeSeries.next()[tick.toInteger()];}
+return price",
+
+"FuelPricesPerGJ", "DecarbonizationModel", "fuels = g.idx('__types__')[[className:'emlab.gen.domain.technology.Substance']].filter{it.name != 'Electricity' && it.name != 'CO2'}
+result = []
+for(v in fuels){
+ price = v.in('SUBSTANCE_MARKET').in('MARKET_POINT').filter{it.time == tick}.collect{it.price};
+ density = v.energyDensity;
+ inGJ = price[0] / density;
+ result.add([v.name,inGJ]);}
+ return result",
+
+"ProducerCash", "EnergyProducer", "[v.name, v.cash]",
+
+"AggregateFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0]) {
+ //totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;
+",
+
+"CountryAProdFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;
+",
+
+"CountryBProdFinances", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+totalCosts = 0;
+totalRevenue = 0;
+totalSpotRevenue = 0;
+totalLTCRevenue = 0;
+totalCMRevenue = 0;
+totalRESRevenue=0;
+totalCO2HedgingRevenue=0;
+totalTargetInvCosts = 0;
+totalTargetInvRevenue = 0;
+totalTargetInvSpotRevenue = 0;
+totalTargetInvLTCRevenue = 0;
+totalTargetInvCMRevenue = 0;
+totalTargetInvRESRevenue=0;
+totalTargetInvCO2HedgingRevenue=0;
+hedgingFlows=[]
+for (key in groups.keySet()) {
+ if (key<3 || (key>9 && key!=12)) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvRevenue += flow.money;
+ }
+ }
+
+ } else if(key!=12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCosts += flow.money;
+ } else if(flow.out('FROM_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCosts += flow.money;
+ }
+ }
+ }
+
+ if (key==1) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalSpotRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvSpotRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==2) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalLTCRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvLTCRevenue += flow.money;
+ }
+ }
+
+ }
+
+ if (key==11) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCMRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCMRevenue += flow.money;
+ }
+ }
+
+ }
+
+
+ if (key==10) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalRESRevenue += flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvRESRevenue += flow.money;
+ }
+ }
+
+ }
+
+if (key==12) {
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ hedgingFlows.add(flow)
+ if (flow.out('TO_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCO2HedgingRevenue += flow.money;
+ totalRevenue+= flow.money;
+ } else if(flow.out('TO_AGENT').collect{it.__type__.contains('TargetInvestor') }[0] && flow.out('TO_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]){
+ totalTargetInvCO2HedgingRevenue += flow.money;
+ }
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer') }[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ totalCO2HedgingRevenue -= flow.money;
+ totalCosts+= flow.money;
+ }
+ }
+ }
+
+}
+result.add(['Total Revenue', totalRevenue]);
+result.add(['Revenue LTC', totalLTCRevenue]);
+result.add(['Revenue Spot', totalSpotRevenue]);
+result.add(['Revenue CM', totalCMRevenue])
+result.add(['Revenue RES',totalRESRevenue])
+result.add(['Revenue CO2Hedge', totalCO2HedgingRevenue]);
+result.add(['Profit', totalRevenue - totalCosts]);
+result.add(['TI Revenue', totalTargetInvRevenue]);
+result.add(['TI Revenue LTC', totalTargetInvLTCRevenue]);
+result.add(['TI Revenue Spot', totalTargetInvSpotRevenue]);
+result.add(['TI Revenue CM', totalTargetInvCMRevenue])
+result.add(['TI Revenue RES',totalTargetInvRESRevenue])
+result.add(['TI Revenue CO2Hedge', totalTargetInvCO2HedgingRevenue]);
+result.add(['TI Profit', totalTargetInvRevenue - totalTargetInvCosts]);
+return result;",
+
+"PriceInEURperMWh", "DecarbonizationModel", "results = []
+points = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+for(scp in points){
+ results.add(['Segment ' + scp.out('MARKET_POINT').out('ZONE').name.next() + ' ' + scp.out('SEGMENT_POINT').segmentID.next(), scp.price])
+}
+return results",
+
+"ShortagesInHoursUnserved", "DecarbonizationModel", "powerplants = g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']].filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}
+production= powerplants.in('POWERPLANT_DISPATCHPLAN').sum{f.determineProductionOfDispatchPlanInMWh(it, tick)};
+segmentloads = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentLoad']]
+productionsum = 0;
+for(segmentload in segmentloads){
+ try{growthfactor = segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentload.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]}
+ productionsum += segmentload.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentload.baseLoad * growthfactor;
+}
+return (production-productionsum)/productionsum*8760;",
+
+"ProducerCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"CountryAProdCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country A')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"CountryBProdCosts", "DecarbonizationModel", "flows = n.getNodes('CashFlow');
+groups = flows.groupBy{it.type}
+result = [];
+allKeys = []
+for(i in 0..12)
+ allKeys.add(i)
+usedKeys=[]
+for (key in allKeys) {
+ usedKeys.add(key)
+ sum = 0;
+ if(key in groups.keySet()){
+ for (flow in groups[key]) {
+ if (flow.time != tick) continue;
+ if (flow.out('FROM_AGENT').collect{it.__type__.contains('EnergyProducer')}[0] && flow.out('FROM_AGENT').out('INVESTOR_MARKET').out('ZONE').collect{it.name.equals('Country B')}[0]) {
+ sum += flow.money;
+ }
+ }
+ }
+ name='Unspecified';
+ if(key==0){name='Unclassified';}
+ if(key==1){name='Electricity spot';}
+ if(key==2){name='Electricity ltc';}
+ if(key==3){name='Fixed O&M';}
+ if(key==4){name='Commodity';}
+ if(key==5){name='CO2 tax';}
+ if(key==6){name='CO2 auction';}
+ if(key==7){name='Loan';}
+ if(key==8){name='Downpayment';}
+ if(key==9){name='National CO2 MinPrice';}
+ if(key==10){name='Strategic Reserve';}
+ if(key==11){name='Capacity Market';}
+ if(key==12){name='CO2 Hedging';}
+ result.add([name, sum]);
+}
+return result;",
+
+"TABLE_SegmentClearingPoints", "DecarbonizationModel", "points = g.idx('__types__')[[className:'emlab.gen.domain.market.electricity.SegmentClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+finalResult = []
+headers=['tick','volume','price','market','segmentID','segmentLength','interconectorFlow','demand','energynotserved']
+finalResult.add(headers)
+for(v in points){
+market=v.out('MARKET_POINT')
+segment=v.out('SEGMENT_POINT').next()
+segmentId=segment.segmentID
+segmentLoad=market.out('SEGMENT_LOAD').as('x').out('SEGMENTLOAD_SEGMENT').filter{it.segmentID==segmentId}.back('x').next();
+//return segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]
+//return segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').next().timeSeries[tick.toInteger()]
+growthfactor=1
+try{growthfactor = segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){
+ growthfactor=segmentLoad.in('SEGMENT_LOAD').out('DEMANDGROWTH_TREND').next().timeSeries[tick.toInteger()]}
+//}
+//return segmentLoad
+demandLevel=segmentLoad.out('SEGMENTLOAD_SEGMENT').lengthInHours.next() * segmentLoad.baseLoad * growthfactor;
+ finalResult.add([v.time, v.volume, v.price, v.out('MARKET_POINT').collect{it.name}[0], v.out('SEGMENT_POINT').collect{it.segmentID}[0], v.out('SEGMENT_POINT').collect{it.lengthInHours}[0],v.interconnectorFlow,demandLevel,demandLevel-v.volume])
+}
+return finalResult;
+",
+
+"TABLE_ClearingPoints", "DecarbonizationModel", "points = g.idx('__types__')[[className:'emlab.gen.domain.market.ClearingPoint']].propertyFilter('time', FilterPipe.Filter.EQUAL, tick).propertyFilter('forecast', FilterPipe.Filter.EQUAL, false)
+finalResult = []
+headers=['tick','volume','price',',market']
+finalResult.add(headers)
+for(v in points){
+finalResult.add([v.time, v.volume, v.price, v.out('MARKET_POINT').collect{it.name}[0]])
+}
+return finalResult",
+
+"TABLE_InitialPowerPlants", "DecarbonizationModel", "if(tick<1){
+powerPlants=g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']];
+finalResult = [];
+columnNames=['Name', 'Technology', 'Location', 'Age', 'Owner', 'Capacity', 'Efficiency']
+finalResult.add(columnNames)
+for(p in powerPlants){
+name = p.name
+technology = p.out('TECHNOLOGY').collect{it.name}[0]
+location = p.out('LOCATION').collect{it.name}[0]
+age = -p.constructionStartTime-p.actualLeadtime-p.actualPermittime
+owner = p.out('POWERPLANT_OWNER').collect{it.name}[0]
+capacity = p.actualNominalCapacity
+efficiency = p.actualEfficiency
+finalResult.add([name,technology,location,age,owner,capacity,efficiency])
+}
+return finalResult
+}",
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/agent/DecarbonizationModel.java b/emlab-generation/src/main/java/emlab/gen/domain/agent/DecarbonizationModel.java
index 8a6ec4be..e7888051 100644
--- a/emlab-generation/src/main/java/emlab/gen/domain/agent/DecarbonizationModel.java
+++ b/emlab-generation/src/main/java/emlab/gen/domain/agent/DecarbonizationModel.java
@@ -54,9 +54,6 @@ public class DecarbonizationModel extends AbstractAgent implements Agent {
private double stabilityReserveBankingThirdYear;
- private boolean noPrivateIntermittentRESInvestment;
-
-
@SimulationParameter(label = "Simulation Length", from = 0, to = 75)
private double simulationLength;
@@ -75,9 +72,44 @@ public class DecarbonizationModel extends AbstractAgent implements Agent {
@SimulationParameter(label = "Exit simulation after simulation length")
private boolean exitSimulationAfterSimulationLength;
+ @SimulationParameter(label = "Simple Capacity Market")
+ private boolean simpleCapacityMarketEnabled;
+
+ @SimulationParameter(label = "Feed in Premium")
+ private boolean feedInPremiumImplemented;
+
@SimulationParameter(label = "Deletion age")
private long deletionAge;
+ @SimulationParameter(label = "Renewable Tender Scheme")
+ private boolean renewableTenderSchemeImplemented;
+
+ private boolean noPrivateIntermittentRESInvestment;
+
+ public boolean isRenewableTenderSchemeImplemented() {
+ return renewableTenderSchemeImplemented;
+ }
+
+ public void setRenewableTenderSchemeImplemented(boolean renewableTenderSchemeImplemented) {
+ this.renewableTenderSchemeImplemented = renewableTenderSchemeImplemented;
+ }
+
+ public boolean isFeedInPremiumImplemented() {
+ return feedInPremiumImplemented;
+ }
+
+ public void setFeedInPremiumImplemented(boolean feedInPremiumImplemented) {
+ this.feedInPremiumImplemented = feedInPremiumImplemented;
+ }
+
+ public boolean isSimpleCapacityMarketEnabled() {
+ return simpleCapacityMarketEnabled;
+ }
+
+ public void setSimpleCapacityMarketEnabled(boolean simpleCapacityMarketEnabled) {
+ this.simpleCapacityMarketEnabled = simpleCapacityMarketEnabled;
+ }
+
public boolean isRealRenewableDataImplemented() {
return realRenewableDataImplemented;
}
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/agent/EnergyProducer.java b/emlab-generation/src/main/java/emlab/gen/domain/agent/EnergyProducer.java
index b9a95bbe..17834c7f 100644
--- a/emlab-generation/src/main/java/emlab/gen/domain/agent/EnergyProducer.java
+++ b/emlab-generation/src/main/java/emlab/gen/domain/agent/EnergyProducer.java
@@ -1,12 +1,12 @@
/*******************************************************************************
* Copyright 2012 the original author or authors.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -42,7 +42,7 @@ public class EnergyProducer extends DecarbonizationAgent implements Agent {
@SimulationParameter(label = "Long-term contract horizon", from = 0, to = 10)
private double longTermContractPastTimeHorizon;
- //Investment
+ // Investment
@SimulationParameter(label = "Investment horizon", from = 0, to = 15)
private int investmentFutureTimeHorizon;
@SimulationParameter(label = "Equity Interest Rate", from = 0, to = 1)
@@ -52,11 +52,22 @@ public class EnergyProducer extends DecarbonizationAgent implements Agent {
private double debtRatioOfInvestments;
private boolean willingToInvest;
+ @SimulationParameter(label = "Simple Capacity Market")
+ private boolean simpleCapacityMarketEnabled;
+
+ public boolean isSimpleCapacityMarketEnabled() {
+ return simpleCapacityMarketEnabled;
+ }
+
+ public void setSimpleCapacityMarketEnabled(boolean isSimpleCapacityMarketEnabled) {
+ this.simpleCapacityMarketEnabled = isSimpleCapacityMarketEnabled;
+ }
+
// Loan
@SimulationParameter(label = "Loan Interest Rate", from = 0, to = 1)
private double loanInterestRate;
- //Forecasting
+ // Forecasting
private int numberOfYearsBacklookingForForecasting;
// Dismantling
@@ -64,6 +75,12 @@ public class EnergyProducer extends DecarbonizationAgent implements Agent {
private double dismantlingRequiredOperatingProfit;
private long pastTimeHorizon;
+ // Historical CVar Parameters
+ private double historicalCVarAlpha;
+ private double historicalCVarBeta;
+ private double historicalCVarPropensityForNewTechnologies;
+ private double historicalCVarInterestRateIncreaseForNewTechnologies;
+
public boolean isWillingToInvest() {
return willingToInvest;
}
@@ -108,7 +125,8 @@ public int getDismantlingProlongingYearsAfterTechnicalLifetime() {
return dismantlingProlongingYearsAfterTechnicalLifetime;
}
- public void setDismantlingProlongingYearsAfterTechnicalLifetime(int dismantlingProlongingYearsAfterTechnicalLifetime) {
+ public void setDismantlingProlongingYearsAfterTechnicalLifetime(
+ int dismantlingProlongingYearsAfterTechnicalLifetime) {
this.dismantlingProlongingYearsAfterTechnicalLifetime = dismantlingProlongingYearsAfterTechnicalLifetime;
}
@@ -183,4 +201,38 @@ public ElectricitySpotMarket getInvestorMarket() {
public void setInvestorMarket(ElectricitySpotMarket investorMarket) {
this.investorMarket = investorMarket;
}
+
+ public double getHistoricalCVarAlpha() {
+ return historicalCVarAlpha;
+ }
+
+ public void setHistoricalCVarAlpha(double historicalCVarAlpha) {
+ this.historicalCVarAlpha = historicalCVarAlpha;
+ }
+
+ public double getHistoricalCVarBeta() {
+ return historicalCVarBeta;
+ }
+
+ public void setHistoricalCVarBeta(double historicalCVarBeta) {
+ this.historicalCVarBeta = historicalCVarBeta;
+ }
+
+ public double getHistoricalCVarPropensityForNewTechnologies() {
+ return historicalCVarPropensityForNewTechnologies;
+ }
+
+ public void setHistoricalCVarPropensityForNewTechnologies(double historicalCVarPropensityForNewTechnologies) {
+ this.historicalCVarPropensityForNewTechnologies = historicalCVarPropensityForNewTechnologies;
+ }
+
+ public double getHistoricalCVarInterestRateIncreaseForNewTechnologies() {
+ return historicalCVarInterestRateIncreaseForNewTechnologies;
+ }
+
+ public void setHistoricalCVarInterestRateIncreaseForNewTechnologies(
+ double historicalCVarInterestRateIncreaseForNewTechnologies) {
+ this.historicalCVarInterestRateIncreaseForNewTechnologies = historicalCVarInterestRateIncreaseForNewTechnologies;
+ }
+
}
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/agent/Government.java b/emlab-generation/src/main/java/emlab/gen/domain/agent/Government.java
index f9d3de7b..1fab770e 100644
--- a/emlab-generation/src/main/java/emlab/gen/domain/agent/Government.java
+++ b/emlab-generation/src/main/java/emlab/gen/domain/agent/Government.java
@@ -61,10 +61,14 @@ public class Government extends DecarbonizationAgent implements Agent {
private boolean adaptiveCapAdjustmentBasedOnCapNotActualEmissions;
+ private boolean adaptiveCapAdjustmentRelativeToNonSubsidisedProduction;
+
private double co2Penalty;
private double stabilityReserve;
+ private boolean stabilityReserveHasOneYearDelayInsteadOfTwoYearDelay;
+
@RelatedTo(type = "STABILITY_RESERVE_UPPER_TRIGGER", elementClass = TimeSeriesImpl.class, direction = Direction.OUTGOING)
private TimeSeriesImpl stabilityReserveUpperTriggerTrend;
@@ -223,4 +227,23 @@ public void setAdaptiveCapAdjustmentBasedOnCapNotActualEmissions(
this.adaptiveCapAdjustmentBasedOnCapNotActualEmissions = adaptiveCapAdjustmentBasedOnCapNotActualEmissions;
}
+
+ public boolean isAdaptiveCapAdjustmentRelativeToNonSubsidisedProduction() {
+ return adaptiveCapAdjustmentRelativeToNonSubsidisedProduction;
+ }
+
+ public void setAdaptiveCapAdjustmentRelativeToNonSubsidisedProduction(
+ boolean adaptiveCapAdjustmentRelativeToNonSubsidisedProduction) {
+ this.adaptiveCapAdjustmentRelativeToNonSubsidisedProduction = adaptiveCapAdjustmentRelativeToNonSubsidisedProduction;
+ }
+
+ public boolean isStabilityReserveHasOneYearDelayInsteadOfTwoYearDelay() {
+ return stabilityReserveHasOneYearDelayInsteadOfTwoYearDelay;
+ }
+
+ public void setStabilityReserveHasOneYearDelayInsteadOfTwoYearDelay(
+ boolean stabilityReserveHasOneYearDelayInsteadOfTwoYearDelay) {
+ this.stabilityReserveHasOneYearDelayInsteadOfTwoYearDelay = stabilityReserveHasOneYearDelayInsteadOfTwoYearDelay;
+ }
+
}
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/agent/Regulator.java b/emlab-generation/src/main/java/emlab/gen/domain/agent/Regulator.java
new file mode 100644
index 00000000..6cbd2ca0
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/domain/agent/Regulator.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright 2015 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.domain.agent;
+
+import org.neo4j.graphdb.Direction;
+import org.springframework.data.neo4j.annotation.NodeEntity;
+import org.springframework.data.neo4j.annotation.RelatedTo;
+
+import agentspring.agent.Agent;
+import agentspring.simulation.SimulationParameter;
+import emlab.gen.domain.gis.Zone;
+
+/**
+ * @author Kaveri
+ *
+ */
+@NodeEntity
+public class Regulator extends DecarbonizationAgent implements Agent {
+
+ @RelatedTo(type = "OF_ZONE", elementClass = Zone.class, direction = Direction.OUTGOING)
+ private Zone zone;
+
+ private int numberOfYearsLookingBackToForecastDemand;
+
+ // Capacity Market Related Parameters
+
+ @SimulationParameter(label = "Capacity Market Price Cap", from = 1000, to = 150000)
+ private double capacityMarketPriceCap;
+
+ @SimulationParameter(label = "Reserve Margin", from = 0, to = 1)
+ private double reserveMargin;
+
+ @SimulationParameter(label = "Reserve Demand Lower Margin", from = 0, to = 1)
+ private double reserveDemandLowerMargin;
+
+ @SimulationParameter(label = "Reserve Demand Upper Margin", from = 0, to = 1)
+ private double reserveDemandUpperMargin;
+
+ private double demandTarget;
+
+ @SimulationParameter(label = "Capacity Market Target Period", from = 0, to = 10)
+ private int targetPeriod; // number of years in the future that the capacity
+ // is being planned for - set to zero
+
+ // Feed-in-Premium Related PÃ rameters
+ @SimulationParameter(label = "FeedInPremiumFactor", from = 0, to = 1)
+ private double feedInPremiumFactor;
+
+ // Tender parameters
+ private double annualRenewableTargetInMwh;
+
+ public double getAnnualRenewableTargetInMwh() {
+ return annualRenewableTargetInMwh;
+ }
+
+ public void setAnnualRenewableTargetInMwh(double annualRenewableTargetInMwh) {
+ this.annualRenewableTargetInMwh = annualRenewableTargetInMwh;
+ }
+
+ public double getDemandTarget() {
+ return demandTarget;
+ }
+
+ public void setDemandTarget(double demandTarget) {
+ this.demandTarget = demandTarget;
+ }
+
+ public double getCapacityMarketPriceCap() {
+ return capacityMarketPriceCap;
+ }
+
+ public void setCapacityMarketPriceCap(double capacityMarketPriceCap) {
+ this.capacityMarketPriceCap = capacityMarketPriceCap;
+ }
+
+ public int getNumberOfYearsLookingBackToForecastDemand() {
+ return numberOfYearsLookingBackToForecastDemand;
+ }
+
+ public void setNumberOfYearsLookingBackToForecastDemand(int numberOfYearsLookingBackToForecastDemand) {
+ this.numberOfYearsLookingBackToForecastDemand = numberOfYearsLookingBackToForecastDemand;
+ }
+
+ public int getTargetPeriod() {
+ return targetPeriod;
+ }
+
+ public double getFeedInPremiumFactor() {
+ return feedInPremiumFactor;
+ }
+
+ public void setFeedInPremiumFactor(double feedInPremiumFactor) {
+ this.feedInPremiumFactor = feedInPremiumFactor;
+ }
+
+ public void setTargetPeriod(int targetPeriod) {
+ this.targetPeriod = targetPeriod;
+ }
+
+ public double getReserveDemandLowerMargin() {
+ return reserveDemandLowerMargin;
+ }
+
+ public void setReserveDemandLowerMargin(double reserveDemandLowerMargin) {
+ this.reserveDemandLowerMargin = reserveDemandLowerMargin;
+ }
+
+ public double getReserveDemandUpperMargin() {
+ return reserveDemandUpperMargin;
+ }
+
+ public void setReserveDemandUpperMargin(double reserveDemandUpperMargin) {
+ this.reserveDemandUpperMargin = reserveDemandUpperMargin;
+ }
+
+ public double getReserveMargin() {
+ return reserveMargin;
+ }
+
+ public void setReserveMargin(double reserveMargin) {
+ this.reserveMargin = reserveMargin;
+ }
+
+ public Zone getZone() {
+ return zone;
+ }
+
+ public void setZone(Zone zone) {
+ this.zone = zone;
+ }
+
+}
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/contract/CashFlow.java b/emlab-generation/src/main/java/emlab/gen/domain/contract/CashFlow.java
index 34ba51f5..84ab348b 100644
--- a/emlab-generation/src/main/java/emlab/gen/domain/contract/CashFlow.java
+++ b/emlab-generation/src/main/java/emlab/gen/domain/contract/CashFlow.java
@@ -36,7 +36,10 @@ public class CashFlow {
public static final int DOWNPAYMENT = 8;
public static final int NATIONALMINCO2 = 9;
public static final int STRRESPAYMENT = 10;
+ public static final int SIMPLE_CAPACITY_MARKET = 11;
public static final int CO2HEDGING = 12;
+ public static final int FEED_IN_PREMIUM = 13;
+ public static final int TENDER_SUBSIDY = 14;
@RelatedTo(type = "FROM_AGENT", elementClass = DecarbonizationAgent.class, direction = Direction.OUTGOING)
private DecarbonizationAgent from;
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/contract/Loan.java b/emlab-generation/src/main/java/emlab/gen/domain/contract/Loan.java
index 3327b949..dcb56b44 100644
--- a/emlab-generation/src/main/java/emlab/gen/domain/contract/Loan.java
+++ b/emlab-generation/src/main/java/emlab/gen/domain/contract/Loan.java
@@ -1,12 +1,12 @@
/*******************************************************************************
* Copyright 2012 the original author or authors.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,9 +16,9 @@
package emlab.gen.domain.contract;
+import org.neo4j.graphdb.Direction;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.RelatedTo;
-import org.neo4j.graphdb.Direction;
import emlab.gen.domain.agent.DecarbonizationAgent;
import emlab.gen.domain.technology.PowerPlant;
@@ -32,7 +32,7 @@ public class Loan {
@RelatedTo(type = "LEND_BY_AGENT", elementClass = DecarbonizationAgent.class, direction = Direction.OUTGOING)
private DecarbonizationAgent to;
- @RelatedTo(type = "REGARDING_POWERPLANT", elementClass = PowerPlant.class, direction = Direction.OUTGOING)
+ @RelatedTo(type = "LOAN_POWERPLANT", elementClass = PowerPlant.class, direction = Direction.OUTGOING)
private PowerPlant regardingPowerPlant;
private double amountPerPayment;
@@ -49,30 +49,30 @@ public void setLoanStartTime(long loanStartTime) {
}
public long getTotalNumberOfPayments() {
- return totalNumberOfPayments;
- }
+ return totalNumberOfPayments;
+ }
- public double getAmountPerPayment() {
- return amountPerPayment;
- }
+ public double getAmountPerPayment() {
+ return amountPerPayment;
+ }
- public void setAmountPerPayment(double amountPerPayment) {
- this.amountPerPayment = amountPerPayment;
- }
+ public void setAmountPerPayment(double amountPerPayment) {
+ this.amountPerPayment = amountPerPayment;
+ }
- public void setTotalNumberOfPayments(long totalNumberOfPayments) {
- this.totalNumberOfPayments = totalNumberOfPayments;
- }
+ public void setTotalNumberOfPayments(long totalNumberOfPayments) {
+ this.totalNumberOfPayments = totalNumberOfPayments;
+ }
- public long getNumberOfPaymentsDone() {
- return numberOfPaymentsDone;
- }
+ public long getNumberOfPaymentsDone() {
+ return numberOfPaymentsDone;
+ }
- public void setNumberOfPaymentsDone(long numberOfPaymentsDone) {
- this.numberOfPaymentsDone = numberOfPaymentsDone;
- }
+ public void setNumberOfPaymentsDone(long numberOfPaymentsDone) {
+ this.numberOfPaymentsDone = numberOfPaymentsDone;
+ }
- public DecarbonizationAgent getFrom() {
+ public DecarbonizationAgent getFrom() {
return from;
}
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/factory/ElectricityProducerFactory.java b/emlab-generation/src/main/java/emlab/gen/domain/factory/ElectricityProducerFactory.java
index 111ce39e..38647ade 100644
--- a/emlab-generation/src/main/java/emlab/gen/domain/factory/ElectricityProducerFactory.java
+++ b/emlab-generation/src/main/java/emlab/gen/domain/factory/ElectricityProducerFactory.java
@@ -67,7 +67,7 @@ private PowerPlant createPowerPlant(PowerGeneratingTechnology technology, Energy
// the pipeline at the start?
plant.setActualLeadtime(plant.getTechnology().getExpectedLeadtime());
plant.setActualPermittime(plant.getTechnology().getExpectedPermittime());
- plant.setExpectedEndOfLife(plant.getConstructionStartTime() + plant.getActualPermittime() + plant.getActualLeadtime()
+ plant.setExpectedEndOfLife(plant.getConstructionStartTime() + plant.getActualPermittime() + plant.getActualLeadTime()
+ plant.getTechnology().getExpectedLifetime());
plant.setActualNominalCapacity(technology.getCapacity() * location.getCapacityMultiplicationFactor());
plant.calculateAndSetActualInvestedCapital(plant.getConstructionStartTime());
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/factory/PowerPlantEntryParser.java b/emlab-generation/src/main/java/emlab/gen/domain/factory/PowerPlantEntryParser.java
index 7dcc170c..0f91b32c 100644
--- a/emlab-generation/src/main/java/emlab/gen/domain/factory/PowerPlantEntryParser.java
+++ b/emlab-generation/src/main/java/emlab/gen/domain/factory/PowerPlantEntryParser.java
@@ -159,7 +159,7 @@ private PowerPlant createPowerPlant(String name, PowerGeneratingTechnology techn
plant.setActualLeadtime(plant.getTechnology().getExpectedLeadtime());
plant.setActualPermittime(plant.getTechnology().getExpectedPermittime());
plant.setExpectedEndOfLife(plant.getConstructionStartTime() + plant.getActualPermittime()
- + plant.getActualLeadtime() + plant.getTechnology().getExpectedLifetime());
+ + plant.getActualLeadTime() + plant.getTechnology().getExpectedLifetime());
if (capacity == 0) {
plant.setActualNominalCapacity(technology.getCapacity() * location.getCapacityMultiplicationFactor());
} else {
@@ -174,6 +174,8 @@ private PowerPlant createPowerPlant(String name, PowerGeneratingTechnology techn
}
plant.calculateAndSetActualFixedOperatingCosts(plant.getConstructionStartTime());
plant.setDismantleTime(1000);
+ // BigBank bigbank = reps.genericRepository.findFirst(BigBank.class);
+
Loan loan = new Loan().persist();
loan.setFrom(energyProducer);
loan.setTo(null);
@@ -189,6 +191,7 @@ private PowerPlant createPowerPlant(String name, PowerGeneratingTechnology techn
// already
// made
plant.setLoan(loan);
+ loan.setRegardingPowerPlant(plant);
return plant;
}
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/market/Bid.java b/emlab-generation/src/main/java/emlab/gen/domain/market/Bid.java
index fc7d5cdf..9bfd74e1 100644
--- a/emlab-generation/src/main/java/emlab/gen/domain/market/Bid.java
+++ b/emlab-generation/src/main/java/emlab/gen/domain/market/Bid.java
@@ -63,9 +63,9 @@ public void setBiddingMarket(DecarbonizationMarket market) {
}
/**
- * IMPORTANT this returns the capacity that was bid into the spot market,
- * so for the depending class PPDP this means without the capacity reserved
- * for long-term markets.
+ * IMPORTANT this returns the capacity that was bid into the spot market, so
+ * for the depending class PPDP this means without the capacity reserved for
+ * long-term markets.
*
* @return
*/
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/market/capacity/CapacityClearingPoint.java b/emlab-generation/src/main/java/emlab/gen/domain/market/capacity/CapacityClearingPoint.java
new file mode 100644
index 00000000..1b5330d8
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/domain/market/capacity/CapacityClearingPoint.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.domain.market.capacity;
+
+import org.neo4j.graphdb.Direction;
+import org.springframework.data.neo4j.annotation.NodeEntity;
+import org.springframework.data.neo4j.annotation.RelatedTo;
+
+import emlab.gen.domain.market.ClearingPoint;
+
+/**
+ * @author Kaveri
+ *
+ */
+@NodeEntity
+public class CapacityClearingPoint extends ClearingPoint {
+
+ @RelatedTo(type = "CAPACITY_MARKET", elementClass = CapacityMarket.class, direction = Direction.OUTGOING)
+ private CapacityMarket capacityMarket;
+
+ public CapacityMarket getCapacityMarket() {
+ return capacityMarket;
+ }
+
+ public void setCapacityMarket(CapacityMarket capacityMarket) {
+ this.capacityMarket = capacityMarket;
+ }
+
+}
\ No newline at end of file
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/market/capacity/CapacityDispatchPlan.java b/emlab-generation/src/main/java/emlab/gen/domain/market/capacity/CapacityDispatchPlan.java
new file mode 100644
index 00000000..22088e96
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/domain/market/capacity/CapacityDispatchPlan.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.domain.market.capacity;
+
+import org.neo4j.graphdb.Direction;
+import org.springframework.data.neo4j.annotation.NodeEntity;
+import org.springframework.data.neo4j.annotation.RelatedTo;
+import org.springframework.transaction.annotation.Transactional;
+
+import emlab.gen.domain.agent.EnergyProducer;
+import emlab.gen.domain.market.Bid;
+import emlab.gen.domain.technology.PowerPlant;
+
+/**
+ * @author Kaveri
+ *
+ */
+
+@NodeEntity
+public class CapacityDispatchPlan extends Bid {
+
+ @RelatedTo(type = "CAPACITY_DISPATCHPLAN", elementClass = PowerPlant.class, direction = Direction.OUTGOING)
+ private PowerPlant plant;
+
+ public PowerPlant getPlant() {
+ return plant;
+ }
+
+ public void setPlant(PowerPlant plant) {
+ this.plant = plant;
+ }
+
+ public void specifyNotPersist(PowerPlant plant, EnergyProducer producer, CapacityMarket market, long time,
+ double price, double capacityMarketCapacity, int status) {
+ this.setPlant(plant);
+ this.setTime(time);
+ this.setBidder(producer);
+ this.setBiddingMarket(market);
+ this.setPrice(price);
+ this.setAmount(capacityMarketCapacity);
+ this.setStatus(status);
+ }
+
+ /**
+ * @param plant
+ */
+
+ // All transactional methods below are signified by starting with update
+ @Transactional
+ public void specifyAndPersist(PowerPlant plant, EnergyProducer producer, CapacityMarket market, long time,
+ double price, double capacityMarketCapacity, int status) {
+ this.persist();
+ this.specifyNotPersist(plant, producer, market, time, price, capacityMarketCapacity, status);
+
+ }
+
+}
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/market/capacity/CapacityMarket.java b/emlab-generation/src/main/java/emlab/gen/domain/market/capacity/CapacityMarket.java
new file mode 100644
index 00000000..2ee11189
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/domain/market/capacity/CapacityMarket.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.domain.market.capacity;
+
+import org.neo4j.graphdb.Direction;
+import org.springframework.data.neo4j.annotation.NodeEntity;
+import org.springframework.data.neo4j.annotation.RelatedTo;
+
+import emlab.gen.domain.agent.EnergyConsumer;
+import emlab.gen.domain.agent.Regulator;
+import emlab.gen.domain.market.DecarbonizationMarket;
+
+/**
+ * @author Kaveri Agent Capacity Market for implementation of a Simple Capacity
+ * Market
+ *
+ */
+@NodeEntity
+public class CapacityMarket extends DecarbonizationMarket {
+
+ @RelatedTo(type = "WITH_REGULATOR", elementClass = Regulator.class, direction = Direction.OUTGOING)
+ private Regulator regulator;
+
+ @RelatedTo(type = "WITH_CONSUMER", elementClass = EnergyConsumer.class, direction = Direction.OUTGOING)
+ private EnergyConsumer consumer;
+
+ public EnergyConsumer getConsumer() {
+ return consumer;
+ }
+
+ public void setConsumer(EnergyConsumer consumer) {
+ this.consumer = consumer;
+ }
+
+ public Regulator getRegulator() {
+ return regulator;
+ }
+
+ public void setRegulator(Regulator regulator) {
+ this.regulator = regulator;
+ }
+
+}
\ No newline at end of file
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/market/capacity/package-info.java b/emlab-generation/src/main/java/emlab/gen/domain/market/capacity/package-info.java
new file mode 100644
index 00000000..76418697
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/domain/market/capacity/package-info.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+/**
+ * @author Kaveri
+ *This package contains all the classes necessary for the implementation of a simple capacity market
+ * */
+package emlab.gen.domain.market.capacity;
\ No newline at end of file
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/market/electricity/ElectricitySpotMarket.java b/emlab-generation/src/main/java/emlab/gen/domain/market/electricity/ElectricitySpotMarket.java
index 22e5bbb8..50b0baef 100644
--- a/emlab-generation/src/main/java/emlab/gen/domain/market/electricity/ElectricitySpotMarket.java
+++ b/emlab-generation/src/main/java/emlab/gen/domain/market/electricity/ElectricitySpotMarket.java
@@ -21,6 +21,7 @@
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.RelatedTo;
+import agentspring.simulation.SimulationParameter;
import emlab.gen.domain.market.DecarbonizationMarket;
import emlab.gen.trend.TimeSeriesImpl;
@@ -30,11 +31,33 @@ public class ElectricitySpotMarket extends DecarbonizationMarket {
@RelatedTo(type = "SEGMENT_LOAD", elementClass = SegmentLoad.class, direction = Direction.OUTGOING)
private Set loadDurationCurve;
- @RelatedTo(type = "DEMANDGROWTH_TREND", elementClass = TimeSeriesImpl.class, direction = Direction.OUTGOING)
- private TimeSeriesImpl demandGrowthTrend;
+ @RelatedTo(type = "DEMANDGROWTH_TREND", elementClass = TimeSeriesImpl.class, direction = Direction.OUTGOING)
+ private TimeSeriesImpl demandGrowthTrend;
private double valueOfLostLoad;
+ @SimulationParameter(label = "Lookback for dismantling", from = 0, to = 10)
+ private long lookback;
+
+ @SimulationParameter(label = "Look back for demand forecasting", from = 0, to = 10)
+ private long backlookingForDemandForecastinginDismantling;
+
+ public long getLookback() {
+ return lookback;
+ }
+
+ public void setLookback(long lookback) {
+ this.lookback = lookback;
+ }
+
+ public long getBacklookingForDemandForecastinginDismantling() {
+ return backlookingForDemandForecastinginDismantling;
+ }
+
+ public void setBacklookingForDemandForecastinginDismantling(long backlookingForDemandForecastinginDismantling) {
+ this.backlookingForDemandForecastinginDismantling = backlookingForDemandForecastinginDismantling;
+ }
+
public Set getLoadDurationCurve() {
return loadDurationCurve;
}
@@ -51,11 +74,11 @@ public void setValueOfLostLoad(double valueOfLostLoad) {
this.valueOfLostLoad = valueOfLostLoad;
}
- public TimeSeriesImpl getDemandGrowthTrend() {
+ public TimeSeriesImpl getDemandGrowthTrend() {
return demandGrowthTrend;
}
- public void setDemandGrowthTrend(TimeSeriesImpl demandGrowthTrend) {
+ public void setDemandGrowthTrend(TimeSeriesImpl demandGrowthTrend) {
this.demandGrowthTrend = demandGrowthTrend;
}
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/market/electricity/FinancialPowerPlantReport.java b/emlab-generation/src/main/java/emlab/gen/domain/market/electricity/FinancialPowerPlantReport.java
new file mode 100644
index 00000000..9436e710
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/domain/market/electricity/FinancialPowerPlantReport.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.domain.market.electricity;
+
+import org.neo4j.graphdb.Direction;
+import org.springframework.data.neo4j.annotation.NodeEntity;
+import org.springframework.data.neo4j.annotation.RelatedTo;
+
+import emlab.gen.domain.technology.PowerPlant;
+
+/**
+ * This class reresents a financial report per power plant per year. It is
+ * mainly used to condense information (from CashFlows and
+ * PowerPlantDispatchPlans, which are regularly deleted for performance reasons)
+ * and make it accessible to agents within the information, but also to the
+ * analyst using EMLab-Generation.
+ *
+ * @author JCRichstein
+ *
+ */
+@NodeEntity
+public class FinancialPowerPlantReport {
+
+ @RelatedTo(type = "FINANCIALREPORT_POWERPLANT", elementClass = PowerPlant.class, direction = Direction.OUTGOING)
+ private PowerPlant powerPlant;
+
+ long time;
+
+ double spotMarketRevenue;
+
+ double longTermMarketRevenue;
+
+ double capacityMarketRevenue;
+
+ double strategicReserveRevenue;
+
+ double co2HedgingRevenue;
+
+ double overallRevenue;
+
+ double commodityCosts;
+
+ double co2Costs;
+
+ double variableCosts;
+
+ double fixedCosts;
+
+ double fullLoadHours;
+
+ double production;
+
+ int powerPlantStatus;
+
+ public static final int UNDERCONSTRUCTION = 0;
+ public static final int OPERATIONAL = 1;
+ public static final int DISMANTLED = 2;
+
+ public long getTime() {
+ return time;
+ }
+
+ public void setTime(long time) {
+ this.time = time;
+ }
+
+ public PowerPlant getPowerPlant() {
+ return powerPlant;
+ }
+
+ public void setPowerPlant(PowerPlant powerPlant) {
+ this.powerPlant = powerPlant;
+ }
+
+ public double getSpotMarketRevenue() {
+ return spotMarketRevenue;
+ }
+
+ public void setSpotMarketRevenue(double spotMarketRevenue) {
+ this.spotMarketRevenue = spotMarketRevenue;
+ }
+
+ public double getLongTermMarketRevenue() {
+ return longTermMarketRevenue;
+ }
+
+ public void setLongTermMarketRevenue(double longTermMarketRevenue) {
+ this.longTermMarketRevenue = longTermMarketRevenue;
+ }
+
+ public double getCapacityMarketRevenue() {
+ return capacityMarketRevenue;
+ }
+
+ public void setCapacityMarketRevenue(double capacityMarketRevenue) {
+ this.capacityMarketRevenue = capacityMarketRevenue;
+ }
+
+ public double getStrategicReserveRevenue() {
+ return strategicReserveRevenue;
+ }
+
+ public void setStrategicReserveRevenue(double strategicReserveRevenue) {
+ this.strategicReserveRevenue = strategicReserveRevenue;
+ }
+
+ public double getCo2HedgingRevenue() {
+ return co2HedgingRevenue;
+ }
+
+ public void setCo2HedgingRevenue(double co2HedgingRevenue) {
+ this.co2HedgingRevenue = co2HedgingRevenue;
+ }
+
+ public double getOverallRevenue() {
+ return this.overallRevenue;
+ }
+
+ public void setOverallRevenue(double overallRevenue) {
+ this.overallRevenue = overallRevenue;
+
+ }
+
+ public double getVariableCosts() {
+ return variableCosts;
+ }
+
+ public void setVariableCosts(double variableCosts) {
+ this.variableCosts = variableCosts;
+ }
+
+ public double getFixedCosts() {
+ return fixedCosts;
+ }
+
+ public void setFixedCosts(double fixedCosts) {
+ this.fixedCosts = fixedCosts;
+ }
+
+ public double getFullLoadHours() {
+ return fullLoadHours;
+ }
+
+ public void setFullLoadHours(double fullLoadHours) {
+ this.fullLoadHours = fullLoadHours;
+ }
+
+ public double getProduction() {
+ return production;
+ }
+
+ public void setProduction(double production) {
+ this.production = production;
+ }
+
+ public double getCommodityCosts() {
+ return commodityCosts;
+ }
+
+ public void setCommodityCosts(double commodityCosts) {
+ this.commodityCosts = commodityCosts;
+ }
+
+ public double getCo2Costs() {
+ return co2Costs;
+ }
+
+ public void setCo2Costs(double co2Costs) {
+ this.co2Costs = co2Costs;
+ }
+
+ public int getPowerPlantStatus() {
+ return powerPlantStatus;
+ }
+
+ public void setPowerPlantStatus(int powerPlantStatus) {
+ this.powerPlantStatus = powerPlantStatus;
+ }
+
+}
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/policy/renewablesupport/RenewableSupportSchemeTender.java b/emlab-generation/src/main/java/emlab/gen/domain/policy/renewablesupport/RenewableSupportSchemeTender.java
new file mode 100644
index 00000000..f68759bf
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/domain/policy/renewablesupport/RenewableSupportSchemeTender.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.domain.policy.renewablesupport;
+
+import java.util.Set;
+
+import org.neo4j.graphdb.Direction;
+import org.springframework.data.neo4j.annotation.NodeEntity;
+import org.springframework.data.neo4j.annotation.RelatedTo;
+
+import agentspring.agent.Agent;
+import agentspring.simulation.SimulationParameter;
+import emlab.gen.domain.agent.DecarbonizationAgent;
+import emlab.gen.domain.agent.Regulator;
+import emlab.gen.domain.technology.PowerGeneratingTechnology;
+
+/**
+ * @author Kaveri3012 A generic renewable support scheme role, meant to be able
+ * to model both price based and quantity based schemes.
+ */
+@NodeEntity
+public class RenewableSupportSchemeTender extends DecarbonizationAgent implements Agent {
+
+ @RelatedTo(type = "WITH_REGULATOR", elementClass = Regulator.class, direction = Direction.OUTGOING)
+ private Regulator regulator;
+
+ @RelatedTo(type = "TECHNOLOGIES_ELIGIBLE_ARE", elementClass = PowerGeneratingTechnology.class, direction = Direction.OUTGOING)
+ private Set powerGeneratingTechnologiesEligible;
+
+ private boolean technologySpecificityEnabled;
+
+ private boolean locationSpecificityEnabled;
+
+ @SimulationParameter(label = "Support Scheme Duration", from = 0, to = 50)
+ private long supportSchemeDuration;
+
+ private String name;
+
+ private long futureTenderOperationStartTime;
+
+ private double yearlyTenderDemandTarget;
+
+ public double getYearlyTenderDemandTarget() {
+ return yearlyTenderDemandTarget;
+ }
+
+ public void setYearlyTenderDemandTarget(double yearlyTenderDemandTarget) {
+ this.yearlyTenderDemandTarget = yearlyTenderDemandTarget;
+ }
+
+ public long getFutureTenderOperationStartTime() {
+ return futureTenderOperationStartTime;
+ }
+
+ public void setFutureTenderOperationStartTime(long futureTimePointTender) {
+ this.futureTenderOperationStartTime = futureTimePointTender;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Set getPowerGeneratingTechnologiesEligible() {
+ return powerGeneratingTechnologiesEligible;
+ }
+
+ public void setPowerGeneratingTechnologiesEligible(
+ Set powerGeneratingTechnologiesEligible) {
+ this.powerGeneratingTechnologiesEligible = powerGeneratingTechnologiesEligible;
+ }
+
+ public Regulator getRegulator() {
+ return regulator;
+ }
+
+ public void setRegulator(Regulator regulator) {
+ this.regulator = regulator;
+ }
+
+ public boolean isTechnologySpecificityEnabled() {
+ return technologySpecificityEnabled;
+ }
+
+ public void setTechnologySpecificityEnabled(boolean technologySpecificityEnabled) {
+ this.technologySpecificityEnabled = technologySpecificityEnabled;
+ }
+
+ public boolean isLocationSpecificityEnabled() {
+ return locationSpecificityEnabled;
+ }
+
+ public void setLocationSpecificityEnabled(boolean locationSpecificityEnabled) {
+ this.locationSpecificityEnabled = locationSpecificityEnabled;
+ }
+
+ public long getSupportSchemeDuration() {
+ return supportSchemeDuration;
+ }
+
+ public void setSupportSchemeDuration(long supportSchemeDuration) {
+ this.supportSchemeDuration = supportSchemeDuration;
+ }
+
+ /**
+ * @param scheme
+ */
+ public void act(RenewableSupportSchemeTender scheme) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/policy/renewablesupport/RenewableTargetForTender.java b/emlab-generation/src/main/java/emlab/gen/domain/policy/renewablesupport/RenewableTargetForTender.java
new file mode 100644
index 00000000..e6601d6c
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/domain/policy/renewablesupport/RenewableTargetForTender.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.domain.policy.renewablesupport;
+
+import org.neo4j.graphdb.Direction;
+import org.springframework.data.neo4j.annotation.NodeEntity;
+import org.springframework.data.neo4j.annotation.RelatedTo;
+
+import emlab.gen.domain.agent.Regulator;
+import emlab.gen.domain.technology.PowerGeneratingTechnology;
+import emlab.gen.domain.technology.PowerGridNode;
+import emlab.gen.trend.TimeSeriesCSVReader;
+import emlab.gen.trend.TimeSeriesImpl;
+
+/**
+ * @author Kaveri3012
+ *
+ */
+@NodeEntity
+public class RenewableTargetForTender {
+
+ @RelatedTo(type = "SET_BY_REGULATOR", elementClass = Regulator.class, direction = Direction.INCOMING)
+ Regulator regulator;
+
+ @RelatedTo(type = "FOR_TECHNOLOGY", elementClass = PowerGeneratingTechnology.class, direction = Direction.OUTGOING)
+ PowerGeneratingTechnology powerGeneratingTechnology;
+
+ @RelatedTo(type = "AT_NODE", elementClass = PowerGridNode.class, direction = Direction.OUTGOING)
+ PowerGridNode powerGridNode;
+
+ @RelatedTo(type = "TARGET_TREND", elementClass = TimeSeriesImpl.class, direction = Direction.OUTGOING)
+ TimeSeriesCSVReader yearlyRenewableTargetTimeSeries;
+
+ public Regulator getRegulator() {
+ return regulator;
+ }
+
+ public void setRegulator(Regulator regulator) {
+ this.regulator = regulator;
+ }
+
+ public PowerGeneratingTechnology getPowerGeneratingTechnology() {
+ return powerGeneratingTechnology;
+ }
+
+ public void setPowerGeneratingTechnology(PowerGeneratingTechnology powerGeneratingTechnology) {
+ this.powerGeneratingTechnology = powerGeneratingTechnology;
+ }
+
+ public PowerGridNode getPowerGridNode() {
+ return powerGridNode;
+ }
+
+ public void setPowerGridNode(PowerGridNode powerGridNode) {
+ this.powerGridNode = powerGridNode;
+ }
+
+ public TimeSeriesCSVReader getYearlyRenewableTargetTimeSeries() {
+ return yearlyRenewableTargetTimeSeries;
+ }
+
+ public void setYearlyRenewableTargetTimeSeries(TimeSeriesCSVReader yearlyRenewableTargetTimeSeries) {
+ this.yearlyRenewableTargetTimeSeries = yearlyRenewableTargetTimeSeries;
+ }
+
+}
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/policy/renewablesupport/TenderBid.java b/emlab-generation/src/main/java/emlab/gen/domain/policy/renewablesupport/TenderBid.java
new file mode 100644
index 00000000..ad2cfb35
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/domain/policy/renewablesupport/TenderBid.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.domain.policy.renewablesupport;
+
+import org.neo4j.graphdb.Direction;
+import org.springframework.data.neo4j.annotation.NodeEntity;
+import org.springframework.data.neo4j.annotation.RelatedTo;
+
+import emlab.gen.domain.market.Bid;
+import emlab.gen.domain.technology.PowerGeneratingTechnology;
+import emlab.gen.domain.technology.PowerGridNode;
+import emlab.gen.domain.technology.PowerPlant;
+
+/**
+ * @author Kaveri for tender
+ *
+ */
+@NodeEntity
+public class TenderBid extends Bid {
+
+ @RelatedTo(type = "FOR_NODE", elementClass = PowerGridNode.class, direction = Direction.OUTGOING)
+ private PowerGridNode powerGridNode;
+
+ @RelatedTo(type = "FOR_TECHNOLOGY", elementClass = PowerGeneratingTechnology.class, direction = Direction.OUTGOING)
+ private PowerGeneratingTechnology technology;
+
+ // why connected to powerplant dispatchplan?
+ @RelatedTo(type = "POWERPLANT_DISPATCHPLAN", elementClass = PowerPlant.class, direction = Direction.OUTGOING)
+ private PowerPlant powerPlant;
+
+ @RelatedTo(type = "TENDERBID_SUPPORTSCHEME", elementClass = RenewableSupportSchemeTender.class, direction = Direction.OUTGOING)
+ private RenewableSupportSchemeTender renewableSupportSchemeTender;
+
+ private long start;
+
+ private long finish;
+
+ public long getStart() {
+ return start;
+ }
+
+ public void setStart(long start) {
+ this.start = start;
+ }
+
+ public long getFinish() {
+ return finish;
+ }
+
+ public void setFinish(long finish) {
+ this.finish = finish;
+ }
+
+ public PowerGridNode getPowerGridNode() {
+ return powerGridNode;
+ }
+
+ public void setPowerGridNode(PowerGridNode powerGridNode) {
+ this.powerGridNode = powerGridNode;
+ }
+
+ public PowerPlant getPowerPlant() {
+ return powerPlant;
+ }
+
+ public void setPowerPlant(PowerPlant powerPlant) {
+ this.powerPlant = powerPlant;
+ }
+
+ public PowerGeneratingTechnology getTechnology() {
+ return technology;
+ }
+
+ public void setTechnology(PowerGeneratingTechnology technology) {
+ this.technology = technology;
+ }
+
+}
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/policy/renewablesupport/TenderClearingPoint.java b/emlab-generation/src/main/java/emlab/gen/domain/policy/renewablesupport/TenderClearingPoint.java
new file mode 100644
index 00000000..ec18f7fe
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/domain/policy/renewablesupport/TenderClearingPoint.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.domain.policy.renewablesupport;
+
+import org.springframework.data.neo4j.annotation.NodeEntity;
+
+import emlab.gen.domain.market.ClearingPoint;
+
+/**
+ * @author rjjdejeu adapted from ClearingPoint.java
+ */
+@NodeEntity
+public class TenderClearingPoint extends ClearingPoint {
+
+}
\ No newline at end of file
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/policy/renewablesupport/package-info.java b/emlab-generation/src/main/java/emlab/gen/domain/policy/renewablesupport/package-info.java
new file mode 100644
index 00000000..d9709567
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/domain/policy/renewablesupport/package-info.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+/**
+ * @author Kaveri3012
+ * This package will contain all classes required to define renewable support schemes in EMLAb. They would include price based schemes, quantity based schemes,
+ * tenders, among others.
+ */
+package emlab.gen.domain.policy.renewablesupport;
\ No newline at end of file
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/technology/PowerGeneratingTechnology.java b/emlab-generation/src/main/java/emlab/gen/domain/technology/PowerGeneratingTechnology.java
index 9e2f2516..318a6945 100644
--- a/emlab-generation/src/main/java/emlab/gen/domain/technology/PowerGeneratingTechnology.java
+++ b/emlab-generation/src/main/java/emlab/gen/domain/technology/PowerGeneratingTechnology.java
@@ -33,19 +33,18 @@ public class PowerGeneratingTechnology {
@SimulationParameter(label = "Capacity (MW)", from = 0, to = 2000)
private double capacity;
- @RelatedTo(type = "PGT_INVESTMENTCOSTS", elementClass = TimeSeriesImpl.class, direction = Direction.OUTGOING)
- private TimeSeriesImpl investmentCostTimeSeries;
+ @RelatedTo(type = "PGT_INVESTMENTCOSTS", elementClass = TimeSeriesImpl.class, direction = Direction.OUTGOING)
+ private TimeSeriesImpl investmentCostTimeSeries;
- @RelatedTo(type = "PGT_OMCOSTS", elementClass = TimeSeriesImpl.class, direction = Direction.OUTGOING)
- private TimeSeriesImpl fixedOperatingCostTimeSeries;
+ @RelatedTo(type = "PGT_OMCOSTS", elementClass = TimeSeriesImpl.class, direction = Direction.OUTGOING)
+ private TimeSeriesImpl fixedOperatingCostTimeSeries;
- @RelatedTo(type = "PGT_EFFICIENCYTS", elementClass = TimeSeriesImpl.class, direction = Direction.OUTGOING)
- private TimeSeriesImpl efficiencyTimeSeries;
+ @RelatedTo(type = "PGT_EFFICIENCYTS", elementClass = TimeSeriesImpl.class, direction = Direction.OUTGOING)
+ private TimeSeriesImpl efficiencyTimeSeries;
@SimulationParameter(label = "CO2 capture efficiency", from = 0, to = 1)
private double co2CaptureEffciency;
-
@SimulationParameter(label = "Depreciation time (years)", from = 0, to = 40)
private int depreciationTime;
@@ -54,6 +53,8 @@ public class PowerGeneratingTechnology {
private double fixedOperatingCostModifierAfterLifetime;
+ private double variableOperatingCostinEURPerMWh;
+
@SimulationParameter(label = "Expected lifetime", from = 0, to = 40)
private int expectedLifetime;
@@ -77,6 +78,16 @@ public class PowerGeneratingTechnology {
private boolean intermittent;
+ private double maximumLifeExtension;
+
+ public double getMaximumLifeExtension() {
+ return maximumLifeExtension;
+ }
+
+ public void setMaximumLifeExtension(double maximumLifeExtension) {
+ this.maximumLifeExtension = maximumLifeExtension;
+ }
+
public double getBaseSegmentDependentAvailability() {
return baseSegmentDependentAvailability;
}
@@ -125,6 +136,14 @@ public void setMinimumRunningHours(double minimumRunningHours) {
this.minimumRunningHours = minimumRunningHours;
}
+ public double getVariableOperatingCostinEURPerMWh() {
+ return variableOperatingCostinEURPerMWh;
+ }
+
+ public void setVariableOperatingCostinEURPerMWh(double variableOperatingCostinEURPerMWh) {
+ this.variableOperatingCostinEURPerMWh = variableOperatingCostinEURPerMWh;
+ }
+
@RelatedTo(type = "FUEL", elementClass = Substance.class, direction = Direction.OUTGOING)
private Set fuels;
@@ -161,35 +180,35 @@ public void setCapacity(double capacity) {
this.capacity = capacity;
}
- public double getEfficiency(long time) {
- return efficiencyTimeSeries.getValue(time);
+ public double getEfficiency(long time) {
+ return efficiencyTimeSeries.getValue(time);
}
- public TimeSeriesImpl getInvestmentCostTimeSeries() {
- return investmentCostTimeSeries;
- }
+ public TimeSeriesImpl getInvestmentCostTimeSeries() {
+ return investmentCostTimeSeries;
+ }
- public void setInvestmentCostTimeSeries(TimeSeriesImpl investmentCostTrend) {
- this.investmentCostTimeSeries = investmentCostTrend;
- }
+ public void setInvestmentCostTimeSeries(TimeSeriesImpl investmentCostTrend) {
+ this.investmentCostTimeSeries = investmentCostTrend;
+ }
- public TimeSeriesImpl getFixedOperatingCostTimeSeries() {
- return fixedOperatingCostTimeSeries;
- }
+ public TimeSeriesImpl getFixedOperatingCostTimeSeries() {
+ return fixedOperatingCostTimeSeries;
+ }
- public void setFixedOperatingCostTimeSeries(TimeSeriesImpl fixedOperatingCostTrend) {
- this.fixedOperatingCostTimeSeries = fixedOperatingCostTrend;
- }
+ public void setFixedOperatingCostTimeSeries(TimeSeriesImpl fixedOperatingCostTrend) {
+ this.fixedOperatingCostTimeSeries = fixedOperatingCostTrend;
+ }
- public TimeSeriesImpl getEfficiencyTimeSeries() {
- return efficiencyTimeSeries;
- }
+ public TimeSeriesImpl getEfficiencyTimeSeries() {
+ return efficiencyTimeSeries;
+ }
- public void setEfficiencyTimeSeries(TimeSeriesImpl efficiencyTrend) {
- this.efficiencyTimeSeries = efficiencyTrend;
- }
+ public void setEfficiencyTimeSeries(TimeSeriesImpl efficiencyTrend) {
+ this.efficiencyTimeSeries = efficiencyTrend;
+ }
- public double getCo2CaptureEffciency() {
+ public double getCo2CaptureEffciency() {
return co2CaptureEffciency;
}
@@ -257,15 +276,15 @@ public void setApplicableForLongTermContract(boolean applicableForLongTermContra
this.applicableForLongTermContract = applicableForLongTermContract;
}
- public double getInvestmentCost(long time) {
- return investmentCostTimeSeries.getValue(time);
+ public double getInvestmentCost(long time) {
+ return investmentCostTimeSeries.getValue(time);
}
- public double getFixedOperatingCost(long time) {
- return fixedOperatingCostTimeSeries.getValue(time);
- }
+ public double getFixedOperatingCost(long time) {
+ return fixedOperatingCostTimeSeries.getValue(time);
+ }
- public boolean isIntermittent() {
+ public boolean isIntermittent() {
return intermittent;
}
diff --git a/emlab-generation/src/main/java/emlab/gen/domain/technology/PowerPlant.java b/emlab-generation/src/main/java/emlab/gen/domain/technology/PowerPlant.java
index 36f61ea0..0d72ffdb 100644
--- a/emlab-generation/src/main/java/emlab/gen/domain/technology/PowerPlant.java
+++ b/emlab-generation/src/main/java/emlab/gen/domain/technology/PowerPlant.java
@@ -87,11 +87,42 @@ public class PowerPlant {
private double actualEfficiency;
private double expectedEndOfLife;
private double actualNominalCapacity;
+ private boolean hasFeedInPremiumContract;
+
+ public double ageFraction;
+ public double profitability;
+
+ private long finishedConstruction;
+
+ public long getFinishedConstruction() {
+ return finishedConstruction;
+ }
+
+ public void setFinishedConstruction(long finishedConstruction) {
+ this.finishedConstruction = getConstructionStartTime() + calculateActualPermittime()
+ + calculateActualLeadtime();
+ }
+
+ public double getProfitability() {
+ return profitability;
+ }
+
+ public void setProfitability(double profitability) {
+ this.profitability = profitability;
+ }
+
+ public double getAgeFraction() {
+ return ageFraction;
+ }
+
+ public void setAgeFraction(double ageFraction) {
+ this.ageFraction = ageFraction;
+ }
public boolean isOperational(long currentTick) {
- double finishedConstruction = getConstructionStartTime()
- + calculateActualPermittime() + calculateActualLeadtime();
+ double finishedConstruction = getConstructionStartTime() + calculateActualPermittime()
+ + calculateActualLeadtime();
if (finishedConstruction <= currentTick) {
// finished construction
@@ -111,10 +142,15 @@ public boolean isOperational(long currentTick) {
return false;
}
- public boolean isExpectedToBeOperational(long time) {
+ public boolean isHasFeedInPremiumContract() {
+ return hasFeedInPremiumContract;
+ }
- double finishedConstruction = getConstructionStartTime()
- + calculateActualPermittime() + calculateActualLeadtime();
+ public void setHasFeedInPremiumContract(boolean hasFeedInPremiumContract) {
+ this.hasFeedInPremiumContract = hasFeedInPremiumContract;
+ }
+
+ public boolean isExpectedToBeOperational(long time) {
if (finishedConstruction <= time) {
// finished construction
@@ -130,8 +166,8 @@ public boolean isExpectedToBeOperational(long time) {
public boolean isInPipeline(long currentTick) {
- double finishedConstruction = getConstructionStartTime()
- + calculateActualPermittime() + calculateActualLeadtime();
+ double finishedConstruction = getConstructionStartTime() + calculateActualPermittime()
+ + calculateActualLeadtime();
if (finishedConstruction > currentTick) {
// finished construction
@@ -151,8 +187,7 @@ public boolean isInPipeline(long currentTick) {
return false;
}
- public double getAvailableCapacity(long currentTick, Segment segment,
- long numberOfSegments) {
+ public double getAvailableCapacity(long currentTick, Segment segment, long numberOfSegments) {
if (isOperational(currentTick)) {
if (this.getTechnology().isIntermittent()) {
IntermittentTechnologyNodeLoadFactor intermittentTechnologyNodeLoadFactor = getIntermittentTechnologyNodeLoadFactor();
@@ -160,17 +195,15 @@ public double getAvailableCapacity(long currentTick, Segment segment,
return getActualNominalCapacity() * factor;
} else {
double factor = 1;
- if (segment != null) {// if no segment supplied, assume we want full
+ if (segment != null) {// if no segment supplied, assume we want
+ // full
// capacity
double segmentID = segment.getSegmentID();
if ((int) segmentID != 1) {
- double min = getTechnology()
- .getPeakSegmentDependentAvailability();
- double max = getTechnology()
- .getBaseSegmentDependentAvailability();
- double segmentPortion = (numberOfSegments - segmentID)
- / (numberOfSegments - 1); // start
+ double min = getTechnology().getPeakSegmentDependentAvailability();
+ double max = getTechnology().getBaseSegmentDependentAvailability();
+ double segmentPortion = (numberOfSegments - segmentID) / (numberOfSegments - 1); // start
// counting
// at
// 1.
@@ -180,8 +213,7 @@ public double getAvailableCapacity(long currentTick, Segment segment,
factor = max - segmentPortion * range;
int i = 0;
} else {
- factor = getTechnology()
- .getPeakSegmentDependentAvailability();
+ factor = getTechnology().getPeakSegmentDependentAvailability();
}
}
return getActualNominalCapacity() * factor;
@@ -191,23 +223,20 @@ public double getAvailableCapacity(long currentTick, Segment segment,
}
}
- public double getExpectedAvailableCapacity(long futureTick,
- Segment segment, long numberOfSegments) {
+ public double getExpectedAvailableCapacity(long futureTick, Segment segment, long numberOfSegments) {
if (isExpectedToBeOperational(futureTick)) {
if (this.getTechnology().isIntermittent()) {
double factor = getIntermittentTechnologyNodeLoadFactor().getLoadFactorForSegment(segment);
return getActualNominalCapacity() * factor;
} else {
double factor = 1;
- if (segment != null) {// if no segment supplied, assume we want full
+ if (segment != null) {// if no segment supplied, assume we want
+ // full
// capacity
double segmentID = segment.getSegmentID();
- double min = getTechnology()
- .getPeakSegmentDependentAvailability();
- double max = getTechnology()
- .getBaseSegmentDependentAvailability();
- double segmentPortion = (numberOfSegments - segmentID)
- / (numberOfSegments - 1); // start
+ double min = getTechnology().getPeakSegmentDependentAvailability();
+ double max = getTechnology().getBaseSegmentDependentAvailability();
+ double segmentPortion = (numberOfSegments - segmentID) / (numberOfSegments - 1); // start
// counting
// at
// 1.
@@ -218,6 +247,7 @@ public double getExpectedAvailableCapacity(long futureTick,
}
return getActualNominalCapacity() * factor;
}
+
} else {
return 0;
}
@@ -233,7 +263,7 @@ public double getAvailableCapacity(long currentTick) {
public long calculateActualLeadtime() {
long actual;
- actual = getActualLeadtime();
+ actual = getActualLeadTime();
if (actual <= 0) {
actual = getTechnology().getExpectedLeadtime();
}
@@ -267,9 +297,8 @@ public long calculateActualLifetime() {
* @return whether the plant is still in its technical lifetime.
*/
public boolean isWithinTechnicalLifetime(long currentTick) {
- long endOfTechnicalLifetime = getConstructionStartTime()
- + calculateActualPermittime() + calculateActualLeadtime()
- + calculateActualLifetime();
+ long endOfTechnicalLifetime = getConstructionStartTime() + calculateActualPermittime()
+ + calculateActualLeadtime() + calculateActualLifetime();
if (endOfTechnicalLifetime <= currentTick) {
return false;
}
@@ -328,7 +357,7 @@ public void setActualLeadtime(long actualLeadtime) {
this.actualLeadtime = actualLeadtime;
}
- public long getActualLeadtime() {
+ public long getActualLeadTime() {
return actualLeadtime;
}
@@ -409,22 +438,21 @@ public String toString() {
*
* @param timeOfPermitorBuildingStart
*/
- public void calculateAndSetActualInvestedCapital(
- long timeOfPermitorBuildingStart) {
- setActualInvestedCapital(this.getTechnology().getInvestmentCost(
- timeOfPermitorBuildingStart + getActualLeadtime() + getActualPermittime())
+ public void calculateAndSetActualInvestedCapital(long timeOfPermitorBuildingStart) {
+ setActualInvestedCapital(this.getTechnology()
+ .getInvestmentCost(timeOfPermitorBuildingStart + getActualLeadTime() + getActualPermittime())
* getActualNominalCapacity());
}
public void calculateAndSetActualFixedOperatingCosts(long timeOfPermitorBuildingStart) {
- setActualFixedOperatingCost(this.getTechnology().getFixedOperatingCost(
- timeOfPermitorBuildingStart + getActualLeadtime() + getActualPermittime())
+ setActualFixedOperatingCost(this.getTechnology()
+ .getFixedOperatingCost(timeOfPermitorBuildingStart + getActualLeadTime() + getActualPermittime())
* getActualNominalCapacity());
}
public void calculateAndSetActualEfficiency(long timeOfPermitorBuildingStart) {
- this.setActualEfficiency(this.getTechnology().getEfficiency(
- timeOfPermitorBuildingStart + getActualLeadtime() + getActualPermittime()));
+ this.setActualEfficiency(this.getTechnology()
+ .getEfficiency(timeOfPermitorBuildingStart + getActualLeadTime() + getActualPermittime()));
}
public double calculateEmissionIntensity() {
@@ -433,8 +461,7 @@ public double calculateEmissionIntensity() {
for (SubstanceShareInFuelMix sub : this.getFuelMix()) {
Substance substance = sub.getSubstance();
double fuelAmount = sub.getShare();
- double co2density = substance.getCo2Density()
- * (1 - this.getTechnology().getCo2CaptureEffciency());
+ double co2density = substance.getCo2Density() * (1 - this.getTechnology().getCo2CaptureEffciency());
// determine the total cost per MWh production of this plant
double emissionForThisFuel = fuelAmount * co2density;
@@ -450,15 +477,13 @@ public double calculateElectricityOutputAtTime(long time, boolean forecast) {
for (PowerPlantDispatchPlan plan : powerPlantDispatchPlanRepository
.findAllPowerPlantDispatchPlansForPowerPlantForTime(this, time, forecast)) {
amount += plan.getSegment().getLengthInHours()
- * (plan.getCapacityLongTermContract() + plan
- .getAcceptedAmount());
+ * (plan.getCapacityLongTermContract() + plan.getAcceptedAmount());
}
return amount;
}
public double calculateCO2EmissionsAtTime(long time, boolean forecast) {
- return this.calculateEmissionIntensity()
- * calculateElectricityOutputAtTime(time, forecast);
+ return this.calculateEmissionIntensity() * calculateElectricityOutputAtTime(time, forecast);
}
@Transactional
@@ -481,14 +506,14 @@ public void dismantlePowerPlant(long time) {
* @author J.C.Richstein
*/
@Transactional
- public void specifyAndPersist(long time, EnergyProducer energyProducer,
- PowerGridNode location, PowerGeneratingTechnology technology) {
+ public void specifyAndPersist(long time, EnergyProducer energyProducer, PowerGridNode location,
+ PowerGeneratingTechnology technology) {
specifyNotPersist(time, energyProducer, location, technology);
this.persist();
}
- public void specifyNotPersist(long time, EnergyProducer energyProducer,
- PowerGridNode location, PowerGeneratingTechnology technology) {
+ public void specifyNotPersist(long time, EnergyProducer energyProducer, PowerGridNode location,
+ PowerGeneratingTechnology technology) {
String label = energyProducer.getName() + " - " + technology.getName();
this.setName(label);
this.setTechnology(technology);
@@ -503,8 +528,8 @@ public void specifyNotPersist(long time, EnergyProducer energyProducer,
this.setDismantleTime(1000);
this.calculateAndSetActualInvestedCapital(time);
this.calculateAndSetActualFixedOperatingCosts(time);
- this.setExpectedEndOfLife(time + getActualPermittime()
- + getActualLeadtime() + getTechnology().getExpectedLifetime());
+ this.setExpectedEndOfLife(
+ time + getActualPermittime() + getActualLeadTime() + getTechnology().getExpectedLifetime());
}
@Transactional
@@ -562,10 +587,9 @@ public void setActualFixedOperatingCost(double actualFixedOperatingCost) {
this.actualFixedOperatingCost = actualFixedOperatingCost;
}
- IntermittentTechnologyNodeLoadFactor getIntermittentTechnologyNodeLoadFactor(){
+ public IntermittentTechnologyNodeLoadFactor getIntermittentTechnologyNodeLoadFactor() {
return intermittentTechnologyNodeLoadFactorRepository
- .findIntermittentTechnologyNodeLoadFactorForNodeAndTechnology(this.getLocation(),
- this.getTechnology());
+ .findIntermittentTechnologyNodeLoadFactorForNodeAndTechnology(this.getLocation(), this.getTechnology());
}
}
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/BidRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/BidRepository.java
index 884c616f..95c2a403 100644
--- a/emlab-generation/src/main/java/emlab/gen/repository/BidRepository.java
+++ b/emlab-generation/src/main/java/emlab/gen/repository/BidRepository.java
@@ -34,113 +34,122 @@
@Repository
public interface BidRepository extends GraphRepository {
- /**
- * Finds all demand bids for a market for a time
- *
- * @param market
- * @param time
- * @return the found bids
- */
- // @Query(value =
- // "g.v(market).in('BIDDINGMARKET').filter{it.time == time}.filter{it.supplyBid == false}",
- // type = QueryType.Gremlin)
- // public Iterable findDemandBidsForMarketForTime(@Param("market")
- // DecarbonizationMarket market, @Param("time") long time);
-
- @Query("START bid=node:__types__(\"className:emlab.gen.domain.market.Bid\") WHERE (bid.time={time}) RETURN bid")
- Iterable findAllBidsForForTime(@Param("time") long time);
-
- @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=false) RETURN bid ORDER BY bid.price desc")
- Iterable findDemandBidsForMarketForTime(@Param("market") DecarbonizationMarket market, @Param("time") long time);
-
- @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=false) and (bid.status>=2) RETURN bid")
- Iterable findAllAcceptedDemandBidsForMarketForTime(@Param("market") DecarbonizationMarket market,
- @Param("time") long time);
-
- /**
- * Finds all supply bids for a market for a time. Cypher adapted from PGC
- * (Alfredas)
- *
- * @param market
- * @param time
- * @return
- */
- // @Query(value =
- // "g.v(market).in('BIDDINGMARKET').filter{it.time == time}.filter{it.supplyBid == true}",
- // type = QueryType.Gremlin)
- // public Iterable findOffersForMarketForTime(@Param("market")
- // DecarbonizationMarket market, @Param("time") long time);
-
- @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=true) RETURN bid ORDER BY bid.price")
- Iterable findOffersForMarketForTime(@Param("market") DecarbonizationMarket market, @Param("time") long time);
-
- @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=true) and (bid.status>=2) RETURN bid")
- Iterable findAllAcceptedOffersForMarketForTime(@Param("market") DecarbonizationMarket market,
- @Param("time") long time);
-
- /**
- * Find bids for a market for a time
- *
- * @param market
- * @param time
- * @param isSupply
- * supply or demand bids
- * @return the bids
- */
-
- @Query(value = "g.v(market).in('BIDDINGMARKET').filter{it.time == time}.filter{it.supplyBid == isSupply}", type = QueryType.Gremlin)
- Iterable getBidsForMarketForTime(@Param("market") DecarbonizationMarket market, @Param("time") long time,
- @Param("isSupply") boolean isSupply);
-
- @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=true) and (bid.price <= {price}) RETURN bid ORDER BY bid.price")
- Iterable findOffersForMarketForTimeBelowPrice(@Param("market") DecarbonizationMarket market,
- @Param("time") long time, @Param("price") double price);
-
- /**
- * Find demand bids above a certain price, and return them in descending
- * order.
- *
- * @param market
- * @param time
- * @param price
- * @return
- */
- @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=false) and (bid.price >= {price}) RETURN bid ORDER BY bid.price desc")
- Iterable findDemandBidsForMarketForTimeAbovePrice(@Param("market") DecarbonizationMarket market,
- @Param("time") long time, @Param("price") double price);
-
- @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=false) and (bid.price >= {price}) RETURN sum(bid.amount)")
- double calculateDemandBidsForMarketForTimeForPrice(@Param("market") DecarbonizationMarket market,
- @Param("time") long time, @Param("price") double price);
-
- @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=false) and (bid.price = {price}) RETURN bid ORDER BY bid.price desc")
- Iterable findDemandBidsForMarketForTimeForPrice(@Param("market") DecarbonizationMarket market,
- @Param("time") long time, @Param("price") double price);
-
- @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=true) and (bid.price = {price}) RETURN bid ORDER BY bid.price desc")
- Iterable findOffersForMarketForTimeForPrice(@Param("market") DecarbonizationMarket market,
- @Param("time") long time, @Param("price") double price);
-
- @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=true) and (bid.price = {price}) RETURN sum(bid.amount)")
- double calculateOffersForMarketForTimeForPrice(@Param("market") DecarbonizationMarket market,
- @Param("time") long time, @Param("price") double price);
-
- @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=false) RETURN sum(bid.amount)")
- double calculateTotalDemandForMarketForTime(@Param("market") DecarbonizationMarket market, @Param("time") long time);
-
- @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=false) and (bid.price >= {price}) RETURN sum(bid.amount)")
- double calculateTotalDemandForMarketForTimeForPrice(@Param("market") DecarbonizationMarket market,
- @Param("time") long time, @Param("price") double price);
-
- @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=true) RETURN sum(bid.amount)")
- double calculateTotalSupplyForMarketForTime(@Param("market") DecarbonizationMarket market, @Param("time") long time);
-
- @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=true) RETURN max(bid.price)")
- double calculateTotalSupplyPriceForMarketForTime(@Param("market") DecarbonizationMarket market,
- @Param("time") long time);
-
- @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=true) RETURN min(bid.price)")
- double calculateMinimumSupplyPriceForMarketForTime(@Param("market") DecarbonizationMarket market,
- @Param("time") long time);
+ /**
+ * Finds all demand bids for a market for a time
+ *
+ * @param market
+ * +Kaveri Search Images Maps Play YouTube News Gmail Drive
+ * Calendar More
+ *
+ * Gmail
+ *
+ * Kaveri Iychettira Share Kaveri Iychettira Kaveri Iychettira
+ *
+ *
+ *
+ * @param time
+ * @return the found bids
+ */
+ // @Query(value =
+ // "g.v(market).in('BIDDINGMARKET').filter{it.time == time}.filter{it.supplyBid == false}",
+ // type = QueryType.Gremlin)
+ // public Iterable findDemandBidsForMarketForTime(@Param("market")
+ // DecarbonizationMarket market, @Param("time") long time);
+
+ @Query("START bid=node:__types__(\"className:emlab.gen.domain.market.Bid\") WHERE (bid.time={time}) RETURN bid")
+ Iterable findAllBidsForForTime(@Param("time") long time);
+
+ @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=false) RETURN bid ORDER BY bid.price desc")
+ Iterable findDemandBidsForMarketForTime(@Param("market") DecarbonizationMarket market, @Param("time") long time);
+
+ @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=false) and (bid.status>=2) RETURN bid")
+ Iterable findAllAcceptedDemandBidsForMarketForTime(@Param("market") DecarbonizationMarket market,
+ @Param("time") long time);
+
+ /**
+ * Finds all supply bids for a market for a time. Cypher adapted from PGC
+ * (Alfredas)
+ *
+ * @param market
+ * @param time
+ * @return
+ */
+ // @Query(value =
+ // "g.v(market).in('BIDDINGMARKET').filter{it.time == time}.filter{it.supplyBid == true}",
+ // type = QueryType.Gremlin)
+ // public Iterable findOffersForMarketForTime(@Param("market")
+ // DecarbonizationMarket market, @Param("time") long time);
+
+ @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=true) RETURN bid ORDER BY bid.price")
+ Iterable findOffersForMarketForTime(@Param("market") DecarbonizationMarket market, @Param("time") long time);
+
+ @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=true) and (bid.status>=2) RETURN bid")
+ Iterable findAllAcceptedOffersForMarketForTime(@Param("market") DecarbonizationMarket market,
+ @Param("time") long time);
+
+ /**
+ * Find bids for a market for a time
+ *
+ * @param market
+ * @param time
+ * @param isSupply
+ * supply or demand bids
+ * @return the bids
+ */
+
+ @Query(value = "g.v(market).in('BIDDINGMARKET').filter{it.time == time}.filter{it.supplyBid == isSupply}", type = QueryType.Gremlin)
+ Iterable getBidsForMarketForTime(@Param("market") DecarbonizationMarket market, @Param("time") long time,
+ @Param("isSupply") boolean isSupply);
+
+ @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=true) and (bid.price <= {price}) RETURN bid ORDER BY bid.price")
+ Iterable findOffersForMarketForTimeBelowPrice(@Param("market") DecarbonizationMarket market,
+ @Param("time") long time, @Param("price") double price);
+
+ /**
+ * Find demand bids above a certain price, and return them in descending
+ * order.
+ *
+ * @param market
+ * @param time
+ * @param price
+ * @return
+ */
+ @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=false) and (bid.price >= {price}) RETURN bid ORDER BY bid.price desc")
+ Iterable findDemandBidsForMarketForTimeAbovePrice(@Param("market") DecarbonizationMarket market,
+ @Param("time") long time, @Param("price") double price);
+
+ @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=false) and (bid.price >= {price}) RETURN sum(bid.amount)")
+ double calculateDemandBidsForMarketForTimeForPrice(@Param("market") DecarbonizationMarket market,
+ @Param("time") long time, @Param("price") double price);
+
+ @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=false) and (bid.price = {price}) RETURN bid ORDER BY bid.price desc")
+ Iterable findDemandBidsForMarketForTimeForPrice(@Param("market") DecarbonizationMarket market,
+ @Param("time") long time, @Param("price") double price);
+
+ @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=true) and (bid.price = {price}) RETURN bid ORDER BY bid.price desc")
+ Iterable findOffersForMarketForTimeForPrice(@Param("market") DecarbonizationMarket market,
+ @Param("time") long time, @Param("price") double price);
+
+ @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=true) and (bid.price = {price}) RETURN sum(bid.amount)")
+ double calculateOffersForMarketForTimeForPrice(@Param("market") DecarbonizationMarket market,
+ @Param("time") long time, @Param("price") double price);
+
+ @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=false) RETURN sum(bid.amount)")
+ double calculateTotalDemandForMarketForTime(@Param("market") DecarbonizationMarket market, @Param("time") long time);
+
+ @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=false) and (bid.price >= {price}) RETURN sum(bid.amount)")
+ double calculateTotalDemandForMarketForTimeForPrice(@Param("market") DecarbonizationMarket market,
+ @Param("time") long time, @Param("price") double price);
+
+ @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=true) RETURN sum(bid.amount)")
+ double calculateTotalSupplyForMarketForTime(@Param("market") DecarbonizationMarket market, @Param("time") long time);
+
+ @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=true) RETURN max(bid.price)")
+ double calculateTotalSupplyPriceForMarketForTime(@Param("market") DecarbonizationMarket market,
+ @Param("time") long time);
+
+ @Query("START market=node({market}) MATCH (market)<-[:BIDDINGMARKET]-(bid) WHERE (bid.time = {time}) and (bid.supplyBid=true) RETURN min(bid.price)")
+ double calculateMinimumSupplyPriceForMarketForTime(@Param("market") DecarbonizationMarket market,
+ @Param("time") long time);
}
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/CapacityClearingPointRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/CapacityClearingPointRepository.java
new file mode 100644
index 00000000..e3707ea2
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/repository/CapacityClearingPointRepository.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.repository;
+
+import org.springframework.data.neo4j.repository.GraphRepository;
+import org.springframework.stereotype.Repository;
+
+import emlab.gen.domain.market.capacity.CapacityClearingPoint;
+
+/**
+ * @author Kaveri
+ *
+ */
+@Repository
+public interface CapacityClearingPointRepository extends GraphRepository {
+
+}
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/CapacityDispatchPlanRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/CapacityDispatchPlanRepository.java
new file mode 100644
index 00000000..97e9712d
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/repository/CapacityDispatchPlanRepository.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ /*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.repository;
+
+import org.springframework.data.neo4j.repository.GraphRepository;
+import org.springframework.stereotype.Repository;
+
+import emlab.gen.domain.market.capacity.CapacityDispatchPlan;
+
+/**
+ * @author Kaveri
+ *
+ */
+@Repository
+public interface CapacityDispatchPlanRepository extends GraphRepository {
+
+}
\ No newline at end of file
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/CapacityMarketRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/CapacityMarketRepository.java
new file mode 100644
index 00000000..d5340b7f
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/repository/CapacityMarketRepository.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ /*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.repository;
+
+import org.springframework.data.neo4j.annotation.Query;
+import org.springframework.data.neo4j.annotation.QueryType;
+import org.springframework.data.neo4j.repository.GraphRepository;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import emlab.gen.domain.agent.Regulator;
+import emlab.gen.domain.gis.Zone;
+import emlab.gen.domain.market.ClearingPoint;
+import emlab.gen.domain.market.capacity.CapacityClearingPoint;
+import emlab.gen.domain.market.capacity.CapacityDispatchPlan;
+import emlab.gen.domain.market.capacity.CapacityMarket;
+
+/**
+ * @author Kaveri
+ *
+ */
+@Repository
+public interface CapacityMarketRepository extends GraphRepository {
+
+ @Query(value = "g.v(zone).in('ZONE').filter{it.__type__=='emlab.gen.domain.market.capacity.CapacityMarket'}", type = QueryType.Gremlin)
+ public CapacityMarket findCapacityMarketForZone(@Param("zone") Zone zone);
+
+ @Query(value = "g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityDispatchPlan']].filter{it.time == tick}.sort{it.price}._()", type = QueryType.Gremlin)
+ public Iterable findAllSortedCapacityDispatchPlansByTime(@Param("tick") long time);
+
+ @Query(value = "g.v(market).in('BIDDINGMARKET').propertyFilter('time', FilterPipe.Filter.EQUAL, time).propertyFilter('status', FilterPipe.Filter.GREATER_THAN, 2)", type = QueryType.Gremlin)
+ public Iterable findAllAcceptedCapacityDispatchPlansForTime(
+ @Param("market") CapacityMarket capacityMarket, @Param("time") long time);
+
+ @Query(value = "g.v(market).in('CAPACITY_MARKET').propertyFilter('time', FilterPipe.Filter.EQUAL, time)", type = QueryType.Gremlin)
+ public CapacityClearingPoint findOneCapacityClearingPointForTimeAndMarket(@Param("time") long time,
+ @Param("market") CapacityMarket capacityMarket);
+
+ @Query(value = "g.v(market).in('CAPACITY_MARKET').propertyFilter('time', FilterPipe.Filter.EQUAL, time)", type = QueryType.Gremlin)
+ public ClearingPoint findOneClearingPointForTimeAndCapacityMarket(@Param("time") long time,
+ @Param("market") CapacityMarket capacityMarket);
+
+ @Query(value = "g.idx('__types__')[[className:'emlab.gen.domain.market.capacity.CapacityClearingPoint']].filter{it.time == tick}", type = QueryType.Gremlin)
+ public CapacityClearingPoint findOneCapacityClearingPointForTime(@Param("time") long time);
+
+ @Query(value = "g.v(zone).in('OF_ZONE')", type = QueryType.Gremlin)
+ public Regulator findRegulatorForZone(@Param("zone") Zone zone);
+
+}
\ No newline at end of file
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/CashFlowRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/CashFlowRepository.java
index e174eb51..ce600654 100644
--- a/emlab-generation/src/main/java/emlab/gen/repository/CashFlowRepository.java
+++ b/emlab-generation/src/main/java/emlab/gen/repository/CashFlowRepository.java
@@ -16,13 +16,18 @@
package emlab.gen.repository;
import org.springframework.data.neo4j.annotation.Query;
+import org.springframework.data.neo4j.annotation.QueryType;
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.repository.query.Param;
import emlab.gen.domain.contract.CashFlow;
+import emlab.gen.domain.technology.PowerPlant;
public interface CashFlowRepository extends GraphRepository {
@Query("START cf=node:__types__(\"className:emlab.gen.domain.contract.CashFlow\") WHERE (cf.time={time}) RETURN cf")
Iterable findAllCashFlowsForForTime(@Param("time") long time);
+ @Query(value = "g.v(plant).in.filter{it.__type__=='emlab.gen.domain.contract.CashFlow' && it.time==tick}", type = QueryType.Gremlin)
+ Iterable findAllCashFlowsForPowerPlantForTime(@Param("plant") PowerPlant plant, @Param("tick") long tick);
+
}
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/FinancialPowerPlantReportRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/FinancialPowerPlantReportRepository.java
new file mode 100644
index 00000000..1ee3fbf2
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/repository/FinancialPowerPlantReportRepository.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.repository;
+
+import org.springframework.data.neo4j.annotation.Query;
+import org.springframework.data.neo4j.annotation.QueryType;
+import org.springframework.data.neo4j.repository.GraphRepository;
+import org.springframework.data.repository.query.Param;
+
+import emlab.gen.domain.agent.EnergyProducer;
+import emlab.gen.domain.market.electricity.FinancialPowerPlantReport;
+import emlab.gen.domain.technology.PowerGeneratingTechnology;
+
+/**
+ * @author jrichstein
+ *
+ */
+public interface FinancialPowerPlantReportRepository extends
+GraphRepository {
+
+ @Query(value = "techName=g.v(tech).name;"
+ + "fr = g.v(producer).in('POWERPLANT_OWNER').as('x').out('TECHNOLOGY').propertyFilter('name',FilterPipe.Filter.EQUAL, techName).back('x').in('FINANCIALREPORT_POWERPLANT').propertyFilter('time', FilterPipe.Filter.GREATER_THAN_EQUAL, from).propertyFilter('time', FilterPipe.Filter.LESS_THAN_EQUAL, to).propertyFilter('powerPlantStatus', FilterPipe.Filter.EQUAL, 1);", type = QueryType.Gremlin)
+ public Iterable findAllFinancialPowerPlantReportsOfOperationaPlantsFromToForEnergyProducerAndTechnology(
+ @Param("from") long from,
+ @Param("to") long to, @Param("producer") EnergyProducer producer,
+ @Param("tech") PowerGeneratingTechnology tech);
+
+ @Query(value = "techName=g.v(tech).name; fr = g.v(producer).in('POWERPLANT_OWNER').as('x').out('TECHNOLOGY').propertyFilter('name',FilterPipe.Filter.EQUAL, techName).back('x').in('FINANCIALREPORT_POWERPLANT').propertyFilter('time', FilterPipe.Filter.GREATER_THAN_EQUAL, from).propertyFilter('time', FilterPipe.Filter.LESS_THAN_EQUAL, to).propertyFilter('powerPlantStatus', FilterPipe.Filter.EQUAL, 1);"
+ + "if(!fr.hasNext()){return null} else{fr=fr.sort{it.overallRevenue-it.variableCosts}._().toList()};"
+ +
+ "length=fr.size(); fiveQuantile=(int)length*0.05;cvar=(long) 0;"+
+ "for(int i=0; i<=fiveQuantile; i++){cvar=cvar+(fr[i].overallRevenue-fr[i].variableCosts)/fr[i].out('FINANCIALREPORT_POWERPLANT').actualNominalCapacity.next()};"
+ +
+ "cvar=cvar/((double)(fiveQuantile+1));"+
+ "return cvar;", type = QueryType.Gremlin)
+ public Double calculateHistoricalCVarRelativePerMWForOperationaPlantsForEnergyProducerAndTechnologyForYearsFromToAndAlphaValue(
+ @Param("from") long from, @Param("to") long to, @Param("producer") EnergyProducer producer,
+ @Param("tech") PowerGeneratingTechnology tech, @Param("alpha") double alpha);
+
+ @Query("START fr=node:__types__(\"className:emlab.gen.domain.market.electricity.FinancialPowerPlantReport\") WHERE (fr.time={time}) RETURN fr")
+ public Iterable findAllFinancialPowerPlantReportsForTime(@Param("time") long time);
+
+}
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/InterconnectorRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/InterconnectorRepository.java
index afaac21a..e45f1beb 100644
--- a/emlab-generation/src/main/java/emlab/gen/repository/InterconnectorRepository.java
+++ b/emlab-generation/src/main/java/emlab/gen/repository/InterconnectorRepository.java
@@ -18,17 +18,24 @@
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.annotation.QueryType;
import org.springframework.data.neo4j.repository.GraphRepository;
-import org.springframework.data.repository.query.Param;
-
import emlab.gen.domain.technology.Interconnector;
public interface InterconnectorRepository extends GraphRepository {
-// @Query(value = "g.v(plant).out('LOCATION').out('REGION').in('GOVERNED_ZONE').next()", type = QueryType.Gremlin)
-// NationalGovernment findNationalGovernmentByPowerPlant(@Param("plant") PowerPlant plant);
+ // @Query(value =
+ // "g.v(plant).out('LOCATION').out('REGION').in('GOVERNED_ZONE').next()",
+ // type = QueryType.Gremlin)
+ // NationalGovernment findNationalGovernmentByPowerPlant(@Param("plant")
+ // PowerPlant plant);
+
+ // @Query(value = "g.v(market).out('ZONE').in('GOVERNED_ZONE').next()", type
+ // = QueryType.Gremlin)
+ // NationalGovernment
+ // findNationalGovernmentByElectricitySpotMarket(@Param("market")
+ // ElectricitySpotMarket market);
-// @Query(value = "g.v(market).out('ZONE').in('GOVERNED_ZONE').next()", type = QueryType.Gremlin)
-// NationalGovernment findNationalGovernmentByElectricitySpotMarket(@Param("market") ElectricitySpotMarket market);
+ @Query(value = "g.idx('__types__')[[className:'emlab.gen.domain.technology.Interconnector']].capacity", type = QueryType.Gremlin)
+ public double findInterconnectorCapacity();
}
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/MarketRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/MarketRepository.java
index 1297a40c..c231c0ed 100644
--- a/emlab-generation/src/main/java/emlab/gen/repository/MarketRepository.java
+++ b/emlab-generation/src/main/java/emlab/gen/repository/MarketRepository.java
@@ -76,14 +76,22 @@ public interface MarketRepository extends GraphRepository
public ElectricitySpotMarket findElectricitySpotMarketForZone(@Param("zone") Zone zone);
@Query(value = "START nationalG = node({nationalG}), electricityMarket = node:__types__(\"className:emlab.gen.domain.market.electricity.ElectricitySpotMarket\") MATCH (nationalG)-[:GOVERNED_ZONE]->(zone)<-[:ZONE]-(electricityMarket) RETURN electricityMarket")
- public ElectricitySpotMarket findElectricitySpotMarketByNationalGovernment(@Param("nationalG") NationalGovernment nationalG);
+ public ElectricitySpotMarket findElectricitySpotMarketByNationalGovernment(
+ @Param("nationalG") NationalGovernment nationalG);
@Query(value = "g.v(plant).out('LOCATION').out('REGION').in('ZONE').filter{it.__type__=='emlab.gen.domain.market.electricity.ElectricitySpotMarket'}.next()", type = QueryType.Gremlin)
public ElectricitySpotMarket findElectricitySpotMarketByPowerPlant(@Param("plant") PowerPlant plant);
@Query(value = "segID = g.v(segment).segmentID;"
+ "return g.v(zone).in('ZONE').filter{it.__type__=='emlab.gen.domain.market.electricity.ElectricitySpotMarket'}.out('SEGMENT_LOAD').as('SL').out('SEGMENTLOAD_SEGMENT').filter{it.segmentID==segID}.back('SL').next();", type = QueryType.Gremlin)
- public SegmentLoad findSegmentLoadForElectricitySpotMarketForZone(@Param("zone") Zone zone, @Param("segment") Segment segment);
+ public SegmentLoad findSegmentLoadForElectricitySpotMarketForZone(@Param("zone") Zone zone,
+ @Param("segment") Segment segment);
+
+ @Query(value = "g.v(zone).in('REGION').in('LOCATION').filter{f.plantIsOperational(it, tick)}.out('TECHNOLOGY').sum{it.capacity*(it.peakSegmentDependentAvailability)}._()", type = QueryType.Gremlin)
+ public double findTotalSupplyInElectricitySpotMarketForZone(@Param("zone") Zone zone);
+
+ @Query(value = "topsegments = g.v(zone).out('SEGMENT_LOAD').max{it.baseLoad}.baseLoad; growthfactors = v.out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0]; adjustedTopSegments = topsegments*growthfactors; return adjustedTopSegments", type = QueryType.Gremlin)
+ public double findPeakDemandInElectricitySpotMarketForZone(@Param("zone") Zone zone);
/**
* Gives the market for a specific substance
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/PowerPlantDispatchPlanRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/PowerPlantDispatchPlanRepository.java
index 0294daf0..de2b60be 100644
--- a/emlab-generation/src/main/java/emlab/gen/repository/PowerPlantDispatchPlanRepository.java
+++ b/emlab-generation/src/main/java/emlab/gen/repository/PowerPlantDispatchPlanRepository.java
@@ -39,38 +39,53 @@
@Repository
public interface PowerPlantDispatchPlanRepository extends GraphRepository {
- // @Query(value = "g.V.filter{it.getProperty('__type__')=='emlab.gen.domain.market.electricity.PowerPlantDispatchPlan' && it.getProperty('time')==time}", type = QueryType.Gremlin)
- // public Iterable findAllPowerPlantDispatchPlansForTime(@Param("time") long time);
+ // @Query(value =
+ // "g.V.filter{it.getProperty('__type__')=='emlab.gen.domain.market.electricity.PowerPlantDispatchPlan' && it.getProperty('time')==time}",
+ // type = QueryType.Gremlin)
+ // public Iterable
+ // findAllPowerPlantDispatchPlansForTime(@Param("time") long time);
@Query("START ppdp=node:__types__(\"className:emlab.gen.domain.market.electricity.PowerPlantDispatchPlan\") WHERE (ppdp.time={time} AND ppdp.forecast = {forecast}) RETURN ppdp")
public Iterable findAllPowerPlantDispatchPlansForTime(@Param("time") long time,
@Param("forecast") boolean forecast);
@Query(value = "result = g.v(plant).in('POWERPLANT_DISPATCHPLAN').as('x').propertyFilter('forecast', FilterPipe.Filter.EQUAL, forecast).out('SEGMENT_DISPATCHPLAN').idFilter(segment, FilterPipe.Filter.EQUAL).back('x')", type = QueryType.Gremlin)
- public Iterable findAllPowerPlantDispatchPlanForPowerPlantForSegmentForTime(@Param("plant") PowerPlant plant,
- @Param("segment") Segment segment, @Param("time") long time,
+ public Iterable findAllPowerPlantDispatchPlanForPowerPlantForSegmentForTime(
+ @Param("plant") PowerPlant plant, @Param("segment") Segment segment, @Param("time") long time,
@Param("forecast") boolean forecast);
@Query(value = "result = g.v(plant).in('POWERPLANT_DISPATCHPLAN').as('x').propertyFilter('forecast', FilterPipe.Filter.EQUAL, forecast).out('SEGMENT_DISPATCHPLAN').idFilter(segment, FilterPipe.Filter.EQUAL).back('x').propertyFilter('time', FilterPipe.Filter.EQUAL, time); if(!result.hasNext()){return null;} else{return result.next();}", type = QueryType.Gremlin)
- public PowerPlantDispatchPlan findOnePowerPlantDispatchPlanForPowerPlantForSegmentForTime(@Param("plant") PowerPlant plant,
- @Param("segment") Segment segment, @Param("time") long time,
+ public PowerPlantDispatchPlan findOnePowerPlantDispatchPlanForPowerPlantForSegmentForTime(
+ @Param("plant") PowerPlant plant, @Param("segment") Segment segment, @Param("time") long time,
@Param("forecast") boolean forecast);
- // @Query(value = "g.v(segment).in('SEGMENT_DISPATCHPLAN').propertyFilter('time', FilterPipe.Filter.EQUAL, time)", type = QueryType.Gremlin)
- // public Iterable findAllPowerPlantDispatchPlansForSegmentForTime(@Param("segment") Segment segment,
+ @Query(value = "result = g.v(plant).in('POWERPLANT_DISPATCHPLAN').as('x').out('SEGMENT_DISPATCHPLAN').filter{it.segmentID==1}.back('x').propertyFilter('forecast', FilterPipe.Filter.EQUAL, forecast).propertyFilter('time', FilterPipe.Filter.EQUAL, time); if(!result.hasNext()){return null;} else{return result.next();}", type = QueryType.Gremlin)
+ public PowerPlantDispatchPlan findOnePowerPlantDispatchPlanForPeakSegmentGivenPowerPlantAndTime(
+ @Param("plant") PowerPlant plant, @Param("time") long time, @Param("forecast") boolean forecast);
+
+ // @Query(value =
+ // "g.v(segment).in('SEGMENT_DISPATCHPLAN').propertyFilter('time', FilterPipe.Filter.EQUAL, time)",
+ // type = QueryType.Gremlin)
+ // public Iterable
+ // findAllPowerPlantDispatchPlansForSegmentForTime(@Param("segment") Segment
+ // segment,
// @Param("time") long time);
@Query("START segment = node({segment}) MATCH (segment)<-[:SEGMENT_DISPATCHPLAN]-(ppdp) WHERE (ppdp.time = {time} AND ppdp.forecast={forecast}) RETURN ppdp")
- public Iterable findAllPowerPlantDispatchPlansForSegmentForTime(@Param("segment") Segment segment,
- @Param("time") long time, @Param("forecast") boolean forecast);
+ public Iterable findAllPowerPlantDispatchPlansForSegmentForTime(
+ @Param("segment") Segment segment, @Param("time") long time, @Param("forecast") boolean forecast);
- // @Query(value = "g.v(segment).in('SEGMENT_DISPATCHPLAN').propertyFilter('time', FilterPipe.Filter.EQUAL, time).sort{it.price}._()", type = QueryType.Gremlin)
- // public Iterable findSortedPowerPlantDispatchPlansForSegmentForTime(@Param("segment") Segment segment,
+ // @Query(value =
+ // "g.v(segment).in('SEGMENT_DISPATCHPLAN').propertyFilter('time', FilterPipe.Filter.EQUAL, time).sort{it.price}._()",
+ // type = QueryType.Gremlin)
+ // public Iterable
+ // findSortedPowerPlantDispatchPlansForSegmentForTime(@Param("segment")
+ // Segment segment,
// @Param("time") long time);
@Query("START segment = node({segment}) MATCH (segment)<-[:SEGMENT_DISPATCHPLAN]-(ppdp) WHERE (ppdp.time = {time} AND ppdp.forecast={forecast}) RETURN ppdp ORDER BY ppdp.price")
- public Iterable findSortedPowerPlantDispatchPlansForSegmentForTime(@Param("segment") Segment segment,
- @Param("time") long time, @Param("forecast") boolean forecast);
+ public Iterable findSortedPowerPlantDispatchPlansForSegmentForTime(
+ @Param("segment") Segment segment, @Param("time") long time, @Param("forecast") boolean forecast);
// descending order
@Query("START segment = node({segment}) MATCH (segment)<-[:SEGMENT_DISPATCHPLAN]-(ppdp) WHERE (ppdp.time = {time} AND ppdp.forecast={forecast}) RETURN ppdp ORDER BY ppdp.price desc")
@@ -78,8 +93,8 @@ public Iterable findDescendingSortedPowerPlantDispatchPl
@Param("segment") Segment segment, @Param("time") long time, @Param("forecast") boolean forecast);
@Query(value = "g.v(plant).in('POWERPLANT_DISPATCHPLAN').propertyFilter('forecast', FilterPipe.Filter.EQUAL, forecast).propertyFilter('time', FilterPipe.Filter.EQUAL, time)", type = QueryType.Gremlin)
- public Iterable findAllPowerPlantDispatchPlansForPowerPlantForTime(@Param("plant") PowerPlant plant,
- @Param("time") long time, @Param("forecast") boolean forecast);
+ public Iterable findAllPowerPlantDispatchPlansForPowerPlantForTime(
+ @Param("plant") PowerPlant plant, @Param("time") long time, @Param("forecast") boolean forecast);
@Query(value = "g.v(producer).out('BIDDER').propertyFilter('time', FilterPipe.Filter.EQUAL, time).propertyFilter('forecast', FilterPipe.Filter.EQUAL, forecast)", type = QueryType.Gremlin)
public Iterable findAllPowerPlantDispatchPlansForEnergyProducerForTime(
@@ -90,19 +105,15 @@ public Iterable findAllPowerPlantDispatchPlansForEnergyP
@Param("producer") EnergyProducer producer, @Param("time") long time,
@Param("tech") PowerGeneratingTechnology pgt, @Param("forecast") boolean forecast);
-
@Query(value = "g.v(producer).out('BIDDER').propertyFilter('time', FilterPipe.Filter.EQUAL, time).propertyFilter('status', FilterPipe.Filter.GREATER_THAN_EQUAL , 2).propertyFilter('forecast', FilterPipe.Filter.EQUAL, forecast)", type = QueryType.Gremlin)
public Iterable findAllAcceptedPowerPlantDispatchPlansForEnergyProducerForTime(
@Param("producer") EnergyProducer producer, @Param("time") long time, @Param("forecast") boolean forecast);
@Query(value = "sum=0;ppdps=g.v(producer).out('BIDDER').propertyFilter('time', FilterPipe.Filter.EQUAL, time).propertyFilter('status', FilterPipe.Filter.GREATER_THAN_EQUAL , 2).propertyFilter('forecast', FilterPipe.Filter.EQUAL, forecast);"
- +
- "for(ppdp in ppdps){"+
- "totalAmount = ppdp.getProperty('acceptedAmount') + ppdp.getProperty('capacityLongTermContract');"+
- "hoursInSegment = ppdp.out('SEGMENT_DISPATCHPLAN').next().getProperty('lengthInHours');"+
- "production = totalAmount * hoursInSegment;"+
- "sum = sum + production};"
- + " return sum;", type = QueryType.Gremlin)
+ + "for(ppdp in ppdps){"
+ + "totalAmount = ppdp.getProperty('acceptedAmount') + ppdp.getProperty('capacityLongTermContract');"
+ + "hoursInSegment = ppdp.out('SEGMENT_DISPATCHPLAN').next().getProperty('lengthInHours');"
+ + "production = totalAmount * hoursInSegment;" + "sum = sum + production};" + " return sum;", type = QueryType.Gremlin)
public double calculateTotalProductionForEnergyProducerForTime(@Param("producer") EnergyProducer producer,
@Param("time") long time, @Param("forecast") boolean forecast);
@@ -117,23 +128,30 @@ public double calculateTotalProductionForEnergyProducerForTimeForTechnology(
@Query(value = "g.v(producer).out('BIDDER').propertyFilter('time', FilterPipe.Filter.EQUAL, time).propertyFilter('forecast', FilterPipe.Filter.EQUAL, forecast).as('x').out('SEGMENT_DISPATCHPLAN').idFilter(segment, FilterPipe.Filter.EQUAL).back('x')", type = QueryType.Gremlin)
public Iterable findAllPowerPlantDispatchPlansForEnergyProducerForTimeAndSegment(
- @Param("segment") Segment segment, @Param("producer") EnergyProducer producer, @Param("time") long time, @Param("forecast") boolean forecast);
+ @Param("segment") Segment segment, @Param("producer") EnergyProducer producer, @Param("time") long time,
+ @Param("forecast") boolean forecast);
@Query(value = "g.v(producer).out('BIDDER').propertyFilter('time', FilterPipe.Filter.EQUAL, time).propertyFilter('forecast', FilterPipe.Filter.EQUAL, forecast).propertyFilter('status', FilterPipe.Filter.GREATER_THAN_EQUAL, 2).as('x').out('SEGMENT_DISPATCHPLAN').idFilter(segment, FilterPipe.Filter.EQUAL).back('x')", type = QueryType.Gremlin)
public Iterable findAllAcceptedPowerPlantDispatchPlansForEnergyProducerForTimeAndSegment(
- @Param("segment") Segment segment, @Param("producer") EnergyProducer producer, @Param("time") long time, @Param("forecast") boolean forecast);
+ @Param("segment") Segment segment, @Param("producer") EnergyProducer producer, @Param("time") long time,
+ @Param("forecast") boolean forecast);
// @Query("START segment = node({segment}), market=node({market}) MATCH (segment)<-[:SEGMENT_DISPATCHPLAN]-(ppdp)-[:BIDDINGMARKET]->(market) WHERE (ppdp.time = {time}) and (ppdp.status >= 2) RETURN ppdp")
- // public Iterable findAllAcceptedPowerPlantDispatchPlansForMarketSegmentAndTime(
- // @Param("market") ElectricitySpotMarket esm, @Param("segment") Segment segment, @Param("time") long time);
+ // public Iterable
+ // findAllAcceptedPowerPlantDispatchPlansForMarketSegmentAndTime(
+ // @Param("market") ElectricitySpotMarket esm, @Param("segment") Segment
+ // segment, @Param("time") long time);
@Query(value = "g.v(market).in('BIDDINGMARKET').propertyFilter('time', FilterPipe.Filter.EQUAL, time).propertyFilter('forecast', FilterPipe.Filter.EQUAL, forecast).propertyFilter('status', FilterPipe.Filter.GREATER_THAN_EQUAL, 2).as('x').out('SEGMENT_DISPATCHPLAN').idFilter(segment, FilterPipe.Filter.EQUAL).back('x')", type = QueryType.Gremlin)
public Iterable findAllAcceptedPowerPlantDispatchPlansForMarketSegmentAndTime(
- @Param("market") ElectricitySpotMarket esm, @Param("segment") Segment segment, @Param("time") long time, @Param("forecast") boolean forecast);
+ @Param("market") ElectricitySpotMarket esm, @Param("segment") Segment segment, @Param("time") long time,
+ @Param("forecast") boolean forecast);
// @Query("START segment = node({segment} MATCH (segment)<-[:SEGMENT_DISPATCHPLAN]-(ppdp)<-[:BIDDER]-(node({producer})) WHERE (ppdp.time = {time}) AND (ppdp.status >=1) RETURN ppdp")
- // public Iterable findAllAcceptedPowerPlantDispatchPlansForEnergyProducerForTimeAndSegment(
- // @Param("segment") Segment segment, @Param("producer") EnergyProducer producer, @Param("time") long time);
+ // public Iterable
+ // findAllAcceptedPowerPlantDispatchPlansForEnergyProducerForTimeAndSegment(
+ // @Param("segment") Segment segment, @Param("producer") EnergyProducer
+ // producer, @Param("time") long time);
}
// package emlab.gen.repository;
@@ -157,10 +175,14 @@ public Iterable findAllAcceptedPowerPlantDispatchPlansFo
// import emlab.gen.domain.technology.PowerPlant;
//
// @Repository
-// public class PowerPlantDispatchPlanRepository extends AbstractRepository {
+// public class PowerPlantDispatchPlanRepository extends
+// AbstractRepository {
//
-// public PowerPlantDispatchPlan findOnePowerPlantDispatchPlanForPowerPlantForSegmentForTime(PowerPlant plant, Segment segment, long time) {
-// for (PowerPlantDispatchPlan plan : findAllPowerPlantDispatchPlansForPowerPlantForTime(plant, time)) {
+// public PowerPlantDispatchPlan
+// findOnePowerPlantDispatchPlanForPowerPlantForSegmentForTime(PowerPlant plant,
+// Segment segment, long time) {
+// for (PowerPlantDispatchPlan plan :
+// findAllPowerPlantDispatchPlansForPowerPlantForTime(plant, time)) {
// if (plan.getSegment().equals(segment)) {
// return plan;
// }
@@ -168,18 +190,23 @@ public Iterable findAllAcceptedPowerPlantDispatchPlansFo
// return null;
// }
//
-// public Iterable findAllPowerPlantDispatchPlansForSegmentForTime(Segment segment, long time) {
+// public Iterable
+// findAllPowerPlantDispatchPlansForSegmentForTime(Segment segment, long time) {
//
// // get incoming bids
-// Pipe bids = new LabeledEdgePipe("SEGMENT_DISPATCHPLAN", LabeledEdgePipe.Step.BOTH_BOTH);
+// Pipe bids = new LabeledEdgePipe("SEGMENT_DISPATCHPLAN",
+// LabeledEdgePipe.Step.BOTH_BOTH);
// // filter by time
-// Pipe timeFilter = new PropertyFilterPipe("time", time, FilterPipe.Filter.EQUAL);
+// Pipe timeFilter = new PropertyFilterPipe("time", time, FilterPipe.Filter.EQUAL);
// // create pipeline
-// Pipe pipeline = new Pipeline(bids, timeFilter);
+// Pipe pipeline = new Pipeline(bids,
+// timeFilter);
// return this.findAllByPipe(segment, pipeline);
// }
//
-// public Iterable findAllPowerPlantDispatchPlansForTime(long time) {
+// public Iterable
+// findAllPowerPlantDispatchPlansForTime(long time) {
// List list = new ArrayList();
// for (PowerPlantDispatchPlan plan : findAll()) {
// if (plan.getTime() == time) {
@@ -189,32 +216,47 @@ public Iterable findAllAcceptedPowerPlantDispatchPlansFo
// return list;
// }
//
-// public Iterable findAllPowerPlantDispatchPlansForPowerPlantForTime(PowerPlant powerPlant, long time) {
-// Pipe bids = new LabeledEdgePipe("POWERPLANT_DISPATCHPLAN", LabeledEdgePipe.Step.BOTH_BOTH);
+// public Iterable
+// findAllPowerPlantDispatchPlansForPowerPlantForTime(PowerPlant powerPlant,
+// long time) {
+// Pipe bids = new LabeledEdgePipe("POWERPLANT_DISPATCHPLAN",
+// LabeledEdgePipe.Step.BOTH_BOTH);
// // filter by time
-// Pipe timeFilter = new PropertyFilterPipe("time", time, FilterPipe.Filter.EQUAL);
+// Pipe timeFilter = new PropertyFilterPipe("time", time, FilterPipe.Filter.EQUAL);
// // create pipeline
-// Pipe pipeline = new Pipeline(bids, timeFilter);
+// Pipe pipeline = new Pipeline(bids,
+// timeFilter);
//
// return this.findAllByPipe(powerPlant, pipeline);
// }
//
-// public Iterable findAllPowerPlantDispatchPlansForEnergyProducerForTime(EnergyProducer energyProducer, long time) {
-// Pipe bids = new LabeledEdgePipe("BIDDER", LabeledEdgePipe.Step.BOTH_BOTH);
+// public Iterable
+// findAllPowerPlantDispatchPlansForEnergyProducerForTime(EnergyProducer
+// energyProducer, long time) {
+// Pipe bids = new LabeledEdgePipe("BIDDER",
+// LabeledEdgePipe.Step.BOTH_BOTH);
// // filter by time
-// Pipe timeFilter = new PropertyFilterPipe("time", time, FilterPipe.Filter.EQUAL);
+// Pipe timeFilter = new PropertyFilterPipe("time", time, FilterPipe.Filter.EQUAL);
// // create pipeline
-// Pipe pipeline = new Pipeline(bids, timeFilter);
+// Pipe pipeline = new Pipeline(bids,
+// timeFilter);
//
// return this.findAllByPipe(energyProducer, pipeline);
// }
//
// @Transactional
-// public PowerPlantDispatchPlan submitOrUpdatePowerPlantDispatchPlanForSpotMarket(PowerPlant plant, EnergyProducer producer,
-// ElectricitySpotMarket market, Segment segment, long time, double price, double capacity) {
+// public PowerPlantDispatchPlan
+// submitOrUpdatePowerPlantDispatchPlanForSpotMarket(PowerPlant plant,
+// EnergyProducer producer,
+// ElectricitySpotMarket market, Segment segment, long time, double price,
+// double capacity) {
//
// // make a new one if it
-// PowerPlantDispatchPlan plan = findOnePowerPlantDispatchPlanForPowerPlantForSegmentForTime(plant, segment, time);
+// PowerPlantDispatchPlan plan =
+// findOnePowerPlantDispatchPlanForPowerPlantForSegmentForTime(plant, segment,
+// time);
// if (plan == null) {
// plan = new PowerPlantDispatchPlan().persist();
// plan.setPowerPlant(plant);
@@ -231,7 +273,8 @@ public Iterable findAllAcceptedPowerPlantDispatchPlansFo
// }
//
// @Transactional
-// public void updateCapacityLongTermContract(PowerPlantDispatchPlan plan, double capacity) {
+// public void updateCapacityLongTermContract(PowerPlantDispatchPlan plan,
+// double capacity) {
// plan.setCapacityLongTermContract(capacity);
// // if(plan.getCapacitySpotMarket() + capacity >
// // plan.getPowerPlant().getTechnology().getCapacity()){
@@ -241,7 +284,8 @@ public Iterable findAllAcceptedPowerPlantDispatchPlansFo
// }
//
// @Transactional
-// public void updateCapacitySpotMarket(PowerPlantDispatchPlan plan, double capacity) {
+// public void updateCapacitySpotMarket(PowerPlantDispatchPlan plan, double
+// capacity) {
// plan.setCapacitySpotMarket(capacity);
// // if(plan.getCapacityLongTermContract() + capacity >
// // plan.getPowerPlant().getTechnology().getCapacity()){
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/PowerPlantRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/PowerPlantRepository.java
index 421ba7e2..6f78cbd3 100644
--- a/emlab-generation/src/main/java/emlab/gen/repository/PowerPlantRepository.java
+++ b/emlab-generation/src/main/java/emlab/gen/repository/PowerPlantRepository.java
@@ -42,7 +42,7 @@ public interface PowerPlantRepository extends GraphRepository {
/**
* Finds plants by owner.
- *
+ *
* @param owner
* of the plants
* @return the list of plants
@@ -79,9 +79,15 @@ public interface PowerPlantRepository extends GraphRepository {
// Iterable findOperationalPowerPlants(@Param("tick") long
// tick);
+ @Query(value = "g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']] .propertyFilter('dismantleTime', FilterPipe.Filter.GREATER_THAN, tick)", type = QueryType.Gremlin)
+ Iterable findAllPowerPlantsWhichAreNotDismantledBeforeTick(@Param("tick") long tick);
+
@Query(value = "g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']] .propertyFilter('dismantleTime', FilterPipe.Filter.LESS_THAN, tick)", type = QueryType.Gremlin)
Iterable findAllPowerPlantsDismantledBeforeTick(@Param("tick") long tick);
+ @Query(value = "g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']].filter{it.constructionStartTime==tick}", type = QueryType.Gremlin)
+ Iterable findAllPowerPlantsWithConstructionStartTimeInTick(@Param("tick") long tick);
+
/**
* Finds operational plants and gives them back as a list (only use for
* current tick, since only officially dismantled powerplants and plants in
@@ -99,9 +105,9 @@ public interface PowerPlantRepository extends GraphRepository {
@Query(value = "g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']].filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.sum{it.actualNominalCapacity};", type = QueryType.Gremlin)
double calculateCapacityOfOperationalPowerPlants(@Param("tick") long tick);
- @Query(value = "t = new Table();" +
- "g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']].filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.as('pp').out('TECHNOLOGY').as('ty').table(t){it.actualNominalCapacity}{it.peakSegmentDependentAvailability}.cap().next(); " +
- "capacitySum = 0; for (row in t){capacitySum += row.get(0) * row.get(1);}; return capacitySum;" , type = QueryType.Gremlin)
+ @Query(value = "t = new Table();"
+ + "g.idx('__types__')[[className:'emlab.gen.domain.technology.PowerPlant']].filter{(it.dismantleTime > tick) && ((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}.as('pp').out('TECHNOLOGY').as('ty').table(t){it.actualNominalCapacity}{it.peakSegmentDependentAvailability}.cap().next(); "
+ + "capacitySum = 0; for (row in t){capacitySum += row.get(0) * row.get(1);}; return capacitySum;", type = QueryType.Gremlin)
double calculatePeakCapacityOfOperationalPowerPlants(@Param("tick") long tick);
/**
@@ -163,9 +169,9 @@ public Iterable findOperationalPowerPlantsInMarket(@Param("market")
public double calculateCapacityOfOperationalPowerPlantsInMarket(@Param("market") ElectricitySpotMarket market,
@Param("tick") long tick);
- @Query(value = "t = new Table();" +
- "g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}.filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.dismantleTime > tick)}.as('pp').out('TECHNOLOGY').as('ty').table(t){it.actualNominalCapacity}{it.peakSegmentDependentAvailability}.cap().next(); " +
- "capacitySum = 0; for (row in t){capacitySum += row.get(0) * row.get(1);}; return capacitySum;" , type = QueryType.Gremlin)
+ @Query(value = "t = new Table();"
+ + "g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}.filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.dismantleTime > tick)}.as('pp').out('TECHNOLOGY').as('ty').table(t){it.actualNominalCapacity}{it.peakSegmentDependentAvailability}.cap().next(); "
+ + "capacitySum = 0; for (row in t){capacitySum += row.get(0) * row.get(1);}; return capacitySum;", type = QueryType.Gremlin)
public double calculatePeakCapacityOfOperationalPowerPlantsInMarket(@Param("market") ElectricitySpotMarket market,
@Param("tick") long tick);
@@ -193,42 +199,37 @@ public double calculateCapacityOfExpectedOperationalPowerPlantsByNodeAndTechnolo
@Param("node") PowerGridNode node, @Param("tech") PowerGeneratingTechnology technology,
@Param("tick") long tick);
- @Query(value = "result = g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}.as('owner').out('POWERPLANT_OWNER').filter{it==g.v(owner)}.back('owner').filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.expectedEndOfLife > tick)}.out('TECHNOLOGY').filter{it==g.v(tech)};", type = QueryType.Gremlin)
+ @Query(value = "result = g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}.out('POWERPLANT_OWNER').filter{it==g.v(owner)}.in('POWERPLANT_OWNER').filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.expectedEndOfLife > tick)}.out('TECHNOLOGY').filter{it==g.v(tech)};", type = QueryType.Gremlin)
public Iterable findExpectedOperationalPowerPlantsInMarketByOwnerAndTechnology(
@Param("market") ElectricitySpotMarket market, @Param("tech") PowerGeneratingTechnology technology,
@Param("tick") long tick, @Param("owner") EnergyProducer owner);
- @Query(value = "result = g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}.as('owner').out('POWERPLANT_OWNER').filter{it==g.v(owner)}.back('owner').filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.expectedEndOfLife > tick)}.as('x').out('TECHNOLOGY').filter{it==g.v(tech)}.back('x').sum{it.actualNominalCapacity};"
+ @Query(value = "result = g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}.out('POWERPLANT_OWNER').filter{it==g.v(owner)}.in('POWERPLANT_OWNER').filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.expectedEndOfLife > tick)}.as('x').out('TECHNOLOGY').filter{it==g.v(tech)}.back('x').sum{it.actualNominalCapacity};"
+ "if(result == null){return 0} else{return result}", type = QueryType.Gremlin)
public double calculateCapacityOfExpectedOperationalPowerPlantsInMarketByOwnerAndTechnology(
@Param("market") ElectricitySpotMarket market, @Param("tech") PowerGeneratingTechnology technology,
@Param("tick") long tick, @Param("owner") EnergyProducer owner);
- @Query(value = "result = g.v(owner).in('POWERPLANT_OWNER').filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.expectedEndOfLife > tick)}.sum{it.actualNominalCapacity};"
+ @Query(value = "result = g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}.out('POWERPLANT_OWNER').filter{it==g.v(owner)}.in('POWERPLANT_OWNER').filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.expectedEndOfLife > tick)}.sum{it.actualNominalCapacity};"
+ "if(result == null){return 0} else{return result}", type = QueryType.Gremlin)
- public double calculateCapacityOfExpectedOperationalPowerPlantsByOwner(@Param("tick") long tick,
+ public double calculateCapacityOfExpectedOperationalPowerPlantsInMarketByOwner(
+ @Param("market") ElectricitySpotMarket market, @Param("tick") long tick,
@Param("owner") EnergyProducer owner);
- @Query(value = "result = g.v(owner).in('POWERPLANT_OWNER').filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.expectedEndOfLife > tick)}.as('x').out('TECHNOLOGY').filter{it.name==g.v(tech).name}.back('x').sum{it.actualNominalCapacity};"
- + "if(result == null){return 0} else{return result}", type = QueryType.Gremlin)
- public double calculateCapacityOfExpectedOperationalPowerPlantsByOwnerByTechnology(@Param("tick") long tick,
- @Param("owner") EnergyProducer owner, @Param("tech") PowerGeneratingTechnology pgt);
-
@Query(value = "result = g.v(owner).in('POWERPLANT_OWNER').filter{it.expectedEndOfLife == tick}.as('x').out('TECHNOLOGY').filter{it.name==g.v(tech).name}.back('x').sum{it.actualNominalCapacity};"
+ "if(result == null){return 0} else{return result}", type = QueryType.Gremlin)
public double calculateCapacityOfExpectedDismantledPowerPlantsByOwnerByTechnology(@Param("tick") long tick,
@Param("owner") EnergyProducer owner, @Param("tech") PowerGeneratingTechnology pgt);
- @Query(value = "result = g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}.as('x').out('POWERPLANT_OWNER').filter{it==g.v(owner)}.back('x').filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.expectedEndOfLife > tick)}.out('TECHNOLOGY');", type = QueryType.Gremlin)
- public Iterable findExpectedOperationalPowerPlantsInMarketByOwner(
- @Param("market") ElectricitySpotMarket market, @Param("tick") long tick,
+ @Query(value = "result = g.v(owner).in('POWERPLANT_OWNER').filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.expectedEndOfLife > tick)}.sum{it.actualNominalCapacity};"
+ + "if(result == null){return 0} else{return result}", type = QueryType.Gremlin)
+ public double calculateCapacityOfExpectedOperationalPowerPlantsByOwner(@Param("tick") long tick,
@Param("owner") EnergyProducer owner);
- @Query(value = "result = g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}.out('POWERPLANT_OWNER').filter{it==g.v(owner)}.in('POWERPLANT_OWNER').filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.expectedEndOfLife > tick)}.sum{it.actualNominalCapacity};"
+ @Query(value = "result = g.v(owner).in('POWERPLANT_OWNER').filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.expectedEndOfLife > tick)}.as('x').out('TECHNOLOGY').filter{it.name==g.v(tech).name}.back('x').sum{it.actualNominalCapacity};"
+ "if(result == null){return 0} else{return result}", type = QueryType.Gremlin)
- public double calculateCapacityOfExpectedOperationalPowerPlantsInMarketByOwner(
- @Param("market") ElectricitySpotMarket market, @Param("tick") long tick,
- @Param("owner") EnergyProducer owner);
+ public double calculateCapacityOfExpectedOperationalPowerPlantsByOwnerByTechnology(@Param("tick") long tick,
+ @Param("owner") EnergyProducer owner, @Param("tech") PowerGeneratingTechnology pgt);
@Query(value = "g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}", type = QueryType.Gremlin)
public Iterable findPowerPlantsInMarket(@Param("market") ElectricitySpotMarket market);
@@ -259,10 +260,44 @@ public double calculateCapacityOfPowerPlantsByTechnologyInPipeline(
public double calculateCapacityOfPowerPlantsByMarketInPipeline(@Param("market") ElectricitySpotMarket market,
@Param("tick") long tick);
+ @Query(value = "g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}.as('plant').filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.dismantleTime > tick)}.sort{-it.ageFraction}_()", type = QueryType.Gremlin)
+ public Iterable findOperationalPowerPlantsByDescendingAgeFactorAndMarket(
+ @Param("market") ElectricitySpotMarket market, @Param("tick") long tick);
+
+ @Query(value = "g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}.as('plant').filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.dismantleTime > tick)}.sort{it.profitability}_()", type = QueryType.Gremlin)
+ public Iterable findOperationalPowerPlantsByAscendingProfitabilityAndMarket(
+ @Param("market") ElectricitySpotMarket market, @Param("tick") long tick);
+
+ @Query(value = "g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}.as('plant').filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.dismantleTime > tick)}.sort{-it.profitability}_()", type = QueryType.Gremlin)
+ public Iterable findOperationalPowerPlantsByDescendingProfitabilityAndMarket(
+ @Param("market") ElectricitySpotMarket market, @Param("tick") long tick);
+
+ @Query(value = "g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}.filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick)}", type = QueryType.Gremlin)
+ public Iterable findExpectedOperationalPowerPlantsInMarketWithoutDismantling(
+ @Param("market") ElectricitySpotMarket market, @Param("tick") long tick);
+
+ @Query(value = "double counter=0;"
+ + "powerplants = g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}.filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.dismantleTime > tick)};"
+ + "for (pp in powerplants) {" + "capacity = pp.actualNominalCapacity.next();"
+ + "peak=pp.out('TECHNOLOGY').peakSegmentDependentAvailability.next();" + "result = capacity*peak;"
+ + "counter = counter+result };" + "return counter", type = QueryType.Gremlin)
+ public double calculatePeakCapacityOfPowerPlantsByMarketTime(@Param("market") ElectricitySpotMarket market,
+ @Param("tick") long tick);
+
@Query(value = "substanceShares = g.v(substance).in('SUBSTANCE').filter{it.__type__=='emlab.gen.domain.technology.SubstanceShareInFuelMix'};"
+ "sum=substanceShares.sum{it.share}; if(sum!=null) return sum else return 0;;", type = QueryType.Gremlin)
public double calculateSubstanceUsage(@Param("substance") Substance substance);
+ @Query(value = "g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}.filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.expectedEndOfLife > tick) && it.profitability>=0}", type = QueryType.Gremlin)
+ public Iterable findExpectedOperationalProfitablePowerPlantsInMarket(
+ @Param("market") ElectricitySpotMarket market, @Param("tick") long tick);
+
+ @Query(value = "t = new Table();"
+ + "g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}.filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.dismantleTime > tick)}.as('pp').out('TECHNOLOGY').as('ty').table(t){it.actualNominalCapacity}{it.baseSegmentDependentAvailability}.cap().next(); "
+ + "capacitySum = 0; for (row in t){capacitySum += row.get(0) * row.get(1);}; return capacitySum;", type = QueryType.Gremlin)
+ public double calculateBaseCapacityOfOperationalPowerPlantsInMarket(@Param("market") ElectricitySpotMarket market,
+ @Param("tick") long tick);
+
@Query(value = "g.v(gridnode).in('LOCATION').filter{(it.__type__=='emlab.gen.domain.technology.PowerPlant')}.as('p').out('TECHNOLOGY').filter{it.intermittent == true}.back('p').filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.dismantleTime > tick)}", type = QueryType.Gremlin)
Iterable findOperationalIntermittentPowerPlantsByPowerGridNode(@Param("gridnode") PowerGridNode node,
@Param("tick") long tick);
@@ -283,4 +318,45 @@ Iterable findOperationalIntermittentPowerPlantsByPowerGridNodeAndTec
@Param("gridnode") PowerGridNode node,
@Param("technology") PowerGeneratingTechnology powerGeneratingTechnology, @Param("tick") long tick);
+ @Query(value = "result=g.v(plant).in('REGARDING_POWERPLANT').propertyFilter('type', FilterPipe.Filter.EQUAL, 1).propertyFilter('time', FilterPipe.Filter.EQUAL, tick).money.sum(); if(result==null){result=0}; return result", type = QueryType.Gremlin)
+ double calculateSpotMarketRevenueOfPowerPlant(@Param("plant") PowerPlant plant, @Param("tick") long tick);
+
+ @Query(value = "result=g.v(plant).in('REGARDING_POWERPLANT').propertyFilter('type', FilterPipe.Filter.EQUAL, 2).propertyFilter('time', FilterPipe.Filter.EQUAL, tick).money.sum(); if(result==null){result=0}; return result", type = QueryType.Gremlin)
+ double calculateLongTermContractRevenueOfPowerPlant(@Param("plant") PowerPlant plant, @Param("tick") long tick);
+
+ @Query(value = "result=g.v(plant).in('REGARDING_POWERPLANT').propertyFilter('type', FilterPipe.Filter.EQUAL, 10).propertyFilter('time', FilterPipe.Filter.EQUAL, tick).money.sum(); if(result==null){result=0}; return result", type = QueryType.Gremlin)
+ double calculateStrategicReserveRevenueOfPowerPlant(@Param("plant") PowerPlant plant, @Param("tick") long tick);
+
+ @Query(value = "result=g.v(plant).in('REGARDING_POWERPLANT').propertyFilter('type', FilterPipe.Filter.EQUAL, 11).propertyFilter('time', FilterPipe.Filter.EQUAL, tick).money.sum(); if(result==null){result=0}; return result", type = QueryType.Gremlin)
+ double calculateCapacityMarketRevenueOfPowerPlant(@Param("plant") PowerPlant plant, @Param("tick") long tick);
+
+ @Query(value = "result=g.v(plant).in('REGARDING_POWERPLANT').propertyFilter('type', FilterPipe.Filter.EQUAL, 12).propertyFilter('time', FilterPipe.Filter.EQUAL, tick).money.sum(); if(result==null){result=0}; return result", type = QueryType.Gremlin)
+ double calculateCO2HedgingRevenueOfPowerPlant(@Param("plant") PowerPlant plant, @Param("tick") long tick);
+
+ @Query(value = "result=g.v(plant).in('REGARDING_POWERPLANT').filter{it.type==5 || it.type==6 || it.type==9}.propertyFilter('time', FilterPipe.Filter.EQUAL, tick).money.sum(); if(result==null){result=0}; return result", type = QueryType.Gremlin)
+ double calculateCO2CostsOfPowerPlant(@Param("plant") PowerPlant plant, @Param("tick") long tick);
+
+ @Query(value = "result=g.v(plant).in('REGARDING_POWERPLANT').filter{it.type==3 || it.type==7 || it.type==8}.propertyFilter('time', FilterPipe.Filter.EQUAL, tick).money.sum(); if(result==null){result=0}; return result", type = QueryType.Gremlin)
+ double calculateFixedCostsOfPowerPlant(@Param("plant") PowerPlant plant, @Param("tick") long tick);
+
+ @Query(value = "ppdps=g.v(plant).in('POWERPLANT_DISPATCHPLAN').filter{it.time==tick}.propertyFilter('forecast', FilterPipe.Filter.EQUAL, false); sum=0;"
+ + "fullLoadHours=0;"
+ + "for(ppdp in ppdps){"
+ + "totalAmount = ppdp.getProperty('acceptedAmount') + ppdp.getProperty('capacityLongTermContract');"
+ + "if(totalAmount==null) totalAmount=0;"
+ + "hoursInSegment = ppdp.out('SEGMENT_DISPATCHPLAN').next().getProperty('lengthInHours');"
+ + "production = totalAmount * hoursInSegment;"
+ + "fullLoadHours = fullLoadHours + hoursInSegment * totalAmount / (ppdp.out('POWERPLANT_DISPATCHPLAN').next().actualNominalCapacity *1.0d);"
+ + "}; return fullLoadHours;", type = QueryType.Gremlin)
+ double calculateFullLoadHoursOfPowerPlant(@Param("plant") PowerPlant plant, @Param("tick") long tick);
+
+ @Query(value = "g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{(it.__type__=='emlab.gen.domain.technology.PowerPlant')}.as('p').out('TECHNOLOGY').filter{it==g.v(technology)}.back('p').filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.dismantleTime > tick)}", type = QueryType.Gremlin)
+ Iterable findOperationalPowerPlantsByMarketAndTechnology(@Param("market") ElectricitySpotMarket market,
+ @Param("technology") PowerGeneratingTechnology powerGeneratingTechnology, @Param("tick") long tick);
+
+ @Query(value = "result = g.v(market).out('ZONE').in('REGION').in('LOCATION').filter{it.__type__=='emlab.gen.domain.technology.PowerPlant'}.as('x').out('POWERPLANT_OWNER').filter{it==g.v(owner)}.back('x').filter{((it.constructionStartTime + it.actualPermittime + it.actualLeadtime) <= tick) && (it.expectedEndOfLife > tick)}.out('TECHNOLOGY');", type = QueryType.Gremlin)
+ public Iterable findExpectedOperationalPowerPlantsInMarketByOwner(
+ @Param("market") ElectricitySpotMarket market, @Param("tick") long tick,
+ @Param("owner") EnergyProducer owner);
+
}
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/RegulatorRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/RegulatorRepository.java
new file mode 100644
index 00000000..fd0b6eb9
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/repository/RegulatorRepository.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.repository;
+
+import org.springframework.data.neo4j.annotation.Query;
+import org.springframework.data.neo4j.annotation.QueryType;
+import org.springframework.data.neo4j.repository.GraphRepository;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import emlab.gen.domain.agent.Regulator;
+import emlab.gen.domain.gis.Zone;
+
+/**
+ * @author Kaveri
+ *
+ */
+@Repository
+public interface RegulatorRepository extends GraphRepository {
+
+ @Query(value = "g.v(zone).in('OF_ZONE')", type = QueryType.Gremlin)
+ public Regulator findRegulatorForZone(@Param("zone") Zone zone);
+
+}
\ No newline at end of file
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/RenewableSupportSchemeTenderRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/RenewableSupportSchemeTenderRepository.java
new file mode 100644
index 00000000..80543d9a
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/repository/RenewableSupportSchemeTenderRepository.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.repository;
+
+import org.springframework.data.neo4j.repository.GraphRepository;
+
+import emlab.gen.domain.policy.renewablesupport.RenewableSupportSchemeTender;
+
+/**
+ * @author Kaveri3012 rjjdejeu
+ *
+ */
+public interface RenewableSupportSchemeTenderRepository extends GraphRepository {
+
+}
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/RenewableTargetForTenderRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/RenewableTargetForTenderRepository.java
new file mode 100644
index 00000000..dd28d1f7
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/repository/RenewableTargetForTenderRepository.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.repository;
+
+import org.springframework.data.neo4j.annotation.Query;
+import org.springframework.data.neo4j.annotation.QueryType;
+import org.springframework.data.neo4j.repository.GraphRepository;
+import org.springframework.data.repository.query.Param;
+
+import emlab.gen.domain.agent.Regulator;
+import emlab.gen.domain.policy.renewablesupport.RenewableTargetForTender;
+
+/**
+ * @author Kaveri3012
+ *
+ */
+public interface RenewableTargetForTenderRepository extends GraphRepository {
+
+ @Query(value = "g.v(regulator).out('SET_BY_REGULATOR')", type = QueryType.Gremlin)
+ public RenewableTargetForTender findRenewableTargetForTenderByRegulator(@Param("regulator") Regulator regulator);
+
+}
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/Reps.java b/emlab-generation/src/main/java/emlab/gen/repository/Reps.java
index 33f872c3..75065255 100644
--- a/emlab-generation/src/main/java/emlab/gen/repository/Reps.java
+++ b/emlab-generation/src/main/java/emlab/gen/repository/Reps.java
@@ -89,6 +89,9 @@ public class Reps {
@Autowired
public PowerGeneratingTechnologyNodeLimitRepository powerGeneratingTechnologyNodeLimitRepository;
+ @Autowired
+ public InterconnectorRepository interconnectorRepository;
+
@Autowired
public StrategicReserveOperatorRepository strategicReserveOperatorRepository;
@@ -98,4 +101,30 @@ public class Reps {
@Autowired
public IntermittentTechnologyNodeLoadFactorRepository intermittentTechnologyNodeLoadFactorRepository;
+ @Autowired
+ public CapacityMarketRepository capacityMarketRepository;
+
+ @Autowired
+ public CapacityClearingPointRepository capacityClearingPointRepository;
+
+ @Autowired
+ public RegulatorRepository regulatorRepository;
+
+ @Autowired
+ public CapacityDispatchPlanRepository capacityDispatchPlanRepository;
+
+ @Autowired
+ public RenewableSupportSchemeTenderRepository renewableSupportSchemeTenderRepository;
+
+ @Autowired
+ public FinancialPowerPlantReportRepository financialPowerPlantReportRepository;
+
+ @Autowired
+ public RenewableTargetForTenderRepository renewableTargetForTenderRepository;
+
+ @Autowired
+ public TenderClearingPointRepository tenderClearingPointRepository;
+
+ @Autowired
+ public TenderBidRepository tenderBidRepository;
}
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/SegmentClearingPointRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/SegmentClearingPointRepository.java
index 1d48e432..95b15827 100644
--- a/emlab-generation/src/main/java/emlab/gen/repository/SegmentClearingPointRepository.java
+++ b/emlab-generation/src/main/java/emlab/gen/repository/SegmentClearingPointRepository.java
@@ -35,11 +35,17 @@ Iterable findAllSegmentClearingPointsForSegmentAndTime(@Pa
@Param("segment") Segment segment, @Param("forecast") boolean forecast);
// @Query("START segment = node({segment}), market=node({market}) MATCH (segment)<-[:SEGMENT_POINT]-(scp)-[:MARKET_POINT]->(market) WHERE (scp.time = {time}) RETURN scp")
- // SegmentClearingPoint findOneSegmentClearingPointForMarketSegmentAndTime(@Param("time") long time, @Param("segment") Segment segment,
+ // SegmentClearingPoint
+ // findOneSegmentClearingPointForMarketSegmentAndTime(@Param("time") long
+ // time, @Param("segment") Segment segment,
// @Param("market") ElectricitySpotMarket electricitySpotMarket);
@Query(value = "g.v(segment).in('SEGMENT_POINT').propertyFilter('time', FilterPipe.Filter.EQUAL, time).propertyFilter('forecast', FilterPipe.Filter.EQUAL, forecast).as('x').out('MARKET_POINT').idFilter(market, FilterPipe.Filter.EQUAL).back('x')", type = QueryType.Gremlin)
- SegmentClearingPoint findOneSegmentClearingPointForMarketSegmentAndTime(@Param("time") long time, @Param("segment") Segment segment,
- @Param("market") ElectricitySpotMarket electricitySpotMarket,
+ SegmentClearingPoint findOneSegmentClearingPointForMarketSegmentAndTime(@Param("time") long time,
+ @Param("segment") Segment segment, @Param("market") ElectricitySpotMarket electricitySpotMarket,
@Param("forecast") boolean forecast);
+
+ @Query(value = "g.v(segment).in('SEGMENT_POINT').propertyFilter('time', FilterPipe.Filter.EQUAL, time).as('x').out('MARKET_POINT').idFilter(market, FilterPipe.Filter.EQUAL).back('x')", type = QueryType.Gremlin)
+ SegmentClearingPoint findOneSegmentClearingPointForMarketSegmentAndTime(@Param("time") long time,
+ @Param("segment") Segment segment, @Param("market") ElectricitySpotMarket electricitySpotMarket);
}
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/SegmentLoadRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/SegmentLoadRepository.java
index 980873b2..6923c8fc 100644
--- a/emlab-generation/src/main/java/emlab/gen/repository/SegmentLoadRepository.java
+++ b/emlab-generation/src/main/java/emlab/gen/repository/SegmentLoadRepository.java
@@ -45,6 +45,9 @@ public interface SegmentLoadRepository extends GraphRepository {
@Query("start segment=node({segment}) match (segment)<-[:SEGMENTLOAD_SEGMENT]-(segmentload) return segmentload")
public Iterable findAllSegmentLoadsBySegment(@Param("segment") Segment segment);
+ @Query("start segment=node({segment}) match (segment)<-[:SEGMENTLOAD_SEGMENT]-(segmentload) return segmentload")
+ public SegmentLoad getSegmentLoadBySegment(@Param("segment") Segment segment);
+
/**
* Finds the segment load for a certain segment and market
*
@@ -64,4 +67,9 @@ public interface SegmentLoadRepository extends GraphRepository {
@Query(value = "g.v(zone).in('ZONE').filter{it.__type__=='emlab.gen.domain.market.electricity.ElectricitySpotMarket'}.outE('SEGMENT_LOAD').inV.max{it.baseLoad}.baseLoad", type = QueryType.Gremlin)
double peakLoadbyZoneMarketandTime(@Param("zone") Zone zone, @Param("market") ElectricitySpotMarket market);
+ @Query(value = "topsegments = g.v(market).out('SEGMENT_LOAD').max{it.baseLoad}.baseLoad;"
+ + "try{growthfactors = g.v(market).out('DEMANDGROWTH_TREND').collect{f.getTrendValue(it, tick)}[0];} catch(Exception e){"
+ + "growthfactors=g.v(market).out('DEMANDGROWTH_TREND').timeSeries.next()[tick.toInteger()]};"
+ + "adjustedTopSegments = topsegments*growthfactors;" + "return[adjustedTopSegments]", type = QueryType.Gremlin)
+ double peakLoadbyMarketandTime(@Param("market") ElectricitySpotMarket market, @Param("tick") long tick);
}
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/SegmentRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/SegmentRepository.java
index 6bedadce..3afdc088 100644
--- a/emlab-generation/src/main/java/emlab/gen/repository/SegmentRepository.java
+++ b/emlab-generation/src/main/java/emlab/gen/repository/SegmentRepository.java
@@ -15,12 +15,27 @@
******************************************************************************/
package emlab.gen.repository;
+import org.springframework.data.neo4j.annotation.Query;
+import org.springframework.data.neo4j.annotation.QueryType;
import org.springframework.data.neo4j.repository.GraphRepository;
+import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
+import emlab.gen.domain.market.electricity.ElectricitySpotMarket;
import emlab.gen.domain.market.electricity.Segment;
@Repository
public interface SegmentRepository extends GraphRepository {
+ @Query(value = "g.v(market).out('SEGMENT_LOAD').out('SEGMENTLOAD_SEGMENT').filter{it.segmentID==1}", type = QueryType.Gremlin)
+ public Segment findPeakSegmentforMarket(@Param("market") ElectricitySpotMarket market);
+
+ @Query(value = "g.v(market).out('SEGMENT_LOAD').out.sort{-it.segmentID}.next()", type = QueryType.Gremlin)
+ public Segment findBaseSegmentforMarket(@Param("market") ElectricitySpotMarket market);
+
+ @Query(value = "g.v(market).out('SEGMENT_LOAD').out.sort{it.segmentID}_()", type = QueryType.Gremlin)
+ public Iterable findSegmentforMarketSortedbySegmentID(@Param("market") ElectricitySpotMarket market);
+
+ @Query(value = "g.v(market).out('SEGMENT_LOAD').out", type = QueryType.Gremlin)
+ public Iterable findSegmentforMarket(@Param("market") ElectricitySpotMarket market);
}
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/TargetInvestorRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/TargetInvestorRepository.java
index 449e85d4..5a05e14b 100644
--- a/emlab-generation/src/main/java/emlab/gen/repository/TargetInvestorRepository.java
+++ b/emlab-generation/src/main/java/emlab/gen/repository/TargetInvestorRepository.java
@@ -27,8 +27,16 @@
* @author JCRichstein
*
*/
-public interface TargetInvestorRepository extends
-GraphRepository {
+public interface TargetInvestorRepository extends GraphRepository {
+
+ @Query(value = "result = g.v(market).in('INVESTOR_MARKET').next(); ; if(!result.hasNext()){return null;} else{return result.next();}", type = QueryType.Gremlin)
+ TargetInvestor findOneByMarket(@Param("market") ElectricitySpotMarket electricitySpotMarket);
+
+ @Query(value = "result = g.v(market).in('INVESTOR_MARKET').next();", type = QueryType.Gremlin)
+ TargetInvestor findInvestorByMarket(@Param("market") ElectricitySpotMarket electricitySpotMarket);
+
+ @Query(value = "result = g.v(market).in('INVESTOR_MARKET').filter{it.__type__=='emlab.gen.domain.agent.TargetInvestor'};", type = QueryType.Gremlin)
+ TargetInvestor findTargetInvestorByMarket(@Param("market") ElectricitySpotMarket electricitySpotMarket);
@Query(value = "g.idx('__types__')[[className:'emlab.gen.domain.agent.TargetInvestor']].as('x').out('INVESTOR_MARKET').idFilter(market, FilterPipe.Filter.EQUAL).back('x')", type = QueryType.Gremlin)
Iterable findAllByMarket(@Param("market") ElectricitySpotMarket electricitySpotMarket);
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/TenderBidRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/TenderBidRepository.java
new file mode 100644
index 00000000..d9ad03f7
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/repository/TenderBidRepository.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.repository;
+
+import org.springframework.data.neo4j.annotation.Query;
+import org.springframework.data.neo4j.annotation.QueryType;
+import org.springframework.data.neo4j.repository.GraphRepository;
+import org.springframework.data.repository.query.Param;
+
+import emlab.gen.domain.policy.renewablesupport.RenewableSupportSchemeTender;
+import emlab.gen.domain.policy.renewablesupport.TenderBid;
+
+/**
+ * @author rjjdejeu
+ *
+ */
+public interface TenderBidRepository extends GraphRepository {
+
+ // This sorts the submitted tender bids by price
+ @Query(value = "g.idx('__types__')[[className:'emlab.gen.domain.policy.renewablesupport.TenderBid']].filter{it.time == tick}.sort{it.price}._()", type = QueryType.Gremlin)
+ public Iterable findAllSortedTenderBidsbyTime(@Param("tick") long time);
+
+ // this returns the accepted tender bids Scheme --with regulator-->
+ // Regulator --of zone--> Zone
+ @Query(value = "g.v(renewableSupportSchemeTender).in('TENDERBID_SUPPORTSCHEME').propertyFilter('start', FilterPipe.Filter.LESS_THAN_EQUAL,time ).propertyFilter('finish', FilterPipe.Filter.GREATER_THAN_EQUAL, time).propertyFilter('status', FilterPipe.Filter.GREATER_THAN_EQUAL, 2)", type = QueryType.Gremlin)
+ public Iterable findAllTenderBidsThatShouldBePaidInTimeStep(
+ @Param("scheme") RenewableSupportSchemeTender renewableSupportSchemeTender, @Param("time") long time);
+
+}
diff --git a/emlab-generation/src/main/java/emlab/gen/repository/TenderClearingPointRepository.java b/emlab-generation/src/main/java/emlab/gen/repository/TenderClearingPointRepository.java
new file mode 100644
index 00000000..c9deb913
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/repository/TenderClearingPointRepository.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.repository;
+
+import org.springframework.data.neo4j.annotation.Query;
+import org.springframework.data.neo4j.annotation.QueryType;
+import org.springframework.data.neo4j.repository.GraphRepository;
+import org.springframework.data.repository.query.Param;
+
+import emlab.gen.domain.market.ClearingPoint;
+import emlab.gen.domain.policy.renewablesupport.RenewableSupportSchemeTender;
+import emlab.gen.domain.policy.renewablesupport.TenderClearingPoint;
+
+/**
+ * @author rjjdejeu
+ *
+ */
+
+public interface TenderClearingPointRepository extends GraphRepository {
+
+ @Query(value = "g.v(market).in('RENEWABLE_SUPPORT_SCHEME_TENDER').propertyFilter('time', FilterPipe.Filter.EQUAL, time)", type = QueryType.Gremlin)
+ public ClearingPoint findOneClearingPointForTimeAndRenewableSupportSchemeTender(@Param("time") long time,
+ @Param("market") RenewableSupportSchemeTender renewableSupportSchemeTender);
+
+}
diff --git a/emlab-generation/src/main/java/emlab/gen/role/AbstractEnergyProducerRole.java b/emlab-generation/src/main/java/emlab/gen/role/AbstractEnergyProducerRole.java
index e2f3a1cc..ae9c615e 100644
--- a/emlab-generation/src/main/java/emlab/gen/role/AbstractEnergyProducerRole.java
+++ b/emlab-generation/src/main/java/emlab/gen/role/AbstractEnergyProducerRole.java
@@ -67,7 +67,7 @@ public double calculateMarginalCostExclCO2MarketCost(PowerPlant powerPlant, long
// fuel cost
mc += calculateMarginalFuelCost(powerPlant, clearingTick);
mc += calculateCO2TaxMarginalCost(powerPlant, clearingTick);
- logger.info("Margincal cost excluding CO2 auction/market cost for plant {} is {}", powerPlant.getName(), mc);
+ logger.info("Marginal cost excluding CO2 auction/market cost for plant {} is {}", powerPlant.getName(), mc);
return mc;
}
@@ -95,7 +95,8 @@ public double calculateMarginalFuelCost(PowerPlant powerPlant, long clearingTick
return fc;
}
- public double calculateExpectedMarginalFuelCost(PowerPlant powerPlant, Map forecastedFuelPrices) {
+ public double calculateExpectedMarginalFuelCost(PowerPlant powerPlant,
+ Map forecastedFuelPrices) {
double fc = 0d;
// fuel cost for each fuel
for (SubstanceShareInFuelMix mix : powerPlant.getFuelMix()) {
@@ -111,16 +112,18 @@ public double calculateExpectedMarginalFuelCost(PowerPlant powerPlant, Map calculateFuelMix(PowerPlant plant, Map substancePriceMap, double co2Price) {
+ public Set calculateFuelMix(PowerPlant plant, Map substancePriceMap,
+ double co2Price) {
double efficiency = plant.getActualEfficiency();
- Set fuelMix = (plant.getFuelMix() == null) ? new HashSet() : plant.getFuelMix();
+ Set fuelMix = (plant.getFuelMix() == null) ? new HashSet()
+ : plant.getFuelMix();
int numberOfFuels = substancePriceMap.size();
if (numberOfFuels == 0) {
@@ -372,8 +381,10 @@ public Set calculateFuelMix(PowerPlant plant, Map= qmin
- // so that the fuelquality weighted by the mass percentages is greater than the minimum fuel quality.
+ // The equation is derived from (example for 2 fuels): q1 * x1 /
+ // (x1+x2) + q2 * x2 / (x1+x2) >= qmin
+ // so that the fuelquality weighted by the mass percentages is
+ // greater than the minimum fuel quality.
constraints.add(new LinearConstraint(fuelQuality, Relationship.GEQ, 0));
try {
@@ -396,14 +407,15 @@ public Set calculateFuelMix(PowerPlant plant, Map determineExpectedCO2PriceInclTa
}
/**
- * Calculates expected CO2 price based on a geometric trend estimation, of the past years. The adjustmentForDetermineFuelMix needs to be set to 1, if this is used in the determine
- * fuel mix role.
+ * Calculates expected CO2 price based on a geometric trend estimation, of
+ * the past years. The adjustmentForDetermineFuelMix needs to be set to 1,
+ * if this is used in the determine fuel mix role.
*
- * @param futureTimePoint Year the prediction is made for
- * @param yearsLookingBackForRegression How many years are used as input for the regression, incl. the current tick.
+ * @param futureTimePoint
+ * Year the prediction is made for
+ * @param yearsLookingBackForRegression
+ * How many years are used as input for the regression, incl. the
+ * current tick.
* @return
*/
protected HashMap determineExpectedCO2PriceInclTax(long futureTimePoint,
long yearsLookingBackForRegression, int adjustmentForDetermineFuelMix, long clearingTick) {
HashMap co2Prices = new HashMap();
CO2Auction co2Auction = reps.marketRepository.findCO2Auction();
- //Find Clearing Points for the last 5 years (counting current year as one of the last 5 years).
+ // Find Clearing Points for the last 5 years (counting current year as
+ // one of the last 5 years).
Iterable cps = reps.clearingPointRepository.findAllClearingPointsForMarketAndTimeRange(
co2Auction, clearingTick - yearsLookingBackForRegression + 1 - adjustmentForDetermineFuelMix,
clearingTick - adjustmentForDetermineFuelMix, false);
@@ -502,18 +527,19 @@ protected HashMap determineExpectedCO2PriceInclTa
}
averagePrice = averagePrice / i;
double expectedCO2Price;
- if(i>1){
+ if (i > 1) {
expectedCO2Price = sr.predict(futureTimePoint);
expectedCO2Price = Math.max(0, expectedCO2Price);
expectedCO2Price = Math.min(expectedCO2Price, government.getCo2Penalty(futureTimePoint));
- }else{
+ } else {
expectedCO2Price = lastPrice;
}
// Calculate average of regression and past average:
expectedCO2Price = (expectedCO2Price + averagePrice) / 2;
for (ElectricitySpotMarket esm : reps.marketRepository.findAllElectricitySpotMarkets()) {
- double nationalCo2MinPriceinFutureTick = reps.nationalGovernmentRepository.findNationalGovernmentByElectricitySpotMarket(esm)
- .getMinNationalCo2PriceTrend().getValue(futureTimePoint);
+ double nationalCo2MinPriceinFutureTick = reps.nationalGovernmentRepository
+ .findNationalGovernmentByElectricitySpotMarket(esm).getMinNationalCo2PriceTrend()
+ .getValue(futureTimePoint);
double co2PriceInCountry = 0d;
if (expectedCO2Price > nationalCo2MinPriceinFutureTick) {
co2PriceInCountry = expectedCO2Price;
@@ -543,8 +569,8 @@ public Map predictFuelPrices(long numberOfYearsBacklookingFor
// Find Clearing Points for the last 5 years (counting current year
// as one of the last 5 years).
Iterable cps = reps.clearingPointRepository
- .findAllClearingPointsForSubstanceTradedOnCommodityMarkesAndTimeRange(substance, getCurrentTick()
- - (numberOfYearsBacklookingForForecasting - 1), getCurrentTick(), false);
+ .findAllClearingPointsForSubstanceTradedOnCommodityMarkesAndTimeRange(substance,
+ getCurrentTick() - (numberOfYearsBacklookingForForecasting - 1), getCurrentTick(), false);
// logger.warn("{}, {}",
// getCurrentTick()-(agent.getNumberOfYearsBacklookingForForecasting()-1),
// getCurrentTick());
@@ -557,11 +583,10 @@ public Map predictFuelPrices(long numberOfYearsBacklookingFor
}
double forecast = gtr.predict(futureTimePoint);
if (Double.isNaN(forecast)) {
- expectedFuelPrices.put(
- substance,
+ expectedFuelPrices.put(substance,
reps.clearingPointRepositoryOld.findClearingPointForMarketAndTime(
reps.marketRepository.findFirstMarketBySubstance(substance), getCurrentTick(), false)
- .getPrice());
+ .getPrice());
} else {
expectedFuelPrices.put(substance, forecast);
}
diff --git a/emlab-generation/src/main/java/emlab/gen/role/DecarbonizationModelRole.java b/emlab-generation/src/main/java/emlab/gen/role/DecarbonizationModelRole.java
index 5dbe6f1a..f08f5815 100644
--- a/emlab-generation/src/main/java/emlab/gen/role/DecarbonizationModelRole.java
+++ b/emlab-generation/src/main/java/emlab/gen/role/DecarbonizationModelRole.java
@@ -1,12 +1,12 @@
/*******************************************************************************
* Copyright 2012 the original author or authors.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -31,16 +31,21 @@
import emlab.gen.domain.agent.StrategicReserveOperator;
import emlab.gen.domain.agent.TargetInvestor;
import emlab.gen.domain.market.CommodityMarket;
+import emlab.gen.domain.market.capacity.CapacityMarket;
import emlab.gen.domain.market.electricity.ElectricitySpotMarket;
+import emlab.gen.domain.policy.renewablesupport.RenewableSupportSchemeTender;
import emlab.gen.repository.Reps;
+import emlab.gen.role.capacitymarket.SimpleCapacityMarketMainRole;
import emlab.gen.role.capacitymechanisms.ProcessAcceptedPowerPlantDispatchRoleinSR;
import emlab.gen.role.capacitymechanisms.StrategicReserveOperatorRole;
import emlab.gen.role.co2policy.MarketStabilityReserveRole;
import emlab.gen.role.co2policy.RenewableAdaptiveCO2CapRole;
+import emlab.gen.role.investment.DismantlePowerPlantOperationalLossRole;
import emlab.gen.role.investment.DismantlePowerPlantPastTechnicalLifetimeRole;
import emlab.gen.role.investment.GenericInvestmentRole;
import emlab.gen.role.market.ClearCommodityMarketRole;
import emlab.gen.role.market.ClearIterativeCO2AndElectricitySpotMarketTwoCountryRole;
+import emlab.gen.role.market.CreatingFinancialReports;
import emlab.gen.role.market.DetermineResidualLoadCurvesForTwoCountriesRole;
import emlab.gen.role.market.ProcessAcceptedBidsRole;
import emlab.gen.role.market.ProcessAcceptedPowerPlantDispatchRole;
@@ -56,6 +61,7 @@
import emlab.gen.role.operating.PayCO2TaxRole;
import emlab.gen.role.operating.PayForLoansRole;
import emlab.gen.role.operating.PayOperatingAndMaintainanceCostsRole;
+import emlab.gen.role.tender.TenderMainRole;
/**
* Main model role.
@@ -71,6 +77,8 @@ public class DecarbonizationModelRole extends AbstractRole
@Autowired
private PayCO2AuctionRole payCO2AuctionRole;
@Autowired
+ private TenderMainRole tenderMainRole;
+ @Autowired
private GenericInvestmentRole genericInvestmentRole;
@Autowired
private SubmitOffersToElectricitySpotMarketRole submitOffersToElectricitySpotMarketRole;
@@ -107,11 +115,17 @@ public class DecarbonizationModelRole extends AbstractRole
@Autowired
private ProcessAcceptedPowerPlantDispatchRoleinSR acceptedPowerPlantDispatchRoleinSR;
@Autowired
+ private DismantlePowerPlantOperationalLossRole dismantlePowerPlantOperationalLossRole;
+ @Autowired
private RenewableAdaptiveCO2CapRole renewableAdaptiveCO2CapRole;
@Autowired
MarketStabilityReserveRole marketStabilityReserveRole;
@Autowired
private DetermineResidualLoadCurvesForTwoCountriesRole determineResidualLoadCurve;
+ @Autowired
+ private SimpleCapacityMarketMainRole simpleCapacityMarketMainRole;
+ @Autowired
+ private CreatingFinancialReports creatingFinancialReports;
@Autowired
Reps reps;
@@ -143,20 +157,42 @@ public void act(DecarbonizationModel model) {
if (model.isRealRenewableDataImplemented())
determineResidualLoadCurve.act(model);
- logger.warn(" 0. Dismantling & paying loans");
- for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
- dismantlePowerPlantRole.act(producer);
- payForLoansRole.act(producer);
- // producer.act(dismantlePowerPlantRole);
- // producer.act(payForLoansRole);
- }
+ // logger.warn(" 0. Dismantling & paying loans");
+ // for (EnergyProducer producer :
+ // reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
+ // dismantlePowerPlantRole.act(producer);
+ // payForLoansRole.act(producer);
+ // producer.act(dismantlePowerPlantRole);
+ // producer.act(payForLoansRole);
+ // }
/*
* Determine fuel mix of power plants
*/
Timer timerMarket = new Timer();
timerMarket.start();
+
+ logger.warn(" 0b. Dismantling");
+ timerMarket.reset();
+ timerMarket.start();
+ for (ElectricitySpotMarket market : reps.marketRepository.findAllElectricitySpotMarketsAsList()) {
+ dismantlePowerPlantOperationalLossRole.act(market);
+ }
+ timerMarket.stop();
+ logger.warn(" took: {} seconds.", timerMarket.seconds());
+
+ logger.warn(" 0c. Paying loans");
+ timerMarket.reset();
+ timerMarket.start();
+ for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
+ payForLoansRole.act(producer);
+ }
+ timerMarket.stop();
+ logger.warn(" took: {} seconds.", timerMarket.seconds());
+
logger.warn(" 1. Determining fuel mix");
+ timerMarket.reset();
+ timerMarket.start();
for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
determineFuelMixRole.act(producer);
// producer.act(determineFuelMixRole);
@@ -164,6 +200,26 @@ public void act(DecarbonizationModel model) {
timerMarket.stop();
logger.warn(" took: {} seconds.", timerMarket.seconds());
+ /*
+ * Run Simple Capacity Market (start from tick 1, due to initialization
+ * requirements- it needs values (revenues from electricity spot market)
+ * from previous tick
+ */
+
+ if ((getCurrentTick() > 0) && (model.isSimpleCapacityMarketEnabled())) {
+ timerMarket.reset();
+ timerMarket.start();
+ logger.warn(" 2a. Run Simple Capacity Market");
+ for (CapacityMarket market : reps.capacityMarketRepository.findAll()) {
+ simpleCapacityMarketMainRole.act(market);
+ }
+
+ // exportLimiterRole.act(model);
+
+ timerMarket.stop();
+ logger.warn(" took: {} seconds.", timerMarket.seconds());
+ }
+
/*
* Submit and select long-term electricity contracts
*/
@@ -171,7 +227,7 @@ public void act(DecarbonizationModel model) {
if (model.isLongTermContractsImplemented()) {
timerMarket.reset();
timerMarket.start();
- logger.warn(" 2. Submit and select long-term electricity contracts");
+ logger.warn(" 2b. Submit and select long-term electricity contracts");
for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
submitLongTermElectricityContractsRole.act(producer);
// producer.act(submitLongTermElectricityContractsRole);
@@ -185,8 +241,21 @@ public void act(DecarbonizationModel model) {
logger.warn(" took: {} seconds.", timerMarket.seconds());
}
+ // timerMarket.reset();
+ // timerMarket.start();
+ // logger.warn(" 2b. Creating market forecast");
+ //
+ // clearIterativeCO2AndElectricitySpotMarketTwoCountryRole
+ // .makeCentralElectricityMarketForecastForTimeStep(getCurrentTick() +
+ // model.getCentralForecastingYear());
+ //
+ // logger.warn(" took: {} seconds.", timerMarket.seconds());
+ //
+ // timerMarket.reset();
+
/*
- * Clear electricity spot and CO2 markets and determine also the commitment of powerplants.
+ * Clear electricity spot and CO2 markets and determine also the
+ * commitment of powerplants.
*/
timerMarket.reset();
timerMarket.start();
@@ -301,6 +370,52 @@ public void act(DecarbonizationModel model) {
timerMarket.stop();
logger.warn(" took: {} seconds.", timerMarket.seconds());
+ logger.warn(" 6.b) Creating power plant financial reports.");
+ Timer financialReports = new Timer();
+ financialReports.start();
+
+ creatingFinancialReports.act(model);
+
+ financialReports.stop();
+ logger.warn(" took: {} seconds.", financialReports.seconds());
+
+ /*
+ * RENEWABLE TENDER
+ */
+
+ if (model.isRenewableTenderSchemeImplemented()) {
+ logger.warn(" 6c Running Renewable Tender Scheme");
+ for (RenewableSupportSchemeTender scheme : reps.renewableSupportSchemeTenderRepository.findAll()) {
+ tenderMainRole.act(scheme);
+ }
+ timerMarket.stop();
+ logger.warn(" took: {} seconds.", timerMarket.seconds());
+ }
+
+ // /*
+ // * Run Simple Capacity Market (start from tick 1, due to
+ // initialization
+ // * requirements- it needs values (revenues from electricity spot
+ // market)
+ // * from previous tick
+ // */
+ //
+ // if ((getCurrentTick() > 0) &&
+ // (model.isSimpleCapacityMarketEnabled())) {
+ // timerMarket.reset();
+ // timerMarket.start();
+ // logger.warn(" 2a. Run Simple Capacity Market");
+ // for (CapacityMarket market : reps.capacityMarketRepository.findAll())
+ // {
+ // simpleCapacityMarketMainRole.act(market);
+ // }
+ //
+ // // exportLimiterRole.act(model);
+ //
+ // timerMarket.stop();
+ // logger.warn(" took: {} seconds.", timerMarket.seconds());
+ // }
+
logger.warn(" 7. Investing");
Timer timerInvest = new Timer();
timerInvest.start();
@@ -335,7 +450,7 @@ public void act(DecarbonizationModel model) {
// agentspring.simulation.Schedule.getSchedule().stop();
// }
- logger.warn(" 7. Reassign LTCs");
+ logger.warn(" 7.5. Reassign LTCs");
timerMarket.reset();
timerMarket.start();
for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
@@ -363,6 +478,8 @@ public void act(DecarbonizationModel model) {
reps.powerPlantDispatchPlanRepository.delete(reps.powerPlantDispatchPlanRepository
.findAllPowerPlantDispatchPlansForTime(getCurrentTick() + model.getCentralForecastingYear() - 1,
true));
+ reps.financialPowerPlantReportRepository.delete(reps.financialPowerPlantReportRepository
+ .findAllFinancialPowerPlantReportsForTime(getCurrentTick() - 5 - model.getDeletionAge()));
timerMarket.stop();
logger.warn(" took: {} seconds.", timerMarket.seconds());
}
diff --git a/emlab-generation/src/main/java/emlab/gen/role/DecarbonizationModelRole.java.orig b/emlab-generation/src/main/java/emlab/gen/role/DecarbonizationModelRole.java.orig
new file mode 100644
index 00000000..7adff2ca
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/role/DecarbonizationModelRole.java.orig
@@ -0,0 +1,498 @@
+/*******************************************************************************
+ * Copyright 2012 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.role;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.neo4j.support.Neo4jTemplate;
+import org.springframework.transaction.annotation.Transactional;
+
+import agentspring.role.AbstractRole;
+import agentspring.role.Role;
+import agentspring.role.ScriptComponent;
+import cern.colt.Timer;
+import emlab.gen.domain.agent.CommoditySupplier;
+import emlab.gen.domain.agent.DecarbonizationModel;
+import emlab.gen.domain.agent.EnergyConsumer;
+import emlab.gen.domain.agent.EnergyProducer;
+import emlab.gen.domain.agent.Government;
+import emlab.gen.domain.agent.StrategicReserveOperator;
+import emlab.gen.domain.market.CommodityMarket;
+import emlab.gen.domain.market.capacity.CapacityMarket;
+import emlab.gen.domain.market.electricity.ElectricitySpotMarket;
+import emlab.gen.domain.policy.renewablesupport.RenewableSupportScheme;
+import emlab.gen.repository.Reps;
+import emlab.gen.role.capacitymarket.ExportLimiterRole;
+import emlab.gen.role.capacitymarket.SimpleCapacityMarketMainRole;
+import emlab.gen.role.capacitymechanisms.ProcessAcceptedPowerPlantDispatchRoleinSR;
+import emlab.gen.role.capacitymechanisms.StrategicReserveOperatorRole;
+import emlab.gen.role.co2policy.MarketStabilityReserveRole;
+import emlab.gen.role.co2policy.RenewableAdaptiveCO2CapRole;
+import emlab.gen.role.investment.DismantlePowerPlantOperationalLossRole;
+import emlab.gen.role.investment.DismantlePowerPlantPastTechnicalLifetimeRole;
+import emlab.gen.role.investment.GenericInvestmentRole;
+import emlab.gen.role.market.ClearCommodityMarketRole;
+import emlab.gen.role.market.ClearIterativeCO2AndElectricitySpotMarketTwoCountryRole;
+<<<<<<< HEAD
+=======
+import emlab.gen.role.market.CreatingFinancialReports;
+>>>>>>> Jorn/feature/historicalCVar
+import emlab.gen.role.market.DetermineResidualLoadCurvesForTwoCountriesRole;
+import emlab.gen.role.market.ProcessAcceptedBidsRole;
+import emlab.gen.role.market.ProcessAcceptedPowerPlantDispatchRole;
+import emlab.gen.role.market.ReassignPowerPlantsToLongTermElectricityContractsRole;
+import emlab.gen.role.market.ReceiveLongTermContractPowerRevenuesRole;
+import emlab.gen.role.market.SelectLongTermElectricityContractsRole;
+import emlab.gen.role.market.SubmitBidsToCommodityMarketRole;
+import emlab.gen.role.market.SubmitLongTermElectricityContractsRole;
+import emlab.gen.role.market.SubmitOffersToCommodityMarketRole;
+import emlab.gen.role.market.SubmitOffersToElectricitySpotMarketRole;
+import emlab.gen.role.operating.DetermineFuelMixRole;
+import emlab.gen.role.operating.PayCO2AuctionRole;
+import emlab.gen.role.operating.PayCO2TaxRole;
+import emlab.gen.role.operating.PayForLoansRole;
+import emlab.gen.role.operating.PayOperatingAndMaintainanceCostsRole;
+import emlab.gen.role.renewablesupport.FeedInPremiumRole;
+
+/**
+ * Main model role.
+ *
+ * @author alfredas, ejlchappin, jcrichstein
+ *
+ */
+@ScriptComponent
+public class DecarbonizationModelRole extends AbstractRole implements Role {
+
+ @Autowired
+ private PayCO2TaxRole payCO2TaxRole;
+ @Autowired
+ private PayCO2AuctionRole payCO2AuctionRole;
+ @Autowired
+ private GenericInvestmentRole genericInvestmentRole;
+ @Autowired
+ private SubmitOffersToElectricitySpotMarketRole submitOffersToElectricitySpotMarketRole;
+ @Autowired
+ private ClearCommodityMarketRole clearCommodityMarketRole;
+ @Autowired
+ private SubmitBidsToCommodityMarketRole submitBidsToCommodityMarketRole;
+ @Autowired
+ private SubmitOffersToCommodityMarketRole submitOffersToCommodityMarketRole;
+ @Autowired
+ private SubmitLongTermElectricityContractsRole submitLongTermElectricityContractsRole;
+ @Autowired
+ private SelectLongTermElectricityContractsRole selectLongTermElectricityContractsRole;
+ @Autowired
+ private DismantlePowerPlantPastTechnicalLifetimeRole dismantlePowerPlantRole;
+ @Autowired
+ private ReassignPowerPlantsToLongTermElectricityContractsRole reassignPowerPlantsToLongTermElectricityContractsRole;
+ @Autowired
+ private ClearIterativeCO2AndElectricitySpotMarketTwoCountryRole clearIterativeCO2AndElectricitySpotMarketTwoCountryRole;
+ @Autowired
+ private DetermineFuelMixRole determineFuelMixRole;
+ @Autowired
+ private ReceiveLongTermContractPowerRevenuesRole receiveLongTermContractPowerRevenuesRole;
+ @Autowired
+ private ProcessAcceptedPowerPlantDispatchRole processAcceptedPowerPlantDispatchRole;
+ @Autowired
+ private ProcessAcceptedBidsRole processAcceptedBidsRole;
+ @Autowired
+ private PayForLoansRole payForLoansRole;
+ @Autowired
+ private PayOperatingAndMaintainanceCostsRole payOperatingAndMaintainanceCostsRole;
+ @Autowired
+ private StrategicReserveOperatorRole strategicReserveOperatorRole;
+ @Autowired
+ private ProcessAcceptedPowerPlantDispatchRoleinSR acceptedPowerPlantDispatchRoleinSR;
+ @Autowired
+ private DismantlePowerPlantOperationalLossRole dismantlePowerPlantOperationalLossRole;
+ @Autowired
+ private RenewableAdaptiveCO2CapRole renewableAdaptiveCO2CapRole;
+ @Autowired
+ MarketStabilityReserveRole marketStabilityReserveRole;
+ @Autowired
+ private DetermineResidualLoadCurvesForTwoCountriesRole determineResidualLoadCurve;
+ @Autowired
+<<<<<<< HEAD
+ private SimpleCapacityMarketMainRole simpleCapacityMarketMainRole;
+ @Autowired
+ private ExportLimiterRole exportLimiterRole;
+ @Autowired
+ private FeedInPremiumRole feedInPremiumRole;
+=======
+ private CreatingFinancialReports creatingFinancialReports;
+>>>>>>> Jorn/feature/historicalCVar
+
+ @Autowired
+ Reps reps;
+
+ @Autowired
+ Neo4jTemplate template;
+
+ /**
+ * Main model script. Executes other roles in the right sequence.
+ */
+ @Override
+ public void act(DecarbonizationModel model) {
+
+ if (getCurrentTick() > model.getSimulationLength() && model.isExitSimulationAfterSimulationLength()) {
+ logger.warn("Simulation is terminating!!!");
+ // agentspring.simulation.Schedule.getSchedule().stop();
+ System.exit(0);
+ }
+
+ if (getCurrentTick() >= model.getSimulationLength()) {
+ agentspring.simulation.Schedule.getSchedule().stop();
+ }
+
+ logger.warn("***** STARTING TICK {} *****", getCurrentTick());
+ Timer timer = new Timer();
+ timer.start();
+
+ logger.warn(" 0a. Determing load duration curves.");
+ if (model.isRealRenewableDataImplemented())
+ determineResidualLoadCurve.act(model);
+
+<<<<<<< HEAD
+ // logger.warn(" 0. Dismantling & paying loans");
+ // for (EnergyProducer producer :
+ // reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
+ // dismantlePowerPlantRole.act(producer);
+ // payForLoansRole.act(producer);
+ // producer.act(dismantlePowerPlantRole);
+ // producer.act(payForLoansRole);
+ // }
+=======
+ logger.warn(" 0. Dismantling & paying loans");
+ for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
+ dismantlePowerPlantRole.act(producer);
+ payForLoansRole.act(producer);
+ // producer.act(dismantlePowerPlantRole);
+ // producer.act(payForLoansRole);
+ }
+>>>>>>> Jorn/feature/historicalCVar
+
+ /*
+ * Determine fuel mix of power plants
+ */
+ Timer timerMarket = new Timer();
+ timerMarket.start();
+
+ logger.warn(" 0b. Dismantling");
+ timerMarket.reset();
+ timerMarket.start();
+ for (ElectricitySpotMarket market : reps.marketRepository.findAllElectricitySpotMarketsAsList()) {
+ dismantlePowerPlantOperationalLossRole.act(market);
+ }
+ timerMarket.stop();
+ logger.warn(" took: {} seconds.", timerMarket.seconds());
+
+ logger.warn(" 0c. Paying loans");
+ timerMarket.reset();
+ timerMarket.start();
+ for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
+ payForLoansRole.act(producer);
+ }
+ timerMarket.stop();
+ logger.warn(" took: {} seconds.", timerMarket.seconds());
+
+ logger.warn(" 1. Determining fuel mix");
+ timerMarket.reset();
+ timerMarket.start();
+ for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
+ determineFuelMixRole.act(producer);
+ // producer.act(determineFuelMixRole);
+ }
+ timerMarket.stop();
+ logger.warn(" took: {} seconds.", timerMarket.seconds());
+
+ /*
+ * Run Simple Capacity Market (start from tick 1, due to initialization
+ * requirements- it needs values (revenues from electricity spot market)
+ * from previous tick
+ */
+
+ if ((getCurrentTick() > 0) && (model.isSimpleCapacityMarketEnabled())) {
+ timerMarket.reset();
+ timerMarket.start();
+ logger.warn(" 2a. Run Simple Capacity Market");
+ for (CapacityMarket market : reps.capacityMarketRepository.findAll()) {
+ simpleCapacityMarketMainRole.act(market);
+ }
+
+ // exportLimiterRole.act(model);
+
+ timerMarket.stop();
+ logger.warn(" took: {} seconds.", timerMarket.seconds());
+ }
+
+ /*
+ * Submit and select long-term electricity contracts
+ */
+
+ if (model.isLongTermContractsImplemented()) {
+ timerMarket.reset();
+ timerMarket.start();
+ logger.warn(" 2b. Submit and select long-term electricity contracts");
+ for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
+ submitLongTermElectricityContractsRole.act(producer);
+ // producer.act(submitLongTermElectricityContractsRole);
+ }
+
+ for (EnergyConsumer consumer : reps.genericRepository.findAllAtRandom(EnergyConsumer.class)) {
+ selectLongTermElectricityContractsRole.act(consumer);
+ // consumer.act(selectLongTermElectricityContractsRole);
+ }
+ timerMarket.stop();
+ logger.warn(" took: {} seconds.", timerMarket.seconds());
+ }
+
+<<<<<<< HEAD
+ // timerMarket.reset();
+ // timerMarket.start();
+ // logger.warn(" 2c. Creating market forecast");
+ //
+ // clearIterativeCO2AndElectricitySpotMarketTwoCountryRole
+ // .makeCentralElectricityMarketForecastForTimeStep(getCurrentTick() +
+ // model.getCentralForecastingYear());
+ //
+ // logger.warn(" took: {} seconds.", timerMarket.seconds());
+ //
+ // timerMarket.reset();
+
+=======
+>>>>>>> Jorn/feature/historicalCVar
+ /*
+ * Clear electricity spot and CO2 markets and determine also the commitment of powerplants.
+ */
+ timerMarket.reset();
+ timerMarket.start();
+ logger.warn(" 3. Submitting offers to market");
+ for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
+ submitOffersToElectricitySpotMarketRole.act(producer);
+ // producer.act(submitOffersToElectricitySpotMarketRole);
+ }
+ timerMarket.stop();
+ logger.warn(" took: {} seconds.", timerMarket.seconds());
+
+ /*
+ * Contract strategic reserve volume and set strategic reserve dispatch
+ * price
+ */
+ for (StrategicReserveOperator strategicReserveOperator : reps.strategicReserveOperatorRepository.findAll()) {
+ logger.warn(" 3a. Contracting Strategic Reserve in " + strategicReserveOperator.getZone().getName());
+ strategicReserveOperatorRole.act(strategicReserveOperator);
+ }
+
+ Government government = template.findAll(Government.class).iterator().next();
+ if (getCurrentTick() > 0 && government.getCo2CapTrend() != null && government.isActivelyAdjustingTheCO2Cap()) {
+ logger.warn("Lowering cap according to RES installations");
+ renewableAdaptiveCO2CapRole.act(government);
+ }
+
+ if (model.isStabilityReserveIsActive() && getCurrentTick() == 0) {
+ government.getStabilityReserveAddingMinimumTrend().getValue(0);
+ government.getStabilityReserveAddingPercentageTrend().getValue(0);
+ government.getStabilityReserveLowerTriggerTrend().getValue(0);
+ government.getStabilityReserveReleaseQuantityTrend().getValue(0);
+ government.getStabilityReserveUpperTriggerTrend().getValue(0);
+ }
+ if (getCurrentTick() >= model.getStabilityReserveFirstYearOfOperation() && model.isStabilityReserveIsActive()) {
+ logger.warn("3b. CO2 Market Stability Reserve");
+ marketStabilityReserveRole.act(government);
+ }
+
+ timerMarket.reset();
+ timerMarket.start();
+ logger.warn(" 4. Clearing electricity spot and CO2 markets");
+ clearIterativeCO2AndElectricitySpotMarketTwoCountryRole.act(model);
+ // model.act(clearIterativeCO2AndElectricitySpotMarketTwoCountryRole);
+ timerMarket.stop();
+ logger.warn(" took: {} seconds.", timerMarket.seconds());
+
+ timerMarket.reset();
+ timerMarket.start();
+ for (EnergyProducer producer : reps.genericRepository.findAll(EnergyProducer.class)) {
+ receiveLongTermContractPowerRevenuesRole.act(producer);
+ // producer.act(receiveLongTermContractPowerRevenuesRole);
+ }
+ for (ElectricitySpotMarket electricitySpotMarket : reps.marketRepository.findAllElectricitySpotMarkets()) {
+ processAcceptedPowerPlantDispatchRole.act(electricitySpotMarket);
+ // electricitySpotMarket.act(processAcceptedPowerPlantDispatchRole);
+ }
+ for (StrategicReserveOperator strategicReserveOperator : reps.strategicReserveOperatorRepository.findAll()) {
+ acceptedPowerPlantDispatchRoleinSR.act(strategicReserveOperator);
+ }
+ // logger.warn(" 4. Processing Strategic Reserve Payment ");
+ timerMarket.stop();
+ logger.warn(" paying took: {} seconds.", timerMarket.seconds());
+ /*
+ * Maintenance and CO2
+ */
+ logger.warn(" 5. Paying for maintenance & co2");
+ timerMarket.reset();
+ timerMarket.start();
+ for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
+ // do accounting
+ payOperatingAndMaintainanceCostsRole.act(producer);
+ // producer.act(payOperatingAndMaintainanceCostsRole);
+ // pay tax
+ payCO2TaxRole.act(producer);
+ // producer.act(payCO2TaxRole);
+ // pay for CO2 auction only if CO2 trading
+ if (model.isCo2TradingImplemented()) {
+ payCO2AuctionRole.act(producer);
+ // producer.act(payCO2AuctionRole);
+ }
+ }
+ timerMarket.stop();
+ logger.warn(" took: {} seconds.", timerMarket.seconds());
+
+ /*
+ * COMMODITY MARKETS
+ */
+ logger.warn(" 6. Purchasing commodities");
+ timerMarket.reset();
+ timerMarket.start();
+
+ // SUPPLIER (supply for commodity markets)
+ for (CommoditySupplier supplier : reps.genericRepository.findAllAtRandom(CommoditySupplier.class)) {
+ // 1) first submit the offers
+ submitOffersToCommodityMarketRole.act(supplier);
+ // supplier.act(submitOffersToCommodityMarketRole);
+ }
+
+ // PRODUCER (demand for commodity markets)
+ for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
+ // 2) submit bids
+ submitBidsToCommodityMarketRole.act(producer);
+ // producer.act(submitBidsToCommodityMarketRole);
+ }
+
+ for (CommodityMarket market : reps.genericRepository.findAllAtRandom(CommodityMarket.class)) {
+ clearCommodityMarketRole.act(market);
+ processAcceptedBidsRole.act(market);
+ // market.act(clearCommodityMarketRole);
+ // market.act(processAcceptedBidsRole);
+ }
+ timerMarket.stop();
+ logger.warn(" took: {} seconds.", timerMarket.seconds());
+
+<<<<<<< HEAD
+ if (model.isFeedInPremiumImplemented()) {
+ logger.warn(" 6a. Run Feed In Premium Scheme");
+ for (RenewableSupportScheme scheme : reps.renewableSupportSchemeRepository.findAll()) {
+ feedInPremiumRole.act(scheme);
+ }
+ timerMarket.stop();
+ logger.warn(" took: {} seconds.", timerMarket.seconds());
+ }
+=======
+ logger.warn(" 6.b) Creating power plant financial reports.");
+ Timer financialReports = new Timer();
+ financialReports.start();
+
+ creatingFinancialReports.act(model);
+
+ financialReports.stop();
+ logger.warn(" took: {} seconds.", financialReports.seconds());
+>>>>>>> Jorn/feature/historicalCVar
+
+ logger.warn(" 7. Investing");
+ Timer timerInvest = new Timer();
+ timerInvest.start();
+
+ logger.warn("\t Private investment");
+ if (getCurrentTick() > 1) {
+ boolean someOneStillWillingToInvest = true;
+ while (someOneStillWillingToInvest) {
+ someOneStillWillingToInvest = false;
+ for (EnergyProducer producer : reps.energyProducerRepository
+ .findAllEnergyProducersExceptForRenewableTargetInvestorsAtRandom()) {
+ // invest in new plants
+ if (producer.isWillingToInvest()) {
+ genericInvestmentRole.act(producer);
+ // producer.act(investInPowerGenerationTechnologiesRole);
+ someOneStillWillingToInvest = true;
+ }
+ }
+ }
+ resetWillingnessToInvest();
+ }
+<<<<<<< HEAD
+ // logger.warn("\t subsidized investment.");
+ // for (TargetInvestor targetInvestor :
+ // template.findAll(TargetInvestor.class)) {
+ // genericInvestmentRole.act(targetInvestor);
+ // }
+=======
+ logger.warn("\t subsidized investment.");
+ for (TargetInvestor targetInvestor : template.findAll(TargetInvestor.class)) {
+ genericInvestmentRole.act(targetInvestor);
+ }
+>>>>>>> Jorn/feature/historicalCVar
+ timerInvest.stop();
+ logger.warn(" took: {} seconds.", timerInvest.seconds());
+
+ if (model.isLongTermContractsImplemented()) { // if (getCurrentTick() >=
+ // model.getSimulationLength())
+ // {
+ // agentspring.simulation.Schedule.getSchedule().stop();
+ // }
+
+ logger.warn(" 7. Reassign LTCs");
+ timerMarket.reset();
+ timerMarket.start();
+ for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
+ reassignPowerPlantsToLongTermElectricityContractsRole.act(producer);
+ // producer.act(reassignPowerPlantsToLongTermElectricityContractsRole);
+ }
+ timerMarket.stop();
+ logger.warn(" took: {} seconds.", timerMarket.seconds());
+ }
+
+ /*
+ * Deletion of old nodes
+ */
+
+ if (model.isDeletionOldPPDPBidsAndCashFlowsEnabled() && (getCurrentTick() - model.getDeletionAge() >= 0)) {
+ timerMarket.reset();
+ timerMarket.start();
+ logger.warn(" 8. Delete old nodes in year {}.", (getCurrentTick() - model.getDeletionAge()));
+ reps.bidRepository.delete(reps.bidRepository.findAllBidsForForTime(getCurrentTick()
+ - model.getDeletionAge()));
+ reps.cashFlowRepository.delete(reps.cashFlowRepository.findAllCashFlowsForForTime(getCurrentTick()
+ - model.getDeletionAge()));
+ reps.powerPlantRepository.delete(reps.powerPlantRepository
+ .findAllPowerPlantsDismantledBeforeTick(getCurrentTick() - 1 - model.getDeletionAge()));
+ reps.powerPlantDispatchPlanRepository.delete(reps.powerPlantDispatchPlanRepository
+ .findAllPowerPlantDispatchPlansForTime(getCurrentTick() + model.getCentralForecastingYear() - 1,
+ true));
+ reps.financialPowerPlantReportRepository.delete(reps.financialPowerPlantReportRepository
+ .findAllFinancialPowerPlantReportsForTime(getCurrentTick() - 5 - model.getDeletionAge()));
+ timerMarket.stop();
+ logger.warn(" took: {} seconds.", timerMarket.seconds());
+ }
+
+ timer.stop();
+ logger.warn("Tick {} took {} seconds.", getCurrentTick(), timer.seconds());
+ }
+
+ @Transactional
+ private void resetWillingnessToInvest() {
+ for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
+ producer.setWillingToInvest(true);
+ }
+ }
+}
diff --git a/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/ClearCapacityMarketRole.java b/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/ClearCapacityMarketRole.java
new file mode 100644
index 00000000..2c661a8f
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/ClearCapacityMarketRole.java
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.role.capacitymarket;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.neo4j.support.Neo4jTemplate;
+import org.springframework.transaction.annotation.Transactional;
+
+import agentspring.role.AbstractRole;
+import agentspring.role.Role;
+import agentspring.role.RoleComponent;
+import emlab.gen.domain.agent.Regulator;
+import emlab.gen.domain.market.Bid;
+import emlab.gen.domain.market.capacity.CapacityClearingPoint;
+import emlab.gen.domain.market.capacity.CapacityDispatchPlan;
+import emlab.gen.domain.market.capacity.CapacityMarket;
+import emlab.gen.repository.Reps;
+
+/**
+ * @author Kaveri
+ *
+ */
+
+@RoleComponent
+public class ClearCapacityMarketRole extends AbstractRole implements Role {
+
+ // CapacityMarketRepository capacityMarketRepository;
+
+ @Autowired
+ Reps reps;
+
+ @Autowired
+ Neo4jTemplate template;
+
+ @Override
+ @Transactional
+ public void act(Regulator regulator) {
+
+ CapacityMarket market = new CapacityMarket();
+ market = reps.capacityMarketRepository.findCapacityMarketForZone(regulator.getZone());
+
+ Iterable sortedListofCDP = null;
+ sortedListofCDP = reps.capacityMarketRepository.findAllSortedCapacityDispatchPlansByTime(getCurrentTick());
+ double demand = 0d;
+ double sumofSupplyBidsAccepted = 0d;
+ double acceptedPrice = 0d;
+ boolean isTheMarketCleared = false;
+
+ // This epsilon is to account for rounding errors for java (only
+ // relevant for exact clearing)
+ double clearingEpsilon = 0.001d;
+
+ if (regulator.getDemandTarget() == 0) {
+ isTheMarketCleared = true;
+ acceptedPrice = 0;
+ }
+
+ for (CapacityDispatchPlan currentCDP : sortedListofCDP) {
+
+ if (currentCDP.getPrice() <= regulator.getCapacityMarketPriceCap()) {
+
+ demand = regulator.getDemandTarget()
+ * (1 - regulator.getReserveDemandLowerMargin())
+ + ((regulator.getCapacityMarketPriceCap() - currentCDP.getPrice())
+ * (regulator.getReserveDemandUpperMargin() + regulator.getReserveDemandLowerMargin()) * regulator
+ .getDemandTarget()) / regulator.getCapacityMarketPriceCap();
+
+ // logger.warn("Price of this cdp is " + currentCDP.getPrice());
+ // logger.warn("Demand at this cdp is " + demand);
+
+ if (isTheMarketCleared == false) {
+ if (demand - (sumofSupplyBidsAccepted + currentCDP.getAmount()) >= -clearingEpsilon) {
+ acceptedPrice = currentCDP.getPrice();
+ currentCDP.setStatus(Bid.ACCEPTED);
+ currentCDP.setAcceptedAmount(currentCDP.getAmount());
+ sumofSupplyBidsAccepted = sumofSupplyBidsAccepted + currentCDP.getAmount();
+ // logger.warn("Price of this cdp is " +
+ // currentCDP.getPrice());
+ // logger.warn("accepted price" + acceptedPrice);
+ }
+
+ else if (demand - (sumofSupplyBidsAccepted + currentCDP.getAmount()) < clearingEpsilon) {
+
+ currentCDP.setStatus(Bid.PARTLY_ACCEPTED);
+ currentCDP.setAcceptedAmount((sumofSupplyBidsAccepted - demand));
+ acceptedPrice = currentCDP.getPrice();
+ sumofSupplyBidsAccepted = sumofSupplyBidsAccepted + currentCDP.getAcceptedAmount();
+ isTheMarketCleared = true;
+
+ // logger.warn("accepted price" + acceptedPrice);
+
+ }
+
+ // else if (demand - sumofSupplyBidsAccepted <
+ // clearingEpsilon) {
+ // isTheMarketCleared = true;
+ // }
+ } else {
+ currentCDP.setStatus(Bid.FAILED);
+ currentCDP.setAcceptedAmount(0);
+ }
+
+ // logger.warn("Cumulatively Accepted Supply " +
+ // sumofSupplyBidsAccepted);
+ currentCDP.persist();
+
+ }
+
+ // logger.warn("Current CDP Price " + currentCDP.getPrice());
+ // logger.warn("Cumulatively accepted volume " +
+ // sumofSupplyBidsAccepted);
+ }
+ // logger.warn("Demand for the capacity market at tick {} is " + demand,
+ // getCurrentTick());
+
+ CapacityClearingPoint clearingPoint = new CapacityClearingPoint();
+ if (isTheMarketCleared == true) {
+ // sumofSupplyBidsAccepted = demand;
+ logger.warn("MARKET CLEARED at price" + acceptedPrice);
+ clearingPoint.setPrice(acceptedPrice);
+ clearingPoint.setVolume(sumofSupplyBidsAccepted);
+ clearingPoint.setTime(getCurrentTick());
+ clearingPoint.setCapacityMarket(market);
+ clearingPoint.persist();
+
+ logger.warn("Clearing point Price {} and volume " + clearingPoint.getVolume(), clearingPoint.getPrice());
+
+ } else {
+ acceptedPrice = regulator.getCapacityMarketPriceCap()
+ * (1 + ((regulator.getDemandTarget() * (1 - regulator.getReserveDemandLowerMargin()) - sumofSupplyBidsAccepted) / ((regulator
+ .getReserveDemandUpperMargin() + regulator.getReserveDemandLowerMargin()) * regulator
+ .getDemandTarget())));
+ clearingPoint.setPrice(max(regulator.getCapacityMarketPriceCap(), acceptedPrice));
+ clearingPoint.setVolume(sumofSupplyBidsAccepted);
+ clearingPoint.setTime(getCurrentTick());
+ clearingPoint.setCapacityMarket(market);
+ clearingPoint.persist();
+ logger.warn("MARKET UNCLEARED at price" + clearingPoint.getPrice());
+ logger.warn("Clearing point Price {} and volume " + clearingPoint.getVolume(), clearingPoint.getPrice());
+
+ }
+ // clearingPoint.persist();
+ // logger.warn("is the market cleared? " + isTheMarketCleared);
+ // logger.warn("Clearing point Price" + clearingPoint.getPrice());
+ // logger.warn("Clearing Point Volume" + clearingPoint.getVolume());
+
+ // VERIFICATION
+ double q2 = clearingPoint.getVolume();
+ double q1 = regulator.getDemandTarget()
+ * (1 - regulator.getReserveDemandLowerMargin())
+ + ((regulator.getCapacityMarketPriceCap() - clearingPoint.getPrice())
+ * (regulator.getReserveDemandUpperMargin() + regulator.getReserveDemandLowerMargin()) * regulator
+ .getDemandTarget()) / regulator.getCapacityMarketPriceCap();
+ if (q1 == q2) {
+ logger.warn("matches");
+ } else {
+ logger.warn("does not match");
+ }
+
+ }
+
+ /**
+ * @param capacityMarketPriceCap
+ * @param acceptedPrice
+ * @return
+ */
+ private double max(double capacityMarketPriceCap, double acceptedPrice) {
+ if (acceptedPrice >= capacityMarketPriceCap)
+ return capacityMarketPriceCap;
+ else
+ return acceptedPrice;
+ }
+
+}
\ No newline at end of file
diff --git a/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/ExportLimiterRole.java b/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/ExportLimiterRole.java
new file mode 100644
index 00000000..f1918169
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/ExportLimiterRole.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.role.capacitymarket;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.neo4j.support.Neo4jTemplate;
+import org.springframework.transaction.annotation.Transactional;
+
+import agentspring.role.AbstractRole;
+import agentspring.role.Role;
+import agentspring.role.RoleComponent;
+import emlab.gen.domain.agent.DecarbonizationModel;
+import emlab.gen.domain.gis.Zone;
+import emlab.gen.domain.market.capacity.CapacityMarket;
+import emlab.gen.domain.market.electricity.ElectricitySpotMarket;
+import emlab.gen.domain.technology.Interconnector;
+import emlab.gen.repository.Reps;
+
+/**
+ * @author Kaveri
+ *
+ */
+
+@RoleComponent
+public class ExportLimiterRole extends AbstractRole implements Role {
+
+ @Autowired
+ Reps reps;
+
+ @Autowired
+ Neo4jTemplate template;
+
+ @Override
+ @Transactional
+ public void act(DecarbonizationModel model) {
+
+ double initialInterconnectorCapacity = 0d;
+
+ // find all interconnectors
+ Interconnector interconnector = template.findAll(Interconnector.class).iterator().next();
+
+ // get initial interconnector capacity at tick 1 as capacity market is
+ // functional only from tick 1
+ if (getCurrentTick() == 1) {
+
+ initialInterconnectorCapacity = interconnector.getCapacity(getCurrentTick());
+ logger.warn("at tick 1 the interconnector capacity is" + initialInterconnectorCapacity);
+
+ }
+
+ // initialize interconnector capacity, irrespective of current tick, to
+ // initialInterconnectorCapacity
+ logger.warn("print capacity temp variable initialICcapacity" + initialInterconnectorCapacity);
+ logger.warn("interconnector capacity before setting " + interconnector.getCapacity(getCurrentTick()));
+ interconnector.setCapacity(initialInterconnectorCapacity);
+ logger.warn("interconnector capacity after setting " + interconnector.getCapacity(getCurrentTick()));
+ // loop through capacity markets and if supply < demand in any of the
+ // capacity market regions, set interconnector capacity = 0
+ for (CapacityMarket market : reps.capacityMarketRepository.findAll()) {
+ Zone zone = market.getZone();
+ logger.warn("zone" + zone);
+ ElectricitySpotMarket emarket = reps.marketRepository.findElectricitySpotMarketForZone(zone);
+
+ // double supply =
+ // reps.marketRepository.findTotalSupplyInElectricitySpotMarketForZone(zone);
+ double supply = reps.powerPlantRepository.calculatePeakCapacityOfOperationalPowerPlantsInMarket(emarket,
+ getCurrentTick());
+ logger.warn("Supply" + supply);
+ // double peakDemand =
+ // reps.marketRepository.findPeakDemandInElectricitySpotMarketForZone(zone);
+ double peakLoadforMarketNOtrend = reps.segmentLoadRepository.peakLoadbyZoneMarketandTime(zone, emarket);
+ double demandfactor = emarket.getDemandGrowthTrend().getValue(getCurrentTick());
+
+ double peakDemand = peakLoadforMarketNOtrend * demandfactor;
+ logger.warn("demand" + peakDemand);
+
+ if ((supply - peakDemand) < 0) {
+
+ interconnector.setCapacity(0);
+ logger.warn("interconnector capacity set to zero" + interconnector.getCapacity(getCurrentTick()));
+ }
+
+ }
+
+ }
+}
diff --git a/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/ForecastDemandRole.java b/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/ForecastDemandRole.java
new file mode 100644
index 00000000..9e3d1b0c
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/ForecastDemandRole.java
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.role.capacitymarket;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+import agentspring.role.AbstractRole;
+import agentspring.role.Role;
+import agentspring.role.RoleComponent;
+import emlab.gen.domain.agent.Regulator;
+import emlab.gen.domain.gis.Zone;
+import emlab.gen.domain.market.electricity.ElectricitySpotMarket;
+import emlab.gen.repository.Reps;
+import emlab.gen.util.GeometricTrendRegression;
+
+/**
+ * @author Kaveri
+ *
+ */
+@RoleComponent
+public class ForecastDemandRole extends AbstractRole implements Role {
+
+ @Autowired
+ Reps reps;
+
+ @Override
+ @Transactional
+ public void act(Regulator regulator) {
+ long capabilityYear = 0;
+ capabilityYear = getCurrentTick() + regulator.getTargetPeriod();
+
+ Zone zone = regulator.getZone();
+ ElectricitySpotMarket market = reps.marketRepository.findElectricitySpotMarketForZone(zone);
+
+ // double trend =
+ // market.getDemandGrowthTrend().getValue(getCurrentTick());
+ // double peakLoadforMarket = trend * peakLoadforMarketNOtrend;
+ // double reserveMargin = regulator.getReserveMargin();
+ // double demandTarget = peakLoadforMarket * (1 + reserveMargin);
+
+ // regulator.setDemandTarget(demandTarget);
+
+ /*
+ * // Computing Demand (the current year's demand is not considered for
+ * // regression, as it is forecasted. double expectedDemandFactor = 0d;
+ */
+
+ double expectedDemandFactor = 0d;
+ if (getCurrentTick() < 2) {
+
+ expectedDemandFactor = market.getDemandGrowthTrend().getValue(getCurrentTick());
+ } else {
+
+ GeometricTrendRegression gtr = new GeometricTrendRegression();
+ for (long time = getCurrentTick() - 1; time > getCurrentTick() - 1
+ - regulator.getNumberOfYearsLookingBackToForecastDemand()
+ && time >= 0; time = time - 1) {
+ gtr.addData(time, market.getDemandGrowthTrend().getValue(time));
+ }
+ expectedDemandFactor = gtr.predict(capabilityYear);
+ }
+ logger.warn("ExpectedDemandFactor for this tick: " + expectedDemandFactor);
+ logger.warn("demand factor " + market.getDemandGrowthTrend().getValue(getCurrentTick()));
+ // Calculate peak demand across all markets
+
+ double peakLoadforMarketNOtrend = reps.segmentLoadRepository.peakLoadbyZoneMarketandTime(zone, market);
+ double peakExpectedDemand = peakLoadforMarketNOtrend * expectedDemandFactor;
+
+ // Compute demand target by multiplying reserve margin double double
+ double demandTarget = peakExpectedDemand * (1 + regulator.getReserveMargin());
+
+ regulator.setDemandTarget(demandTarget);
+
+ }
+
+}
\ No newline at end of file
diff --git a/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/PaymentFromConsumerToProducerForCapacityRole.java b/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/PaymentFromConsumerToProducerForCapacityRole.java
new file mode 100644
index 00000000..11ddac1b
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/PaymentFromConsumerToProducerForCapacityRole.java
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.role.capacitymarket;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+import agentspring.role.Role;
+import agentspring.role.RoleComponent;
+import emlab.gen.domain.contract.CashFlow;
+import emlab.gen.domain.market.ClearingPoint;
+import emlab.gen.domain.market.capacity.CapacityDispatchPlan;
+import emlab.gen.domain.market.capacity.CapacityMarket;
+import emlab.gen.domain.market.electricity.ElectricitySpotMarket;
+import emlab.gen.repository.Reps;
+import emlab.gen.role.market.AbstractMarketRole;
+
+//import org.springframework.data.neo4j.annotation.NodeEntity;
+
+/**
+ * @author Kaveri
+ *
+ */
+@RoleComponent
+public class PaymentFromConsumerToProducerForCapacityRole extends AbstractMarketRole implements
+ Role {
+
+ @Autowired
+ Reps reps;
+
+ // CashFlow cash = new CashFlow();
+
+ @Override
+ @Transactional
+ public void act(CapacityMarket capacityMarket) {
+
+ for (CapacityDispatchPlan plan : reps.capacityMarketRepository.findAllAcceptedCapacityDispatchPlansForTime(
+ capacityMarket, getCurrentTick())) {
+
+ // logger.warn("Hi");
+ // logger.warn("cdp for plant" + plan.getPlant());
+
+ ClearingPoint capacityClearingPoint = reps.capacityMarketRepository
+ .findOneClearingPointForTimeAndCapacityMarket(getCurrentTick(), capacityMarket);
+
+ // logger.warn("capacity clearing point " +
+ // capacityClearingPoint.getPrice());
+ // double price = capacityClearingPoint.getPrice();
+ ElectricitySpotMarket esm = reps.marketRepository
+ .findElectricitySpotMarketForZone(capacityMarket.getZone());
+ // logger.warn("esmt " + esm.getName());
+
+ reps.nonTransactionalCreateRepository.createCashFlow(esm, plan.getBidder(), plan.getAcceptedAmount()
+ * capacityClearingPoint.getPrice(), CashFlow.SIMPLE_CAPACITY_MARKET, getCurrentTick(),
+ plan.getPlant());
+ // logger.warn("Cash flow from consumer {} to Producer {} of value {} "
+ // + plan.getAcceptedAmount()
+ // * capacityClearingPoint.getPrice(), plan.getBidder(),
+ // capacityMarket.getConsumer());
+ }
+
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see emlab.gen.role.market.AbstractMarketRole#getReps()
+ */
+ @Override
+ public Reps getReps() {
+
+ return reps;
+
+ }
+
+}
diff --git a/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/SimpleCapacityMarketMainRole.java b/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/SimpleCapacityMarketMainRole.java
new file mode 100644
index 00000000..047fcca5
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/SimpleCapacityMarketMainRole.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.role.capacitymarket;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+import agentspring.role.AbstractRole;
+import agentspring.role.Role;
+import agentspring.role.RoleComponent;
+import emlab.gen.domain.agent.EnergyProducer;
+import emlab.gen.domain.agent.Regulator;
+import emlab.gen.domain.market.capacity.CapacityMarket;
+import emlab.gen.repository.Reps;
+
+/**
+ * @author Kaveri
+ *
+ */
+
+@RoleComponent
+public class SimpleCapacityMarketMainRole extends AbstractRole implements Role {
+
+ @Autowired
+ Reps reps;
+
+ @Autowired
+ ForecastDemandRole forecastDemandRole;
+
+ @Autowired
+ SubmitCapacityBidToMarketRole submitCapacityBidToMarketRole;
+
+ @Autowired
+ ClearCapacityMarketRole clearCapacityMarketRole;
+
+ @Autowired
+ PaymentFromConsumerToProducerForCapacityRole paymentFromConsumerToProducerforCapacityRole;
+
+ @Override
+ @Transactional
+ public void act(CapacityMarket market) {
+
+ Regulator regulator = market.getRegulator();
+
+ // Forecast Demand
+ forecastDemandRole.act(regulator);
+ logger.warn("Forecast demand role run");
+
+ // Energy producers submit Bids to Capacity market
+ for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
+ submitCapacityBidToMarketRole.act(producer);
+ }
+ logger.warn("******************capacity bids submitted****************************");
+
+ // Clear capacity market
+ clearCapacityMarketRole.act(regulator);
+
+ logger.warn("************************Capacity Market cleared******************************");
+
+ // ensure cash flows
+ paymentFromConsumerToProducerforCapacityRole.act(market);
+
+ logger.warn("capacity payments made");
+ logger.warn("Capacity Market Main Role Completed once");
+
+ }
+
+}
diff --git a/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/SubmitCapacityBidToMarketRole.java b/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/SubmitCapacityBidToMarketRole.java
new file mode 100644
index 00000000..da47bda7
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/SubmitCapacityBidToMarketRole.java
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.role.capacitymarket;
+
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+import agentspring.role.Role;
+import agentspring.role.RoleComponent;
+import emlab.gen.domain.agent.EnergyProducer;
+import emlab.gen.domain.market.Bid;
+import emlab.gen.domain.market.capacity.CapacityDispatchPlan;
+import emlab.gen.domain.market.capacity.CapacityMarket;
+import emlab.gen.domain.market.electricity.ElectricitySpotMarket;
+import emlab.gen.domain.market.electricity.PowerPlantDispatchPlan;
+import emlab.gen.domain.market.electricity.Segment;
+import emlab.gen.domain.market.electricity.SegmentLoad;
+import emlab.gen.domain.technology.PowerPlant;
+import emlab.gen.repository.Reps;
+import emlab.gen.role.AbstractEnergyProducerRole;
+
+//import org.springframework.data.neo4j.annotation.NodeEntity;
+
+/**
+ * @author Kaveri
+ *
+ */
+
+@RoleComponent
+public class SubmitCapacityBidToMarketRole extends AbstractEnergyProducerRole implements
+ Role {
+
+ Logger logger = Logger.getLogger(SubmitCapacityBidToMarketRole.class);
+
+ @Autowired
+ Reps reps;
+
+ @Override
+ @Transactional
+ public void act(EnergyProducer producer) {
+ // logger.warn("***********Submitting Bid Role for Energy Producer ********"
+ // + producer.getName());
+
+ for (PowerPlant plant : reps.powerPlantRepository.findOperationalPowerPlantsByOwner(producer, getCurrentTick())) {
+
+ // logger.warn("Bid calculation for PowerPlant " + plant.getName());
+ // get market for the plant by zone
+ CapacityMarket market = reps.capacityMarketRepository.findCapacityMarketForZone(plant.getLocation()
+ .getZone());
+ if (market != null) {
+ // logger.warn("CapacityMarket is " + market.getName());
+
+ ElectricitySpotMarket eMarket = reps.marketRepository.findElectricitySpotMarketForZone(plant
+ .getLocation().getZone());
+
+ // compute bid price as (fixedOMCost - elecricityMarketRevenue),
+ // if
+ // the difference is positive. Else if negative, bid at zero.
+ double bidPrice = 0d;
+
+ // get FixedOMCost
+ double fixedOnMCost = plant.getTechnology().getFixedOperatingCost(getCurrentTick());
+ // logger.warn("FIxed OM cost is " + fixedOnMCost);
+
+ // logger.warn("fixed operation and maintenance cost is " +
+ // fixedOnMCost);
+
+ double expectedElectricityPrice = 0;
+ double electricityMarketRevenue = 0d;
+ long numberOfSegments = reps.segmentRepository.count();
+ double mc = 0d;
+ if (getCurrentTick() == 0) {
+ mc = 0;
+ electricityMarketRevenue = 0d;
+
+ } else {
+
+ // ********** to check if plant was in the merit order or
+ // not in the previous tick, hence tickTemp******
+ long tickTemp = (getCurrentTick() - 1);
+ // logger.warn("current tick - 1 is " + tickTemp);
+
+ PowerPlantDispatchPlan ppdpTest = reps.powerPlantDispatchPlanRepository
+ .findOnePowerPlantDispatchPlanForPeakSegmentGivenPowerPlantAndTime(plant, tickTemp, false);
+
+ if (ppdpTest == null) {
+
+ } else {
+ // compute revenue from the energy market, using
+ // previous
+ // tick's
+ // electricity spot market prices
+ double capacityAccepted = 0d;
+ mc = calculateMarginalCostExclCO2MarketCost(plant, getCurrentTick());
+
+ double sumEMR = 0d;
+
+ for (SegmentLoad segmentLoad : eMarket.getLoadDurationCurve()) {
+
+ PowerPlantDispatchPlan ppdp = reps.powerPlantDispatchPlanRepository
+ .findOnePowerPlantDispatchPlanForPowerPlantForSegmentForTime(plant,
+ segmentLoad.getSegment(), tickTemp, false);
+
+ if (ppdp.getStatus() < 0) {
+ electricityMarketRevenue = 0d;
+ } else if (ppdp.getStatus() >= 2) {
+ capacityAccepted = ppdp.getAcceptedAmount();
+
+ expectedElectricityPrice = reps.segmentClearingPointRepository
+ .findOneSegmentClearingPointForMarketSegmentAndTime(getCurrentTick() - 1,
+ segmentLoad.getSegment(), eMarket).getPrice();
+
+ double hours = segmentLoad.getSegment().getLengthInHours();
+ // logger.warn("Number of hours per segment is"logger.warn("EL Market revenue is "
+ // + electricityMarketRevenue);
+ // +
+ // hours);
+ // because you're only trying to compute
+ // marginal cost of capacity, you subtract the
+ // marg. cost of energy from the revenue
+ if (mc <= expectedElectricityPrice) {
+ sumEMR = sumEMR + (expectedElectricityPrice - mc) * hours
+ * ppdp.getAcceptedAmount();
+ // logger.warn("EL Market revenue for this segment is "
+ // + sumEMR);
+ }
+
+ }
+
+ }
+
+ electricityMarketRevenue = sumEMR;
+ }
+ }
+
+ double electricityMarketRevenuePerMW = electricityMarketRevenue
+ / plant.getAvailableCapacity(getCurrentTick());
+ // logger.warn("FINAL EL Market revenue is " +
+ // electricityMarketRevenue);
+ // logger.warn("EL Market revenue per MW is " +
+ // electricityMarketRevenuePerMW);
+
+ double mcCapacity = fixedOnMCost - electricityMarketRevenuePerMW;
+ // logger.warn("Fixed Cost - ESM Rev = " + mcCapacity);
+
+ if (mcCapacity < 0) {
+ bidPrice = 0d;
+ // } else if (mcCapacity <= fixedOnMCost) {
+ } else {
+ bidPrice = mcCapacity;
+ }
+
+ Segment peakSegment = reps.segmentRepository.findPeakSegmentforMarket(eMarket);
+ double capacity = plant.getAvailableCapacity(getCurrentTick(), peakSegment, numberOfSegments);
+
+ CapacityDispatchPlan plan = new CapacityDispatchPlan().persist();
+ plan.specifyAndPersist(plant, producer, market, getCurrentTick(), bidPrice, capacity, Bid.SUBMITTED);
+
+ // logger.warn("CDP for powerplant " +
+ // plan.getPlant().getName());
+ // logger.warn("CDP price is " + plan.getPrice());
+ // logger.warn("CDP amount is " + plan.getAmount());
+
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/package-info.java b/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/package-info.java
new file mode 100644
index 00000000..d2fa577d
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/role/capacitymarket/package-info.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+/**
+ * @author Kaveri
+ *
+ */
+package emlab.gen.role.capacitymarket;
\ No newline at end of file
diff --git a/emlab-generation/src/main/java/emlab/gen/role/capacitymechanisms/StrategicReserveOperatorRole.java b/emlab-generation/src/main/java/emlab/gen/role/capacitymechanisms/StrategicReserveOperatorRole.java
index ffa2b9b3..bee04201 100644
--- a/emlab-generation/src/main/java/emlab/gen/role/capacitymechanisms/StrategicReserveOperatorRole.java
+++ b/emlab-generation/src/main/java/emlab/gen/role/capacitymechanisms/StrategicReserveOperatorRole.java
@@ -22,10 +22,11 @@
/**
*
* @author pbhagwat
- *
+ *
*/
@RoleComponent
-public class StrategicReserveOperatorRole extends AbstractRole implements Role{
+public class StrategicReserveOperatorRole extends AbstractRole implements
+ Role {
@Autowired
Reps reps;
@@ -45,198 +46,243 @@ public class StrategicReserveOperatorRole extends AbstractRole sortedListofBidPairs = bidRepository.findOffersDescendingForMarketForTime(currentMarket, getCurrentTick());
+ // Iterable sortedListofBidPairs =
+ // bidRepository.findOffersDescendingForMarketForTime(currentMarket,
+ // getCurrentTick());
- //finds List of all segments
- //List segments = Utils.asList(reps.segmentRepository.findAll());
- //for(Segment currentSegment: reps.segmentRepository.findAll()){
- //segmentCounter += 1;
- //}
+ // finds List of all segments
+ // List segments =
+ // Utils.asList(reps.segmentRepository.findAll());
+ // for(Segment currentSegment: reps.segmentRepository.findAll()){
+ // segmentCounter += 1;
+ // }
// Count all segments in the given market
segmentCounter = reps.segmentRepository.count();
// find all segments for the given market
- for(Segment currentSegment: reps.segmentRepository.findAll()){
- //logger.warn("Current segment is" + currentSegment);
- //find query for specific market
-
+ for (Segment currentSegment : reps.segmentRepository.findAll()) {
+ // logger.warn("Current segment is" + currentSegment);
+ // find query for specific market
boolean isORMarketCleared = false;
- double sumofContractedBids=0;
+ double sumofContractedBids = 0;
double volumetobeContracted = strategicReserveOperator.getReserveVolume();
- //logger.warn("volumetobeContracted " + volumetobeContracted);
+ // logger.warn("volumetobeContracted " + volumetobeContracted);
double clearingEpsilon = 0.001;
double dispatchPrice = strategicReserveOperator.getReservePriceSR();
- //logger.warn("dispatchPrice " + dispatchPrice);
- //double reserveMargin = peakCapacityforMarket-peakLoadforMarket;
+ // logger.warn("dispatchPrice " + dispatchPrice);
+ // double reserveMargin = peakCapacityforMarket-peakLoadforMarket;
Iterable sortedListofPPDP = plantDispatchPlanRepository
.findDescendingSortedPowerPlantDispatchPlansForSegmentForTime(currentSegment, getCurrentTick(),
false);
- for (PowerPlantDispatchPlan currentPPDP: sortedListofPPDP){
+ for (PowerPlantDispatchPlan currentPPDP : sortedListofPPDP) {
- //logger.warn("Bidding Market " + currentPPDP.getBiddingMarket().getNodeId().intValue());
- //logger.warn("Bidding Volume" + (currentPPDP.getAmount()));
- //logger.warn("current Market" + market.getNodeId().intValue());
+ // logger.warn("Bidding Market " +
+ // currentPPDP.getBiddingMarket().getNodeId().intValue());
+ // logger.warn("Bidding Volume" + (currentPPDP.getAmount()));
+ // logger.warn("current Market" +
+ // market.getNodeId().intValue());
// **use querying for market**
- if (currentPPDP.getBiddingMarket().getNodeId().intValue() == market.getNodeId().intValue()){
- //logger.warn("isOR market cleared" + isORMarketCleared);
-
- // Check the size of margin
-
- /* if (strategicReserveOperator.getReserveVolume()>reserveMargin){
- if (reserveMargin-currentPPDP.getAmount()>strategicReserveOperator.getReserveVolume()){
- currentPPDP.setSRstatus(PowerPlantDispatchPlan.NOT_CONTRACTED);
- reserveMargin -= currentPPDP.getAmount();
- }
-
- }*/
-
- if (volumetobeContracted==0){
- isORMarketCleared=true;
- }
- else if (isORMarketCleared == false){
- //logger.warn("volume of current PPDP " + currentPPDP.getAmount());
- if (volumetobeContracted-(sumofContractedBids + currentPPDP.getAmount()) >= clearingEpsilon){
-
- // check if already not contracted
- //if(currentPPDP.getSRstatus()!=PowerPlantDispatchPlan.NOT_CONTRACTED){
- //logger.warn("RemainingVolume" + (volumetobeContracted-(sumofContractedBids + currentPPDP.getAmount())));
- currentPPDP.setSRstatus(PowerPlantDispatchPlan.CONTRACTED);
- //logger.warn("SRSTATUS " +currentPPDP.getSRstatus());
- sumofContractedBids += currentPPDP.getAmount();
- currentPPDP.setOldPrice(currentPPDP.getPrice());
- //logger.warn("Old Price" + currentPPDP.getOldPrice());
- currentPPDP.setPrice(dispatchPrice);
-
- //logger.warn("New Price" + currentPPDP.getPrice());
- // Pays O&M costs to the generated for the contracted capacity
-
- double Loan = 0;
- if ((currentPPDP.getPowerPlant().getLoan().getTotalNumberOfPayments() - currentPPDP
- .getPowerPlant().getLoan().getNumberOfPaymentsDone()) > 0d) {
- Loan = (currentPPDP.getPowerPlant().getLoan().getAmountPerPayment());
+ if (currentPPDP.getBiddingMarket().getNodeId().intValue() == market.getNodeId().intValue()) {
+
+ if (currentPPDP.getPowerPlant().getAgeFraction() < 1.2) {
+ // logger.warn("isOR market cleared" +
+ // isORMarketCleared);
+
+ // Check the size of margin
+
+ /*
+ * if (strategicReserveOperator.getReserveVolume()>
+ * reserveMargin ){ if
+ * (reserveMargin-currentPPDP.getAmount()>
+ * strategicReserveOperator.getReserveVolume()){
+ * currentPPDP.
+ * setSRstatus(PowerPlantDispatchPlan.NOT_CONTRACTED);
+ * reserveMargin -= currentPPDP.getAmount(); }
+ *
+ * }
+ */
+
+ if (volumetobeContracted == 0) {
+ isORMarketCleared = true;
+ } else if (isORMarketCleared == false) {
+ // logger.warn("volume of current PPDP " +
+ // currentPPDP.getAmount());
+ if (volumetobeContracted - (sumofContractedBids + currentPPDP.getAmount()) >= clearingEpsilon) {
+
+ // check if already not contracted
+ // if(currentPPDP.getSRstatus()!=PowerPlantDispatchPlan.NOT_CONTRACTED){
+ // logger.warn("RemainingVolume" +
+ // (volumetobeContracted-(sumofContractedBids +
+ // currentPPDP.getAmount())));
+ currentPPDP.setSRstatus(PowerPlantDispatchPlan.CONTRACTED);
+ // logger.warn("SRSTATUS "
+ // +currentPPDP.getSRstatus());
+ sumofContractedBids += currentPPDP.getAmount();
+ currentPPDP.setOldPrice(currentPPDP.getPrice());
+ // logger.warn("Old Price" +
+ // currentPPDP.getOldPrice());
+ currentPPDP.setPrice(dispatchPrice);
+
+ // logger.warn("New Price" +
+ // currentPPDP.getPrice());
+ // Pays O&M costs to the generated for the
+ // contracted capacity
+
+ double Loan = 0;
+ if ((currentPPDP.getPowerPlant().getLoan().getTotalNumberOfPayments() - currentPPDP
+ .getPowerPlant().getLoan().getNumberOfPaymentsDone()) > 0d) {
+ Loan = (currentPPDP.getPowerPlant().getLoan().getAmountPerPayment());
+ }
+
+ double money = ((currentPPDP.getPowerPlant().getActualFixedOperatingCost()) + Loan)
+ / segmentCounter;
+ // logger.warn("Annual FOC "+
+ // currentPPDP.getPowerPlant().getTechnology().getFixedOperatingCost());
+ // logger.warn("No of Segments "
+ // +segmentCounter);
+ // logger.warn("Money Paid " +money);
+
+ // logger.warn("SRO "+
+ // strategicReserveOperator.getName()
+ // +" CASH Before"
+ // +strategicReserveOperator.getCash());
+ // logger.warn("Owner " +
+ // currentPPDP.getBidder().getName() +
+ // "money Before"
+ // +currentPPDP.getBidder().getCash());
+
+ reps.nonTransactionalCreateRepository.createCashFlow(strategicReserveOperator,
+ currentPPDP.getBidder(), money, CashFlow.STRRESPAYMENT, getCurrentTick(),
+ currentPPDP.getPowerPlant());
+
+ // logger.warn("SRO's CASH After"
+ // +strategicReserveOperator.getCash());
+ // logger.warn("Owner " +
+ // currentPPDP.getBidder().getName() +
+ // " money After"
+ // +currentPPDP.getBidder().getCash());
+ // }
}
- double money = ((currentPPDP.getPowerPlant().getActualFixedOperatingCost()) + Loan)
- / segmentCounter;
- //logger.warn("Annual FOC "+ currentPPDP.getPowerPlant().getTechnology().getFixedOperatingCost());
- //logger.warn("No of Segments " +segmentCounter);
- //logger.warn("Money Paid " +money);
-
- //logger.warn("SRO "+ strategicReserveOperator.getName() +" CASH Before" +strategicReserveOperator.getCash());
- //logger.warn("Owner " + currentPPDP.getBidder().getName() + "money Before" +currentPPDP.getBidder().getCash());
-
+ else if (volumetobeContracted - (sumofContractedBids + currentPPDP.getAmount()) < clearingEpsilon) {
+
+ // if(currentPPDP.getSRstatus()!=PowerPlantDispatchPlan.NOT_CONTRACTED){
+
+ currentPPDP.setSRstatus(PowerPlantDispatchPlan.PARTLY_CONTRACTED);
+ // logger.warn("SRSTATUS "
+ // +currentPPDP.getSRstatus());
+ sumofContractedBids += currentPPDP.getAmount();
+ currentPPDP.setOldPrice(currentPPDP.getPrice());
+ // logger.warn("Old Price" +
+ // currentPPDP.getOldPrice());
+ currentPPDP.setPrice(dispatchPrice);
+
+ // logger.warn("New Price" +
+ // currentPPDP.getPrice());
+ isORMarketCleared = true;
+ // Pays O&M costs and outstanding loans to the
+ // generated for the contracted capacity
+ double Loan = 0;
+ if ((currentPPDP.getPowerPlant().getLoan().getTotalNumberOfPayments() - currentPPDP
+ .getPowerPlant().getLoan().getNumberOfPaymentsDone()) > 0d) {
+ Loan = (currentPPDP.getPowerPlant().getLoan().getAmountPerPayment());
+ }
+
+ double money = ((currentPPDP.getPowerPlant().getActualFixedOperatingCost()) + Loan)
+ / segmentCounter;
+ // logger.warn("Annual FOC "+
+ // currentPPDP.getPowerPlant().getTechnology().getFixedOperatingCost());
+ // logger.warn("No of Segments "
+ // +segmentCounter);
+ // logger.warn("Money Paid " +money);
+
+ // logger.warn("SRO "+
+ // strategicReserveOperator.getName()
+ // +" CASH Before"
+ // +strategicReserveOperator.getCash());
+ // logger.warn("Owner " +
+ // currentPPDP.getBidder().getName() +
+ // "money Before"
+ // +currentPPDP.getBidder().getCash());
+
+ reps.nonTransactionalCreateRepository.createCashFlow(strategicReserveOperator,
+ currentPPDP.getBidder(), money, CashFlow.STRRESPAYMENT, getCurrentTick(),
+ currentPPDP.getPowerPlant());
+
+ // logger.warn("SRO's CASH After"
+ // +strategicReserveOperator.getCash());
+ // logger.warn("Owner " +
+ // currentPPDP.getBidder().getName() +
+ // " money After"
+ // +currentPPDP.getBidder().getCash());
+ // }
+ }
- reps.nonTransactionalCreateRepository.createCashFlow(strategicReserveOperator, currentPPDP.getBidder(), money, CashFlow.STRRESPAYMENT, getCurrentTick(), currentPPDP.getPowerPlant());
+ } else {
+ currentPPDP.setSRstatus(PowerPlantDispatchPlan.NOT_CONTRACTED);
- //logger.warn("SRO's CASH After" +strategicReserveOperator.getCash());
- //logger.warn("Owner " + currentPPDP.getBidder().getName() + " money After" +currentPPDP.getBidder().getCash());
- // }
}
-
- else if (volumetobeContracted-(sumofContractedBids + currentPPDP.getAmount()) < clearingEpsilon){
-
- // if(currentPPDP.getSRstatus()!=PowerPlantDispatchPlan.NOT_CONTRACTED){
-
- currentPPDP.setSRstatus(PowerPlantDispatchPlan.PARTLY_CONTRACTED);
- //logger.warn("SRSTATUS " +currentPPDP.getSRstatus());
- sumofContractedBids += currentPPDP.getAmount();
- currentPPDP.setOldPrice(currentPPDP.getPrice());
- //logger.warn("Old Price" + currentPPDP.getOldPrice());
- currentPPDP.setPrice(dispatchPrice);
-
- //logger.warn("New Price" + currentPPDP.getPrice());
+ // logger.warn(volumetobeContracted-sumofContractedBids);
+ if (volumetobeContracted - sumofContractedBids < clearingEpsilon) {
+ // logger.warn("is market clear" +
+ // isORMarketCleared);
isORMarketCleared = true;
- // Pays O&M costs and outstanding loans to the
- // generated for the contracted capacity
- double Loan = 0;
- if ((currentPPDP.getPowerPlant().getLoan().getTotalNumberOfPayments() - currentPPDP
- .getPowerPlant().getLoan().getNumberOfPaymentsDone()) > 0d) {
- Loan = (currentPPDP.getPowerPlant().getLoan().getAmountPerPayment());
- }
-
-
- double money = ((currentPPDP.getPowerPlant().getActualFixedOperatingCost()) + Loan)
- / segmentCounter;
- //logger.warn("Annual FOC "+ currentPPDP.getPowerPlant().getTechnology().getFixedOperatingCost());
- //logger.warn("No of Segments " +segmentCounter);
- //logger.warn("Money Paid " +money);
-
- //logger.warn("SRO "+ strategicReserveOperator.getName() +" CASH Before" +strategicReserveOperator.getCash());
- //logger.warn("Owner " + currentPPDP.getBidder().getName() + "money Before" +currentPPDP.getBidder().getCash());
-
- reps.nonTransactionalCreateRepository.createCashFlow(strategicReserveOperator, currentPPDP.getBidder(), money, CashFlow.STRRESPAYMENT, getCurrentTick(), currentPPDP.getPowerPlant());
-
- //logger.warn("SRO's CASH After" +strategicReserveOperator.getCash());
- //logger.warn("Owner " + currentPPDP.getBidder().getName() + " money After" +currentPPDP.getBidder().getCash());
- //}
}
-
- }
- else {
- currentPPDP.setSRstatus(PowerPlantDispatchPlan.NOT_CONTRACTED);
-
- }
- //logger.warn(volumetobeContracted-sumofContractedBids);
- if (volumetobeContracted-sumofContractedBids < clearingEpsilon){
- //logger.warn("is market clear" + isORMarketCleared);
- isORMarketCleared = true;
+ // logger.warn(" iS OR CLEARED "+isORMarketCleared);
+ // logger.warn("Price is "+currentPPDP.getPrice());
+ currentPPDP.persist();
}
- //logger.warn(" iS OR CLEARED "+isORMarketCleared);
- //logger.warn("Price is "+currentPPDP.getPrice());
- currentPPDP.persist();
}
}
}
- //logger.warn("cash of SR " +strategicReserveOperator.getCash());
+ // logger.warn("cash of SR " +strategicReserveOperator.getCash());
}
}
\ No newline at end of file
diff --git a/emlab-generation/src/main/java/emlab/gen/role/co2policy/MarketStabilityReserveRole.java b/emlab-generation/src/main/java/emlab/gen/role/co2policy/MarketStabilityReserveRole.java
index 6d3bca33..91127e4a 100644
--- a/emlab-generation/src/main/java/emlab/gen/role/co2policy/MarketStabilityReserveRole.java
+++ b/emlab-generation/src/main/java/emlab/gen/role/co2policy/MarketStabilityReserveRole.java
@@ -46,7 +46,9 @@ public class MarketStabilityReserveRole extends AbstractRole {
@Transactional
public void act(Government government) {
- double allowancesInCirculation = reps.decarbonizationAgentRepository.determinePreviouslyBankedCO2Certificates();
+ double allowancesInCirculation = government.isStabilityReserveHasOneYearDelayInsteadOfTwoYearDelay() ? reps.decarbonizationAgentRepository
+ .determineTotallyBankedCO2Certificates() : reps.decarbonizationAgentRepository
+ .determinePreviouslyBankedCO2Certificates();
double inflowToMarketReserve = calculateInflowToMarketReserveForTimeStep(getCurrentTick(),
allowancesInCirculation, government);
government.setStabilityReserve(government.getStabilityReserve() + inflowToMarketReserve);
@@ -66,7 +68,7 @@ public double calculateInflowToMarketReserveForTimeStep(long clearingTick, doubl
return allowancesToBeAddedToReserve;
} else if (allowancesInCirculation < government.getStabilityReserveLowerTriggerTrend().getValue(clearingTick)) {
double allowancesToBeReleased = Math.min(government.getStabilityReserve(),
- government
+ government
.getStabilityReserveReleaseQuantityTrend().getValue(clearingTick));
return -allowancesToBeReleased;
}
diff --git a/emlab-generation/src/main/java/emlab/gen/role/co2policy/RenewableAdaptiveCO2CapRole.java b/emlab-generation/src/main/java/emlab/gen/role/co2policy/RenewableAdaptiveCO2CapRole.java
index 7d974950..1a6b59c4 100644
--- a/emlab-generation/src/main/java/emlab/gen/role/co2policy/RenewableAdaptiveCO2CapRole.java
+++ b/emlab-generation/src/main/java/emlab/gen/role/co2policy/RenewableAdaptiveCO2CapRole.java
@@ -27,7 +27,9 @@
import emlab.gen.domain.market.CO2Auction;
import emlab.gen.domain.market.ClearingPoint;
import emlab.gen.domain.market.electricity.ElectricitySpotMarket;
+import emlab.gen.domain.market.electricity.Segment;
import emlab.gen.domain.policy.PowerGeneratingTechnologyTarget;
+import emlab.gen.domain.technology.PowerPlant;
import emlab.gen.repository.Reps;
import emlab.gen.repository.StrategicReserveOperatorRepository;
import emlab.gen.trend.TimeSeriesImpl;
@@ -75,57 +77,61 @@ public void act(Government government) {
}
}
- double averageEmissionsPerMWh = government.isAdaptiveCapAdjustmentBasedOnCapNotActualEmissions() ? (government
- .getCo2CapTrend().getValue(getCurrentTick()) / totalProduction) : (co2Emissions / totalProduction);
+ double absoluteBase = government.isAdaptiveCapAdjustmentBasedOnCapNotActualEmissions() ? government
+ .getCo2CapTrend().getValue(getCurrentTick()) : co2Emissions;
- double plannedProductionByRenewables = 0;
- double totalPlannedCapacity = 0;
-
- double totalProducedRenewableElectricity = 0;
-
- double totalActualInstalledCapacity = 0;
- for (TargetInvestor targetInvestor : template.findAll(TargetInvestor.class)) {
- for (PowerGeneratingTechnologyTarget target : targetInvestor.getPowerGenerationTechnologyTargets()) {
- double producedRenewableElectricityByTechnologyByTargetInvestor = reps.powerPlantDispatchPlanRepository
- .calculateTotalProductionForEnergyProducerForTimeForTechnology(targetInvestor,
- getCurrentTick() - 1, target.getPowerGeneratingTechnology(), false);
- totalProducedRenewableElectricity += producedRenewableElectricityByTechnologyByTargetInvestor;
- double installedCapacityByTechnology = reps.powerPlantRepository
- .calculateCapacityOfExpectedOperationalPowerPlantsByOwnerByTechnology(getCurrentTick() - 1,
- targetInvestor, target.getPowerGeneratingTechnology());
- totalActualInstalledCapacity += installedCapacityByTechnology;
- double plannedCapacityByTechnologyAndTargetInvestor = target.getTrend().getValue(getCurrentTick() - 1);
- totalPlannedCapacity += plannedCapacityByTechnologyAndTargetInvestor;
- double plannedProducedRenewableElectricityByTechnologyAndTargetInvestor = plannedCapacityByTechnologyAndTargetInvestor
- / installedCapacityByTechnology * producedRenewableElectricityByTechnologyByTargetInvestor;
- logger.warn("plannedProducedRenewable " + target.getPowerGeneratingTechnology().getName() + ": "
- + plannedProducedRenewableElectricityByTechnologyAndTargetInvestor + " = "
- + plannedCapacityByTechnologyAndTargetInvestor
- +"/" + installedCapacityByTechnology +"*" + producedRenewableElectricityByTechnologyByTargetInvestor);
- plannedProductionByRenewables += Double
- .isNaN(plannedProducedRenewableElectricityByTechnologyAndTargetInvestor) ? 0
- : plannedProducedRenewableElectricityByTechnologyAndTargetInvestor;
- }
- }
+ double plannedProductionByRenewables = 0;
+ double totalPlannedCapacity = 0;
- double plannedSavedEmissionsApproximation = plannedProductionByRenewables * averageEmissionsPerMWh;
- double actualSavedEmissionsApproximation = totalProducedRenewableElectricity * averageEmissionsPerMWh;
+ double totalProducedRenewableElectricity = 0;
- double capReduction = calculateCapReductionForTimeStep(government, plannedSavedEmissionsApproximation,
- actualSavedEmissionsApproximation);
- government.getCo2CapTrend().setValue(getCurrentTick(),
- government.getCo2CapTrend().getValue(getCurrentTick()) - capReduction);
- TimeSeriesImpl co2CapAdjustmentTimeSeries = government.getCo2CapAdjustmentTimeSeries();
- if (co2CapAdjustmentTimeSeries == null) {
- co2CapAdjustmentTimeSeries = new TimeSeriesImpl();
- co2CapAdjustmentTimeSeries.setTimeSeries(new double[government.getCo2CapTrend().getTimeSeries().length]);
- co2CapAdjustmentTimeSeries.persist();
- government.setCo2CapAdjustmentTimeSeries(co2CapAdjustmentTimeSeries);
- }
- co2CapAdjustmentTimeSeries.setValue(getCurrentTick(), capReduction);
-
- // logger.warn("TimeSeries after: {}",
- // government.getCo2CapTrend().getTimeSeries());
+ double totalActualInstalledCapacity = 0;
+ for (TargetInvestor targetInvestor : template.findAll(TargetInvestor.class)) {
+ for (PowerGeneratingTechnologyTarget target : targetInvestor.getPowerGenerationTechnologyTargets()) {
+ double producedRenewableElectricityByTechnologyByTargetInvestor = reps.powerPlantDispatchPlanRepository
+ .calculateTotalProductionForEnergyProducerForTimeForTechnology(targetInvestor,
+ getCurrentTick() - 1, target.getPowerGeneratingTechnology(), false);
+ totalProducedRenewableElectricity += producedRenewableElectricityByTechnologyByTargetInvestor;
+ double installedCapacityByTechnology = reps.powerPlantRepository
+ .calculateCapacityOfExpectedOperationalPowerPlantsByOwnerByTechnology(getCurrentTick() - 1,
+ targetInvestor, target.getPowerGeneratingTechnology());
+ totalActualInstalledCapacity += installedCapacityByTechnology;
+ double plannedCapacityByTechnologyAndTargetInvestor = target.getTrend().getValue(getCurrentTick() - 1);
+ totalPlannedCapacity += plannedCapacityByTechnologyAndTargetInvestor;
+ double plannedProducedRenewableElectricityByTechnologyAndTargetInvestor = plannedCapacityByTechnologyAndTargetInvestor
+ / installedCapacityByTechnology * producedRenewableElectricityByTechnologyByTargetInvestor;
+ // logger.warn("plannedProducedRenewable " +
+ // target.getPowerGeneratingTechnology().getName() + ": "
+ // +
+ // plannedProducedRenewableElectricityByTechnologyAndTargetInvestor
+ // + " = "
+ // + plannedCapacityByTechnologyAndTargetInvestor
+ // +"/" + installedCapacityByTechnology +"*" +
+ // producedRenewableElectricityByTechnologyByTargetInvestor);
+ plannedProductionByRenewables += Double
+ .isNaN(plannedProducedRenewableElectricityByTechnologyAndTargetInvestor) ? 0
+ : plannedProducedRenewableElectricityByTechnologyAndTargetInvestor;
+ }
+ }
+
+ double capReduction = government.isAdaptiveCapAdjustmentRelativeToNonSubsidisedProduction() ? calculateCapReductionForTimeStepRelativeToNonSubsidizedGeneration(
+ government, plannedProductionByRenewables, totalProducedRenewableElectricity, totalProduction,
+ absoluteBase)
+ : calculateCapReductionForTimeStepRelativeToTotalGeneration(government,
+ plannedProductionByRenewables, totalProducedRenewableElectricity, totalProduction, absoluteBase);
+ government.getCo2CapTrend().setValue(getCurrentTick(),
+ government.getCo2CapTrend().getValue(getCurrentTick()) - capReduction);
+ TimeSeriesImpl co2CapAdjustmentTimeSeries = government.getCo2CapAdjustmentTimeSeries();
+ if (co2CapAdjustmentTimeSeries == null) {
+ co2CapAdjustmentTimeSeries = new TimeSeriesImpl();
+ co2CapAdjustmentTimeSeries.setTimeSeries(new double[government.getCo2CapTrend().getTimeSeries().length]);
+ co2CapAdjustmentTimeSeries.persist();
+ government.setCo2CapAdjustmentTimeSeries(co2CapAdjustmentTimeSeries);
+ }
+ co2CapAdjustmentTimeSeries.setValue(getCurrentTick(), capReduction);
+
+ // logger.warn("TimeSeries after: {}",
+ // government.getCo2CapTrend().getTimeSeries());
}
public double calculatedExpectedCapReductionForTimeStep(Government government, long currentTimeStep,
@@ -150,8 +156,7 @@ public double calculatedExpectedCapReductionForTimeStep(Government government, l
}
}
- double averageEmissionsPerMWh = government.isAdaptiveCapAdjustmentBasedOnCapNotActualEmissions() ? (government
- .getCo2CapTrend().getValue(futureTimeStep - 1) / totalProduction) : (co2Emissions / totalProduction);
+ double absoluteBase = government.isAdaptiveCapAdjustmentBasedOnCapNotActualEmissions() ? government.getCo2CapTrend().getValue(futureTimeStep - 1) : co2Emissions;
double plannedProductionByRenewables = 0;
double totalPlannedCapacity = 0;
@@ -179,26 +184,34 @@ public double calculatedExpectedCapReductionForTimeStep(Government government, l
totalPlannedCapacity += plannedCapacityByTechnologyAndTargetInvestor;
double plannedProducedRenewableElectricityByTechnologyAndTargetInvestor = plannedCapacityByTechnologyAndTargetInvestor
/ installedCapacityByTechnology * producedRenewableElectricityByTechnologyByTargetInvestor;
- logger.warn("plannedProducedRenewable " + target.getPowerGeneratingTechnology().getName() + ": "
- + plannedProducedRenewableElectricityByTechnologyAndTargetInvestor + " = "
- + plannedCapacityByTechnologyAndTargetInvestor + "/" + installedCapacityByTechnology + "*"
- + producedRenewableElectricityByTechnologyByTargetInvestor);
+ // logger.warn("plannedProducedRenewable " +
+ // target.getPowerGeneratingTechnology().getName() + ": "
+ // +
+ // plannedProducedRenewableElectricityByTechnologyAndTargetInvestor
+ // + " = "
+ // + plannedCapacityByTechnologyAndTargetInvestor + "/" +
+ // installedCapacityByTechnology + "*"
+ // + producedRenewableElectricityByTechnologyByTargetInvestor);
plannedProductionByRenewables += Double
.isNaN(plannedProducedRenewableElectricityByTechnologyAndTargetInvestor) ? 0
: plannedProducedRenewableElectricityByTechnologyAndTargetInvestor;
}
}
- double plannedSavedEmissionsApproximation = plannedProductionByRenewables * averageEmissionsPerMWh;
- double actualSavedEmissionsApproximation = totalProducedRenewableElectricity * averageEmissionsPerMWh;
- double capReduction = calculateCapReductionForTimeStep(government, plannedSavedEmissionsApproximation,
- actualSavedEmissionsApproximation);
- return capReduction;
+ double capReduction = government.isAdaptiveCapAdjustmentRelativeToNonSubsidisedProduction() ? calculateCapReductionForTimeStepRelativeToNonSubsidizedGeneration(
+ government, plannedProductionByRenewables, totalProducedRenewableElectricity, totalProduction,absoluteBase)
+ : calculateCapReductionForTimeStepRelativeToTotalGeneration(government,
+ plannedProductionByRenewables, totalProducedRenewableElectricity, totalProduction, absoluteBase);
+ return capReduction;
}
- double calculateCapReductionForTimeStep(Government government,
- double plannedSavedEmissionsApproximation, double actualSavedEmissionsApproximation) {
+ double calculateCapReductionForTimeStepRelativeToTotalGeneration(Government government,
+ double plannedProductionByRenewables, double totalProducedRenewableElectricity, double totalProduction,
+ double absoluteBase) {
+ double averageEmissionsPerMWh = (absoluteBase / totalProduction);
+ double plannedSavedEmissionsApproximation = plannedProductionByRenewables * averageEmissionsPerMWh;
+ double actualSavedEmissionsApproximation = totalProducedRenewableElectricity * averageEmissionsPerMWh;
double capReduction = 0;
@@ -208,12 +221,28 @@ public double calculatedExpectedCapReductionForTimeStep(Government government, l
capReduction = Math.max(0, actualSavedEmissionsApproximation - plannedSavedEmissionsApproximation)
* government.getAdaptiveCapCO2SavingsWeighingFactor();
}
- logger.warn("plannedSavedEmissionsApproximation: " + plannedSavedEmissionsApproximation
- + ", actualSavedEmissionsApproximation: " + actualSavedEmissionsApproximation + ", Cap reduction: "
- + capReduction);
+ // logger.warn("plannedSavedEmissionsApproximation: " +
+ // plannedSavedEmissionsApproximation
+ // + ", actualSavedEmissionsApproximation: " +
+ // actualSavedEmissionsApproximation + ", Cap reduction: "
+ // + capReduction);
// logger.warn("TimeSeries after: {}",
// government.getCo2CapTrend().getTimeSeries());
+ return capReduction;
+
+ }
+ double calculateCapReductionForTimeStepRelativeToNonSubsidizedGeneration(Government government,
+ double plannedProductionByRenewables, double totalProducedRenewableElectricity, double totalProduction,
+ double absoluteBase) {
+ double capReduction = Math.max(0, (totalProducedRenewableElectricity - plannedProductionByRenewables)
+ / (totalProduction - plannedProductionByRenewables))
+ * absoluteBase;
+ // double alternativeCapReduction =
+ // calculateCapReductionForTimeStepRelativeToTotalGeneration(government,
+ // plannedProductionByRenewables, totalProducedRenewableElectricity,
+ // totalProduction,absoluteBase);
+ // logger.warn("CapReductionToNonSub: {}, instead of to toal: {}",capReduction,alternativeCapReduction);
return capReduction;
}
diff --git a/emlab-generation/src/main/java/emlab/gen/role/co2policy/RenewableAdaptiveCO2CapRole.java.orig b/emlab-generation/src/main/java/emlab/gen/role/co2policy/RenewableAdaptiveCO2CapRole.java.orig
new file mode 100644
index 00000000..7cc345ff
--- /dev/null
+++ b/emlab-generation/src/main/java/emlab/gen/role/co2policy/RenewableAdaptiveCO2CapRole.java.orig
@@ -0,0 +1,389 @@
+/*******************************************************************************
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package emlab.gen.role.co2policy;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.annotation.Transient;
+import org.springframework.data.neo4j.support.Neo4jTemplate;
+import org.springframework.transaction.annotation.Transactional;
+
+import agentspring.role.AbstractRole;
+import agentspring.role.RoleComponent;
+import emlab.gen.domain.agent.Government;
+import emlab.gen.domain.agent.TargetInvestor;
+import emlab.gen.domain.market.CO2Auction;
+import emlab.gen.domain.market.ClearingPoint;
+import emlab.gen.domain.market.electricity.ElectricitySpotMarket;
+import emlab.gen.domain.policy.PowerGeneratingTechnologyTarget;
+import emlab.gen.repository.Reps;
+import emlab.gen.repository.StrategicReserveOperatorRepository;
+import emlab.gen.trend.TimeSeriesImpl;
+
+/**
+ * @author JCRichstein
+ *
+ */
+@RoleComponent
+public class RenewableAdaptiveCO2CapRole extends AbstractRole {
+
+ @Transient
+ @Autowired
+ Reps reps;
+
+ @Transient
+ @Autowired
+ StrategicReserveOperatorRepository strategicReserveOperatorRepository;
+
+ @Autowired
+ Neo4jTemplate template;
+
+ @Transactional
+ public void act(Government government) {
+
+ // logger.warn("TimeSeries before: {}",
+ // government.getCo2CapTrend().getTimeSeries());
+
+ double co2Emissions = 0;
+
+ CO2Auction co2Auction = template.findAll(CO2Auction.class).iterator().next();
+
+ ClearingPoint lastClearingPointOfCo2Market = reps.clearingPointRepositoryOld.findClearingPointForMarketAndTime(
+ co2Auction, getCurrentTick() - 1, false);
+ if (lastClearingPointOfCo2Market != null) {
+ co2Emissions = lastClearingPointOfCo2Market.getVolume();
+ }
+
+ double totalProduction = 0;
+
+ for (ElectricitySpotMarket esm : reps.marketRepository.findAllElectricitySpotMarkets()) {
+ for (ClearingPoint cp : reps.clearingPointRepository.findAllClearingPointsForMarketAndTimeRange(esm,
+ getCurrentTick() - 1, getCurrentTick() - 1, false)) {
+ totalProduction += cp.getVolume();
+ }
+ }
+
+<<<<<<< HEAD
+ double averageEmissionsPerMWh = government.isAdaptiveCapAdjustmentBasedOnCapNotActualEmissions() ? (government
+ .getCo2CapTrend().getValue(getCurrentTick()) / totalProduction) : (co2Emissions / totalProduction);
+
+ double plannedProductionByRenewables = 0;
+ double totalPlannedCapacity = 0;
+
+ double totalProducedRenewableElectricity = 0;
+
+ double totalActualInstalledCapacity = 0;
+ for (TargetInvestor targetInvestor : template.findAll(TargetInvestor.class)) {
+ for (PowerGeneratingTechnologyTarget target : targetInvestor.getPowerGenerationTechnologyTargets()) {
+ double producedRenewableElectricityByTechnologyByTargetInvestor = reps.powerPlantDispatchPlanRepository
+ .calculateTotalProductionForEnergyProducerForTimeForTechnology(targetInvestor,
+ getCurrentTick() - 1, target.getPowerGeneratingTechnology(), false);
+ totalProducedRenewableElectricity += producedRenewableElectricityByTechnologyByTargetInvestor;
+ double installedCapacityByTechnology = reps.powerPlantRepository
+ .calculateCapacityOfExpectedOperationalPowerPlantsByOwnerByTechnology(getCurrentTick() - 1,
+ targetInvestor, target.getPowerGeneratingTechnology());
+ totalActualInstalledCapacity += installedCapacityByTechnology;
+ double plannedCapacityByTechnologyAndTargetInvestor = target.getTrend().getValue(getCurrentTick() - 1);
+ totalPlannedCapacity += plannedCapacityByTechnologyAndTargetInvestor;
+ double plannedProducedRenewableElectricityByTechnologyAndTargetInvestor = plannedCapacityByTechnologyAndTargetInvestor
+ / installedCapacityByTechnology * producedRenewableElectricityByTechnologyByTargetInvestor;
+ logger.warn("plannedProducedRenewable " + target.getPowerGeneratingTechnology().getName() + ": "
+ + plannedProducedRenewableElectricityByTechnologyAndTargetInvestor + " = "
+ + plannedCapacityByTechnologyAndTargetInvestor
+ +"/" + installedCapacityByTechnology +"*" + producedRenewableElectricityByTechnologyByTargetInvestor);
+ plannedProductionByRenewables += Double
+ .isNaN(plannedProducedRenewableElectricityByTechnologyAndTargetInvestor) ? 0
+ : plannedProducedRenewableElectricityByTechnologyAndTargetInvestor;
+ }
+ }
+
+ double plannedSavedEmissionsApproximation = plannedProductionByRenewables * averageEmissionsPerMWh;
+ double actualSavedEmissionsApproximation = totalProducedRenewableElectricity * averageEmissionsPerMWh;
+
+ double capReduction = calculateCapReductionForTimeStep(government, plannedSavedEmissionsApproximation,
+ actualSavedEmissionsApproximation);
+ government.getCo2CapTrend().setValue(getCurrentTick(),
+ government.getCo2CapTrend().getValue(getCurrentTick()) - capReduction);
+ TimeSeriesImpl co2CapAdjustmentTimeSeries = government.getCo2CapAdjustmentTimeSeries();
+ if (co2CapAdjustmentTimeSeries == null) {
+ co2CapAdjustmentTimeSeries = new TimeSeriesImpl();
+ co2CapAdjustmentTimeSeries.setTimeSeries(new double[government.getCo2CapTrend().getTimeSeries().length]);
+ co2CapAdjustmentTimeSeries.persist();
+ government.setCo2CapAdjustmentTimeSeries(co2CapAdjustmentTimeSeries);
+ }
+ co2CapAdjustmentTimeSeries.setValue(getCurrentTick(), capReduction);
+
+ // logger.warn("TimeSeries after: {}",
+ // government.getCo2CapTrend().getTimeSeries());
+ }
+
+ public double calculatedExpectedCapReductionForTimeStep(Government government, long currentTimeStep,
+ long futureTimeStep,
+ double currentEmissions,
+ double futureEmissions, long centralForecastingYear) {
+
+ double co2Emissions = 1.0d / centralForecastingYear * currentEmissions + (centralForecastingYear - 1.0d)
+ / centralForecastingYear * futureEmissions;
+
+ double totalProduction = 0;
+
+ for (ElectricitySpotMarket esm : reps.marketRepository.findAllElectricitySpotMarkets()) {
+ for (ClearingPoint cp : reps.clearingPointRepository.findAllClearingPointsForMarketAndTimeRange(esm,
+ currentTimeStep, currentTimeStep, false)) {
+ totalProduction += cp.getVolume() * 1 / centralForecastingYear;
+ }
+ for (ClearingPoint cp : reps.clearingPointRepository.findAllClearingPointsForMarketAndTimeRange(esm,
+ futureTimeStep, futureTimeStep, true)) {
+ totalProduction += cp.getVolume() * (centralForecastingYear - 1) / centralForecastingYear;
+ ;
+ }
+ }
+
+ double averageEmissionsPerMWh = government.isAdaptiveCapAdjustmentBasedOnCapNotActualEmissions() ? (government
+ .getCo2CapTrend().getValue(futureTimeStep - 1) / totalProduction) : (co2Emissions / totalProduction);
+
+ double plannedProductionByRenewables = 0;
+ double totalPlannedCapacity = 0;
+
+ double totalProducedRenewableElectricity = 0;
+
+ double totalActualInstalledCapacity = 0;
+ for (TargetInvestor targetInvestor : template.findAll(TargetInvestor.class)) {
+ for (PowerGeneratingTechnologyTarget target : targetInvestor.getPowerGenerationTechnologyTargets()) {
+ double producedRenewableElectricityByTechnologyByTargetInvestor = reps.powerPlantDispatchPlanRepository
+ .calculateTotalProductionForEnergyProducerForTimeForTechnology(targetInvestor, currentTimeStep,
+ target.getPowerGeneratingTechnology(), false)
+ * 1
+ / centralForecastingYear
+ + reps.powerPlantDispatchPlanRepository
+ .calculateTotalProductionForEnergyProducerForTimeForTechnology(targetInvestor,
+ futureTimeStep, target.getPowerGeneratingTechnology(), true)
+ * (centralForecastingYear - 1) / centralForecastingYear;
+ totalProducedRenewableElectricity += producedRenewableElectricityByTechnologyByTargetInvestor;
+ double installedCapacityByTechnology = reps.powerPlantRepository
+ .calculateCapacityOfExpectedOperationalPowerPlantsByOwnerByTechnology(futureTimeStep - 1,
+ targetInvestor, target.getPowerGeneratingTechnology());
+ totalActualInstalledCapacity += installedCapacityByTechnology;
+ double plannedCapacityByTechnologyAndTargetInvestor = target.getTrend().getValue(futureTimeStep - 1);
+ totalPlannedCapacity += plannedCapacityByTechnologyAndTargetInvestor;
+ double plannedProducedRenewableElectricityByTechnologyAndTargetInvestor = plannedCapacityByTechnologyAndTargetInvestor
+ / installedCapacityByTechnology * producedRenewableElectricityByTechnologyByTargetInvestor;
+ logger.warn("plannedProducedRenewable " + target.getPowerGeneratingTechnology().getName() + ": "
+ + plannedProducedRenewableElectricityByTechnologyAndTargetInvestor + " = "
+ + plannedCapacityByTechnologyAndTargetInvestor + "/" + installedCapacityByTechnology + "*"
+ + producedRenewableElectricityByTechnologyByTargetInvestor);
+ plannedProductionByRenewables += Double
+ .isNaN(plannedProducedRenewableElectricityByTechnologyAndTargetInvestor) ? 0
+ : plannedProducedRenewableElectricityByTechnologyAndTargetInvestor;
+ }
+ }
+
+ double plannedSavedEmissionsApproximation = plannedProductionByRenewables * averageEmissionsPerMWh;
+ double actualSavedEmissionsApproximation = totalProducedRenewableElectricity * averageEmissionsPerMWh;
+
+ double capReduction = calculateCapReductionForTimeStep(government, plannedSavedEmissionsApproximation,
+ actualSavedEmissionsApproximation);
+ return capReduction;
+ }
+
+ double calculateCapReductionForTimeStep(Government government,
+ double plannedSavedEmissionsApproximation, double actualSavedEmissionsApproximation) {
+
+ double capReduction = 0;
+
+ if (!government.isDeviationFromResTargetAdjustment()) {
+ capReduction = actualSavedEmissionsApproximation * government.getAdaptiveCapCO2SavingsWeighingFactor();
+ } else {
+ capReduction = Math.max(0, actualSavedEmissionsApproximation - plannedSavedEmissionsApproximation)
+ * government.getAdaptiveCapCO2SavingsWeighingFactor();
+ }
+ logger.warn("plannedSavedEmissionsApproximation: " + plannedSavedEmissionsApproximation
+ + ", actualSavedEmissionsApproximation: " + actualSavedEmissionsApproximation + ", Cap reduction: "
+ + capReduction);
+ // logger.warn("TimeSeries after: {}",
+ // government.getCo2CapTrend().getTimeSeries());
+
+=======
+ double absoluteBase = government.isAdaptiveCapAdjustmentBasedOnCapNotActualEmissions() ? government
+ .getCo2CapTrend().getValue(getCurrentTick()) : co2Emissions;
+
+ double plannedProductionByRenewables = 0;
+ double totalPlannedCapacity = 0;
+
+ double totalProducedRenewableElectricity = 0;
+
+ double totalActualInstalledCapacity = 0;
+ for (TargetInvestor targetInvestor : template.findAll(TargetInvestor.class)) {
+ for (PowerGeneratingTechnologyTarget target : targetInvestor.getPowerGenerationTechnologyTargets()) {
+ double producedRenewableElectricityByTechnologyByTargetInvestor = reps.powerPlantDispatchPlanRepository
+ .calculateTotalProductionForEnergyProducerForTimeForTechnology(targetInvestor,
+ getCurrentTick() - 1, target.getPowerGeneratingTechnology(), false);
+ totalProducedRenewableElectricity += producedRenewableElectricityByTechnologyByTargetInvestor;
+ double installedCapacityByTechnology = reps.powerPlantRepository
+ .calculateCapacityOfExpectedOperationalPowerPlantsByOwnerByTechnology(getCurrentTick() - 1,
+ targetInvestor, target.getPowerGeneratingTechnology());
+ totalActualInstalledCapacity += installedCapacityByTechnology;
+ double plannedCapacityByTechnologyAndTargetInvestor = target.getTrend().getValue(getCurrentTick() - 1);
+ totalPlannedCapacity += plannedCapacityByTechnologyAndTargetInvestor;
+ double plannedProducedRenewableElectricityByTechnologyAndTargetInvestor = plannedCapacityByTechnologyAndTargetInvestor
+ / installedCapacityByTechnology * producedRenewableElectricityByTechnologyByTargetInvestor;
+ // logger.warn("plannedProducedRenewable " +
+ // target.getPowerGeneratingTechnology().getName() + ": "
+ // +
+ // plannedProducedRenewableElectricityByTechnologyAndTargetInvestor
+ // + " = "
+ // + plannedCapacityByTechnologyAndTargetInvestor
+ // +"/" + installedCapacityByTechnology +"*" +
+ // producedRenewableElectricityByTechnologyByTargetInvestor);
+ plannedProductionByRenewables += Double
+ .isNaN(plannedProducedRenewableElectricityByTechnologyAndTargetInvestor) ? 0
+ : plannedProducedRenewableElectricityByTechnologyAndTargetInvestor;
+ }
+ }
+
+ double capReduction = government.isAdaptiveCapAdjustmentRelativeToNonSubsidisedProduction() ? calculateCapReductionForTimeStepRelativeToNonSubsidizedGeneration(
+ government, plannedProductionByRenewables, totalProducedRenewableElectricity, totalProduction,
+ absoluteBase)
+ : calculateCapReductionForTimeStepRelativeToTotalGeneration(government,
+ plannedProductionByRenewables, totalProducedRenewableElectricity, totalProduction, absoluteBase);
+ government.getCo2CapTrend().setValue(getCurrentTick(),
+ government.getCo2CapTrend().getValue(getCurrentTick()) - capReduction);
+ TimeSeriesImpl co2CapAdjustmentTimeSeries = government.getCo2CapAdjustmentTimeSeries();
+ if (co2CapAdjustmentTimeSeries == null) {
+ co2CapAdjustmentTimeSeries = new TimeSeriesImpl();
+ co2CapAdjustmentTimeSeries.setTimeSeries(new double[government.getCo2CapTrend().getTimeSeries().length]);
+ co2CapAdjustmentTimeSeries.persist();
+ government.setCo2CapAdjustmentTimeSeries(co2CapAdjustmentTimeSeries);
+ }
+ co2CapAdjustmentTimeSeries.setValue(getCurrentTick(), capReduction);
+
+ // logger.warn("TimeSeries after: {}",
+ // government.getCo2CapTrend().getTimeSeries());
+ }
+
+ public double calculatedExpectedCapReductionForTimeStep(Government government, long currentTimeStep,
+ long futureTimeStep,
+ double currentEmissions,
+ double futureEmissions, long centralForecastingYear) {
+
+ double co2Emissions = 1.0d / centralForecastingYear * currentEmissions + (centralForecastingYear - 1.0d)
+ / centralForecastingYear * futureEmissions;
+
+ double totalProduction = 0;
+
+ for (ElectricitySpotMarket esm : reps.marketRepository.findAllElectricitySpotMarkets()) {
+ for (ClearingPoint cp : reps.clearingPointRepository.findAllClearingPointsForMarketAndTimeRange(esm,
+ currentTimeStep, currentTimeStep, false)) {
+ totalProduction += cp.getVolume() * 1 / centralForecastingYear;
+ }
+ for (ClearingPoint cp : reps.clearingPointRepository.findAllClearingPointsForMarketAndTimeRange(esm,
+ futureTimeStep, futureTimeStep, true)) {
+ totalProduction += cp.getVolume() * (centralForecastingYear - 1) / centralForecastingYear;
+ ;
+ }
+ }
+
+ double absoluteBase = government.isAdaptiveCapAdjustmentBasedOnCapNotActualEmissions() ? government.getCo2CapTrend().getValue(futureTimeStep - 1) : co2Emissions;
+
+ double plannedProductionByRenewables = 0;
+ double totalPlannedCapacity = 0;
+
+ double totalProducedRenewableElectricity = 0;
+
+ double totalActualInstalledCapacity = 0;
+ for (TargetInvestor targetInvestor : template.findAll(TargetInvestor.class)) {
+ for (PowerGeneratingTechnologyTarget target : targetInvestor.getPowerGenerationTechnologyTargets()) {
+ double producedRenewableElectricityByTechnologyByTargetInvestor = reps.powerPlantDispatchPlanRepository
+ .calculateTotalProductionForEnergyProducerForTimeForTechnology(targetInvestor, currentTimeStep,
+ target.getPowerGeneratingTechnology(), false)
+ * 1
+ / centralForecastingYear
+ + reps.powerPlantDispatchPlanRepository
+ .calculateTotalProductionForEnergyProducerForTimeForTechnology(targetInvestor,
+ futureTimeStep, target.getPowerGeneratingTechnology(), true)
+ * (centralForecastingYear - 1) / centralForecastingYear;
+ totalProducedRenewableElectricity += producedRenewableElectricityByTechnologyByTargetInvestor;
+ double installedCapacityByTechnology = reps.powerPlantRepository
+ .calculateCapacityOfExpectedOperationalPowerPlantsByOwnerByTechnology(futureTimeStep - 1,
+ targetInvestor, target.getPowerGeneratingTechnology());
+ totalActualInstalledCapacity += installedCapacityByTechnology;
+ double plannedCapacityByTechnologyAndTargetInvestor = target.getTrend().getValue(futureTimeStep - 1);
+ totalPlannedCapacity += plannedCapacityByTechnologyAndTargetInvestor;
+ double plannedProducedRenewableElectricityByTechnologyAndTargetInvestor = plannedCapacityByTechnologyAndTargetInvestor
+ / installedCapacityByTechnology * producedRenewableElectricityByTechnologyByTargetInvestor;
+ // logger.warn("plannedProducedRenewable " +
+ // target.getPowerGeneratingTechnology().getName() + ": "
+ // +
+ // plannedProducedRenewableElectricityByTechnologyAndTargetInvestor
+ // + " = "
+ // + plannedCapacityByTechnologyAndTargetInvestor + "/" +
+ // installedCapacityByTechnology + "*"
+ // + producedRenewableElectricityByTechnologyByTargetInvestor);
+ plannedProductionByRenewables += Double
+ .isNaN(plannedProducedRenewableElectricityByTechnologyAndTargetInvestor) ? 0
+ : plannedProducedRenewableElectricityByTechnologyAndTargetInvestor;
+ }
+ }
+
+
+ double capReduction = government.isAdaptiveCapAdjustmentRelativeToNonSubsidisedProduction() ? calculateCapReductionForTimeStepRelativeToNonSubsidizedGeneration(
+ government, plannedProductionByRenewables, totalProducedRenewableElectricity, totalProduction,absoluteBase)
+ : calculateCapReductionForTimeStepRelativeToTotalGeneration(government,
+ plannedProductionByRenewables, totalProducedRenewableElectricity, totalProduction, absoluteBase);
+ return capReduction;
+ }
+
+ double calculateCapReductionForTimeStepRelativeToTotalGeneration(Government government,
+ double plannedProductionByRenewables, double totalProducedRenewableElectricity, double totalProduction,
+ double absoluteBase) {
+ double averageEmissionsPerMWh = (absoluteBase / totalProduction);
+ double plannedSavedEmissionsApproximation = plannedProductionByRenewables * averageEmissionsPerMWh;
+ double actualSavedEmissionsApproximation = totalProducedRenewableElectricity * averageEmissionsPerMWh;
+
+ double capReduction = 0;
+
+ if (!government.isDeviationFromResTargetAdjustment()) {
+ capReduction = actualSavedEmissionsApproximation * government.getAdaptiveCapCO2SavingsWeighingFactor();
+ } else {
+ capReduction = Math.max(0, actualSavedEmissionsApproximation - plannedSavedEmissionsApproximation)
+ * government.getAdaptiveCapCO2SavingsWeighingFactor();
+ }
+ // logger.warn("plannedSavedEmissionsApproximation: " +
+ // plannedSavedEmissionsApproximation
+ // + ", actualSavedEmissionsApproximation: " +
+ // actualSavedEmissionsApproximation + ", Cap reduction: "
+ // + capReduction);
+ // logger.warn("TimeSeries after: {}",
+ // government.getCo2CapTrend().getTimeSeries());
+ return capReduction;
+
+ }
+
+ double calculateCapReductionForTimeStepRelativeToNonSubsidizedGeneration(Government government,
+ double plannedProductionByRenewables, double totalProducedRenewableElectricity, double totalProduction,
+ double absoluteBase) {
+ double capReduction = Math.max(0, (totalProducedRenewableElectricity - plannedProductionByRenewables)
+ / (totalProduction - plannedProductionByRenewables))
+ * absoluteBase;
+ // double alternativeCapReduction =
+ // calculateCapReductionForTimeStepRelativeToTotalGeneration(government,
+ // plannedProductionByRenewables, totalProducedRenewableElectricity,
+ // totalProduction,absoluteBase);
+ // logger.warn("CapReductionToNonSub: {}, instead of to toal: {}",capReduction,alternativeCapReduction);
+>>>>>>> Jorn/feature/historicalCVar
+ return capReduction;
+
+ }
+}
diff --git a/emlab-generation/src/main/java/emlab/gen/role/investment/DismantlePowerPlantOperationalLossRole.java b/emlab-generation/src/main/java/emlab/gen/role/investment/DismantlePowerPlantOperationalLossRole.java
index 051deff3..846ec776 100644
--- a/emlab-generation/src/main/java/emlab/gen/role/investment/DismantlePowerPlantOperationalLossRole.java
+++ b/emlab-generation/src/main/java/emlab/gen/role/investment/DismantlePowerPlantOperationalLossRole.java
@@ -15,25 +15,39 @@
******************************************************************************/
package emlab.gen.role.investment;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
+import org.apache.commons.math.stat.regression.SimpleRegression;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
-import agentspring.role.Role;
+import agentspring.role.AbstractRole;
import agentspring.role.RoleComponent;
-import emlab.gen.domain.agent.EnergyProducer;
+import emlab.gen.domain.agent.CommoditySupplier;
+import emlab.gen.domain.agent.Government;
+import emlab.gen.domain.contract.CashFlow;
+import emlab.gen.domain.contract.Loan;
+import emlab.gen.domain.market.ClearingPoint;
+import emlab.gen.domain.market.DecarbonizationMarket;
+import emlab.gen.domain.market.electricity.ElectricitySpotMarket;
+import emlab.gen.domain.market.electricity.PowerPlantDispatchPlan;
+import emlab.gen.domain.market.electricity.Segment;
import emlab.gen.domain.technology.PowerPlant;
+import emlab.gen.domain.technology.Substance;
+import emlab.gen.domain.technology.SubstanceShareInFuelMix;
import emlab.gen.repository.Reps;
-import emlab.gen.role.AbstractEnergyProducerRole;
+import emlab.gen.util.MapValueComparator;
/**
- * {@link EnergyProducer}s dismantle {@link PowerPlant}s that are out of merit
- *
- * @author Emile Chappin @author
- * Alfredas
- * Chmieliauskas
+ * @author pradyumnabhagwat
*
*/
+
@RoleComponent
-public class DismantlePowerPlantOperationalLossRole extends AbstractEnergyProducerRole implements Role {
+public class DismantlePowerPlantOperationalLossRole extends AbstractRole {
@Autowired
Reps reps;
@@ -42,23 +56,424 @@ public Reps getReps() {
return reps;
}
- public void act(EnergyProducer producer) {
+ @Transactional
+ public void act(ElectricitySpotMarket market) {
+ if (getCurrentTick() > 0) {
+
+ for (PowerPlant plant : reps.powerPlantRepository.findOperationalPowerPlantsInMarket(market,
+ getCurrentTick())) {
+
+ double age = 0;
+ long currentLiftime = 0;
+ currentLiftime = getCurrentTick() - plant.getConstructionStartTime()
+ - plant.getTechnology().getExpectedLeadtime() - plant.getTechnology().getExpectedPermittime();
+
+ plant.setActualLifetime(currentLiftime);
+
+ age = (double) plant.getActualLifetime() / (((double) plant.getTechnology().getExpectedLifetime()));
+
+ plant.setAgeFraction((double) age);
+
+ if (plant.getAgeFraction() > 1.00D) {
+
+ double ModifiedOM = plant.getActualFixedOperatingCost()
+ * Math.pow((1 + (plant.getTechnology().getFixedOperatingCostModifierAfterLifetime())),
+ ((double) plant.getActualLifetime() - (((double) plant.getTechnology()
+ .getExpectedLifetime()))));
+
+ plant.setActualFixedOperatingCost(ModifiedOM);
+ }
+
+ long yearIterator = 1;
+
+ double profitability = 0;
+ double totalInvestment = 0;
+ for (yearIterator = 1; yearIterator <= market.getLookback() && yearIterator > 0; yearIterator++) {
+ double profit = 0;
+ double plantMarginalCost = 0;
+ double cost = 0;
+ double revenue = 0;
+ double energyGenerated = 0;
+ double calculatedOM = 0;
+ if ((getCurrentTick() - yearIterator) >= 0) {
+
+ for (Segment currentSegment : reps.segmentRepository.findAll()) {
+
+ PowerPlantDispatchPlan ppdp = new PowerPlantDispatchPlan();
+ ppdp = reps.powerPlantDispatchPlanRepository
+ .findOnePowerPlantDispatchPlanForPowerPlantForSegmentForTime(plant, currentSegment,
+ getCurrentTick() - yearIterator, false);
+
+ if (ppdp != null) {
+
+ double segmentMC = 0;
+ double mc = 0;
+ double acceptedAmount = 0;
+ double energyInSegment = 0;
+
+ acceptedAmount = ppdp.getAcceptedAmount();
+ mc = calculateMarginalCostExclCO2MarketCost(plant, getCurrentTick());
+ segmentMC = mc * acceptedAmount * currentSegment.getLengthInHours();
+ energyInSegment = acceptedAmount * currentSegment.getLengthInHours();
+ plantMarginalCost += segmentMC;
+ energyGenerated += energyInSegment;
+ }
+
+ }
+
+ for (CashFlow cf : reps.cashFlowRepository.findAllCashFlowsForPowerPlantForTime(plant,
+ (getCurrentTick() - yearIterator))) {
+
+ if (cf.getType() == CashFlow.FIXEDOMCOST) {
+ calculatedOM = cf.getMoney();
+ }
+
+ if (cf.getType() == CashFlow.COMMODITY || cf.getType() == CashFlow.CO2TAX
+ || cf.getType() == CashFlow.CO2AUCTION) {
+
+ cost = cost + cf.getMoney();
+ }
+
+ if (cf.getType() == CashFlow.ELECTRICITY_SPOT || cf.getType() == CashFlow.STRRESPAYMENT
+ || cf.getType() == CashFlow.SIMPLE_CAPACITY_MARKET) {
+ revenue = revenue + cf.getMoney();
+
+ }
+
+ }
+
+ double actualOM = (calculatedOM - (plant.getTechnology().getVariableOperatingCostinEURPerMWh() * 8760 * plant
+ .getTechnology().getCapacity()))
+ + (plant.getTechnology().getVariableOperatingCostinEURPerMWh() * energyGenerated);
+
+ cost = cost + plantMarginalCost + actualOM;
+ profit = (revenue - cost);
+
+ }
+ profitability += profit;
+ totalInvestment = plant.getTechnology().getInvestmentCost(plant.getConstructionStartTime())
+ * plant.getActualNominalCapacity();
+ }
+
+ plant.setProfitability((profitability / totalInvestment));
+
+ // logger.warn("1 ROI " + plant.getProfitability());
+ // logger.warn("prof " + plant.getProfitability() + " plant " +
+ // plant.getName());
+ }
+
+ for (PowerPlant plant : reps.powerPlantRepository.findOperationalPowerPlantsInMarket(market,
+ getCurrentTick())) {
+
+ if (plant.getOwner().equals(reps.targetInvestorRepository.findInvestorByMarket(market))) {
+
+ double prolongYearsOfDismantlng = plant.getTechnology().getMaximumLifeExtension()
+ + plant.getTechnology().getExpectedLifetime();
+
+ if (plant.getActualLifetime() > (prolongYearsOfDismantlng)) {
+
+ plant.dismantlePowerPlant(getCurrentTick());
+ }
+ }
+ }
+
+ for (PowerPlant plant : reps.powerPlantRepository
+ .findOperationalPowerPlantsByAscendingProfitabilityAndMarket(market, getCurrentTick())) {
+ // logger.warn("profitability " + plant.getProfitability());
+ if (plant.getProfitability() < 0) {
+
+ Map marginalCostMap = new HashMap();
+ Map meritOrder;
+
+ for (PowerPlant plant1 : reps.powerPlantRepository.findExpectedOperationalPowerPlantsInMarket(
+ market, getCurrentTick())) {
+ marginalCostMap.put(plant1, calculateMarginalCostExclCO2MarketCost(plant1, getCurrentTick()));
+
+ }
+
+ MapValueComparator comp = new MapValueComparator(marginalCostMap);
+ meritOrder = new TreeMap(comp);
+ meritOrder.putAll(marginalCostMap);
+
+ double mc = 0;
+ double OM = 0;
+ double sumProfit = 0;
+ double energy = 0;
+
+ double totalProfit = 0;
+ double demandGrowthFactor = 0;
+ double assignment = 0;
+
+ mc = calculateMarginalCostExclCO2MarketCost(plant, getCurrentTick());
+
+ OM = plant.getActualFixedOperatingCost();
+
+ if (getCurrentTick() == 1) {
+ demandGrowthFactor = (market.getDemandGrowthTrend().getValue(getCurrentTick()));
+ }
+ if (getCurrentTick() > 1) {
+ SimpleRegression sr = new SimpleRegression();
+ for (long time = getCurrentTick() - 1; time >= getCurrentTick()
+ - market.getBacklookingForDemandForecastinginDismantling()
+ && time >= 0; time = time - 1) {
+ sr.addData(time, market.getDemandGrowthTrend().getValue(time));
+
+ }
+
+ demandGrowthFactor = (market.getDemandGrowthTrend().getValue(getCurrentTick()));
+ }
+
+ double range = 0;
+
+ if (getCurrentTick() == 1) {
+ double max = reps.powerPlantRepository.calculateBaseCapacityOfOperationalPowerPlantsInMarket(
+ market, getCurrentTick());
+ double min = reps.powerPlantRepository.calculatePeakCapacityOfOperationalPowerPlantsInMarket(
+ market, getCurrentTick());
+
+ range = ((max + min) / 2);
+
+ }
+
+ if (getCurrentTick() > 1) {
+ SimpleRegression sr = new SimpleRegression();
+ for (long time = getCurrentTick() - 1; time >= getCurrentTick()
+ - market.getBacklookingForDemandForecastinginDismantling()
+ && time >= 0; time = time - 1) {
+
+ double max = reps.powerPlantRepository
+ .calculateBaseCapacityOfOperationalPowerPlantsInMarket(market, time);
+ double min = reps.powerPlantRepository
+ .calculatePeakCapacityOfOperationalPowerPlantsInMarket(market, time);
+
+ sr.addData(time, ((max + min) / 2));
+
+ }
+
+ range = (sr.predict(getCurrentTick()));
+ }
+
+ // * ((100 + r.nextGaussian() * 20) / 100);
+
+ for (Segment currentSegment : reps.segmentRepository.findAll()) {
+ double segmentCapacity = 0;
+ double segmentLoad = demandGrowthFactor
+ * reps.segmentLoadRepository.returnSegmentBaseLoadBySegmentAndMarket(currentSegment,
+ market);
+
+ if ((int) currentSegment.getSegmentID() != 1) {
+
+ double segmentPortion = (int) currentSegment.getSegmentID();
+
+ segmentCapacity = reps.powerPlantRepository
+ .calculateBaseCapacityOfOperationalPowerPlantsInMarket(market, getCurrentTick());
+
+ // reps.powerPlantRepository
+ // .calculateBaseCapacityOfOperationalPowerPlantsInMarket(market,
+ // getCurrentTick())
+ // - (range);
+ }
+
+ else {
+ segmentCapacity = reps.powerPlantRepository
+ .calculateBaseCapacityOfOperationalPowerPlantsInMarket(market, getCurrentTick());
+
+ // reps.powerPlantRepository
+ // .calculateBaseCapacityOfOperationalPowerPlantsInMarket(market,
+ // getCurrentTick())
+ // - (range);
+ }
+ // logger.warn("Capacity " + market.getName() + " DGF "
+ // + demandGrowthFactor);
+
+ if (segmentLoad > (segmentCapacity)) {
+ double price = 0;
+ double profit1 = 0;
+ price = market.getValueOfLostLoad();
+
+ profit1 = currentSegment.getLengthInHours()
+ * plant.getAvailableCapacity(getCurrentTick(), currentSegment,
+ reps.segmentRepository.count()) * (price - mc);
+
+ sumProfit += profit1;
+ energy += currentSegment.getLengthInHours()
+ * plant.getAvailableCapacity(getCurrentTick(), currentSegment,
+ reps.segmentRepository.count());
+ }
+
+ if (segmentLoad <= (segmentCapacity)) {
+ double price = 0;
+ double capacityCounter = 0;
+
+ for (Entry plantCost : meritOrder.entrySet()) {
+ PowerPlant plant1 = plantCost.getKey();
+
+ if (capacityCounter < segmentLoad) {
+ capacityCounter += plant1.getAvailableCapacity(getCurrentTick(), currentSegment,
+ reps.segmentRepository.count());
+ price = plantCost.getValue();
+ }
+
+ }
+
+ if (price > mc) {
+ double profit1 = 0;
+ profit1 = currentSegment.getLengthInHours()
+ * plant.getAvailableCapacity(getCurrentTick(), currentSegment,
+ reps.segmentRepository.count()) * (price - mc);
+
+ energy += currentSegment.getLengthInHours()
+ * plant.getAvailableCapacity(getCurrentTick(), currentSegment,
+ reps.segmentRepository.count());
+ sumProfit += profit1;
+ }
+ }
+ }
+
+ totalProfit = (sumProfit - ((OM - (plant.getTechnology().getVariableOperatingCostinEURPerMWh() * 8760 * plant
+ .getTechnology().getCapacity())) + (plant.getTechnology()
+ .getVariableOperatingCostinEURPerMWh() * energy)));
+
+ // logger.warn("2 Range " + (range1*mc));
+
+ if ((totalProfit + plant.getProfitability()) < 0) {
+
+ // REMAINING LOAN-----//
+ Loan loan = plant.getLoan();
+
+ if (loan != null) {
+
+ logger.info("Found a loan: {}", loan);
+ if (loan.getNumberOfPaymentsDone() < loan.getTotalNumberOfPayments()) {
+
+ double payment = loan.getAmountPerPayment()
+ * (loan.getTotalNumberOfPayments() - loan.getNumberOfPaymentsDone());
+
+ reps.nonTransactionalCreateRepository.createCashFlow(plant.getOwner(), loan.getTo(),
+ payment, CashFlow.LOAN, getCurrentTick(), loan.getRegardingPowerPlant());
+
+ loan.setNumberOfPaymentsDone(loan.getNumberOfPaymentsDone()
+ + (loan.getTotalNumberOfPayments() - loan.getNumberOfPaymentsDone()));
+
+ logger.info("DISMANTLING: Paying {} (euro) for remaining loan {}", payment, loan);
+ }
+ }
+ Loan downpayment = plant.getDownpayment();
+ if (downpayment != null) {
+ logger.info("Found downpayment");
+ if (downpayment.getNumberOfPaymentsDone() < downpayment.getTotalNumberOfPayments()) {
+
+ double payment = downpayment.getAmountPerPayment()
+ * (downpayment.getTotalNumberOfPayments() - downpayment
+ .getNumberOfPaymentsDone());
+ reps.nonTransactionalCreateRepository.createCashFlow(plant.getOwner(),
+ downpayment.getTo(), payment, CashFlow.DOWNPAYMENT, getCurrentTick(),
+ downpayment.getRegardingPowerPlant());
+
+ downpayment.setNumberOfPaymentsDone(downpayment.getNumberOfPaymentsDone()
+ + (downpayment.getTotalNumberOfPayments() - downpayment
+ .getNumberOfPaymentsDone()));
+
+ logger.info("DISMANTLING: Paying {} (euro) for remaining downpayment {}", payment,
+ downpayment);
+ }
+ }
+ // logger.warn("dismantled " + plant.getName());
+ plant.dismantlePowerPlant(getCurrentTick());
+
+ }
+ }
+ }
+ }
+ }
+
+ public double calculateMarginalCostExclCO2MarketCost(PowerPlant powerPlant, long clearingTick) {
+ double mc = 0d;
+ // fuel cost
+ mc += calculateMarginalFuelCost(powerPlant, clearingTick);
+ mc += calculateCO2TaxMarginalCost(powerPlant, clearingTick);
+ logger.info("Margincal cost excluding CO2 auction/market cost for plant {} is {}", powerPlant.getName(), mc);
+ return mc;
+ }
- logger.info("Dismantling plants if out of merit");
+ public double calculateMarginalFuelCost(PowerPlant powerPlant, long clearingTick) {
+ double fc = 0d;
+ // fuel cost for each fuel
+ for (SubstanceShareInFuelMix mix : powerPlant.getFuelMix()) {
- // dis-mantle plants when passed technical lifetime.
- for (PowerPlant plant : reps.powerPlantRepository.findOperationalPowerPlantsByOwner(producer, getCurrentTick())) {
- long horizon = producer.getPastTimeHorizon();
+ double amount = mix.getShare();
+ logger.info("Calculating need for fuel: {} units of {}", mix.getShare(), mix.getSubstance().getName());
+ double fuelPrice = findLastKnownPriceForSubstance(mix.getSubstance(), clearingTick);
+ fc += amount * fuelPrice;
+ logger.info("Calculating marginal cost and found a fuel price which is {} per unit of fuel", fuelPrice);
+ }
+
+ return fc;
+ }
- double requiredProfit = producer.getDismantlingRequiredOperatingProfit();
- if (calculateAveragePastOperatingProfit(plant, horizon) < requiredProfit) {
- logger.info("Dismantling power plant because it has had an operating loss (incl O&M cost) on average in the last "
- + horizon + " years: " + plant);
+ public double calculateCO2TaxMarginalCost(PowerPlant powerPlant, long tick) {
+ double co2Intensity = powerPlant.calculateEmissionIntensity();
+ Government government = reps.genericRepository.findFirst(Government.class);
+ double co2Tax = government.getCO2Tax(tick);
+ return co2Intensity * co2Tax;
+ }
- plant.dismantlePowerPlant(getCurrentTick());
+ public double findLastKnownPriceForSubstance(Substance substance, long clearingTick) {
+
+ DecarbonizationMarket market = reps.marketRepository.findFirstMarketBySubstance(substance);
+ if (market == null) {
+ logger.warn("No market found for {} so no price can be found", substance.getName());
+ return 0d;
+ } else {
+ return findLastKnownPriceOnMarket(market, clearingTick);
+ }
+ }
+ public double findLastKnownPriceOnMarket(DecarbonizationMarket market, long clearingTick) {
+ Double average = calculateAverageMarketPriceBasedOnClearingPoints(reps.clearingPointRepositoryOld
+ .findClearingPointsForMarketAndTime(market, clearingTick, false));
+ Substance substance = market.getSubstance();
+
+ if (average != null) {
+ logger.info("Average price found on market for this tick for {}", substance.getName());
+ return average;
+ }
+
+ average = calculateAverageMarketPriceBasedOnClearingPoints(reps.clearingPointRepositoryOld
+ .findClearingPointsForMarketAndTime(market, clearingTick - 1, false));
+ if (average != null) {
+ logger.info("Average price found on market for previous tick for {}", substance.getName());
+ return average;
+ }
+
+ if (market.getReferencePrice() > 0) {
+ logger.info("Found a reference price found for market for {}", substance.getName());
+ return market.getReferencePrice();
+ }
+
+ for (CommoditySupplier supplier : reps.genericRepository.findAll(CommoditySupplier.class)) {
+ if (supplier.getSubstance().equals(substance)) {
+
+ return supplier.getPriceOfCommodity().getValue(clearingTick);
}
}
+
+ logger.info("No price has been found for {}", substance.getName());
+ return 0d;
+ }
+
+ private Double calculateAverageMarketPriceBasedOnClearingPoints(Iterable clearingPoints) {
+ double priceTimesVolume = 0d;
+ double volume = 0d;
+
+ for (ClearingPoint point : clearingPoints) {
+ priceTimesVolume += point.getPrice() * point.getVolume();
+ volume += point.getVolume();
+ }
+ if (volume > 0) {
+ return priceTimesVolume / volume;
+ }
+ return null;
}
-}
+}
\ No newline at end of file
diff --git a/emlab-generation/src/main/java/emlab/gen/role/investment/GenericInvestmentRole.java b/emlab-generation/src/main/java/emlab/gen/role/investment/GenericInvestmentRole.java
index 74b8fd2f..1ecedb66 100644
--- a/emlab-generation/src/main/java/emlab/gen/role/investment/GenericInvestmentRole.java
+++ b/emlab-generation/src/main/java/emlab/gen/role/investment/GenericInvestmentRole.java
@@ -36,7 +36,7 @@ public class GenericInvestmentRole extends AbstractEne
public void act(T agent) {
// logger.warn(agent.getName() + " does " +
// agent.getInvestmentRole().getClass().toString());
- agent.getInvestmentRole().act(agent);
+ agent.getInvestmentRole().act( (EnergyProducer) agent);
}
diff --git a/emlab-generation/src/main/java/emlab/gen/role/investment/InvestInPowerGenerationTechnologiesRole.java b/emlab-generation/src/main/java/emlab/gen/role/investment/InvestInPowerGenerationTechnologiesRole.java
index d89d5aaf..0a54677f 100644
--- a/emlab-generation/src/main/java/emlab/gen/role/investment/InvestInPowerGenerationTechnologiesRole.java
+++ b/emlab-generation/src/main/java/emlab/gen/role/investment/InvestInPowerGenerationTechnologiesRole.java
@@ -33,11 +33,13 @@
import emlab.gen.domain.agent.BigBank;
import emlab.gen.domain.agent.EnergyProducer;
import emlab.gen.domain.agent.PowerPlantManufacturer;
+import emlab.gen.domain.agent.Regulator;
import emlab.gen.domain.agent.StrategicReserveOperator;
import emlab.gen.domain.contract.CashFlow;
import emlab.gen.domain.contract.Loan;
import emlab.gen.domain.gis.Zone;
import emlab.gen.domain.market.ClearingPoint;
+import emlab.gen.domain.market.capacity.CapacityMarket;
import emlab.gen.domain.market.electricity.ElectricitySpotMarket;
import emlab.gen.domain.market.electricity.Segment;
import emlab.gen.domain.market.electricity.SegmentLoad;
@@ -56,15 +58,15 @@
/**
* {@link EnergyProducer}s decide to invest in new {@link PowerPlant}
*
- * @author Emile Chappin @author Alfredas Chmieliauskas
+ * @author Emile Chappin @author
+ * Alfredas
+ * Chmieliauskas
* @author JCRichstein
*/
@Configurable
@NodeEntity
public class InvestInPowerGenerationTechnologiesRole extends GenericInvestmentRole
-implements
-Role,
-NodeBacked {
+ implements Role, NodeBacked {
@Transient
@Autowired
@@ -98,38 +100,42 @@ public void act(T agent) {
// logger.warn(expectedCO2Price.toString());
- //Demand
+ // Demand
Map expectedDemand = new HashMap();
- for(ElectricitySpotMarket elm : reps.template.findAll(ElectricitySpotMarket.class)){
+ for (ElectricitySpotMarket elm : reps.template.findAll(ElectricitySpotMarket.class)) {
GeometricTrendRegression gtr = new GeometricTrendRegression();
- for(long time = getCurrentTick(); time>getCurrentTick()-agent.getNumberOfYearsBacklookingForForecasting() && time>=0; time=time-1){
+ for (long time = getCurrentTick(); time > getCurrentTick()
+ - agent.getNumberOfYearsBacklookingForForecasting() && time >= 0; time = time - 1) {
gtr.addData(time, elm.getDemandGrowthTrend().getValue(time));
}
expectedDemand.put(elm, gtr.predict(futureTimePoint));
}
-
-
// Investment decision
// for (ElectricitySpotMarket market :
// reps.genericRepository.findAllAtRandom(ElectricitySpotMarket.class))
// {
ElectricitySpotMarket market = agent.getInvestorMarket();
- MarketInformation marketInformation = new MarketInformation(market, expectedDemand, expectedFuelPrices, expectedCO2Price.get(market)
- .doubleValue(), futureTimePoint);
- /*
- * if (marketInfoMap.containsKey(market) && marketInfoMap.get(market).time == futureTimePoint) { marketInformation = marketInfoMap.get(market); } else { marketInformation = new
- * MarketInformation(market, expectedFuelPrices, expectedCO2Price, futureTimePoint); marketInfoMap.put(market, marketInformation); }
- */
+ MarketInformation marketInformation = new MarketInformation(market, expectedDemand, expectedFuelPrices,
+ expectedCO2Price.get(market).doubleValue(), futureTimePoint);
+ /*
+ * if (marketInfoMap.containsKey(market) &&
+ * marketInfoMap.get(market).time == futureTimePoint) {
+ * marketInformation = marketInfoMap.get(market); } else {
+ * marketInformation = new MarketInformation(market,
+ * expectedFuelPrices, expectedCO2Price, futureTimePoint);
+ * marketInfoMap.put(market, marketInformation); }
+ */
// logger.warn(agent + " is expecting a CO2 price of " +
// expectedCO2Price.get(market) + " Euro/MWh at timepoint "
// + futureTimePoint + " in Market " + market);
- // logger.warn("Agent {} found the expected prices to be {}", agent,
+ // logger.warn("Agent {} found the expected prices to be {}", agent,
// marketInformation.expectedElectricityPricesPerSegment);
- // logger.warn("Agent {} found that the installed capacity in the market {} in future to be "
+ // logger.warn("Agent {} found that the installed capacity in the market
+ // {} in future to be "
// + marketInformation.capacitySum +
// "and expectde maximum demand to be "
// + marketInformation.maxExpectedLoad, agent, market);
@@ -144,11 +150,14 @@ public void act(T agent) {
// if too much capacity of this technology in the pipeline (not
// limited to the 5 years)
double expectedInstalledCapacityOfTechnology = reps.powerPlantRepository
- .calculateCapacityOfExpectedOperationalPowerPlantsInMarketAndTechnology(market, technology, futureTimePoint);
- PowerGeneratingTechnologyTarget technologyTarget = reps.powerGenerationTechnologyTargetRepository.findOneByTechnologyAndMarket(technology, market);
- if(technologyTarget!=null){
+ .calculateCapacityOfExpectedOperationalPowerPlantsInMarketAndTechnology(market, technology,
+ futureTimePoint);
+ PowerGeneratingTechnologyTarget technologyTarget = reps.powerGenerationTechnologyTargetRepository
+ .findOneByTechnologyAndMarket(technology, market);
+ if (technologyTarget != null) {
double technologyTargetCapacity = technologyTarget.getTrend().getValue(futureTimePoint);
- expectedInstalledCapacityOfTechnology = (technologyTargetCapacity > expectedInstalledCapacityOfTechnology) ? technologyTargetCapacity : expectedInstalledCapacityOfTechnology;
+ expectedInstalledCapacityOfTechnology = (technologyTargetCapacity > expectedInstalledCapacityOfTechnology)
+ ? technologyTargetCapacity : expectedInstalledCapacityOfTechnology;
}
double pgtNodeLimit = Double.MAX_VALUE;
PowerGeneratingTechnologyNodeLimit pgtLimit = reps.powerGeneratingTechnologyNodeLimitRepository
@@ -162,41 +171,48 @@ public void act(T agent) {
double expectedOwnedTotalCapacityInMarket = reps.powerPlantRepository
.calculateCapacityOfExpectedOperationalPowerPlantsInMarketByOwner(market, futureTimePoint, agent);
double expectedOwnedCapacityInMarketOfThisTechnology = reps.powerPlantRepository
- .calculateCapacityOfExpectedOperationalPowerPlantsInMarketByOwnerAndTechnology(market, technology, futureTimePoint,
- agent);
- double capacityOfTechnologyInPipeline = reps.powerPlantRepository.calculateCapacityOfPowerPlantsByTechnologyInPipeline(
- technology, getCurrentTick());
- double operationalCapacityOfTechnology = reps.powerPlantRepository.calculateCapacityOfOperationalPowerPlantsByTechnology(
- technology, getCurrentTick());
+ .calculateCapacityOfExpectedOperationalPowerPlantsInMarketByOwnerAndTechnology(market, technology,
+ futureTimePoint, agent);
+ double capacityOfTechnologyInPipeline = reps.powerPlantRepository
+ .calculateCapacityOfPowerPlantsByTechnologyInPipeline(technology, getCurrentTick());
+ double operationalCapacityOfTechnology = reps.powerPlantRepository
+ .calculateCapacityOfOperationalPowerPlantsByTechnology(technology, getCurrentTick());
double capacityInPipelineInMarket = reps.powerPlantRepository
.calculateCapacityOfPowerPlantsByMarketInPipeline(market, getCurrentTick());
if ((expectedInstalledCapacityOfTechnology + plant.getActualNominalCapacity())
/ (marketInformation.maxExpectedLoad + plant.getActualNominalCapacity()) > technology
- .getMaximumInstalledCapacityFractionInCountry()) {
+ .getMaximumInstalledCapacityFractionInCountry()) {
// logger.warn(agent +
- // " will not invest in {} technology because there's too much of this type in the market",
+ // " will not invest in {} technology because there's too much
+ // of this type in the market",
// technology);
- } else if ((expectedInstalledCapacityOfTechnologyInNode + plant.getActualNominalCapacity()) > pgtNodeLimit) {
+ } else
+ if ((expectedInstalledCapacityOfTechnologyInNode + plant.getActualNominalCapacity()) > pgtNodeLimit) {
} else if (expectedOwnedCapacityInMarketOfThisTechnology > expectedOwnedTotalCapacityInMarket
* technology.getMaximumInstalledCapacityFractionPerAgent()) {
// logger.warn(agent +
- // " will not invest in {} technology because there's too much capacity planned by him",
+ // " will not invest in {} technology because there's too much
+ // capacity planned by him",
// technology);
} else if (capacityInPipelineInMarket > 0.2 * marketInformation.maxExpectedLoad) {
- // logger.warn("Not investing because more than 20% of demand in pipeline.");
+ // logger.warn("Not investing because more than 20% of demand in
+ // pipeline.");
} else if ((capacityOfTechnologyInPipeline > 2.0 * operationalCapacityOfTechnology)
&& capacityOfTechnologyInPipeline > 9000) { // TODO:
// reflects that you cannot expand a technology out of zero.
// logger.warn(agent +
- // " will not invest in {} technology because there's too much capacity in the pipeline",
+ // " will not invest in {} technology because there's too much
+ // capacity in the pipeline",
// technology);
- } else if (plant.getActualInvestedCapital() * (1 - agent.getDebtRatioOfInvestments()) > agent
- .getDownpaymentFractionOfCash() * agent.getCash()) {
+ } else if (plant.getActualInvestedCapital()
+ * (1 - agent.getDebtRatioOfInvestments()) > agent.getDownpaymentFractionOfCash()
+ * agent.getCash()) {
// logger.warn(agent +
- // " will not invest in {} technology as he does not have enough money for downpayment",
+ // " will not invest in {} technology as he does not have enough
+ // money for downpayment",
// technology);
} else {
@@ -204,10 +220,12 @@ public void act(T agent) {
for (Substance fuel : technology.getFuels()) {
myFuelPrices.put(fuel, expectedFuelPrices.get(fuel));
}
- Set fuelMix = calculateFuelMix(plant, myFuelPrices, expectedCO2Price.get(market));
+ Set fuelMix = calculateFuelMix(plant, myFuelPrices,
+ expectedCO2Price.get(market));
plant.setFuelMix(fuelMix);
- double expectedMarginalCost = determineExpectedMarginalCost(plant, expectedFuelPrices, expectedCO2Price.get(market));
+ double expectedMarginalCost = determineExpectedMarginalCost(plant, expectedFuelPrices,
+ expectedCO2Price.get(market));
double runningHours = 0d;
double expectedGrossProfit = 0d;
@@ -217,13 +235,13 @@ public void act(T agent) {
// be used here to determine the expected profit. Maybe not
// though...
for (SegmentLoad segmentLoad : market.getLoadDurationCurve()) {
- double expectedElectricityPrice = marketInformation.expectedElectricityPricesPerSegment.get(segmentLoad
- .getSegment());
+ double expectedElectricityPrice = marketInformation.expectedElectricityPricesPerSegment
+ .get(segmentLoad.getSegment());
double hours = segmentLoad.getSegment().getLengthInHours();
if (expectedMarginalCost <= expectedElectricityPrice) {
runningHours += hours;
- expectedGrossProfit += (expectedElectricityPrice - expectedMarginalCost) * hours
- * plant.getAvailableCapacity(futureTimePoint, segmentLoad.getSegment(), numberOfSegments);
+ expectedGrossProfit += (expectedElectricityPrice - expectedMarginalCost) * hours * plant
+ .getAvailableCapacity(futureTimePoint, segmentLoad.getSegment(), numberOfSegments);
}
}
@@ -233,7 +251,8 @@ public void act(T agent) {
// expect to meet minimum running hours?
if (runningHours < plant.getTechnology().getMinimumRunningHours()) {
// logger.warn(agent+
- // " will not invest in {} technology as he expect to have {} running, which is lower then required",
+ // " will not invest in {} technology as he expect to have
+ // {} running, which is lower then required",
// technology, runningHours);
} else {
@@ -241,6 +260,83 @@ public void act(T agent) {
// plant.getActualNominalCapacity();
double operatingProfit = expectedGrossProfit - fixedOMCost;
+ // logger.warn("Operating Profit without Capacity Revenue" +
+ // operatingProfit);
+ Segment peakSegment = reps.segmentRepository.findPeakSegmentforMarket(market);
+
+ Zone zoneTemp = market.getZone();
+ Regulator regulator = reps.regulatorRepository.findRegulatorForZone(zoneTemp);
+ CapacityMarket cMarket = reps.capacityMarketRepository.findCapacityMarketForZone(zoneTemp);
+
+ double capacityRevenue = 0d;
+ double sumCapacityRevenue = 0d;
+ // the following is a piece of bad coding - as it requires
+ // each agent to have the property of
+ // 'issimplecapacitymarketenabled. While the concept of
+ // 'enablingCapacityMarket' should not be related
+ // to an agent but to the zone in question., and therefore
+ // be accessed by the zone as well.
+
+ if ((agent.isSimpleCapacityMarketEnabled()) && (regulator != null)) {
+
+ long time = 0l;
+ for (time = getCurrentTick(); time > getCurrentTick()
+ - agent.getNumberOfYearsBacklookingForForecasting() && time > 0; time = time - 1) {
+ double capacityRevenueTemp = reps.capacityMarketRepository
+ .findOneClearingPointForTimeAndCapacityMarket(time, cMarket).getPrice();
+ sumCapacityRevenue += capacityRevenueTemp;
+ }
+ // logger.warn(" And capacity (peak segment) is"
+ // + plant.getExpectedAvailableCapacity(futureTimePoint,
+ // peakSegment, numberOfSegments));
+ // logger.warn(" And capacity (null) is"
+ // + plant.getExpectedAvailableCapacity(futureTimePoint,
+ // null, numberOfSegments));
+
+ // -------expected capacity revenue, N years in the
+ // future, is the AVERAGE of the past few years of
+ // capacity revenue-----
+ capacityRevenue = plant.getExpectedAvailableCapacity(futureTimePoint, peakSegment,
+ numberOfSegments) * sumCapacityRevenue / (getCurrentTick() - time);
+
+ } else {
+ capacityRevenue = 0;
+ }
+ // logger.warn("Capacity Revenue" + capacityRevenue);
+
+ operatingProfit = operatingProfit + capacityRevenue;
+
+ // Feed In Premium revenues :
+ // if feed in premiumImplemented, then get regulator's
+ // feedInPremiumFactor and then
+ // if technology is eligible,
+ //
+
+ // if (reps.renewableSupportSchemeRepository.findAll() !=
+ // null) // change
+ // this
+ // later
+ // to
+ // make
+ // it
+ // specific
+ // to
+ // feed
+ // in
+ // tariff
+
+ // {
+ // for (RenewableSupportSchemeTender scheme :
+ // reps.renewableSupportSchemeRepository.findAll()) {
+
+ // if
+ // (scheme.getPowerGeneratingTechnologiesEligible().contains(technology))
+ // operatingProfit = operatingProfit * (1 +
+ // regulator.getFeedInPremiumFactor());
+ //
+ // }
+
+ // }
// TODO Alter discount rate on the basis of the amount
// in long-term contracts?
@@ -256,31 +352,35 @@ public void act(T agent) {
// Creation of out cash-flow during power plant building
// phase (note that the cash-flow is negative!)
TreeMap discountedProjectCapitalOutflow = calculateSimplePowerPlantInvestmentCashFlow(
- technology.getDepreciationTime(), (int) plant.getActualLeadtime(),
+ technology.getDepreciationTime(), (int) plant.getActualLeadTime(),
plant.getActualInvestedCapital(), 0);
// Creation of in cashflow during operation
TreeMap discountedProjectCashInflow = calculateSimplePowerPlantInvestmentCashFlow(
- technology.getDepreciationTime(), (int) plant.getActualLeadtime(), 0, operatingProfit);
+ technology.getDepreciationTime(), (int) plant.getActualLeadTime(), 0, operatingProfit);
double discountedCapitalCosts = npv(discountedProjectCapitalOutflow, wacc);// are
// defined
// negative!!
// plant.getActualNominalCapacity();
- // logger.warn("Agent {} found that the discounted capital for technology {} to be "
+ // logger.warn("Agent {} found that the discounted capital
+ // for technology {} to be "
// + discountedCapitalCosts, agent,
// technology);
double discountedOpProfit = npv(discountedProjectCashInflow, wacc);
- // logger.warn("Agent {} found that the projected discounted inflows for technology {} to be "
+ // logger.warn("Agent {} found that the projected discounted
+ // inflows for technology {} to be "
// + discountedOpProfit,
// agent, technology);
double projectValue = discountedOpProfit + discountedCapitalCosts;
+ // logger.warn("Project value" + projectValue);
// logger.warn(
- // "Agent {} found the project value for technology {} to be "
+ // "Agent {} found the project value for technology {} to be
+ // "
// + Math.round(projectValue /
// plant.getActualNominalCapacity()) +
// " EUR/kW (running hours: "
@@ -307,28 +407,31 @@ public void act(T agent) {
}
if (bestTechnology != null) {
- // logger.warn("Agent {} invested in technology {} at tick " + getCurrentTick(), agent, bestTechnology);
+ // logger.warn("Agent {} invested in technology {} at tick " +
+ // getCurrentTick(), agent, bestTechnology);
PowerPlant plant = new PowerPlant();
plant.specifyAndPersist(getCurrentTick(), agent, getNodeForZone(market.getZone()), bestTechnology);
PowerPlantManufacturer manufacturer = reps.genericRepository.findFirst(PowerPlantManufacturer.class);
BigBank bigbank = reps.genericRepository.findFirst(BigBank.class);
- double investmentCostPayedByEquity = plant.getActualInvestedCapital() * (1 - agent.getDebtRatioOfInvestments());
+ double investmentCostPayedByEquity = plant.getActualInvestedCapital()
+ * (1 - agent.getDebtRatioOfInvestments());
double investmentCostPayedByDebt = plant.getActualInvestedCapital() * agent.getDebtRatioOfInvestments();
double downPayment = investmentCostPayedByEquity;
createSpreadOutDownPayments(agent, manufacturer, downPayment, plant);
- double amount = determineLoanAnnuities(investmentCostPayedByDebt, plant.getTechnology().getDepreciationTime(),
- agent.getLoanInterestRate());
+ double amount = determineLoanAnnuities(investmentCostPayedByDebt,
+ plant.getTechnology().getDepreciationTime(), agent.getLoanInterestRate());
// logger.warn("Loan amount is: " + amount);
- Loan loan = reps.loanRepository.createLoan(agent, bigbank, amount, plant.getTechnology().getDepreciationTime(),
- getCurrentTick(), plant);
+ Loan loan = reps.loanRepository.createLoan(agent, bigbank, amount,
+ plant.getTechnology().getDepreciationTime(), getCurrentTick(), plant);
// Create the loan
plant.createOrUpdateLoan(loan);
} else {
- // logger.warn("{} found no suitable technology anymore to invest in at tick "
+ // logger.warn("{} found no suitable technology anymore to invest in
+ // at tick "
// + getCurrentTick(), agent);
// agent will not participate in the next round of investment if
// he does not invest now
@@ -341,9 +444,9 @@ public void act(T agent) {
// Creates n downpayments of equal size in each of the n building years of a
// power plant
@Transactional
- private void createSpreadOutDownPayments(EnergyProducer agent, PowerPlantManufacturer manufacturer, double totalDownPayment,
- PowerPlant plant) {
- int buildingTime = (int) plant.getActualLeadtime();
+ private void createSpreadOutDownPayments(EnergyProducer agent, PowerPlantManufacturer manufacturer,
+ double totalDownPayment, PowerPlant plant) {
+ int buildingTime = (int) plant.getActualLeadTime();
reps.nonTransactionalCreateRepository.createCashFlow(agent, manufacturer, totalDownPayment / buildingTime,
CashFlow.DOWNPAYMENT, getCurrentTick(), plant);
Loan downpayment = reps.loanRepository.createLoan(agent, manufacturer, totalDownPayment / buildingTime,
@@ -357,29 +460,37 @@ private void setNotWillingToInvest(EnergyProducer agent) {
}
/**
- * Predicts fuel prices for {@link futureTimePoint} using a geometric trend regression forecast. Only predicts fuels that are
- * traded on a commodity market.
+ * Predicts fuel prices for {@link futureTimePoint} using a geometric trend
+ * regression forecast. Only predicts fuels that are traded on a commodity
+ * market.
+ *
* @param agent
* @param futureTimePoint
* @return Map of predicted prices.
*/
- public Map predictFuelPrices(EnergyProducer agent, long futureTimePoint){
+ public Map predictFuelPrices(EnergyProducer agent, long futureTimePoint) {
// Fuel Prices
Map expectedFuelPrices = new HashMap();
for (Substance substance : reps.substanceRepository.findAllSubstancesTradedOnCommodityMarkets()) {
- //Find Clearing Points for the last 5 years (counting current year as one of the last 5 years).
+ // Find Clearing Points for the last 5 years (counting current year
+ // as one of the last 5 years).
Iterable cps = reps.clearingPointRepository
- .findAllClearingPointsForSubstanceTradedOnCommodityMarkesAndTimeRange(substance, getCurrentTick()
- - (agent.getNumberOfYearsBacklookingForForecasting() - 1), getCurrentTick(), false);
- //logger.warn("{}, {}", getCurrentTick()-(agent.getNumberOfYearsBacklookingForForecasting()-1), getCurrentTick());
- //Create regression object
+ .findAllClearingPointsForSubstanceTradedOnCommodityMarkesAndTimeRange(substance,
+ getCurrentTick() - (agent.getNumberOfYearsBacklookingForForecasting() - 1),
+ getCurrentTick(), false);
+ // logger.warn("{}, {}",
+ // getCurrentTick()-(agent.getNumberOfYearsBacklookingForForecasting()-1),
+ // getCurrentTick());
+ // Create regression object
GeometricTrendRegression gtr = new GeometricTrendRegression();
for (ClearingPoint clearingPoint : cps) {
- //logger.warn("CP {}: {} , in" + clearingPoint.getTime(), substance.getName(), clearingPoint.getPrice());
+ // logger.warn("CP {}: {} , in" + clearingPoint.getTime(),
+ // substance.getName(), clearingPoint.getPrice());
gtr.addData(clearingPoint.getTime(), clearingPoint.getPrice());
}
expectedFuelPrices.put(substance, gtr.predict(futureTimePoint));
- //logger.warn("Forecast {}: {}, in Step " + futureTimePoint, substance, expectedFuelPrices.get(substance));
+ // logger.warn("Forecast {}: {}, in Step " + futureTimePoint,
+ // substance, expectedFuelPrices.get(substance));
}
return expectedFuelPrices;
}
@@ -409,7 +520,8 @@ private double npv(TreeMap netCashFlow, double wacc) {
return npv;
}
- public double determineExpectedMarginalCost(PowerPlant plant, Map expectedFuelPrices, double expectedCO2Price) {
+ public double determineExpectedMarginalCost(PowerPlant plant, Map expectedFuelPrices,
+ double expectedCO2Price) {
double mc = determineExpectedMarginalFuelCost(plant, expectedFuelPrices);
double co2Intensity = plant.calculateEmissionIntensity();
mc += co2Intensity * expectedCO2Price;
@@ -442,27 +554,35 @@ private class MarketInformation {
Map meritOrder;
double capacitySum;
- MarketInformation(ElectricitySpotMarket market, Map expectedDemand, Map fuelPrices, double co2price, long time) {
+ MarketInformation(ElectricitySpotMarket market, Map expectedDemand,
+ Map fuelPrices, double co2price, long time) {
// determine expected power prices
expectedElectricityPricesPerSegment = new HashMap();
Map marginalCostMap = new HashMap();
capacitySum = 0d;
// get merit order for this market
- for (PowerPlant plant : reps.powerPlantRepository.findExpectedOperationalPowerPlantsInMarket(market, time)) {
+ for (PowerPlant plant : reps.powerPlantRepository.findExpectedOperationalPowerPlantsInMarket(market,
+ time)) {
double plantMarginalCost = determineExpectedMarginalCost(plant, fuelPrices, co2price);
marginalCostMap.put(plant, plantMarginalCost);
capacitySum += plant.getActualNominalCapacity();
}
- //get difference between technology target and expected operational capacity
- for(PowerGeneratingTechnologyTarget pggt : reps.powerGenerationTechnologyTargetRepository.findAllByMarket(market)){
- double expectedTechnologyCapacity = reps.powerPlantRepository.calculateCapacityOfExpectedOperationalPowerPlantsInMarketAndTechnology(market, pggt.getPowerGeneratingTechnology(), time);
+ // get difference between technology target and expected operational
+ // capacity
+ for (PowerGeneratingTechnologyTarget pggt : reps.powerGenerationTechnologyTargetRepository
+ .findAllByMarket(market)) {
+ double expectedTechnologyCapacity = reps.powerPlantRepository
+ .calculateCapacityOfExpectedOperationalPowerPlantsInMarketAndTechnology(market,
+ pggt.getPowerGeneratingTechnology(), time);
double targetDifference = pggt.getTrend().getValue(time) - expectedTechnologyCapacity;
- if(targetDifference > 0){
+ if (targetDifference > 0) {
PowerPlant plant = new PowerPlant();
- plant.specifyNotPersist(getCurrentTick(), new EnergyProducer(), reps.powerGridNodeRepository.findFirstPowerGridNodeByElectricitySpotMarket(market), pggt.getPowerGeneratingTechnology());
+ plant.specifyNotPersist(getCurrentTick(), new EnergyProducer(),
+ reps.powerGridNodeRepository.findFirstPowerGridNodeByElectricitySpotMarket(market),
+ pggt.getPowerGeneratingTechnology());
plant.setActualNominalCapacity(targetDifference);
double plantMarginalCost = determineExpectedMarginalCost(plant, fuelPrices, co2price);
marginalCostMap.put(plant, plantMarginalCost);
@@ -496,7 +616,8 @@ private class MarketInformation {
double plantCapacity = 0d;
// Determine available capacity in the future in this
// segment
- plantCapacity = plant.getExpectedAvailableCapacity(time, segmentLoad.getSegment(), numberOfSegments);
+ plantCapacity = plant.getExpectedAvailableCapacity(time, segmentLoad.getSegment(),
+ numberOfSegments);
totalCapacityAvailable += plantCapacity;
// logger.warn("Capacity of plant " + plant.toString() +
// " is " +
@@ -517,8 +638,8 @@ private class MarketInformation {
double reservePrice = 0;
double reserveVolume = 0;
for (StrategicReserveOperator operator : strategicReserveOperatorRepository.findAll()) {
- ElectricitySpotMarket market1 = reps.marketRepository.findElectricitySpotMarketForZone(operator
- .getZone());
+ ElectricitySpotMarket market1 = reps.marketRepository
+ .findElectricitySpotMarketForZone(operator.getZone());
if (market.getNodeId().intValue() == market1.getNodeId().intValue()) {
reservePrice = operator.getReservePriceSR();
reserveVolume = operator.getReserveVolume();
diff --git a/emlab-generation/src/main/java/emlab/gen/role/investment/InvestInPowerGenerationTechnologiesStandard.java b/emlab-generation/src/main/java/emlab/gen/role/investment/InvestInPowerGenerationTechnologiesStandard.java
index 9f9e90fa..62794459 100644
--- a/emlab-generation/src/main/java/emlab/gen/role/investment/InvestInPowerGenerationTechnologiesStandard.java
+++ b/emlab-generation/src/main/java/emlab/gen/role/investment/InvestInPowerGenerationTechnologiesStandard.java
@@ -63,15 +63,15 @@
/**
* {@link EnergyProducer}s decide to invest in new {@link PowerPlant}
*
- * @author Emile Chappin @author Alfredas Chmieliauskas
+ * @author Emile Chappin @author
+ * Alfredas
+ * Chmieliauskas
* @author JCRichstein
*/
@Configurable
@NodeEntity
public class InvestInPowerGenerationTechnologiesStandard extends GenericInvestmentRole
-implements
-Role,
-NodeBacked {
+ implements Role, NodeBacked {
@Transient
@Autowired
@@ -101,51 +101,55 @@ public void act(T agent) {
// CO2
Map expectedCO2Price = determineExpectedCO2PriceInclTaxAndFundamentalForecast(
- futureTimePoint,
- agent.getNumberOfYearsBacklookingForForecasting(), 0, getCurrentTick());
+ futureTimePoint, agent.getNumberOfYearsBacklookingForForecasting(), 0, getCurrentTick());
// logger.warn("{} expects CO2 prices {}", agent.getName(),
// expectedCO2Price);
Map expectedCO2PriceOld = determineExpectedCO2PriceInclTax(futureTimePoint,
agent.getNumberOfYearsBacklookingForForecasting(), getCurrentTick());
- // logger.warn("{} used to expect CO2 prices {}", agent.getName(),
- // expectedCO2PriceOld);
+ // logger.warn("{} used to expect CO2 prices {}",
+ // agent.getName(),
+ // expectedCO2PriceOld);
// logger.warn(expectedCO2Price.toString());
- //Demand
+ // Demand
Map expectedDemand = new HashMap();
- for(ElectricitySpotMarket elm : reps.template.findAll(ElectricitySpotMarket.class)){
+ for (ElectricitySpotMarket elm : reps.template.findAll(ElectricitySpotMarket.class)) {
GeometricTrendRegression gtr = new GeometricTrendRegression();
- for(long time = getCurrentTick(); time>getCurrentTick()-agent.getNumberOfYearsBacklookingForForecasting() && time>=0; time=time-1){
+ for (long time = getCurrentTick(); time > getCurrentTick()
+ - agent.getNumberOfYearsBacklookingForForecasting() && time >= 0; time = time - 1) {
gtr.addData(time, elm.getDemandGrowthTrend().getValue(time));
}
expectedDemand.put(elm, gtr.predict(futureTimePoint));
}
-
-
// Investment decision
// for (ElectricitySpotMarket market :
// reps.genericRepository.findAllAtRandom(ElectricitySpotMarket.class))
// {
ElectricitySpotMarket market = agent.getInvestorMarket();
- MarketInformation marketInformation = new MarketInformation(market, expectedDemand, expectedFuelPrices, expectedCO2Price.get(market)
- .doubleValue(), futureTimePoint);
- /*
- * if (marketInfoMap.containsKey(market) && marketInfoMap.get(market).time == futureTimePoint) { marketInformation = marketInfoMap.get(market); } else { marketInformation = new
- * MarketInformation(market, expectedFuelPrices, expectedCO2Price, futureTimePoint); marketInfoMap.put(market, marketInformation); }
- */
+ MarketInformation marketInformation = new MarketInformation(market, expectedDemand, expectedFuelPrices,
+ expectedCO2Price.get(market).doubleValue(), futureTimePoint);
+ /*
+ * if (marketInfoMap.containsKey(market) &&
+ * marketInfoMap.get(market).time == futureTimePoint) {
+ * marketInformation = marketInfoMap.get(market); } else {
+ * marketInformation = new MarketInformation(market,
+ * expectedFuelPrices, expectedCO2Price, futureTimePoint);
+ * marketInfoMap.put(market, marketInformation); }
+ */
// logger.warn(agent + " is expecting a CO2 price of " +
// expectedCO2Price.get(market) + " Euro/MWh at timepoint "
// + futureTimePoint + " in Market " + market);
- // logger.warn("Agent {} found the expected prices to be {}", agent,
+ // logger.warn("Agent {} found the expected prices to be {}", agent,
// marketInformation.expectedElectricityPricesPerSegment);
- // logger.warn("Agent {} found that the installed capacity in the market {} in future to be "
+ // logger.warn("Agent {} found that the installed capacity in the market
+ // {} in future to be "
// + marketInformation.capacitySum +
// "and expectde maximum demand to be "
// + marketInformation.maxExpectedLoad, agent, market);
@@ -167,12 +171,12 @@ public void act(T agent) {
* For dispatchable technologies just choose a random node. For
* intermittent evaluate all possibilities.
*/
- if(technology.isIntermittent())
+ if (technology.isIntermittent())
possibleInstallationNodes = reps.powerGridNodeRepository.findAllPowerGridNodesByZone(market.getZone());
- else{
+ else {
possibleInstallationNodes = new LinkedList();
- ((LinkedList) possibleInstallationNodes).add(reps.powerGridNodeRepository
- .findAllPowerGridNodesByZone(market.getZone()).iterator().next());
+ ((LinkedList) possibleInstallationNodes).add(
+ reps.powerGridNodeRepository.findAllPowerGridNodesByZone(market.getZone()).iterator().next());
}
// logger.warn("Calculating for " + technology.getName() +
@@ -186,13 +190,14 @@ public void act(T agent) {
// if too much capacity of this technology in the pipeline (not
// limited to the 5 years)
double expectedInstalledCapacityOfTechnology = reps.powerPlantRepository
- .calculateCapacityOfExpectedOperationalPowerPlantsInMarketAndTechnology(market, technology, futureTimePoint);
+ .calculateCapacityOfExpectedOperationalPowerPlantsInMarketAndTechnology(market, technology,
+ futureTimePoint);
PowerGeneratingTechnologyTarget technologyTarget = reps.powerGenerationTechnologyTargetRepository
.findOneByTechnologyAndMarket(technology, market);
if (technologyTarget != null) {
double technologyTargetCapacity = technologyTarget.getTrend().getValue(futureTimePoint);
- expectedInstalledCapacityOfTechnology = (technologyTargetCapacity > expectedInstalledCapacityOfTechnology) ? technologyTargetCapacity
- : expectedInstalledCapacityOfTechnology;
+ expectedInstalledCapacityOfTechnology = (technologyTargetCapacity > expectedInstalledCapacityOfTechnology)
+ ? technologyTargetCapacity : expectedInstalledCapacityOfTechnology;
}
double pgtNodeLimit = Double.MAX_VALUE;
PowerGeneratingTechnologyNodeLimit pgtLimit = reps.powerGeneratingTechnologyNodeLimitRepository
@@ -204,43 +209,51 @@ public void act(T agent) {
.calculateCapacityOfExpectedOperationalPowerPlantsByNodeAndTechnology(plant.getLocation(),
technology, futureTimePoint);
double expectedOwnedTotalCapacityInMarket = reps.powerPlantRepository
- .calculateCapacityOfExpectedOperationalPowerPlantsInMarketByOwner(market, futureTimePoint, agent);
- double expectedOwnedCapacityInMarketOfThisTechnology = reps.powerPlantRepository
- .calculateCapacityOfExpectedOperationalPowerPlantsInMarketByOwnerAndTechnology(market, technology, futureTimePoint,
+ .calculateCapacityOfExpectedOperationalPowerPlantsInMarketByOwner(market, futureTimePoint,
agent);
- double capacityOfTechnologyInPipeline = reps.powerPlantRepository.calculateCapacityOfPowerPlantsByTechnologyInPipeline(
- technology, getCurrentTick());
- double operationalCapacityOfTechnology = reps.powerPlantRepository.calculateCapacityOfOperationalPowerPlantsByTechnology(
- technology, getCurrentTick());
+ double expectedOwnedCapacityInMarketOfThisTechnology = reps.powerPlantRepository
+ .calculateCapacityOfExpectedOperationalPowerPlantsInMarketByOwnerAndTechnology(market,
+ technology, futureTimePoint, agent);
+ double capacityOfTechnologyInPipeline = reps.powerPlantRepository
+ .calculateCapacityOfPowerPlantsByTechnologyInPipeline(technology, getCurrentTick());
+ double operationalCapacityOfTechnology = reps.powerPlantRepository
+ .calculateCapacityOfOperationalPowerPlantsByTechnology(technology, getCurrentTick());
double capacityInPipelineInMarket = reps.powerPlantRepository
.calculateCapacityOfPowerPlantsByMarketInPipeline(market, getCurrentTick());
if ((expectedInstalledCapacityOfTechnology + plant.getActualNominalCapacity())
/ (marketInformation.maxExpectedLoad + plant.getActualNominalCapacity()) > technology
- .getMaximumInstalledCapacityFractionInCountry()) {
+ .getMaximumInstalledCapacityFractionInCountry()) {
// logger.warn(agent +
- // " will not invest in {} technology because there's too much of this type in the market",
+ // " will not invest in {} technology because there's too
+ // much of this type in the market",
// technology);
- } else if ((expectedInstalledCapacityOfTechnologyInNode + plant.getActualNominalCapacity()) > pgtNodeLimit) {
+ } else if ((expectedInstalledCapacityOfTechnologyInNode
+ + plant.getActualNominalCapacity()) > pgtNodeLimit) {
} else if (expectedOwnedCapacityInMarketOfThisTechnology > expectedOwnedTotalCapacityInMarket
* technology.getMaximumInstalledCapacityFractionPerAgent()) {
// logger.warn(agent +
- // " will not invest in {} technology because there's too much capacity planned by him",
+ // " will not invest in {} technology because there's too
+ // much capacity planned by him",
// technology);
} else if (capacityInPipelineInMarket > 0.2 * marketInformation.maxExpectedLoad) {
- // logger.warn("Not investing because more than 20% of demand in pipeline.");
+ // logger.warn("Not investing because more than 20% of
+ // demand in pipeline.");
} else if ((capacityOfTechnologyInPipeline > 2.0 * operationalCapacityOfTechnology)
&& capacityOfTechnologyInPipeline > 9000) { // TODO:
// reflects that you cannot expand a technology out of zero.
// logger.warn(agent +
- // " will not invest in {} technology because there's too much capacity in the pipeline",
+ // " will not invest in {} technology because there's too
+ // much capacity in the pipeline",
// technology);
- } else if (plant.getActualInvestedCapital() * (1 - agent.getDebtRatioOfInvestments()) > agent
- .getDownpaymentFractionOfCash() * agent.getCash()) {
+ } else if (plant.getActualInvestedCapital()
+ * (1 - agent.getDebtRatioOfInvestments()) > agent.getDownpaymentFractionOfCash()
+ * agent.getCash()) {
// logger.warn(agent +
- // " will not invest in {} technology as he does not have enough money for downpayment",
+ // " will not invest in {} technology as he does not have
+ // enough money for downpayment",
// technology);
} else {
@@ -248,10 +261,12 @@ public void act(T agent) {
for (Substance fuel : technology.getFuels()) {
myFuelPrices.put(fuel, expectedFuelPrices.get(fuel));
}
- Set