-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add function to fit Sandia inverter model #1011
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
Conversation
pvlib/inverter.py
Outdated
Columns must be ``'fraction_of_rated_power'``, ``'dc_voltage_level'``, | ||
``'dc_voltage'``, ``'ac_power'``, ``'efficiency'``. See notes for the | ||
definition and unit for each column. | ||
p_ac_0 : numeric |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it intentional that p_ac_0
and p_nt
are spelled differently here than in inverter.sandia
? Seems like these two functions would benefit from a consistent interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, which would you prefer? p_ac_0
is more appealing than Pac0
as a program variable. The inertia is with Pac0
, which is the column key for this parameter read from the SAM files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not clear to me where the balance should be struck between (1) presenting a consistent interface across functions or (2) maintaining as clear a connection as possible to the original model definitions. I think I would lean towards p_ac_0
over Pac0
with the hope that existing Pac0
s would be changed to match.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is my preference as well. The function returns a dict ready for pvlib.inverter.sandia
so at least in one direction the two are compatible.
pvlib/inverter.py
Outdated
Parameters | ||
---------- | ||
curves : DataFrame | ||
Columns must be ``'fraction_of_rated_power'``, ``'dc_voltage_level'``, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is fraction_of_rated_power
actually required? I don't see it getting used anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The values are not used explicitly, but I think it would be confusing to describe the needed input without fraction_of_rated_power
. If working from a datasheet, efficiency in usually given in terms of fraction_of_rated_power
rather than ac_power
.
Test failures are due to #1018 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Idea for a future PR: I think pairing the fit functions with the associated models would make for good gallery examples.
@Peque any comments or edits to this before we merge? |
I'm not going to make much use of this function so my comments come from an API design/consistency point of view... I generally want to avoid DataFrame input to functions because the API should be as self-documenting as possible. Here there's already an issue with an unused column that, to me, is a red flag for the API design. I also recommend refactoring a lot of the logic into a function that works on one curve at a time curve. |
I think a Dataframe is a convenient way for a user to organize the data input, but I'm open to different ideas. I can remove the The data are a set of efficiency curves, where a curve is set of points (efficiency, ac power) (the docstring is incorrect on this point and I'll fix that). The curves do not have to be, but usually are, aligned on a set of common efficiency values. The algorithm needs to know one fact about each curve, the DC voltage level. If working from a datasheet there are typically 3 curves, one at each voltage level. From lab data, several curves are measured at each voltage level, and the algorithm needs to accommodate these repeated measurements. Data = a list of tuples The algorithm doesn't work one curve at a time. The parameters are gotten from regressions across DC voltage levels (i.e., across subsets of the curves). Here's a diagram that illustrates how the 6 parameters are gotten from the set of curves. Three coefficients come from fitting a quadratic to the curve(s) |
pvlib/inverter.py
Outdated
# independent variable for regressions, x_d | ||
x_d = v_d - v_nom | ||
|
||
curves['dc_power'] = curves['ac_power'] / curves['efficiency'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this modify the input DataFrame?
Sorry I now see I misread the loop and assumed something about the structure of the rows of the DataFrame that is not true.
Agreed, but the same is true for many of the other low level functions in pvlib and they still require arguments for API clarity. ModelChain takes DataFrame input and we see a lot more user confusion there about what the input needs to contain (granted it's a confusing thing for many reasons). Apologies if I'm still missing something, but is there a reason to avoid an api like
This doesn't sound like the function's problem to solve. Perhaps would be good to include in an example in the gallery. |
No you aren't missing something, that's a good idea - easy for a user to get to those inputs if a datasheet table is transcribed to a Dataframe, and makes the inputs explicit. Thanks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one nit, but otherwise LGTM assuming the tests pass when the syntax error is fixed.
pvlib/inverter.py
Outdated
ac_power : Series | ||
AC power output at each data point [W]. | ||
dc_power : Series | ||
DC power input at each data point [W]. | ||
dc_voltage : Series | ||
DC input voltage at each data point [V]. | ||
dc_voltage_level : Series |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: these should be array_like, not Series.
@cwhanse Looks great. 😊 |
docs/sphinx/source/api.rst
for API changes.docs/sphinx/source/whatsnew
for all changes. Includes link to the GitHub Issue with:issue:`num`
or this Pull Request with:pull:`num`
. Includes contributor name and/or GitHub username (link with:ghuser:`user`
).Inputs are: efficiency curves with DC voltage and AC power, rated AC power and night tare. Returns dict ready for the Sandia inverter model function. The algorithm reference is on the PVPMC site.