Example #1
0
def test_liion_dc_connected_dc_sizing():
    model = batt.default("GenericBatteryCommercial")
    model.BatteryCell.batt_chem = 1
    model.Inverter.inverter_model = 0
    model.Inverter.inv_snl_eff_cec = 50
    model.BatterySystem.batt_ac_or_dc = 0
    BatteryTools.battery_model_sizing(model, 100, 400, 500)
    assert (model.BatterySystem.batt_computed_bank_capacity == pytest.approx(
        400, 1))
    assert (model.BatterySystem.batt_power_discharge_max_kwdc == pytest.approx(
        100, 1))
    assert (model.BatterySystem.batt_power_charge_max_kwdc == pytest.approx(
        100, 1))
    assert (model.BatterySystem.batt_power_discharge_max_kwac == pytest.approx(
        49, 1))
    assert (model.BatterySystem.batt_power_charge_max_kwac == pytest.approx(
        204, 1))
    assert (model.BatterySystem.batt_current_discharge_max == pytest.approx(
        200, 1))
    assert (model.BatterySystem.batt_current_charge_max == pytest.approx(
        200, 1))

    model.Inverter.inv_snl_eff_cec = 100
    model.BatterySystem.batt_ac_or_dc = 0
    BatteryTools.battery_model_sizing(model, 100, 400, 500)
    assert (model.BatterySystem.batt_computed_bank_capacity == pytest.approx(
        400, 1))
    assert (model.BatterySystem.batt_power_discharge_max_kwdc == pytest.approx(
        100, 1))
    assert (model.BatterySystem.batt_power_charge_max_kwdc == pytest.approx(
        100, 1))
    assert (model.BatterySystem.batt_power_discharge_max_kwac == pytest.approx(
        98, 1))
    assert (model.BatterySystem.batt_power_charge_max_kwac == pytest.approx(
        102, 1))
Example #2
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()))
Example #3
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'])
Example #4
0
def test_leadacid():
    model = batt.default("GenericBatteryCommercial")
    model.BatteryCell.batt_chem = 0
    assert (model.BatterySystem.batt_computed_bank_capacity != pytest.approx(
        100, .5))
    assert (model.BatterySystem.batt_power_charge_max_kwdc != pytest.approx(
        50, 0.5))

    BatteryTools.battery_model_sizing(model, 100, 400, 500)
    assert (model.BatterySystem.batt_computed_strings == 261)
    assert (model.BatterySystem.batt_computed_series == 139)
    assert (model.BatterySystem.batt_computed_bank_capacity == pytest.approx(
        417, 1))
    assert (model.BatterySystem.batt_power_charge_max_kwdc == pytest.approx(
        96.29, 1))
Example #5
0
    def system_capacity_voltage(self, capacity_voltage: tuple):
        size_kwh = capacity_voltage[0]
        voltage_volts = capacity_voltage[1]

        # sizing function may run into future issues if size_kwh == 0 is allowed
        if size_kwh == 0:
            size_kwh = 1e-7

        BatteryTools.battery_model_sizing(self._system_model,
                                          0.,
                                          size_kwh,
                                          voltage_volts,
                                          module_specs=Battery.module_specs)
        logger.info("Battery set system_capacity to {} kWh".format(size_kwh))
        logger.info("Battery set system_voltage to {} volts".format(voltage_volts))
Example #6
0
def test_liion_ac_connected_ac_sizing():
    model = batt.default("GenericBatteryCommercial")
    model.BatteryCell.batt_chem = 1
    model.BatterySystem.batt_ac_or_dc = 1  # ac
    BatteryTools.battery_model_sizing(model, 100, 400, 500)
    assert (model.BatterySystem.batt_computed_bank_capacity == pytest.approx(
        417, 1))
    assert (model.BatterySystem.batt_power_discharge_max_kwdc == pytest.approx(
        104, 1))
    assert (model.BatterySystem.batt_power_charge_max_kwdc == pytest.approx(
        96, 1))
    assert (model.BatterySystem.batt_power_discharge_max_kwac == pytest.approx(
        100, 1))
    assert (model.BatterySystem.batt_power_charge_max_kwac == pytest.approx(
        100, 1))
    assert (model.BatterySystem.batt_current_discharge_max == pytest.approx(
        208, 1))
    assert (model.BatterySystem.batt_current_charge_max == pytest.approx(
        192, 1))
Example #7
0
def test_calculate_thermal_params():
    input_dict = {
        'mass': 20272.2,
        'surface_area': 23.9614,
        'original_capacity': 4000.323,
        'desired_capacity': 2000
    }
    output = BatteryTools.calculate_thermal_params(input_dict)
    assert (output['mass'] == pytest.approx(10135.28))
    assert (output['surface_area'] == pytest.approx(15.09392))
Example #8
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'])
Example #9
0
File: models.py Project: NREL/vapor
    def _size_battery(self):
        if self.storage:
            # --- Force duration to be 0, 2, 4 ---
            desired_duration = self.system_config['BatteryTools'][
                'desired_capacity']

            if desired_duration < 1:
                self.battery_duration = 0
                self.storage = False
            elif desired_duration < 2:
                self.battery_duration = 2
            elif desired_duration <= 4:
                self.battery_duration = 4

            self.system_config['BatteryTools'][
                'desired_capacity'] = self.battery_duration * self.system_config[
                    'BatteryTools'][
                        'desired_power']  #convert capacity expressed in hours to kWh
            self.battery_params = self.battery_sizing_config = bt.battery_model_sizing(
                model=self.battery, **self.system_config['BatteryTools'])
        else:
            self.battery_params = None
Example #10
0
 def chemistry(self, battery_chemistry: str):
     BatteryTools.battery_model_change_chemistry(self._system_model, battery_chemistry)
     self._chemistry = battery_chemistry
     logger.info("Battery chemistry set to {}".format(battery_chemistry))