Skip to content

Commit 4943742

Browse files
rayhickeychetan201
authored andcommitted
Fix mpp temperature sensitivity (#68)
* Merging v4 branch before submitting PR (#1) * improve python 3 compatibility in pvsys, strs and mods, require future * change dict.iter*() to iter*(dic), fix import * in tests * fix two diode test for SymPy-1.1.1 * fixes #55 * replace string keys in expected_data with the actual symbol objects, so instead of {'ic': IC}, use {ic: IC} where ic is the SymPy symbol object * replace string substitutions in expressions with the actual SymPy symbols, so use didv.subs(vc + rs*ic, 'vd') instead of didv.subs('vc + rs * ic(vc)', 'vd') which is error prone anyway, because the string could change, how do you know what string to use? * leave these subs in for now, but they are not necessary, since vd = vc + ic*rs can evaluate just fine * when numerically evaluating expressions using evalf(subs=expected_data) substitute values for the symbol di_dv, NOT the string "Derivative(ic(vc), vc)" since this doesn't work anymore! * don't substitute for the string 'ic(vc)', instead use the SymPy symbols ic, since parentheses don't work in SymPy substitutions or evaluations anymore, and this is more explicit since ic was defined as f(vc) when it was initialized! * freeze versions in requirements so this doesn't an issue again * ignore .spyproject - the new spyder-IDE project file Signed-off-by: Mark Mikofski <[email protected]> * update travis to test Py3, update setup with correct install and test reqs, add setup.cfg for universal wheel * ENH: BUG: add _calc_now flag to determine when cell is recalculated (GH59) (#61) * fixes #59 * add class attr _calc_now * override _calc_now with instance attribte at the end of constructor * check if _calc_now is True to decide to call self.calcCell() instead of checking for pvconst * use self.__dict__.update() instead of using super(PVcell, self).__setattr__(key, value) * in update, remove TODO, b/c even tho __dict__.update() would bypass __setattr__() then would have to check for floats, and still set _calc_now = True to trigger recalc, so instead, just set _calc_now = False first to turn calculations off, until all attr are set, then recalc * don't set pvcell.pvconst in pvstring * just raise an exception if they don't match for now * remove comments about "deepcopy" everywhere * oops, recalculate means _calc_now = True, duh! * remove commented legacy code in __setattr__, add comment in update re checking for floats * add test for new _calc_now flag * if _calc_now == False, then calcCell() is not called in __setattr__ * if _calc_now == True, then calcCell() is called in __setattr__ * BUG: pvconst is not a singleton, inconsistent, doesn't update (GH38) (#62) * fixes #59 * add class attr _calc_now * override _calc_now with instance attribte at the end of constructor * check if _calc_now is True to decide to call self.calcCell() instead of checking for pvconst * use self.__dict__.update() instead of using super(PVcell, self).__setattr__(key, value) * in update, remove TODO, b/c even tho __dict__.update() would bypass __setattr__() then would have to check for floats, and still set _calc_now = True to trigger recalc, so instead, just set _calc_now = False first to turn calculations off, until all attr are set, then recalc * don't set pvcell.pvconst in pvstring * just raise an exception if they don't match for now * remove comments about "deepcopy" everywhere * oops, recalculate means _calc_now = True, duh! * remove commented legacy code in __setattr__, add comment in update re checking for floats * add test for new _calc_now flag * if _calc_now == False, then calcCell() is not called in __setattr__ * if _calc_now == True, then calcCell() is called in __setattr__ * closes #38 consistent pvconst behavior * use duck typing to check pvstrs in PVsystem() for list, object or none * set pvconst from pvstrs if given * set numbstrs from pvstrs if given * set numbermods form pvstrs.pvmods if given * check that pvconst and pvmods are consistent * add tests * apply same changes in pvsystem from last commit to pvstr * change default pvconst arg to None * use duck typing to check if pvmods is a list, an object, or None * relax requirement that all strings have same number of modules * change pvsys.numberMods to a list of number of modules in each string * add test to check pvstring * check that all pvconst are the same for all modules * add docstring for members * also test that pvsys.numberMods is now a list * each item in list is number of modules in corresponding string * use ducktyping to determine if pvcells is list or obj or None * add missing blank lines and wrap long lines per pep8 * add pvcell object to pvcells docstring arg type * add tests in test_module to check that pvconst is the same for module and all cells * add test for update method * replace npts attr with a property * add new private _npts attribute, return for npts in getter * set npts, pts, negpts, Imod_pts, and Imod_negpts in setter * add test to show that changing npts changes pts, negpts, Imod_pts, and Imod_negpts * add pvsystem update method * make system calculation DRY, use everywhere calcSystem and calcMPP_IscVocFFeff are called back to back to set Isys, Vsys, Psys, etc. * also makes it explicity to recalc the system after a change, like change pvconst.npts * Update example.py Isat2 => Isat2_T0 * reverting changes - didn't mean to commit master * Isat2fix (#64) * Added temperature dependance for Isat2, i.e. Isat2(Tcell) * test for wide range of Tcell values - added after implementing Isat2 as a function of Tcell * generated new iv curve * Isat2 to Isat2_T0 * Update example.py Isat2 => Isat2_T0 * Update test_diode.py * Deleting the old IV curve * updated IV curve test file * fixed isat2 typos caused by replace * use entire iec matrix * Update .travis.yml added new pipy credentials * Fixes MPP Sensitivity to Temperature Fixes I_mp and V_mp sensitivity to temperature caused by selecting Isys and Vsys values at the maximum Psys index. This is accomplished by linear interpolation between the points surrounding MPP. * Correct indices * Cleanup * Changed setsuns test for new MPP calculation Also changed MPP calc to return float rather than array
1 parent 060b76c commit 4943742

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

pvmismatch/pvmismatch_lib/pvsystem.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,21 @@ def calcSystem(self):
9494

9595
def calcMPP_IscVocFFeff(self):
9696
mpp = np.argmax(self.Psys)
97-
Pmp = self.Psys[mpp]
98-
Vmp = self.Vsys[mpp]
99-
Imp = self.Isys[mpp]
97+
P = self.Psys[mpp - 1:mpp + 2]
98+
V = self.Vsys[mpp - 1:mpp + 2]
99+
I = self.Isys[mpp - 1:mpp + 2]
100+
# calculate derivative dP/dV using central difference
101+
dP = np.diff(P, axis=0) # size is (2, 1)
102+
dV = np.diff(V, axis=0) # size is (2, 1)
103+
Pv = dP / dV # size is (2, 1)
104+
# dP/dV is central difference at midpoints,
105+
Vmid = (V[1:] + V[:-1]) / 2.0 # size is (2, 1)
106+
Imid = (I[1:] + I[:-1]) / 2.0 # size is (2, 1)
107+
# interpolate to find Vmp
108+
Vmp = (-Pv[0] * np.diff(Vmid, axis=0) / np.diff(Pv, axis=0) + Vmid[0]).item()
109+
Imp = (-Pv[0] * np.diff(Imid, axis=0) / np.diff(Pv, axis=0) + Imid[0]).item()
110+
# calculate max power at Pv = 0
111+
Pmp = Imp * Vmp
100112
# calculate Voc, current must be increasing so flipup()
101113
Voc = np.interp(np.float64(0), np.flipud(self.Isys),
102114
np.flipud(self.Vsys))

pvmismatch/tests/test_setsuns.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,45 @@
1616
def test_basic():
1717
pvsys = PVsystem()
1818
pvsys.setSuns(.75)
19-
ok_(np.isclose(pvsys.Pmp, 23907.936630685774))
19+
ok_(np.isclose(pvsys.Pmp, 23903.15106763))
2020

2121

2222
def test_dictionary():
2323
pvsys = PVsystem()
2424
Ee = {1: {3: {'cells': np.arange(30), 'Ee': [.25] * 30}}}
2525
pvsys.setSuns(Ee)
26-
ok_(np.isclose(pvsys.Pmp, 31618.1813179655))
26+
ok_(np.isclose(pvsys.Pmp, 31610.21081155355))
2727

2828

2929
def test_set_mod_1():
3030
pvsys = PVsystem()
3131
Ee = {1: {3: [.2], 0: [.1]}}
3232
pvsys.setSuns(Ee)
33-
ok_(np.isclose(pvsys.Pmp, 29566.303088387336))
33+
ok_(np.isclose(pvsys.Pmp, 29559.422265401034))
3434

3535

3636
def test_set_mod_2():
3737
pvsys = PVsystem()
3838
Ee = {1: {3: .2, 0: .1}}
3939
pvsys.setSuns(Ee)
40-
ok_(np.isclose(pvsys.Pmp, 29566.303088387336))
40+
ok_(np.isclose(pvsys.Pmp, 29559.422265401034))
41+
# 1001 points linear: [ 29579.12191565]
4142

4243

4344
def test_set_str_1():
4445
pvsys = PVsystem()
4546
Ee = {1: [.1]}
4647
pvsys.setSuns(Ee)
47-
ok_(np.isclose(pvsys.Pmp, 29136.544447716446))
48+
ok_(np.isclose(pvsys.Pmp, 29133.81083801798))
49+
# 1001 points linear: [ 29141.73034719]
4850

4951

5052
def test_set_str_2():
5153
pvsys = PVsystem()
5254
Ee = {1: .1}
5355
pvsys.setSuns(Ee)
54-
ok_(np.isclose(pvsys.Pmp, 29136.544447716446))
56+
ok_(np.isclose(pvsys.Pmp, 29133.81083801798))
57+
# 1001 points linear: [ 29141.73034719]
5558

5659

5760
def test_gh34_35():

0 commit comments

Comments
 (0)