Ejemplo n.º 1
0
def getDailyHydroPotentialsUC(fleetUC, hydroData, daysUC, ucYear):
    """ Compiles dict with daily hydro potentials

    Compiles dict with daily hydro potentials for individual hydro gens for UC run from list with monthly potentials

    :param fleetUC: 2d list with complete generator fleet
    :param hydroData: 2d list with monthly hydro potentials for simulation year
    :param daysUC: list with days of the year (1-365) that UC simulation will be performed
    :return: dict with {genID: hydro energy MWh}
    """

    headers = fleetUC[0]
    plantCol = headers.index('PlantType')
    orisCol = headers.index('ORIS Plant Code')
    capacityCol = headers.index('Capacity (MW)')
    hydroFleet = [headers
                  ] + [row for row in fleetUC if row[plantCol] == 'Hydro']

    hydroDailyPotential = dict()

    for rowFleet in hydroFleet[1:]:

        genSymbol = createGenSymbol(rowFleet, headers)

        # get row in hydroFleet of this generator
        rowHydroData = [
            row for row in hydroData[1:] if row[0] == rowFleet[orisCol]
        ]

        if len(rowHydroData) > 0:
            rowHydroData = rowHydroData[0]

            capacity = float(rowFleet[capacityCol])

            hydroEnergyAux = 0
            for d in daysUC:
                date_aux = dt.date(ucYear, 1, 1) + dt.timedelta(days=d - 1)
                imonth = date_aux.month
                ndays = calendar.monthrange(ucYear, imonth)[1]
                hydroEnergyAux = hydroEnergyAux + float(
                    rowHydroData[imonth]) / ndays

            hydroDailyPotential[genSymbol] = hydroEnergyAux
            #hydroDailyPotential[genSymbol] = hydroEnergyAux/(capacity*len(daysUC)*24)

        else:
            hydroDailyPotential[genSymbol] = 0

    return hydroDailyPotential
Ejemplo n.º 2
0
def assignPotentialsToMissingUnits(unitsNoData, fleet, seasonDict, repHrs):
    """For ORIS units not in PNNL data, assign them potential for season based on
    average potential as CF of rest of fleet for that season. Modifies seasonDict to include other units

    :param unitsNoData: gen symbols (oris+unit ID) for units w/out data, ,
    :param fleet: 2d list with gen fleet
    :param seasonDict: dict of season:genSymbol:potential
    :param repHrs: 1d list of rep hrs per season
    """
    plantCol = fleet[0].index('PlantType')
    capacCol = fleet[0].index('Capacity (MW)')
    hydroUnits = [row for row in fleet[1:] if row[plantCol] == 'Hydro']
    genSymbols = [createGenSymbol(row, fleet[0]) for row in hydroUnits]
    capacs = [float(row[capacCol]) for row in hydroUnits]
    fleetAvgCF = getFleetAverageCF(genSymbols, capacs, seasonDict, repHrs)
    for genSymbol in unitsNoData:
        seasonDict[genSymbol] = capacs[genSymbols.index(genSymbol)] * len(
            repHrs) * fleetAvgCF
Ejemplo n.º 3
0
def setupHourlyPHResults(genByPlant, fleetUC):
    """Create empty 2d list for pumped hydro variables using genByPlant as a template

    :param genByPlant: empty 2d list template with all generators
    :param fleetUC: 2d list with gen data
    :return: Empty 2d lists for pumphydroSoc (state of charge) and pumphydroCharge (charge)
    """

    # get list of Ids of Pumped Hydro Plants
    plantTypeCol = fleetUC[0].index('PlantType')
    phIDs = [createGenSymbol(row, fleetUC[0]) for row in fleetUC[1:] if row[plantTypeCol] == 'Pumped Storage']

    # state of charge
    pumphydroSoc = [copy.deepcopy(genByPlant[0])] + [copy.deepcopy(row) for row in genByPlant if row[0] in phIDs]

    # charge
    pumphydroCharge = [copy.deepcopy(genByPlant[0])] + [copy.deepcopy(row) for row in genByPlant if row[0] in phIDs]

    return pumphydroSoc, pumphydroCharge
Ejemplo n.º 4
0
def markAndSaveRetiredUnitsFromAge(genFleet, currYear,
                                   capacExpRetiredUnitsByAge, dataRoot,
                                   scenario):
    """Retire units by age

    Marks units that retire in gen fleet list due to lifetime and modifies them in list.
    The function returns nothing, but modifies list genFleet.

    :param genFleet: (2d list) gen fleet
    :param currYear: (int) current CE year
    :param capacExpRetiredUnitsByAge: (2d list) list of units retired each year
    :param dataRoot: list of units retired each year (2d list)
    :param scenario: (string) name of plant retirement scenario
    """
    lifetimeByPlantTypeDict = importPlantTypeLifetimes(dataRoot, scenario)
    renewablePlantTypes = [
        'Geothermal', 'Hydro', 'Pumped Storage', 'Wind', 'Solar PV'
    ]
    onlineYearCol = genFleet[0].index('On Line Year')
    plantTypeCol = genFleet[0].index('PlantType')
    retiredByAgeCol = genFleet[0].index('YearRetiredByAge')
    retiredByCECol = genFleet[0].index('YearRetiredByCE')
    retiredUnitsByAge = []

    for row in genFleet[1:]:
        if row[retiredByAgeCol] == '' and row[
                retiredByCECol] == '':  # if not already retired by age or CE
            (onlineYear, plantType) = (row[onlineYearCol], row[plantTypeCol])
            lifetimePlantType = lifetimeByPlantTypeDict[plantType]
            if int(onlineYear) + lifetimePlantType < currYear:
                if plantType in renewablePlantTypes:
                    readdRenewablePlant(
                        genFleet, row,
                        currYear)  # readd to fleet before add retired year!

                row[retiredByAgeCol] = currYear
                retiredUnitsByAge.append(createGenSymbol(row, genFleet[0]))

    capacExpRetiredUnitsByAge.append(['UnitsRetiredByAge' + str(currYear)] +
                                     retiredUnitsByAge)
