Skip to content

NOCT cell temperature function #1177

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 14 commits into from
Mar 10, 2021
Merged

NOCT cell temperature function #1177

merged 14 commits into from
Mar 10, 2021

Conversation

cwhanse
Copy link
Member

@cwhanse cwhanse commented Feb 25, 2021

  • [ ] Closes #xxxx
  • I am familiar with the contributing guidelines
  • Tests added
  • Updates entries to docs/sphinx/source/api.rst for API changes.
  • Adds description and name entries in the appropriate "what's new" file in 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`).
  • New code is fully documented. Includes numpydoc compliant docstrings, examples, and comments where necessary.
  • Pull request is nearly complete and ready for detailed review.
  • Maintainer: Appropriate GitHub Labels and Milestone are assigned to the Pull Request and linked Issue.

Implement cell temperature function that is the default in SAM when the CEC module model is chosen.

@cwhanse cwhanse added this to the 0.9.0 milestone Mar 1, 2021
@cwhanse
Copy link
Member Author

cwhanse commented Mar 1, 2021

Ready for review. check failure is codecov, but all of temperature.py is covered.

@kandersolar kandersolar self-requested a review March 1, 2021 20:54
Copy link
Member

@wholmgren wholmgren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks good. Are you planning a follow up issue/pr for integration into PVSystem and ModelChain?

expected = 54.41542289
result = temperature.noct(poa_global, temp_air, wind_speed, noct,
eta_m_ref)
assert np.isclose(result, expected)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert np.isclose(result, expected)
assert_allclose(result, expected)

result = temperature.noct(np.array(poa_global), np.array(temp_air),
np.array(wind_speed), np.array(noct),
np.array(eta_m_ref))
assert np.isclose(result, expected)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert np.isclose(result, expected)
assert_allclose(result, expected)

transmittance_absorbtance, array_height,
mount_standoff)
expected = 58.36654459
assert np.isclose(result, expected)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
assert np.isclose(result, expected)
assert_allclose(result, expected)

'''
Cell temperature model from the System Advisor Model (SAM).

The model is described in [1], Section 10.6.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The model is described in [1], Section 10.6.
The model is described in [1]_, Section 10.6.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SAM document says "The NOCT photovoltaic cell temperature model is from Chapter 23.3 of Duffie and Beckman (2013), also de- scribed in De Soto (2004b)." Should we mention those references as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with the comment. Let me see if I can locate a copy of Duffie and Beckman. There's an issue with the De Soto reference, I downloaded both (paper and thesis) and there's no discussion in either of the cell temperature model.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -706,3 +706,94 @@ def fuentes(poa_global, temp_air, wind_speed, noct_installed, module_height=5,
sun0 = sun

return pd.Series(tmod_array - 273.15, index=poa_global.index, name='tmod')


def _adj_noct(x):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something more descriptive like _adj_for_mounting_standoff

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SAM document is not clear on if we should use >= or <=. Maybe check the ssc code for consistency? And probably add a comment on this detail, too.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SAM code doesn't process a distance, only passes through an integer index to the values. Except for the "x > 3.5" case, the SAM interface text doesn't specify > or >=. So we're filling in a detail here. I'll adjust the default to 3.51 and put in some comments.

cell_temp_init = ross(poa_global, temp_air, noct_adj)
heat_loss = 1 - eta_m_ref / tau_alpha
wind_loss = 9.5 / (5.7 + 3.8 * wind_adj)
return cell_temp_init * heat_loss * wind_loss
Copy link
Member

@wholmgren wholmgren Mar 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is correct. ross returns air temperature + temperature correction. You want to multiply only temperature correction by heat_loss and wind_loss, but you've also multiplied the air temperature by these terms

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are correct. We can't re-use ross here.

@cwhanse
Copy link
Member Author

cwhanse commented Mar 1, 2021

Mostly looks good. Are you planning a follow up issue/pr for integration into PVSystem and ModelChain?

Yes, I wanted to get consensus on the function first.

Copy link
Member

@kandersolar kandersolar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm only partially able to reconcile the standoff adjustment values in SAM Tech Ref Eq. 10.36 with their supposed source, Fuentes Table 4. Not sure where some of these SAM/SSC values came from (e.g. 2inch -> +6C?); it almost seems like they interpolated/projected the Fuentes values. Maybe that makes sense here too -- to go from discrete to continuous, just interpolate instead of bin? Although that would be more of a departure from SAM/SSC.

Some helpful links for anyone following along:

tau_alpha = transmittance_absorbtance * irr_ratio

# [1] Eq. 10.37 isn't clear on exactly what "G" is. SAM SSC code uses
# poa_global where G appears
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the bottom of page 57 it says "The cell temperature is only calculated when the effective transmitted irradiance from Equation 10.25 is greater than zero, G>0.", and tracing back through to Eq 10.20 shows that G is after accounting for surface reflection and airmass.

if effective_irradiance is None:
irr_ratio = 1.
else:
irr_ratio = effective_irradiance / poa_global
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this is correct. Eq 10.22 has the ratio as G0/G, where G0 is irradiance after reflections and G is after reflections and airmass.

@cwhanse
Copy link
Member Author

cwhanse commented Mar 2, 2021

I'm only partially able to reconcile the standoff adjustment values in SAM Tech Ref Eq. 10.36 with their supposed source, Fuentes Table 4.

I think we should regard SAM as the source for standoff adjustment values.

About "G" vs. "G0" in the SAM document: the term "G" is redefined twice in Chapter 10 (Eq. 10.13 and 10.22 are POA broadband, Eq. 10.25 and 10.26 (and 7.8) are effective irradiance absorbed by the cells. I don't read C well, but it looked to me that G_total in the SAM function is POA irradiance, not effective irradiance.

It would be desirable if this temperature model could be used without requiring both poa_global and effective_irradiance, or a third quantity falling in between which isn't present in pvlib: absorbed irradiance, POA after reflection but before spectral adjustment, this quantity is 'S' in De Soto's papers.

The SAM implementation is more involved that what is described in Duffie and Beckman. One way forward would be to implement noct_duffie_beckman rather than noct_sam. In D&B:

  • 'G' is POA irradiance
  • the transmittance/absorptance term isn't adjusted with effective_irradiance
  • wind speed isn't adjusted for standoff

@cwhanse
Copy link
Member Author

cwhanse commented Mar 3, 2021

I spent some time trying to get SAM to give me back cell temperatures, without success. That quantity isn't available in the time series output, and the relevant function (noct_celltemp_t) isn't directly accessible through PySAM. I was able to get a 'tcell' value using PySAM's Pv6parmod object and of course it's not what I expected to see from the inputs I provided.

At this point, my recommendation is to fall back to implementing the model in Duffie and Beckman, and adding the SAM model in the future (as a different function) when we're clear exactly what the SAM model does. @kanderso-nrel? @wholmgren?

The driver for this PR is the Solar Performance Insight project, where it would be nice to have a pre-packaged "SAM" model chain.

@kandersolar
Copy link
Member

No preference from me on the way best way forward. For getting cell temps from SAM: it is available in the UI, but maybe not under a name you expect (Subarray 1 Cell Temperature), see screenshots below. You can grab numerical values from the Data tables tab. I think I've pulled it directly from SSC before, but that was before the days of PySAM so I don't know how to do it there.

Click to expand!

image


image

@cwhanse
Copy link
Member Author

cwhanse commented Mar 5, 2021

@kanderso-nrel thanks for those pointers to SAM output. I am able to reproduce the Subarray 1 Cell Temperature values. To reproduce, I equated the following terms used in the SAM code with pvlib variables:

  • Geff_total is equivalent to pvlib's effective_irradiance,
  • G_total is equivalent to pvlib's poa_global (plane of array before reflections or spectrum adjustment).

I will put comments in the pvlib code to clarify why we assign these variables and write one test that reproduces the SAM value.

@cwhanse
Copy link
Member Author

cwhanse commented Mar 7, 2021

Failed check is codecov. This is ready to go, I think.

Copy link
Member

@wholmgren wholmgren left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 for test_noct_sam_against_sam. I don't know what's going on with codecov. Maybe we need to start specifying a target value for that configuration.

temp_air : numeric
Ambient dry bulb temperature. [C]

wind_speed : numeric, default 1.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no default value in the function signature

The irradiance that is converted to photocurrent. If None,
assumed equal to poa_global. [W/m^2]

eta_m_ref : float
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comes before effective_irradiance in function signature.

Can we call this module_efficiency so that more people can easily understand it?

Copy link
Member Author

@cwhanse cwhanse Mar 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok with module_efficiency but I'd rather have a common name with pvsyst_cell, where eta_m is the same quantity. I used eta_m_ref here because for SAM it's clear that it's at STC, which is not clear for Pvsyst.

20C. Calculate as
.. math::

\eta_{m} = \frac{V_{mp} I_{mp}}{A \times 1000 W/m^2} # noQA: W605
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised you need noqa: W605 since the whole docstring is preceded by r

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest changing this to inline with :math: as right now it's rendering as a code block (not a math block) on RTD.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had the noQA before I put the r in the docstring. Should be OK without the noQA now.

Copy link
Member

@kandersolar kandersolar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After taking a closer look and correcting my understanding of the SSC implementation, LGTM besides @wholmgren's comments and a formatting note below.

20C. Calculate as
.. math::

\eta_{m} = \frac{V_{mp} I_{mp}}{A \times 1000 W/m^2} # noQA: W605
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest changing this to inline with :math: as right now it's rendering as a code block (not a math block) on RTD.

@wholmgren wholmgren merged commit 684b247 into pvlib:master Mar 10, 2021
@wholmgren wholmgren added the SPI DOE SETO Solar Performance Insight project label Mar 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement SPI DOE SETO Solar Performance Insight project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants