Open abooda1981 opened 3 years ago
Hi @abooda1981 ,
If these are currents in a single PV module in which all cells are in series (as in a standard Si module) then there seems to me to be something fishy going on. AFAIK all currents should be identical at a given module operating point. Without seeing what Python code you are using, it would be difficult to trouble shoot. Sorry.
Also as Kevin commented there are some pvmismatch questions & answers on StackOverflow, you may get a wider audience there.
If I use your irradiance distribution here's what I get:
from pvmismatch import *
import numpy as np
Esun = [213.9050, 175.0628, 199.4696, 174.6492, 187.5090, 159.7476,
215.7734, 230.8677, 180.7294, 166.6885, 168.1310, 199.5440,
229.3951, 217.8146, 195.3562, 183.8101, 155.5469, 183.3035,
209.5742, 227.4405, 226.7091, 194.7483, 198.0606, 180.4816,
227.2889, 206.0805, 217.0147, 226.6177, 177.0109, 182.4648,
223.5549, 221.1798, 227.0709, 234.8297, 201.6358, 196.6677,
293.7470, 293.7470, 293.7470, 293.7470, 293.7470, 293.7470,
293.7470, 293.7470, 293.7470, 293.7470, 293.7470, 293.7470,
293.7470, 293.7470, 293.7470, 293.7470, 293.7470, 293.7470,
293.7470, 293.7470, 293.7470, 293.7470, 293.7470, 293.7470]
Ee = np.array(Esun)/1000.
# a standard 60 cell Si module cell position pattern
STD60 = pvmodule.standard_cellpos_pat(10, [2, 2, 2])
# 1-sun module
pvmod0 = pvmodule.PVmodule(cell_pos=STD60)
# another identical test module
pvmod = pvmodule.PVmodule(cell_pos=STD60)
# set the test module to your irradiance distribution
pvmod.setSuns(Ee)
# check the max power
pvmod.Pmod.max()
# 33.68645804634907 [W]
# check the 1-sun module max power
pvmod0.Pmod.max()
# 200.7958518246065 [W]
# find the indices in the power-voltage curve that correspond to the max power
idx_pmax = np.argmax(pvmod.Pmod)
# 121
# ditto for 1-sun module
idx_p0max = np.argmax(pvmod0.Pmod)
# 121
# get the module current at that index in the curve
# module with your irradiance distribution
pvmod.Imod(idx_pmax)
# 1.005869089412653 [A]
# 1-sun module
pvmod0.Imod[idx_p0max]
# 5.9072865777167225 [A]
So the current of all cells in the module at the max power point would be 1.006[A].
Here's the IV & power-voltage curves for the 1-sun module
And here's the IV & power-voltage curves for the module with your irradiance distribution
Remember! PVMismatch returns a full trace of the IV curve for cells, modules, and strings. So it's up to the user to select the operating point that they want from the curve. If you want functions that describe the max power point, you should use pvsystem.PVsystem
Thanks @mikofski for your response. Actually, the module contains 10 series-connected groups. Perhaps the following codes might clear things up.
The following is the code I use to draw the PV module pattern. This is from a previous discussion with @adambgnr
# define a function that returns the cell positions in a dataframe
def create_cell_pos_df(pv_mod):
"""Create cell position dataframe of a module"""
pv_mod_pattern = pvmismatch.pvmodule.standard_cellpos_pat(nrows=10, ncols_per_substr=[2]*3) #define the pattern here
my_module_copy = pvmismatch.pvmodule.PVmodule(cell_pos=pv_mod_pattern) #define the module to have that pattern
#fed_shades = shades #We will feed this pattern of shades into the function we define
fed_module = my_module_copy
cell_positions = pv_mod.cell_pos
#Simple way to define the number of rows in the module
#Limit it to integers
nrows = int(pv_mod.numberCells / sum(pv_mod.subStrCells))
cell_pos_df = pd.DataFrame(index=['{}'.format(nr)
for nr
in range(nrows)])
for b, bypass in enumerate(cell_positions):
for c, col in enumerate(bypass):
cell_pos_df['{}_{}'.format(b, c)] = [i['idx'] for i in col]
return cell_pos_df
# make the cell position DataFrame
cell_positions = create_cell_pos_df(pv_mod=fed_module)
The next bit of code is the function which I access in R, which takes a module with the given structure and sets the shading for each sun to be the same as the value of the irradiance (in suns) after it is shaded by the required amount.
def shade_the_module_3(module_input, shade_input):
positions_input = create_cell_pos_df(module_input)
positions_input_np = positions_input.to_numpy()
module_input.setSuns(shade_input, positions_input_np)
return module_input
Finally, after I have created a module, and shaded it, I want to know what the photo-induced current is at each cell. My assumption--and I could be implementing this incorrectly, I guess--is that if each of the 60 cells has a different level of shading, then they should produce a different current. The following bit of code is what gives the output I reproduced above:
def moving_day_shaded_currents(shaded_module):
moving_day_shaded_currents = []
for c, cells in enumerate(shaded_module.pvcells):
moving_day_shaded_currents.append(shaded_module.pvcells[c].Igen)
return moving_day_shaded_currents
I wonder: would it not make more sense for me to take the shading level cell by cell, and then use the PVLIB function for single diodes? In other words, use pvlib.pvsystem.calcparams_cec for each cell and then just vary the irradiance parameter?
Thanks again for your help. I will follow this up with a question on the StackOverflow as you suggest if you still think there's something wrong with this.
Hi @abooda1981 ,
I think you are doing everything right, except that the "Igen
"s are not the droids currents you are looking for.
The Igen
you accessed is this Igen
in the diode model:
# diode model
# *-->--*--->---*--Rs->-Icell--+
# ^ | | ^
# | | | |
# Igen Idiode Ishunt Vcell
# | | | |
# | v v v
# *--<--*---<---*--<-----------=
# from: https://github.com/SunPower/PVMismatch/blob/5c4bc75fe7b1b4eddcaa0df15cf630f8e8676fc5/pvmismatch/pvmismatch_lib/pvcell.py
Is this current what you really want? Not the Icell
?
I think @mikofski is right about that the Icell
in all cells has to be the same if they are connected in series.
But then again if it is really the Igen
what you want, then I guess it should be correct what you got. Just make sure that you don't mix up which Igen
values correspond to which cell index.
An other thing about the shading: Please @mikofski correct me if I am wrong, but I think if we set the suns with a 60 long 1 dimensional array, then the cell irradiances will be set in the order of the PV cell indexes (0-59), which can mess up the layout of the shadow on the PV module. I think what @abooda1981 wants is to fill the irradiances like this:
Where on the left are the cell irradiances and on the right the cell indexes. (As far as I know, PVMM sets the cell indexes like this by default, please correct me if I'm wrong.) Thus if the irradiance input of @abooda1981 is in such form (the irradiance input array looks like how the shadow looks like in real life) then he/she can use the create_cell_pos_df()
function to align the shade to the cell indexes, see here:
https://github.com/SunPower/PVMismatch/issues/134
Hi @adambgnr , thanks for your input. Without wanting to spoil your Star Wars meme, I'm fairly sure that the Igen is what I want--in a later part of the code, I take all of the cells in a given string and define the current of the string to be the lowest current in that string. I am assuming that this lowest current is the one which is actually contributed to the module. (If this sounds off, please let me know.)
Going back and forth with the PVLIB email list here: I'm wondering if it's more sensible to just PVLIB to calculate the photo-induced current for each cell individually using a single diode equation. For one thing, this would avoid my having to worry about the way cell indexing works in PVMM.
Hello all. I've received a lot of help from @mikofski and @adambgnr for which I'm very grateful. I will need to run this kind of calculation for roughly ~ 1 year worth of data, I just wanted to make sure this isn't some weird mistake on my part. My codes below should be more or less self explanatory, but I will also offer some commentary.
FWIW (and I don't think it changes much), I'm using Python in R through the reticulate package and just trying to limit the routines that are actually written in Python. The only reason I'll mention this is you might notice some indexes are strange (eg, 60 elements start with 1 and end with 60 and not 0 and 59).
Here's where I begin, it's a set of irradiances which have been attenuated for each cell in a 60-cell module. Expressed in W/m^2.
Next, two python scripts which I can call from R. The first takes a module and a set of shades, as above, and applies "setSuns" to the module using the shades. The second takes a shaded module and returns a list of currents for each cell.
And the next bit, in R, ties it all together and produces a vector which holds the current generated by each cell.