From fc3c6b89b7a23e34cd39b4412e5b0a2e4bec0899 Mon Sep 17 00:00:00 2001 From: Bennet Meyers Date: Thu, 25 Jul 2013 16:25:17 -0700 Subject: [PATCH 1/5] ignore pyo --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index dd6e9df..5da14e5 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ pvmismatch.sublime-project pvmismatch.sublime-workspace /benchmark_* *.orig +*.pyo From 2cc4f4f3812855efa2b32f9c55d71cbaf767d127 Mon Sep 17 00:00:00 2001 From: Bennet Meyers Date: Thu, 6 Oct 2016 16:13:04 -0700 Subject: [PATCH 2/5] Adding back in .gitignore --- .gitignore | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5b04d77 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# ide +.spyderproject +.project +.pydevproject +.settings/ +.idea/ +pvmismatch.sublime-project +pvmismatch.sublime-workspace + +# files +*.pyc +*.orig + +# build +dist/ +pvmismatch.egg-info/ +build/ +Makefile + +# docs +!docs/_templates/ +_*/ + +# test +testPV/ +benchmark_*/ + +# virtualenv +venv/ From 21ded8e78b3d07bba9be9dd468623ef2c1ba5575 Mon Sep 17 00:00:00 2001 From: Bennet Meyers Date: Fri, 7 Oct 2016 00:19:21 -0700 Subject: [PATCH 3/5] setSuns method at the module level can now take a scalar to set an entire module. Can also still use len-1 list. Issue #33 --- pvmismatch/pvmismatch_lib/pvstring.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pvmismatch/pvmismatch_lib/pvstring.py b/pvmismatch/pvmismatch_lib/pvstring.py index 3cfa028..54672f0 100644 --- a/pvmismatch/pvmismatch_lib/pvstring.py +++ b/pvmismatch/pvmismatch_lib/pvstring.py @@ -94,7 +94,10 @@ def setSuns(self, Ee): if hasattr(cell_Ee, 'keys'): self.pvmods[pvmod].setSuns(**cell_Ee) else: - self.pvmods[pvmod].setSuns(*cell_Ee) + try: + self.pvmods[pvmod].setSuns(*cell_Ee) + except TypeError: + self.pvmods[pvmod].setSuns(cell_Ee) # update modules self.Istring, self.Vstring, self.Pstring = self.calcString() From f104148f79659b906a14b00ab031e65d519eae2f Mon Sep 17 00:00:00 2001 From: Bennet Meyers Date: Mon, 10 Oct 2016 23:55:41 -0700 Subject: [PATCH 4/5] Adding tests for improved setSuns method. Added ducktyping to string-level setting as well. Relaxed constraint on test_pvcell.test_calc_series to allow for change due to Numpy update. --- pvmismatch/pvmismatch_lib/pvstring.py | 21 ++++++----- pvmismatch/tests/test_pvcell.py | 2 +- pvmismatch/tests/test_setsuns.py | 50 +++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 pvmismatch/tests/test_setsuns.py diff --git a/pvmismatch/pvmismatch_lib/pvstring.py b/pvmismatch/pvmismatch_lib/pvstring.py index 54672f0..02b32ea 100644 --- a/pvmismatch/pvmismatch_lib/pvstring.py +++ b/pvmismatch/pvmismatch_lib/pvstring.py @@ -90,14 +90,19 @@ def setSuns(self, Ee): for pvmod in iter(self.pvmods): pvmod.setSuns(Ee) else: - for pvmod, cell_Ee in Ee.iteritems(): - if hasattr(cell_Ee, 'keys'): - self.pvmods[pvmod].setSuns(**cell_Ee) - else: - try: - self.pvmods[pvmod].setSuns(*cell_Ee) - except TypeError: - self.pvmods[pvmod].setSuns(cell_Ee) + try: + for pvmod, cell_Ee in Ee.iteritems(): + if hasattr(cell_Ee, 'keys'): + self.pvmods[pvmod].setSuns(**cell_Ee) + else: + try: + self.pvmods[pvmod].setSuns(*cell_Ee) + except TypeError: + self.pvmods[pvmod].setSuns(cell_Ee) + except AttributeError: + Ee = Ee[0] + for pvmod in iter(self.pvmods): + pvmod.setSuns(Ee) # update modules self.Istring, self.Vstring, self.Pstring = self.calcString() diff --git a/pvmismatch/tests/test_pvcell.py b/pvmismatch/tests/test_pvcell.py index 84d5119..ce395a6 100644 --- a/pvmismatch/tests/test_pvcell.py +++ b/pvmismatch/tests/test_pvcell.py @@ -59,7 +59,7 @@ def test_calc_series(): # noinspection PyTypeChecker ok_(np.allclose(i, iv[0])) # noinspection PyTypeChecker - ok_(np.allclose(v, iv[1])) + ok_(np.allclose(v, iv[1], rtol=1e-4)) return i, v diff --git a/pvmismatch/tests/test_setsuns.py b/pvmismatch/tests/test_setsuns.py new file mode 100644 index 0000000..73c0046 --- /dev/null +++ b/pvmismatch/tests/test_setsuns.py @@ -0,0 +1,50 @@ +""" +Test for setSuns method. + +Bennet Meyers 10/10/16 +""" + +import numpy as np +from nose.tools import ok_ +from pvmismatch.pvmismatch_lib.pvsystem import PVsystem + + +def test_basic(): + pvsys = PVsystem() + pvsys.setSuns(.75) + ok_(np.isclose(pvsys.Pmp, 23907.936630685774)) + + +def test_dictionary(): + pvsys = PVsystem() + Ee = {1: {3: {'cells': np.arange(30), 'Ee': [.25] * 30}}} + pvsys.setSuns(Ee) + ok_(np.isclose(pvsys.Pmp, 31618.1813179655)) + + +def test_set_mod_1(): + pvsys = PVsystem() + Ee = {1: {3: [.2], 0: [.1]}} + pvsys.setSuns(Ee) + ok_(np.isclose(pvsys.Pmp, 29566.303088387336)) + + +def test_set_mod_2(): + pvsys = PVsystem() + Ee = {1: {3: .2, 0: .1}} + pvsys.setSuns(Ee) + ok_(np.isclose(pvsys.Pmp, 29566.303088387336)) + + +def test_set_str_1(): + pvsys = PVsystem() + Ee = {1: [.1]} + pvsys.setSuns(Ee) + ok_(np.isclose(pvsys.Pmp, 29136.544447716446)) + + +def test_set_str_2(): + pvsys = PVsystem() + Ee = {1: .1} + pvsys.setSuns(Ee) + ok_(np.isclose(pvsys.Pmp, 29136.544447716446)) From 01039227621c2263489545d637b07f7ffada2278 Mon Sep 17 00:00:00 2001 From: Bennet Meyers Date: Mon, 23 Jan 2017 17:22:07 -0800 Subject: [PATCH 5/5] Cell cashing for each PVmodule instance. Only unique cells are stored in memory. Identical cells within a single module point to the same object in memory. --- pvmismatch/pvmismatch_lib/pvcell.py | 7 +++ pvmismatch/pvmismatch_lib/pvmodule.py | 66 ++++++++++++++++++++++++--- 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/pvmismatch/pvmismatch_lib/pvcell.py b/pvmismatch/pvmismatch_lib/pvcell.py index 28f0566..818bdfd 100644 --- a/pvmismatch/pvmismatch_lib/pvcell.py +++ b/pvmismatch/pvmismatch_lib/pvcell.py @@ -98,6 +98,13 @@ def update(self, **kwargs): for k, v in kwargs.iteritems(): setattr(self, k, v) + @property + def dictionary(self): + d = {'Rs': self.Rs, 'Rsh': self.Rsh, 'Isat1_T0': self.Isat1_T0, 'Isat2': self.Isat2, 'Isc0_T0': self.Isc0_T0, + 'aRBD': self.aRBD, 'bRBD': self.bRBD, 'VRBD': self.VRBD, 'nRBD': self.nRBD, 'Eg': self.Eg, + 'alpha_Isc': self.alpha_Isc, 'Tcell': self.Tcell, 'Ee': self.Ee, 'pvconst': self.pvconst} + return d + @property def Vt(self): """ diff --git a/pvmismatch/pvmismatch_lib/pvmodule.py b/pvmismatch/pvmismatch_lib/pvmodule.py index 3c557c0..b3cbf66 100644 --- a/pvmismatch/pvmismatch_lib/pvmodule.py +++ b/pvmismatch/pvmismatch_lib/pvmodule.py @@ -175,13 +175,28 @@ def __init__(self, cell_pos=STD96, pvcells=None, pvconst=PVconstants(), # PVcell.calcCell() creates new np.ndarray if attributes change pvcells = PVcell(pvconst=self.pvconst) if isinstance(pvcells, PVcell): - pvcells = [copy(pvcells) for _ in xrange(self.numberCells)] + cashed_cells = [pvcells] + pvcells = [pvcells] * self.numberCells + else: + cashed_cells = [pvcells[0]] + cashed_dicts = [pvcells[0].dictionary] + append_cells = cashed_cells.append + append_dicts = cashed_dicts.append + for ind, acell in enumerate(pvcells): + if ind > 0: # skip first entry, as we just used it + if acell.dictionary in cashed_dicts: # check if this cell is identical to a previous one + idx = cashed_dicts.index(acell.dictionary) + pvcells[ind] = cashed_cells[idx] # if so, overwrite entry with pointer to cashed cell + else: # otherwise, add the unique cell to cashed lists + append_cells(acell) + append_dicts(acell.dictionary) if len(pvcells) != self.numberCells: # TODO: use pvexception raise Exception( "Number of cells doesn't match cell position pattern." ) self.pvcells = pvcells #: list of `PVcell` objects in this `PVmodule` + self.cashed_cells = cashed_cells self.numSubStr = len(self.cell_pos) #: number of substrings self.subStrCells = [len(_) for _ in self.cell_pos] #: cells per substr # initialize members so PyLint doesn't get upset @@ -235,21 +250,60 @@ def setSuns(self, Ee, cells=None): """ if cells is None: if np.isscalar(Ee): - for pvc in self.pvcells: + # Set all cells to the same irradiance. This can be achieved by only setting the irradiance on the + # cashed cells. No regard needs to be taken for keeping track of unique cells + for pvc in self.cashed_cells: pvc.Ee = Ee elif np.size(Ee) == self.numberCells: - for pvc, Ee_idx in zip(self.pvcells, Ee): - pvc.Ee = Ee_idx + cashed_dicts = [acell.dictionary for acell in self.cashed_cells] + append_cells = self.cashed_cells.append + append_dicts = cashed_dicts.append + for ind, val in zip(self.pvcells, Ee): + pvc, Ee_idx = val + pvcell_dict = pvc.dictionary + pvcell_dict['Ee'] = Ee_idx + if pvcell_dict in cashed_dicts: # Check if this cell has already been made + idx = cashed_dicts.index(pvcell_dict) + self.pvcells[ind] = self.cashed_cells[idx] # If so set pointer to existing cell + else: # Otherwise, make a new copy of the cell and set the new Ee value + new_cell = copy(pvc) + new_cell.Ee = Ee_idx + self.pvcells[ind] = new_cell + append_cells(new_cell) + append_dicts(new_cell.dictionary) else: raise Exception("Input irradiance value (Ee) for each cell!") else: + cashed_dicts = [acell.dictionary for acell in self.cashed_cells] + append_cells = self.cashed_cells.append + append_dicts = cashed_dicts.append Ncells = np.size(cells) if np.isscalar(Ee): for cell_idx in cells: - self.pvcells[cell_idx].Ee = Ee + pvcell_dict = self.pvcells[cell_idx].dictionary + pvcell_dict['Ee'] = Ee + if pvcell_dict in cashed_dicts: + idx = cashed_dicts.index(pvcell_dict) + self.pvcells[cell_idx] = self.cashed_cells[idx] + else: + new_cell = copy(self.pvcells[cell_idx]) + new_cell.Ee = Ee + self.pvcells[cell_idx] = new_cell + append_cells(new_cell) + append_dicts(new_cell.dictionary) elif np.size(Ee) == Ncells: for cell_idx, Ee_idx in zip(cells, Ee): - self.pvcells[cell_idx].Ee = Ee_idx + pvcell_dict = self.pvcells[cell_idx].dictionary + pvcell_dict['Ee'] = Ee_idx + if pvcell_dict in cashed_dicts: + idx = cashed_dicts.index(pvcell_dict) + self.pvcells[cell_idx] = self.cashed_cells[idx] + else: + new_cell = copy(self.pvcells[cell_idx]) + new_cell.Ee = Ee_idx + self.pvcells[cell_idx] = new_cell + append_cells(new_cell) + append_dicts(new_cell.dictionary) else: raise Exception("Input irradiance value (Ee) for each cell!") self.Imod, self.Vmod, self.Pmod, self.Isubstr, self.Vsubstr = self.calcMod()