Ejemplo n.º 5
0
def setupHourlyGenByPlant(hours,fleetUC):
    genSymbols = [createGenSymbol(row,fleetUC[0]) for row in fleetUC[1:]]
    (genByPlant,genToRow,hourToCol) = setupEmptyHourly2dList(genSymbols,hours,'genID')
    return (genByPlant,genToRow,hourToCol)
Ejemplo n.º 6
0
def compute_max_daily_hydro(fleet, currYear, genparam, gcm):
    """ Converts monthly hydro capacity for each plant to daily hydro capacity

    This conversion follows a simple linear rule with simulated water releases simulated by PNNL.

    .. math::
       P^{MAX}_{day} = P_{month}^{PNNL}\\frac{r_{day}^{PNNL}}{\sum_{day \in month} r_{day}^{PNNL}}


    :param fleet: (2d list) gen fleet
    :param currYear: (int) current year
    :param dataRoot: (string) folder with input data
    :return: dictionary with daily hydro capacity {gensymbol: 1d list of daily capacities}
    """

    # reads monthly hydro potential for year currYear (in MWh)
    hydroPotentials = importHydroPotentialGen(currYear, genparam, gcm=gcm)

    # reads daily water releases for year currYear
    daily_releases = importHydroDailyReleases(currYear,
                                              genparam.dataRoot,
                                              gcm=gcm)

    plantCol, orisCol = fleet[0].index('PlantType'), fleet[0].index(
        'ORIS Plant Code')
    zoneCol = fleet[0].index('Region Name')
    hydroUnits = [row for row in fleet[1:] if row[plantCol] == 'Hydro']

    dailyPotentialDict = dict()

    for row in hydroUnits:

        # oris is a string value
        oris, zone, genSymbol = row[orisCol], row[zoneCol], createGenSymbol(
            row, fleet[0])

        # in daily releases oris code is an integer. So convert variable oris to integer here
        daily_releases_unit = daily_releases[daily_releases['oris_id'] == int(
            oris)]

        dailyPotential = list()

        # loop through days of year (no leap years)
        for m in range(1, 13):
            potMonth, hasData = getMonthsPotential(oris, hydroPotentials, [m])

            # get release daily values for this unit in month m
            values_in_month = daily_releases_unit[
                daily_releases_unit['time'].dt.month ==
                m]['streamflow_cms'].values

            # total accumulated releases for this unit in month m
            monthlyReleasesTot = values_in_month.sum()

            dailyPotential = dailyPotential + [
                potMonth * (val / monthlyReleasesTot)
                for val in values_in_month
            ]

        dailyPotentialDict[genSymbol] = dailyPotential

    return dailyPotentialDict
Ejemplo n.º 7
0
def getHydroEPotential(fleet, demandZonal, repAndSpeHoursDict, currYear,
                       genparam, curtailparam):
    """Computes maximum hydro potential for each hydro generator

    This function computes the maximum hydro potential for each hydro generator using PNNL data. Hydro potential is
    indexed by hydro unit and time block (special hours, summer, winter, ...). This max hydro potential will be used
    as upper bound in hourly hydro generation by the GAMS model. Scales potential

    July 2018: Currently we have only one hydro potential value per season. The objective is to decompose monthly
    potential to daily potential

    :param fleet: gen fleet
    :param demandZonal: zonal demand (dict)
    :param repAndSpeHoursDict: rep hrs per season or special block (dict of block:rep hrs, where seasons are labeled by name and special hours are 'special')
    :param currYear: current year
    :param genparam: object of class Generalparameters
    :param curtailparam: object of class Curtailmentparameters

    :return: nested dict of {gcm:{season:{genSymbol:generation potential}}}
    """

    hydroPotentials = {
        gcm: importHydroPotentialGen(currYear, genparam, gcm)
        for gcm in curtailparam.listgcms
    }

    hydroPotentialsTotal = dict()

    for gcm in repAndSpeHoursDict:
        hydroPotPerSeason = dict()
        plantCol, orisCol = fleet[0].index('PlantType'), fleet[0].index(
            'ORIS Plant Code')
        zoneCol = fleet[0].index('Region Name')
        hydroUnits = [row for row in fleet[1:] if row[plantCol] == 'Hydro']
        for season in repAndSpeHoursDict[gcm]:
            repHrs = repAndSpeHoursDict[gcm][season]
            months = getMonthsOfRepHrs(repHrs)
            monthlyDemandZonal = getMonthlyDemand(demandZonal[gcm], months)
            repHrsDemandZonal = getRepHrsDemand(demandZonal[gcm], repHrs)
            seasonDict, unitsNoData = dict(), list()

            for row in hydroUnits:
                oris, zone, genSymbol = row[orisCol], row[
                    zoneCol], createGenSymbol(row, fleet[0])
                potential, hasData = getMonthsPotential(
                    oris, hydroPotentials[gcm], months)

                if not hasData:
                    unitsNoData.append(genSymbol)
                else:
                    seasonDict[genSymbol] = potential * repHrsDemandZonal[
                        zone] / monthlyDemandZonal[zone]

            if len(unitsNoData) > 0:
                assignPotentialsToMissingUnits(unitsNoData, fleet, seasonDict,
                                               repHrs)

            hydroPotPerSeason[season] = seasonDict

        hydroPotentialsTotal[gcm] = hydroPotPerSeason

    return hydroPotentialsTotal