コード例 #1
0
def test_batterystateful_model_change_chemistry():
    model = battstfl.default("leadacid")
    original_capacity = model.ParamsPack.nominal_energy

    BatteryTools.battery_model_change_chemistry(model, 'nmcgraphite')

    params_new = battstfl.default('nmcgraphite').export()
    cell_params = params_new['ParamsCell']
    pack_params = params_new['ParamsPack']

    assert (model.value('nominal_energy') == pytest.approx(
        original_capacity, 0.1))
    assert (model.ParamsCell.Vnom_default == cell_params['Vnom_default'])
    assert (model.ParamsPack.Cp == pack_params['Cp'])
コード例 #2
0
def chem_batterystateful(model: BattStfl.BatteryStateful, chem):
    """
    Helper function for battery_model_change_chemistry
    """
    if type(model) != BattStfl.BatteryStateful:
        raise TypeError

    chem = chem.lower()

    if chem != 'LeadAcid' and chem != 'lfpgraphite' and chem != 'nmcgraphite':
        raise NotImplementedError

    if chem == 'leadacid':
        model.ParamsCell.chem = 0
    else:
        model.ParamsCell.chem = 1

    original_capacity = model.ParamsPack.nominal_energy
    original_voltage = model.ParamsPack.nominal_voltage

    params_dict = BattStfl.default(chem).export()

    for group in ('ParamsCell', 'ParamsPack'):
        for k, v in params_dict[group].items():
            model.value(k, v)

    battery_model_sizing(model, -1, original_capacity, original_voltage)
コード例 #3
0
    def __init__(self,
                 site: SiteInfo,
                 battery_config: dict,
                 chemistry: str = 'lfpgraphite',
                 system_voltage_volts: float = 500):
        """
        Battery Storage class based on PySAM's BatteryStateful Model

        :param site: Power source site information (SiteInfo object)
        :param battery_config: Battery configuration with the following keys:

            #. ``system_capacity_kwh``: float, Battery energy capacity [kWh]
            #. ``system_capacity_kw``: float, Battery rated power capacity [kW]

        :param chemistry: Battery storage chemistry, options include:

            #. ``LFPGraphite``: Lithium Iron Phosphate (Lithium Ion)
            #. ``LMOLTO``: LMO/Lithium Titanate (Lithium Ion)
            #. ``LeadAcid``: Lead Acid
            #. ``NMCGraphite``: Nickel Manganese Cobalt Oxide (Lithium Ion)

        :param system_voltage_volts: Battery system voltage [VDC]
        """
        for key in ('system_capacity_kwh', 'system_capacity_kw'):
            if key not in battery_config.keys():
                raise ValueError

        system_model = BatteryModel.default(chemistry)
        financial_model = Singleowner.from_existing(system_model, "StandaloneBatterySingleOwner")
        super().__init__("Battery", site, system_model, financial_model)

        self.Outputs = BatteryOutputs(n_timesteps=site.n_timesteps)
        self.system_capacity_kw: float = battery_config['system_capacity_kw']
        self.chemistry = chemistry
        BatteryTools.battery_model_sizing(self._system_model,
                                          battery_config['system_capacity_kw'],
                                          battery_config['system_capacity_kwh'],
                                          system_voltage_volts,
                                          module_specs=Battery.module_specs)
        self._system_model.ParamsPack.h = 20
        self._system_model.ParamsPack.Cp = 900
        self._system_model.ParamsCell.resistance = 0.001
        self._system_model.ParamsCell.C_rate = battery_config['system_capacity_kw'] / battery_config['system_capacity_kwh']

        # Minimum set of parameters to set to get statefulBattery to work
        self._system_model.value("control_mode", 0.0)
        self._system_model.value("input_current", 0.0)
        self._system_model.value("dt_hr", 1.0)
        self._system_model.value("minimum_SOC", 10.0)
        self._system_model.value("maximum_SOC", 90.0)
        self._system_model.value("initial_SOC", 10.0)

        self._dispatch = None

        logger.info("Initialized battery with parameters and state {}".format(self._system_model.export()))
