Skip to content

implement voltage, current, power scaling function and method #171

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 20, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/sphinx/source/whatsnew/v0.3.3.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Enhancements
~~~~~~~~~~~~

* Adds the Erbs model. (:issue:`2`)
* Adds the ``scale_voltage_current_power`` function and ``PVSystem`` method
to support simple array modeling. (:issue:`159`)


Bug fixes
Expand Down
2 changes: 2 additions & 0 deletions pvlib/modelchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,8 @@ def run_model(self, times, irradiance=None, weather=None):
self.airmass['airmass_absolute'],
self.aoi)

self.dc = self.system.scale_voltage_current_power(self.dc)

self.ac = self.system.snlinverter(self.dc['v_mp'], self.dc['p_mp'])

return self
72 changes: 71 additions & 1 deletion pvlib/pvsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ class PVSystem(object):
See the :py:class:`LocalizedPVSystem` class for an object model that
describes an installed PV system.

The class supports basic system topologies consisting of:

* `N` total modules arranged in series
(`series_modules=N`, `parallel_modules=1`).
* `M` total modules arranged in parallel
(`series_modules=1`, `parallel_modules=M`).
* `NxM` total modules arranged in `M` strings of `N` modules each
(`series_modules=N`, `parallel_modules=M`).

The class is complementary to the module-level functions.

The attributes should generally be things that don't change about
Expand Down Expand Up @@ -69,6 +78,12 @@ class PVSystem(object):
module_parameters : None, dict or Series
Module parameters as defined by the SAPM, CEC, or other.

series_modules: int or float
See system topology discussion above.

parallel_modules: int or float
See system topology discussion above.

inverter : None, string
The model name of the inverters.
May be used to look up the inverter_parameters dictionary
Expand All @@ -95,7 +110,7 @@ def __init__(self,
surface_tilt=0, surface_azimuth=180,
albedo=None, surface_type=None,
module=None, module_parameters=None,
series_modules=None, parallel_modules=None,
series_modules=1, parallel_modules=1,
inverter=None, inverter_parameters=None,
racking_model='open_rack_cell_glassback',
**kwargs):
Expand Down Expand Up @@ -363,6 +378,27 @@ def snlinverter(self, v_dc, p_dc):
"""
return snlinverter(self.inverter_parameters, v_dc, p_dc)

def scale_voltage_current_power(self, data):
"""
Scales the voltage, current, and power of the DataFrames
returned by :py:func:`singlediode` and :py:func:`sapm`
by `self.series_modules` and `self.parallel_modules`.

Parameters
----------
data: DataFrame
Must contain columns `'v_mp', 'v_oc', 'i_mp' ,'i_x', 'i_xx',
'i_sc', 'p_mp'`.

Returns
-------
scaled_data: DataFrame
A scaled copy of the input data.
"""

return scale_voltage_current_power(data, voltage=self.series_modules,
current=self.parallel_modules)

def localize(self, location=None, latitude=None, longitude=None,
**kwargs):
"""Creates a LocalizedPVSystem object using this object
Expand Down Expand Up @@ -1668,3 +1704,37 @@ def snlinverter(inverter, v_dc, p_dc):
ac_power = ac_power.ix[0]

return ac_power


def scale_voltage_current_power(data, voltage=1, current=1):
"""
Scales the voltage, current, and power of the DataFrames
returned by :py:func:`singlediode` and :py:func:`sapm`.

Parameters
----------
data: DataFrame
Must contain columns `'v_mp', 'v_oc', 'i_mp' ,'i_x', 'i_xx',
'i_sc', 'p_mp'`.
voltage: numeric
The amount by which to multiply the voltages.
current: numeric
The amount by which to multiply the currents.

Returns
-------
scaled_data: DataFrame
A scaled copy of the input data.
`'p_mp'` is scaled by `voltage * current`.
"""

# as written, only works with a DataFrame
# could make it work with a dict, but it would be more verbose
data = data.copy()
voltages = ['v_mp', 'v_oc']
currents = ['i_mp' ,'i_x', 'i_xx', 'i_sc']
data[voltages] *= voltage
data[currents] *= current
data['p_mp'] *= voltage * current

return data
25 changes: 25 additions & 0 deletions pvlib/test/test_pvsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,31 @@ def test_PVSystem_singlediode_floats():
assert_almost_equals(expected[k], v, 5)


def test_scale_voltage_current_power():
data = pd.DataFrame(
np.array([[2, 1.5, 10, 8, 12, 0.5, 1.5]]),
columns=['i_sc', 'i_mp', 'v_oc', 'v_mp', 'p_mp', 'i_x', 'i_xx'],
index=[0])
expected = pd.DataFrame(
np.array([[6, 4.5, 20, 16, 72, 1.5, 4.5]]),
columns=['i_sc', 'i_mp', 'v_oc', 'v_mp', 'p_mp', 'i_x', 'i_xx'],
index=[0])
out = pvsystem.scale_voltage_current_power(data, voltage=2, current=3)


def test_PVSystem_scale_voltage_current_power():
data = pd.DataFrame(
np.array([[2, 1.5, 10, 8, 12, 0.5, 1.5]]),
columns=['i_sc', 'i_mp', 'v_oc', 'v_mp', 'p_mp', 'i_x', 'i_xx'],
index=[0])
expected = pd.DataFrame(
np.array([[6, 4.5, 20, 16, 72, 1.5, 4.5]]),
columns=['i_sc', 'i_mp', 'v_oc', 'v_mp', 'p_mp', 'i_x', 'i_xx'],
index=[0])
system = pvsystem.PVSystem(series_modules=2, parallel_modules=3)
out = system.scale_voltage_current_power(data)


def test_sapm_celltemp():
default = pvsystem.sapm_celltemp(900, 5, 20)
assert_almost_equals(43.509, default.ix[0, 'temp_cell'], 3)
Expand Down