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 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; @@ -261,22 +276,22 @@ 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; if (technology.isIntermittent()) - expectedGrossProfit += (expectedElectricityPrice - expectedMarginalCost) - * hours - * plant.getActualNominalCapacity() - * reps.intermittentTechnologyNodeLoadFactorRepository - .findIntermittentTechnologyNodeLoadFactorForNodeAndTechnology(node, - technology).getLoadFactorForSegment(segmentLoad.getSegment()); + expectedGrossProfit += (expectedElectricityPrice - expectedMarginalCost) * hours + * plant.getActualNominalCapacity() + * reps.intermittentTechnologyNodeLoadFactorRepository + .findIntermittentTechnologyNodeLoadFactorForNodeAndTechnology(node, + technology) + .getLoadFactorForSegment(segmentLoad.getSegment()); else - expectedGrossProfit += (expectedElectricityPrice - expectedMarginalCost) - * hours - * plant.getAvailableCapacity(futureTimePoint, segmentLoad.getSegment(), numberOfSegments); + expectedGrossProfit += (expectedElectricityPrice - expectedMarginalCost) * hours + * plant.getAvailableCapacity(futureTimePoint, segmentLoad.getSegment(), + numberOfSegments); } } @@ -286,7 +301,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 { @@ -295,6 +311,12 @@ public void act(T agent) { double operatingProfit = expectedGrossProfit - fixedOMCost; + // Feed In Premium revenues : + // if feed in premiumImplemented, then get regulator's + // feedInPremiumFactor and then + // if technology is eligible, + // + // TODO Alter discount rate on the basis of the amount // in long-term contracts? // TODO Alter discount rate on the basis of other stuff, @@ -309,24 +331,26 @@ 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); @@ -339,7 +363,8 @@ public void act(T agent) { // } // 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: " + runningHours + "", @@ -352,7 +377,8 @@ public void act(T agent) { // / (-discountedCapitalCosts); /* - * Divide by capacity, in order not to favour large power plants (which have the single largest NPV + * Divide by capacity, in order not to favour large + * power plants (which have the single largest NPV */ if (projectValue > 0 && projectValue / plant.getActualNominalCapacity() > highestValue) { @@ -376,21 +402,23 @@ public void act(T agent) { 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 @@ -403,9 +431,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, @@ -419,30 +447,38 @@ 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 SimpleRegression gtr = new SimpleRegression(); 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()); } gtr.addData(getCurrentTick(), findLastKnownPriceForSubstance(substance, getCurrentTick())); 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; } @@ -472,7 +508,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; @@ -505,21 +542,24 @@ 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 + // get difference between technology target and expected operational + // capacity for (TargetInvestor targetInvestor : reps.targetInvestorRepository.findAllByMarket(market)) { if (!(targetInvestor instanceof StochasticTargetInvestor)) { for (PowerGeneratingTechnologyTarget pggt : targetInvestor.getPowerGenerationTechnologyTargets()) { @@ -547,9 +587,10 @@ private class MarketInformation { long contructionTime = getCurrentTick() + pggt.getPowerGeneratingTechnology().getExpectedLeadtime() + pggt.getPowerGeneratingTechnology().getExpectedPermittime(); - for (long investmentTimeStep = contructionTime + 1; investmentTimeStep <= time; investmentTimeStep = investmentTimeStep + 1) { - expectedTechnologyAddition += (pggt.getTrend().getValue(investmentTimeStep) - pggt - .getTrend().getValue(investmentTimeStep - 1)); + for (long investmentTimeStep = contructionTime + + 1; investmentTimeStep <= time; investmentTimeStep = investmentTimeStep + 1) { + expectedTechnologyAddition += (pggt.getTrend().getValue(investmentTimeStep) + - pggt.getTrend().getValue(investmentTimeStep - 1)); } if (expectedTechnologyAddition > 0) { PowerPlant plant = new PowerPlant(); @@ -592,7 +633,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 " + @@ -613,8 +655,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(); @@ -677,15 +719,15 @@ protected HashMap determineExpectedCO2PriceInclTa if (i > 1) { expectedRegressionCO2Price = sr.predict(futureTimePoint); expectedRegressionCO2Price = Math.max(0, expectedRegressionCO2Price); - expectedRegressionCO2Price = Math - .min(expectedRegressionCO2Price, government.getCo2Penalty(futureTimePoint)); + expectedRegressionCO2Price = Math.min(expectedRegressionCO2Price, + government.getCo2Penalty(futureTimePoint)); } else { expectedRegressionCO2Price = lastPrice; } ClearingPoint expectedCO2ClearingPoint = reps.clearingPointRepository.findClearingPointForMarketAndTime( co2Auction, getCurrentTick() - + reps.genericRepository.findFirst(DecarbonizationModel.class).getCentralForecastingYear(), + + reps.genericRepository.findFirst(DecarbonizationModel.class).getCentralForecastingYear(), true); expectedCO2Price = (expectedCO2ClearingPoint == null) ? 0 : expectedCO2ClearingPoint.getPrice(); expectedCO2Price = (expectedCO2Price + expectedRegressionCO2Price) / 2; diff --git a/emlab-generation/src/main/java/emlab/gen/role/investment/InvestInPowerGenerationTechnologiesStandard.java.orig b/emlab-generation/src/main/java/emlab/gen/role/investment/InvestInPowerGenerationTechnologiesStandard.java.orig new file mode 100644 index 00000000..8f1b8ef1 --- /dev/null +++ b/emlab-generation/src/main/java/emlab/gen/role/investment/InvestInPowerGenerationTechnologiesStandard.java.orig @@ -0,0 +1,712 @@ +/******************************************************************************* + * Copyright 2014 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.investment; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; + +import org.apache.commons.math.stat.regression.SimpleRegression; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.data.annotation.Transient; +import org.springframework.data.neo4j.annotation.NodeEntity; +import org.springframework.data.neo4j.aspects.core.NodeBacked; +import org.springframework.data.neo4j.support.Neo4jTemplate; +import org.springframework.transaction.annotation.Transactional; + +import agentspring.role.Role; +import emlab.gen.domain.agent.BigBank; +import emlab.gen.domain.agent.DecarbonizationModel; +import emlab.gen.domain.agent.EnergyProducer; +import emlab.gen.domain.agent.Government; +import emlab.gen.domain.agent.PowerPlantManufacturer; +import emlab.gen.domain.agent.StochasticTargetInvestor; +import emlab.gen.domain.agent.StrategicReserveOperator; +import emlab.gen.domain.agent.TargetInvestor; +import emlab.gen.domain.contract.CashFlow; +import emlab.gen.domain.contract.Loan; +import emlab.gen.domain.gis.Zone; +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.market.electricity.SegmentLoad; +import emlab.gen.domain.policy.PowerGeneratingTechnologyTarget; +import emlab.gen.domain.technology.PowerGeneratingTechnology; +import emlab.gen.domain.technology.PowerGeneratingTechnologyNodeLimit; +import emlab.gen.domain.technology.PowerGridNode; +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.repository.StrategicReserveOperatorRepository; +import emlab.gen.util.GeometricTrendRegression; +import emlab.gen.util.MapValueComparator; + +/** + * {@link EnergyProducer}s decide to invest in new {@link PowerPlant} + * + * @author Emile Chappin @author Alfredas Chmieliauskas + * @author JCRichstein + */ +@Configurable +@NodeEntity +public class InvestInPowerGenerationTechnologiesStandard extends GenericInvestmentRole +implements +Role, +NodeBacked { + + @Transient + @Autowired + Reps reps; + + @Transient + @Autowired + Neo4jTemplate template; + + @Transient + @Autowired + StrategicReserveOperatorRepository strategicReserveOperatorRepository; + + // market expectations + @Transient + Map marketInfoMap = new HashMap(); + + @Override + public void act(T agent) { + + long futureTimePoint = getCurrentTick() + agent.getInvestmentFutureTimeHorizon(); + // logger.warn(agent + " is looking at timepoint " + futureTimePoint); + + // ==== Expectations === + + Map expectedFuelPrices = predictFuelPrices(agent, futureTimePoint); + + // CO2 + Map expectedCO2Price = determineExpectedCO2PriceInclTaxAndFundamentalForecast( + 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(expectedCO2Price.toString()); + + //Demand + Map expectedDemand = new HashMap(); + 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){ + 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); } + */ + + // 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, + // marketInformation.expectedElectricityPricesPerSegment); + + // 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); + + double highestValue = Double.MIN_VALUE; + PowerGeneratingTechnology bestTechnology = null; + PowerGridNode bestNode = null; + + for (PowerGeneratingTechnology technology : reps.genericRepository.findAll(PowerGeneratingTechnology.class)) { + + DecarbonizationModel model = reps.genericRepository.findAll(DecarbonizationModel.class).iterator().next(); + + if (technology.isIntermittent() && model.isNoPrivateIntermittentRESInvestment()) + continue; + + Iterable possibleInstallationNodes; + + /* + * For dispatchable technologies just choose a random node. For + * intermittent evaluate all possibilities. + */ + if(technology.isIntermittent()) + possibleInstallationNodes = reps.powerGridNodeRepository.findAllPowerGridNodesByZone(market.getZone()); + else{ + possibleInstallationNodes = new LinkedList(); + ((LinkedList) possibleInstallationNodes).add(reps.powerGridNodeRepository + .findAllPowerGridNodesByZone(market.getZone()).iterator().next()); + } + + // logger.warn("Calculating for " + technology.getName() + + // ", for Nodes: " + // + possibleInstallationNodes.toString()); + + for (PowerGridNode node : possibleInstallationNodes) { + + PowerPlant plant = new PowerPlant(); + plant.specifyNotPersist(getCurrentTick(), agent, node, technology); + // 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) { + double technologyTargetCapacity = technologyTarget.getTrend().getValue(futureTimePoint); + expectedInstalledCapacityOfTechnology = (technologyTargetCapacity > expectedInstalledCapacityOfTechnology) ? technologyTargetCapacity + : expectedInstalledCapacityOfTechnology; + } + double pgtNodeLimit = Double.MAX_VALUE; + PowerGeneratingTechnologyNodeLimit pgtLimit = reps.powerGeneratingTechnologyNodeLimitRepository + .findOneByTechnologyAndNode(technology, plant.getLocation()); + if (pgtLimit != null) { + pgtNodeLimit = pgtLimit.getUpperCapacityLimit(futureTimePoint); + } + double expectedInstalledCapacityOfTechnologyInNode = reps.powerPlantRepository + .calculateCapacityOfExpectedOperationalPowerPlantsByNodeAndTechnology(plant.getLocation(), + technology, futureTimePoint); + 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()); + double capacityInPipelineInMarket = reps.powerPlantRepository + .calculateCapacityOfPowerPlantsByMarketInPipeline(market, getCurrentTick()); + + if ((expectedInstalledCapacityOfTechnology + plant.getActualNominalCapacity()) + / (marketInformation.maxExpectedLoad + plant.getActualNominalCapacity()) > technology + .getMaximumInstalledCapacityFractionInCountry()) { + // logger.warn(agent + + // " 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 (expectedOwnedCapacityInMarketOfThisTechnology > expectedOwnedTotalCapacityInMarket + * technology.getMaximumInstalledCapacityFractionPerAgent()) { + // logger.warn(agent + + // " 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."); + + } 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", + // technology); + } 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", + // technology); + } else { + + Map myFuelPrices = new HashMap(); + for (Substance fuel : technology.getFuels()) { + myFuelPrices.put(fuel, expectedFuelPrices.get(fuel)); + } + Set fuelMix = calculateFuelMix(plant, myFuelPrices, expectedCO2Price.get(market)); + plant.setFuelMix(fuelMix); + + double expectedMarginalCost = determineExpectedMarginalCost(plant, expectedFuelPrices, expectedCO2Price.get(market)); + double runningHours = 0d; + double expectedGrossProfit = 0d; + + long numberOfSegments = reps.segmentRepository.count(); + + // TODO somehow the prices of long-term contracts could also + // be used here to determine the expected profit. Maybe not + // though... + for (SegmentLoad segmentLoad : market.getLoadDurationCurve()) { + double expectedElectricityPrice = marketInformation.expectedElectricityPricesPerSegment.get(segmentLoad + .getSegment()); + double hours = segmentLoad.getSegment().getLengthInHours(); + if (expectedMarginalCost <= expectedElectricityPrice) { + runningHours += hours; + if (technology.isIntermittent()) + expectedGrossProfit += (expectedElectricityPrice - expectedMarginalCost) + * hours + * plant.getActualNominalCapacity() + * reps.intermittentTechnologyNodeLoadFactorRepository + .findIntermittentTechnologyNodeLoadFactorForNodeAndTechnology(node, + technology).getLoadFactorForSegment(segmentLoad.getSegment()); + else + expectedGrossProfit += (expectedElectricityPrice - expectedMarginalCost) + * hours + * plant.getAvailableCapacity(futureTimePoint, segmentLoad.getSegment(), numberOfSegments); + } + } + + // logger.warn(agent + + // "expects technology {} to have {} running", technology, + // runningHours); + // 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", + // technology, runningHours); + } else { + + double fixedOMCost = calculateFixedOperatingCost(plant, getCurrentTick());// / + // plant.getActualNominalCapacity(); + + double operatingProfit = expectedGrossProfit - fixedOMCost; + + // TODO Alter discount rate on the basis of the amount + // in long-term contracts? + // TODO Alter discount rate on the basis of other stuff, + // such as amount of money, market share, portfolio + // size. + + // Calculation of weighted average cost of capital, + // based on the companies debt-ratio + double wacc = (1 - agent.getDebtRatioOfInvestments()) * agent.getEquityInterestRate() + + agent.getDebtRatioOfInvestments() * agent.getLoanInterestRate(); + + // 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(), + plant.getActualInvestedCapital(), 0); + // Creation of in cashflow during operation + TreeMap discountedProjectCashInflow = calculateSimplePowerPlantInvestmentCashFlow( + 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 " + // + discountedCapitalCosts, agent, + // technology); + + double discountedOpProfit = npv(discountedProjectCashInflow, wacc); + + // logger.warn("Agent {} found that the projected discounted inflows for technology {} to be " + // + discountedOpProfit, + // agent, technology); + + double projectValue = discountedOpProfit + discountedCapitalCosts; + + // if (technology.isIntermittent()) { + // logger.warn(technology + "in " + node.getName() + + // ", NPV: " + projectValue + // + ", GrossProfit: " + expectedGrossProfit); + // } + + // logger.warn( + // "Agent {} found the project value for technology {} to be " + // + Math.round(projectValue / + // plant.getActualNominalCapacity()) + // + " EUR/kW (running hours: " + runningHours + "", + // agent, technology); + + // double projectTotalValue = projectValuePerMW * + // plant.getActualNominalCapacity(); + + // double projectReturnOnInvestment = discountedOpProfit + // / (-discountedCapitalCosts); + + /* + * Divide by capacity, in order not to favour large power plants (which have the single largest NPV + */ + + if (projectValue > 0 && projectValue / plant.getActualNominalCapacity() > highestValue) { + highestValue = projectValue / plant.getActualNominalCapacity(); + bestTechnology = plant.getTechnology(); + bestNode = node; + } + } + + } + + } + } + + if (bestTechnology != null) { + // logger.warn("Agent {} invested in technology {} at tick " + + // getCurrentTick(), agent, bestTechnology); + + PowerPlant plant = new PowerPlant(); + plant.specifyAndPersist(getCurrentTick(), agent, bestNode, bestTechnology); + PowerPlantManufacturer manufacturer = reps.genericRepository.findFirst(PowerPlantManufacturer.class); + BigBank bigbank = reps.genericRepository.findFirst(BigBank.class); + + 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()); + // logger.warn("Loan amount is: " + amount); + 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 " + // + getCurrentTick(), agent); + // agent will not participate in the next round of investment if + // he does not invest now + setNotWillingToInvest(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(); + reps.nonTransactionalCreateRepository.createCashFlow(agent, manufacturer, totalDownPayment / buildingTime, + CashFlow.DOWNPAYMENT, getCurrentTick(), plant); + Loan downpayment = reps.loanRepository.createLoan(agent, manufacturer, totalDownPayment / buildingTime, + buildingTime - 1, getCurrentTick(), plant); + plant.createOrUpdateDownPayment(downpayment); + } + + @Transactional + private void setNotWillingToInvest(EnergyProducer agent) { + agent.setWillingToInvest(false); + } + + /** + * 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){ + // 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). + Iterable cps = reps.clearingPointRepository + .findAllClearingPointsForSubstanceTradedOnCommodityMarkesAndTimeRange(substance, getCurrentTick() + - (agent.getNumberOfYearsBacklookingForForecasting() - 1), getCurrentTick(), false); + //logger.warn("{}, {}", getCurrentTick()-(agent.getNumberOfYearsBacklookingForForecasting()-1), getCurrentTick()); + //Create regression object + SimpleRegression gtr = new SimpleRegression(); + for (ClearingPoint clearingPoint : cps) { + //logger.warn("CP {}: {} , in" + clearingPoint.getTime(), substance.getName(), clearingPoint.getPrice()); + gtr.addData(clearingPoint.getTime(), clearingPoint.getPrice()); + } + gtr.addData(getCurrentTick(), findLastKnownPriceForSubstance(substance, getCurrentTick())); + expectedFuelPrices.put(substance, gtr.predict(futureTimePoint)); + //logger.warn("Forecast {}: {}, in Step " + futureTimePoint, substance, expectedFuelPrices.get(substance)); + } + return expectedFuelPrices; + } + + // Create a powerplant investment and operation cash-flow in the form of a + // map. If only investment, or operation costs should be considered set + // totalInvestment or operatingProfit to 0 + private TreeMap calculateSimplePowerPlantInvestmentCashFlow(int depriacationTime, int buildingTime, + double totalInvestment, double operatingProfit) { + TreeMap investmentCashFlow = new TreeMap(); + double equalTotalDownPaymentInstallement = totalInvestment / buildingTime; + for (int i = 0; i < buildingTime; i++) { + investmentCashFlow.put(new Integer(i), -equalTotalDownPaymentInstallement); + } + for (int i = buildingTime; i < depriacationTime + buildingTime; i++) { + investmentCashFlow.put(new Integer(i), operatingProfit); + } + + return investmentCashFlow; + } + + private double npv(TreeMap netCashFlow, double wacc) { + double npv = 0; + for (Integer iterator : netCashFlow.keySet()) { + npv += netCashFlow.get(iterator).doubleValue() / Math.pow(1 + wacc, iterator.intValue()); + } + return npv; + } + + public double determineExpectedMarginalCost(PowerPlant plant, Map expectedFuelPrices, double expectedCO2Price) { + double mc = determineExpectedMarginalFuelCost(plant, expectedFuelPrices); + double co2Intensity = plant.calculateEmissionIntensity(); + mc += co2Intensity * expectedCO2Price; + return mc; + } + + public double determineExpectedMarginalFuelCost(PowerPlant powerPlant, Map expectedFuelPrices) { + double fc = 0d; + for (SubstanceShareInFuelMix mix : powerPlant.getFuelMix()) { + double amount = mix.getShare(); + double fuelPrice = expectedFuelPrices.get(mix.getSubstance()); + fc += amount * fuelPrice; + } + return fc; + } + + private PowerGridNode getNodeForZone(Zone zone) { + for (PowerGridNode node : reps.genericRepository.findAll(PowerGridNode.class)) { + if (node.getZone().equals(zone)) { + return node; + } + } + return null; + } + + private class MarketInformation { + + Map expectedElectricityPricesPerSegment; + double maxExpectedLoad = 0d; + Map meritOrder; + double capacitySum; + + 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)) { + + double plantMarginalCost = determineExpectedMarginalCost(plant, fuelPrices, co2price); + marginalCostMap.put(plant, plantMarginalCost); + capacitySum += plant.getActualNominalCapacity(); + } + + //get difference between technology target and expected operational capacity +<<<<<<< HEAD + for (TargetInvestor targetInvestor : reps.targetInvestorRepository.findAll()) { +======= + for (TargetInvestor targetInvestor : reps.targetInvestorRepository.findAllByMarket(market)) { +>>>>>>> Jorn/feature/historicalCVar + if (!(targetInvestor instanceof StochasticTargetInvestor)) { + for (PowerGeneratingTechnologyTarget pggt : targetInvestor.getPowerGenerationTechnologyTargets()) { + double expectedTechnologyCapacity = reps.powerPlantRepository + .calculateCapacityOfExpectedOperationalPowerPlantsInMarketAndTechnology(market, + pggt.getPowerGeneratingTechnology(), time); + double targetDifference = pggt.getTrend().getValue(time) - expectedTechnologyCapacity; + if (targetDifference > 0) { + PowerPlant plant = new PowerPlant(); + plant.specifyNotPersist(getCurrentTick(), new EnergyProducer(), + reps.powerGridNodeRepository.findFirstPowerGridNodeByElectricitySpotMarket(market), + pggt.getPowerGeneratingTechnology()); + plant.setActualNominalCapacity(targetDifference); + double plantMarginalCost = determineExpectedMarginalCost(plant, fuelPrices, co2price); + marginalCostMap.put(plant, plantMarginalCost); + capacitySum += targetDifference; + } + } + } else { + for (PowerGeneratingTechnologyTarget pggt : targetInvestor.getPowerGenerationTechnologyTargets()) { + double expectedTechnologyCapacity = reps.powerPlantRepository + .calculateCapacityOfExpectedOperationalPowerPlantsInMarketAndTechnology(market, + pggt.getPowerGeneratingTechnology(), time); + double expectedTechnologyAddition = 0; + long contructionTime = getCurrentTick() + + pggt.getPowerGeneratingTechnology().getExpectedLeadtime() + + pggt.getPowerGeneratingTechnology().getExpectedPermittime(); + for (long investmentTimeStep = contructionTime + 1; investmentTimeStep <= time; investmentTimeStep = investmentTimeStep + 1) { + expectedTechnologyAddition += (pggt.getTrend().getValue(investmentTimeStep) - pggt + .getTrend().getValue(investmentTimeStep - 1)); + } + if (expectedTechnologyAddition > 0) { + PowerPlant plant = new PowerPlant(); + plant.specifyNotPersist(getCurrentTick(), new EnergyProducer(), + reps.powerGridNodeRepository.findFirstPowerGridNodeByElectricitySpotMarket(market), + pggt.getPowerGeneratingTechnology()); + plant.setActualNominalCapacity(expectedTechnologyAddition); + double plantMarginalCost = determineExpectedMarginalCost(plant, fuelPrices, co2price); + marginalCostMap.put(plant, plantMarginalCost); + capacitySum += expectedTechnologyAddition; + } + } + } + + } + + MapValueComparator comp = new MapValueComparator(marginalCostMap); + meritOrder = new TreeMap(comp); + meritOrder.putAll(marginalCostMap); + + long numberOfSegments = reps.segmentRepository.count(); + + double demandFactor = expectedDemand.get(market).doubleValue(); + + // find expected prices per segment given merit order + for (SegmentLoad segmentLoad : market.getLoadDurationCurve()) { + + double expectedSegmentLoad = segmentLoad.getBaseLoad() * demandFactor; + + if (expectedSegmentLoad > maxExpectedLoad) { + maxExpectedLoad = expectedSegmentLoad; + } + + double segmentSupply = 0d; + double segmentPrice = 0d; + double totalCapacityAvailable = 0d; + + for (Entry plantCost : meritOrder.entrySet()) { + PowerPlant plant = plantCost.getKey(); + double plantCapacity = 0d; + // Determine available capacity in the future in this + // segment + plantCapacity = plant.getExpectedAvailableCapacity(time, segmentLoad.getSegment(), numberOfSegments); + totalCapacityAvailable += plantCapacity; + // logger.warn("Capacity of plant " + plant.toString() + + // " is " + + // plantCapacity/plant.getActualNominalCapacity()); + if (segmentSupply < expectedSegmentLoad) { + segmentSupply += plantCapacity; + segmentPrice = plantCost.getValue(); + } + + } + + // logger.warn("Segment " + + // segmentLoad.getSegment().getSegmentID() + " supply equals " + + // segmentSupply + " and segment demand equals " + + // expectedSegmentLoad); + + // Find strategic reserve operator for the market. + double reservePrice = 0; + double reserveVolume = 0; + for (StrategicReserveOperator operator : strategicReserveOperatorRepository.findAll()) { + ElectricitySpotMarket market1 = reps.marketRepository.findElectricitySpotMarketForZone(operator + .getZone()); + if (market.getNodeId().intValue() == market1.getNodeId().intValue()) { + reservePrice = operator.getReservePriceSR(); + reserveVolume = operator.getReserveVolume(); + } + } + + if (segmentSupply >= expectedSegmentLoad + && ((totalCapacityAvailable - expectedSegmentLoad) <= (reserveVolume))) { + expectedElectricityPricesPerSegment.put(segmentLoad.getSegment(), reservePrice); + // logger.warn("Price: "+ + // expectedElectricityPricesPerSegment); + } else if (segmentSupply >= expectedSegmentLoad + && ((totalCapacityAvailable - expectedSegmentLoad) > (reserveVolume))) { + expectedElectricityPricesPerSegment.put(segmentLoad.getSegment(), segmentPrice); + // logger.warn("Price: "+ + // expectedElectricityPricesPerSegment); + } else { + expectedElectricityPricesPerSegment.put(segmentLoad.getSegment(), market.getValueOfLostLoad()); + } + + } + } + } + + /** + * 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. + * @return + */ + protected HashMap determineExpectedCO2PriceInclTaxAndFundamentalForecast( + long futureTimePoint, long yearsLookingBackForRegression, int adjustmentForDetermineFuelMix, + long clearingTick) { + HashMap co2Prices = new HashMap(); + CO2Auction co2Auction = reps.genericRepository.findFirst(CO2Auction.class); + Iterable cps = reps.clearingPointRepository.findAllClearingPointsForMarketAndTimeRange( + co2Auction, clearingTick - yearsLookingBackForRegression + 1 - adjustmentForDetermineFuelMix, + clearingTick - adjustmentForDetermineFuelMix, false); + // Create regression object and calculate average + SimpleRegression sr = new SimpleRegression(); + Government government = reps.template.findAll(Government.class).iterator().next(); + double lastPrice = 0; + double averagePrice = 0; + int i = 0; + for (ClearingPoint clearingPoint : cps) { + sr.addData(clearingPoint.getTime(), clearingPoint.getPrice()); + lastPrice = clearingPoint.getPrice(); + averagePrice += lastPrice; + i++; + } + averagePrice = averagePrice / i; + double expectedCO2Price; + double expectedRegressionCO2Price; + if (i > 1) { + expectedRegressionCO2Price = sr.predict(futureTimePoint); + expectedRegressionCO2Price = Math.max(0, expectedRegressionCO2Price); + expectedRegressionCO2Price = Math + .min(expectedRegressionCO2Price, government.getCo2Penalty(futureTimePoint)); + } else { + expectedRegressionCO2Price = lastPrice; + } + ClearingPoint expectedCO2ClearingPoint = reps.clearingPointRepository.findClearingPointForMarketAndTime( + co2Auction, + getCurrentTick() + + reps.genericRepository.findFirst(DecarbonizationModel.class).getCentralForecastingYear(), + true); + expectedCO2Price = (expectedCO2ClearingPoint == null) ? 0 : expectedCO2ClearingPoint.getPrice(); + expectedCO2Price = (expectedCO2Price + expectedRegressionCO2Price) / 2; + for (ElectricitySpotMarket esm : reps.marketRepository.findAllElectricitySpotMarkets()) { + double nationalCo2MinPriceinFutureTick = reps.nationalGovernmentRepository + .findNationalGovernmentByElectricitySpotMarket(esm).getMinNationalCo2PriceTrend() + .getValue(futureTimePoint); + double co2PriceInCountry = 0d; + if (expectedCO2Price > nationalCo2MinPriceinFutureTick) { + co2PriceInCountry = expectedCO2Price; + } else { + co2PriceInCountry = nationalCo2MinPriceinFutureTick; + } + co2PriceInCountry += reps.genericRepository.findFirst(Government.class).getCO2Tax(futureTimePoint); + co2Prices.put(esm, Double.valueOf(co2PriceInCountry)); + } + return co2Prices; + } + +} diff --git a/emlab-generation/src/main/java/emlab/gen/role/investment/InvestInPowerGenerationTechnologiesWithCO2ForecastRole.java b/emlab-generation/src/main/java/emlab/gen/role/investment/InvestInPowerGenerationTechnologiesWithCO2ForecastRole.java index e0d5c300..848cf9c4 100644 --- a/emlab-generation/src/main/java/emlab/gen/role/investment/InvestInPowerGenerationTechnologiesWithCO2ForecastRole.java +++ b/emlab-generation/src/main/java/emlab/gen/role/investment/InvestInPowerGenerationTechnologiesWithCO2ForecastRole.java @@ -269,11 +269,11 @@ 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 @@ -355,7 +355,7 @@ public void act(T agent) { @Transactional private void createSpreadOutDownPayments(EnergyProducer agent, PowerPlantManufacturer manufacturer, double totalDownPayment, PowerPlant plant) { - int buildingTime = (int) plant.getActualLeadtime(); + 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, diff --git a/emlab-generation/src/main/java/emlab/gen/role/investment/InvestWithHistoricalCVar.java b/emlab-generation/src/main/java/emlab/gen/role/investment/InvestWithHistoricalCVar.java new file mode 100644 index 00000000..30131262 --- /dev/null +++ b/emlab-generation/src/main/java/emlab/gen/role/investment/InvestWithHistoricalCVar.java @@ -0,0 +1,793 @@ +/******************************************************************************* + * Copyright 2014 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.investment; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; + +import org.apache.commons.math.stat.regression.SimpleRegression; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.data.annotation.Transient; +import org.springframework.data.neo4j.annotation.NodeEntity; +import org.springframework.data.neo4j.aspects.core.NodeBacked; +import org.springframework.data.neo4j.support.Neo4jTemplate; +import org.springframework.transaction.annotation.Transactional; + +import agentspring.role.Role; +import emlab.gen.domain.agent.BigBank; +import emlab.gen.domain.agent.DecarbonizationModel; +import emlab.gen.domain.agent.EnergyProducer; +import emlab.gen.domain.agent.Government; +import emlab.gen.domain.agent.PowerPlantManufacturer; +import emlab.gen.domain.agent.StochasticTargetInvestor; +import emlab.gen.domain.agent.StrategicReserveOperator; +import emlab.gen.domain.agent.TargetInvestor; +import emlab.gen.domain.contract.CashFlow; +import emlab.gen.domain.contract.Loan; +import emlab.gen.domain.gis.Zone; +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.market.electricity.SegmentLoad; +import emlab.gen.domain.policy.PowerGeneratingTechnologyTarget; +import emlab.gen.domain.technology.PowerGeneratingTechnology; +import emlab.gen.domain.technology.PowerGeneratingTechnologyNodeLimit; +import emlab.gen.domain.technology.PowerGridNode; +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.repository.StrategicReserveOperatorRepository; +import emlab.gen.util.GeometricTrendRegression; +import emlab.gen.util.MapValueComparator; + +/** + * {@link EnergyProducer}s decide to invest in new {@link PowerPlant} + * + * @author Emile Chappin @author Alfredas Chmieliauskas + * @author JCRichstein + */ +@Configurable +@NodeEntity +public class InvestWithHistoricalCVar extends GenericInvestmentRole +implements +Role, +NodeBacked { + + @Transient + @Autowired + Reps reps; + + @Transient + @Autowired + Neo4jTemplate template; + + @Transient + @Autowired + StrategicReserveOperatorRepository strategicReserveOperatorRepository; + + // market expectations + @Transient + Map marketInfoMap = new HashMap(); + + @Override + public void act(T agent) { + + long futureTimePoint = getCurrentTick() + agent.getInvestmentFutureTimeHorizon(); + // logger.warn(agent + " is looking at timepoint " + futureTimePoint); + + // ==== Expectations === + + Map expectedFuelPrices = predictFuelPrices(agent, futureTimePoint); + + // CO2 + Map expectedCO2Price = determineExpectedCO2PriceInclTaxAndFundamentalForecast( + 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(expectedCO2Price.toString()); + + //Demand + Map expectedDemand = new HashMap(); + 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){ + 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); } + */ + + // 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, + // marketInformation.expectedElectricityPricesPerSegment); + + // 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); + + double highestValue = Double.MIN_VALUE; + double highestValueWithoutCvar = Double.MIN_VALUE; + PowerGeneratingTechnology bestTechnology = null; + PowerGeneratingTechnology bestTechnologyWithoutCVar = null; + PowerGridNode bestNode = null; + PowerGridNode bestNodeWithoutCvar = null; + + for (PowerGeneratingTechnology technology : reps.genericRepository.findAll(PowerGeneratingTechnology.class)) { + + DecarbonizationModel model = reps.genericRepository.findAll(DecarbonizationModel.class).iterator().next(); + + if (technology.isIntermittent() && model.isNoPrivateIntermittentRESInvestment()) + continue; + + Iterable possibleInstallationNodes; + + /* + * For dispatchable technologies just choose a random node. For + * intermittent evaluate all possibilities. + */ + if(technology.isIntermittent()) + possibleInstallationNodes = reps.powerGridNodeRepository.findAllPowerGridNodesByZone(market.getZone()); + else{ + possibleInstallationNodes = new LinkedList(); + ((LinkedList) possibleInstallationNodes).add(reps.powerGridNodeRepository + .findAllPowerGridNodesByZone(market.getZone()).iterator().next()); + } + + // logger.warn("Calculating for " + technology.getName() + + // ", for Nodes: " + // + possibleInstallationNodes.toString()); + + for (PowerGridNode node : possibleInstallationNodes) { + + PowerPlant plant = new PowerPlant(); + plant.specifyNotPersist(getCurrentTick(), agent, node, technology); + // 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) { + double technologyTargetCapacity = technologyTarget.getTrend().getValue(futureTimePoint); + expectedInstalledCapacityOfTechnology = (technologyTargetCapacity > expectedInstalledCapacityOfTechnology) ? technologyTargetCapacity + : expectedInstalledCapacityOfTechnology; + } + double pgtNodeLimit = Double.MAX_VALUE; + PowerGeneratingTechnologyNodeLimit pgtLimit = reps.powerGeneratingTechnologyNodeLimitRepository + .findOneByTechnologyAndNode(technology, plant.getLocation()); + if (pgtLimit != null) { + pgtNodeLimit = pgtLimit.getUpperCapacityLimit(futureTimePoint); + } + double expectedInstalledCapacityOfTechnologyInNode = reps.powerPlantRepository + .calculateCapacityOfExpectedOperationalPowerPlantsByNodeAndTechnology(plant.getLocation(), + technology, futureTimePoint); + 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()); + double capacityInPipelineInMarket = reps.powerPlantRepository + .calculateCapacityOfPowerPlantsByMarketInPipeline(market, getCurrentTick()); + + if ((expectedInstalledCapacityOfTechnology + plant.getActualNominalCapacity()) + / (marketInformation.maxExpectedLoad + plant.getActualNominalCapacity()) > technology + .getMaximumInstalledCapacityFractionInCountry()) { + // logger.warn(agent + + // " 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 (expectedOwnedCapacityInMarketOfThisTechnology > expectedOwnedTotalCapacityInMarket + * technology.getMaximumInstalledCapacityFractionPerAgent()) { + // logger.warn(agent + + // " 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."); + + } 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", + // technology); + } 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", + // technology); + } else { + + Map myFuelPrices = new HashMap(); + for (Substance fuel : technology.getFuels()) { + myFuelPrices.put(fuel, expectedFuelPrices.get(fuel)); + } + Set fuelMix = calculateFuelMix(plant, myFuelPrices, expectedCO2Price.get(market)); + plant.setFuelMix(fuelMix); + + double expectedMarginalCost = determineExpectedMarginalCost(plant, expectedFuelPrices, expectedCO2Price.get(market)); + double runningHours = 0d; + double expectedGrossProfit = 0d; + + long numberOfSegments = reps.segmentRepository.count(); + + // TODO somehow the prices of long-term contracts could also + // be used here to determine the expected profit. Maybe not + // though... + for (SegmentLoad segmentLoad : market.getLoadDurationCurve()) { + double expectedElectricityPrice = marketInformation.expectedElectricityPricesPerSegment.get(segmentLoad + .getSegment()); + double hours = segmentLoad.getSegment().getLengthInHours(); + if (expectedMarginalCost <= expectedElectricityPrice) { + runningHours += hours; + if (technology.isIntermittent()) + expectedGrossProfit += (expectedElectricityPrice - expectedMarginalCost) + * hours + * plant.getActualNominalCapacity() + * reps.intermittentTechnologyNodeLoadFactorRepository + .findIntermittentTechnologyNodeLoadFactorForNodeAndTechnology(node, + technology).getLoadFactorForSegment(segmentLoad.getSegment()); + else + expectedGrossProfit += (expectedElectricityPrice - expectedMarginalCost) + * hours + * plant.getAvailableCapacity(futureTimePoint, segmentLoad.getSegment(), numberOfSegments); + } + } + + // logger.warn(agent + + // "expects technology {} to have {} running", technology, + // runningHours); + // 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", + // technology, runningHours); + } else { + + double fixedOMCost = calculateFixedOperatingCost(plant, getCurrentTick());// / + // plant.getActualNominalCapacity(); + + + Double cVarOfHistoricalGrossProfitsResult = reps.financialPowerPlantReportRepository + .calculateHistoricalCVarRelativePerMWForOperationaPlantsForEnergyProducerAndTechnologyForYearsFromToAndAlphaValue( + getCurrentTick() - 5, getCurrentTick(), agent, technology, + agent.getHistoricalCVarAlpha()); + + double cVarOfHistoricalGrossProfits = 0; + if (cVarOfHistoricalGrossProfitsResult != null) { + cVarOfHistoricalGrossProfits = cVarOfHistoricalGrossProfitsResult.doubleValue() + * plant.getActualNominalCapacity(); + } else { + cVarOfHistoricalGrossProfits = agent.getHistoricalCVarPropensityForNewTechnologies() + * expectedGrossProfit; + } + + + + double operatingProfit = expectedGrossProfit - fixedOMCost; + + double historicalCvarOperatingProfit = cVarOfHistoricalGrossProfits - fixedOMCost; + + + // TODO Alter discount rate on the basis of the amount + // in long-term contracts? + // TODO Alter discount rate on the basis of other stuff, + // such as amount of money, market share, portfolio + // size. + + // Calculation of weighted average cost of capital, + // based on the companies debt-ratio + double wacc = (1 - agent.getDebtRatioOfInvestments()) * agent.getEquityInterestRate() + + agent.getDebtRatioOfInvestments() * agent.getLoanInterestRate(); + if (cVarOfHistoricalGrossProfitsResult == null) + wacc += agent.getHistoricalCVarInterestRateIncreaseForNewTechnologies(); + + // Creation of out cash-flow during power plant building + // phase (note that the cash-flow is negative!) + TreeMap projectCapitalOutflow = calculateSimplePowerPlantInvestmentCashFlow( + technology.getDepreciationTime(), (int) plant.getActualLeadTime(), + plant.getActualInvestedCapital(), 0); + // Creation of in cashflow during operation + TreeMap projectCashInflow = calculateSimplePowerPlantInvestmentCashFlow( + technology.getDepreciationTime(), (int) plant.getActualLeadTime(), 0, operatingProfit); + + TreeMap projectCashInflowHistoricalCVar = calculateSimplePowerPlantInvestmentCashFlow( + technology.getDepreciationTime(), (int) plant.getActualLeadTime(), 0, + historicalCvarOperatingProfit); + + double discountedCapitalCosts = npv(projectCapitalOutflow, wacc);// are + // defined + // negative!! + // plant.getActualNominalCapacity(); + + // logger.warn("Agent {} found that the discounted capital for technology {} to be " + // + discountedCapitalCosts, agent, + // technology); + + double discountedOpProfit = npv(projectCashInflow, wacc); + + double discountedHistoricalCvarOpProfit = npv(projectCashInflowHistoricalCVar, wacc); + + // logger.warn("Agent {} found that the projected discounted inflows for technology {} to be " + // + discountedOpProfit, + // agent, technology); + + double projectValue = discountedOpProfit + discountedCapitalCosts; + double oldProjectValue = projectValue; + + double historicalCvarProjectValue = discountedHistoricalCvarOpProfit + discountedCapitalCosts; + + if (cVarOfHistoricalGrossProfitsResult != null + || (agent.getHistoricalCVarInterestRateIncreaseForNewTechnologies() == 0 & cVarOfHistoricalGrossProfitsResult == null)) { + projectValue += (agent.getHistoricalCVarBeta() * historicalCvarProjectValue < 0) ? agent + .getHistoricalCVarBeta() * historicalCvarProjectValue : 0; + } + // if (historicalCvarProjectValue < 0) { + // logger.warn("Adjusting NPV!"); + // projectValue += beta * historicalCvarProjectValue; + // } + + // if (technology.isIntermittent()) { + // logger.warn(technology + "in " + node.getName() + + // ", NPV: " + projectValue + // + ", GrossProfit: " + expectedGrossProfit); + // } + + // logger.warn(technology + "in " + node.getName() + + // ", NPV: " + projectValue + ", GrossProfit: " + // + expectedGrossProfit); + // + // logger.warn("CVar: " + historicalCvarProjectValue); + // + // logger.warn("NPV-CVAR: " + projectValue); + + // logger.warn( + // "Agent {} found the project value for technology {} to be " + // + Math.round(projectValue / + // plant.getActualNominalCapacity()) + // + " EUR/kW (running hours: " + runningHours + "", + // agent, technology); + + // double projectTotalValue = projectValuePerMW * + // plant.getActualNominalCapacity(); + + // double projectReturnOnInvestment = discountedOpProfit + // / (-discountedCapitalCosts); + + /* + * Divide by capacity, in order not to favour large power plants (which have the single largest NPV + */ + if (projectValue < 0 && oldProjectValue > 0) { + logger.warn( + "Not profitable w CVAR. NPV-CVAR: {}, NPV: {}, CVAR-GP: " + + cVarOfHistoricalGrossProfits / plant.getActualNominalCapacity() + " Tech:" + + technology + " in " + + node.getName(), projectValue / plant.getActualNominalCapacity(), + oldProjectValue / plant.getActualNominalCapacity()); + } + if (projectValue > 0) { + logger.warn( + "Is profitable w CVAR. NPV-CVAR: {}, NPV: {}, CVAR-GP: " + + cVarOfHistoricalGrossProfits / plant.getActualNominalCapacity() + " Tech:" + + technology + " in " + + node.getName(), projectValue / plant.getActualNominalCapacity(), + oldProjectValue / plant.getActualNominalCapacity()); + } + + if (projectValue > 0 && projectValue / plant.getActualNominalCapacity() > highestValue) { + highestValue = projectValue / plant.getActualNominalCapacity(); + bestTechnology = plant.getTechnology(); + bestNode = node; + } + + if (oldProjectValue > 0 + && oldProjectValue / plant.getActualNominalCapacity() > highestValueWithoutCvar) { + highestValueWithoutCvar = oldProjectValue / plant.getActualNominalCapacity(); + bestTechnologyWithoutCVar = plant.getTechnology(); + bestNodeWithoutCvar = node; + } + } + + } + + } + } + + if (bestTechnology != null && bestTechnologyWithoutCVar != null + && !bestTechnologyWithoutCVar.equals(bestTechnology)) { + logger.warn("Because of CVar investing in {}, instead of in {}", bestTechnology.getName(), + bestTechnologyWithoutCVar.getName()); + } + if (bestTechnology == null && bestTechnologyWithoutCVar != null) { + logger.warn("Not investing. W/o CVar would have invested in {}", + bestTechnologyWithoutCVar.getName()); + } + + if (bestTechnology != null) { + // logger.warn("Agent {} invested in technology {} at tick " + + // getCurrentTick(), agent, bestTechnology); + + PowerPlant plant = new PowerPlant(); + plant.specifyAndPersist(getCurrentTick(), agent, bestNode, bestTechnology); + PowerPlantManufacturer manufacturer = reps.genericRepository.findFirst(PowerPlantManufacturer.class); + BigBank bigbank = reps.genericRepository.findFirst(BigBank.class); + + 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()); + // logger.warn("Loan amount is: " + amount); + 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 " + // + getCurrentTick(), agent); + // agent will not participate in the next round of investment if + // he does not invest now + setNotWillingToInvest(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(); + reps.nonTransactionalCreateRepository.createCashFlow(agent, manufacturer, totalDownPayment / buildingTime, + CashFlow.DOWNPAYMENT, getCurrentTick(), plant); + Loan downpayment = reps.loanRepository.createLoan(agent, manufacturer, totalDownPayment / buildingTime, + buildingTime - 1, getCurrentTick(), plant); + plant.createOrUpdateDownPayment(downpayment); + } + + @Transactional + private void setNotWillingToInvest(EnergyProducer agent) { + agent.setWillingToInvest(false); + } + + /** + * 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){ + // 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). + Iterable cps = reps.clearingPointRepository + .findAllClearingPointsForSubstanceTradedOnCommodityMarkesAndTimeRange(substance, getCurrentTick() + - (agent.getNumberOfYearsBacklookingForForecasting() - 1), getCurrentTick(), false); + //logger.warn("{}, {}", getCurrentTick()-(agent.getNumberOfYearsBacklookingForForecasting()-1), getCurrentTick()); + //Create regression object + SimpleRegression gtr = new SimpleRegression(); + for (ClearingPoint clearingPoint : cps) { + //logger.warn("CP {}: {} , in" + clearingPoint.getTime(), substance.getName(), clearingPoint.getPrice()); + gtr.addData(clearingPoint.getTime(), clearingPoint.getPrice()); + } + gtr.addData(getCurrentTick(), findLastKnownPriceForSubstance(substance, getCurrentTick())); + expectedFuelPrices.put(substance, gtr.predict(futureTimePoint)); + //logger.warn("Forecast {}: {}, in Step " + futureTimePoint, substance, expectedFuelPrices.get(substance)); + } + return expectedFuelPrices; + } + + // Create a powerplant investment and operation cash-flow in the form of a + // map. If only investment, or operation costs should be considered set + // totalInvestment or operatingProfit to 0 + private TreeMap calculateSimplePowerPlantInvestmentCashFlow(int depriacationTime, int buildingTime, + double totalInvestment, double operatingProfit) { + TreeMap investmentCashFlow = new TreeMap(); + double equalTotalDownPaymentInstallement = totalInvestment / buildingTime; + for (int i = 0; i < buildingTime; i++) { + investmentCashFlow.put(new Integer(i), -equalTotalDownPaymentInstallement); + } + for (int i = buildingTime; i < depriacationTime + buildingTime; i++) { + investmentCashFlow.put(new Integer(i), operatingProfit); + } + + return investmentCashFlow; + } + + private double npv(TreeMap netCashFlow, double wacc) { + double npv = 0; + for (Integer iterator : netCashFlow.keySet()) { + npv += netCashFlow.get(iterator).doubleValue() / Math.pow(1 + wacc, iterator.intValue()); + } + return npv; + } + + public double determineExpectedMarginalCost(PowerPlant plant, Map expectedFuelPrices, double expectedCO2Price) { + double mc = determineExpectedMarginalFuelCost(plant, expectedFuelPrices); + double co2Intensity = plant.calculateEmissionIntensity(); + mc += co2Intensity * expectedCO2Price; + return mc; + } + + public double determineExpectedMarginalFuelCost(PowerPlant powerPlant, Map expectedFuelPrices) { + double fc = 0d; + for (SubstanceShareInFuelMix mix : powerPlant.getFuelMix()) { + double amount = mix.getShare(); + double fuelPrice = expectedFuelPrices.get(mix.getSubstance()); + fc += amount * fuelPrice; + } + return fc; + } + + private PowerGridNode getNodeForZone(Zone zone) { + for (PowerGridNode node : reps.genericRepository.findAll(PowerGridNode.class)) { + if (node.getZone().equals(zone)) { + return node; + } + } + return null; + } + + private class MarketInformation { + + Map expectedElectricityPricesPerSegment; + double maxExpectedLoad = 0d; + Map meritOrder; + double capacitySum; + + 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)) { + + double plantMarginalCost = determineExpectedMarginalCost(plant, fuelPrices, co2price); + marginalCostMap.put(plant, plantMarginalCost); + capacitySum += plant.getActualNominalCapacity(); + } + + //get difference between technology target and expected operational capacity + for (TargetInvestor targetInvestor : reps.targetInvestorRepository.findAllByMarket(market)) { + if (!(targetInvestor instanceof StochasticTargetInvestor)) { + for (PowerGeneratingTechnologyTarget pggt : targetInvestor.getPowerGenerationTechnologyTargets()) { + double expectedTechnologyCapacity = reps.powerPlantRepository + .calculateCapacityOfExpectedOperationalPowerPlantsInMarketAndTechnology(market, + pggt.getPowerGeneratingTechnology(), time); + double targetDifference = pggt.getTrend().getValue(time) - expectedTechnologyCapacity; + if (targetDifference > 0) { + PowerPlant plant = new PowerPlant(); + plant.specifyNotPersist(getCurrentTick(), new EnergyProducer(), + reps.powerGridNodeRepository.findFirstPowerGridNodeByElectricitySpotMarket(market), + pggt.getPowerGeneratingTechnology()); + plant.setActualNominalCapacity(targetDifference); + double plantMarginalCost = determineExpectedMarginalCost(plant, fuelPrices, co2price); + marginalCostMap.put(plant, plantMarginalCost); + capacitySum += targetDifference; + } + } + } else { + for (PowerGeneratingTechnologyTarget pggt : targetInvestor.getPowerGenerationTechnologyTargets()) { + double expectedTechnologyCapacity = reps.powerPlantRepository + .calculateCapacityOfExpectedOperationalPowerPlantsInMarketAndTechnology(market, + pggt.getPowerGeneratingTechnology(), time); + double expectedTechnologyAddition = 0; + long contructionTime = getCurrentTick() + + pggt.getPowerGeneratingTechnology().getExpectedLeadtime() + + pggt.getPowerGeneratingTechnology().getExpectedPermittime(); + for (long investmentTimeStep = contructionTime + 1; investmentTimeStep <= time; investmentTimeStep = investmentTimeStep + 1) { + expectedTechnologyAddition += (pggt.getTrend().getValue(investmentTimeStep) - pggt + .getTrend().getValue(investmentTimeStep - 1)); + } + if (expectedTechnologyAddition > 0) { + PowerPlant plant = new PowerPlant(); + plant.specifyNotPersist(getCurrentTick(), new EnergyProducer(), + reps.powerGridNodeRepository.findFirstPowerGridNodeByElectricitySpotMarket(market), + pggt.getPowerGeneratingTechnology()); + plant.setActualNominalCapacity(expectedTechnologyAddition); + double plantMarginalCost = determineExpectedMarginalCost(plant, fuelPrices, co2price); + marginalCostMap.put(plant, plantMarginalCost); + capacitySum += expectedTechnologyAddition; + } + } + } + + } + + MapValueComparator comp = new MapValueComparator(marginalCostMap); + meritOrder = new TreeMap(comp); + meritOrder.putAll(marginalCostMap); + + long numberOfSegments = reps.segmentRepository.count(); + + double demandFactor = expectedDemand.get(market).doubleValue(); + + // find expected prices per segment given merit order + for (SegmentLoad segmentLoad : market.getLoadDurationCurve()) { + + double expectedSegmentLoad = segmentLoad.getBaseLoad() * demandFactor; + + if (expectedSegmentLoad > maxExpectedLoad) { + maxExpectedLoad = expectedSegmentLoad; + } + + double segmentSupply = 0d; + double segmentPrice = 0d; + double totalCapacityAvailable = 0d; + + for (Entry plantCost : meritOrder.entrySet()) { + PowerPlant plant = plantCost.getKey(); + double plantCapacity = 0d; + // Determine available capacity in the future in this + // segment + plantCapacity = plant.getExpectedAvailableCapacity(time, segmentLoad.getSegment(), numberOfSegments); + totalCapacityAvailable += plantCapacity; + // logger.warn("Capacity of plant " + plant.toString() + + // " is " + + // plantCapacity/plant.getActualNominalCapacity()); + if (segmentSupply < expectedSegmentLoad) { + segmentSupply += plantCapacity; + segmentPrice = plantCost.getValue(); + } + + } + + // logger.warn("Segment " + + // segmentLoad.getSegment().getSegmentID() + " supply equals " + + // segmentSupply + " and segment demand equals " + + // expectedSegmentLoad); + + // Find strategic reserve operator for the market. + double reservePrice = 0; + double reserveVolume = 0; + for (StrategicReserveOperator operator : strategicReserveOperatorRepository.findAll()) { + ElectricitySpotMarket market1 = reps.marketRepository.findElectricitySpotMarketForZone(operator + .getZone()); + if (market.getNodeId().intValue() == market1.getNodeId().intValue()) { + reservePrice = operator.getReservePriceSR(); + reserveVolume = operator.getReserveVolume(); + } + } + + if (segmentSupply >= expectedSegmentLoad + && ((totalCapacityAvailable - expectedSegmentLoad) <= (reserveVolume))) { + expectedElectricityPricesPerSegment.put(segmentLoad.getSegment(), reservePrice); + // logger.warn("Price: "+ + // expectedElectricityPricesPerSegment); + } else if (segmentSupply >= expectedSegmentLoad + && ((totalCapacityAvailable - expectedSegmentLoad) > (reserveVolume))) { + expectedElectricityPricesPerSegment.put(segmentLoad.getSegment(), segmentPrice); + // logger.warn("Price: "+ + // expectedElectricityPricesPerSegment); + } else { + expectedElectricityPricesPerSegment.put(segmentLoad.getSegment(), market.getValueOfLostLoad()); + } + + } + } + } + + /** + * 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. + * @return + */ + protected HashMap determineExpectedCO2PriceInclTaxAndFundamentalForecast( + long futureTimePoint, long yearsLookingBackForRegression, int adjustmentForDetermineFuelMix, + long clearingTick) { + HashMap co2Prices = new HashMap(); + CO2Auction co2Auction = reps.genericRepository.findFirst(CO2Auction.class); + Iterable cps = reps.clearingPointRepository.findAllClearingPointsForMarketAndTimeRange( + co2Auction, clearingTick - yearsLookingBackForRegression + 1 - adjustmentForDetermineFuelMix, + clearingTick - adjustmentForDetermineFuelMix, false); + // Create regression object and calculate average + SimpleRegression sr = new SimpleRegression(); + Government government = reps.template.findAll(Government.class).iterator().next(); + double lastPrice = 0; + double averagePrice = 0; + int i = 0; + for (ClearingPoint clearingPoint : cps) { + sr.addData(clearingPoint.getTime(), clearingPoint.getPrice()); + lastPrice = clearingPoint.getPrice(); + averagePrice += lastPrice; + i++; + } + averagePrice = averagePrice / i; + double expectedCO2Price; + double expectedRegressionCO2Price; + if (i > 1) { + expectedRegressionCO2Price = sr.predict(futureTimePoint); + expectedRegressionCO2Price = Math.max(0, expectedRegressionCO2Price); + expectedRegressionCO2Price = Math + .min(expectedRegressionCO2Price, government.getCo2Penalty(futureTimePoint)); + } else { + expectedRegressionCO2Price = lastPrice; + } + ClearingPoint expectedCO2ClearingPoint = reps.clearingPointRepository.findClearingPointForMarketAndTime( + co2Auction, + getCurrentTick() + + reps.genericRepository.findFirst(DecarbonizationModel.class).getCentralForecastingYear(), + true); + expectedCO2Price = (expectedCO2ClearingPoint == null) ? 0 : expectedCO2ClearingPoint.getPrice(); + expectedCO2Price = (expectedCO2Price + expectedRegressionCO2Price) / 2; + for (ElectricitySpotMarket esm : reps.marketRepository.findAllElectricitySpotMarkets()) { + double nationalCo2MinPriceinFutureTick = reps.nationalGovernmentRepository + .findNationalGovernmentByElectricitySpotMarket(esm).getMinNationalCo2PriceTrend() + .getValue(futureTimePoint); + double co2PriceInCountry = 0d; + if (expectedCO2Price > nationalCo2MinPriceinFutureTick) { + co2PriceInCountry = expectedCO2Price; + } else { + co2PriceInCountry = nationalCo2MinPriceinFutureTick; + } + co2PriceInCountry += reps.genericRepository.findFirst(Government.class).getCO2Tax(futureTimePoint); + co2Prices.put(esm, Double.valueOf(co2PriceInCountry)); + } + return co2Prices; + } + +} diff --git a/emlab-generation/src/main/java/emlab/gen/role/investment/StochasticTargetInvestmentRole.java b/emlab-generation/src/main/java/emlab/gen/role/investment/StochasticTargetInvestmentRole.java index 863df1c9..866beec2 100644 --- a/emlab-generation/src/main/java/emlab/gen/role/investment/StochasticTargetInvestmentRole.java +++ b/emlab-generation/src/main/java/emlab/gen/role/investment/StochasticTargetInvestmentRole.java @@ -50,11 +50,11 @@ public class StochasticTargetInvestmentRole extends GenericInvestmentRole expectedInstalledCapacity + targetInstallationDelta) { installedCapacityDeviation = targetInstallationDelta; @@ -125,7 +129,7 @@ public void act(StochasticTargetInvestor targetInvestor) { private void createSpreadOutDownPayments(EnergyProducer agent, PowerPlantManufacturer manufacturer, double totalDownPayment, PowerPlant plant) { - int buildingTime = (int) plant.getActualLeadtime(); + int buildingTime = (int) plant.getActualLeadTime(); for (int i = 0; i < buildingTime; i++) { reps.nonTransactionalCreateRepository.createCashFlow(agent, manufacturer, totalDownPayment / buildingTime, CashFlow.DOWNPAYMENT, getCurrentTick() + i, plant); diff --git a/emlab-generation/src/main/java/emlab/gen/role/investment/StochasticTargetInvestmentRole.java.orig b/emlab-generation/src/main/java/emlab/gen/role/investment/StochasticTargetInvestmentRole.java.orig new file mode 100644 index 00000000..130d2d69 --- /dev/null +++ b/emlab-generation/src/main/java/emlab/gen/role/investment/StochasticTargetInvestmentRole.java.orig @@ -0,0 +1,173 @@ +/******************************************************************************* + * 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.investment; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.data.annotation.Transient; +import org.springframework.data.neo4j.annotation.NodeEntity; +import org.springframework.transaction.annotation.Transactional; + +import emlab.gen.domain.agent.BigBank; +import emlab.gen.domain.agent.EnergyProducer; +import emlab.gen.domain.agent.PowerPlantManufacturer; +import emlab.gen.domain.agent.StochasticTargetInvestor; +import emlab.gen.domain.contract.CashFlow; +import emlab.gen.domain.contract.Loan; +import emlab.gen.domain.policy.PowerGeneratingTechnologyTarget; +import emlab.gen.domain.policy.PowerGeneratingTechnologyTargetFulfillment; +import emlab.gen.domain.technology.PowerGeneratingTechnology; +import emlab.gen.domain.technology.PowerGeneratingTechnologyNodeLimit; +import emlab.gen.domain.technology.PowerGridNode; +import emlab.gen.domain.technology.PowerPlant; +import emlab.gen.repository.Reps; + +/** + * @author JCRichstein + * + */ +@Configurable +@NodeEntity +public class StochasticTargetInvestmentRole extends GenericInvestmentRole { + + @Transient + @Autowired Reps reps; + + @Override + @Transactional + public void act(StochasticTargetInvestor targetInvestor) { + +<<<<<<< HEAD + logger.warn(targetInvestor.getName() + " making investments."); + + for(PowerGeneratingTechnologyTarget target : targetInvestor.getPowerGenerationTechnologyTargets()){ + PowerGeneratingTechnology pgt = target.getPowerGeneratingTechnology(); + logger.warn("\t looking at" + pgt.getName()); +======= + // logger.warn(targetInvestor.getName() + " making investments."); + + for(PowerGeneratingTechnologyTarget target : targetInvestor.getPowerGenerationTechnologyTargets()){ + PowerGeneratingTechnology pgt = target.getPowerGeneratingTechnology(); + // logger.warn("\t looking at" + pgt.getName()); +>>>>>>> Jorn/feature/historicalCVar + PowerGeneratingTechnologyTargetFulfillment targetFulfillment = null; + for (PowerGeneratingTechnologyTargetFulfillment tgtFulfillment : targetInvestor + .getPowerGeneratingTechnologyPercentageOfYearlyTargetFulfillments()) { + if(tgtFulfillment.getPowerGeneratingTechnology().getName().equals(pgt.getName())) + targetFulfillment = tgtFulfillment; + } + + PowerGridNode installationNode = targetInvestor.getSpecificPowerGridNode(); + + if (installationNode == null) +<<<<<<< HEAD + reps.powerGeneratingTechnologyNodeLimitRepository.findOneByTechnologyAndMarket(pgt, + targetInvestor.getInvestorMarket()); +======= + installationNode = reps.powerGridNodeRepository.findFirstPowerGridNodeByElectricitySpotMarket(targetInvestor.getInvestorMarket()); +>>>>>>> Jorn/feature/historicalCVar + + long futureTimePoint = getCurrentTick()+pgt.getExpectedLeadtime()+pgt.getExpectedPermittime(); + double expectedInstalledCapacity = reps.powerPlantRepository.calculateCapacityOfExpectedOperationalPowerPlantsInMarketAndTechnology(targetInvestor.getInvestorMarket(), pgt, futureTimePoint); + double pgtNodeLimit = Double.MAX_VALUE; + // For simplicity using the market, instead of the node here. Needs + // to be changed, if more than one node per market exists. + PowerGeneratingTechnologyNodeLimit pgtLimit = reps.powerGeneratingTechnologyNodeLimitRepository + .findOneByTechnologyAndNode(pgt, installationNode); + if (pgtLimit != null) { + pgtNodeLimit = pgtLimit.getUpperCapacityLimit(futureTimePoint); + } +<<<<<<< HEAD + logger.warn("TechName: " + pgt.getName() + ", EnergyProducer" + targetInvestor + ", time: " + + futureTimePoint); +======= + // logger.warn("TechName: " + pgt.getName() + ", EnergyProducer" + + // targetInvestor + ", time: " + // + futureTimePoint); +>>>>>>> Jorn/feature/historicalCVar + double expectedDismantledPowerPlantCapacityOfTechnologyAndOwner = reps.powerPlantRepository + .calculateCapacityOfExpectedDismantledPowerPlantsByOwnerByTechnology(futureTimePoint, targetInvestor, pgt); + double targetInstallationDelta = (target.getTrend().getValue(futureTimePoint) - target.getTrend().getValue( + futureTimePoint - 1)) + + expectedDismantledPowerPlantCapacityOfTechnologyAndOwner; +<<<<<<< HEAD + logger.warn(target.getPowerGeneratingTechnology().getName() + ": " + targetInstallationDelta + + " of which repowering: " + expectedDismantledPowerPlantCapacityOfTechnologyAndOwner); + targetInstallationDelta = targetInstallationDelta * targetFulfillment.getTrend().getValue(futureTimePoint); + logger.warn(target.getPowerGeneratingTechnology().getName() + " Stochastic: " + targetInstallationDelta); +======= + // logger.warn(target.getPowerGeneratingTechnology().getName() + + // ": " + targetInstallationDelta + // + " of which repowering: " + + // expectedDismantledPowerPlantCapacityOfTechnologyAndOwner); + targetInstallationDelta = targetInstallationDelta * targetFulfillment.getTrend().getValue(futureTimePoint); + // logger.warn(target.getPowerGeneratingTechnology().getName() + + // " Stochastic: " + targetInstallationDelta); +>>>>>>> Jorn/feature/historicalCVar + double installedCapacityDeviation = 0; + if (pgtNodeLimit > expectedInstalledCapacity + targetInstallationDelta) { + installedCapacityDeviation = targetInstallationDelta; + } else { + installedCapacityDeviation = pgtNodeLimit - expectedInstalledCapacity; + } + + if (installedCapacityDeviation > 0) { + + double powerPlantCapacityRatio = installedCapacityDeviation/pgt.getCapacity(); + + PowerPlant plant = new PowerPlant(); + plant.specifyNotPersist(getCurrentTick(), targetInvestor, installationNode, pgt); + plant.setActualNominalCapacity(pgt.getCapacity()*powerPlantCapacityRatio); + PowerPlantManufacturer manufacturer = reps.genericRepository.findFirst(PowerPlantManufacturer.class); + BigBank bigbank = reps.genericRepository.findFirst(BigBank.class); + + double investmentCostPayedByEquity = plant.getActualInvestedCapital() * (1 - targetInvestor.getDebtRatioOfInvestments())*powerPlantCapacityRatio; + double investmentCostPayedByDebt = plant.getActualInvestedCapital() * targetInvestor.getDebtRatioOfInvestments()*powerPlantCapacityRatio; + double downPayment = investmentCostPayedByEquity; + createSpreadOutDownPayments(targetInvestor, manufacturer, downPayment, plant); + + double amount = determineLoanAnnuities(investmentCostPayedByDebt, plant.getTechnology().getDepreciationTime(), + targetInvestor.getLoanInterestRate()); + // logger.warn("Loan amount is: " + amount); + Loan loan = reps.loanRepository.createLoan(targetInvestor, bigbank, amount, plant.getTechnology().getDepreciationTime(), + getCurrentTick(), plant); + // Create the loan + plant.createOrUpdateLoan(loan); + + } + } + + } + + private void createSpreadOutDownPayments(EnergyProducer agent, PowerPlantManufacturer manufacturer, double totalDownPayment, + PowerPlant plant) { + int buildingTime = (int) plant.getActualLeadtime(); + for (int i = 0; i < buildingTime; i++) { + reps.nonTransactionalCreateRepository.createCashFlow(agent, manufacturer, totalDownPayment / buildingTime, + CashFlow.DOWNPAYMENT, getCurrentTick() + i, plant); + } + } + + @Override + public double determineLoanAnnuities(double totalLoan, double payBackTime, double interestRate) { + + double q = 1 + interestRate; + double annuity = totalLoan * (Math.pow(q, payBackTime) * (q - 1)) / (Math.pow(q, payBackTime) - 1); + + return annuity; + } + +} diff --git a/emlab-generation/src/main/java/emlab/gen/role/investment/TargetInvestmentRole.java b/emlab-generation/src/main/java/emlab/gen/role/investment/TargetInvestmentRole.java index 1ba4a02c..500b914c 100644 --- a/emlab-generation/src/main/java/emlab/gen/role/investment/TargetInvestmentRole.java +++ b/emlab-generation/src/main/java/emlab/gen/role/investment/TargetInvestmentRole.java @@ -104,7 +104,7 @@ public void act(TargetInvestor targetInvestor) { private void createSpreadOutDownPayments(EnergyProducer agent, PowerPlantManufacturer manufacturer, double totalDownPayment, PowerPlant plant) { - int buildingTime = (int) plant.getActualLeadtime(); + int buildingTime = (int) plant.getActualLeadTime(); for (int i = 0; i < buildingTime; i++) { reps.nonTransactionalCreateRepository.createCashFlow(agent, manufacturer, totalDownPayment / buildingTime, CashFlow.DOWNPAYMENT, getCurrentTick() + i, plant); diff --git a/emlab-generation/src/main/java/emlab/gen/role/market/AbstractClearElectricitySpotMarketRole.java b/emlab-generation/src/main/java/emlab/gen/role/market/AbstractClearElectricitySpotMarketRole.java index 0d50c3b7..f1e6c32b 100644 --- a/emlab-generation/src/main/java/emlab/gen/role/market/AbstractClearElectricitySpotMarketRole.java +++ b/emlab-generation/src/main/java/emlab/gen/role/market/AbstractClearElectricitySpotMarketRole.java @@ -619,6 +619,15 @@ CO2PriceStability determineStabilityOfCO2andElectricityPricesAndAdjustIfNecessar .findClearingPointsForMarketAndTime(market, getCurrentTick(), false)); Substance substance = market.getSubstance(); + for (CommoditySupplier supplier : reps.genericRepository.findAll(CommoditySupplier.class)) { + if (supplier.getSubstance().equals(substance)) { + + logger.info("Price found for {} by asking the supplier {} directly", substance.getName(), + supplier.getName()); + return supplier.getPriceOfCommodity().getValue(getCurrentTick()); + } + } + if (average != null) { logger.info("Average price found on market for this tick for {}", substance.getName()); return average; @@ -636,13 +645,7 @@ CO2PriceStability determineStabilityOfCO2andElectricityPricesAndAdjustIfNecessar return market.getReferencePrice(); } - for (CommoditySupplier supplier : reps.genericRepository.findAll(CommoditySupplier.class)) { - if (supplier.getSubstance().equals(substance)) { - logger.info("Price found for {} by asking the supplier {} directly", substance.getName(), supplier.getName()); - return supplier.getPriceOfCommodity().getValue(getCurrentTick()); - } - } logger.info("No price has been found for {}", substance.getName()); return 0d; diff --git a/emlab-generation/src/main/java/emlab/gen/role/market/ClearIterativeCO2AndElectricitySpotMarketTwoCountryRole.java b/emlab-generation/src/main/java/emlab/gen/role/market/ClearIterativeCO2AndElectricitySpotMarketTwoCountryRole.java index 6804904d..20112262 100644 --- a/emlab-generation/src/main/java/emlab/gen/role/market/ClearIterativeCO2AndElectricitySpotMarketTwoCountryRole.java +++ b/emlab-generation/src/main/java/emlab/gen/role/market/ClearIterativeCO2AndElectricitySpotMarketTwoCountryRole.java @@ -105,7 +105,7 @@ public void makeCentralElectricityMarketForecastForTimeStep(long clearingTick) { Map fuelPriceMap = predictFuelPrices(model.getCentralForecastBacklookingYears(), clearingTick); - logger.warn("Fuel prices: {}", fuelPriceMap); + // logger.warn("Fuel prices: {}", fuelPriceMap); Map demandGrowthMap = predictDemand(model.getCentralForecastBacklookingYears(), clearingTick); @@ -628,7 +628,6 @@ public void clearIterativeCO2ElectricitySpotMarketAndFutureMarketTwoCountryForTi double targetEnergyProducerBanking = calculateTargetCO2EmissionBankingOfEnergyProducers(clearingTick, clearingTick + model.getCentralForecastingYear(), government, model); - logger.warn("Hedging Target: {}, Relative Hedging: {}", targetEnergyProducerBanking, targetEnergyProducerBanking/government.getCo2Cap(getCurrentTick())); double deltaBankedEmissionCertificateToReachBankingTarget = (targetEnergyProducerBanking - previouslyBankedCertificates) / model.getCentralCO2TargetReversionSpeedFactor(); @@ -684,6 +683,7 @@ public void clearIterativeCO2ElectricitySpotMarketAndFutureMarketTwoCountryForTi futureCO2Price = co2SecantSearch.co2Price * Math.pow(1 + model.getCentralPrivateDiscountingRate(), model.getCentralForecastingYear()); + logger.warn("Iteration " + breakOffIterator + ", CO2Price for clearing: " + co2SecantSearch.co2Price); clearOneOrTwoConnectedElectricityMarketsAtAGivenCO2PriceForSegments(government, clearingTick + model.getCentralForecastingYear(), true, futureDemandGrowthMap, futureFuelPriceMap, futureCO2Price, futureNationalMinCo2Prices, segments, interconnector, model); @@ -706,13 +706,16 @@ public void clearIterativeCO2ElectricitySpotMarketAndFutureMarketTwoCountryForTi clearingTick, -deltaBankedEmissionCertificateToReachBankingTarget, currentEmissions, futureEmissions, previouslyBankedCertificates, averageCO2PriceOfLastTwoYears); - logger.warn("Iteration: " + breakOffIterator + ": " + co2SecantSearch.toString() + ", Future: " - + futureCO2Price); + // logger.warn("Iteration: " + breakOffIterator + ": " + + // co2SecantSearch.toString() + ", Future: " + // + futureCO2Price); if (!co2SecantSearch.stable) { targetEnergyProducerBanking = calculateTargetCO2EmissionBankingOfEnergyProducers(currentEmissions, futureEmissions, model); - logger.warn("Hedging Target: {}, Relative Hedging: {}", targetEnergyProducerBanking, targetEnergyProducerBanking/government.getCo2Cap(getCurrentTick())); + // logger.warn("Hedging Target: {}, Relative Hedging: {}", + // targetEnergyProducerBanking, + // targetEnergyProducerBanking/government.getCo2Cap(getCurrentTick())); deltaBankedEmissionCertificateToReachBankingTarget = (targetEnergyProducerBanking - previouslyBankedCertificates) / model.getCentralCO2TargetReversionSpeedFactor(); @@ -791,6 +794,7 @@ public void clearIterativeCO2ElectricitySpotMarketAndFutureMarketTwoCountryForTi } } + logger.warn("CO2Price that is saved: " + co2SecantSearch.co2Price); reps.clearingPointRepositoryOld.createOrUpdateCO2MarketClearingPoint(co2Auction, co2SecantSearch.co2Price, currentEmissions, emergencyPriceTriggerActive, emergencyAllowancesToBeReleased, clearingTick, false); reps.clearingPointRepositoryOld.createOrUpdateCO2MarketClearingPoint(co2Auction, @@ -815,10 +819,11 @@ public void clearIterativeCO2ElectricitySpotMarketAndFutureMarketTwoCountryForTi producer.setCo2Allowances(bankedEmissionsOfProducer); } } else { - clearIterativeCO2AndElectricitySpotMarketTwoCountryForTimestepAndFuelPrices(model, false, clearingTick, - fuelPriceMap, null, previouslyBankedCertificates); + logger.warn("Banking exhausted."); clearIterativeCO2AndElectricitySpotMarketTwoCountryForTimestepAndFuelPrices(model, true, clearingTick + model.getCentralForecastingYear(), futureFuelPriceMap, futureDemandGrowthMap, 0); + clearIterativeCO2AndElectricitySpotMarketTwoCountryForTimestepAndFuelPrices(model, false, clearingTick, + fuelPriceMap, null, previouslyBankedCertificates); for (EnergyProducer producer : reps.energyProducerRepository.findAll()) { producer.setLastYearsCo2Allowances(producer.getCo2Allowances()); producer.setCo2Allowances(0); @@ -948,18 +953,19 @@ CO2SecantSearch co2PriceSecantSearchUpdateWithCO2Banking(CO2SecantSearch co2Seca DecarbonizationModel model, Government government, long clearingTick, double co2CapAdjustment, double currentEmissions, double futureEmissions, double previouslyBankedCertificates, double averageCO2PriceOfLastTwoYears) { + co2SecantSearch.stable = false; double capDeviationCriterion = model.getCapDeviationCriterion(); double currentCap = government.getCo2Cap(clearingTick); - logger.warn("Current cap: {}", currentCap); + // logger.warn("Current cap: {}", currentCap); double futureCap = government.getCo2Cap(clearingTick + model.getCentralForecastingYear()); - logger.warn("Future cap: {}", futureCap); + // logger.warn("Future cap: {}", futureCap); // logger.warn("Is MSR active in future ? {}.", // (model.isStabilityReserveIsActive() && (model.getStabilityReserveFirstYearOfOperation() <= clearingTick // + model.getCentralForecastingYear()))); // logger.warn("First year MSR is active: {}", model.getStabilityReserveFirstYearOfOperation()); double expectedBankedPermits = calculateExpectedBankedCertificates(currentEmissions, futureEmissions, - currentCap, futureCap, previouslyBankedCertificates, model.getCentralForecastingYear()); + currentCap, futureCap, previouslyBankedCertificates, model.getCentralForecastingYear(), government); double effectiveCapInFuture = (model.isStabilityReserveIsActive() && (model .getStabilityReserveFirstYearOfOperation() <= clearingTick + model.getCentralForecastingYear())) ? futureCap - marketStabilityReserveRole.calculateInflowToMarketReserveForTimeStep( @@ -967,7 +973,7 @@ CO2SecantSearch co2PriceSecantSearchUpdateWithCO2Banking(CO2SecantSearch co2Seca expectedBankedPermits, government) : futureCap; - logger.warn("effective future cap: {}", effectiveCapInFuture); + // logger.warn("effective future cap: {}", effectiveCapInFuture); effectiveCapInFuture -= (government.isActivelyAdjustingTheCO2Cap() & getCurrentTick() > 0) ? renewableAdaptiveCO2CapRole .calculatedExpectedCapReductionForTimeStep(government, clearingTick, clearingTick + model.getCentralForecastingYear(), currentEmissions, futureEmissions, @@ -991,7 +997,7 @@ CO2SecantSearch co2PriceSecantSearchUpdateWithCO2Banking(CO2SecantSearch co2Seca return co2SecantSearch; } - // Check and update the twoPricesExistWithBelowAboveEmissions + // Check and update the twoPricesExistWithBelowAboveEmissions if (co2SecantSearch.tooHighEmissionsPair != null && co2SecantSearch.tooLowEmissionsPair != null) { co2SecantSearch.twoPricesExistWithBelowAboveEmissions = true; @@ -1113,10 +1119,11 @@ CO2SecantSearch co2PriceSecantSearchUpdateWithCO2Banking(CO2SecantSearch co2Seca } double calculateExpectedBankedCertificates(double currentEmissions, double futureEmissions, double currentCap, - double futureCap, double currentlyBankedEmissions, long centralForecastingYear) { + double futureCap, double currentlyBankedEmissions, long centralForecastingYear, Government government) { double expectedBankedCertificates = currentlyBankedEmissions + currentCap - currentEmissions + futureCap - futureEmissions; - expectedBankedCertificates = 1 / 3.0 + expectedBankedCertificates = government.isStabilityReserveHasOneYearDelayInsteadOfTwoYearDelay() ? 2.0 / 3.0 + * expectedBankedCertificates + 1.0 / 3.0 * currentlyBankedEmissions : 1 / 3.0 * expectedBankedCertificates + 2 / 3.0 * currentlyBankedEmissions; return expectedBankedCertificates; diff --git a/emlab-generation/src/main/java/emlab/gen/role/market/ClearIterativeCO2AndElectricitySpotMarketTwoCountryRole.java.orig b/emlab-generation/src/main/java/emlab/gen/role/market/ClearIterativeCO2AndElectricitySpotMarketTwoCountryRole.java.orig new file mode 100644 index 00000000..cbde43f3 --- /dev/null +++ b/emlab-generation/src/main/java/emlab/gen/role/market/ClearIterativeCO2AndElectricitySpotMarketTwoCountryRole.java.orig @@ -0,0 +1,1161 @@ +/******************************************************************************* + * 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.market; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.neo4j.support.Neo4jTemplate; +import org.springframework.transaction.annotation.Transactional; + +import agentspring.role.Role; +import agentspring.role.RoleComponent; +import emlab.gen.domain.agent.DecarbonizationModel; +import emlab.gen.domain.agent.EnergyProducer; +import emlab.gen.domain.agent.Government; +import emlab.gen.domain.agent.NationalGovernment; +import emlab.gen.domain.gis.Zone; +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.PowerPlantDispatchPlan; +import emlab.gen.domain.market.electricity.Segment; +import emlab.gen.domain.technology.Interconnector; +import emlab.gen.domain.technology.Substance; +import emlab.gen.repository.Reps; +import emlab.gen.role.co2policy.MarketStabilityReserveRole; +import emlab.gen.role.co2policy.RenewableAdaptiveCO2CapRole; +import emlab.gen.role.operating.DetermineFuelMixRole; +import emlab.gen.util.Utils; + +/** + * Creates and clears the {@link ElectricitySpotMarket} for two {@link Zone}s. + * The market is divided into {@link Segment}s and cleared for each segment. A + * global CO2 emissions market is cleared. The process is iterative and the + * target is to let the total emissions match the cap. + * + * @author Emile Chappin + * + * @author Alfredas + * Chmieliauskas + * + * @author Joern C. Richstein + * + */ +@RoleComponent +public class ClearIterativeCO2AndElectricitySpotMarketTwoCountryRole extends +AbstractClearElectricitySpotMarketRole implements Role { + + @Autowired + private Reps reps; + + @Autowired + SubmitOffersToElectricitySpotMarketRole submitOffersToElectricitySpotMarketRole; + + @Autowired + DetermineFuelMixRole determineFuelMixRole; + + @Autowired + MarketStabilityReserveRole marketStabilityReserveRole; + + @Autowired + RenewableAdaptiveCO2CapRole renewableAdaptiveCO2CapRole; + + @Autowired + Neo4jTemplate template; + + @Override + @Transactional + public void act(DecarbonizationModel model) { + Map fuelPriceMap = new HashMap(); + for (Substance substance : template.findAll(Substance.class)) { + fuelPriceMap.put(substance, findLastKnownPriceForSubstance(substance)); + } + + if (!model.isCo2BankingIsImplemented() || !model.isCo2TradingImplemented()) + clearIterativeCO2AndElectricitySpotMarketTwoCountryForTimestepAndFuelPrices(model, false, getCurrentTick(), + fuelPriceMap, null, 0); + else + clearIterativeCO2ElectricitySpotMarketAndFutureMarketTwoCountryForTimestepAndFuelPrices(model, + getCurrentTick()); + + } + + @Transactional + public void makeCentralElectricityMarketForecastForTimeStep(long clearingTick) { + + DecarbonizationModel model = template.findAll(DecarbonizationModel.class).iterator().next(); + + Map fuelPriceMap = predictFuelPrices(model.getCentralForecastBacklookingYears(), + clearingTick); + + // logger.warn("Fuel prices: {}", fuelPriceMap); + + Map demandGrowthMap = predictDemand(model.getCentralForecastBacklookingYears(), + clearingTick); + + Government government = template.findAll(Government.class).iterator().next(); + + // find national minimum CO2 prices. Initial Map size is 2. + Map nationalMinCo2Prices = new HashMap(2); + Iterable nationalGovernments = template.findAll(NationalGovernment.class); + for (NationalGovernment nG : nationalGovernments) { + if (model.isCo2TradingImplemented()) { + nationalMinCo2Prices.put(reps.marketRepository.findElectricitySpotMarketByNationalGovernment(nG), nG + .getMinNationalCo2PriceTrend().getValue(clearingTick)); + } else { + nationalMinCo2Prices.put(reps.marketRepository.findElectricitySpotMarketByNationalGovernment(nG), 0d); + } + + } + + determineFuelMixRole.determineFuelMixForecastForYearAndFuelPriceMap(clearingTick, fuelPriceMap, + nationalMinCo2Prices); + + submitOffersToElectricitySpotMarketRole.createOffersForElectricitySpotMarket(null, clearingTick, true, + fuelPriceMap); + + Iterable ppdps = reps.powerPlantDispatchPlanRepository.findAll(); + for (PowerPlantDispatchPlan ppdp : ppdps) { + logger.info(ppdp.toString() + " in " + ppdp.getBiddingMarket() + " accepted: " + ppdp.getAcceptedAmount()); + } + + double previouslyBankedCertificates = reps.decarbonizationAgentRepository + .determineTotallyBankedCO2Certificates(); + + if (clearingTick > model.getCentralForecastingYear()) { + CO2Auction co2Auction = template.findAll(CO2Auction.class).iterator().next(); + ClearingPoint forecastedCO2Clearing = reps.clearingPointRepository.findClearingPointForMarketAndTime( + co2Auction, clearingTick - 1, true); + ClearingPoint lastCO2Clearing = reps.clearingPointRepository.findClearingPointForMarketAndTime(co2Auction, + clearingTick - model.getCentralForecastingYear() - 1, false); + + double targetProducerBanking = calculateTargetCO2EmissionBankingOfEnergyProducers(clearingTick, + clearingTick + model.getCentralForecastingYear(), government, model); + + clearIterativeCO2AndElectricitySpotMarketTwoCountryForTimestepAndFuelPrices(model, true, clearingTick, + fuelPriceMap, demandGrowthMap, + (previouslyBankedCertificates - targetProducerBanking) / model.getCentralForecastingYear()); + } else { + clearIterativeCO2AndElectricitySpotMarketTwoCountryForTimestepAndFuelPrices(model, true, clearingTick, + fuelPriceMap, demandGrowthMap, 0); + } + + } + + public CO2SecantSearch clearIterativeCO2AndElectricitySpotMarketTwoCountryForTimestepAndFuelPrices( + DecarbonizationModel model, boolean forecast, long clearingTick, Map fuelPriceMap, + Map demandGrowthMap, double co2CapAdjustment) { + + if (model == null) + model = template.findAll(DecarbonizationModel.class).iterator().next(); + + if (fuelPriceMap == null && forecast) + fuelPriceMap = predictFuelPrices(model.getCentralForecastBacklookingYears(), clearingTick); + + if (demandGrowthMap == null && forecast) + demandGrowthMap = predictDemand(model.getCentralForecastBacklookingYears(), clearingTick); + + // find all operational power plants and store the ones operational to a + // list. + + logger.info("Clearing the CO2 and electricity spot markets using iteration for 2 countries "); + + // find all fuel prices + + // find all interconnectors + Interconnector interconnector = template.findAll(Interconnector.class).iterator().next(); + + // find all segments + List segments = Utils.asList(reps.segmentRepository.findAll()); + + // find the EU government + Government government = template.findAll(Government.class).iterator().next(); + + // find national minimum CO2 prices. Initial Map size is 2. + Map nationalMinCo2Prices = new HashMap(2); + Iterable nationalGovernments = template.findAll(NationalGovernment.class); + for (NationalGovernment nG : nationalGovernments) { + if (model.isCo2TradingImplemented()) { + nationalMinCo2Prices.put(reps.marketRepository.findElectricitySpotMarketByNationalGovernment(nG), nG + .getMinNationalCo2PriceTrend().getValue(clearingTick)); + } else { + nationalMinCo2Prices.put(reps.marketRepository.findElectricitySpotMarketByNationalGovernment(nG), 0d); + } + + } + + CO2Auction co2Auction = template.findAll(CO2Auction.class).iterator().next(); + CO2SecantSearch co2SecantSearch = null; + + if (model.isCo2TradingImplemented()) { + + co2SecantSearch = new CO2SecantSearch(); + co2SecantSearch.stable = false; + co2SecantSearch.twoPricesExistWithBelowAboveEmissions = false; + co2SecantSearch.co2Price = findLastKnownPriceOnMarket(co2Auction); + co2SecantSearch.tooHighEmissionsPair = null; + co2SecantSearch.tooLowEmissionsPair = null; + + // Change Iteration algorithm here, and a few lines below... + + ClearingPoint lastClearingPointOfCo2Market = reps.clearingPointRepositoryOld + .findClearingPointForMarketAndTime(co2Auction, getCurrentTick() - 1, false); + if (lastClearingPointOfCo2Market != null) { + co2SecantSearch.co2Emissions = lastClearingPointOfCo2Market.getVolume(); + } else { + co2SecantSearch.co2Emissions = 0d; + } + + int breakOffIterator = 0; + while (!co2SecantSearch.stable) { + + if (breakOffIterator > 15) { + logger.warn("Iteration cancelled, last found CO2 Price is used."); + break; + } + + // Clear the electricity markets with the expected co2Price + + // updatePowerPlanDispatchPlansWithNewCO2Prices(co2SecantSearch.co2Price, + // nationalMinCo2Prices); + // submitOffersToElectricitySpotMarketRole.updateMarginalCostInclCO2AfterFuelMixChange( + // co2SecantSearch.co2Price, nationalMinCo2Prices, clearingTick, + // forecast, fuelPriceMap); + // + // if (model.isLongTermContractsImplemented()) + // determineCommitmentOfPowerPlantsOnTheBasisOfLongTermContracts(segments, + // forecast); + // + // for (Segment segment : segments) { + // clearOneOrTwoConnectedElectricityMarketsAtAGivenCO2PriceForOneSegment(interconnector.getCapacity(), + // segment, government, clearingTick, forecast, + // demandGrowthMap); + // } + clearOneOrTwoConnectedElectricityMarketsAtAGivenCO2PriceForSegments(government, clearingTick, forecast, + demandGrowthMap, fuelPriceMap, co2SecantSearch.co2Price, nationalMinCo2Prices, segments, + interconnector, model); + + // Change Iteration algorithm here + // co2PriceStability = + // determineStabilityOfCO2andElectricityPricesAndAdjustIfNecessary(co2PriceStability, + // model, government); + co2SecantSearch = co2PriceSecantSearchUpdate(co2SecantSearch, model, government, forecast, + clearingTick, co2CapAdjustment); + breakOffIterator++; + + } + + reps.clearingPointRepositoryOld.createOrUpdateClearingPoint(co2Auction, co2SecantSearch.co2Price, + co2SecantSearch.co2Emissions, clearingTick, forecast); + } else { + if (model.isLongTermContractsImplemented()) + determineCommitmentOfPowerPlantsOnTheBasisOfLongTermContracts(segments, forecast); + for (Segment segment : segments) { + clearOneOrTwoConnectedElectricityMarketsAtAGivenCO2PriceForOneSegment( + interconnector.getCapacity(clearingTick), + segment, government, clearingTick, forecast, demandGrowthMap); + } + + } + + return co2SecantSearch; + + } + + /** + * Clears a time segment of all electricity markets for a given CO2 price. + * + * @param powerPlants + * to be used + * @param markets + * to clear + * @return the total CO2 emissions + */ + @Transactional + void clearOneOrTwoConnectedElectricityMarketsAtAGivenCO2PriceForOneSegment(double interconnectorCapacity, + Segment segment, Government government, long clearingTick, boolean forecast, + Map demandGrowthMap) { + + GlobalSegmentClearingOutcome globalOutcome = new GlobalSegmentClearingOutcome(); + + globalOutcome.loads = determineActualDemandForSpotMarkets(segment, demandGrowthMap); + + globalOutcome.globalLoad = determineTotalLoadFromLoadMap(globalOutcome.loads); + + // Keep track of supply per market. Start at 0. + for (ElectricitySpotMarket m : reps.marketRepository.findAllElectricitySpotMarkets()) { + globalOutcome.supplies.put(m, 0d); + } + + // empty list of plants that are supplying. + double marginalPlantMarginalCost = clearGlobalMarketWithNoCapacityConstraints(segment, globalOutcome, forecast, + clearingTick); + + // For each plant in the cost-ordered list + + // Determine the flow over the interconnector. + ElectricitySpotMarket firstMarket = reps.marketRepository.findAllElectricitySpotMarkets().iterator().next(); + double loadInFirstMarket = globalOutcome.loads.get(firstMarket); + double supplyInFirstMarket = globalOutcome.supplies.get(firstMarket); + + // Interconnector flow defined as from market A --> market B = positive + double interconnectorFlow = supplyInFirstMarket - loadInFirstMarket; + + logger.info("Before market coupling interconnector flow: {}, available interconnector capacity {}", + interconnectorFlow, interconnectorCapacity); + + // if interconnector is not limiting or there is only one market, there + // is one price + if (reps.marketRepository.countAllElectricitySpotMarkets() < 2 + || Math.abs(interconnectorFlow) + epsilon <= interconnectorCapacity) { + // Set the price to the bid of the marginal plant. + for (ElectricitySpotMarket market : reps.marketRepository.findAllElectricitySpotMarkets()) { + double supplyInThisMarket = globalOutcome.supplies.get(market); + + // globalOutcome.globalSupply += supplyInThisMarket; + + if (globalOutcome.globalLoad <= globalOutcome.globalSupply + epsilon) { + globalOutcome.globalPrice = marginalPlantMarginalCost; + } else { + globalOutcome.globalPrice = market.getValueOfLostLoad(); + } + + double interconenctorFlowForCurrentMarket = market.equals(firstMarket) ? interconnectorFlow * (-1.0) + : interconnectorFlow; + + reps.clearingPointRepositoryOld.createOrUpdateSegmentClearingPoint(segment, market, + globalOutcome.globalPrice, + (supplyInThisMarket + interconenctorFlowForCurrentMarket) * segment.getLengthInHours(), + (interconenctorFlowForCurrentMarket * segment.getLengthInHours()), clearingTick, forecast); + logger.info("Stored a system-uniform price for market " + market + " / segment " + segment + + " -- supply " + supplyInThisMarket + " -- price: " + globalOutcome.globalPrice); + } + + } else { + + MarketSegmentClearingOutcome marketOutcomes = new MarketSegmentClearingOutcome(); + for (ElectricitySpotMarket m : reps.marketRepository.findAllElectricitySpotMarkets()) { + marketOutcomes.supplies.put(m, 0d); + marketOutcomes.prices.put(m, m.getValueOfLostLoad()); + } + + // else there are two prices + logger.info("There should be multiple prices, but first we should do market coupling."); + + boolean firstImporting = true; + if (interconnectorFlow > 0) { + firstImporting = false; + } + + + for (ElectricitySpotMarket market : reps.marketRepository.findAllElectricitySpotMarkets()) { + boolean first = market.equals(firstMarket); + // Update the load for this market. Which is market's true load + // +/- the full interconnector capacity, based on direction of + // the flow + if ((first && firstImporting) || (!first && !firstImporting)) { + marketOutcomes.loads.put(market, globalOutcome.loads.get(market) - interconnectorCapacity); + } else { + marketOutcomes.loads.put(market, globalOutcome.loads.get(market) + interconnectorCapacity); + } + + } + + // For each plant in the cost-ordered list + + clearTwoInterconnectedMarketsGivenAnInterconnectorAdjustedLoad(segment, marketOutcomes, clearingTick, + forecast); + + // updatePowerDispatchPlansAfterTwoCountryClearingIsComplete(segment); + + for (ElectricitySpotMarket market : reps.marketRepository.findAllElectricitySpotMarkets()) { + if (marketOutcomes.supplies.get(market) + epsilon < marketOutcomes.loads.get(market)) { + marketOutcomes.prices.put(market, market.getValueOfLostLoad()); + } + } + + for (ElectricitySpotMarket market : reps.marketRepository.findAllElectricitySpotMarkets()) { + double interconenctorFlowForCurrentMarket = (market.equals(firstMarket) && firstImporting) + || (!market.equals(firstMarket) && !firstImporting) ? interconnectorCapacity + : interconnectorCapacity * (-1.0); + reps.clearingPointRepositoryOld.createOrUpdateSegmentClearingPoint(segment, market, + marketOutcomes.prices.get(market), + (marketOutcomes.supplies.get(market) + interconenctorFlowForCurrentMarket) + * segment.getLengthInHours(), + (interconenctorFlowForCurrentMarket * segment.getLengthInHours()), clearingTick, forecast); + logger.info("Stored a market specific price for market " + market + " / segment " + segment + + " -- supply " + marketOutcomes.supplies.get(market) + " -- demand: " + + marketOutcomes.loads.get(market) + " -- price: " + marketOutcomes.prices.get(market)); + } + + @SuppressWarnings("unused") + int i = 0; + } + } + + void clearOneOrTwoConnectedElectricityMarketsAtAGivenCO2PriceForSegments(Government government, long clearingTick, + boolean forecast, Map demandGrowthMap, Map fuelPriceMap, + double co2Price, Map nationalMinCo2Prices, List segments, + Interconnector interconnector, DecarbonizationModel model) { + + submitOffersToElectricitySpotMarketRole.updateMarginalCostInclCO2AfterFuelMixChange(co2Price, + nationalMinCo2Prices, clearingTick, forecast, fuelPriceMap); + + if (model.isLongTermContractsImplemented()) + determineCommitmentOfPowerPlantsOnTheBasisOfLongTermContracts(segments, forecast); + + for (Segment segment : segments) { + clearOneOrTwoConnectedElectricityMarketsAtAGivenCO2PriceForOneSegment( + interconnector.getCapacity(clearingTick), + segment, government, clearingTick, forecast, demandGrowthMap); + } + } + + void clearTwoInterconnectedMarketsGivenAnInterconnectorAdjustedLoad(Segment segment, + MarketSegmentClearingOutcome marketOutcomes, long clearingTick, boolean forecast) { + + for (PowerPlantDispatchPlan plan : reps.powerPlantDispatchPlanRepository + .findSortedPowerPlantDispatchPlansForSegmentForTime(segment, clearingTick, forecast)) { + + ElectricitySpotMarket myMarket = (ElectricitySpotMarket) plan.getBiddingMarket(); + + // Make it produce as long as there is load. + double plantSupply = determineProductionOnSpotMarket(plan, marketOutcomes.supplies.get(myMarket), + marketOutcomes.loads.get(myMarket)); + if (plantSupply > 0) { + // Plant is producing, store the information to + // determine price and so on. + marketOutcomes.supplies.put(myMarket, marketOutcomes.supplies.get(myMarket) + plantSupply); + marketOutcomes.prices.put(myMarket, plan.getPrice()); + // logger.warn("Storing price: {} for plant {} in market " + + // myMarket, plantCost.getValue(), plant); + } + } + + } + + void clearCO2AndElectricitySpotMarketTwoCountryWithBanking(DecarbonizationModel model, boolean forecast, + long clearingTick, Map fuelPriceMap, Map demandGrowthMap) { + + double previouslyBankedCertificates = reps.decarbonizationAgentRepository + .determineTotallyBankedCO2Certificates(); + + // Check we are not in timestep 0 + if (clearingTick < 1) { + clearIterativeCO2AndElectricitySpotMarketTwoCountryForTimestepAndFuelPrices(model, forecast, clearingTick, + fuelPriceMap, demandGrowthMap, 0); + return; + } + CO2Auction co2Auction = template.findAll(CO2Auction.class).iterator().next(); + // find all interconnectors + Interconnector interconnector = template.findAll(Interconnector.class).iterator().next(); + + Government government = template.findAll(Government.class).iterator().next(); + + // find all segments + List segments = Utils.asList(reps.segmentRepository.findAll()); + + ClearingPoint forecastedCO2Clearing = reps.clearingPointRepository.findClearingPointForMarketAndTime( + co2Auction, clearingTick + model.getCentralForecastingYear(), true); + ClearingPoint lastCO2Clearing = reps.clearingPointRepository.findClearingPointForMarketAndTime(co2Auction, + clearingTick - 1, false); + + double maximumEnergyProducerBanking = calculateTargetCO2EmissionBankingOfEnergyProducers(clearingTick, + clearingTick + model.getCentralForecastingYear(), government, model); + + CO2SecantSearch co2SecantSearch = clearIterativeCO2AndElectricitySpotMarketTwoCountryForTimestepAndFuelPrices( + model, forecast, clearingTick, fuelPriceMap, demandGrowthMap, 0); + + double fundamentalCO2Price = calculateFundamentalCO2PriceForEnergyProducers(clearingTick, model, co2Auction, + co2SecantSearch); + logger.warn("Fundanmental price: {}", fundamentalCO2Price); + + // find national minimum CO2 prices. Initial Map size is 2. + Map nationalMinCo2Prices = new HashMap(2); + Iterable nationalGovernments = template.findAll(NationalGovernment.class); + for (NationalGovernment nG : nationalGovernments) { + if (model.isCo2TradingImplemented()) { + nationalMinCo2Prices.put(reps.marketRepository.findElectricitySpotMarketByNationalGovernment(nG), nG + .getMinNationalCo2PriceTrend().getValue(clearingTick)); + } else { + nationalMinCo2Prices.put(reps.marketRepository.findElectricitySpotMarketByNationalGovernment(nG), 0d); + } + } + + double adjustedFundamentalCO2Price = fundamentalCO2Price + * calculateCO2PriceReductionFactor(government, maximumEnergyProducerBanking, + previouslyBankedCertificates, 10, clearingTick); + + double previousAdjustedFundamentalCO2Price = adjustedFundamentalCO2Price; + double co2emissions; + double deltaBankedEmissionCertificates; + + // adjust fundamental CO2Price + int i = 0; + do { + + previousAdjustedFundamentalCO2Price = adjustedFundamentalCO2Price; + + clearOneOrTwoConnectedElectricityMarketsAtAGivenCO2PriceForSegments(government, clearingTick, forecast, + demandGrowthMap, fuelPriceMap, adjustedFundamentalCO2Price, nationalMinCo2Prices, segments, + interconnector, model); + + co2emissions = determineTotalEmissionsBasedOnPowerPlantDispatchPlan(forecast, clearingTick); + + deltaBankedEmissionCertificates = government.getCo2Cap(clearingTick) - co2emissions; + adjustedFundamentalCO2Price = fundamentalCO2Price + * calculateCO2PriceReductionFactor(government, maximumEnergyProducerBanking, + previouslyBankedCertificates, 10, clearingTick); + + i++; + adjustedFundamentalCO2Price = fundamentalCO2Price + * calculateCO2PriceReductionFactor(government, maximumEnergyProducerBanking, + previouslyBankedCertificates + deltaBankedEmissionCertificates, 10, clearingTick); + + logger.warn("CO2 Fundamental Price iteration " + i + ", Old: {}, New:{}", + previousAdjustedFundamentalCO2Price, adjustedFundamentalCO2Price); + + } while (Math.abs(adjustedFundamentalCO2Price - previousAdjustedFundamentalCO2Price) > 1); + + if (previouslyBankedCertificates + deltaBankedEmissionCertificates > 0) { + + reps.clearingPointRepositoryOld.createOrUpdateClearingPoint(co2Auction, adjustedFundamentalCO2Price, + co2emissions, clearingTick, forecast); + + for (EnergyProducer producer : reps.energyProducerRepository.findAll()) { + producer.setLastYearsCo2Allowances(producer.getCo2Allowances()); + double futureEmissionShare = determineTotalEmissionsBasedOnPowerPlantDispatchPlanForEnergyProducer( + true, clearingTick + model.getCentralForecastingYear(), producer) + / forecastedCO2Clearing.getVolume(); + double bankedEmissionsOfProducer = (deltaBankedEmissionCertificates + previouslyBankedCertificates) + * futureEmissionShare; + producer.setCo2Allowances(bankedEmissionsOfProducer); + } + } else { + clearIterativeCO2AndElectricitySpotMarketTwoCountryForTimestepAndFuelPrices(model, forecast, clearingTick, + fuelPriceMap, demandGrowthMap, previouslyBankedCertificates); + for (EnergyProducer producer : reps.energyProducerRepository.findAll()) { + producer.setLastYearsCo2Allowances(producer.getCo2Allowances()); + producer.setCo2Allowances(0); + } + } + + } + + public void clearIterativeCO2ElectricitySpotMarketAndFutureMarketTwoCountryForTimestepAndFuelPrices( + DecarbonizationModel model, long clearingTick) { + + if (model == null) + model = template.findAll(DecarbonizationModel.class).iterator().next(); + + Map fuelPriceMap = new HashMap(); + for (Substance substance : template.findAll(Substance.class)) { + fuelPriceMap.put(substance, findLastKnownPriceForSubstance(substance)); + } + + logger.warn(fuelPriceMap.toString()); + + Map futureFuelPriceMap = predictFuelPrices(model.getCentralForecastBacklookingYears(), + clearingTick + model.getCentralForecastingYear()); + + Map futureDemandGrowthMap = predictDemand( + model.getCentralForecastBacklookingYears(), clearingTick + model.getCentralForecastingYear()); + + // find national minimum CO2 prices. Initial Map size is 2. + Map futureNationalMinCo2Prices = new HashMap(2); + Iterable nationalGovernments = template.findAll(NationalGovernment.class); + for (NationalGovernment nG : nationalGovernments) { + if (model.isCo2TradingImplemented()) { + futureNationalMinCo2Prices.put(reps.marketRepository.findElectricitySpotMarketByNationalGovernment(nG), + nG.getMinNationalCo2PriceTrend().getValue(clearingTick + model.getCentralForecastingYear())); + } else { + futureNationalMinCo2Prices.put(reps.marketRepository.findElectricitySpotMarketByNationalGovernment(nG), + 0d); + } + + } + + // find all operational power plants and store the ones operational to a + // list. + + logger.info("Clearing the CO2 and electricity spot markets using iteration for 2 countries "); + + // find all fuel prices + + // find all interconnectors + Interconnector interconnector = template.findAll(Interconnector.class).iterator().next(); + + // find all segments + List segments = Utils.asList(reps.segmentRepository.findAll()); + + // find the EU government + Government government = template.findAll(Government.class).iterator().next(); + + // find national minimum CO2 prices. Initial Map size is 2. + // find national minimum CO2 prices. Initial Map size is 2. + Map nationalMinCo2Prices = new HashMap(2); + nationalGovernments = template.findAll(NationalGovernment.class); + for (NationalGovernment nG : nationalGovernments) { + if (model.isCo2TradingImplemented()) { + nationalMinCo2Prices.put(reps.marketRepository.findElectricitySpotMarketByNationalGovernment(nG), nG + .getMinNationalCo2PriceTrend().getValue(clearingTick)); + } else { + nationalMinCo2Prices.put(reps.marketRepository.findElectricitySpotMarketByNationalGovernment(nG), 0d); + } + + } + + CO2Auction co2Auction = template.findAll(CO2Auction.class).iterator().next(); + CO2SecantSearch co2SecantSearch = null; + + double previouslyBankedCertificates = reps.decarbonizationAgentRepository + .determineTotallyBankedCO2Certificates(); + + double targetEnergyProducerBanking = calculateTargetCO2EmissionBankingOfEnergyProducers(clearingTick, + clearingTick + model.getCentralForecastingYear(), government, model); + logger.warn("Hedging Target: {}, Relative Hedging: {}", targetEnergyProducerBanking, targetEnergyProducerBanking/government.getCo2Cap(getCurrentTick())); + + double deltaBankedEmissionCertificateToReachBankingTarget = (targetEnergyProducerBanking - previouslyBankedCertificates) + / model.getCentralCO2TargetReversionSpeedFactor(); + ; + double deltaBankedEmissionCertificates; + + co2SecantSearch = new CO2SecantSearch(); + co2SecantSearch.stable = false; + co2SecantSearch.twoPricesExistWithBelowAboveEmissions = false; + co2SecantSearch.bankingEffectiveMinimumPrice = calculateBankingEffectiveMinCO2Price(nationalMinCo2Prices, + futureNationalMinCo2Prices, model); + co2SecantSearch.co2Price = Math.max(findLastKnownPriceOnMarket(co2Auction), + co2SecantSearch.bankingEffectiveMinimumPrice); + co2SecantSearch.tooHighEmissionsPair = null; + co2SecantSearch.tooLowEmissionsPair = null; + + double futureCO2Price = 0; + + double currentEmissions = 0; + double futureEmissions = 0; + double co2CapAdjustment = 0; + + double averageCO2PriceOfLastTwoYears = reps.clearingPointRepository + .calculateAverageClearingPriceForMarketAndTimeRange(co2Auction, getCurrentTick() - 2, + getCurrentTick() - 1, false); + + determineFuelMixRole.determineFuelMixForecastForYearAndFuelPriceMap(clearingTick, futureFuelPriceMap, + futureNationalMinCo2Prices); + + submitOffersToElectricitySpotMarketRole.createOffersForElectricitySpotMarket(null, + clearingTick + model.getCentralForecastingYear(), true, futureFuelPriceMap); + + // Change Iteration algorithm here, and a few lines below... + + ClearingPoint lastClearingPointOfCo2Market = reps.clearingPointRepositoryOld.findClearingPointForMarketAndTime( + co2Auction, getCurrentTick() - 1, false); + if (lastClearingPointOfCo2Market != null) { + co2SecantSearch.co2Emissions = lastClearingPointOfCo2Market.getVolume(); + } else { + co2SecantSearch.co2Emissions = 0d; + } + + boolean emergencyPriceTriggerActive = false; + int breakOffIterator = 0; + double emergencyAllowancesToBeReleased = 0; + while (breakOffIterator < 2 || !co2SecantSearch.stable) { + + if (breakOffIterator > 15) { + logger.warn("Iteration cancelled, last found CO2 Price is used."); + break; + } + + futureCO2Price = co2SecantSearch.co2Price + * Math.pow(1 + model.getCentralPrivateDiscountingRate(), model.getCentralForecastingYear()); + + logger.warn("Iteration " + breakOffIterator + ", CO2Price for clearing: " + co2SecantSearch.co2Price); + clearOneOrTwoConnectedElectricityMarketsAtAGivenCO2PriceForSegments(government, + clearingTick + model.getCentralForecastingYear(), true, futureDemandGrowthMap, futureFuelPriceMap, + futureCO2Price, futureNationalMinCo2Prices, segments, interconnector, model); + futureEmissions = determineTotalEmissionsBasedOnPowerPlantDispatchPlan(true, + clearingTick + model.getCentralForecastingYear()); + + clearOneOrTwoConnectedElectricityMarketsAtAGivenCO2PriceForSegments(government, clearingTick, false, null, + fuelPriceMap, co2SecantSearch.co2Price, nationalMinCo2Prices, segments, interconnector, model); + currentEmissions = determineTotalEmissionsBasedOnPowerPlantDispatchPlan(false, clearingTick); + + // for (Substance substance : template.findAll(Substance.class)) { + // double sum = + // reps.powerPlantRepository.calculateSubstanceUsage(substance); + // logger.warn(substance.getName() + ": {}", sum); + // } + + deltaBankedEmissionCertificates = government.getCo2Cap(clearingTick) - currentEmissions; + + co2SecantSearch = co2PriceSecantSearchUpdateWithCO2Banking(co2SecantSearch, model, government, + clearingTick, -deltaBankedEmissionCertificateToReachBankingTarget, currentEmissions, + futureEmissions, previouslyBankedCertificates, averageCO2PriceOfLastTwoYears); + + // logger.warn("Iteration: " + breakOffIterator + ": " + + // co2SecantSearch.toString() + ", Future: " + // + futureCO2Price); + + if (!co2SecantSearch.stable) { + targetEnergyProducerBanking = calculateTargetCO2EmissionBankingOfEnergyProducers(currentEmissions, + futureEmissions, model); +<<<<<<< HEAD + logger.warn("Hedging Target: {}, Relative Hedging: {}", targetEnergyProducerBanking, targetEnergyProducerBanking/government.getCo2Cap(getCurrentTick())); +======= + // logger.warn("Hedging Target: {}, Relative Hedging: {}", + // targetEnergyProducerBanking, + // targetEnergyProducerBanking/government.getCo2Cap(getCurrentTick())); +>>>>>>> Jorn/feature/historicalCVar + + deltaBankedEmissionCertificateToReachBankingTarget = (targetEnergyProducerBanking - previouslyBankedCertificates) + / model.getCentralCO2TargetReversionSpeedFactor(); + } + + if (co2SecantSearch.stable || breakOffIterator >= 15) { + logger.warn("Average price last 2 years: {}, Clearing price {}", averageCO2PriceOfLastTwoYears, + co2SecantSearch.co2Price); + logger.warn("StabilityReserveActive: " + + model.isStabilityReserveIsActive() + + ", InOperation: " + + (model.getStabilityReserveFirstYearOfOperation() <= clearingTick + + model.getCentralForecastingYear()) + ", priceEmergencyTriggerNotActive: " + + !emergencyPriceTriggerActive + ", 3x Price: " + + (co2SecantSearch.co2Price > 3 * averageCO2PriceOfLastTwoYears)); + if ((model.isStabilityReserveIsActive() + && (model.getStabilityReserveFirstYearOfOperation() <= clearingTick) && !emergencyPriceTriggerActive) + && (co2SecantSearch.co2Price > 3 * averageCO2PriceOfLastTwoYears) + && government.getStabilityReserve() > 0) { + breakOffIterator = 0; + emergencyPriceTriggerActive = true; + emergencyAllowancesToBeReleased = Math.min(government.getStabilityReserve(), government + .getStabilityReserveReleaseQuantityTrend().getValue(clearingTick)); + logger.warn( + "Stability Reserve releasing " + emergencyAllowancesToBeReleased + + " credits since price would be {}, which has 3x time higher than {}", + co2SecantSearch.co2Price, averageCO2PriceOfLastTwoYears); + co2SecantSearch.stable = false; + co2SecantSearch.twoPricesExistWithBelowAboveEmissions = false; + co2SecantSearch.tooHighEmissionsPair = null; + co2SecantSearch.tooLowEmissionsPair = null; + government.getCo2CapTrend().setValue(getCurrentTick(), + government.getCo2CapTrend().getValue(getCurrentTick()) + emergencyAllowancesToBeReleased); + government.setStabilityReserve(government.getStabilityReserve() - emergencyAllowancesToBeReleased); + } + } + breakOffIterator++; + + } + + if (model.getCentralCO2BackSmoothingFactor() != 0) { + + Iterable clearingPoints = reps.clearingPointRepository + .findAllClearingPointsForMarketAndTimeRange(co2Auction, + clearingTick - model.getCentralForecastBacklookingYears(), clearingTick, false); + + double averagePastCO2Price = 0; + int i = 0; + for (ClearingPoint cp : clearingPoints) { + averagePastCO2Price = (cp.getPrice() + / Math.pow(1 + model.getCentralPrivateDiscountingRate(), clearingTick - cp.getTime()) + i + * averagePastCO2Price) + / (i + 1); + i++; + } + + double oldCO2Price = co2SecantSearch.co2Price; + co2SecantSearch.co2Price = (1 - model.getCentralCO2BackSmoothingFactor()) * co2SecantSearch.co2Price + + model.getCentralCO2BackSmoothingFactor() * averagePastCO2Price; + if (oldCO2Price != co2SecantSearch.bankingEffectiveMinimumPrice + && co2SecantSearch.co2Price > co2SecantSearch.bankingEffectiveMinimumPrice) { + futureCO2Price = co2SecantSearch.co2Price + * Math.pow(1 + model.getCentralPrivateDiscountingRate(), model.getCentralForecastingYear()); + clearOneOrTwoConnectedElectricityMarketsAtAGivenCO2PriceForSegments(government, + clearingTick + model.getCentralForecastingYear(), true, futureDemandGrowthMap, + futureFuelPriceMap, futureCO2Price, futureNationalMinCo2Prices, segments, interconnector, model); + futureEmissions = determineTotalEmissionsBasedOnPowerPlantDispatchPlan(true, + clearingTick + model.getCentralForecastingYear()); + + clearOneOrTwoConnectedElectricityMarketsAtAGivenCO2PriceForSegments(government, clearingTick, false, + null, fuelPriceMap, co2SecantSearch.co2Price, nationalMinCo2Prices, segments, interconnector, + model); + currentEmissions = determineTotalEmissionsBasedOnPowerPlantDispatchPlan(false, clearingTick); + } else { + co2SecantSearch.co2Price = oldCO2Price; + } + } + +<<<<<<< HEAD +======= + logger.warn("CO2Price that is saved: " + co2SecantSearch.co2Price); +>>>>>>> Jorn/feature/historicalCVar + reps.clearingPointRepositoryOld.createOrUpdateCO2MarketClearingPoint(co2Auction, co2SecantSearch.co2Price, + currentEmissions, emergencyPriceTriggerActive, emergencyAllowancesToBeReleased, clearingTick, false); + reps.clearingPointRepositoryOld.createOrUpdateCO2MarketClearingPoint(co2Auction, + Math.max(futureCO2Price, Collections.min(futureNationalMinCo2Prices.values())), futureEmissions, false, + 0, + clearingTick + model.getCentralForecastingYear(), true); + + if (co2SecantSearch.co2Price > co2SecantSearch.bankingEffectiveMinimumPrice) + deltaBankedEmissionCertificates = government.getCo2Cap(clearingTick) - currentEmissions; + else { + deltaBankedEmissionCertificates = Math.min(deltaBankedEmissionCertificateToReachBankingTarget, + government.getCo2Cap(clearingTick) - currentEmissions); + } + + if (previouslyBankedCertificates + deltaBankedEmissionCertificates > 0) { + for (EnergyProducer producer : reps.energyProducerRepository.findAll()) { + producer.setLastYearsCo2Allowances(producer.getCo2Allowances()); + double emissionShare = determineTotalEmissionsBasedOnPowerPlantDispatchPlanForEnergyProducer(false, + clearingTick, producer) / currentEmissions; + double bankedEmissionsOfProducer = (deltaBankedEmissionCertificates + previouslyBankedCertificates) + * emissionShare; + producer.setCo2Allowances(bankedEmissionsOfProducer); + } + } else { + logger.warn("Banking exhausted."); + clearIterativeCO2AndElectricitySpotMarketTwoCountryForTimestepAndFuelPrices(model, true, clearingTick + + model.getCentralForecastingYear(), futureFuelPriceMap, futureDemandGrowthMap, 0); + clearIterativeCO2AndElectricitySpotMarketTwoCountryForTimestepAndFuelPrices(model, false, clearingTick, + fuelPriceMap, null, previouslyBankedCertificates); + for (EnergyProducer producer : reps.energyProducerRepository.findAll()) { + producer.setLastYearsCo2Allowances(producer.getCo2Allowances()); + producer.setCo2Allowances(0); + } + + } + } + + double[] interpolateLinearDiscountedPricesBetweenClearingPoints(ClearingPoint cp1, ClearingPoint cp2, + double discountRate) { + int length = (int) Math.abs(cp1.getTime() - cp2.getTime()); + ClearingPoint earlierCp = cp1.getTime() <= cp2.getTime() ? cp1 : cp2; + ClearingPoint laterCp = cp1.getTime() <= cp2.getTime() ? cp2 : cp1; + double[] priceInterpolation = new double[length]; + for (int i = 0; i < length; i++) { + priceInterpolation[i] = earlierCp.getPrice() + ((double) i + 1) / (length) + * (laterCp.getPrice() - earlierCp.getPrice()) / Math.pow((1 + discountRate), i); + } + + return priceInterpolation; + } + + double[] interpolateLinearVolumesBetweenClearingPoints(ClearingPoint cp1, ClearingPoint cp2) { + int length = (int) Math.abs(cp1.getTime() - cp2.getTime()); + ClearingPoint earlierCp = cp1.getTime() <= cp2.getTime() ? cp1 : cp2; + ClearingPoint laterCp = cp1.getTime() <= cp2.getTime() ? cp2 : cp1; + double[] volumeInterpolation = new double[length]; + for (int i = 0; i < length; i++) { + volumeInterpolation[i] = earlierCp.getVolume() + ((double) i + 1) / (length) + * (laterCp.getVolume() - earlierCp.getVolume()); + } + + return volumeInterpolation; + } + + double calculateTargetCO2EmissionBankingOfEnergyProducers(long timeFrom, long timeTo, Government government, DecarbonizationModel model) { + int length = (int) (timeTo - timeFrom); + double[] volumeInterpolation = new double[length]; + for (int i = 0; i < length; i++) { + volumeInterpolation[i] = government.getCo2Cap(timeFrom) + ((double) i + 1) / (length) + * (government.getCo2Cap(timeTo) - government.getCo2Cap(timeFrom)); + } + // double targetBankedEmissions = 0.8 * volumeInterpolation[0] + 0.5 * + // volumeInterpolation[1] + 0.2 + // * volumeInterpolation[2]; + double targetBankedEmissions = model.getStabilityReserveBankingFirstYear() * volumeInterpolation[0] + + model.getStabilityReserveBankingSecondYear() * volumeInterpolation[1] + + model.getStabilityReserveBankingThirdYear() + * volumeInterpolation[2]; + + return targetBankedEmissions; + } + + double calculateTargetCO2EmissionBankingOfEnergyProducers(double currentEmissions, double futureEmissions, + DecarbonizationModel model) { + int length = (int) model.getCentralForecastingYear(); + double[] volumeInterpolation = new double[length]; + for (int i = 0; i < length; i++) { + volumeInterpolation[i] = currentEmissions + ((double) i + 1) / (length) + * (futureEmissions - currentEmissions); + } + // double targetBankedEmissions = 0.8 * volumeInterpolation[0] + 0.5 * volumeInterpolation[1] + 0.2 + // * volumeInterpolation[2]; + double targetBankedEmissions = model.getStabilityReserveBankingFirstYear() * volumeInterpolation[0] + + model.getStabilityReserveBankingSecondYear() * volumeInterpolation[1] + + model.getStabilityReserveBankingThirdYear() + * volumeInterpolation[2]; + + return targetBankedEmissions; + } + + double calculateFundamentalCO2PriceForEnergyProducers(long clearingTick, DecarbonizationModel model, + CO2Auction co2Auction, CO2SecantSearch co2SecantSearch) { + + ClearingPoint forecastedCO2Clearing = reps.clearingPointRepository.findClearingPointForMarketAndTime( + co2Auction, clearingTick + model.getCentralForecastingYear(), true); + ClearingPoint lastCO2Clearing; + if (co2SecantSearch == null) + lastCO2Clearing = reps.clearingPointRepository.findClearingPointForMarketAndTime(co2Auction, + clearingTick - 1, false); + else { + lastCO2Clearing = new ClearingPoint(); + lastCO2Clearing.setPrice(co2SecantSearch.co2Price); + lastCO2Clearing.setVolume(co2SecantSearch.co2Emissions); + lastCO2Clearing.setTime(clearingTick); + } + double[] priceInterpolation = interpolateLinearDiscountedPricesBetweenClearingPoints(lastCO2Clearing, + forecastedCO2Clearing, model.getCentralPrivateDiscountingRate()); + logger.warn("Price interpolation: {}", priceInterpolation); + double[] volumeInterpolation = interpolateLinearVolumesBetweenClearingPoints(lastCO2Clearing, + forecastedCO2Clearing); + logger.warn("Volume interpolation: {}", volumeInterpolation); + double totalEmissions = 0; + double fundamentalPrice = 0; + for (int i = 0; i < volumeInterpolation.length; i++) { + fundamentalPrice += priceInterpolation[i] * volumeInterpolation[i]; + totalEmissions += volumeInterpolation[i]; + } + fundamentalPrice = fundamentalPrice / totalEmissions; + return fundamentalPrice; + } + + double calculateCO2PriceReductionFactor(Government government, double maximumEnergyProducerBanking, + double bankedCertificates, long yearsForwardLooking, long clearingTick) { + double allowedEmissionsInFuture = 0d; + for (long i = clearingTick; i < (clearingTick + yearsForwardLooking); i++) { + allowedEmissionsInFuture += government.getCo2Cap(i); + } + double co2PriceReductionFactor = 1 - ((bankedCertificates - maximumEnergyProducerBanking) / allowedEmissionsInFuture); + return co2PriceReductionFactor; + } + + double calculateBankingEffectiveMinCO2Price(Map nationalMinCo2Prices, + Map futureNationalMinCo2Prices, DecarbonizationModel model) { + double currentMinimumPrice = Collections.min(nationalMinCo2Prices.values()); + // double futureMinimumPrice = + // Collections.min(futureNationalMinCo2Prices.values()); + // double bankingEffectiveCO2Price = Math.max( + // currentMinimumPrice, + // futureMinimumPrice + // / Math.pow(1 + model.getCentralPrivateDiscountingRate(), + // model.getCentralForecastingYear())); + return currentMinimumPrice; + } + + CO2SecantSearch co2PriceSecantSearchUpdateWithCO2Banking(CO2SecantSearch co2SecantSearch, + DecarbonizationModel model, Government government, long clearingTick, double co2CapAdjustment, + double currentEmissions, double futureEmissions, double previouslyBankedCertificates, + double averageCO2PriceOfLastTwoYears) { + co2SecantSearch.stable = false; + double capDeviationCriterion = model.getCapDeviationCriterion(); + double currentCap = government.getCo2Cap(clearingTick); +<<<<<<< HEAD + logger.warn("Current cap: {}", currentCap); + double futureCap = government.getCo2Cap(clearingTick + model.getCentralForecastingYear()); + logger.warn("Future cap: {}", futureCap); +======= + // logger.warn("Current cap: {}", currentCap); + double futureCap = government.getCo2Cap(clearingTick + model.getCentralForecastingYear()); + // logger.warn("Future cap: {}", futureCap); +>>>>>>> Jorn/feature/historicalCVar + // logger.warn("Is MSR active in future ? {}.", + // (model.isStabilityReserveIsActive() && (model.getStabilityReserveFirstYearOfOperation() <= clearingTick + // + model.getCentralForecastingYear()))); + // logger.warn("First year MSR is active: {}", model.getStabilityReserveFirstYearOfOperation()); + double expectedBankedPermits = calculateExpectedBankedCertificates(currentEmissions, futureEmissions, + currentCap, futureCap, previouslyBankedCertificates, model.getCentralForecastingYear(), government); + double effectiveCapInFuture = (model.isStabilityReserveIsActive() && (model + .getStabilityReserveFirstYearOfOperation() <= clearingTick + model.getCentralForecastingYear())) ? futureCap + - marketStabilityReserveRole.calculateInflowToMarketReserveForTimeStep( + clearingTick + model.getCentralForecastingYear(), + expectedBankedPermits, + government) + : futureCap; +<<<<<<< HEAD + logger.warn("effective future cap: {}", effectiveCapInFuture); +======= + // logger.warn("effective future cap: {}", effectiveCapInFuture); +>>>>>>> Jorn/feature/historicalCVar + effectiveCapInFuture -= (government.isActivelyAdjustingTheCO2Cap() & getCurrentTick() > 0) ? renewableAdaptiveCO2CapRole + .calculatedExpectedCapReductionForTimeStep(government, clearingTick, + clearingTick + model.getCentralForecastingYear(), currentEmissions, futureEmissions, + model.getCentralForecastingYear()) : 0; + double co2Cap = currentCap + effectiveCapInFuture + co2CapAdjustment; + co2SecantSearch.co2Emissions = currentEmissions + futureEmissions; + + double deviation = (co2SecantSearch.co2Emissions - co2Cap) / co2Cap; + + if (co2SecantSearch.co2Price == co2SecantSearch.bankingEffectiveMinimumPrice + && co2SecantSearch.co2Emissions < co2Cap) { + co2SecantSearch.stable = true; + return co2SecantSearch; + } + + // Check if current price leads to emissions close to the cap. + if (Math.abs(deviation) < capDeviationCriterion + && co2SecantSearch.co2Price > co2SecantSearch.bankingEffectiveMinimumPrice) { + // logger.warn("Deviation is less than capDeviationCriterion"); + co2SecantSearch.stable = true; + return co2SecantSearch; + } + + // Check and update the twoPricesExistWithBelowAboveEmissions + + if (co2SecantSearch.tooHighEmissionsPair != null && co2SecantSearch.tooLowEmissionsPair != null) { + co2SecantSearch.twoPricesExistWithBelowAboveEmissions = true; + } else if (co2SecantSearch.co2Price == government.getMinCo2Price(clearingTick) + && co2SecantSearch.co2Emissions < co2Cap) { + // logger.warn("Deviation CO2 price has reached minimum"); + // check if stable enough --> 2. Cap is met with a co2Price + // equal to the minimum co2 price + co2SecantSearch.stable = true; + return co2SecantSearch; + } else if (co2SecantSearch.co2Price >= government.getCo2Penalty(clearingTick) + && co2SecantSearch.co2Emissions >= co2Cap) { + // Only if above the cap... + // logger.warn("CO2 price ceiling reached {}", + // co2SecantSearch.co2Price); + co2SecantSearch.co2Price = government.getCo2Penalty(clearingTick); + co2SecantSearch.stable = true; + return co2SecantSearch; + } + + // Check whether we know two pairs, one with EmissionsAboveCap, one with + // EmissionsBelowCap + // in case of yes: calculate new CO2 price via secant calculation. In + // case of no: Take last known + // price above or below, or halve/double the price. + if (co2SecantSearch.twoPricesExistWithBelowAboveEmissions) { + + // Update the emission pairs + if (deviation > 0) { + co2SecantSearch.tooHighEmissionsPair.price = co2SecantSearch.co2Price; + co2SecantSearch.tooHighEmissionsPair.emission = co2SecantSearch.co2Emissions - co2Cap; + } else { + co2SecantSearch.tooLowEmissionsPair.price = co2SecantSearch.co2Price; + co2SecantSearch.tooLowEmissionsPair.emission = co2SecantSearch.co2Emissions - co2Cap; + } + + double p2 = co2SecantSearch.tooHighEmissionsPair.price; + double p1 = co2SecantSearch.tooLowEmissionsPair.price; + double e2 = co2SecantSearch.tooHighEmissionsPair.emission; + double e1 = co2SecantSearch.tooLowEmissionsPair.emission; + + // Interrupts long iterations by making a binary search step. + if (co2SecantSearch.iteration < 5) { + co2SecantSearch.co2Price = p1 - (e1 * (p2 - p1) / (e2 - e1)); + co2SecantSearch.iteration++; + // logger.warn("New CO2 Secant price {}", + // co2SecantSearch.co2Price); + } else { + co2SecantSearch.co2Price = (p1 + p2) / 2; + co2SecantSearch.iteration = 0; + // logger.warn("New CO2 Binary price {}", + // co2SecantSearch.co2Price); + } + + } else { + + if (deviation > 0) { + if (co2SecantSearch.tooHighEmissionsPair == null) + co2SecantSearch.tooHighEmissionsPair = new PriceEmissionPair(); + + co2SecantSearch.tooHighEmissionsPair.price = co2SecantSearch.co2Price; + co2SecantSearch.tooHighEmissionsPair.emission = co2SecantSearch.co2Emissions - co2Cap; + + if (co2SecantSearch.tooLowEmissionsPair == null) { + co2SecantSearch.co2Price = (co2SecantSearch.co2Price != 0d) ? ((co2SecantSearch.co2Price * 2 < government + .getCo2Penalty(clearingTick)) ? (co2SecantSearch.co2Price * 2) : government + .getCo2Penalty(clearingTick)) : 5d; + // logger.warn("New doubled CO2 search price {}", + // co2SecantSearch.co2Price); + } else { + double p2 = co2SecantSearch.tooHighEmissionsPair.price; + double p1 = co2SecantSearch.tooLowEmissionsPair.price; + double e2 = co2SecantSearch.tooHighEmissionsPair.emission; + double e1 = co2SecantSearch.tooLowEmissionsPair.emission; + + co2SecantSearch.co2Price = p1 - (e1 * (p2 - p1) / (e2 - e1)); + co2SecantSearch.iteration++; + // logger.warn("New CO2 Secant price {}", + // co2SecantSearch.co2Price); + } + + } else { + + if (co2SecantSearch.tooLowEmissionsPair == null) + co2SecantSearch.tooLowEmissionsPair = new PriceEmissionPair(); + + co2SecantSearch.tooLowEmissionsPair.price = co2SecantSearch.co2Price; + co2SecantSearch.tooLowEmissionsPair.emission = co2SecantSearch.co2Emissions - co2Cap; + + if (co2SecantSearch.tooHighEmissionsPair == null) { + co2SecantSearch.co2Price = Math.max((co2SecantSearch.co2Price / 2), + co2SecantSearch.bankingEffectiveMinimumPrice); + // logger.warn("New halved CO2 search price {}", + // co2SecantSearch.co2Price); + } else { + double p2 = co2SecantSearch.tooHighEmissionsPair.price; + double p1 = co2SecantSearch.tooLowEmissionsPair.price; + double e2 = co2SecantSearch.tooHighEmissionsPair.emission; + double e1 = co2SecantSearch.tooLowEmissionsPair.emission; + + co2SecantSearch.co2Price = p1 - (e1 * (p2 - p1) / (e2 - e1)); + // logger.warn("New CO2 Secant price {}", + // co2SecantSearch.co2Price); + co2SecantSearch.iteration++; + + } + + if (co2SecantSearch.co2Price < 0.5 + || co2SecantSearch.co2Price - government.getMinCo2Price(clearingTick) < 0.5) { + co2SecantSearch.stable = true; + } + + } + + } + + return co2SecantSearch; + + } + + double calculateExpectedBankedCertificates(double currentEmissions, double futureEmissions, double currentCap, + double futureCap, double currentlyBankedEmissions, long centralForecastingYear, Government government) { + double expectedBankedCertificates = currentlyBankedEmissions + currentCap - currentEmissions + futureCap + - futureEmissions; +<<<<<<< HEAD + expectedBankedCertificates = 1 / 3.0 +======= + expectedBankedCertificates = government.isStabilityReserveHasOneYearDelayInsteadOfTwoYearDelay() ? 2.0 / 3.0 + * expectedBankedCertificates + 1.0 / 3.0 * currentlyBankedEmissions : 1 / 3.0 +>>>>>>> Jorn/feature/historicalCVar + * expectedBankedCertificates + + 2 / 3.0 * currentlyBankedEmissions; + return expectedBankedCertificates; + + } + + @Override + public Reps getReps() { + return reps; + } + +} diff --git a/emlab-generation/src/main/java/emlab/gen/role/market/CreatingFinancialReports.java b/emlab-generation/src/main/java/emlab/gen/role/market/CreatingFinancialReports.java new file mode 100644 index 00000000..c3a47f55 --- /dev/null +++ b/emlab-generation/src/main/java/emlab/gen/role/market/CreatingFinancialReports.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * 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.market; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +import agentspring.role.RoleComponent; +import emlab.gen.domain.agent.DecarbonizationModel; +import org.springframework.data.neo4j.support.Neo4jTemplate; +import emlab.gen.domain.market.electricity.FinancialPowerPlantReport; +import emlab.gen.domain.technology.PowerPlant; +import emlab.gen.domain.technology.Substance; +import emlab.gen.domain.technology.SubstanceShareInFuelMix; +import emlab.gen.repository.Reps; + +/** + * Creating finanical reports for each power plant. Currently implemented for + * use with spot markets only. Long-term contracts are ignored since costs can + * not easily be assigned to individual power plants. + * + * @author Joern + * + */ +@RoleComponent +public class CreatingFinancialReports extends AbstractClearElectricitySpotMarketRole { + + @Autowired + private Reps reps; + + @Autowired + Neo4jTemplate template; + + @Transactional + public void act(DecarbonizationModel model) { + + Map fuelPriceMap = new HashMap(); + for (Substance substance : template.findAll(Substance.class)) { + fuelPriceMap.put(substance, findLastKnownPriceForSubstance(substance)); + } + logger.warn(fuelPriceMap.toString()); + + createFinancialReportsForPowerPlantsAndTick( + reps.powerPlantRepository.findAllPowerPlantsWhichAreNotDismantledBeforeTick(getCurrentTick() - 2), + getCurrentTick()); + + } + + public void createFinancialReportsForNewInvestments(DecarbonizationModel model) { + createFinancialReportsForPowerPlantsAndTick( + reps.powerPlantRepository.findAllPowerPlantsWithConstructionStartTimeInTick(getCurrentTick()), + getCurrentTick()); + } + + void createFinancialReportsForPowerPlantsAndTick(Iterable plants, long tick) { + + for (PowerPlant plant : plants) { + + FinancialPowerPlantReport financialPowerPlantReport = new FinancialPowerPlantReport(); + financialPowerPlantReport.setTime(tick); + financialPowerPlantReport.setFullLoadHours(0); + financialPowerPlantReport.setPowerPlant(plant); + financialPowerPlantReport.setCommodityCosts(0); + financialPowerPlantReport.persist(); + + + // Determining variable and CO2 costs in current time step. + double totalSupply = plant.calculateElectricityOutputAtTime(tick, false); + financialPowerPlantReport.setProduction(totalSupply); + + for (SubstanceShareInFuelMix share : plant.getFuelMix()) { + + double amount = share.getShare() * totalSupply; + Substance substance = share.getSubstance(); + double substanceCost = findLastKnownPriceForSubstance(substance) * amount; + financialPowerPlantReport.setCommodityCosts(financialPowerPlantReport.getCommodityCosts() + + substanceCost); + + + } + financialPowerPlantReport.setCo2Costs(reps.powerPlantRepository.calculateCO2CostsOfPowerPlant(plant, + tick)); + financialPowerPlantReport.setVariableCosts(financialPowerPlantReport.getCommodityCosts()+financialPowerPlantReport.getCo2Costs()); + + //Determine fixed costs + financialPowerPlantReport.setFixedCosts(reps.powerPlantRepository + .calculateFixedCostsOfPowerPlant(plant, + tick)); + + //Calculate overall revenue + financialPowerPlantReport.setSpotMarketRevenue(reps.powerPlantRepository + .calculateSpotMarketRevenueOfPowerPlant(plant, tick)); + + financialPowerPlantReport.setStrategicReserveRevenue(reps.powerPlantRepository + .calculateStrategicReserveRevenueOfPowerPlant(plant, tick)); + + financialPowerPlantReport.setCapacityMarketRevenue(reps.powerPlantRepository + .calculateCapacityMarketRevenueOfPowerPlant(plant, tick)); + + financialPowerPlantReport.setCo2HedgingRevenue(reps.powerPlantRepository + .calculateCO2HedgingRevenueOfPowerPlant(plant, tick)); + + + financialPowerPlantReport.setOverallRevenue(financialPowerPlantReport.getCapacityMarketRevenue() + financialPowerPlantReport.getCo2HedgingRevenue() + financialPowerPlantReport.getSpotMarketRevenue() + financialPowerPlantReport + .getStrategicReserveRevenue()); + + // Calculate Full load hours + financialPowerPlantReport.setFullLoadHours(reps.powerPlantRepository.calculateFullLoadHoursOfPowerPlant( + plant, tick)); + + int operationalStatus; + if (plant.isOperational(tick)) + operationalStatus = 1; + else if (plant.isInPipeline(tick)) + operationalStatus = 0; + else + operationalStatus = 2; + + financialPowerPlantReport.setPowerPlantStatus(operationalStatus); + + + + } + + } + +} diff --git a/emlab-generation/src/main/java/emlab/gen/role/tender/CalculateRenewableTargetForTenderRole.java b/emlab-generation/src/main/java/emlab/gen/role/tender/CalculateRenewableTargetForTenderRole.java new file mode 100644 index 00000000..e7641f97 --- /dev/null +++ b/emlab-generation/src/main/java/emlab/gen/role/tender/CalculateRenewableTargetForTenderRole.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * 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.tender; + +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.gis.Zone; +import emlab.gen.domain.market.electricity.ElectricitySpotMarket; +import emlab.gen.domain.market.electricity.Segment; +import emlab.gen.domain.market.electricity.SegmentLoad; +import emlab.gen.domain.policy.renewablesupport.RenewableSupportSchemeTender; +import emlab.gen.domain.policy.renewablesupport.RenewableTargetForTender; +import emlab.gen.domain.technology.PowerGeneratingTechnology; +import emlab.gen.domain.technology.PowerPlant; +import emlab.gen.repository.Reps; +import emlab.gen.util.GeometricTrendRegression; + +/** + * @author Kaveri, rjjdejeu + * + */ + +@RoleComponent +public class CalculateRenewableTargetForTenderRole extends AbstractRole + implements Role { + + @Autowired + Reps reps; + + @Override + @Transactional + public void act(RenewableSupportSchemeTender scheme) { + + double demandFactor; + double targetFactor; + Zone zone = scheme.getRegulator().getZone(); + ElectricitySpotMarket market = reps.marketRepository.findElectricitySpotMarketForZone(zone); + + // get demand factor + demandFactor = predictDemandForElectricitySpotMarket(market, + scheme.getRegulator().getNumberOfYearsLookingBackToForecastDemand(), + scheme.getFutureTenderOperationStartTime()); + + logger.warn("demandFactor for this tick: " + demandFactor); + logger.warn("future tender operations start time is: " + scheme.getFutureTenderOperationStartTime()); + + // get renewable energy target in factor (percent) + RenewableTargetForTender target = reps.renewableTargetForTenderRepository + .findRenewableTargetForTenderByRegulator(scheme.getRegulator()); + targetFactor = target.getYearlyRenewableTargetTimeSeries().getValue(scheme.getFutureTenderOperationStartTime()); + + logger.warn("zone is " + zone); + logger.warn("market is" + market); + logger.warn("scheme is " + scheme); + logger.warn("target is " + target); + + targetFactor = target.getYearlyRenewableTargetTimeSeries().getValue(scheme.getFutureTenderOperationStartTime()); + + logger.warn("targetFactor for this tick: " + targetFactor); + + // get totalLoad in MWh + double totalConsumption = 0; + for (SegmentLoad segmentLoad : reps.segmentLoadRepository.findAll()) { + + totalConsumption += segmentLoad.getBaseLoad() * demandFactor * segmentLoad.getSegment().getLengthInHours(); + } + + logger.warn("totalConsumption for this tick: " + totalConsumption); + + // renewable target for tender operation start year in MWh is + double renewableTargetInMwh = targetFactor * totalConsumption; + + logger.warn("renewableTargetInMwh for this tick: " + renewableTargetInMwh); + + // calculate expected generation, and subtract that from annual target. + // will be ActualTarget + double expectedGenerationPerTechnology = 0d; + double totalExpectedGeneration = 0d; + long numberOfSegments = reps.segmentRepository.count(); + double factor = 0d; + double fullLoadHours = 0d; + + for (PowerGeneratingTechnology technology : scheme.getPowerGeneratingTechnologiesEligible()) { + + double expectedTechnologyCapacity = reps.powerPlantRepository + .calculateCapacityOfOperationalPowerPlantsByTechnology(technology, + scheme.getFutureTenderOperationStartTime()); + + for (PowerPlant plant : reps.powerPlantRepository.findOperationalPowerPlantsByTechnology(technology, + scheme.getFutureTenderOperationStartTime())) { + for (Segment segment : reps.segmentRepository.findAll()) { + + if (technology.isIntermittent()) { + factor = plant.getIntermittentTechnologyNodeLoadFactor().getLoadFactorForSegment(segment); + } else { + double segmentID = segment.getSegmentID(); + double min = technology.getPeakSegmentDependentAvailability(); + double max = technology.getBaseSegmentDependentAvailability(); + double segmentPortion = (numberOfSegments - segmentID) / (numberOfSegments - 1); // start + // counting + // at + // 1. + + double range = max - min; + factor = max - segmentPortion * range; + + } + + fullLoadHours += factor * segment.getLengthInHours(); + } + } + expectedGenerationPerTechnology = fullLoadHours * expectedTechnologyCapacity; + totalExpectedGeneration += expectedGenerationPerTechnology; + } + + renewableTargetInMwh = renewableTargetInMwh - totalExpectedGeneration; + + if (renewableTargetInMwh < 0) { + renewableTargetInMwh = 0; + } + scheme.getRegulator().setAnnualRenewableTargetInMwh(renewableTargetInMwh); + + logger.warn("actual renewableTargetInMwh for this tick: " + renewableTargetInMwh); + + } + + public double predictDemandForElectricitySpotMarket(ElectricitySpotMarket market, + long numberOfYearsBacklookingForForecasting, long futureTimePoint) { + GeometricTrendRegression gtr = new GeometricTrendRegression(); + for (long time = getCurrentTick(); time > getCurrentTick() - numberOfYearsBacklookingForForecasting + && time >= 0; time = time - 1) { + gtr.addData(time, market.getDemandGrowthTrend().getValue(time)); + } + double forecast = gtr.predict(futureTimePoint); + if (Double.isNaN(forecast)) + forecast = market.getDemandGrowthTrend().getValue(getCurrentTick()); + return forecast; + } +} diff --git a/emlab-generation/src/main/java/emlab/gen/role/tender/ClearRenewableTenderRole.java b/emlab-generation/src/main/java/emlab/gen/role/tender/ClearRenewableTenderRole.java new file mode 100644 index 00000000..588fc1c8 --- /dev/null +++ b/emlab-generation/src/main/java/emlab/gen/role/tender/ClearRenewableTenderRole.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * 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.tender; + +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.BigBank; +import emlab.gen.domain.agent.EnergyProducer; +import emlab.gen.domain.agent.PowerPlantManufacturer; +import emlab.gen.domain.agent.Regulator; +import emlab.gen.domain.contract.CashFlow; +import emlab.gen.domain.contract.Loan; +import emlab.gen.domain.market.Bid; +import emlab.gen.domain.market.ClearingPoint; +import emlab.gen.domain.policy.renewablesupport.TenderBid; +import emlab.gen.domain.technology.PowerPlant; +import emlab.gen.repository.Reps; + +/** + * @author rjjdejeu + */ +@RoleComponent +public class ClearRenewableTenderRole extends AbstractRole implements Role { + + @Autowired + Reps reps; + + @Autowired + Neo4jTemplate template; + + @Override + @Transactional + public void act(Regulator regulator) { + + // Initialize a sorted list for tender bids + Iterable sortedTenderBidsbyPrice = null; + sortedTenderBidsbyPrice = reps.tenderBidRepository.findAllSortedTenderBidsbyTime(getCurrentTick()); + + // for a certain year? + double tenderQuota = regulator.getAnnualRenewableTargetInMwh(); + double sumOfTenderBidQuantityAccepted = 0d; + double acceptedSubsidyPrice = 0d; + boolean isTheTenderCleared = false; + + if (tenderQuota == 0) { + isTheTenderCleared = true; + acceptedSubsidyPrice = 0; + } + + // This epsilon is to account for rounding errors for java (only + // relevant for exact clearing) + double clearingEpsilon = 0.0001d; + + // Goes through the list of the bids that are sorted on ascending order + // by price + for (TenderBid currentTenderBid : sortedTenderBidsbyPrice) { + + // if the tender is not cleared yet, it collects complete bids + if (isTheTenderCleared == false) { + if (tenderQuota - (sumOfTenderBidQuantityAccepted + currentTenderBid.getAmount()) >= -clearingEpsilon) { + acceptedSubsidyPrice = currentTenderBid.getPrice(); + currentTenderBid.setStatus(Bid.ACCEPTED); + currentTenderBid.setAcceptedAmount(currentTenderBid.getAmount()); + sumOfTenderBidQuantityAccepted = sumOfTenderBidQuantityAccepted + currentTenderBid.getAmount(); + } + + // it collects a bid partially if that bid fulfills the quota + // partially + else if (tenderQuota - (sumOfTenderBidQuantityAccepted + currentTenderBid.getAmount()) < clearingEpsilon) { + acceptedSubsidyPrice = currentTenderBid.getPrice(); + currentTenderBid.setStatus(Bid.PARTLY_ACCEPTED); + + // When I adapted this from ClearCapacityMarket, this line + // was + // reversed: sumOfTenderBidQuantityAccepted - tenderQuota + currentTenderBid.setAcceptedAmount((tenderQuota - sumOfTenderBidQuantityAccepted)); + sumOfTenderBidQuantityAccepted = sumOfTenderBidQuantityAccepted + + currentTenderBid.getAcceptedAmount(); + isTheTenderCleared = true; + } + // the tenderQuota is reached and the bids after that are not + // accepted + } else { + currentTenderBid.setStatus(Bid.FAILED); + currentTenderBid.setAcceptedAmount(0); + } + + currentTenderBid.persist(); + + // A power plant can be created if the bid is (partly) accepted + + // there is a mistake in EnergyProdcer and DecarbonizationAgent..... + if (currentTenderBid.getStatus() == Bid.ACCEPTED || currentTenderBid.getStatus() == Bid.PARTLY_ACCEPTED) { + + PowerPlant plant = new PowerPlant(); + EnergyProducer bidder = (EnergyProducer) currentTenderBid.getBidder(); + + plant.specifyAndPersist(currentTenderBid.getStart(), bidder, currentTenderBid.getPowerGridNode(), + currentTenderBid.getTechnology()); + PowerPlantManufacturer manufacturer = reps.genericRepository.findFirst(PowerPlantManufacturer.class); + BigBank bigbank = reps.genericRepository.findFirst(BigBank.class); + + double investmentCostPayedByEquity = plant.getActualInvestedCapital() + * (1 - bidder.getDebtRatioOfInvestments()); + double investmentCostPayedByDebt = plant.getActualInvestedCapital() + * bidder.getDebtRatioOfInvestments(); + double downPayment = investmentCostPayedByEquity; + createSpreadOutDownPayments(bidder, manufacturer, downPayment, plant); + + double amount = determineLoanAnnuities(investmentCostPayedByDebt, plant.getTechnology() + .getDepreciationTime(), bidder.getLoanInterestRate()); + // logger.warn("Loan amount is: " + amount); + Loan loan = reps.loanRepository.createLoan(currentTenderBid.getBidder(), bigbank, amount, plant + .getTechnology().getDepreciationTime(), getCurrentTick(), plant); + // Create the loan + plant.createOrUpdateLoan(loan); + + } + } // FOR Loop ends here + + // This creates a clearing point that contains general information about + // the cleared tender + // volume, subsidy price, current tick, and stores it in the graph + // database + + if (isTheTenderCleared == true) { + ClearingPoint tenderClearingPoint = new ClearingPoint(); + tenderClearingPoint.setPrice(acceptedSubsidyPrice); + tenderClearingPoint.setVolume(sumOfTenderBidQuantityAccepted); + tenderClearingPoint.setTime(getCurrentTick()); + tenderClearingPoint.persist(); + + } else { + ClearingPoint tenderClearingPoint = new ClearingPoint(); + tenderClearingPoint.setPrice(acceptedSubsidyPrice); + tenderClearingPoint.setVolume(sumOfTenderBidQuantityAccepted); + tenderClearingPoint.setTime(getCurrentTick()); + tenderClearingPoint.persist(); + + } + + } + + 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, + buildingTime - 1, getCurrentTick(), plant); + plant.createOrUpdateDownPayment(downpayment); + } + + public double determineLoanAnnuities(double totalLoan, double payBackTime, double interestRate) { + + double q = 1 + interestRate; + double annuity = totalLoan * (Math.pow(q, payBackTime) * (q - 1)) / (Math.pow(q, payBackTime) - 1); + + return annuity; + } + +} diff --git a/emlab-generation/src/main/java/emlab/gen/role/tender/OrganizeRenewableTenderPaymentsRole.java b/emlab-generation/src/main/java/emlab/gen/role/tender/OrganizeRenewableTenderPaymentsRole.java new file mode 100644 index 00000000..463cf79c --- /dev/null +++ b/emlab-generation/src/main/java/emlab/gen/role/tender/OrganizeRenewableTenderPaymentsRole.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * 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.tender; + +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.contract.CashFlow; +import emlab.gen.domain.market.ClearingPoint; +import emlab.gen.domain.policy.renewablesupport.RenewableSupportSchemeTender; +import emlab.gen.domain.policy.renewablesupport.TenderBid; +import emlab.gen.repository.Reps; + +/** + * @author rjjdejeu + * + */ + +@RoleComponent +public class OrganizeRenewableTenderPaymentsRole extends AbstractRole implements + Role { + + @Autowired + Reps reps; + + @Override + @Transactional + public void act(RenewableSupportSchemeTender scheme) { + + // what about the other (earlier or later) bids that need to be paid + // out? - i have included them as well with my if statement. - and I put + // that later in the query + + // the following query should return only all accepted or partially + // accepted bids - write a query that only returns accepted bids. Look + // up powerPlantDispatchPlanRepository for examples - there are two. + for (TenderBid currentTenderBid : reps.tenderBidRepository.findAllTenderBidsThatShouldBePaidInTimeStep(scheme, + getCurrentTick())) { + + ClearingPoint tenderClearingPoint = reps.tenderClearingPointRepository + .findOneClearingPointForTimeAndRenewableSupportSchemeTender(getCurrentTick(), scheme); + + reps.nonTransactionalCreateRepository.createCashFlow(scheme, currentTenderBid.getBidder(), + currentTenderBid.getAcceptedAmount() * tenderClearingPoint.getPrice(), CashFlow.TENDER_SUBSIDY, + getCurrentTick(), currentTenderBid.getPowerPlant()); + + } + + } + +} \ No newline at end of file diff --git a/emlab-generation/src/main/java/emlab/gen/role/tender/SubmitTenderBidRole.java b/emlab-generation/src/main/java/emlab/gen/role/tender/SubmitTenderBidRole.java new file mode 100644 index 00000000..397f289a --- /dev/null +++ b/emlab-generation/src/main/java/emlab/gen/role/tender/SubmitTenderBidRole.java @@ -0,0 +1,645 @@ +/******************************************************************************* + * 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.tender; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; + +import org.apache.commons.math.stat.regression.SimpleRegression; +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.Role; +import agentspring.role.RoleComponent; +import emlab.gen.domain.agent.DecarbonizationModel; +import emlab.gen.domain.agent.EnergyProducer; +import emlab.gen.domain.agent.Government; +import emlab.gen.domain.agent.PowerPlantManufacturer; +import emlab.gen.domain.agent.StochasticTargetInvestor; +import emlab.gen.domain.agent.StrategicReserveOperator; +import emlab.gen.domain.agent.TargetInvestor; +import emlab.gen.domain.contract.CashFlow; +import emlab.gen.domain.contract.Loan; +import emlab.gen.domain.gis.Zone; +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.market.electricity.SegmentLoad; +import emlab.gen.domain.policy.PowerGeneratingTechnologyTarget; +import emlab.gen.domain.policy.renewablesupport.TenderBid; +import emlab.gen.domain.technology.PowerGeneratingTechnology; +import emlab.gen.domain.technology.PowerGeneratingTechnologyNodeLimit; +import emlab.gen.domain.technology.PowerGridNode; +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.repository.StrategicReserveOperatorRepository; +import emlab.gen.role.AbstractEnergyProducerRole; +import emlab.gen.util.GeometricTrendRegression; +import emlab.gen.util.MapValueComparator; + +/** + * @author kaveri + * + */ + +@RoleComponent +public class SubmitTenderBidRole extends AbstractEnergyProducerRole implements Role { + + @Transient + @Autowired + Reps reps; + + @Transient + @Autowired + Neo4jTemplate template; + + @Transient + @Autowired + StrategicReserveOperatorRepository strategicReserveOperatorRepository; + + // market expectations + @Transient + Map marketInfoMap = new HashMap(); + + @Override + public void act(EnergyProducer agent) { + + long futureTimePoint = getCurrentTick() + agent.getInvestmentFutureTimeHorizon(); + logger.warn(agent + " looking at timepoint " + futureTimePoint); + + // ==== Expectations === + + Map expectedFuelPrices = predictFuelPrices(agent, futureTimePoint); + + // CO2 + Map expectedCO2Price = determineExpectedCO2PriceInclTaxAndFundamentalForecast( + 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(expectedCO2Price.toString()); + + // Demand + Map expectedDemand = new HashMap(); + 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) { + gtr.addData(time, elm.getDemandGrowthTrend().getValue(time)); + } + expectedDemand.put(elm, gtr.predict(futureTimePoint)); + } + + ElectricitySpotMarket market = agent.getInvestorMarket(); + MarketInformation marketInformation = new MarketInformation(market, expectedDemand, expectedFuelPrices, + expectedCO2Price.get(market).doubleValue(), futureTimePoint); + + for (PowerGeneratingTechnology technology : reps.genericRepository.findAll(PowerGeneratingTechnology.class)) { + + DecarbonizationModel model = reps.genericRepository.findAll(DecarbonizationModel.class).iterator().next(); + + if (technology.isIntermittent() && model.isNoPrivateIntermittentRESInvestment()) + continue; + + Iterable possibleInstallationNodes; + + /* + * For dispatchable technologies just choose a random node. For + * intermittent evaluate all possibilities. + */ + if (technology.isIntermittent()) + possibleInstallationNodes = reps.powerGridNodeRepository.findAllPowerGridNodesByZone(market.getZone()); + else { + possibleInstallationNodes = new LinkedList(); + ((LinkedList) possibleInstallationNodes).add(reps.powerGridNodeRepository + .findAllPowerGridNodesByZone(market.getZone()).iterator().next()); + } + + logger.warn("Calculating for " + technology.getName() + ", for Nodes: " + + possibleInstallationNodes.toString()); + + for (PowerGridNode node : possibleInstallationNodes) { + + PowerPlant plant = new PowerPlant(); + plant.specifyNotPersist(getCurrentTick(), agent, node, technology); + // 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) { + double technologyTargetCapacity = technologyTarget.getTrend().getValue(futureTimePoint); + expectedInstalledCapacityOfTechnology = (technologyTargetCapacity > expectedInstalledCapacityOfTechnology) ? technologyTargetCapacity + : expectedInstalledCapacityOfTechnology; + } + double pgtNodeLimit = Double.MAX_VALUE; + PowerGeneratingTechnologyNodeLimit pgtLimit = reps.powerGeneratingTechnologyNodeLimitRepository + .findOneByTechnologyAndNode(technology, plant.getLocation()); + if (pgtLimit != null) { + pgtNodeLimit = pgtLimit.getUpperCapacityLimit(futureTimePoint); + } + + // Calculate bid quantity. No of plants to be bid - as many as + // the node permits + double ratioNodeCapacity = pgtNodeLimit / plant.getActualNominalCapacity(); + long numberOfPlants = (long) ratioNodeCapacity; // truncates + // towards lower + // integer + + double bidQuantityPerPlant = plant.getActualNominalCapacity(); + + // if cash strapped, bid quantity according to fraction of cash + // available. + + if (numberOfPlants * plant.getActualInvestedCapital() * (1 - agent.getDebtRatioOfInvestments()) > agent + .getDownpaymentFractionOfCash() * agent.getCash()) { + + double cashAvailableFraction = (agent.getDownpaymentFractionOfCash() * agent.getCash()) + / (numberOfPlants * plant.getActualInvestedCapital() * (1 - agent + .getDebtRatioOfInvestments())); + + numberOfPlants = Math.round(cashAvailableFraction) * numberOfPlants; + + } + + // computing tender bid price + + double bidPricePerMWh = 0d; + + Map myFuelPrices = new HashMap(); + for (Substance fuel : technology.getFuels()) { + myFuelPrices.put(fuel, expectedFuelPrices.get(fuel)); + } + + Set fuelMix = calculateFuelMix(plant, myFuelPrices, + expectedCO2Price.get(market)); + plant.setFuelMix(fuelMix); + + double expectedMarginalCost = determineExpectedMarginalCost(plant, expectedFuelPrices, + expectedCO2Price.get(market)); + double runningHours = 0d; + double expectedGrossProfit = 0d; + + long numberOfSegments = reps.segmentRepository.count(); + double totalAnnualExpectedGenerationOfPlant = 0d; + + long tenderSchemeDuration = reps.renewableSupportSchemeTenderRepository.findOne(null) + .getSupportSchemeDuration(); // should be + // modified when + // location + // specific + + for (SegmentLoad segmentLoad : market.getLoadDurationCurve()) { + double expectedElectricityPrice = marketInformation.expectedElectricityPricesPerSegment + .get(segmentLoad.getSegment()); + double hours = segmentLoad.getSegment().getLengthInHours(); + if (expectedMarginalCost <= expectedElectricityPrice) { + runningHours += hours; + if (technology.isIntermittent()) { + expectedGrossProfit += (expectedElectricityPrice - expectedMarginalCost) + * hours + * plant.getActualNominalCapacity() + * reps.intermittentTechnologyNodeLoadFactorRepository + .findIntermittentTechnologyNodeLoadFactorForNodeAndTechnology(node, + technology).getLoadFactorForSegment(segmentLoad.getSegment()); + + totalAnnualExpectedGenerationOfPlant += hours + * plant.getActualNominalCapacity() + * reps.intermittentTechnologyNodeLoadFactorRepository + .findIntermittentTechnologyNodeLoadFactorForNodeAndTechnology(node, + technology).getLoadFactorForSegment(segmentLoad.getSegment()); + + } else { + expectedGrossProfit += (expectedElectricityPrice - expectedMarginalCost) + * hours + * plant.getAvailableCapacity(futureTimePoint, segmentLoad.getSegment(), + numberOfSegments); + + totalAnnualExpectedGenerationOfPlant += hours + * plant.getAvailableCapacity(futureTimePoint, segmentLoad.getSegment(), + numberOfSegments); + } + } + } + + // logger.warn(agent + + // "expects technology {} to have {} running", technology, + // runningHours); + // expect to meet minimum running hours? + if (runningHours < plant.getTechnology().getMinimumRunningHours()) { + // logger.warn(agent+ + // " will not bid in {} technology as he expect to + // have {} running, which is lower then required", + // technology, runningHours); + } else { + + double fixedOMCost = calculateFixedOperatingCost(plant, getCurrentTick());// / + double operatingProfit = expectedGrossProfit - fixedOMCost; + double wacc = (1 - agent.getDebtRatioOfInvestments()) * agent.getEquityInterestRate() + + agent.getDebtRatioOfInvestments() * agent.getLoanInterestRate(); + + // Creation of out cash-flow during power plant building + // phase (note that the cash-flow is negative!) + TreeMap discountedProjectCapitalOutflow = calculateSimplePowerPlantInvestmentCashFlow( + technology.getDepreciationTime(), (int) plant.getFinishedConstruction(), + plant.getActualInvestedCapital(), 0); + // Creation of in cashflow during operation + TreeMap discountedProjectCashInflow = calculateSimplePowerPlantInvestmentCashFlow( + technology.getDepreciationTime(), (int) plant.getFinishedConstruction(), 0, operatingProfit); + + double discountedCapitalCosts = npv(discountedProjectCapitalOutflow, wacc); + double discountedOpProfit = npv(discountedProjectCashInflow, wacc); + double projectValue = discountedOpProfit + discountedCapitalCosts; + + if (projectValue >= 0) { + bidPricePerMWh = 0d; + } else { + // calculate discounted tender return factor term + + TreeMap discountedTenderReturnFactorSummingTerm = calculateSimplePowerPlantInvestmentCashFlow( + (int) tenderSchemeDuration, (int) plant.getFinishedConstruction(), 0, 1); + double discountedTenderReturnFactor = npv(discountedTenderReturnFactorSummingTerm, wacc); + // calculate generation in MWh per year + bidPricePerMWh = -projectValue + / (discountedTenderReturnFactor * totalAnnualExpectedGenerationOfPlant); + + } + + // create and persist tender bids for number of power plants + // as found earlier. + for (int i = 1; i <= (int) numberOfPlants; i++) { + + TenderBid bid = new TenderBid().persist(); + bid.setAmount(totalAnnualExpectedGenerationOfPlant); + bid.setBidder(agent); + bid.setPrice(bidPricePerMWh); + bid.setPowerGridNode(node); + bid.setTechnology(technology); + bid.setStart(getCurrentTick() + plant.getFinishedConstruction()); + bid.setFinish(getCurrentTick() + plant.getFinishedConstruction() + tenderSchemeDuration); + bid.setTime(getCurrentTick()); + bid.persist(); + + logger.warn(" bid amount of " + agent + " is " + totalAnnualExpectedGenerationOfPlant); + logger.warn(" bid price of " + agent + " is " + bidPricePerMWh); + logger.warn(" bid node of " + agent + " is " + node); + logger.warn(" bid technology of " + agent + " is " + technology); + logger.warn(" bid start time tender support of " + agent + " is " + getCurrentTick() + + plant.getFinishedConstruction()); + logger.warn(" bid end time tender support of " + agent + " is " + getCurrentTick() + + plant.getFinishedConstruction() + tenderSchemeDuration); + + } + + } + + } + } + } + + // } + + // 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.getFinishedConstruction(); + reps.nonTransactionalCreateRepository.createCashFlow(agent, manufacturer, totalDownPayment / buildingTime, + CashFlow.DOWNPAYMENT, getCurrentTick(), plant); + Loan downpayment = reps.loanRepository.createLoan(agent, manufacturer, totalDownPayment / buildingTime, + buildingTime - 1, getCurrentTick(), plant); + plant.createOrUpdateDownPayment(downpayment); + } + + /** + * 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) { + // 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). + Iterable cps = reps.clearingPointRepository + .findAllClearingPointsForSubstanceTradedOnCommodityMarkesAndTimeRange(substance, getCurrentTick() + - (agent.getNumberOfYearsBacklookingForForecasting() - 1), getCurrentTick(), false); + // logger.warn("{}, {}", + // getCurrentTick()-(agent.getNumberOfYearsBacklookingForForecasting()-1), + // getCurrentTick()); + // Create regression object + SimpleRegression gtr = new SimpleRegression(); + for (ClearingPoint clearingPoint : cps) { + // logger.warn("CP {}: {} , in" + clearingPoint.getTime(), + // substance.getName(), clearingPoint.getPrice()); + gtr.addData(clearingPoint.getTime(), clearingPoint.getPrice()); + } + gtr.addData(getCurrentTick(), findLastKnownPriceForSubstance(substance, getCurrentTick())); + expectedFuelPrices.put(substance, gtr.predict(futureTimePoint)); + // logger.warn("Forecast {}: {}, in Step " + futureTimePoint, + // substance, expectedFuelPrices.get(substance)); + } + return expectedFuelPrices; + } + + // Create a powerplant investment and operation cash-flow in the form of a + // map. If only investment, or operation costs should be considered set + // totalInvestment or operatingProfit to 0 + private TreeMap calculateSimplePowerPlantInvestmentCashFlow(int depriacationTime, + int buildingTime, double totalInvestment, double operatingProfit) { + TreeMap investmentCashFlow = new TreeMap(); + double equalTotalDownPaymentInstallement = totalInvestment / buildingTime; + for (int i = 0; i < buildingTime; i++) { + investmentCashFlow.put(new Integer(i), -equalTotalDownPaymentInstallement); + } + for (int i = buildingTime; i < depriacationTime + buildingTime; i++) { + investmentCashFlow.put(new Integer(i), operatingProfit); + } + + return investmentCashFlow; + } + + private double npv(TreeMap netCashFlow, double wacc) { + double npv = 0; + for (Integer iterator : netCashFlow.keySet()) { + npv += netCashFlow.get(iterator).doubleValue() / Math.pow(1 + wacc, iterator.intValue()); + } + return npv; + } + + public double determineExpectedMarginalCost(PowerPlant plant, Map expectedFuelPrices, + double expectedCO2Price) { + double mc = determineExpectedMarginalFuelCost(plant, expectedFuelPrices); + double co2Intensity = plant.calculateEmissionIntensity(); + mc += co2Intensity * expectedCO2Price; + return mc; + } + + public double determineExpectedMarginalFuelCost(PowerPlant powerPlant, Map expectedFuelPrices) { + double fc = 0d; + for (SubstanceShareInFuelMix mix : powerPlant.getFuelMix()) { + double amount = mix.getShare(); + double fuelPrice = expectedFuelPrices.get(mix.getSubstance()); + fc += amount * fuelPrice; + } + return fc; + } + + private PowerGridNode getNodeForZone(Zone zone) { + for (PowerGridNode node : reps.genericRepository.findAll(PowerGridNode.class)) { + if (node.getZone().equals(zone)) { + return node; + } + } + return null; + } + + private class MarketInformation { + + Map expectedElectricityPricesPerSegment; + double maxExpectedLoad = 0d; + Map meritOrder; + double capacitySum; + + 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)) { + + double plantMarginalCost = determineExpectedMarginalCost(plant, fuelPrices, co2price); + marginalCostMap.put(plant, plantMarginalCost); + capacitySum += plant.getActualNominalCapacity(); + } + + // get difference between technology target and expected operational + // capacity + for (TargetInvestor targetInvestor : reps.targetInvestorRepository.findAllByMarket(market)) { + if (!(targetInvestor instanceof StochasticTargetInvestor)) { + for (PowerGeneratingTechnologyTarget pggt : targetInvestor.getPowerGenerationTechnologyTargets()) { + double expectedTechnologyCapacity = reps.powerPlantRepository + .calculateCapacityOfExpectedOperationalPowerPlantsInMarketAndTechnology(market, + pggt.getPowerGeneratingTechnology(), time); + double targetDifference = pggt.getTrend().getValue(time) - expectedTechnologyCapacity; + if (targetDifference > 0) { + PowerPlant plant = new PowerPlant(); + plant.specifyNotPersist(getCurrentTick(), new EnergyProducer(), + reps.powerGridNodeRepository.findFirstPowerGridNodeByElectricitySpotMarket(market), + pggt.getPowerGeneratingTechnology()); + plant.setActualNominalCapacity(targetDifference); + double plantMarginalCost = determineExpectedMarginalCost(plant, fuelPrices, co2price); + marginalCostMap.put(plant, plantMarginalCost); + capacitySum += targetDifference; + } + } + + } else { + for (PowerGeneratingTechnologyTarget pggt : targetInvestor.getPowerGenerationTechnologyTargets()) { + double expectedTechnologyCapacity = reps.powerPlantRepository + .calculateCapacityOfExpectedOperationalPowerPlantsInMarketAndTechnology(market, + pggt.getPowerGeneratingTechnology(), time); + double expectedTechnologyAddition = 0; + long contructionTime = getCurrentTick() + + pggt.getPowerGeneratingTechnology().getExpectedLeadtime() + + pggt.getPowerGeneratingTechnology().getExpectedPermittime(); + for (long investmentTimeStep = contructionTime + 1; investmentTimeStep <= time; investmentTimeStep = investmentTimeStep + 1) { + expectedTechnologyAddition += (pggt.getTrend().getValue(investmentTimeStep) - pggt + .getTrend().getValue(investmentTimeStep - 1)); + } + if (expectedTechnologyAddition > 0) { + PowerPlant plant = new PowerPlant(); + plant.specifyNotPersist(getCurrentTick(), new EnergyProducer(), + reps.powerGridNodeRepository.findFirstPowerGridNodeByElectricitySpotMarket(market), + pggt.getPowerGeneratingTechnology()); + plant.setActualNominalCapacity(expectedTechnologyAddition); + double plantMarginalCost = determineExpectedMarginalCost(plant, fuelPrices, co2price); + marginalCostMap.put(plant, plantMarginalCost); + capacitySum += expectedTechnologyAddition; + } + } + } + + } + + MapValueComparator comp = new MapValueComparator(marginalCostMap); + meritOrder = new TreeMap(comp); + meritOrder.putAll(marginalCostMap); + + long numberOfSegments = reps.segmentRepository.count(); + + double demandFactor = expectedDemand.get(market).doubleValue(); + + // find expected prices per segment given merit order + for (SegmentLoad segmentLoad : market.getLoadDurationCurve()) { + + double expectedSegmentLoad = segmentLoad.getBaseLoad() * demandFactor; + + if (expectedSegmentLoad > maxExpectedLoad) { + maxExpectedLoad = expectedSegmentLoad; + } + + double segmentSupply = 0d; + double segmentPrice = 0d; + double totalCapacityAvailable = 0d; + + for (Entry plantCost : meritOrder.entrySet()) { + PowerPlant plant = plantCost.getKey(); + double plantCapacity = 0d; + // Determine available capacity in the future in this + // segment + plantCapacity = plant + .getExpectedAvailableCapacity(time, segmentLoad.getSegment(), numberOfSegments); + totalCapacityAvailable += plantCapacity; + // logger.warn("Capacity of plant " + plant.toString() + + // " is " + + // plantCapacity/plant.getActualNominalCapacity()); + if (segmentSupply < expectedSegmentLoad) { + segmentSupply += plantCapacity; + segmentPrice = plantCost.getValue(); + } + + } + + // logger.warn("Segment " + + // segmentLoad.getSegment().getSegmentID() + " supply equals " + + // segmentSupply + " and segment demand equals " + + // expectedSegmentLoad); + + // Find strategic reserve operator for the market. + double reservePrice = 0; + double reserveVolume = 0; + for (StrategicReserveOperator operator : strategicReserveOperatorRepository.findAll()) { + ElectricitySpotMarket market1 = reps.marketRepository.findElectricitySpotMarketForZone(operator + .getZone()); + if (market.getNodeId().intValue() == market1.getNodeId().intValue()) { + reservePrice = operator.getReservePriceSR(); + reserveVolume = operator.getReserveVolume(); + } + } + + if (segmentSupply >= expectedSegmentLoad + && ((totalCapacityAvailable - expectedSegmentLoad) <= (reserveVolume))) { + expectedElectricityPricesPerSegment.put(segmentLoad.getSegment(), reservePrice); + // logger.warn("Price: "+ + // expectedElectricityPricesPerSegment); + } else if (segmentSupply >= expectedSegmentLoad + && ((totalCapacityAvailable - expectedSegmentLoad) > (reserveVolume))) { + expectedElectricityPricesPerSegment.put(segmentLoad.getSegment(), segmentPrice); + // logger.warn("Price: "+ + // expectedElectricityPricesPerSegment); + } else { + expectedElectricityPricesPerSegment.put(segmentLoad.getSegment(), market.getValueOfLostLoad()); + } + + } + } + } + + /** + * 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. + * @return + */ + protected HashMap determineExpectedCO2PriceInclTaxAndFundamentalForecast( + long futureTimePoint, long yearsLookingBackForRegression, int adjustmentForDetermineFuelMix, + long clearingTick) { + HashMap co2Prices = new HashMap(); + CO2Auction co2Auction = reps.genericRepository.findFirst(CO2Auction.class); + Iterable cps = reps.clearingPointRepository.findAllClearingPointsForMarketAndTimeRange( + co2Auction, clearingTick - yearsLookingBackForRegression + 1 - adjustmentForDetermineFuelMix, + clearingTick - adjustmentForDetermineFuelMix, false); + // Create regression object and calculate average + SimpleRegression sr = new SimpleRegression(); + Government government = reps.template.findAll(Government.class).iterator().next(); + double lastPrice = 0; + double averagePrice = 0; + int i = 0; + for (ClearingPoint clearingPoint : cps) { + sr.addData(clearingPoint.getTime(), clearingPoint.getPrice()); + lastPrice = clearingPoint.getPrice(); + averagePrice += lastPrice; + i++; + } + averagePrice = averagePrice / i; + double expectedCO2Price; + double expectedRegressionCO2Price; + if (i > 1) { + expectedRegressionCO2Price = sr.predict(futureTimePoint); + expectedRegressionCO2Price = Math.max(0, expectedRegressionCO2Price); + expectedRegressionCO2Price = Math + .min(expectedRegressionCO2Price, government.getCo2Penalty(futureTimePoint)); + } else { + expectedRegressionCO2Price = lastPrice; + } + ClearingPoint expectedCO2ClearingPoint = reps.clearingPointRepository.findClearingPointForMarketAndTime( + co2Auction, getCurrentTick() + + reps.genericRepository.findFirst(DecarbonizationModel.class).getCentralForecastingYear(), + true); + expectedCO2Price = (expectedCO2ClearingPoint == null) ? 0 : expectedCO2ClearingPoint.getPrice(); + expectedCO2Price = (expectedCO2Price + expectedRegressionCO2Price) / 2; + for (ElectricitySpotMarket esm : reps.marketRepository.findAllElectricitySpotMarkets()) { + double nationalCo2MinPriceinFutureTick = reps.nationalGovernmentRepository + .findNationalGovernmentByElectricitySpotMarket(esm).getMinNationalCo2PriceTrend() + .getValue(futureTimePoint); + double co2PriceInCountry = 0d; + if (expectedCO2Price > nationalCo2MinPriceinFutureTick) { + co2PriceInCountry = expectedCO2Price; + } else { + co2PriceInCountry = nationalCo2MinPriceinFutureTick; + } + co2PriceInCountry += reps.genericRepository.findFirst(Government.class).getCO2Tax(futureTimePoint); + co2Prices.put(esm, Double.valueOf(co2PriceInCountry)); + } + return co2Prices; + } + +} diff --git a/emlab-generation/src/main/java/emlab/gen/role/tender/TenderMainRole.java b/emlab-generation/src/main/java/emlab/gen/role/tender/TenderMainRole.java new file mode 100644 index 00000000..034750b9 --- /dev/null +++ b/emlab-generation/src/main/java/emlab/gen/role/tender/TenderMainRole.java @@ -0,0 +1,74 @@ +/******************************************************************************* + * 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.tender; + +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.policy.renewablesupport.RenewableSupportSchemeTender; +import emlab.gen.repository.Reps; + +/** + * @author Kaveri3012 + * + */ +@RoleComponent +public class TenderMainRole extends AbstractRole implements + Role { + + /* + * (non-Javadoc) + * + * @see agentspring.role.Role#act(agentspring.agent.Agent) + */ + @Autowired + Reps reps; + + @Autowired + CalculateRenewableTargetForTenderRole calculateRenewableTargetForTenderRole; + + @Autowired + SubmitTenderBidRole submitTenderBidRole; + + @Autowired + ClearRenewableTenderRole clearRenewableTenderRole; + + @Autowired + OrganizeRenewableTenderPaymentsRole organizeRenewableTenderPaymentsRole; + + @Override + @Transactional + public void act(RenewableSupportSchemeTender scheme) { + + Regulator regulator = scheme.getRegulator(); + + calculateRenewableTargetForTenderRole.act(scheme); + + for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) { + submitTenderBidRole.act(producer); + } + + clearRenewableTenderRole.act(regulator); + + organizeRenewableTenderPaymentsRole.act(scheme); + } + +} diff --git a/emlab-generation/src/main/java/emlab/gen/role/tender/package-info.java b/emlab-generation/src/main/java/emlab/gen/role/tender/package-info.java new file mode 100644 index 00000000..c1f35cc4 --- /dev/null +++ b/emlab-generation/src/main/java/emlab/gen/role/tender/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 Kaveri3012 + * + */ +package emlab.gen.role.tender; \ No newline at end of file diff --git a/emlab-generation/src/main/java/emlab/gen/util/PredictionAnalysis.java b/emlab-generation/src/main/java/emlab/gen/util/PredictionAnalysis.java new file mode 100644 index 00000000..5329730b --- /dev/null +++ b/emlab-generation/src/main/java/emlab/gen/util/PredictionAnalysis.java @@ -0,0 +1,219 @@ +/******************************************************************************* + * 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.util; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +import org.apache.commons.math.stat.regression.SimpleRegression; + +/** + * @author manebel, jrichstein + * + */ +public class PredictionAnalysis { + + /** + * @param args + */ + public static void main(String[] args) { + // read in data + String inputFolder = "/home/jrichstein/emlab-generation/emlab-generation" + + "/src/main/resources/data/stochasticFuelPrices/"; + + String outputFile = "/home/jrichstein/Desktop/emlabGen/PredictionAnalyse/"; + // First year, where Prediction shall be calculated for + int startYear = 2022; + // Last year, where Prediction shall be calculated for + int endYear = 2050; + double[] confidenceLevels = { 0.95 }; + + // Create data for different confidence levels + for (int i = 0; i < confidenceLevels.length; i++) { + createData(startYear, endYear, confidenceLevels[i], outputFile, inputFolder); + } + } + + public static void createData(int startingYear, int endYear, double predictionInterval, String outputFile, + String inputFolder) { + BufferedReader br = null; + String line = ""; + String cvsSplitBy = ","; + String[] years = new String[200]; + String[] coalMedium = new String[200]; + String[] gasMedium = new String[200]; + StringBuffer bufCoal = new StringBuffer(); + StringBuffer bufGas = new StringBuffer(); + bufCoal.append("stochId,year,real,prediction-6-8,prediction-4-6,prediction-4-8,prediction-6-6,prediction-5-7\n"); + bufGas.append("stochId,year,real,prediction-6-8,prediction-4-6,prediction-4-8,prediction-6-6,prediction-5-7\n"); + + for (int j = 1; j <= 120; j++) { + String filename = "fuelPrices-" + j + ".csv"; + String fuelFile = inputFolder + filename; + try { + + br = new BufferedReader(new FileReader(fuelFile)); + int i = 0; + while ((line = br.readLine()) != null) { + if (i == 0) { + years = line.split(cvsSplitBy); + } + if (i == 1) { + coalMedium = line.split(cvsSplitBy); + } + if (i == 2) { + gasMedium = line.split(cvsSplitBy); + } + i++; + + } + + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + // FORECASTS FOR COAL PRICES + // according to different values for numberOfYearsBackLooking and + // futureTimePoint + double[][] coal1 = new double[endYear - startingYear + 1][3]; + coal1 = getData(6, 8, predictionInterval, coalMedium, years, startingYear, endYear); + double[][] coal2 = new double[endYear - startingYear + 1][3]; + coal2 = getData(4, 6, predictionInterval, coalMedium, years, startingYear, endYear); + double[][] coal3 = new double[endYear - startingYear + 1][3]; + coal3 = getData(4, 8, predictionInterval, coalMedium, years, startingYear, endYear); + double[][] coal4 = new double[endYear - startingYear + 1][3]; + coal4 = getData(6, 6, predictionInterval, coalMedium, years, startingYear, endYear); + double[][] coal5 = new double[endYear - startingYear + 1][3]; + coal5 = getData(5, 7, predictionInterval, coalMedium, years, startingYear, endYear); + // Calculating the average. There are 4 agents, that have + // numberOfYearsBackLooking: 6 and futureTimePoint: 8 + for (int i = 0; i < endYear - startingYear + 1; i++) { + bufCoal.append(j); + bufCoal.append(","); + bufCoal.append(coal1[i][0]); + bufCoal.append(","); + bufCoal.append(coal1[i][2]); + bufCoal.append(","); + bufCoal.append(coal1[i][1]); + bufCoal.append(","); + bufCoal.append(coal2[i][1]); + bufCoal.append(","); + bufCoal.append(coal3[i][1]); + bufCoal.append(","); + bufCoal.append(coal4[i][1]); + bufCoal.append(","); + bufCoal.append(coal5[i][1]); + bufCoal.append("\n"); + + } + + // FORECASTS FOR GAS PRICES + // according to different values for numberOfYearsBackLooking and + // futureTimePoint + double[][] gas1 = new double[endYear - startingYear + 1][3]; + gas1 = getData(6, 8, predictionInterval, gasMedium, years, startingYear, endYear); + double[][] gas2 = new double[endYear - startingYear + 1][3]; + gas2 = getData(4, 6, predictionInterval, gasMedium, years, startingYear, endYear); + double[][] gas3 = new double[endYear - startingYear + 1][3]; + gas3 = getData(4, 8, predictionInterval, gasMedium, years, startingYear, endYear); + double[][] gas4 = new double[endYear - startingYear + 1][3]; + gas4 = getData(6, 6, predictionInterval, gasMedium, years, startingYear, endYear); + double[][] gas5 = new double[endYear - startingYear + 1][3]; + gas5 = getData(5, 7, predictionInterval, gasMedium, years, startingYear, endYear); + // Calculating the average. There are 4 agents, that have + // numberOfYearsBackLooking: 6 and futureTimePoint: 8 + for (int i = 0; i < endYear - startingYear + 1; i++) { + bufGas.append(j); + bufGas.append(","); + bufGas.append(gas1[i][0]); + bufGas.append(","); + bufGas.append(gas1[i][2]); + bufGas.append(","); + bufGas.append(gas1[i][1]); + bufGas.append(","); + bufGas.append(gas2[i][1]); + bufGas.append(","); + bufGas.append(gas3[i][1]); + bufGas.append(","); + bufGas.append(gas4[i][1]); + bufGas.append(","); + bufGas.append(gas5[i][1]); + bufGas.append("\n"); + + } + } + + try { + FileWriter writer = new FileWriter(outputFile + "Coal" + "_" + predictionInterval + ".csv"); + writer.append(bufCoal); + writer.flush(); + writer.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + + try { + FileWriter writer = new FileWriter(outputFile + "Gas" + "_" + predictionInterval + ".csv"); + writer.append(bufGas); + writer.flush(); + writer.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static double[][] getData(int yearsBack, int yearsAhead, double alpha, String[] data, String[] years, + int startYear, int endYear) { + double[][] result = new double[endYear - startYear + 1][3]; + int currentYear = startYear - yearsAhead; + int i = 0; + while (currentYear + yearsAhead <= endYear) { + int startToCollect = Math.max(1, currentYear - 2011 - yearsBack); + SimpleRegression sr = new SimpleRegression(); + while (startToCollect <= currentYear - 2011) { + sr.addData(Integer.parseInt(years[startToCollect]), Double.parseDouble(data[startToCollect])); + startToCollect++; + } + + result[i][0] = Integer.parseInt(years[currentYear - 2011 + yearsAhead]); + result[i][1] = sr.predict(currentYear + yearsAhead); + // result[i][2] = Math.max(0, sr.getPredictionInterval(currentYear + + // yearsAhead, alpha)[0]); + // result[i][3] = sr.getPredictionInterval(currentYear + yearsAhead, + // alpha)[1]; + result[i][2] = Double.parseDouble(data[currentYear - 2011 + yearsAhead]); + + i++; + currentYear++; + } + return result; + } +} diff --git a/emlab-generation/src/main/resources/data/.~lock.learningCurves.csv# b/emlab-generation/src/main/resources/data/.~lock.learningCurves.csv# new file mode 100644 index 00000000..d4b58542 --- /dev/null +++ b/emlab-generation/src/main/resources/data/.~lock.learningCurves.csv# @@ -0,0 +1 @@ +,kaveri,kaveri-HP-Compaq-8100-Elite-SFF-PC,23.06.2015 12:53,file:///home/kaveri/.config/libreoffice/4; \ No newline at end of file diff --git a/emlab-generation/src/main/resources/data/.~lock.policyGoalNREAP_CF_CWE.csv# b/emlab-generation/src/main/resources/data/.~lock.policyGoalNREAP_CF_CWE.csv# new file mode 100644 index 00000000..3777cf46 --- /dev/null +++ b/emlab-generation/src/main/resources/data/.~lock.policyGoalNREAP_CF_CWE.csv# @@ -0,0 +1 @@ +,kaveri,kaveri-HP-Compaq-8100-Elite-SFF-PC,22.06.2015 17:52,file:///home/kaveri/.config/libreoffice/4; \ No newline at end of file diff --git a/emlab-generation/src/main/resources/data/policyGoalNREAP_NL_DE_2050.csv b/emlab-generation/src/main/resources/data/policyGoalNREAP_NL_DE_2050.csv new file mode 100644 index 00000000..73cc3005 --- /dev/null +++ b/emlab-generation/src/main/resources/data/policyGoalNREAP_NL_DE_2050.csv @@ -0,0 +1,4 @@ +realtime,2015,2016,2017,2018,2019,2020,2021,2022,2023,2024,2025,2026,2027,2028,2029,2030,2031,2032,2033,2034,2035,2036,2037,2038,2039,2040,2041,2042,2043,2044,2045,2046,2047,2048,2049,2050 +timestep,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35 +nl_target,0.1,0.13,0.19,0.25,0.31,0.37,0.38,0.39,0.4,0.41,0.42,0.425,0.43,0.435,0.44,0.45,0.46,0.47,0.48,0.49,0.5,0.51,0.52,0.53,0.54,0.55,0.56,0.57,0.58,0.59,0.6,0.61,0.62,0.63,0.64,0.65 +de_target,0.3,0.31,0.33,0.34,0.35,0.37,0.39,0.41,0.42,0.43,0.44,0.46,0.47,0.48,0.49,0.5,0.52,0.54,0.56,0.58,0.6,0.61,0.62,0.63,0.64,0.65,0.67,0.69,0.71,0.73,0.75,0.76,0.77,0.78,0.79,0.8 diff --git a/emlab-generation/src/main/resources/scenarios/BL.xml b/emlab-generation/src/main/resources/scenarios/BL.xml new file mode 100644 index 00000000..d658912b --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/BL.xml @@ -0,0 +1,1146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.422 + + + + + + 0.1371 + + + + + + 0.10514 + + + + + + 0.04846 + + + + + + 0.0731 + + + + + + 0.1551 + + + + + + 0.0591 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.422 + + + + + + 0.1271 + + + + + + 0.10514 + + + + + + 0.04846 + + + + + + 0.0731 + + + + + + 0.1551 + + + + + + 0.0591 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/CmTwoCountry-1.xml b/emlab-generation/src/main/resources/scenarios/CmTwoCountry-1.xml new file mode 100644 index 00000000..e5dcae3a --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/CmTwoCountry-1.xml @@ -0,0 +1,1263 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.422 + + + + + + 0.1371 + + + + + + 0.10514 + + + + + + 0.04846 + + + + + + 0.0731 + + + + + + 0.1551 + + + + + + 0.0591 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.422 + + + + + + 0.1271 + + + + + + 0.10514 + + + + + + 0.04846 + + + + + + 0.0731 + + + + + + 0.1551 + + + + + + 0.0591 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/CmTwoCountry-2.xml b/emlab-generation/src/main/resources/scenarios/CmTwoCountry-2.xml new file mode 100644 index 00000000..803b3436 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/CmTwoCountry-2.xml @@ -0,0 +1,1252 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.422 + + + + + + 0.1371 + + + + + + 0.10514 + + + + + + 0.04846 + + + + + + 0.0731 + + + + + + 0.1551 + + + + + + 0.0591 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.422 + + + + + + 0.1271 + + + + + + 0.10514 + + + + + + 0.04846 + + + + + + 0.0731 + + + + + + 0.1551 + + + + + + 0.0591 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/CmTwoCountry-3.xml b/emlab-generation/src/main/resources/scenarios/CmTwoCountry-3.xml new file mode 100644 index 00000000..6a4a6688 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/CmTwoCountry-3.xml @@ -0,0 +1,1253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.422 + + + + + + 0.1371 + + + + + + 0.10514 + + + + + + 0.04846 + + + + + + 0.0731 + + + + + + 0.1551 + + + + + + 0.0591 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.422 + + + + + + 0.1271 + + + + + + 0.10514 + + + + + + 0.04846 + + + + + + 0.0731 + + + + + + 0.1551 + + + + + + 0.0591 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/CmTwoCountryDE.properties b/emlab-generation/src/main/resources/scenarios/CmTwoCountryDE.properties new file mode 100644 index 00000000..79040ede --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/CmTwoCountryDE.properties @@ -0,0 +1,158 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +coalPriceStart=3.6917419368 +coalPriceMin=0.9707458246 +coalPriceTop=1.0107458246 +coalPriceMax=1.0507458246 + +gasPriceStart=7.5 +gasPriceMin=0.9446627902 +gasPriceTop=1.0146627902 +gasPriceMax=1.0846627902 + +biomassPriceStart=4.5 +biomassPriceMin=0.97 +biomassPriceTop=1.01 +biomassPriceMax=1.05 + +uraniumPriceStart=1.286 +uraniumPriceMin=1 +uraniumPriceMax=1.02 +uraniumPriceTop=1.01 + +#coalPriceStart=3.6917419368 +#coalPriceMin=1 +#coalPriceTop=1 +#coalPriceMax=1 + +#gasPriceStart=7.5 +#gasPriceMin=1 +#gasPriceTop=1 +#gasPriceMax=1 + +#biomassPriceStart=4.5 +#biomassPriceMin=1 +#biomassPriceTop=1 +#biomassPriceMax=1 + +#uraniumPriceStart=1.286 +#uraniumPriceMin=1 +#uraniumPriceMax=1 +#uraniumPriceTop=1 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +#co2CapStart=351.75e6 +co2CapStart=72e10 +co2CapIncrement=0 +#co2CapIncrement=0 +co2CapDuration=1 + +minCo2DEPriceStart=0 +minCo2DEPriceIncrement=0 +minCo2DEPriceDuration=1 + +minCo2NLPriceStart=0 +minCo2NLPriceIncrement=0 +minCo2NLPriceDuration=1 + +segment1nl=8160.778 +segment2nl=8390.36 +segment3nl=8961.656 +segment4nl=9448.219 +segment5nl=9828.25 +segment6nl=10333.58 +segment7nl=10887.66 +segment8nl=11438.97 +segment9nl=11957.73 +segment10nl=12498.55 +segment11nl=13155.53 +segment12nl=13819.34 +segment13nl=14395.3 +segment14nl=14826.11 +segment15nl=15221.23 +segment16nl=15797.4 +segment17nl=16622.16 +segment18nl=17535.46 +segment19nl=18179.78 +segment20nl=18390.00 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + + +demandGrowthDEStart=1 +demandGrowthDEMin=1 +demandGrowthDETop=1 +demandGrowthDEMax=1 + +demandGrowthNLStart=1 +demandGrowthNLMin=1 +demandGrowthNLTop=1 +demandGrowthNLMax=1 + +#demandGrowthDEStart=1 +#demandGrowthDEMin=0.99 +#demandGrowthDETop=1.02 +#demandGrowthDEMax=1.05 + +#demandGrowthNLStart=1 +#demandGrowthNLMin=0.99 +#demandGrowthNLTop=1.02 +#demandGrowthNLMax=1.05 + + +startCash=3e9 +priceMarkUp=1 + +co2TradingImplemented=false +simulationLength=50 + +interconnectorCapacity=5000 + +investmentFutureTimeHorizon=7 + +numberOfYearsBacklookingForForecasting=5 +simpleCapacityMarketEnabled=true + +capacityMarketPriceCap=58940 +reserveMargin=0.15 +reserveDemandLowerMargin=0.025 +reserveDemandUpperMargin=0.025 diff --git a/emlab-generation/src/main/resources/scenarios/CmTwoCountryNl.properties b/emlab-generation/src/main/resources/scenarios/CmTwoCountryNl.properties new file mode 100644 index 00000000..79040ede --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/CmTwoCountryNl.properties @@ -0,0 +1,158 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +coalPriceStart=3.6917419368 +coalPriceMin=0.9707458246 +coalPriceTop=1.0107458246 +coalPriceMax=1.0507458246 + +gasPriceStart=7.5 +gasPriceMin=0.9446627902 +gasPriceTop=1.0146627902 +gasPriceMax=1.0846627902 + +biomassPriceStart=4.5 +biomassPriceMin=0.97 +biomassPriceTop=1.01 +biomassPriceMax=1.05 + +uraniumPriceStart=1.286 +uraniumPriceMin=1 +uraniumPriceMax=1.02 +uraniumPriceTop=1.01 + +#coalPriceStart=3.6917419368 +#coalPriceMin=1 +#coalPriceTop=1 +#coalPriceMax=1 + +#gasPriceStart=7.5 +#gasPriceMin=1 +#gasPriceTop=1 +#gasPriceMax=1 + +#biomassPriceStart=4.5 +#biomassPriceMin=1 +#biomassPriceTop=1 +#biomassPriceMax=1 + +#uraniumPriceStart=1.286 +#uraniumPriceMin=1 +#uraniumPriceMax=1 +#uraniumPriceTop=1 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +#co2CapStart=351.75e6 +co2CapStart=72e10 +co2CapIncrement=0 +#co2CapIncrement=0 +co2CapDuration=1 + +minCo2DEPriceStart=0 +minCo2DEPriceIncrement=0 +minCo2DEPriceDuration=1 + +minCo2NLPriceStart=0 +minCo2NLPriceIncrement=0 +minCo2NLPriceDuration=1 + +segment1nl=8160.778 +segment2nl=8390.36 +segment3nl=8961.656 +segment4nl=9448.219 +segment5nl=9828.25 +segment6nl=10333.58 +segment7nl=10887.66 +segment8nl=11438.97 +segment9nl=11957.73 +segment10nl=12498.55 +segment11nl=13155.53 +segment12nl=13819.34 +segment13nl=14395.3 +segment14nl=14826.11 +segment15nl=15221.23 +segment16nl=15797.4 +segment17nl=16622.16 +segment18nl=17535.46 +segment19nl=18179.78 +segment20nl=18390.00 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + + +demandGrowthDEStart=1 +demandGrowthDEMin=1 +demandGrowthDETop=1 +demandGrowthDEMax=1 + +demandGrowthNLStart=1 +demandGrowthNLMin=1 +demandGrowthNLTop=1 +demandGrowthNLMax=1 + +#demandGrowthDEStart=1 +#demandGrowthDEMin=0.99 +#demandGrowthDETop=1.02 +#demandGrowthDEMax=1.05 + +#demandGrowthNLStart=1 +#demandGrowthNLMin=0.99 +#demandGrowthNLTop=1.02 +#demandGrowthNLMax=1.05 + + +startCash=3e9 +priceMarkUp=1 + +co2TradingImplemented=false +simulationLength=50 + +interconnectorCapacity=5000 + +investmentFutureTimeHorizon=7 + +numberOfYearsBacklookingForForecasting=5 +simpleCapacityMarketEnabled=true + +capacityMarketPriceCap=58940 +reserveMargin=0.15 +reserveDemandLowerMargin=0.025 +reserveDemandUpperMargin=0.025 diff --git a/emlab-generation/src/main/resources/scenarios/CmTwoCountryNone.properties b/emlab-generation/src/main/resources/scenarios/CmTwoCountryNone.properties new file mode 100644 index 00000000..407b7d28 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/CmTwoCountryNone.properties @@ -0,0 +1,158 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +coalPriceStart=3.6917419368 +coalPriceMin=0.9707458246 +coalPriceTop=1.0107458246 +coalPriceMax=1.0507458246 + +gasPriceStart=7.5 +gasPriceMin=0.9446627902 +gasPriceTop=1.0146627902 +gasPriceMax=1.0846627902 + +biomassPriceStart=4.5 +biomassPriceMin=0.97 +biomassPriceTop=1.01 +biomassPriceMax=1.05 + +uraniumPriceStart=1.286 +uraniumPriceMin=1 +uraniumPriceMax=1.02 +uraniumPriceTop=1.01 + +#coalPriceStart=3.6917419368 +#coalPriceMin=1 +#coalPriceTop=1 +#coalPriceMax=1 + +#gasPriceStart=7.5 +#gasPriceMin=1 +#gasPriceTop=1 +#gasPriceMax=1 + +#biomassPriceStart=4.5 +#biomassPriceMin=1 +#biomassPriceTop=1 +#biomassPriceMax=1 + +#uraniumPriceStart=1.286 +#uraniumPriceMin=1 +#uraniumPriceMax=1 +#uraniumPriceTop=1 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +#co2CapStart=351.75e6 +co2CapStart=72e10 +co2CapIncrement=0 +#co2CapIncrement=0 +co2CapDuration=1 + +minCo2DEPriceStart=0 +minCo2DEPriceIncrement=0 +minCo2DEPriceDuration=1 + +minCo2NLPriceStart=0 +minCo2NLPriceIncrement=0 +minCo2NLPriceDuration=1 + +segment1nl=8160.778 +segment2nl=8390.36 +segment3nl=8961.656 +segment4nl=9448.219 +segment5nl=9828.25 +segment6nl=10333.58 +segment7nl=10887.66 +segment8nl=11438.97 +segment9nl=11957.73 +segment10nl=12498.55 +segment11nl=13155.53 +segment12nl=13819.34 +segment13nl=14395.3 +segment14nl=14826.11 +segment15nl=15221.23 +segment16nl=15797.4 +segment17nl=16622.16 +segment18nl=17535.46 +segment19nl=18179.78 +segment20nl=18390.00 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + + +demandGrowthDEStart=1 +demandGrowthDEMin=1 +demandGrowthDETop=1 +demandGrowthDEMax=1 + +demandGrowthNLStart=1 +demandGrowthNLMin=1 +demandGrowthNLTop=1 +demandGrowthNLMax=1 + +#demandGrowthDEStart=1 +#demandGrowthDEMin=0.99 +#demandGrowthDETop=1.02 +#demandGrowthDEMax=1.05 + +#demandGrowthNLStart=1 +#demandGrowthNLMin=0.99 +#demandGrowthNLTop=1.02 +#demandGrowthNLMax=1.05 + + +startCash=3e9 +priceMarkUp=1 + +co2TradingImplemented=false +simulationLength=50 + +interconnectorCapacity=5000 + +investmentFutureTimeHorizon=7 + +numberOfYearsBacklookingForForecasting=5 +simpleCapacityMarketEnabled=false + +capacityMarketPriceCap=58940 +reserveMargin=0.15 +reserveDemandLowerMargin=0.025 +reserveDemandUpperMargin=0.025 diff --git a/emlab-generation/src/main/resources/scenarios/DET-BL-110.xml b/emlab-generation/src/main/resources/scenarios/DET-BL-110.xml new file mode 100644 index 00000000..6c2f866a --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/DET-BL-110.xml @@ -0,0 +1,838 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/DET-BL-TT-81.xml b/emlab-generation/src/main/resources/scenarios/DET-BL-TT-81.xml new file mode 100644 index 00000000..11110ae7 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/DET-BL-TT-81.xml @@ -0,0 +1,838 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/JornIntResExample.xml b/emlab-generation/src/main/resources/scenarios/JornIntResExample.xml new file mode 100644 index 00000000..383f917e --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/JornIntResExample.xml @@ -0,0 +1,1620 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/K_S_Fip.xml b/emlab-generation/src/main/resources/scenarios/K_S_Fip.xml new file mode 100644 index 00000000..80dc5423 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/K_S_Fip.xml @@ -0,0 +1,838 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/K_S_Np.xml b/emlab-generation/src/main/resources/scenarios/K_S_Np.xml new file mode 100644 index 00000000..f4dc15df --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/K_S_Np.xml @@ -0,0 +1,823 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/RDJ_RenewableTender_SingleCountry.xml b/emlab-generation/src/main/resources/scenarios/RDJ_RenewableTender_SingleCountry.xml new file mode 100644 index 00000000..2848ed5a --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/RDJ_RenewableTender_SingleCountry.xml @@ -0,0 +1,849 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/RES-BL-119.xml b/emlab-generation/src/main/resources/scenarios/RES-BL-119.xml new file mode 100644 index 00000000..28df5328 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/RES-BL-119.xml @@ -0,0 +1,873 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/RES-SR-66.xml b/emlab-generation/src/main/resources/scenarios/RES-SR-66.xml new file mode 100644 index 00000000..ed60f2e8 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/RES-SR-66.xml @@ -0,0 +1,873 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-1-8.xml b/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-1-8.xml new file mode 100644 index 00000000..ecb2302b --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-1-8.xml @@ -0,0 +1,873 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-2-11.xml b/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-2-11.xml new file mode 100644 index 00000000..c1315c7a --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-2-11.xml @@ -0,0 +1,873 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-3-26.xml b/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-3-26.xml new file mode 100644 index 00000000..caf514a6 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-3-26.xml @@ -0,0 +1,873 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-4-19.xml b/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-4-19.xml new file mode 100644 index 00000000..13b1b442 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-4-19.xml @@ -0,0 +1,873 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-5-44.xml b/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-5-44.xml new file mode 100644 index 00000000..c7d10da9 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-5-44.xml @@ -0,0 +1,873 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-6-12.xml b/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-6-12.xml new file mode 100644 index 00000000..6a495945 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-6-12.xml @@ -0,0 +1,873 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-7-45.xml b/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-7-45.xml new file mode 100644 index 00000000..b526c797 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-7-45.xml @@ -0,0 +1,873 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-8-100.xml b/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-8-100.xml new file mode 100644 index 00000000..a05b6fd1 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/SENS-RES-SR-8-100.xml @@ -0,0 +1,873 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/StaticDemand-1.xml b/emlab-generation/src/main/resources/scenarios/StaticDemand-1.xml new file mode 100644 index 00000000..6569a1bc --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/StaticDemand-1.xml @@ -0,0 +1,840 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/TM-BL-108.xml b/emlab-generation/src/main/resources/scenarios/TM-BL-108.xml new file mode 100644 index 00000000..56434f7b --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TM-BL-108.xml @@ -0,0 +1,831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/TM-BL-111.xml b/emlab-generation/src/main/resources/scenarios/TM-BL-111.xml new file mode 100644 index 00000000..77cabfa0 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TM-BL-111.xml @@ -0,0 +1,831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/TM-BL-119.xml b/emlab-generation/src/main/resources/scenarios/TM-BL-119.xml new file mode 100644 index 00000000..8a095cb1 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TM-BL-119.xml @@ -0,0 +1,859 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/TM-SR-82.xml b/emlab-generation/src/main/resources/scenarios/TM-SR-82.xml new file mode 100644 index 00000000..593296d8 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TM-SR-82.xml @@ -0,0 +1,831 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/Tender-RES-TwoCountryNL-DE.xml b/emlab-generation/src/main/resources/scenarios/Tender-RES-TwoCountryNL-DE.xml new file mode 100644 index 00000000..aab14552 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/Tender-RES-TwoCountryNL-DE.xml @@ -0,0 +1,1139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.422 + + + + + + 0.1271 + + + + + + 0.10514 + + + + + + 0.04846 + + + + + + 0.0731 + + + + + + 0.1551 + + + + + + 0.0591 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/TwoCountryBC-1.properties b/emlab-generation/src/main/resources/scenarios/TwoCountryBC-1.properties new file mode 100644 index 00000000..82a60fbf --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TwoCountryBC-1.properties @@ -0,0 +1,142 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +coalPriceStart=100.8629923136 +#coalPriceStart=86.300754753 +#coalPriceStart=50.0 +#coalPriceMin=0.96 +coalPriceMin=0.9707458246 +#coalPriceTop=1.00 +coalPriceTop=1.0107458246 +#coalPriceMax=1.04 +coalPriceMax=1.0507458246 + +gasPriceStart=0.3246874961 +#gasPriceStart=0.2286412084 +#gasPriceMin=0.95 +gasPriceMin=0.9446627902 +#gasPriceTop=1.01 +gasPriceTop=1.0146627902 +#gasPriceMax=1.07 +gasPriceMax=1.0846627902 + +biomassPriceStart=112.5 +#biomassPriceMin=0.95 +biomassPriceMin=0.97 +#biomassPriceTop=1.01 +biomassPriceTop=1.01 +#biomassPriceMax=1.05 +biomassPriceMax=1.05 + +uraniumPriceStart=5000000 +uraniumPriceMin=1.00 +#uraniumPriceMax=1.02 +uraniumPriceMax=1.02 +#uraniumPriceTop=1.01 +uraniumPriceTop=1.01 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +co2CapStart=0 +co2CapIncrement=0 +#co2CapIncrement=0 +co2CapDuration=1 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +minCo2DEPriceStart=0 +minCo2DEPriceIncrement=0 +minCo2DEPriceDuration=1 + +minCo2NLPriceStart=0 +minCo2NLPriceIncrement=0 +minCo2NLPriceDuration=1 + +segment1nl=8160.778 +segment2nl=8390.36 +segment3nl=8961.656 +segment4nl=9448.219 +segment5nl=9828.25 +segment6nl=10333.58 +segment7nl=10887.66 +segment8nl=11438.97 +segment9nl=11957.73 +segment10nl=12498.55 +segment11nl=13155.53 +segment12nl=13819.34 +segment13nl=14395.3 +segment14nl=14826.11 +segment15nl=15221.23 +segment16nl=15797.4 +segment17nl=16622.16 +segment18nl=17535.46 +segment19nl=18179.78 +segment20nl=18390.00 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + +demandGrowthDEStart=1 +demandGrowthDEMin=0.942294159 +demandGrowthDETop=1.0082073112 +demandGrowthDEMax=1.0548917102 +#demandGrowthDEMax=1.0548917102 + +demandGrowthNLStart=1 +demandGrowthNLMin=0.9516263553 +demandGrowthNLTop=1.0194189818 +demandGrowthNLMax=1.0435267857 + + +startCash=3e9 +priceMarkUp=1.1 + +co2TradingImplemented=false +simulationLength=50 + +interconnectorCapacity=4441 + +investmentFutureTimeHorizon=7 + +numberOfYearsBacklookingForForecasting=5 + +simpleCapacityMarketEnabled=false +capacityMarketPriceCap=58940 +reserveMargin=0.156 +reserveDemandLowerMargin=0.025 +reserveDemandUpperMargin=0.025 + diff --git a/emlab-generation/src/main/resources/scenarios/TwoCountryBC-1.xml b/emlab-generation/src/main/resources/scenarios/TwoCountryBC-1.xml new file mode 100644 index 00000000..fd852151 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TwoCountryBC-1.xml @@ -0,0 +1,1487 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1436 + + + + + + 0.1931 + + + + + + 0.1071 + + + + + + 0.0851 + + + + + + 0.0302 + + + + + + 0.072376 + + + + + + 0.1725 + + + + + + 0.1453 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-1.properties b/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-1.properties new file mode 100644 index 00000000..82a60fbf --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-1.properties @@ -0,0 +1,142 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +coalPriceStart=100.8629923136 +#coalPriceStart=86.300754753 +#coalPriceStart=50.0 +#coalPriceMin=0.96 +coalPriceMin=0.9707458246 +#coalPriceTop=1.00 +coalPriceTop=1.0107458246 +#coalPriceMax=1.04 +coalPriceMax=1.0507458246 + +gasPriceStart=0.3246874961 +#gasPriceStart=0.2286412084 +#gasPriceMin=0.95 +gasPriceMin=0.9446627902 +#gasPriceTop=1.01 +gasPriceTop=1.0146627902 +#gasPriceMax=1.07 +gasPriceMax=1.0846627902 + +biomassPriceStart=112.5 +#biomassPriceMin=0.95 +biomassPriceMin=0.97 +#biomassPriceTop=1.01 +biomassPriceTop=1.01 +#biomassPriceMax=1.05 +biomassPriceMax=1.05 + +uraniumPriceStart=5000000 +uraniumPriceMin=1.00 +#uraniumPriceMax=1.02 +uraniumPriceMax=1.02 +#uraniumPriceTop=1.01 +uraniumPriceTop=1.01 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +co2CapStart=0 +co2CapIncrement=0 +#co2CapIncrement=0 +co2CapDuration=1 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +minCo2DEPriceStart=0 +minCo2DEPriceIncrement=0 +minCo2DEPriceDuration=1 + +minCo2NLPriceStart=0 +minCo2NLPriceIncrement=0 +minCo2NLPriceDuration=1 + +segment1nl=8160.778 +segment2nl=8390.36 +segment3nl=8961.656 +segment4nl=9448.219 +segment5nl=9828.25 +segment6nl=10333.58 +segment7nl=10887.66 +segment8nl=11438.97 +segment9nl=11957.73 +segment10nl=12498.55 +segment11nl=13155.53 +segment12nl=13819.34 +segment13nl=14395.3 +segment14nl=14826.11 +segment15nl=15221.23 +segment16nl=15797.4 +segment17nl=16622.16 +segment18nl=17535.46 +segment19nl=18179.78 +segment20nl=18390.00 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + +demandGrowthDEStart=1 +demandGrowthDEMin=0.942294159 +demandGrowthDETop=1.0082073112 +demandGrowthDEMax=1.0548917102 +#demandGrowthDEMax=1.0548917102 + +demandGrowthNLStart=1 +demandGrowthNLMin=0.9516263553 +demandGrowthNLTop=1.0194189818 +demandGrowthNLMax=1.0435267857 + + +startCash=3e9 +priceMarkUp=1.1 + +co2TradingImplemented=false +simulationLength=50 + +interconnectorCapacity=4441 + +investmentFutureTimeHorizon=7 + +numberOfYearsBacklookingForForecasting=5 + +simpleCapacityMarketEnabled=false +capacityMarketPriceCap=58940 +reserveMargin=0.156 +reserveDemandLowerMargin=0.025 +reserveDemandUpperMargin=0.025 + diff --git a/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-1.xml b/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-1.xml new file mode 100644 index 00000000..0f0788bf --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-1.xml @@ -0,0 +1,1576 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1436 + + + + + + 0.1931 + + + + + + 0.1071 + + + + + + 0.0851 + + + + + + 0.0302 + + + + + + 0.072376 + + + + + + 0.1725 + + + + + + 0.1453 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-1.xml.orig b/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-1.xml.orig new file mode 100644 index 00000000..0f0788bf --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-1.xml.orig @@ -0,0 +1,1576 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1436 + + + + + + 0.1931 + + + + + + 0.1071 + + + + + + 0.0851 + + + + + + 0.0302 + + + + + + 0.072376 + + + + + + 0.1725 + + + + + + 0.1453 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-2.properties b/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-2.properties new file mode 100644 index 00000000..23f12db0 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-2.properties @@ -0,0 +1,142 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +coalPriceStart=100.8629923136 +#coalPriceStart=86.300754753 +#coalPriceStart=50.0 +#coalPriceMin=0.96 +coalPriceMin=0.9707458246 +#coalPriceTop=1.00 +coalPriceTop=1.0107458246 +#coalPriceMax=1.04 +coalPriceMax=1.0507458246 + +gasPriceStart=0.3246874961 +#gasPriceStart=0.2286412084 +#gasPriceMin=0.95 +gasPriceMin=0.9446627902 +#gasPriceTop=1.01 +gasPriceTop=1.0146627902 +#gasPriceMax=1.07 +gasPriceMax=1.0846627902 + +biomassPriceStart=112.5 +#biomassPriceMin=0.95 +biomassPriceMin=0.97 +#biomassPriceTop=1.01 +biomassPriceTop=1.01 +#biomassPriceMax=1.05 +biomassPriceMax=1.05 + +uraniumPriceStart=5000000 +uraniumPriceMin=1.00 +#uraniumPriceMax=1.02 +uraniumPriceMax=1.02 +#uraniumPriceTop=1.01 +uraniumPriceTop=1.01 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +co2CapStart=470.635e6 +co2CapIncrement=-8.189049e6 +#co2CapIncrement=0 +co2CapDuration=1 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +minCo2DEPriceStart=0 +minCo2DEPriceIncrement=0 +minCo2DEPriceDuration=1 + +minCo2NLPriceStart=0 +minCo2NLPriceIncrement=0 +minCo2NLPriceDuration=1 + +segment1nl=8160.778 +segment2nl=8390.36 +segment3nl=8961.656 +segment4nl=9448.219 +segment5nl=9828.25 +segment6nl=10333.58 +segment7nl=10887.66 +segment8nl=11438.97 +segment9nl=11957.73 +segment10nl=12498.55 +segment11nl=13155.53 +segment12nl=13819.34 +segment13nl=14395.3 +segment14nl=14826.11 +segment15nl=15221.23 +segment16nl=15797.4 +segment17nl=16622.16 +segment18nl=17535.46 +segment19nl=18179.78 +segment20nl=18390.00 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + +demandGrowthDEStart=1 +demandGrowthDEMin=0.942294159 +demandGrowthDETop=1.0082073112 +demandGrowthDEMax=1.0548917102 +#demandGrowthDEMax=1.0548917102 + +demandGrowthNLStart=1 +demandGrowthNLMin=0.9516263553 +demandGrowthNLTop=1.0194189818 +demandGrowthNLMax=1.0435267857 + + +startCash=3e9 +priceMarkUp=1.1 + +co2TradingImplemented=true +simulationLength=50 + +interconnectorCapacity=4441 + +investmentFutureTimeHorizon=7 + +numberOfYearsBacklookingForForecasting=5 + +simpleCapacityMarketEnabled=false +capacityMarketPriceCap=58940 +reserveMargin=0.156 +reserveDemandLowerMargin=0.025 +reserveDemandUpperMargin=0.025 + diff --git a/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-2.properties.orig b/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-2.properties.orig new file mode 100644 index 00000000..23f12db0 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-2.properties.orig @@ -0,0 +1,142 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +coalPriceStart=100.8629923136 +#coalPriceStart=86.300754753 +#coalPriceStart=50.0 +#coalPriceMin=0.96 +coalPriceMin=0.9707458246 +#coalPriceTop=1.00 +coalPriceTop=1.0107458246 +#coalPriceMax=1.04 +coalPriceMax=1.0507458246 + +gasPriceStart=0.3246874961 +#gasPriceStart=0.2286412084 +#gasPriceMin=0.95 +gasPriceMin=0.9446627902 +#gasPriceTop=1.01 +gasPriceTop=1.0146627902 +#gasPriceMax=1.07 +gasPriceMax=1.0846627902 + +biomassPriceStart=112.5 +#biomassPriceMin=0.95 +biomassPriceMin=0.97 +#biomassPriceTop=1.01 +biomassPriceTop=1.01 +#biomassPriceMax=1.05 +biomassPriceMax=1.05 + +uraniumPriceStart=5000000 +uraniumPriceMin=1.00 +#uraniumPriceMax=1.02 +uraniumPriceMax=1.02 +#uraniumPriceTop=1.01 +uraniumPriceTop=1.01 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +co2CapStart=470.635e6 +co2CapIncrement=-8.189049e6 +#co2CapIncrement=0 +co2CapDuration=1 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +minCo2DEPriceStart=0 +minCo2DEPriceIncrement=0 +minCo2DEPriceDuration=1 + +minCo2NLPriceStart=0 +minCo2NLPriceIncrement=0 +minCo2NLPriceDuration=1 + +segment1nl=8160.778 +segment2nl=8390.36 +segment3nl=8961.656 +segment4nl=9448.219 +segment5nl=9828.25 +segment6nl=10333.58 +segment7nl=10887.66 +segment8nl=11438.97 +segment9nl=11957.73 +segment10nl=12498.55 +segment11nl=13155.53 +segment12nl=13819.34 +segment13nl=14395.3 +segment14nl=14826.11 +segment15nl=15221.23 +segment16nl=15797.4 +segment17nl=16622.16 +segment18nl=17535.46 +segment19nl=18179.78 +segment20nl=18390.00 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + +demandGrowthDEStart=1 +demandGrowthDEMin=0.942294159 +demandGrowthDETop=1.0082073112 +demandGrowthDEMax=1.0548917102 +#demandGrowthDEMax=1.0548917102 + +demandGrowthNLStart=1 +demandGrowthNLMin=0.9516263553 +demandGrowthNLTop=1.0194189818 +demandGrowthNLMax=1.0435267857 + + +startCash=3e9 +priceMarkUp=1.1 + +co2TradingImplemented=true +simulationLength=50 + +interconnectorCapacity=4441 + +investmentFutureTimeHorizon=7 + +numberOfYearsBacklookingForForecasting=5 + +simpleCapacityMarketEnabled=false +capacityMarketPriceCap=58940 +reserveMargin=0.156 +reserveDemandLowerMargin=0.025 +reserveDemandUpperMargin=0.025 + diff --git a/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-2.xml b/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-2.xml new file mode 100644 index 00000000..6847ba16 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-2.xml @@ -0,0 +1,1576 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1436 + + + + + + 0.1931 + + + + + + 0.1071 + + + + + + 0.0851 + + + + + + 0.0302 + + + + + + 0.072376 + + + + + + 0.1725 + + + + + + 0.1453 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-2.xml.orig b/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-2.xml.orig new file mode 100644 index 00000000..6847ba16 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TwoCountryBCres-2.xml.orig @@ -0,0 +1,1576 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1436 + + + + + + 0.1931 + + + + + + 0.1071 + + + + + + 0.0851 + + + + + + 0.0302 + + + + + + 0.072376 + + + + + + 0.1725 + + + + + + 0.1453 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/TwoCountryCM-1.properties b/emlab-generation/src/main/resources/scenarios/TwoCountryCM-1.properties new file mode 100644 index 00000000..43a8d103 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TwoCountryCM-1.properties @@ -0,0 +1,142 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +coalPriceStart=100.8629923136 +#coalPriceStart=86.300754753 +#coalPriceStart=50.0 +#coalPriceMin=0.96 +coalPriceMin=0.9707458246 +#coalPriceTop=1.00 +coalPriceTop=1.0107458246 +#coalPriceMax=1.04 +coalPriceMax=1.0507458246 + +gasPriceStart=0.3246874961 +#gasPriceStart=0.2286412084 +#gasPriceMin=0.95 +gasPriceMin=0.9446627902 +#gasPriceTop=1.01 +gasPriceTop=1.0146627902 +#gasPriceMax=1.07 +gasPriceMax=1.0846627902 + +biomassPriceStart=112.5 +#biomassPriceMin=0.95 +biomassPriceMin=0.97 +#biomassPriceTop=1.01 +biomassPriceTop=1.01 +#biomassPriceMax=1.05 +biomassPriceMax=1.05 + +uraniumPriceStart=5000000 +uraniumPriceMin=1.00 +#uraniumPriceMax=1.02 +uraniumPriceMax=1.02 +#uraniumPriceTop=1.01 +uraniumPriceTop=1.01 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +co2CapStart=0 +co2CapIncrement=0 +#co2CapIncrement=0 +co2CapDuration=1 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +minCo2DEPriceStart=0 +minCo2DEPriceIncrement=0 +minCo2DEPriceDuration=1 + +minCo2NLPriceStart=0 +minCo2NLPriceIncrement=0 +minCo2NLPriceDuration=1 + +segment1nl=8160.778 +segment2nl=8390.36 +segment3nl=8961.656 +segment4nl=9448.219 +segment5nl=9828.25 +segment6nl=10333.58 +segment7nl=10887.66 +segment8nl=11438.97 +segment9nl=11957.73 +segment10nl=12498.55 +segment11nl=13155.53 +segment12nl=13819.34 +segment13nl=14395.3 +segment14nl=14826.11 +segment15nl=15221.23 +segment16nl=15797.4 +segment17nl=16622.16 +segment18nl=17535.46 +segment19nl=18179.78 +segment20nl=18390.00 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + +demandGrowthDEStart=1 +demandGrowthDEMin=0.942294159 +demandGrowthDETop=1.0082073112 +demandGrowthDEMax=1.0548917102 +#demandGrowthDEMax=1.0548917102 + +demandGrowthNLStart=1 +demandGrowthNLMin=0.9516263553 +demandGrowthNLTop=1.0194189818 +demandGrowthNLMax=1.0435267857 + + +startCash=3e9 +priceMarkUp=1.1 + +co2TradingImplemented=false +simulationLength=50 + +interconnectorCapacity=4441 + +investmentFutureTimeHorizon=7 + +numberOfYearsBacklookingForForecasting=5 + +simpleCapacityMarketEnabled=true +capacityMarketPriceCap=58940 +reserveMargin=0.156 +reserveDemandLowerMargin=0.025 +reserveDemandUpperMargin=0.025 + diff --git a/emlab-generation/src/main/resources/scenarios/TwoCountryCM-1.xml b/emlab-generation/src/main/resources/scenarios/TwoCountryCM-1.xml new file mode 100644 index 00000000..6249d10b --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TwoCountryCM-1.xml @@ -0,0 +1,1487 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1436 + + + + + + 0.1931 + + + + + + 0.1071 + + + + + + 0.0851 + + + + + + 0.0302 + + + + + + 0.072376 + + + + + + 0.1725 + + + + + + 0.1453 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/TwoCountryCMres-1.properties b/emlab-generation/src/main/resources/scenarios/TwoCountryCMres-1.properties new file mode 100644 index 00000000..43a8d103 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TwoCountryCMres-1.properties @@ -0,0 +1,142 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +coalPriceStart=100.8629923136 +#coalPriceStart=86.300754753 +#coalPriceStart=50.0 +#coalPriceMin=0.96 +coalPriceMin=0.9707458246 +#coalPriceTop=1.00 +coalPriceTop=1.0107458246 +#coalPriceMax=1.04 +coalPriceMax=1.0507458246 + +gasPriceStart=0.3246874961 +#gasPriceStart=0.2286412084 +#gasPriceMin=0.95 +gasPriceMin=0.9446627902 +#gasPriceTop=1.01 +gasPriceTop=1.0146627902 +#gasPriceMax=1.07 +gasPriceMax=1.0846627902 + +biomassPriceStart=112.5 +#biomassPriceMin=0.95 +biomassPriceMin=0.97 +#biomassPriceTop=1.01 +biomassPriceTop=1.01 +#biomassPriceMax=1.05 +biomassPriceMax=1.05 + +uraniumPriceStart=5000000 +uraniumPriceMin=1.00 +#uraniumPriceMax=1.02 +uraniumPriceMax=1.02 +#uraniumPriceTop=1.01 +uraniumPriceTop=1.01 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +co2CapStart=0 +co2CapIncrement=0 +#co2CapIncrement=0 +co2CapDuration=1 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +minCo2DEPriceStart=0 +minCo2DEPriceIncrement=0 +minCo2DEPriceDuration=1 + +minCo2NLPriceStart=0 +minCo2NLPriceIncrement=0 +minCo2NLPriceDuration=1 + +segment1nl=8160.778 +segment2nl=8390.36 +segment3nl=8961.656 +segment4nl=9448.219 +segment5nl=9828.25 +segment6nl=10333.58 +segment7nl=10887.66 +segment8nl=11438.97 +segment9nl=11957.73 +segment10nl=12498.55 +segment11nl=13155.53 +segment12nl=13819.34 +segment13nl=14395.3 +segment14nl=14826.11 +segment15nl=15221.23 +segment16nl=15797.4 +segment17nl=16622.16 +segment18nl=17535.46 +segment19nl=18179.78 +segment20nl=18390.00 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + +demandGrowthDEStart=1 +demandGrowthDEMin=0.942294159 +demandGrowthDETop=1.0082073112 +demandGrowthDEMax=1.0548917102 +#demandGrowthDEMax=1.0548917102 + +demandGrowthNLStart=1 +demandGrowthNLMin=0.9516263553 +demandGrowthNLTop=1.0194189818 +demandGrowthNLMax=1.0435267857 + + +startCash=3e9 +priceMarkUp=1.1 + +co2TradingImplemented=false +simulationLength=50 + +interconnectorCapacity=4441 + +investmentFutureTimeHorizon=7 + +numberOfYearsBacklookingForForecasting=5 + +simpleCapacityMarketEnabled=true +capacityMarketPriceCap=58940 +reserveMargin=0.156 +reserveDemandLowerMargin=0.025 +reserveDemandUpperMargin=0.025 + diff --git a/emlab-generation/src/main/resources/scenarios/TwoCountryCMres-1.xml b/emlab-generation/src/main/resources/scenarios/TwoCountryCMres-1.xml new file mode 100644 index 00000000..c6db6042 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TwoCountryCMres-1.xml @@ -0,0 +1,1576 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1436 + + + + + + 0.1931 + + + + + + 0.1071 + + + + + + 0.0851 + + + + + + 0.0302 + + + + + + 0.072376 + + + + + + 0.1725 + + + + + + 0.1453 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/TwoCountryCMres-2.properties b/emlab-generation/src/main/resources/scenarios/TwoCountryCMres-2.properties new file mode 100644 index 00000000..3cea680e --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TwoCountryCMres-2.properties @@ -0,0 +1,141 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +coalPriceStart=100.8629923136 +#coalPriceStart=86.300754753 +#coalPriceStart=50.0 +#coalPriceMin=0.96 +coalPriceMin=0.9707458246 +#coalPriceTop=1.00 +coalPriceTop=1.0107458246 +#coalPriceMax=1.04 +coalPriceMax=1.0507458246 + +gasPriceStart=0.3246874961 +#gasPriceStart=0.2286412084 +#gasPriceMin=0.95 +gasPriceMin=0.9446627902 +#gasPriceTop=1.01 +gasPriceTop=1.0146627902 +#gasPriceMax=1.07 +gasPriceMax=1.0846627902 + +biomassPriceStart=112.5 +#biomassPriceMin=0.95 +biomassPriceMin=0.97 +#biomassPriceTop=1.01 +biomassPriceTop=1.01 +#biomassPriceMax=1.05 +biomassPriceMax=1.05 + +uraniumPriceStart=5000000 +uraniumPriceMin=1.00 +#uraniumPriceMax=1.02 +uraniumPriceMax=1.02 +#uraniumPriceTop=1.01 +uraniumPriceTop=1.01 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +co2CapStart=470.635e6 +co2CapIncrement=-8.189049e6 +#co2CapIncrement=0 +co2CapDuration=1 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +minCo2DEPriceStart=0 +minCo2DEPriceIncrement=0 +minCo2DEPriceDuration=1 + +minCo2NLPriceStart=0 +minCo2NLPriceIncrement=0 +minCo2NLPriceDuration=1 + +segment1nl=8160.778 +segment2nl=8390.36 +segment3nl=8961.656 +segment4nl=9448.219 +segment5nl=9828.25 +segment6nl=10333.58 +segment7nl=10887.66 +segment8nl=11438.97 +segment9nl=11957.73 +segment10nl=12498.55 +segment11nl=13155.53 +segment12nl=13819.34 +segment13nl=14395.3 +segment14nl=14826.11 +segment15nl=15221.23 +segment16nl=15797.4 +segment17nl=16622.16 +segment18nl=17535.46 +segment19nl=18179.78 +segment20nl=18390.00 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + +demandGrowthDEStart=1 +demandGrowthDEMin=0.942294159 +demandGrowthDETop=1.0082073112 +demandGrowthDEMax=1.0548917102 +#demandGrowthDEMax=1.0548917102 + +demandGrowthNLStart=1 +demandGrowthNLMin=0.9516263553 +demandGrowthNLTop=1.0194189818 +demandGrowthNLMax=1.0435267857 + +startCash=3e9 +priceMarkUp=1.1 + +co2TradingImplemented=true +simulationLength=50 + +interconnectorCapacity=4441 + +investmentFutureTimeHorizon=7 + +numberOfYearsBacklookingForForecasting=5 + +simpleCapacityMarketEnabled=true +capacityMarketPriceCap=58940 +reserveMargin=0.156 +reserveDemandLowerMargin=0.025 +reserveDemandUpperMargin=0.025 + diff --git a/emlab-generation/src/main/resources/scenarios/TwoCountryCMres-2.properties.orig b/emlab-generation/src/main/resources/scenarios/TwoCountryCMres-2.properties.orig new file mode 100644 index 00000000..3cea680e --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TwoCountryCMres-2.properties.orig @@ -0,0 +1,141 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +coalPriceStart=100.8629923136 +#coalPriceStart=86.300754753 +#coalPriceStart=50.0 +#coalPriceMin=0.96 +coalPriceMin=0.9707458246 +#coalPriceTop=1.00 +coalPriceTop=1.0107458246 +#coalPriceMax=1.04 +coalPriceMax=1.0507458246 + +gasPriceStart=0.3246874961 +#gasPriceStart=0.2286412084 +#gasPriceMin=0.95 +gasPriceMin=0.9446627902 +#gasPriceTop=1.01 +gasPriceTop=1.0146627902 +#gasPriceMax=1.07 +gasPriceMax=1.0846627902 + +biomassPriceStart=112.5 +#biomassPriceMin=0.95 +biomassPriceMin=0.97 +#biomassPriceTop=1.01 +biomassPriceTop=1.01 +#biomassPriceMax=1.05 +biomassPriceMax=1.05 + +uraniumPriceStart=5000000 +uraniumPriceMin=1.00 +#uraniumPriceMax=1.02 +uraniumPriceMax=1.02 +#uraniumPriceTop=1.01 +uraniumPriceTop=1.01 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +co2CapStart=470.635e6 +co2CapIncrement=-8.189049e6 +#co2CapIncrement=0 +co2CapDuration=1 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +minCo2DEPriceStart=0 +minCo2DEPriceIncrement=0 +minCo2DEPriceDuration=1 + +minCo2NLPriceStart=0 +minCo2NLPriceIncrement=0 +minCo2NLPriceDuration=1 + +segment1nl=8160.778 +segment2nl=8390.36 +segment3nl=8961.656 +segment4nl=9448.219 +segment5nl=9828.25 +segment6nl=10333.58 +segment7nl=10887.66 +segment8nl=11438.97 +segment9nl=11957.73 +segment10nl=12498.55 +segment11nl=13155.53 +segment12nl=13819.34 +segment13nl=14395.3 +segment14nl=14826.11 +segment15nl=15221.23 +segment16nl=15797.4 +segment17nl=16622.16 +segment18nl=17535.46 +segment19nl=18179.78 +segment20nl=18390.00 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + +demandGrowthDEStart=1 +demandGrowthDEMin=0.942294159 +demandGrowthDETop=1.0082073112 +demandGrowthDEMax=1.0548917102 +#demandGrowthDEMax=1.0548917102 + +demandGrowthNLStart=1 +demandGrowthNLMin=0.9516263553 +demandGrowthNLTop=1.0194189818 +demandGrowthNLMax=1.0435267857 + +startCash=3e9 +priceMarkUp=1.1 + +co2TradingImplemented=true +simulationLength=50 + +interconnectorCapacity=4441 + +investmentFutureTimeHorizon=7 + +numberOfYearsBacklookingForForecasting=5 + +simpleCapacityMarketEnabled=true +capacityMarketPriceCap=58940 +reserveMargin=0.156 +reserveDemandLowerMargin=0.025 +reserveDemandUpperMargin=0.025 + diff --git a/emlab-generation/src/main/resources/scenarios/TwoCountryCMres-2.xml b/emlab-generation/src/main/resources/scenarios/TwoCountryCMres-2.xml new file mode 100644 index 00000000..37d4525d --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/TwoCountryCMres-2.xml @@ -0,0 +1,1576 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1436 + + + + + + 0.1931 + + + + + + 0.1071 + + + + + + 0.0851 + + + + + + 0.0302 + + + + + + 0.072376 + + + + + + 0.1725 + + + + + + 0.1453 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/ZERO_START_RES-BL-108.xml b/emlab-generation/src/main/resources/scenarios/ZERO_START_RES-BL-108.xml new file mode 100644 index 00000000..06fe66ea --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/ZERO_START_RES-BL-108.xml @@ -0,0 +1,873 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/ZERO_START_RES-BL-119.xml b/emlab-generation/src/main/resources/scenarios/ZERO_START_RES-BL-119.xml new file mode 100644 index 00000000..00679a57 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/ZERO_START_RES-BL-119.xml @@ -0,0 +1,873 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.50 + + + + + + 0.19 + + + + + + 0.13 + + + + + + 0.18 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/emlab-generation (9).launch b/emlab-generation/src/main/resources/scenarios/emlab-generation (9).launch new file mode 100755 index 00000000..4a305b1a --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/emlab-generation (9).launch @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/parametersA-Old-CM.properties b/emlab-generation/src/main/resources/scenarios/parametersA-Old-CM.properties new file mode 100644 index 00000000..9de8a871 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/parametersA-Old-CM.properties @@ -0,0 +1,99 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +coalPriceStart=50.0 +#coalPriceMin=0.96 +coalPriceMin=1 +#coalPriceTop=1.00 +coalPriceTop=1 +#coalPriceMax=1.04 +coalPriceMax=1 + +gasPriceStart=0.25 +#gasPriceMin=0.95 +gasPriceMin=1 +#gasPriceTop=1.01 +gasPriceTop=1 +#gasPriceMax=1.07 +gasPriceMax=1 + +biomassPriceStart=100 +#biomassPriceMin=0.95 +biomassPriceMin=1 +#biomassPriceTop=1.01 +biomassPriceTop=1 +#biomassPriceMax=1.05 +biomassPriceMax=1 + +uraniumPriceStart=5000000 +uraniumPriceMin=1 +#uraniumPriceMax=1.02 +uraniumPriceMax=1 +#uraniumPriceTop=1.01 +uraniumPriceTop=1 +uraniumSeries=5000000,5050000,5100500,5151505,5203020.05,5255050.2505,5307600.753005,5360676.76053505,5414283.5281404,5468426.3634218,5523110.62705602,5578341.73332658,5634125.15065985,5690466.40216645,5747371.06618811,5804844.77684999,5862893.22461849,5921522.15686468,5980737.37843332,6040544.75221766,6100950.19973983,6161959.70173723,6223579.2987546,6285815.09174215,6348673.24265957,6412159.97508617,6476281.57483703,6541044.3905854,6606454.83449125,6672519.38283617,6739244.57666453,6806637.02243117,6874703.39265549,6943450.42658204,7012884.93084786,7083013.78015634,7153843.9179579,7225382.35713748,7297636.18070886,7370612.54251594,7444318.6679411,7518761.85462052,7593949.47316672,7669888.96789839,7746587.85757737,7824053.73615315,7902294.27351468,7981317.21624983,8061130.38841232,8141741.69229645,8223159.10921941,8305390.70031161,8388444.60731472,8472329.05338787,8557052.34392175,8642622.86736096,8729049.09603457,8816339.58699492,8904502.98286487,8993548.01269352,9083483.49282045 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +co2CapStart=10e7 +#co2CapIncrement=-.5e6 +co2CapIncrement=0 +co2CapDuration=1 + +minCo2PriceStart=0 +minCo2PriceIncrement=0 +minCo2PriceDuration=20 + +segment1nl=9074 +segment2nl=10455 +segment3nl=11980 +segment4nl=13642 +segment5nl=15342 + +segment1de=13500 +segment2de=15200 +segment3de=18000 +segment4de=20000 +segment5de=22500 + +demandGrowthDEStart=1 +demandGrowthDEMin=1 +demandGrowthDETop=1 +demandGrowthDEMax=1 + +demandGrowthNLStart=1 +demandGrowthNLMin=1 +demandGrowthNLTop=1 +demandGrowthNLMax=1 + +startCash=1e9 +priceMarkUp=1.1 + +co2TradingImplemented=false +simpleCapacityMarketEnabled=true +simulationLength=50 + +interconnectorCapacity=0 + +numberOfYearsBacklookingForForecasting=5 + +capacityMarketPriceCap=109500 +reserveMargin=0.15 +reserveDemandLowerMargin=0.05 +reserveDemandUpperMargin=0.05 + + diff --git a/emlab-generation/src/main/resources/scenarios/parametersB-DYN.properties b/emlab-generation/src/main/resources/scenarios/parametersB-DYN.properties new file mode 100644 index 00000000..e3d5f7d1 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/parametersB-DYN.properties @@ -0,0 +1,64 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +co2CapStart=72e10 +co2CapIncrement=0 +co2CapDuration=1 + +minCo2DEPriceStart=0 +minCo2DEPriceIncrement=0 +minCo2DEPriceDuration=1 + +minCo2PriceStart=0 +minCo2PriceIncrement=0 +minCo2PriceDuration=1 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + +startCash=5e10 +priceMarkUp=1 + +co2TradingImplemented=false +simulationLength=40 + +interconnectorCapacity=0 + diff --git a/emlab-generation/src/main/resources/scenarios/parametersB-OneCountry-CapacityMarket.properties b/emlab-generation/src/main/resources/scenarios/parametersB-OneCountry-CapacityMarket.properties new file mode 100644 index 00000000..d44f3081 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/parametersB-OneCountry-CapacityMarket.properties @@ -0,0 +1,146 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +#coalPriceStart=86.300754753 +#coalPriceStart=50.0 +#coalPriceMin=0.96 +#coalPriceMin=0.97 +#coalPriceTop=1.00 +#coalPriceTop=1.01 +#coalPriceMax=1.04 +#coalPriceMax=1.05 + +coalPriceStart=100.8629923136 +coalPriceMin=1 +coalPriceTop=1 +coalPriceMax=1 + +gasPriceStart=0.3246874961 +#gasPriceStart=0.2286412084 +gasPriceMin=1 +#gasPriceMin=0.9446627902 +gasPriceTop=1 +#gasPriceTop=1.0146627902 +gasPriceMax=1 +#gasPriceMax=1.0846627902 + +#gasPriceStart=0.2286412084 +#gasPriceMin=0.95 +#gasPriceMin=0.96 +#gasPriceTop=1.01 +#gasPriceTop=1.03 +#gasPriceMax=1.07 +#gasPriceMax=1.10 + +biomassPriceStart=112.5 +biomassPriceMin=1 +#biomassPriceMin=0.97 +biomassPriceTop=1 +#biomassPriceTop=1.01 +biomassPriceMax=1 +#biomassPriceMax=1.05 + +#biomassPriceStart=112.5 +#biomassPriceMin=0.95 +#biomassPriceMin=0.97 +#biomassPriceTop=1.01 +#biomassPriceTop=1.01 +#biomassPriceMax=1.05 +#biomassPriceMax=1.05 + +uraniumPriceStart=5000000 +uraniumPriceMin=1 +uraniumPriceMax=1 +#uraniumPriceMax=1.02 +uraniumPriceTop=1 +#uraniumPriceTop=1.01 + +#uraniumPriceStart=5000000 +#uraniumPriceMin=1.00 +#uraniumPriceMax=1.02 +#uraniumPriceMax=1.02 +#uraniumPriceTop=1.01 +#uraniumPriceTop=1.01 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +co2CapStart=72e10 +#co2CapIncrement=-1.104e6 +co2CapIncrement=0 +co2CapDuration=1 + +minCo2NLPriceStart=0 +minCo2NLPriceIncrement=0 +minCo2NLPriceDuration=1 + +minCo2PriceStart=0 +minCo2PriceIncrement=0 +minCo2PriceDuration=1 + +segment1nl=8160.778 +segment2nl=8390.36 +segment3nl=8961.656 +segment4nl=9448.219 +segment5nl=9828.25 +segment6nl=10333.58 +segment7nl=10887.66 +segment8nl=11438.97 +segment9nl=11957.73 +segment10nl=12498.55 +segment11nl=13155.53 +segment12nl=13819.34 +segment13nl=14395.3 +segment14nl=14826.11 +segment15nl=15221.23 +segment16nl=15797.4 +segment17nl=16622.16 +segment18nl=17535.46 +segment19nl=18179.78 +segment20nl=18390.00 + + +demandGrowthNLStart=1 +demandGrowthNLMin=0.95 +demandGrowthNLTop=1.022 +demandGrowthNLMax=1.07 + +#demandGrowthNLStart=1 +#demandGrowthNLMin=1 +#demandGrowthNLTop=1 +#demandGrowthNLMax=1 + +startCash=3e9 +priceMarkUp=1 + +co2TradingImplemented=false +simpleCapacityMarketEnabled=true +simulationLength=50 + +interconnectorCapacity=0 + +investmentFutureTimeHorizon=7 + +numberOfYearsBacklookingForForecasting=5 + +capacityMarketPriceCap=58940 +reserveMargin=0.156 +reserveDemandLowerMargin=0.025 +reserveDemandUpperMargin=0.025 diff --git a/emlab-generation/src/main/resources/scenarios/parametersB-OneCountry.properties b/emlab-generation/src/main/resources/scenarios/parametersB-OneCountry.properties index 7bcfe8f8..10abfc90 100644 --- a/emlab-generation/src/main/resources/scenarios/parametersB-OneCountry.properties +++ b/emlab-generation/src/main/resources/scenarios/parametersB-OneCountry.properties @@ -116,21 +116,20 @@ segment18nl=17535.46 segment19nl=18179.78 segment20nl=18390.00 +demandGrowthNLStart=1 +demandGrowthNLMin=0.95 +demandGrowthNLTop=1.022 +demandGrowthNLMax=1.07 #demandGrowthNLStart=1 -#demandGrowthNLMin=0.99 -#demandGrowthNLTop=1.02 -#demandGrowthNLMax=1.05 - -demandGrowthNLStart=1 -demandGrowthNLMin=1 -demandGrowthNLTop=1 -demandGrowthNLMax=1 +#demandGrowthNLMin=1 +#demandGrowthNLTop=1 +#demandGrowthNLMax=1 startCash=3e9 priceMarkUp=1 -co2TradingImplemented=true +co2TradingImplemented=false simulationLength=50 interconnectorCapacity=0 diff --git a/emlab-generation/src/main/resources/scenarios/parametersB-TM-DE.properties b/emlab-generation/src/main/resources/scenarios/parametersB-TM-DE.properties new file mode 100644 index 00000000..488100f3 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/parametersB-TM-DE.properties @@ -0,0 +1,98 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- + + +coalPriceStart=3.6917419368 +coalPriceMin=1 +coalPriceTop=1 +coalPriceMax=1 + +gasPriceStart=7.5 +gasPriceMin=1 +gasPriceTop=1 +gasPriceMax=1 + + +biomassPriceStart=4.5 +biomassPriceMin=1 +biomassPriceTop=1 +biomassPriceMax=1 + +uraniumPriceStart=1.286 +uraniumPriceMin=1 +uraniumPriceMax=1 +uraniumPriceTop=1 + +lignitePriceStart=1.428 +lignitePriceMin=1 +lignitePriceMax=1 +lignitePriceTop=1 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +co2CapStart=72e10 +co2CapIncrement=0 +co2CapDuration=1 + +minCo2DEPriceStart=0 +minCo2DEPriceIncrement=0 +minCo2DEPriceDuration=1 + +minCo2PriceStart=0 +minCo2PriceIncrement=0 +minCo2PriceDuration=1 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + +demandGrowthDEStart=1 +demandGrowthDEMin=1 +demandGrowthDETop=1 +demandGrowthDEMax=1 + +startCash=5e10 +priceMarkUp=1 + +co2TradingImplemented=false +simulationLength=40 + +interconnectorCapacity=0 + + diff --git a/emlab-generation/src/main/resources/scenarios/parametersB-ThermalMixDE.properties b/emlab-generation/src/main/resources/scenarios/parametersB-ThermalMixDE-CapacityMarket.properties similarity index 93% rename from emlab-generation/src/main/resources/scenarios/parametersB-ThermalMixDE.properties rename to emlab-generation/src/main/resources/scenarios/parametersB-ThermalMixDE-CapacityMarket.properties index 8f79ca96..2ad15151 100644 --- a/emlab-generation/src/main/resources/scenarios/parametersB-ThermalMixDE.properties +++ b/emlab-generation/src/main/resources/scenarios/parametersB-ThermalMixDE-CapacityMarket.properties @@ -122,11 +122,17 @@ demandGrowthDEMax=1 startCash=8e10 priceMarkUp=1 -co2TradingImplemented=true -simulationLength=110 +co2TradingImplemented=false +simpleCapacityMarketEnabled=true +simulationLength=100 interconnectorCapacity=0 investmentFutureTimeHorizon=7 numberOfYearsBacklookingForForecasting=5 + +capacityMarketPriceCap=10000 +reserveMargin=0.5 +reserveDemandLowerMargin=0.05 +reserveDemandUpperMargin=0.05 diff --git a/emlab-generation/src/main/resources/scenarios/parametersC-ETS-CM-de.properties b/emlab-generation/src/main/resources/scenarios/parametersC-ETS-CM-de.properties new file mode 100644 index 00000000..60863dc2 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/parametersC-ETS-CM-de.properties @@ -0,0 +1,124 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +#In EUR/GJ Real terms +coalPriceSeries=3.4342903691,2.8364179566,3.0588821101,3.2285110271,3.2451958386,3.2646614521,3.2813462636,3.300811877,3.3174966885,3.3369623019,3.3369623019,3.3369623019,3.3369623019,3.3369623019,3.3369623019,3.3369623019,3.3369623019,3.3369623019,3.3369623019,3.3369623019,3.3318397721,3.3267172422,3.3215947124,3.3164721825,3.3113496527,3.3062271228,3.301104593,3.2959820631,3.2908595333,3.2857370034,3.2806144736,3.2754919437,3.2703694139,3.265246884,3.2601243542,3.2550018243,3.2498792945,3.2447567646,3.2396342348,3.2345117049,3.229389175,3.2242666452,3.2191441153,3.2140215855,3.2088990556,3.2037765258,3.1986539959,3.1935314661,3.1884089362,3.1832864064,3.1781638765,3.1730413467,3.1679188168,3.162796287,3.1576737571 +gasPriceSeries=6.1337281391,6.496939571,7.2868612059,8.0767828408,8.1488536615,8.2216174709,7.9256284194,7.6296393679,7.6296393679,7.6296393679,7.6296393679,7.6296393679,7.6296393679,7.6296393679,7.6296393679,7.6296393679,7.6296393679,7.6296393679,7.6296393679,7.6296393679,7.7083715378,7.7871037077,7.8658358777,7.9445680476,8.0233002175,8.1020323875,8.1807645574,8.2594967273,8.3382288973,8.4169610672,8.4956932371,8.5744254071,8.653157577,8.7318897469,8.8106219169,8.8893540868,8.9680862567,9.0468184267,9.1255505966,9.2042827665,9.2830149364,9.3617471064,9.4404792763,9.5192114462,9.5979436162,9.6766757861,9.7554079561,9.834140126,9.9128722959,9.9916044659,10.0703366358,10.1490688057,10.2278009757,10.3065331456,10.3852653156 + +biomassPriceStart=112.5 +#biomassPriceMin=0.95 +biomassPriceMin=1.00 +#biomassPriceTop=1.01 +biomassPriceTop=1.00 +#biomassPriceMax=1.05 +biomassPriceMax=1.00 + +uraniumPriceStart=5000000 +uraniumPriceMin=1.00 +#uraniumPriceMax=1.02 +uraniumPriceMax=1.00 +#uraniumPriceTop=1.01 +uraniumPriceTop=1.00 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +co2CapStart=351.75e6 +co2CapIncrement=-6.120624e6 +#co2CapIncrement=0 +co2CapDuration=1 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +minCo2DEPriceStart=0 +minCo2DEPriceIncrement=0 +minCo2DEPriceDuration=1 + +minCo2NLPriceStart=0 +minCo2NLPriceIncrement=0 +minCo2NLPriceDuration=1 + +segment1nl=8160.778 +segment2nl=8390.36 +segment3nl=8961.656 +segment4nl=9448.219 +segment5nl=9828.25 +segment6nl=10333.58 +segment7nl=10887.66 +segment8nl=11438.97 +segment9nl=11957.73 +segment10nl=12498.55 +segment11nl=13155.53 +segment12nl=13819.34 +segment13nl=14395.3 +segment14nl=14826.11 +segment15nl=15221.23 +segment16nl=15797.4 +segment17nl=16622.16 +segment18nl=17535.46 +segment19nl=18179.78 +segment20nl=18390.00 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + +demandGrowthDEStart=1 +demandGrowthDEMin=0.99 +demandGrowthDETop=1.02 +demandGrowthDEMax=1.05 + +demandGrowthNLStart=1 +demandGrowthNLMin=0.99 +demandGrowthNLTop=1.02 +demandGrowthNLMax=1.05 + +startCash=3e9 +priceMarkUp=1.1 + +co2TradingImplemented=true +simulationLength=50 + +interconnectorCapacity=4000 + +investmentFutureTimeHorizon=7 + +numberOfYearsBacklookingForForecasting=5 + +simpleCapacityMarketEnabled=true +capacityMarketPriceCap=58940 +reserveMargin=0.156 +reserveDemandLowerMargin=0.025 +reserveDemandUpperMargin=0.025 diff --git a/emlab-generation/src/main/resources/scenarios/parametersCM-SR.properties b/emlab-generation/src/main/resources/scenarios/parametersCM-SR.properties new file mode 100644 index 00000000..9b5004ac --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/parametersCM-SR.properties @@ -0,0 +1,158 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +coalPriceStart=3.6917419368 +coalPriceMin=0.9707458246 +coalPriceTop=1.0107458246 +coalPriceMax=1.0507458246 + +gasPriceStart=7.5 +gasPriceMin=0.9446627902 +gasPriceTop=1.0146627902 +gasPriceMax=1.0846627902 + +biomassPriceStart=4.5 +biomassPriceMin=0.97 +biomassPriceTop=1.01 +biomassPriceMax=1.05 + +uraniumPriceStart=1.286 +uraniumPriceMin=1 +uraniumPriceMax=1.02 +uraniumPriceTop=1.01 + +#coalPriceStart=3.6917419368 +#coalPriceMin=1 +#coalPriceTop=1 +#coalPriceMax=1 + +#gasPriceStart=7.5 +#gasPriceMin=1 +#gasPriceTop=1 +#gasPriceMax=1 + +#biomassPriceStart=4.5 +#biomassPriceMin=1 +#biomassPriceTop=1 +#biomassPriceMax=1 + +#uraniumPriceStart=1.286 +#uraniumPriceMin=1 +#uraniumPriceMax=1 +#uraniumPriceTop=1 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +#co2CapStart=351.75e6 +co2CapStart=72e10 +co2CapIncrement=0 +#co2CapIncrement=0 +co2CapDuration=1 + +minCo2DEPriceStart=0 +minCo2DEPriceIncrement=0 +minCo2DEPriceDuration=1 + +minCo2NLPriceStart=0 +minCo2NLPriceIncrement=0 +minCo2NLPriceDuration=1 + +segment1nl=35311.89 +segment2nl=36657.44 +segment3nl=40401.68 +segment4nl=43606.1 +segment5nl=45600.58 +segment6nl=47414.54 +segment7nl=49337.31 +segment8nl=51439.43 +segment9nl=53771.93 +segment10nl=56143.54 +segment11nl=58402.19 +segment12nl=60234.9 +segment13nl=61923.03 +segment14nl=63697.04 +segment15nl=65580.2 +segment16nl=67797.75 +segment17nl=71192.97 +segment18nl=75390.2 +segment19nl=77408.11 +segment20nl=79884 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + + +demandGrowthDEStart=1 +demandGrowthDEMin=1 +demandGrowthDETop=1 +demandGrowthDEMax=1 + +demandGrowthNLStart=1 +demandGrowthNLMin=1 +demandGrowthNLTop=1 +demandGrowthNLMax=1 + +#demandGrowthDEStart=1 +#demandGrowthDEMin=0.99 +#demandGrowthDETop=1.02 +#demandGrowthDEMax=1.05 + +#demandGrowthNLStart=1 +#demandGrowthNLMin=0.99 +#demandGrowthNLTop=1.02 +#demandGrowthNLMax=1.05 + + +startCash=3e9 +priceMarkUp=1 + +co2TradingImplemented=false +simulationLength=50 + +interconnectorCapacity=5000 + +investmentFutureTimeHorizon=7 + +numberOfYearsBacklookingForForecasting=5 +simpleCapacityMarketEnabled=1 + +capacityMarketPriceCap=58940 +reserveMargin=0.15 +reserveDemandLowerMargin=0.025 +reserveDemandUpperMargin=0.025 diff --git a/emlab-generation/src/main/resources/scenarios/parametersE-MinCO2-resTarget-CM.properties b/emlab-generation/src/main/resources/scenarios/parametersE-MinCO2-resTarget-CM.properties new file mode 100644 index 00000000..15d9b350 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/parametersE-MinCO2-resTarget-CM.properties @@ -0,0 +1,139 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +coalPriceStart=100.8629923136 +#coalPriceStart=86.300754753 +#coalPriceStart=50.0 +#coalPriceMin=0.96 +coalPriceMin=0.9707458246 +#coalPriceTop=1.00 +coalPriceTop=1.0107458246 +#coalPriceMax=1.04 +coalPriceMax=1.0507458246 + +gasPriceStart=0.3246874961 +#gasPriceStart=0.2286412084 +#gasPriceMin=0.95 +gasPriceMin=0.9446627902 +#gasPriceTop=1.01 +gasPriceTop=1.0146627902 +#gasPriceMax=1.07 +gasPriceMax=1.0846627902 + +biomassPriceStart=112.5 +#biomassPriceMin=0.95 +biomassPriceMin=0.97 +#biomassPriceTop=1.01 +biomassPriceTop=1.01 +#biomassPriceMax=1.05 +biomassPriceMax=1.05 + +uraniumPriceStart=5000000 +uraniumPriceMin=1.00 +#uraniumPriceMax=1.02 +uraniumPriceMax=1.02 +#uraniumPriceTop=1.01 +uraniumPriceTop=1.01 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +co2CapStart=351.75e6 +co2CapIncrement=-6.120624e6 +#co2CapIncrement=0 +co2CapDuration=1 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +minCo2DEPriceStart=25 +minCo2DEPriceIncrement=1.5 +minCo2DEPriceDuration=1 + +minCo2NLPriceStart=25 +minCo2NLPriceIncrement=1.5 +minCo2NLPriceDuration=1 + +segment1nl=8160.778 +segment2nl=8390.36 +segment3nl=8961.656 +segment4nl=9448.219 +segment5nl=9828.25 +segment6nl=10333.58 +segment7nl=10887.66 +segment8nl=11438.97 +segment9nl=11957.73 +segment10nl=12498.55 +segment11nl=13155.53 +segment12nl=13819.34 +segment13nl=14395.3 +segment14nl=14826.11 +segment15nl=15221.23 +segment16nl=15797.4 +segment17nl=16622.16 +segment18nl=17535.46 +segment19nl=18179.78 +segment20nl=18390.00 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + +demandGrowthDEStart=1 +demandGrowthDEMin=0.98 +demandGrowthDETop=1.00 +demandGrowthDEMax=1.03 + +demandGrowthNLStart=1 +demandGrowthNLMin=0.99 +demandGrowthNLTop=1.02 +demandGrowthNLMax=1.05 + +startCash=5e9 +priceMarkUp=1.1 + +co2TradingImplemented=true +simulationLength=50 + +interconnectorCapacity=3000 + +investmentFutureTimeHorizon=7 + +numberOfYearsBacklookingForForecasting=5 + +simpleCapacityMarketEnabled=true +capacityMarketPriceCap=58940 +reserveMargin=0.156 +reserveDemandLowerMargin=0.025 +reserveDemandUpperMargin=0.025 diff --git a/emlab-generation/src/main/resources/scenarios/parametersE-MinCO2-resTarget-CM.properties.orig b/emlab-generation/src/main/resources/scenarios/parametersE-MinCO2-resTarget-CM.properties.orig new file mode 100644 index 00000000..15d9b350 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/parametersE-MinCO2-resTarget-CM.properties.orig @@ -0,0 +1,139 @@ +#------------------------------------------------------------------------------- +# 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. +#------------------------------------------------------------------------------- +coalPriceStart=100.8629923136 +#coalPriceStart=86.300754753 +#coalPriceStart=50.0 +#coalPriceMin=0.96 +coalPriceMin=0.9707458246 +#coalPriceTop=1.00 +coalPriceTop=1.0107458246 +#coalPriceMax=1.04 +coalPriceMax=1.0507458246 + +gasPriceStart=0.3246874961 +#gasPriceStart=0.2286412084 +#gasPriceMin=0.95 +gasPriceMin=0.9446627902 +#gasPriceTop=1.01 +gasPriceTop=1.0146627902 +#gasPriceMax=1.07 +gasPriceMax=1.0846627902 + +biomassPriceStart=112.5 +#biomassPriceMin=0.95 +biomassPriceMin=0.97 +#biomassPriceTop=1.01 +biomassPriceTop=1.01 +#biomassPriceMax=1.05 +biomassPriceMax=1.05 + +uraniumPriceStart=5000000 +uraniumPriceMin=1.00 +#uraniumPriceMax=1.02 +uraniumPriceMax=1.02 +#uraniumPriceTop=1.01 +uraniumPriceTop=1.01 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +co2CapStart=351.75e6 +co2CapIncrement=-6.120624e6 +#co2CapIncrement=0 +co2CapDuration=1 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +minCo2DEPriceStart=25 +minCo2DEPriceIncrement=1.5 +minCo2DEPriceDuration=1 + +minCo2NLPriceStart=25 +minCo2NLPriceIncrement=1.5 +minCo2NLPriceDuration=1 + +segment1nl=8160.778 +segment2nl=8390.36 +segment3nl=8961.656 +segment4nl=9448.219 +segment5nl=9828.25 +segment6nl=10333.58 +segment7nl=10887.66 +segment8nl=11438.97 +segment9nl=11957.73 +segment10nl=12498.55 +segment11nl=13155.53 +segment12nl=13819.34 +segment13nl=14395.3 +segment14nl=14826.11 +segment15nl=15221.23 +segment16nl=15797.4 +segment17nl=16622.16 +segment18nl=17535.46 +segment19nl=18179.78 +segment20nl=18390.00 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + +demandGrowthDEStart=1 +demandGrowthDEMin=0.98 +demandGrowthDETop=1.00 +demandGrowthDEMax=1.03 + +demandGrowthNLStart=1 +demandGrowthNLMin=0.99 +demandGrowthNLTop=1.02 +demandGrowthNLMax=1.05 + +startCash=5e9 +priceMarkUp=1.1 + +co2TradingImplemented=true +simulationLength=50 + +interconnectorCapacity=3000 + +investmentFutureTimeHorizon=7 + +numberOfYearsBacklookingForForecasting=5 + +simpleCapacityMarketEnabled=true +capacityMarketPriceCap=58940 +reserveMargin=0.156 +reserveDemandLowerMargin=0.025 +reserveDemandUpperMargin=0.025 diff --git a/emlab-generation/src/main/resources/scenarios/parametersE-WithCSVFileReader.properties.orig b/emlab-generation/src/main/resources/scenarios/parametersE-WithCSVFileReader.properties.orig new file mode 100644 index 00000000..e69de29b diff --git a/emlab-generation/src/main/resources/scenarios/parametersE-WithCSVFileReader.properties~HEAD b/emlab-generation/src/main/resources/scenarios/parametersE-WithCSVFileReader.properties~HEAD new file mode 100644 index 00000000..118dbf8b --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/parametersE-WithCSVFileReader.properties~HEAD @@ -0,0 +1,116 @@ +coalPriceStart=100.8629923136 +#coalPriceStart=86.300754753 +#coalPriceStart=50.0 +#coalPriceMin=0.96 +coalPriceMin=0.9707458246 +#coalPriceTop=1.00 +coalPriceTop=1.0107458246 +#coalPriceMax=1.04 +coalPriceMax=1.0507458246 + +gasPriceStart=0.3246874961 +#gasPriceStart=0.2286412084 +#gasPriceMin=0.95 +gasPriceMin=0.9446627902 +#gasPriceTop=1.01 +gasPriceTop=1.0146627902 +#gasPriceMax=1.07 +gasPriceMax=1.0846627902 + +biomassPriceStart=112.5 +#biomassPriceMin=0.95 +biomassPriceMin=0.97 +#biomassPriceTop=1.01 +biomassPriceTop=1.01 +#biomassPriceMax=1.05 +biomassPriceMax=1.05 + +uraniumPriceStart=5000000 +uraniumPriceMin=1.00 +#uraniumPriceMax=1.02 +uraniumPriceMax=1.02 +#uraniumPriceTop=1.01 +uraniumPriceTop=1.01 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +co2CapStart=351.75e6 +co2CapIncrement=-6.120624e6 +#co2CapIncrement=0 +co2CapDuration=1 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +minCo2DEPriceStart=0 +minCo2DEPriceIncrement=0 +minCo2DEPriceDuration=1 + +minCo2NLPriceStart=0 +minCo2NLPriceIncrement=0 +minCo2NLPriceDuration=1 + +segment1nl=8160.778 +segment2nl=8390.36 +segment3nl=8961.656 +segment4nl=9448.219 +segment5nl=9828.25 +segment6nl=10333.58 +segment7nl=10887.66 +segment8nl=11438.97 +segment9nl=11957.73 +segment10nl=12498.55 +segment11nl=13155.53 +segment12nl=13819.34 +segment13nl=14395.3 +segment14nl=14826.11 +segment15nl=15221.23 +segment16nl=15797.4 +segment17nl=16622.16 +segment18nl=17535.46 +segment19nl=18179.78 +segment20nl=18390.00 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + +demandGrowthDEStart=1 +demandGrowthDEMin=0.99 +demandGrowthDETop=1.02 +demandGrowthDEMax=1.05 + +demandGrowthNLStart=1 +demandGrowthNLMin=0.99 +demandGrowthNLTop=1.02 +demandGrowthNLMax=1.05 + +startCash=3e9 +priceMarkUp=1.1 + +co2TradingImplemented=true +simulationLength=40 + +interconnectorCapacity=3000 + +investmentFutureTimeHorizon=7 diff --git a/emlab-generation/src/main/resources/scenarios/parametersE-WithCSVFileReader.properties~Jorn_feature_historicalCVar b/emlab-generation/src/main/resources/scenarios/parametersE-WithCSVFileReader.properties~Jorn_feature_historicalCVar new file mode 100644 index 00000000..118dbf8b --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/parametersE-WithCSVFileReader.properties~Jorn_feature_historicalCVar @@ -0,0 +1,116 @@ +coalPriceStart=100.8629923136 +#coalPriceStart=86.300754753 +#coalPriceStart=50.0 +#coalPriceMin=0.96 +coalPriceMin=0.9707458246 +#coalPriceTop=1.00 +coalPriceTop=1.0107458246 +#coalPriceMax=1.04 +coalPriceMax=1.0507458246 + +gasPriceStart=0.3246874961 +#gasPriceStart=0.2286412084 +#gasPriceMin=0.95 +gasPriceMin=0.9446627902 +#gasPriceTop=1.01 +gasPriceTop=1.0146627902 +#gasPriceMax=1.07 +gasPriceMax=1.0846627902 + +biomassPriceStart=112.5 +#biomassPriceMin=0.95 +biomassPriceMin=0.97 +#biomassPriceTop=1.01 +biomassPriceTop=1.01 +#biomassPriceMax=1.05 +biomassPriceMax=1.05 + +uraniumPriceStart=5000000 +uraniumPriceMin=1.00 +#uraniumPriceMax=1.02 +uraniumPriceMax=1.02 +#uraniumPriceTop=1.01 +uraniumPriceTop=1.01 + +co2TaxStart=0 +co2TaxIncrement=0 +co2TaxDuration=5 + +co2CapStart=351.75e6 +co2CapIncrement=-6.120624e6 +#co2CapIncrement=0 +co2CapDuration=1 + +minCo2EUPriceStart=0 +minCo2EUPriceIncrement=0 +minCo2PriceDuration=1 + +minCo2DEPriceStart=0 +minCo2DEPriceIncrement=0 +minCo2DEPriceDuration=1 + +minCo2NLPriceStart=0 +minCo2NLPriceIncrement=0 +minCo2NLPriceDuration=1 + +segment1nl=8160.778 +segment2nl=8390.36 +segment3nl=8961.656 +segment4nl=9448.219 +segment5nl=9828.25 +segment6nl=10333.58 +segment7nl=10887.66 +segment8nl=11438.97 +segment9nl=11957.73 +segment10nl=12498.55 +segment11nl=13155.53 +segment12nl=13819.34 +segment13nl=14395.3 +segment14nl=14826.11 +segment15nl=15221.23 +segment16nl=15797.4 +segment17nl=16622.16 +segment18nl=17535.46 +segment19nl=18179.78 +segment20nl=18390.00 + +segment1de=35311.89 +segment2de=36657.44 +segment3de=40401.68 +segment4de=43606.1 +segment5de=45600.58 +segment6de=47414.54 +segment7de=49337.31 +segment8de=51439.43 +segment9de=53771.93 +segment10de=56143.54 +segment11de=58402.19 +segment12de=60234.9 +segment13de=61923.03 +segment14de=63697.04 +segment15de=65580.2 +segment16de=67797.75 +segment17de=71192.97 +segment18de=75390.2 +segment19de=77408.11 +segment20de=79884 + +demandGrowthDEStart=1 +demandGrowthDEMin=0.99 +demandGrowthDETop=1.02 +demandGrowthDEMax=1.05 + +demandGrowthNLStart=1 +demandGrowthNLMin=0.99 +demandGrowthNLTop=1.02 +demandGrowthNLMax=1.05 + +startCash=3e9 +priceMarkUp=1.1 + +co2TradingImplemented=true +simulationLength=40 + +interconnectorCapacity=3000 + +investmentFutureTimeHorizon=7 diff --git a/emlab-generation/src/main/resources/scenarios/scenarioA-Old-CM.xml b/emlab-generation/src/main/resources/scenarios/scenarioA-Old-CM.xml new file mode 100644 index 00000000..97e7c04e --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/scenarioA-Old-CM.xml @@ -0,0 +1,727 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.56 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.45 + + + + + + 0.20 + + + + + + 0.05 + + + + + + 0.20 + + + + + + 0.10 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/scenarioA-ToyModel.xml b/emlab-generation/src/main/resources/scenarios/scenarioA-ToyModel.xml deleted file mode 100644 index 6762448e..00000000 --- a/emlab-generation/src/main/resources/scenarios/scenarioA-ToyModel.xml +++ /dev/null @@ -1,463 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/emlab-generation/src/main/resources/scenarios/scenarioB-OneCountry-CapacityMarket.xml b/emlab-generation/src/main/resources/scenarios/scenarioB-OneCountry-CapacityMarket.xml new file mode 100644 index 00000000..1c2e3bab --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/scenarioB-OneCountry-CapacityMarket.xml @@ -0,0 +1,842 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/scenarioB-OneCountry-RES-CM.xml b/emlab-generation/src/main/resources/scenarios/scenarioB-OneCountry-RES-CM.xml new file mode 100644 index 00000000..f43e759a --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/scenarioB-OneCountry-RES-CM.xml @@ -0,0 +1,887 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/scenarioB-OneCountry-RES.xml b/emlab-generation/src/main/resources/scenarios/scenarioB-OneCountry-RES.xml new file mode 100644 index 00000000..bcac9f98 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/scenarioB-OneCountry-RES.xml @@ -0,0 +1,861 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/scenarioB-OneCountry.xml b/emlab-generation/src/main/resources/scenarios/scenarioB-OneCountry.xml index aabb1e89..ed4a69c2 100644 --- a/emlab-generation/src/main/resources/scenarios/scenarioB-OneCountry.xml +++ b/emlab-generation/src/main/resources/scenarios/scenarioB-OneCountry.xml @@ -117,7 +117,7 @@ + p:referencePrice="40" p:valueOfLostLoad="2000" p:lookback="5" p:backlookingForDemandForecastinginDismantling="5"> diff --git a/emlab-generation/src/main/resources/scenarios/scenarioB-ThermalMixDE.xml b/emlab-generation/src/main/resources/scenarios/scenarioB-ThermalMixDE-CapacityMarket.xml similarity index 96% rename from emlab-generation/src/main/resources/scenarios/scenarioB-ThermalMixDE.xml rename to emlab-generation/src/main/resources/scenarios/scenarioB-ThermalMixDE-CapacityMarket.xml index c318d2be..99fcc101 100644 --- a/emlab-generation/src/main/resources/scenarios/scenarioB-ThermalMixDE.xml +++ b/emlab-generation/src/main/resources/scenarios/scenarioB-ThermalMixDE-CapacityMarket.xml @@ -27,9 +27,26 @@ p:co2TradingImplemented="false" p:realRenewableDataImplemented="false" p:iterationSpeedFactor="3" p:iterationSpeedCriterion="0.005" p:capDeviationCriterion="0.03" + p:simpleCapacityMarketEnabled="${simpleCapacityMarketEnabled}" p:deletionOldPPDPBidsAndCashFlowsEnabled="true" p:deletionAge="4"> + + + + + + + + + + + @@ -312,6 +329,7 @@ + value="classpath:scenarios/parametersB-OneCountry-CapacityMarket.properties" /> - + \ No newline at end of file diff --git a/emlab-generation/src/main/resources/scenarios/scenarioC-ETS-CM-de.xml b/emlab-generation/src/main/resources/scenarios/scenarioC-ETS-CM-de.xml new file mode 100644 index 00000000..330dde60 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/scenarioC-ETS-CM-de.xml @@ -0,0 +1,1479 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1436 + + + + + + 0.1931 + + + + + + 0.1071 + + + + + + 0.0851 + + + + + + 0.0302 + + + + + + 0.072376 + + + + + + 0.1725 + + + + + + 0.1453 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/scenarioC-ETS-CM-de.xml.orig b/emlab-generation/src/main/resources/scenarios/scenarioC-ETS-CM-de.xml.orig new file mode 100644 index 00000000..330dde60 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/scenarioC-ETS-CM-de.xml.orig @@ -0,0 +1,1479 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1436 + + + + + + 0.1931 + + + + + + 0.1071 + + + + + + 0.0851 + + + + + + 0.0302 + + + + + + 0.072376 + + + + + + 0.1725 + + + + + + 0.1453 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/scenarioC-MinCO2-CM.xml b/emlab-generation/src/main/resources/scenarios/scenarioC-MinCO2-CM.xml new file mode 100644 index 00000000..4ae52e90 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/scenarioC-MinCO2-CM.xml @@ -0,0 +1,1471 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1436 + + + + + + 0.1931 + + + + + + 0.1071 + + + + + + 0.0851 + + + + + + 0.0302 + + + + + + 0.072376 + + + + + + 0.1725 + + + + + + 0.1453 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/scenarioE-WithCSVFileReader-CalculationUK-CWE.xml.orig b/emlab-generation/src/main/resources/scenarios/scenarioE-WithCSVFileReader-CalculationUK-CWE.xml.orig new file mode 100644 index 00000000..e69de29b diff --git a/emlab-generation/src/main/resources/scenarios/scenarioE-WithCSVFileReader-CalculationUK-CWE.xml~HEAD b/emlab-generation/src/main/resources/scenarios/scenarioE-WithCSVFileReader-CalculationUK-CWE.xml~HEAD new file mode 100644 index 00000000..682b6313 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/scenarioE-WithCSVFileReader-CalculationUK-CWE.xml~HEAD @@ -0,0 +1,1558 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1436 + + + + + + 0.1931 + + + + + + 0.1071 + + + + + + 0.0851 + + + + + + 0.0302 + + + + + + 0.072376 + + + + + + 0 + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/scenarioE-WithCSVFileReader-CalculationUK-CWE.xml~Jorn_feature_historicalCVar b/emlab-generation/src/main/resources/scenarios/scenarioE-WithCSVFileReader-CalculationUK-CWE.xml~Jorn_feature_historicalCVar new file mode 100644 index 00000000..682b6313 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/scenarioE-WithCSVFileReader-CalculationUK-CWE.xml~Jorn_feature_historicalCVar @@ -0,0 +1,1558 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1436 + + + + + + 0.1931 + + + + + + 0.1071 + + + + + + 0.0851 + + + + + + 0.0302 + + + + + + 0.072376 + + + + + + 0 + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/scenarioE-WithCSVFileReader.xml.orig b/emlab-generation/src/main/resources/scenarios/scenarioE-WithCSVFileReader.xml.orig new file mode 100644 index 00000000..e69de29b diff --git a/emlab-generation/src/main/resources/scenarios/scenarioE-WithCSVFileReader.xml~HEAD b/emlab-generation/src/main/resources/scenarios/scenarioE-WithCSVFileReader.xml~HEAD new file mode 100644 index 00000000..9d7c5dbf --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/scenarioE-WithCSVFileReader.xml~HEAD @@ -0,0 +1,1549 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1436 + + + + + + 0.1931 + + + + + + 0.1071 + + + + + + 0.0851 + + + + + + 0.0302 + + + + + + 0.072376 + + + + + + 0 + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/scenarioE-WithCSVFileReader.xml~Jorn_feature_historicalCVar b/emlab-generation/src/main/resources/scenarios/scenarioE-WithCSVFileReader.xml~Jorn_feature_historicalCVar new file mode 100644 index 00000000..9d7c5dbf --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/scenarioE-WithCSVFileReader.xml~Jorn_feature_historicalCVar @@ -0,0 +1,1549 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1436 + + + + + + 0.1931 + + + + + + 0.1071 + + + + + + 0.0851 + + + + + + 0.0302 + + + + + + 0.072376 + + + + + + 0 + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/scenarioU-MinCO2-resTargetwithCM.xml b/emlab-generation/src/main/resources/scenarios/scenarioU-MinCO2-resTargetwithCM.xml new file mode 100644 index 00000000..9180645e --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/scenarioU-MinCO2-resTargetwithCM.xml @@ -0,0 +1,1575 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1436 + + + + + + 0.1931 + + + + + + 0.1071 + + + + + + 0.0851 + + + + + + 0.0302 + + + + + + 0.072376 + + + + + + 0.1725 + + + + + + 0.1453 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/scenarioU-MinCO2-resTargetwithCM.xml.orig b/emlab-generation/src/main/resources/scenarios/scenarioU-MinCO2-resTargetwithCM.xml.orig new file mode 100644 index 00000000..9180645e --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/scenarioU-MinCO2-resTargetwithCM.xml.orig @@ -0,0 +1,1575 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.33 + + + + + + 0.40 + + + + + + 0.16 + + + + + + 0.01 + + + + + + 0.03 + + + + + + 0.07 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.1436 + + + + + + 0.1931 + + + + + + 0.1071 + + + + + + 0.0851 + + + + + + 0.0302 + + + + + + 0.072376 + + + + + + 0.1725 + + + + + + 0.1453 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/scenarioU-bothMin-resTarget-ecoDism.xml b/emlab-generation/src/main/resources/scenarios/scenarioU-bothMin-resTarget-ecoDism.xml new file mode 100644 index 00000000..5c7d5e58 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/scenarioU-bothMin-resTarget-ecoDism.xml @@ -0,0 +1,1652 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.123 + + + + + + 0.061 + + + + + + 0.134 + + + + + + 0.108 + + + + + + 0.008 + + + + + + 0.012 + + + + + + 0.080 + + + + + + 0.270 + + + + + + 0.107 + + + + + + 0.058 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.307 + + + + + + 0.262 + + + + + + 0.188 + + + + + + 0.0302 + + + + + + 0.119 + + + + + + 0.047 + + + + + + 0.0 + + + + + + 0.018 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/scenarios/scenarioU-bothMin-resTarget-ecoDism.xml.orig b/emlab-generation/src/main/resources/scenarios/scenarioU-bothMin-resTarget-ecoDism.xml.orig new file mode 100644 index 00000000..5c7d5e58 --- /dev/null +++ b/emlab-generation/src/main/resources/scenarios/scenarioU-bothMin-resTarget-ecoDism.xml.orig @@ -0,0 +1,1652 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.123 + + + + + + 0.061 + + + + + + 0.134 + + + + + + 0.108 + + + + + + 0.008 + + + + + + 0.012 + + + + + + 0.080 + + + + + + 0.270 + + + + + + 0.107 + + + + + + 0.058 + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0.307 + + + + + + 0.262 + + + + + + 0.188 + + + + + + 0.0302 + + + + + + 0.119 + + + + + + 0.047 + + + + + + 0.0 + + + + + + 0.018 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/main/resources/settings.xml b/emlab-generation/src/main/resources/settings.xml index ad7faa7d..4dceee5b 100644 --- a/emlab-generation/src/main/resources/settings.xml +++ b/emlab-generation/src/main/resources/settings.xml @@ -1,48 +1,48 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/emlab-generation/src/test/java/emlab/gen/domain/PowerPlantCSVFactoryTest.java b/emlab-generation/src/test/java/emlab/gen/domain/PowerPlantCSVFactoryTest.java index d71e5698..040d4377 100644 --- a/emlab-generation/src/test/java/emlab/gen/domain/PowerPlantCSVFactoryTest.java +++ b/emlab-generation/src/test/java/emlab/gen/domain/PowerPlantCSVFactoryTest.java @@ -151,14 +151,14 @@ public void testCSVReader() { + plant.getTechnology().getName() + ", Location: " + plant.getLocation().getName() + ", contructionStarted: " + plant.getConstructionStartTime() + ", Age: " - + -(plant.getConstructionStartTime() + plant.getActualLeadtime() + plant.getActualPermittime()) + + -(plant.getConstructionStartTime() + plant.getActualLeadTime() + plant.getActualPermittime()) + ", Cap: " + plant.getActualNominalCapacity() + ", Eff: " + plant.getActualEfficiency()); String name = plant.getName(); if (name.equals("Coal1")) { assertEquals("Correct tech", "coalPGT", plant.getTechnology().getName()); assertEquals("Correct location", "de", plant.getLocation().getName()); assertEquals("Correct age", 10, - -(plant.getConstructionStartTime() + plant.getActualLeadtime() + plant.getActualPermittime())); + -(plant.getConstructionStartTime() + plant.getActualLeadTime() + plant.getActualPermittime())); assertEquals("Correct capacity: ", 650.0, plant.getActualNominalCapacity(), 0.01); assertEquals("Correct efficiency: ", 0.3, plant.getActualEfficiency(), 0.01); assertEquals("Correct owner", "aon", plant.getOwner().getName()); @@ -167,7 +167,7 @@ public void testCSVReader() { assertEquals("Correct tech", "coalPGT", plant.getTechnology().getName()); assertEquals("Correct location", "nl", plant.getLocation().getName()); assertEquals("Correct age", 30, - -(plant.getConstructionStartTime() + plant.getActualLeadtime() + plant.getActualPermittime())); + -(plant.getConstructionStartTime() + plant.getActualLeadTime() + plant.getActualPermittime())); assertEquals("Correct capacity: ", 500, plant.getActualNominalCapacity(), 0.01); assertEquals("Correct efficiency: ", 0.37, plant.getActualEfficiency(), 0.01); assertEquals("Correct owner", "swe", plant.getOwner().getName()); @@ -176,7 +176,7 @@ public void testCSVReader() { assertEquals("Correct tech", "gasPGT", plant.getTechnology().getName()); assertEquals("Correct location", "nl", plant.getLocation().getName()); assertEquals("Correct age", 15, - -(plant.getConstructionStartTime() + plant.getActualLeadtime() + plant.getActualPermittime())); + -(plant.getConstructionStartTime() + plant.getActualLeadTime() + plant.getActualPermittime())); assertEquals("Correct capacity: ", 300, plant.getActualNominalCapacity(), 0.01); assertEquals("Correct efficiency: ", 0.3, plant.getActualEfficiency(), 0.01); assertEquals("Correct owner", "aon", plant.getOwner().getName()); @@ -185,7 +185,7 @@ public void testCSVReader() { assertEquals("Correct tech", "gasPGT", plant.getTechnology().getName()); assertEquals("Correct location", "de", plant.getLocation().getName()); assertEquals("Correct age", 3, - -(plant.getConstructionStartTime() + plant.getActualLeadtime() + plant.getActualPermittime())); + -(plant.getConstructionStartTime() + plant.getActualLeadTime() + plant.getActualPermittime())); assertEquals("Correct capacity: ", 300, plant.getActualNominalCapacity(), 0.01); assertEquals("Correct efficiency: ", 0.3, plant.getActualEfficiency(), 0.01); assertTrue("Correct owner", (plant.getOwner().getName().equals("aon") || plant.getOwner().getName() diff --git a/emlab-generation/src/test/java/emlab/gen/role/IntermittentElectricityMarketWithInterconnectorTest.java b/emlab-generation/src/test/java/emlab/gen/role/IntermittentElectricityMarketWithInterconnectorTest.java index e6ddfea7..eefc732f 100644 --- a/emlab-generation/src/test/java/emlab/gen/role/IntermittentElectricityMarketWithInterconnectorTest.java +++ b/emlab-generation/src/test/java/emlab/gen/role/IntermittentElectricityMarketWithInterconnectorTest.java @@ -709,10 +709,13 @@ public void electricityMarketTestWithALotRenewablesForCurrentTick() { assertEquals("CoalInM1 right amount", 700, plan.getAmount(), 0.001); switch (s.getSegmentID()) { case 1: + logger.warn("CoalInM1, S1 , " + plan.getAcceptedAmount()); assertEquals("CoalInM1 right accepted amount in S1", 700, plan.getAcceptedAmount(), 0.001); break; case 2: + logger.warn("CoalInM1, S2 , " + plan.getAcceptedAmount()); assertEquals("CoalInM1 right accepted amount in S2", 572.055, plan.getAcceptedAmount(), 0.001); + break; } } else if (plan.getPowerPlant().getName().equals("CoalInM2")) { assertEquals("CoalInM2 right price", 27, plan.getBidWithoutCO2(), 0.001); diff --git a/emlab-generation/src/test/java/emlab/gen/role/IntermittentElectricityMarketWithInterconnectorTest.java.orig b/emlab-generation/src/test/java/emlab/gen/role/IntermittentElectricityMarketWithInterconnectorTest.java.orig new file mode 100644 index 00000000..33446c29 --- /dev/null +++ b/emlab-generation/src/test/java/emlab/gen/role/IntermittentElectricityMarketWithInterconnectorTest.java.orig @@ -0,0 +1,890 @@ +package emlab.gen.role; + +import static org.junit.Assert.assertEquals; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +import emlab.gen.domain.agent.DecarbonizationModel; +import emlab.gen.domain.agent.EnergyProducer; +import emlab.gen.domain.agent.Government; +import emlab.gen.domain.agent.NationalGovernment; +import emlab.gen.domain.contract.Loan; +import emlab.gen.domain.gis.Zone; +import emlab.gen.domain.market.CO2Auction; +import emlab.gen.domain.market.ClearingPoint; +import emlab.gen.domain.market.CommodityMarket; +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.SegmentClearingPoint; +import emlab.gen.domain.market.electricity.SegmentLoad; +import emlab.gen.domain.technology.Interconnector; +import emlab.gen.domain.technology.IntermittentResourceProfile; +import emlab.gen.domain.technology.PowerGeneratingTechnology; +import emlab.gen.domain.technology.PowerGridNode; +import emlab.gen.domain.technology.PowerPlant; +import emlab.gen.domain.technology.Substance; +import emlab.gen.repository.BidRepository; +import emlab.gen.repository.MarketRepository; +import emlab.gen.repository.PowerPlantDispatchPlanRepository; +import emlab.gen.repository.Reps; +import emlab.gen.repository.SegmentLoadRepository; +import emlab.gen.repository.ZoneRepository; +import emlab.gen.role.market.ClearIterativeCO2AndElectricitySpotMarketTwoCountryRole; +import emlab.gen.role.market.DetermineResidualLoadCurvesForTwoCountriesRole; +import emlab.gen.role.market.SubmitOffersToElectricitySpotMarketRole; +import emlab.gen.role.operating.DetermineFuelMixRole; +import emlab.gen.trend.HourlyCSVTimeSeries; +import emlab.gen.trend.LinearTrend; +import emlab.gen.trend.TriangularTrend; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration({ "/emlab-gen-test-context.xml" }) +@Transactional +public class IntermittentElectricityMarketWithInterconnectorTest { + + Logger logger = Logger.getLogger(RenewableTargetInvestmentRoleTest.class); + + @Autowired + Reps reps; + + @Autowired + SegmentLoadRepository segmentLoadRepository; + + @Autowired + MarketRepository marketRepository; + + @Autowired + BidRepository bidRepository; + + @Autowired + PowerPlantDispatchPlanRepository plantDispatchPlanRepository; + + @Autowired + ZoneRepository zoneRepository; + + @Autowired + ClearIterativeCO2AndElectricitySpotMarketTwoCountryRole clearIterativeCO2AndElectricitySpotMarketTwoCountryRole; + + @Autowired + SubmitOffersToElectricitySpotMarketRole submitOffersToElectricitySpotMarketRole; + + @Autowired + DetermineFuelMixRole determineFuelMixRole; + + @Autowired + DetermineResidualLoadCurvesForTwoCountriesRole determineResidualLoadCurvesForTwoCountriesRole; + + // 6 power plants in two markets, one intermittent power plant in each. + @Before + @Transactional + public void setUp() throws Exception { + DecarbonizationModel model = new DecarbonizationModel(); + model.setCo2TradingImplemented(false); + model.setRealRenewableDataImplemented(false); + model.setIterationSpeedFactor(3); + model.setIterationSpeedCriterion(0.005); + model.setCapDeviationCriterion(0.03); + model.persist(); + + Government gov = new Government().persist(); + LinearTrend co2TaxTrend = new LinearTrend().persist(); + co2TaxTrend.setStart(0); + co2TaxTrend.setIncrement(0); + gov.setCo2TaxTrend(co2TaxTrend); + +<<<<<<< HEAD + CO2Auction co2Auction = new CO2Auction().persist(); + +======= + + + CO2Auction co2Auction = new CO2Auction().persist(); + + + +>>>>>>> Jorn/feature/historicalCVar + Zone zone1 = new Zone(); + Zone zone2 = new Zone(); + zone1.setName("Zone 1"); + + zone2.setName("Zone2"); + + zone1.persist(); + zone2.persist(); + + NationalGovernment natGov1 = new NationalGovernment().persist(); + NationalGovernment natGov2 = new NationalGovernment().persist(); + + natGov1.setGovernedZone(zone1); + natGov2.setGovernedZone(zone2); + + LinearTrend minCo2TaxTrend1 = new LinearTrend().persist(); + minCo2TaxTrend1.setStart(0); + minCo2TaxTrend1.setIncrement(0); + natGov1.setMinNationalCo2PriceTrend(minCo2TaxTrend1); + + LinearTrend minCo2TaxTrend2 = new LinearTrend().persist(); + minCo2TaxTrend2.setStart(0); + minCo2TaxTrend2.setIncrement(0); + natGov2.setMinNationalCo2PriceTrend(minCo2TaxTrend2); + + HourlyCSVTimeSeries load1TimeSeries = new HourlyCSVTimeSeries(); + load1TimeSeries.setFilename("/data/ZoneALoad.csv"); + + HourlyCSVTimeSeries load2TimeSeries = new HourlyCSVTimeSeries(); + load2TimeSeries.setFilename("/data/ZoneBLoad.csv"); + + load1TimeSeries.persist(); + load2TimeSeries.persist(); + + PowerGridNode node1 = new PowerGridNode(); + PowerGridNode node2 = new PowerGridNode(); + node1.setCapacityMultiplicationFactor(1); + node2.setCapacityMultiplicationFactor(1); + node1.setZone(zone1); + node2.setZone(zone2); + node1.setName("Node1"); + node2.setName("Node2"); + node1.setHourlyDemand(load1TimeSeries); + node2.setHourlyDemand(load2TimeSeries); + node1.persist(); + node2.persist(); + + HashSet intNodes = new HashSet(); + intNodes.add(node1); + intNodes.add(node2); + + Interconnector interconnector = new Interconnector().persist(); + interconnector.setConnections(intNodes); + interconnector.setCapacity(100); + + Segment S1 = new Segment(); + S1.setLengthInHours(10); + S1.setSegmentID(1); + S1.persist(); + + Segment S2 = new Segment(); + S2.setLengthInHours(20); + S2.setSegmentID(2); + S2.persist(); + + SegmentLoad segmentLoadMarket1S2 = new SegmentLoad().persist(); + segmentLoadMarket1S2.setSegment(S2); + // segmentLoadMarket1S2.setBaseLoad(500.01); + + SegmentLoad segmentLoadMarket2S2 = new SegmentLoad().persist(); + segmentLoadMarket2S2.setSegment(S2); + // segmentLoadMarket2S2.setBaseLoad(399.99); + + SegmentLoad segmentLoadMarket1S1 = new SegmentLoad().persist(); + segmentLoadMarket1S1.setSegment(S1); + // segmentLoadMarket1S1.setBaseLoad(790); + + SegmentLoad segmentLoadMarket2S1 = new SegmentLoad().persist(); + segmentLoadMarket2S1.setSegment(S1); + // segmentLoadMarket2S1.setBaseLoad(600); + + Set segmentLoads1 = new HashSet(); + segmentLoads1.add(segmentLoadMarket1S1); + segmentLoads1.add(segmentLoadMarket1S2); + + Set segmentLoads2 = new HashSet(); + segmentLoads2.add(segmentLoadMarket2S1); + segmentLoads2.add(segmentLoadMarket2S2); + + TriangularTrend demandGrowthTrend = new TriangularTrend(); + demandGrowthTrend.setMax(1); + demandGrowthTrend.setMin(1); + demandGrowthTrend.setStart(1); + demandGrowthTrend.setTop(1); + + demandGrowthTrend.persist(); + + ElectricitySpotMarket market1 = new ElectricitySpotMarket(); + market1.setName("Market1"); + market1.setZone(zone1); + market1.setLoadDurationCurve(segmentLoads1); + market1.setDemandGrowthTrend(demandGrowthTrend); + market1.setValueOfLostLoad(2000); + market1.persist(); + + ElectricitySpotMarket market2 = new ElectricitySpotMarket(); + market2.setZone(zone2); + market2.setName("Market2"); + market2.setLoadDurationCurve(segmentLoads2); + market2.setDemandGrowthTrend(demandGrowthTrend); + market2.setValueOfLostLoad(2000); + market2.persist(); + + Substance coal = new Substance().persist(); + coal.setName("Coal"); + coal.setEnergyDensity(1000); + Substance gas = new Substance().persist(); + gas.setName("Gas"); + gas.setEnergyDensity(1000); + +<<<<<<< HEAD + CommodityMarket coalMarket = new CommodityMarket().persist(); +======= + CommodityMarket coalMarket = new CommodityMarket().persist(); +>>>>>>> Jorn/feature/historicalCVar + CommodityMarket gasMarket = new CommodityMarket().persist(); + + coalMarket.setSubstance(coal); + gasMarket.setSubstance(gas); + + LinearTrend coalPrice = new LinearTrend().persist(); + coalPrice.setStart(3); + coalPrice.setIncrement(1); + + LinearTrend gasPrice = new LinearTrend().persist(); + gasPrice.setStart(6); + coalPrice.setIncrement(2); + + HashSet fuelMixCoal = new HashSet(); + fuelMixCoal.add(coal); + + HashSet fuelMixGas = new HashSet(); + fuelMixGas.add(gas); + +<<<<<<< HEAD +======= + +>>>>>>> Jorn/feature/historicalCVar + PowerGeneratingTechnology coalTech = new PowerGeneratingTechnology(); + coalTech.setFuels(fuelMixCoal); + coalTech.setPeakSegmentDependentAvailability(1); + coalTech.setBaseSegmentDependentAvailability(1); + + PowerGeneratingTechnology gasTech = new PowerGeneratingTechnology(); + gasTech.setFuels(fuelMixGas); + gasTech.setPeakSegmentDependentAvailability(1); + gasTech.setBaseSegmentDependentAvailability(1); + + PowerGeneratingTechnology windTech = new PowerGeneratingTechnology(); + windTech.setName("WindTech"); + windTech.setIntermittent(true); + +<<<<<<< HEAD +======= + +>>>>>>> Jorn/feature/historicalCVar + coalTech.persist(); + gasTech.persist(); + windTech.persist(); + + IntermittentResourceProfile windIntermittentResourceProfile1 = new IntermittentResourceProfile(); + windIntermittentResourceProfile1.setIntermittentTechnology(windTech); + windIntermittentResourceProfile1.setIntermittentProductionNode(node1); + windIntermittentResourceProfile1.setFilename("/data/ResLFA.csv"); + + IntermittentResourceProfile windIntermittentResourceProfile2 = new IntermittentResourceProfile(); + windIntermittentResourceProfile2.setIntermittentTechnology(windTech); + windIntermittentResourceProfile2.setIntermittentProductionNode(node2); + windIntermittentResourceProfile2.setFilename("/data/ResLFB.csv"); + + windIntermittentResourceProfile1.persist(); + windIntermittentResourceProfile2.persist(); + + EnergyProducer market1Prod1 = new EnergyProducer(); + market1Prod1.setName("market1Prod1"); + market1Prod1.setCash(0); + market1Prod1.setPriceMarkUp(1); + market1Prod1.setInvestorMarket(market1); + + EnergyProducer market1Prod2 = new EnergyProducer(); + market1Prod2.setCash(0); + market1Prod2.setPriceMarkUp(1); + market1Prod2.setName("market1Prod2"); + market1Prod2.setInvestorMarket(market1); + + EnergyProducer market2Prod1 = new EnergyProducer(); + market2Prod1.setCash(0); + market2Prod1.setPriceMarkUp(1); + market2Prod1.setName("market2Prod1"); + market2Prod1.setInvestorMarket(market2); + + EnergyProducer market2Prod2 = new EnergyProducer(); + market2Prod2.setCash(0); + market2Prod2.setPriceMarkUp(1); + market2Prod2.setName("market2Prod2"); + market2Prod2.setInvestorMarket(market2); + + market1Prod1.persist(); + market1Prod2.persist(); + market2Prod1.persist(); + + Loan l1 = new Loan(); + l1.setAmountPerPayment(6000); + l1.setNumberOfPaymentsDone(10); + l1.setTotalNumberOfPayments(15); + + Loan l2 = new Loan(); + l2.setAmountPerPayment(5000); + l2.setNumberOfPaymentsDone(29); + l2.setTotalNumberOfPayments(19); + + Loan l3 = new Loan(); + l3.setAmountPerPayment(4000); + l3.setNumberOfPaymentsDone(8); + l3.setTotalNumberOfPayments(13); + + Loan l4 = new Loan(); + l4.setAmountPerPayment(3000); + l4.setNumberOfPaymentsDone(7); + l4.setTotalNumberOfPayments(12); + + Loan l5 = new Loan(); + l5.setAmountPerPayment(2000); + l5.setNumberOfPaymentsDone(6); + l5.setTotalNumberOfPayments(11); + + Loan l6 = new Loan(); + l6.setAmountPerPayment(1000); + l6.setNumberOfPaymentsDone(5); + l6.setTotalNumberOfPayments(10); + + l1.persist(); + l2.persist(); + l3.persist(); + l4.persist(); + l5.persist(); + l6.persist(); + + // At 3 Eur/GJ has a mc of 24 Eur/Mwh + PowerPlant pp1 = new PowerPlant(); + pp1.setTechnology(coalTech); + pp1.setOwner(market1Prod1); + pp1.setActualFixedOperatingCost(99000); + pp1.setLoan(l1); + pp1.setActualNominalCapacity(700); + pp1.setActualEfficiency(0.45); + pp1.setLocation(node1); + pp1.setActualPermittime(0); + pp1.setConstructionStartTime(-2); + pp1.setActualLeadtime(0); + pp1.setDismantleTime(10); + pp1.setExpectedEndOfLife(10); + pp1.setName("CoalInM1"); + + // At 3 Eur/GJ has a mc of 27 Eur/MWh + PowerPlant pp2 = new PowerPlant(); + pp2.setTechnology(coalTech); + pp2.setOwner(market2Prod1); + pp2.setActualFixedOperatingCost(99000); + pp2.setLoan(l2); + pp2.setActualNominalCapacity(1300); + pp2.setActualEfficiency(0.40); + pp2.setLocation(node2); + pp2.setActualPermittime(0); + pp2.setConstructionStartTime(-2); + pp2.setActualLeadtime(0); + pp2.setDismantleTime(10); + pp2.setExpectedEndOfLife(10); + pp2.setName("CoalInM2"); + + // At 6 Eur/GJ has a mc of 36 + PowerPlant pp3 = new PowerPlant(); + pp3.setTechnology(gasTech); + pp3.setOwner(market1Prod1); + pp3.setActualFixedOperatingCost(99000); + pp3.setLoan(l3); + pp3.setActualNominalCapacity(650); + pp3.setActualEfficiency(0.60); + pp3.setLocation(node1); + pp3.setActualPermittime(0); + pp3.setConstructionStartTime(-2); + pp3.setActualLeadtime(0); + pp3.setDismantleTime(1000); + pp3.setExpectedEndOfLife(2); + pp3.setName("GasInM1"); + + // At 6 Eur/GJ has a mc of 40 Eur/MWh + PowerPlant pp4 = new PowerPlant(); + pp4.setTechnology(gasTech); + pp4.setOwner(market2Prod2); + pp4.setActualFixedOperatingCost(99000); + pp4.setLoan(l3); + pp4.setActualNominalCapacity(1000); + pp4.setActualEfficiency(0.54); + pp4.setLocation(node2); + pp4.setActualPermittime(0); + pp4.setConstructionStartTime(-2); + pp4.setActualLeadtime(0); + pp4.setDismantleTime(10); + pp4.setExpectedEndOfLife(10); + pp4.setName("GasInM2"); + + pp1.persist(); + pp2.persist(); + pp3.persist(); + pp4.persist(); + + // At 6 Eur/GJ has a mc of 36 + PowerPlant ppRes1 = new PowerPlant(); + ppRes1.setTechnology(windTech); + ppRes1.setOwner(market1Prod1); + ppRes1.setActualFixedOperatingCost(99000); + ppRes1.setLoan(l5); + ppRes1.setActualNominalCapacity(500); + ppRes1.setActualEfficiency(1); + ppRes1.setLocation(node1); + ppRes1.setActualPermittime(0); + ppRes1.setConstructionStartTime(-8); + ppRes1.setActualLeadtime(0); + ppRes1.setDismantleTime(1000); + ppRes1.setExpectedEndOfLife(2); + ppRes1.setName("WindInM1"); + + // At 6 Eur/GJ has a mc of 40 Eur/MWh + PowerPlant ppRes2 = new PowerPlant(); + ppRes2.setTechnology(windTech); + ppRes2.setOwner(market2Prod2); + ppRes2.setActualFixedOperatingCost(99000); + ppRes2.setLoan(l6); + ppRes2.setActualNominalCapacity(1200); + ppRes2.setActualEfficiency(1); + ppRes2.setLocation(node2); + ppRes2.setActualPermittime(0); + ppRes2.setConstructionStartTime(-6); + ppRes2.setActualLeadtime(0); + ppRes2.setDismantleTime(10); + ppRes2.setExpectedEndOfLife(10); + ppRes2.setName("WindInM2"); + + ppRes1.persist(); + ppRes2.persist(); + + ClearingPoint coalClearingPoint = new ClearingPoint().persist(); + coalClearingPoint.setAbstractMarket(coalMarket); + coalClearingPoint.setTime(0); + coalClearingPoint.setPrice(3); + coalClearingPoint.setVolume(1000); + coalClearingPoint.setForecast(false); + + ClearingPoint gasClearingPoint = new ClearingPoint().persist(); + gasClearingPoint.setAbstractMarket(gasMarket); + gasClearingPoint.setTime(0); + gasClearingPoint.setPrice(6); + gasClearingPoint.setVolume(1000); + gasClearingPoint.setForecast(false); + + } + + // @Test + public void electricityMarketTestForCurrentTick() { + + DecarbonizationModel model = reps.genericRepository.findFirst(DecarbonizationModel.class); + +<<<<<<< HEAD +======= + +>>>>>>> Jorn/feature/historicalCVar + determineResidualLoadCurvesForTwoCountriesRole.act(model); + + for (SegmentLoad segmentLoad : reps.segmentLoadRepository.findAll()) { + if (segmentLoad.getElectricitySpotMarket().getName() == "Market1") { + switch (segmentLoad.getSegment().getSegmentID()) { + case 1: + assertEquals("SegmentLoad Market 1, Segment 1", 1156.95, segmentLoad.getBaseLoad(), 0.001); + break; + case 2: + assertEquals("SegmentLoad Market 1, Segment 2", 718.95, segmentLoad.getBaseLoad(), 0.001); + break; + } + } else if (segmentLoad.getElectricitySpotMarket().getName() == "Market2") { + switch (segmentLoad.getSegment().getSegmentID()) { + case 1: + assertEquals("SegmentLoad Market 2, Segment 1", 2313.9, segmentLoad.getBaseLoad(), 0.001); + break; + case 2: + assertEquals("SegmentLoad Market 2, Segment 2", 1437.9, segmentLoad.getBaseLoad(), 0.001); + break; + } + } + } + + for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) { + determineFuelMixRole.act(producer); + submitOffersToElectricitySpotMarketRole.act(producer); + producer.act(determineFuelMixRole); + } + +<<<<<<< HEAD +======= + +>>>>>>> Jorn/feature/historicalCVar + // submitOffersToElectricitySpotMarketRole + // .createOffersForElectricitySpotMarket(null, getCurrentTick(), true, + // null); + // submitOffersToElectricitySpotMarketRole.createOffersForElectricitySpotMarket(null, + // getCurrentTick(), false, + // null); + + clearIterativeCO2AndElectricitySpotMarketTwoCountryRole +<<<<<<< HEAD + .clearIterativeCO2AndElectricitySpotMarketTwoCountryForTimestepAndFuelPrices(model, false, + getCurrentTick(), null, null, 0); + + // Check that + for (PowerPlant plant : reps.powerPlantRepository.findAll()) { + for (Segment s : reps.segmentRepository.findAll()) { + PowerPlantDispatchPlan plan = reps.powerPlantDispatchPlanRepository + .findOnePowerPlantDispatchPlanForPowerPlantForSegmentForTime(plant, s, 0, false); + if (plan.getPowerPlant().getName().equals("CoalInM1")) { +======= + .clearIterativeCO2AndElectricitySpotMarketTwoCountryForTimestepAndFuelPrices(model, false, + getCurrentTick(), null, null, 0); + + + //Check that + for (PowerPlant plant : reps.powerPlantRepository.findAll()) { + for(Segment s : reps.segmentRepository.findAll()){ + PowerPlantDispatchPlan plan = reps.powerPlantDispatchPlanRepository + .findOnePowerPlantDispatchPlanForPowerPlantForSegmentForTime(plant, s, 0, false); + if(plan.getPowerPlant().getName().equals("CoalInM1")){ +>>>>>>> Jorn/feature/historicalCVar + assertEquals("CoalInM1 right price", 24, plan.getBidWithoutCO2(), 0.001); + assertEquals("CoalInM1 right amount", 700, plan.getAmount(), 0.001); + switch (s.getSegmentID()) { + case 1: + assertEquals("CoalInM1 right accepted amount in S1", 700, plan.getAcceptedAmount(), 0.001); + break; + case 2: + assertEquals("CoalInM1 right accepted amount in S2", 700, plan.getAcceptedAmount(), 0.001); + } + break; +<<<<<<< HEAD + } else if (plan.getPowerPlant().getName().equals("CoalInM2")) { +======= + } else if(plan.getPowerPlant().getName().equals("CoalInM2")){ +>>>>>>> Jorn/feature/historicalCVar + assertEquals("CoalInM2 right price", 27, plan.getBidWithoutCO2(), 0.001); + assertEquals("CoalInM2 right amount", 1300, plan.getAmount(), 0.001); + switch (s.getSegmentID()) { + case 1: + assertEquals("CoalInM2 right accepted amount in S1", 1300, plan.getAcceptedAmount(), 0.001); + break; + case 2: + assertEquals("CoalInM2 right accepted amount in S2", 1263.681, plan.getAcceptedAmount(), 0.001); + break; + } + } else if (plan.getPowerPlant().getName().equals("GasInM1")) { + assertEquals("GasInM1 right price", 36, plan.getBidWithoutCO2(), 0.001); + assertEquals("GasInM1 right amount", 650, plan.getAmount(), 0.001); + switch (s.getSegmentID()) { + case 1: + assertEquals("GasInM1 right accepted amount in S1", 466.255, plan.getAcceptedAmount(), 0.001); + break; + case 2: + assertEquals("GasInM1 right accepted amount in S2", 0, plan.getAcceptedAmount(), 0.001); + break; + } + } else if (plan.getPowerPlant().getName().equals("GasInM2")) { + assertEquals("GasInM2 right price", 40, plan.getBidWithoutCO2(), 0.001); + assertEquals("GasInM2 right amount", 1000, plan.getAmount(), 0.001); + switch (s.getSegmentID()) { + case 1: + assertEquals("GasInM2 right accepted amount in S1", 715.066, plan.getAcceptedAmount(), 0.001); + break; + case 2: + assertEquals("GasInM2 right accepted amount in S2", 0, plan.getAcceptedAmount(), 0.001); + break; + } + } else if (plan.getPowerPlant().getName().equals("WindInM1")) { + assertEquals("WindInM1 right price", 0, plan.getBidWithoutCO2(), 0.001); + switch (s.getSegmentID()) { + case 1: + assertEquals("WindInM1 right amount", 90.695, plan.getAmount(), 0.001); + assertEquals("WindInM1 right accepted amount in S1", 90.695, plan.getAcceptedAmount(), 0.001); + break; + case 2: + assertEquals("WindInM1 right amount", 46.895, plan.getAmount(), 0.001); + assertEquals("WindInM1 right accepted amount in S2", 46.895, plan.getAcceptedAmount(), 0.001); + break; + } + } else if (plan.getPowerPlant().getName().equals("WindInM2")) { + assertEquals("WindInM2 right price", 0, plan.getBidWithoutCO2(), 0.001); + switch (s.getSegmentID()) { + case 1: + assertEquals("WindInM2 right amount", 198.834, plan.getAmount(), 0.001); + assertEquals("WindInM2 right accepted amount in S1", 198.834, plan.getAcceptedAmount(), 0.001); + break; + case 2: + assertEquals("WindInM2 right amount", 146.274, plan.getAmount(), 0.001); + assertEquals("WindInM2 right accepted amount in S2", 146.274, plan.getAcceptedAmount(), 0.001); + break; + } + } + } + + } + +<<<<<<< HEAD + for (SegmentClearingPoint scp : reps.segmentClearingPointRepository.findAll()) { + if (scp.getAbstractMarket().getName().equals("Market1")) { + switch (scp.getSegment().getSegmentID()) { +======= + for (SegmentClearingPoint scp : reps.segmentClearingPointRepository.findAll()){ + if(scp.getAbstractMarket().getName().equals("Market1")){ + switch(scp.getSegment().getSegmentID()){ +>>>>>>> Jorn/feature/historicalCVar + case 1: + assertEquals("Clearing Point Market 1, segment1 price", 36, scp.getPrice(), 0.001); + assertEquals("Clearing Point Market 1, segment1 volume", 5067441, scp.getVolume(), 0.001); + break; + case 2: + assertEquals("Clearing Point Market 1, segment2 price", 27, scp.getPrice(), 0.001); + assertEquals("Clearing Point Market 1, segment2 volume", 3149001, scp.getVolume(), 0.001); + break; + } +<<<<<<< HEAD + } else if (scp.getAbstractMarket().getName().equals("Market2")) { +======= + } else if(scp.getAbstractMarket().getName().equals("Market2")){ +>>>>>>> Jorn/feature/historicalCVar + switch (scp.getSegment().getSegmentID()) { + case 1: + assertEquals("Clearing Point Market 2, segment1 price", 40, scp.getPrice(), 0.001); + assertEquals("Clearing Point Market 2, segment1 volume", 10134882, scp.getVolume(), 0.001); + break; + case 2: + assertEquals("Clearing Point Market 2, segment2 price", 27, scp.getPrice(), 0.001); + assertEquals("Clearing Point Market 2, segment2 volume", 6298002, scp.getVolume(), 0.001); + break; + } + } + } + +<<<<<<< HEAD +======= + +>>>>>>> Jorn/feature/historicalCVar + } + + @Transactional + void updateWindPowerPlants() { + logger.warn("Updating wind"); + for (PowerPlant plant : reps.powerPlantRepository.findAll()) { + logger.warn(plant.getName()); + if (plant.getName().equals("WindInM1")) { + // logger.warn("Updated WindInM1"); + // plant.setActualNominalCapacity(12000); + } else if (plant.getName().equals("WindInM2")) { + plant.setActualNominalCapacity(16000); + logger.warn("Updated WindInM2"); + } + } + } + + @Test + public void electricityMarketTestWithALotRenewablesForCurrentTick() { + + DecarbonizationModel model = reps.genericRepository.findFirst(DecarbonizationModel.class); + + this.updateWindPowerPlants(); + + determineResidualLoadCurvesForTwoCountriesRole.act(model); + + // for (SegmentLoad segmentLoad : reps.segmentLoadRepository.findAll()) + // { + // logger.warn("SegmentLoad: " + segmentLoad.getBaseLoad() + + // "SegmentId: " + // + segmentLoad.getSegment().getSegmentID() + "SegmentMarket: " + // + segmentLoad.getElectricitySpotMarket().getName()); + // if + // (segmentLoad.getElectricitySpotMarket().getName().equals("Market1")) + // { + // switch (segmentLoad.getSegment().getSegmentID()) { + // case 1: + // assertEquals("SegmentLoad Market 1, Segment 1", 1156.95, + // segmentLoad.getBaseLoad(), 0.001); + // break; + // case 2: + // assertEquals("SegmentLoad Market 1, Segment 2", 718.95, + // segmentLoad.getBaseLoad(), 0.001); + // break; + // } + // } else if + // (segmentLoad.getElectricitySpotMarket().getName().equals("Market2")) + // { + // switch (segmentLoad.getSegment().getSegmentID()) { + // case 1: + // assertEquals("SegmentLoad Market 2, Segment 1", 2313.9, + // segmentLoad.getBaseLoad(), 0.001); + // break; + // case 2: + // assertEquals("SegmentLoad Market 2, Segment 2", 1437.9, + // segmentLoad.getBaseLoad(), 0.001); + // break; + // } + // } + // } + + for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) { + determineFuelMixRole.act(producer); + submitOffersToElectricitySpotMarketRole.act(producer); + producer.act(determineFuelMixRole); + } + + // submitOffersToElectricitySpotMarketRole + // .createOffersForElectricitySpotMarket(null, getCurrentTick(), true, + // null); + // submitOffersToElectricitySpotMarketRole.createOffersForElectricitySpotMarket(null, + // getCurrentTick(), false, + // null); + + clearIterativeCO2AndElectricitySpotMarketTwoCountryRole +<<<<<<< HEAD + .clearIterativeCO2AndElectricitySpotMarketTwoCountryForTimestepAndFuelPrices(model, false, + getCurrentTick(), null, null, 0); + + // Check that + for (PowerPlant plant : reps.powerPlantRepository.findAll()) { + logger.warn("Plant: " + plant.getName()); + for (Segment s : reps.segmentRepository.findAll()) { + logger.warn("segment " + s.getSegmentID()); +======= + .clearIterativeCO2AndElectricitySpotMarketTwoCountryForTimestepAndFuelPrices(model, false, + getCurrentTick(), null, null, 0); + + // Check that + for (PowerPlant plant : reps.powerPlantRepository.findAll()) { + for (Segment s : reps.segmentRepository.findAll()) { +>>>>>>> Jorn/feature/historicalCVar + PowerPlantDispatchPlan plan = reps.powerPlantDispatchPlanRepository + .findOnePowerPlantDispatchPlanForPowerPlantForSegmentForTime(plant, s, 0, false); + if (plan.getPowerPlant().getName().equals("CoalInM1")) { + assertEquals("CoalInM1 right price", 24, plan.getBidWithoutCO2(), 0.001); + assertEquals("CoalInM1 right amount", 700, plan.getAmount(), 0.001); + switch (s.getSegmentID()) { + case 1: +<<<<<<< HEAD + logger.warn("CoalInM1, S1 , " + plan.getAcceptedAmount()); + assertEquals("CoalInM1 right accepted amount in S1", 700, plan.getAcceptedAmount(), 0.001); + break; + case 2: + logger.warn("CoalInM1, S2 , " + plan.getAcceptedAmount()); + assertEquals("CoalInM1 right accepted amount in S2", 572.055, plan.getAcceptedAmount(), 0.001); + break; +======= + assertEquals("CoalInM1 right accepted amount in S1", 700, plan.getAcceptedAmount(), 0.001); + break; + case 2: + assertEquals("CoalInM1 right accepted amount in S2", 572.055, plan.getAcceptedAmount(), 0.001); +>>>>>>> Jorn/feature/historicalCVar + } + } else if (plan.getPowerPlant().getName().equals("CoalInM2")) { + assertEquals("CoalInM2 right price", 27, plan.getBidWithoutCO2(), 0.001); + assertEquals("CoalInM2 right amount", 1300, plan.getAmount(), 0.001); + switch (s.getSegmentID()) { + case 1: + assertEquals("CoalInM2 right accepted amount in S1", 0, plan.getAcceptedAmount(), 0.001); + logger.warn("CoalM2, S1: " + plan.getAcceptedAmount()); + break; + case 2: + assertEquals("CoalInM2 right accepted amount in S2", 0, plan.getAcceptedAmount(), 0.001); + logger.warn("CoalM2, S2: " + plan.getAcceptedAmount()); + break; + } + } else if (plan.getPowerPlant().getName().equals("GasInM1")) { + assertEquals("GasInM1 right price", 36, plan.getBidWithoutCO2(), 0.001); + assertEquals("GasInM1 right amount", 650, plan.getAmount(), 0.001); + switch (s.getSegmentID()) { + case 1: + assertEquals("GasInM1 right accepted amount in S1", 266.255, plan.getAcceptedAmount(), 0.001); + break; + case 2: + assertEquals("GasInM1 right accepted amount in S2", 0, plan.getAcceptedAmount(), 0.001); + break; + } + } else if (plan.getPowerPlant().getName().equals("GasInM2")) { + assertEquals("GasInM2 right price", 40, plan.getBidWithoutCO2(), 0.001); + assertEquals("GasInM2 right amount", 1000, plan.getAmount(), 0.001); + switch (s.getSegmentID()) { + case 1: + assertEquals("GasInM2 right accepted amount in S1", 0, plan.getAcceptedAmount(), 0.001); + break; + case 2: + assertEquals("GasInM2 right accepted amount in S2", 0, plan.getAcceptedAmount(), 0.001); + break; + } + } else if (plan.getPowerPlant().getName().equals("WindInM1")) { + assertEquals("WindInM1 right price", 0, plan.getBidWithoutCO2(), 0.001); + switch (s.getSegmentID()) { + case 1: + assertEquals("WindInM1 right amount", 90.695, plan.getAmount(), 0.001); + assertEquals("WindInM1 right accepted amount in S1", 90.695, plan.getAcceptedAmount(), 0.001); + break; + case 2: + assertEquals("WindInM1 right amount", 46.894, plan.getAmount(), 0.001); + assertEquals("WindInM1 right accepted amount in S2", 46.894, plan.getAcceptedAmount(), 0.001); + break; + } + } else if (plan.getPowerPlant().getName().equals("WindInM2")) { + assertEquals("WindInM2 right price", 0, plan.getBidWithoutCO2(), 0.001); + switch (s.getSegmentID()) { + case 1: + assertEquals("WindInM2 right amount", 2413.90, plan.getAmount(), 0.001); + assertEquals("WindInM2 right accepted amount in S1", 2413.90, plan.getAcceptedAmount(), 0.001); + break; + case 2: + assertEquals("WindInM2 right amount", 1537.900, plan.getAmount(), 0.001); + assertEquals("WindInM2 right accepted amount in S2", 1537.90, plan.getAcceptedAmount(), 0.001); + break; + } + } + } + + } + + for (SegmentClearingPoint scp : reps.segmentClearingPointRepository.findAll()) { + if (scp.getAbstractMarket().getName().equals("Market1")) { + switch (scp.getSegment().getSegmentID()) { + case 1: + assertEquals("Clearing Point Market 1, segment1 price", 36, scp.getPrice(), 0.001); + // assertEquals("Clearing Point Market 1, segment1 volume", + // 5067441, scp.getVolume(), 0.001); + break; + case 2: + assertEquals("Clearing Point Market 1, segment2 price", 24, scp.getPrice(), 0.001); + // assertEquals("Clearing Point Market 1, segment2 volume", + // 3149001, scp.getVolume(), 0.001); + break; + } + } else if (scp.getAbstractMarket().getName().equals("Market2")) { + switch (scp.getSegment().getSegmentID()) { + case 1: + assertEquals("Clearing Point Market 2, segment1 price", 0, scp.getPrice(), 0.001); + // assertEquals("Clearing Point Market 2, segment1 volume", + // 10134882, scp.getVolume(), 0.001); + break; + case 2: + assertEquals("Clearing Point Market 2, segment2 price", 0, scp.getPrice(), 0.001); + // assertEquals("Clearing Point Market 2, segment2 volume", + // 6298002, scp.getVolume(), 0.001); + break; + } + } + } + + } + + private long getCurrentTick() { + return 0; + } + +} + +// } diff --git a/emlab-generation/src/test/java/emlab/gen/role/capacitymarket/ClearCapacityMarketRoleTest.java b/emlab-generation/src/test/java/emlab/gen/role/capacitymarket/ClearCapacityMarketRoleTest.java new file mode 100644 index 00000000..a325eeff --- /dev/null +++ b/emlab-generation/src/test/java/emlab/gen/role/capacitymarket/ClearCapacityMarketRoleTest.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * 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.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +import emlab.gen.domain.agent.Regulator; +import emlab.gen.domain.gis.Zone; +import emlab.gen.domain.market.capacity.CapacityDispatchPlan; +import emlab.gen.domain.market.capacity.CapacityMarket; +import emlab.gen.repository.CapacityMarketRepository; +import emlab.gen.repository.Reps; + +/** + * @author Kaveri + * + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration({ "/emlab-gen-test-context.xml" }) +@Transactional +public class ClearCapacityMarketRoleTest { + + Logger logger = Logger.getLogger(ClearCapacityMarketRole.class); + + @Autowired + Reps reps; + + @Autowired + CapacityMarketRepository capacityMarketRepository; + + @Autowired + ClearCapacityMarketRole clearCapacityMarketRoleTest; + + @Test + public void ClearCapacityMarketBasicFunctionality() { + + CapacityMarket market = new CapacityMarket(); + market.persist(); + + Zone zone = new Zone(); + zone.persist(); + + Regulator regulator = new Regulator(); + + regulator.setDemandTarget(100); + regulator.setCapacityMarketPriceCap(10); + // regulator.setReserveMargin(0.156); + regulator.setReserveDemandLowerMargin(0.15); + regulator.setReserveDemandUpperMargin(0.05); + regulator.setZone(zone); + regulator.persist(); + + CapacityDispatchPlan cdp1 = new CapacityDispatchPlan(); + cdp1.setAmount(8); + cdp1.setPrice(0); + cdp1.setTime(0l); + cdp1.setStatus(1); + cdp1.persist(); + + CapacityDispatchPlan cdp2 = new CapacityDispatchPlan(); + cdp2.setAmount(20); + cdp2.setPrice(0); + cdp2.setTime(0l); + cdp2.setStatus(1); + cdp2.persist(); + + CapacityDispatchPlan cdp3 = new CapacityDispatchPlan(); + cdp3.setAmount(70); + cdp3.setPrice(1); + cdp3.setTime(0l); + cdp3.setStatus(1); + cdp3.persist(); + + CapacityDispatchPlan cdp4 = new CapacityDispatchPlan(); + cdp4.setAmount(10); + cdp4.setPrice(20); + cdp4.setTime(0l); + cdp4.setStatus(1); + cdp4.persist(); + + clearCapacityMarketRoleTest.act(regulator); + + logger.warn("Status of CDP 1 is " + cdp1.getStatus()); + logger.warn("Status of CDP 2 is " + cdp2.getStatus()); + logger.warn("Status of CDP 3 is " + cdp3.getStatus()); + logger.warn("Status of (overpriced) CDP 4 is " + cdp4.getStatus()); + + // CapacityClearingPoint capacityClearingPoint = + // reps.capacityMarketRepository + // .findOneCapacityClearingPointForTime(0); + + // logger.warn("Clearing point Price" + + // capacityClearingPoint.getPrice()); + // logger.warn("Clearing Point Volume" + + // capacityClearingPoint.getVolume()); + + } + +} diff --git a/emlab-generation/src/test/java/emlab/gen/role/capacitymarket/ForecastDemandRoleTest.java b/emlab-generation/src/test/java/emlab/gen/role/capacitymarket/ForecastDemandRoleTest.java new file mode 100644 index 00000000..1701e609 --- /dev/null +++ b/emlab-generation/src/test/java/emlab/gen/role/capacitymarket/ForecastDemandRoleTest.java @@ -0,0 +1,136 @@ +/******************************************************************************* +` * 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 java.util.HashSet; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +import emlab.gen.domain.agent.Regulator; +import emlab.gen.domain.gis.Zone; +import emlab.gen.domain.market.electricity.ElectricitySpotMarket; +import emlab.gen.domain.market.electricity.Segment; +import emlab.gen.domain.market.electricity.SegmentLoad; +import emlab.gen.repository.MarketRepository; +import emlab.gen.repository.Reps; +import emlab.gen.trend.TriangularTrend; + +/** + * @author Kaveri + * + */ + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration({ "/emlab-gen-test-context.xml" }) +@Transactional +public class ForecastDemandRoleTest { + Logger logger = Logger.getLogger(ForecastDemandRole.class); + + @Autowired + Reps reps; + + @Autowired + MarketRepository marketRepository; + + @Autowired + ForecastDemandRole fDemandRole; + + @Test + public void checkForecastDemandFunctionality() { + + Zone zone = new Zone(); + zone.persist(); + Regulator regulator = new Regulator(); + regulator.setTargetPeriod(0); + regulator.setReserveMargin(0.15); + regulator.setNumberOfYearsLookingBackToForecastDemand(3); + regulator.setZone(zone); + regulator.persist(); + + Segment S1 = new Segment(); + S1.setLengthInHours(20); + S1.persist(); + + Segment S2 = new Segment(); + S2.setLengthInHours(30); + S2.persist(); + + SegmentLoad SG1 = new SegmentLoad(); + SG1.setSegment(S2); + SG1.setBaseLoad(2500); + SG1.persist(); + // SegmentLoad SG2 = new SegmentLoad(); + // SG2.setSegment(S2); + // SG2.setBaseLoad(2000); + + SegmentLoad SG3 = new SegmentLoad(); + SG3.setSegment(S1); + SG3.setBaseLoad(3700); + + // SegmentLoad SG4 = new SegmentLoad(); + // SG4.setSegment(S1); + // SG4.setBaseLoad(4000); + + // SG2.persist(); + SG3.persist(); + // SG4.persist(); + + Set segmentLoads1 = new HashSet(); + segmentLoads1.add(SG1); + segmentLoads1.add(SG3); + // + // TimeSeriesImpl demandGrowthTrend = new TimeSeriesImpl(); + // int lengthOfSeries = 50; + // double[] timeSeries = new double[lengthOfSeries]; + // timeSeries[0] = 1; + // for (int i = 1; i <= lengthOfSeries; i++) { + // timeSeries[i] = timeSeries[i - 1] * 1.02; + // } + + TriangularTrend demandGrowthTrend = new TriangularTrend(); + demandGrowthTrend.setMax(2); + demandGrowthTrend.setMin(1); + demandGrowthTrend.setStart(1); + demandGrowthTrend.setTop(1); + + // demandGrowthTrend.setTimeSeries(timeSeries); + // demandGrowthTrend.setStartingYear(0); + demandGrowthTrend.persist(); + + ElectricitySpotMarket market1 = new ElectricitySpotMarket(); + market1.setName("Market1"); + market1.setLoadDurationCurve(segmentLoads1); + market1.setDemandGrowthTrend(demandGrowthTrend); + market1.setZone(zone); + market1.persist(); + + fDemandRole.act(regulator); + + // logger.warn("Target Demand for this tick: " + + // regulator.getRelativeRenewableTarget()); + // assertTrue(regulator.getRelativeRenewableTarget() == 4255); + // logger.warn("Target Demand for this tick: " + + // fDemandRole.expectedDemandFactor); + + } +} diff --git a/emlab-generation/src/test/java/emlab/gen/role/capacitymarket/ForecastDemandRoleTest2.java b/emlab-generation/src/test/java/emlab/gen/role/capacitymarket/ForecastDemandRoleTest2.java new file mode 100644 index 00000000..21c1c1f2 --- /dev/null +++ b/emlab-generation/src/test/java/emlab/gen/role/capacitymarket/ForecastDemandRoleTest2.java @@ -0,0 +1,362 @@ +/******************************************************************************* + * 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 java.util.HashSet; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +import emlab.gen.domain.agent.EnergyProducer; +import emlab.gen.domain.agent.Regulator; +import emlab.gen.domain.contract.Loan; +import emlab.gen.domain.gis.Zone; +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.SegmentClearingPoint; +import emlab.gen.domain.market.electricity.SegmentLoad; +import emlab.gen.domain.technology.PowerGeneratingTechnology; +import emlab.gen.domain.technology.PowerPlant; +import emlab.gen.repository.BidRepository; +import emlab.gen.repository.MarketRepository; +import emlab.gen.repository.PowerPlantDispatchPlanRepository; +import emlab.gen.repository.Reps; +import emlab.gen.repository.SegmentLoadRepository; +import emlab.gen.repository.ZoneRepository; +import emlab.gen.trend.TriangularTrend; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration({ "/emlab-gen-test-context.xml" }) +@Transactional +public class ForecastDemandRoleTest2 { + Logger logger = Logger.getLogger(ForecastDemandRole.class); + + @Autowired + Reps reps; + + @Autowired + SegmentLoadRepository segmentLoadRepository; + + @Autowired + MarketRepository marketRepository; + + @Autowired + BidRepository bidRepository; + + @Autowired + PowerPlantDispatchPlanRepository plantDispatchPlanRepository; + + @Autowired + ZoneRepository zoneRepository; + + @Autowired + ForecastDemandRole fDemandRole; + + @Test + public void ZonalTest() { + + Zone zone1 = new Zone(); + // Zone zone2 = new Zone(); + zone1.setName("Zone 1"); + + // zone2.setName("Zone2"); + + zone1.persist(); + + // zone2.persist(); + + Segment S1 = new Segment(); + S1.setLengthInHours(20); + S1.persist(); + + Segment S2 = new Segment(); + S2.setLengthInHours(30); + S2.persist(); + + SegmentLoad SG1 = new SegmentLoad(); + SG1.setSegment(S2); + SG1.setBaseLoad(2500); + + // SegmentLoad SG2 = new SegmentLoad(); + // SG2.setSegment(S2); + // SG2.setBaseLoad(2000); + + SegmentLoad SG3 = new SegmentLoad(); + SG3.setSegment(S1); + SG3.setBaseLoad(3700); + + // SegmentLoad SG4 = new SegmentLoad(); + // SG4.setSegment(S1); + // SG4.setBaseLoad(4000); + + SG1.persist(); + // SG2.persist(); + SG3.persist(); + // SG4.persist(); + + Set segmentLoads1 = new HashSet(); + segmentLoads1.add(SG1); + segmentLoads1.add(SG3); + + // Set segmentLoads2 = new HashSet(); + // segmentLoads2.add(SG2); + // segmentLoads2.add(SG4); + + TriangularTrend demandGrowthTrend = new TriangularTrend(); + demandGrowthTrend.setMax(2); + demandGrowthTrend.setMin(0); + demandGrowthTrend.setStart(1); + demandGrowthTrend.setTop(1); + + demandGrowthTrend.persist(); + + ElectricitySpotMarket market1 = new ElectricitySpotMarket(); + market1.setName("Market1"); + market1.setZone(zone1); + market1.setLoadDurationCurve(segmentLoads1); + market1.setDemandGrowthTrend(demandGrowthTrend); + market1.persist(); + + // ElectricitySpotMarket market2 = new ElectricitySpotMarket(); + // market2.setZone(zone2); + // market2.setName("Market2"); + // market2.setLoadDurationCurve(segmentLoads2); + // market2.setDemandGrowthTrend(demandGrowthTrend); + // market2.persist(); + + PowerGeneratingTechnology coal1 = new PowerGeneratingTechnology(); + + PowerGeneratingTechnology coal2 = new PowerGeneratingTechnology(); + + PowerGeneratingTechnology gas1 = new PowerGeneratingTechnology(); + + PowerGeneratingTechnology gas2 = new PowerGeneratingTechnology(); + + coal1.persist(); + coal2.persist(); + gas1.persist(); + gas2.persist(); + + EnergyProducer e1 = new EnergyProducer(); + e1.setName("E1"); + e1.setCash(0); + e1.setPriceMarkUp(1); + + EnergyProducer e2 = new EnergyProducer(); + e2.setCash(0); + e2.setPriceMarkUp(1); + e2.setName("E2"); + + EnergyProducer e3 = new EnergyProducer(); + e3.setCash(0); + e3.setPriceMarkUp(1); + e3.setName("E3"); + + e1.persist(); + e2.persist(); + e3.persist(); + + Loan l1 = new Loan(); + l1.setAmountPerPayment(6000); + l1.setNumberOfPaymentsDone(10); + l1.setTotalNumberOfPayments(15); + + Loan l2 = new Loan(); + l2.setAmountPerPayment(5000); + l2.setNumberOfPaymentsDone(29); + l2.setTotalNumberOfPayments(19); + + Loan l3 = new Loan(); + l3.setAmountPerPayment(4000); + l3.setNumberOfPaymentsDone(8); + l3.setTotalNumberOfPayments(13); + + Loan l4 = new Loan(); + l4.setAmountPerPayment(3000); + l4.setNumberOfPaymentsDone(7); + l4.setTotalNumberOfPayments(12); + + Loan l5 = new Loan(); + l5.setAmountPerPayment(2000); + l5.setNumberOfPaymentsDone(6); + l5.setTotalNumberOfPayments(11); + + Loan l6 = new Loan(); + l6.setAmountPerPayment(1000); + l6.setNumberOfPaymentsDone(5); + l6.setTotalNumberOfPayments(10); + + l1.persist(); + l2.persist(); + l3.persist(); + l4.persist(); + l5.persist(); + l6.persist(); + + PowerPlant pp1 = new PowerPlant(); + pp1.setTechnology(coal1); + pp1.setOwner(e1); + pp1.setActualFixedOperatingCost(99000); + pp1.setLoan(l1); + // pp1.setName("PP1"); + + PowerPlant pp2 = new PowerPlant(); + pp2.setTechnology(coal2); + pp2.setOwner(e2); + pp2.setActualFixedOperatingCost(111000); + pp2.setLoan(l2); + // pp2.setName("PP2"); + + PowerPlant pp3 = new PowerPlant(); + pp3.setTechnology(gas1); + pp3.setOwner(e3); + pp3.setActualFixedOperatingCost(56000); + pp3.setLoan(l3); + + PowerPlant pp4 = new PowerPlant(); + pp4.setTechnology(gas2); + pp4.setOwner(e3); + pp4.setActualFixedOperatingCost(65000); + pp4.setLoan(l4); + + PowerPlant pp5 = new PowerPlant(); + pp5.setTechnology(gas1); + pp5.setOwner(e2); + pp5.setActualFixedOperatingCost(56000); + pp5.setLoan(l5); + + PowerPlant pp6 = new PowerPlant(); + pp6.setTechnology(gas2); + pp6.setOwner(e1); + pp6.setActualFixedOperatingCost(65000); + pp6.setLoan(l6); + + pp1.persist(); + pp2.persist(); + pp3.persist(); + pp4.persist(); + pp5.persist(); + pp6.persist(); + + // for Zone 1 Segment 1 + PowerPlantDispatchPlan p1 = new PowerPlantDispatchPlan(); + p1.setAmount(1500.0d); + p1.setSegment(S1); + p1.setPrice(5.0d); + p1.setTime(0l); + p1.setBiddingMarket(market1); + p1.setPowerPlant(pp1); + p1.setBidder(e1); + p1.setStatus(3); + p1.setAcceptedAmount(1500); + p1.persist(); + + PowerPlantDispatchPlan p11 = new PowerPlantDispatchPlan(); + p11.setAmount(1000.0d); + p11.setSegment(S1); + p11.setPrice(15.0d); + p11.setTime(0l); + p11.setBiddingMarket(market1); + p11.setPowerPlant(pp2); + p11.setBidder(e2); + p11.setStatus(3); + p11.setAcceptedAmount(1000); + p11.persist(); + + PowerPlantDispatchPlan p111 = new PowerPlantDispatchPlan(); + p111.setAmount(1200.0d); + p111.setSegment(S1); + p111.setPrice(7.0d); + p111.setTime(0l); + p111.setBiddingMarket(market1); + p111.setPowerPlant(pp3); + p111.setBidder(e3); + p111.setStatus(3); + p111.setAcceptedAmount(1200); + p111.persist(); + + // For Zone 1 segment 2 + PowerPlantDispatchPlan p1111 = new PowerPlantDispatchPlan(); + p1111.setAmount(1500.0d); + p1111.setSegment(S2); + p1111.setPrice(5.0d); + p1111.setTime(0l); + p1111.setBiddingMarket(market1); + p1111.setPowerPlant(pp1); + p1111.setBidder(e1); + p1111.setStatus(3); + p1111.setAcceptedAmount(1500); + p1111.persist(); + + PowerPlantDispatchPlan p11111 = new PowerPlantDispatchPlan(); + p11111.setAmount(1000.0d); + p11111.setSegment(S2); + p11111.setPrice(15.0d); + p11111.setTime(0l); + p11111.setBiddingMarket(market1); + p11111.setPowerPlant(pp2); + p11111.setBidder(e2); + p11111.setStatus(-1); + p11111.setAcceptedAmount(0); + p11111.persist(); + + PowerPlantDispatchPlan p111111 = new PowerPlantDispatchPlan(); + p111111.setAmount(1200.0d); + p111111.setSegment(S2); + p111111.setPrice(7.0d); + p111111.setTime(0l); + p111111.setBiddingMarket(market1); + p111111.setPowerPlant(pp3); + p111111.setBidder(e3); + p111111.setStatus(2); + p111111.setAcceptedAmount(1000); + p111111.persist(); + + SegmentClearingPoint clearingPoint1 = new SegmentClearingPoint(); + clearingPoint1.setSegment(S1); + clearingPoint1.setAbstractMarket(market1); + clearingPoint1.setPrice(25); + clearingPoint1.setTime(0l); + + SegmentClearingPoint clearingPoint111 = new SegmentClearingPoint(); + clearingPoint111.setSegment(S2); + clearingPoint111.setAbstractMarket(market1); + clearingPoint111.setPrice(7); + clearingPoint111.setTime(0l); + + clearingPoint1.persist(); + clearingPoint111.persist(); + + Regulator regulator = new Regulator(); + regulator.setTargetPeriod(0); + regulator.setReserveMargin(0.15); + regulator.setNumberOfYearsLookingBackToForecastDemand(3); + regulator.setZone(zone1); + regulator.persist(); + + fDemandRole.act(regulator); + + // logger.warn("Target Demand for this tick: " + + // regulator.getRelativeRenewableTarget()); + } +} \ No newline at end of file diff --git a/emlab-generation/src/test/java/emlab/gen/role/capacitymarket/PaymentFromConsumerToProducerforCapacityRoleTest.java b/emlab-generation/src/test/java/emlab/gen/role/capacitymarket/PaymentFromConsumerToProducerforCapacityRoleTest.java new file mode 100644 index 00000000..b747fe25 --- /dev/null +++ b/emlab-generation/src/test/java/emlab/gen/role/capacitymarket/PaymentFromConsumerToProducerforCapacityRoleTest.java @@ -0,0 +1,144 @@ +/******************************************************************************* + * 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.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +import emlab.gen.domain.agent.EnergyConsumer; +import emlab.gen.domain.agent.EnergyProducer; +import emlab.gen.domain.gis.Zone; +import emlab.gen.domain.market.capacity.CapacityClearingPoint; +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.technology.PowerPlant; +import emlab.gen.repository.Reps; + +/** + * @author Kaveri + * + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration({ "/emlab-gen-test-context.xml" }) +@Transactional +public class PaymentFromConsumerToProducerforCapacityRoleTest { + + @Autowired + Reps reps; + + /** + * + */ + + @Autowired + PaymentFromConsumerToProducerForCapacityRole paymentFromConsumerToProducerForCapacityRole; + + Logger logger = Logger.getLogger(PaymentFromConsumerToProducerForCapacityRole.class); + + @Test + public void capacityMarketPaymentFunctionality() { + + Zone zone = new Zone(); + zone.persist(); + + EnergyProducer ep1 = new EnergyProducer(); + EnergyProducer ep2 = new EnergyProducer(); + ep1.persist(); + ep2.persist(); + + EnergyConsumer consumer = new EnergyConsumer(); + consumer.persist(); + + CapacityMarket market = new CapacityMarket(); + market.setConsumer(consumer); + market.setZone(zone); + market.persist(); + + ElectricitySpotMarket esm = new ElectricitySpotMarket(); + esm.setZone(zone); + esm.persist(); + + CapacityClearingPoint clearingPoint = new CapacityClearingPoint(); + clearingPoint.setCapacityMarket(market); + clearingPoint.setPrice(1); + clearingPoint.setTime(0l); + clearingPoint.persist(); + + PowerPlant pp1 = new PowerPlant(); + PowerPlant pp2 = new PowerPlant(); + PowerPlant pp3 = new PowerPlant(); + PowerPlant pp4 = new PowerPlant(); + + pp1.persist(); + pp2.persist(); + pp3.persist(); + pp4.persist(); + + CapacityDispatchPlan cdp1 = new CapacityDispatchPlan(); + cdp1.setBidder(ep1); + cdp1.setBiddingMarket(market); + cdp1.setTime(0l); + cdp1.setAcceptedAmount(100); + cdp1.setPlant(pp1); + cdp1.setStatus(3); + cdp1.persist(); + + CapacityDispatchPlan cdp2 = new CapacityDispatchPlan(); + cdp2.setBidder(ep1); + cdp2.setBiddingMarket(market); + cdp2.setTime(0l); + cdp2.setAcceptedAmount(80); + cdp2.setPlant(pp2); + cdp2.setStatus(2); + cdp2.persist(); + + CapacityDispatchPlan cdp3 = new CapacityDispatchPlan(); + cdp3.setBidder(ep2); + cdp3.setBiddingMarket(market); + cdp3.setTime(0l); + cdp3.setAcceptedAmount(150); + cdp3.setPlant(pp3); + cdp3.setStatus(3); + cdp3.persist(); + + CapacityDispatchPlan cdp4 = new CapacityDispatchPlan(); + cdp4.setBidder(ep2); + cdp4.setBiddingMarket(market); + cdp4.setTime(0l); + cdp4.setAcceptedAmount(100); + cdp4.setPlant(pp4); + cdp4.setStatus(3); + cdp4.persist(); + + logger.warn("Consumer's Cash before Payment Process " + consumer.getCash()); + logger.warn("Energy Producer1's Cash before Payment Process" + ep1.getCash()); + logger.warn("Energy Producer2's Cash before Payment Process" + ep2.getCash()); + + paymentFromConsumerToProducerForCapacityRole.act(market); + + logger.warn("Consumer's Cash After Payment Process " + consumer.getCash()); + logger.warn("Energy Producer1's Cash After Payment Process" + ep1.getCash()); + logger.warn("Energy Producer2's Cash After Payment Process" + ep2.getCash()); + + } + +} diff --git a/emlab-generation/src/test/java/emlab/gen/role/capacitymarket/SubmitCapacityBidToMarketRoleTest.java b/emlab-generation/src/test/java/emlab/gen/role/capacitymarket/SubmitCapacityBidToMarketRoleTest.java new file mode 100644 index 00000000..200f64f4 --- /dev/null +++ b/emlab-generation/src/test/java/emlab/gen/role/capacitymarket/SubmitCapacityBidToMarketRoleTest.java @@ -0,0 +1,303 @@ +/******************************************************************************* + * 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 java.util.HashSet; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +import emlab.gen.domain.agent.EnergyProducer; +import emlab.gen.domain.gis.Zone; +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.SegmentClearingPoint; +import emlab.gen.domain.market.electricity.SegmentLoad; +import emlab.gen.domain.technology.PowerGeneratingTechnology; +import emlab.gen.domain.technology.PowerGridNode; +import emlab.gen.domain.technology.PowerPlant; +import emlab.gen.repository.Reps; +import emlab.gen.trend.TriangularTrend; + +/** + * @author Kaveri + * + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration({ "/emlab-gen-test-context.xml" }) +@Transactional +public class SubmitCapacityBidToMarketRoleTest { + + Logger logger = Logger.getLogger(SubmitCapacityBidToMarketRole.class); + + @Autowired + Reps reps; + + @Autowired + SubmitCapacityBidToMarketRole submitCapacityBidRole; + + @Test + public void testSubmitBidFunctionality1() { + // for bidding a positive value + Segment S1 = new Segment(); + S1.setLengthInHours(20); + S1.persist(); + + Segment S2 = new Segment(); + S2.setLengthInHours(30); + S2.persist(); + + SegmentLoad SG1 = new SegmentLoad(); + SG1.setSegment(S2); + SG1.setBaseLoad(2500); + + // SegmentLoad SG2 = new SegmentLoad(); + // SG2.setSegment(S2); + // SG2.setBaseLoad(2000); + + SegmentLoad SG3 = new SegmentLoad(); + SG3.setSegment(S1); + SG3.setBaseLoad(3700); + + // SegmentLoad SG4 = new SegmentLoad(); + // SG4.setSegment(S1); + // SG4.setBaseLoad(4000); + + SG1.persist(); + // SG2.persist(); + SG3.persist(); + // SG4.persist(); + + Set segmentLoads = new HashSet(); + segmentLoads.add(SG1); + segmentLoads.add(SG3); + + // Set segmentLoads2 = new HashSet(); + // segmentLoads2.add(SG2); + // segmentLoads2.add(SG4); + + /* + * TriangularTrend demandGrowthTrend = new TriangularTrend(); + * demandGrowthTrend.setMax(2); demandGrowthTrend.setMin(0); + * demandGrowthTrend.setStart(1); demandGrowthTrend.setTop(1); + * + * demandGrowthTrend.persist(); + */ + + Zone zone = new Zone(); + zone.persist(); + + PowerGridNode location = new PowerGridNode(); + location.setZone(zone); + location.persist(); + + ElectricitySpotMarket market = new ElectricitySpotMarket(); + market.setName("Market1"); + market.setZone(zone); + market.setLoadDurationCurve(segmentLoads); + // market.setDemandGrowthTrend(demandGrowthTrend); + market.persist(); + + TriangularTrend gasFixedOperatingCostTimeSeries = new TriangularTrend(); + // gasFixedOperatingCostTimeSeries[0] + gasFixedOperatingCostTimeSeries.setMax(1.10); + gasFixedOperatingCostTimeSeries.setMin(0.96); + gasFixedOperatingCostTimeSeries.setStart(0.25); + gasFixedOperatingCostTimeSeries.setTop(1.03); + gasFixedOperatingCostTimeSeries.persist(); + + TriangularTrend coalFixedOperatingCostTimeSeries = new TriangularTrend(); + coalFixedOperatingCostTimeSeries.setMax(1.05); + coalFixedOperatingCostTimeSeries.setMin(0.97); + coalFixedOperatingCostTimeSeries.setStart(100); + coalFixedOperatingCostTimeSeries.setTop(1.01); + coalFixedOperatingCostTimeSeries.persist(); + + PowerGeneratingTechnology coal1 = new PowerGeneratingTechnology(); + coal1.setFixedOperatingCostTimeSeries(coalFixedOperatingCostTimeSeries); + PowerGeneratingTechnology coal2 = new PowerGeneratingTechnology(); + coal2.setFixedOperatingCostTimeSeries(coalFixedOperatingCostTimeSeries); + PowerGeneratingTechnology gas1 = new PowerGeneratingTechnology(); + gas1.setFixedOperatingCostTimeSeries(gasFixedOperatingCostTimeSeries); + PowerGeneratingTechnology gas2 = new PowerGeneratingTechnology(); + gas2.setFixedOperatingCostTimeSeries(gasFixedOperatingCostTimeSeries); + + coal1.persist(); + coal2.persist(); + gas1.persist(); + gas2.persist(); + + EnergyProducer e1 = new EnergyProducer(); + e1.setName("E1"); + e1.setCash(0); + e1.setPriceMarkUp(1); + + EnergyProducer e2 = new EnergyProducer(); + e2.setCash(0); + e2.setPriceMarkUp(1); + e2.setName("E2"); + + e1.persist(); + e2.persist(); + + PowerPlant pp1 = new PowerPlant(); + pp1.setName("plant 1"); + pp1.setTechnology(coal1); + pp1.setOwner(e1); + pp1.setActualFixedOperatingCost(99000); + pp1.setActualNominalCapacity(700); + pp1.setActualPermittime(0); + pp1.setActualLeadtime(0); + pp1.setConstructionStartTime(-1); + pp1.setDismantleTime(99); + pp1.setLocation(location); + // pp1.setName("PP1"); + + PowerPlant pp2 = new PowerPlant(); + pp2.setName("Plant 2"); + pp2.setActualPermittime(0); + pp2.setActualLeadtime(0); + pp2.setDismantleTime(99); + pp2.setConstructionStartTime(-1); + pp2.setTechnology(coal2); + pp2.setActualNominalCapacity(700); + pp2.setOwner(e2); + pp2.setActualFixedOperatingCost(111000); + pp2.setLocation(location); + // pp2.setName("PP2"); + + PowerPlant pp3 = new PowerPlant(); + pp3.setName("Plant 3"); + pp3.setActualPermittime(0); + pp3.setDismantleTime(99); + pp3.setActualLeadtime(0); + pp3.setConstructionStartTime(-1); + pp3.setTechnology(gas1); + pp3.setActualNominalCapacity(600); + pp3.setOwner(e2); + pp3.setActualFixedOperatingCost(56000); + + pp3.setLocation(location); + + PowerPlant pp4 = new PowerPlant(); + pp4.setName("Plant 4"); + pp4.setActualPermittime(0); + pp4.setActualLeadtime(0); + pp4.setConstructionStartTime(-1); + pp4.setDismantleTime(99); + pp4.setTechnology(gas2); + pp4.setActualNominalCapacity(600); + pp4.setOwner(e1); + pp4.setActualFixedOperatingCost(65000); + pp4.setLocation(location); + + PowerPlant pp5 = new PowerPlant(); + pp5.setName("Plant 5"); + pp5.setActualPermittime(0); + pp5.setActualLeadtime(0); + pp5.setConstructionStartTime(-1); + pp5.setDismantleTime(99); + pp5.setTechnology(gas1); + pp5.setActualNominalCapacity(600); + pp5.setOwner(e2); + pp5.setActualFixedOperatingCost(56000); + pp5.setLocation(location); + + PowerPlant pp6 = new PowerPlant(); + pp6.setName("Plant 6"); + pp6.setActualPermittime(0); + pp6.setActualLeadtime(0); + pp6.setConstructionStartTime(-1); + pp6.setDismantleTime(99); + pp6.setTechnology(gas2); + pp6.setActualNominalCapacity(600); + pp6.setOwner(e1); + pp6.setActualFixedOperatingCost(65000); + pp6.setLocation(location); + + pp1.persist(); + pp2.persist(); + pp3.persist(); + pp4.persist(); + pp5.persist(); + pp6.persist(); + + PowerPlantDispatchPlan ppdp1 = new PowerPlantDispatchPlan(); + ppdp1.setPowerPlant(pp1); + ppdp1.setStatus(-1); + ppdp1.persist(); + + PowerPlantDispatchPlan ppdp2 = new PowerPlantDispatchPlan(); + ppdp2.setPowerPlant(pp2); + ppdp2.setStatus(2); + ppdp2.persist(); + + PowerPlantDispatchPlan ppdp3 = new PowerPlantDispatchPlan(); + ppdp3.setPowerPlant(pp3); + ppdp3.setStatus(3); + ppdp3.persist(); + + PowerPlantDispatchPlan ppdp4 = new PowerPlantDispatchPlan(); + ppdp4.setPowerPlant(pp4); + ppdp4.setStatus(-1); + ppdp4.persist(); + + PowerPlantDispatchPlan ppdp5 = new PowerPlantDispatchPlan(); + ppdp5.setPowerPlant(pp5); + ppdp5.setStatus(2); + ppdp5.persist(); + + PowerPlantDispatchPlan ppdp6 = new PowerPlantDispatchPlan(); + ppdp6.setPowerPlant(pp6); + ppdp6.setStatus(3); + ppdp6.persist(); + + CapacityMarket cMarket = new CapacityMarket(); + cMarket.setName("Capaciteit Markt"); + cMarket.setZone(zone); + cMarket.persist(); + + SegmentClearingPoint clearingPoint1 = new SegmentClearingPoint(); + clearingPoint1.setSegment(S1); + clearingPoint1.setAbstractMarket(market); + clearingPoint1.setPrice(25); + clearingPoint1.setTime(0); + clearingPoint1.persist(); + + SegmentClearingPoint clearingPoint2 = new SegmentClearingPoint(); + clearingPoint2.setSegment(S2); + clearingPoint2.setAbstractMarket(market); + clearingPoint2.setPrice(7); + clearingPoint2.setTime(0); + clearingPoint2.persist(); + + for (EnergyProducer ep : reps.energyProducerRepository + .findAllEnergyProducersExceptForRenewableTargetInvestorsAtRandom()) { + submitCapacityBidRole.act(ep); + logger.warn("Submitted"); + + } + + } +} diff --git a/rscripts/asHeadlessQueryReader.py b/rscripts/asHeadlessQueryReader.py new file mode 100644 index 00000000..02334d5e --- /dev/null +++ b/rscripts/asHeadlessQueryReader.py @@ -0,0 +1,260 @@ +# -*- coding: utf-8 *-* +import json +import glob +import re +import csv +import sys + + +def check_that_dict_has_equal_length(resultDict): + i = 0 + for key, value in resultDict.iteritems(): + if i == 0: + length = len(value) + if not length == len(value): + return False + i = i + 1 + return True + + +def read_query_of_runid(path, runName, runId, queryName, resultDict): + filename = runId + "-" + queryName + filepath = path + runName + "/" + filename + json_data = open(filepath, 'r') + resultList = [] + line = json_data.readline() + jsonLine = json.loads(line[:-2], encoding="ascii") + #In case its a pure list of numbers or strings + if len(jsonLine) == 1 and \ + isinstance(jsonLine[0], (int, float, long, complex, basestring)): + while line: + resultList.append(json.loads(line[:-2], encoding="ascii")[0]) + line = json_data.readline() + resultDict[queryName] = resultList + return resultDict + wrapperCounter = 0 + tempJsonLine = jsonLine + #Unwrapping the json lists, in case it is wrapped + while (tempJsonLine is not None) and len(tempJsonLine) == 1 and \ + isinstance(tempJsonLine, (list)) and \ + (not isinstance(tempJsonLine[0][0], (basestring))): + tempJsonLine = tempJsonLine[0] + wrapperCounter = wrapperCounter + 1 + #Checking if it conforms to the standard and starting the dictionary. + if tempJsonLine is None: + return None + elif len(tempJsonLine[0]) == 2: + return read_standard_conform_key_value_pairs(tempJsonLine, + wrapperCounter, runId, queryName, json_data, resultDict) + else: + #print("Non-Standard: " + queryName) + raise NameError("Query returns in " + runId + " ," + queryName + + " are not standard [Name, Value] for each tick!") + #return read_nonstandard_conform_key_value_pairs(tempJsonLine,\ + # wrapperCounter,runId,queryName,json_data,resultDict) + + +def read_nonstandard_conform_key_value_pairs(tempJsonLine, wrapperCounter, +runId, queryName, json_data, resultDict): + subElementNumber = 0 + for subelement in tempJsonLine: + for subsubelement in subelement: + if not len(subsubelement) == 2: + print(wrapperCounter) + print(subsubelement) + raise NameError("Query returns in " + runId + " ," + + queryName + " are not [Name, Value] for each tick!") + for content in subsubelement: + if isinstance(content, list): + raise NameError("Query returns in " + runId + " ," + + queryName + " are not [Name, Value] for each tick!") + resultDict[(queryName + "_" + + subsubelement[0]).encode("ascii")] = [subsubelement[1]] + subElementNumber = subElementNumber + 1 + #Reading the rest of the file + line = json_data.readline() + while line: + counter = 0 + tempJsonLine = json.loads(line[:-2], encoding="ascii") + while counter < wrapperCounter: + tempJsonLine = tempJsonLine[0] + counter = counter + 1 + subElementCounter = 0 + for subelement in tempJsonLine: + for subsubelement in subelement: + if not len(subsubelement) == 2: + raise NameError("Query returns should be \ + [Name, Value] for each tick!") + for content in subsubelement: + if isinstance(content, list): + raise NameError("Query returns should be \ + [Name, Value] for each tick!") + resultDict[(queryName + "_" + + subsubelement[0]).encode("ascii")].append(subsubelement[1]) + subElementCounter = subElementCounter + 1 + if not subElementCounter == subElementNumber: + raise NameError("Number of subresults is not consistent!") + line = json_data.readline() + #print(resultDict) + return resultDict + + +def read_standard_conform_key_value_pairs(tempJsonLine, wrapperCounter, runId, +queryName, json_data, resultDict): + subElementNumber = 0 + for subelement in tempJsonLine: + if not len(subelement) == 2: + print(wrapperCounter) + print(subelement) + raise NameError("Query returns in " + runId + " ," + queryName + + " are not [Name, Value] for each tick!") + for content in subelement: + if isinstance(content, list): + raise NameError("Query returns in " + runId + " ," + queryName + + " are not [Name, Value] for each tick!") + resultDict[(queryName + "_" + + subelement[0]).encode("ascii")] = [subelement[1]] + subElementNumber = subElementNumber + 1 + #Reading the rest of the file + line = json_data.readline() + while line: + counter = 0 + tempJsonLine = json.loads(line[:-2], encoding="ascii") + while counter < wrapperCounter: + tempJsonLine = tempJsonLine[0] + counter = counter + 1 + subElementCounter = 0 + for subelement in tempJsonLine: + if not len(subelement) == 2: + raise NameError("Query returns should be [Name, Value] for \ + each tick!") + for content in subelement: + if isinstance(content, list): + raise NameError("Query returns should be [Name, Value]\ + for each tick!") + resultDict[(queryName + "_" + + subelement[0]).encode("ascii")].append(subelement[1]) + subElementCounter = subElementCounter + 1 + if not subElementCounter == subElementNumber: + raise NameError("Number of subresults is not consistent!") + line = json_data.readline() + #print(resultDict) + return resultDict + + +def find_query_names_in_directory_for_runId(path, runName, runId): + listOfQueryPaths = glob.glob(path + runName + "/" + runId + "-*") + listOfQueries = [] + listOfTableQueries = [] + for query in listOfQueryPaths: + m = re.search('(?<={0}{1}/{2}-).*'.format(path, runName, runId), query) + if not m.group(0).startswith("TABLE_"): + listOfQueries.append(m.group(0)) + else: + listOfTableQueries.append(m.group(0)) + listOfQueries.sort() + listOfQueryPaths.sort() + #return listOfQueries,listOfQueryPaths + return listOfQueries, listOfTableQueries + + +def find_runIds_based_on_logfiles_and_runname(path, runName): + listOfQueryPaths = glob.glob(path + runName + "/*.log") + listOfRunIds = [] + for query in listOfQueryPaths: + m = re.search('(?<={0}{1}/).*'.format(path, runName), query) + n = re.sub("^(.*).log$", "\\1", m.group(0)) + listOfRunIds.append(n) + return listOfRunIds + + +def read_runId_to_dictionary(path, runName, runId, ignoredQueries): + print("Reading " + runId) + queryNames, tableQueryNames = find_query_names_in_directory_for_runId(path, + runName, runId) + for ignoredQuery in ignoredQueries: + queryNames.remove(ignoredQuery) + resultDict = {} + for queryName in queryNames: + singleQueryResult = read_query_of_runid(path, runName, runId, + queryName, resultDict) + if singleQueryResult is not None: + resultDict.update(singleQueryResult) + if not check_that_dict_has_equal_length(resultDict): + raise NameError("Results of uneven time step length in ." + runName) + return resultDict + + +def write_first_runid_dictionary_to_csv(path, runName, runId, +resultDict, noOfTicks): + queryNames = ["tick", "runId"] + queryNames = set(queryNames) + queryNames.update(resultDict.keys()) + with open(path + runName + ".csv", 'w') as csvfile: + csvwriter = csv.DictWriter(csvfile, fieldnames=queryNames) + headers = {} + for n in csvwriter.fieldnames: + headers[n] = n + csvwriter.writerow(headers) + i = 0 + while i < noOfTicks: + singleTickDict = {} + for key, value in resultDict.iteritems(): + singleTickDict.update({key: value[i]}) + singleTickDict.update({"tick": i}) + singleTickDict.update({"runId": runId}) + csvwriter.writerow(singleTickDict) + i = i + 1 + + +def write_following_runids_to_csv(path, runName, runId, resultDict, noOfTicks): + queryNames = {} + with open(path + runName + ".csv", 'rb') as csvtoupdate: + dictReader = csv.DictReader(csvtoupdate) + queryNames = dictReader.fieldnames + with open(path + runName + ".csv", 'a') as csvfile: + csvwriter = csv.DictWriter(csvfile, fieldnames=queryNames) + i = 0 + while i < noOfTicks: + singleTickDict = {} + for key, value in resultDict.iteritems(): + singleTickDict.update({key: value[i]}) + singleTickDict.update({"tick": i}) + singleTickDict.update({"runId": runId}) + csvwriter.writerow(singleTickDict) + i = i + 1 + + +def write_csv_for_run_name(path, runName, ignoredQueries): + runIds = find_runIds_based_on_logfiles_and_runname(path, runName) + totalRunIdNo = len(runIds) + j = 0 + for runId in runIds: + resultDict = read_runId_to_dictionary(path, runName, + runId, ignoredQueries) + noOfTicks = len(resultDict.items()[1][1]) + if j == 0: + write_first_runid_dictionary_to_csv(path, runName, runId, + resultDict, noOfTicks) + else: + write_following_runids_to_csv(path, runName, runId, + resultDict, noOfTicks) + j = j + 1 + percentage = 1.0 * j / totalRunIdNo * 100 + print((str(percentage) + "% done.")) + + +def main(outputPath, runName, ignoredQueries): + if(not outputPath.endswith("/")): + outputPath = outputPath + "/" + print((find_runIds_based_on_logfiles_and_runname(outputPath, runName))) + write_csv_for_run_name(outputPath, runName, ignoredQueries) + +if __name__ == "__main__": + if len(sys.argv[1:]) > 2: + main(sys.argv[1], sys.argv[2], sys.argv[3:]) + elif len(sys.argv[1:]) == 2: + main(sys.argv[1], sys.argv[2], []) + else: + print("This script needs to be called with: outputPath, \ + runName (, ignoredQueries)") diff --git a/rscripts/asHeadlessTableReader.py b/rscripts/asHeadlessTableReader.py new file mode 100644 index 00000000..d75e2566 --- /dev/null +++ b/rscripts/asHeadlessTableReader.py @@ -0,0 +1,93 @@ +import csv +import sys +import json + + +def read_tableQuery_of_runid(path, runName, runId, tableName): + resultDict = {} + filename = runId + "-" + "TABLE_" + tableName + filepath = path + runName + "/" + filename + json_data = open(filepath, 'r') + line = json_data.readline() + jsonLine = json.loads(line[:-2], encoding="ascii") + wrapperCounter = 0 + tempJsonLine = jsonLine + #Unwrapping the json lists, in case it is wrapped + while (tempJsonLine is not None) and len(tempJsonLine) == 1 and \ + isinstance(tempJsonLine, (list)) and \ + (not isinstance(tempJsonLine[0][0], (basestring))): + tempJsonLine = tempJsonLine[0] + wrapperCounter = wrapperCounter + 1 + headers = tempJsonLine[0] + tempJsonLine = tempJsonLine[1:] + headerNumber = 0 + for header in headers: + resultDict[(headers[headerNumber]).encode("ascii")] = [] + headerNumber = headerNumber + 1 + for subelement in tempJsonLine: + headerNumber = 0 + if not len(subelement) == len(headers): + raise NameError("Table length differs from header length!") + for content in subelement: + resultDict[(headers[headerNumber]).encode("ascii")].append(content) + headerNumber = headerNumber + 1 + line = json_data.readline() + while line and (line is not None) and isinstance(line, (list)): + counter = 0 + tempJsonLine = json.loads(line[:-2], encoding="ascii") + while counter < wrapperCounter: + tempJsonLine = tempJsonLine[0] + counter = counter + 1 + tempJsonLine = tempJsonLine[1:] + for subelement in tempJsonLine: + headerNumber = 0 + if not len(subelement) == len(headers): + raise NameError("Table length differs from header length!") + for content in subelement: + resultDict[(headers[headerNumber]). + encode("ascii")].append(content) + headerNumber = headerNumber + 1 + line = json_data.readline() + return resultDict + + +def write_tableResultDict_to_csv(path, runName, runId, tableName, +resultDict): + queryNames = resultDict.keys() + #queryNames.update(resultDict.keys()) + noOfTicks = len(resultDict.items()[1][1]) + with open(path + runId + "-" + tableName + ".csv", 'w') as csvfile: + csvwriter = csv.DictWriter(csvfile, fieldnames=queryNames) + csvwriter.writeheader() + i = 0 + while i < noOfTicks: + singleTickDict = {} + for key, value in resultDict.iteritems(): + singleTickDict.update({key: value[i]}) + csvwriter.writerow(singleTickDict) + i = i + 1 + + +def write_tableQuery_to_csv(path, runName, runId, tableName): + resultDict = read_tableQuery_of_runid(path, runName, runId, tableName) + write_tableResultDict_to_csv(path, runName, runId, tableName, resultDict) + + +def main(path, runName, runId, tableName): + if(not path.endswith("/")): + path = path + "/" + write_tableQuery_to_csv(path, runName, runId, tableName) + +if __name__ == "__main__": + if len(sys.argv[1:]) == 4: + main(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]) + else: + print("This script needs to be called with: outputPath, \ + runName, runId, tableName") + +#path='/home/jrichstein/Desktop/emlabGen/output/' +#runName="scriptTest" +#tableName='PowerPlantDispatchPlans' +#runId="scriptTest-1" + +#main(path, runName, runId, tableName) diff --git a/rscripts/batchRunAnalysis.R b/rscripts/batchRunAnalysis.R index d8c21046..db32a0e1 100644 --- a/rscripts/batchRunAnalysis.R +++ b/rscripts/batchRunAnalysis.R @@ -146,11 +146,14 @@ plotTimeSeriesWithConfidenceIntervalByFacettedGroup <- function(df, variable, yl #stat_summary(aes_string(fill="modelRun"), fun.data=fun.data, conf.int=conf.int, geom="smooth") + stat_summary(fun.data=fun.data, conf.int=conf.int, geom="smooth", colour="black") + stat_summary(fun.data=fun.data, conf.int=conf.int2, geom="smooth", colour="black")+ + stat_summary(fun.y="mean", conf.int=.95, geom="smooth", lty="dashed", colour="black") + + #facet_grid(. ~ modelRun)+ facet_wrap(~ modelRun, nrow=nrow)+ theme(legend.position="none")+ xlab("Time [a]")+ - ylab(ylabel) + ylab(ylabel)+ + scale_linetype_manual(breaks=c("a","b")) }