コード例 #4
0
def test_battery_model_change_chemistry():
    model = batt.default("GenericBatterySingleOwner")
    original_capacity = model.value('batt_computed_bank_capacity')
    original_power = model.BatterySystem.batt_power_discharge_max_kwac

    BatteryTools.battery_model_change_chemistry(model, 'leadacid')

    params_new = battstfl.default('leadacid').export()
    cell_params = params_new['ParamsCell']
    pack_params = params_new['ParamsPack']

    assert (model.value('batt_computed_bank_capacity') == pytest.approx(
        original_capacity, 0.1))
    assert (model.value('batt_power_discharge_max_kwac') == pytest.approx(
        original_power, 0.1))
    assert (model.BatteryCell.batt_chem == cell_params['chem'])
    assert (model.BatteryCell.batt_calendar_choice ==
            cell_params['calendar_choice'])
    assert (model.BatteryCell.batt_Vnom_default == cell_params['Vnom_default'])
    assert (
        model.BatteryCell.LeadAcid_q10_computed == cell_params['leadacid_q10'])
    assert (model.BatteryCell.batt_Cp == pack_params['Cp'])

    BatteryTools.battery_model_change_chemistry(model, 'nmcgraphite')

    params_new = battstfl.default('nmcgraphite').export()
    cell_params = params_new['ParamsCell']
    pack_params = params_new['ParamsPack']

    assert (model.value('batt_computed_bank_capacity') == pytest.approx(
        original_capacity, 0.1))
    assert (model.value('batt_power_discharge_max_kwac') == pytest.approx(
        original_power, 0.1))
    assert (model.BatteryCell.batt_C_rate == cell_params['C_rate'])
    assert (model.BatteryCell.batt_calendar_choice ==
            cell_params['calendar_choice'])
    assert (model.BatteryCell.batt_Vexp == cell_params['Vexp'])
    assert (model.BatteryCell.batt_Cp == pack_params['Cp'])
コード例 #5
0
ファイル: test_stateful.py プロジェクト: mike-welch/pysam
def test_stateful():
    b = bt.default("NMCGraphite")
    b.Controls.control_mode = 1
    b.Controls.dt_hr = 1
    b.ParamsCell.minimum_SOC = 10
    b.ParamsCell.maximum_SOC = 90
    b.ParamsCell.initial_SOC = 50
    b.Controls.input_power = 0
    b.setup()
    assert (b.StatePack.SOC == approx(50))

    b.Controls.input_power = 0.5
    b.execute(0)
    assert (b.StatePack.SOC == approx(44.811, 1e-2))
コード例 #6
0
ファイル: test_stateful.py プロジェクト: NREL/pysam
def test_stateful_lmolto():
    b = bt.default("LMOLTO")
    b.Controls.control_mode = 1
    b.Controls.dt_hr = 1
    b.ParamsCell.minimum_SOC = 10
    b.ParamsCell.maximum_SOC = 90
    b.ParamsCell.initial_SOC = 50
    b.Controls.input_power = 0
    b.setup()
    assert (b.StatePack.SOC == approx(50))

    b.Controls.input_power = 0.5
    b.execute(0)
    assert (b.StatePack.SOC == approx(45.216, 1e-2))
コード例 #7
0
def chem_battery(model: Batt.Battery, chem):
    """
    Helper function for battery_model_change_chemistry
    """
    if type(model) != Batt.Battery:
        raise TypeError

    chem = chem.lower()

    if chem != 'leadacid' and chem != 'lfpgraphite' and chem != 'nmcgraphite':
        raise NotImplementedError

    if chem == 'leadacid':
        model.BatteryCell.batt_chem = 0
    else:
        model.BatteryCell.batt_chem = 1

    original_capacity = model.value('batt_computed_bank_capacity')
    original_voltage = model.BatteryCell.batt_Vnom_default * model.BatterySystem.batt_computed_series
    if model.BatterySystem.batt_ac_or_dc:
        original_power = model.BatterySystem.batt_power_discharge_max_kwac
    else:
        original_power = model.BatterySystem.batt_power_discharge_max_kwdc

    params_dict = BattStfl.default(chem).export()

    for group in ('ParamsCell', 'ParamsPack'):
        for k, v in params_dict[group].items():
            if k == 'nominal_voltage' or k == "T_room_init":
                continue
            elif k == 'cycling_matrix':
                k = 'batt_lifetime_matrix'
            elif 'leadacid' in k:
                k = 'LeadAcid' + k[8:]
                if 'tn' not in k:
                    k += '_computed'
            elif k == 'h':
                k = 'batt_h_to_ambient'
            elif k == 'nominal_energy':
                k = 'batt_computed_bank_capacity'
            elif k == 'cap_vs_temp':
                pass
            else:
                k = 'batt_' + k

            model.value(k, v)

    battery_model_sizing(model, original_power, original_capacity,
                         original_voltage)