Skip to content

Commit

Permalink
Martinez shading factor (#2070)
Browse files Browse the repository at this point in the history
* Update shading.py

* Minimal test

* Implementation

From NREL paper

* Fix, fix, fix, fix & format

* Format issues

* Extend tests (compare with singleaxis) & format with ruff

* Format fixes

* Upgrade tests

* Array -> Axis

* type

* Whatsnew

* xd

* bruh

* Minor Python optimization a la tracking.singleaxis

* Comment and minor optimizations

* Surface -> Axis

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Elevation -> Zenith

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Elev -> Zenith

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Update shading.py

* Update docstring

Co-Authored-By: Anton Driesse <9001027+adriesse@users.noreply.github.com>

* Add comments from `tracking.singleaxis`

Co-Authored-By: Will Holmgren <william.holmgren@gmail.com>
Co-Authored-By: Mark Mikofski <bwana.marko@yahoo.com>

* Singleaxis implementation port & test addition, based on old pvlib.tracking.singleaxis

* Update v0.10.4.rst

* Linter

* Code review

Co-Authored-By: Cliff Hansen <5393711+cwhanse@users.noreply.github.com>

* Add Fig 5 [1] (still gotta check the built output)

* Add caption, change size and describe in alternate text

* rST fixes ?

* Figures have captions, images do not

https://pandemic-overview.readthedocs.io/en/latest/myGuides/reStructuredText-Images-and-Figures-Examples.html#id18

* Flip arguments order

* I forgot 💀

* Linter are you happy now?

* Remove port test and add edge cases test

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Update test_shading.py

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Indentation xd

* Update test_shading.py

* I forgot how to code

* Align data

* Docstring suggestion from Kevin

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Update link to example?

* add linear shade loss for thin films

* add tests, update docs, what's new

* fix what's new gh issue and pr links

* fix trailing whitespace

* responding to comments

- move linear shade loss to shading module
- don't use ternary, doesn't work on vectors, instead use np.where()
- set cross axis default to zero
- test vectors
- update docs

* update docstring for linear shade loss

- applicable to other monolithic thin film like CIGS, not just CdTe
- only when shade is perpendicular to scribe lines

* update example in linear_shade_loss

* add figure and formulas to shaded fraction

* shaded fraction consistently

* Add alternative text to image

* Update implementation based on PSZ PR. See description.

Commit highlights ✨ :
* I think I made all the code a bit more legible; sorry for the big changes @mikofski
* Tests a bit more complete (not much, still consider the same test data)
* Rename shaded fraction acronym from `fs` to `sf`
* Asserts changed to `assert_allclose` for a more legible output in case of failure

Co-Authored-By: Mark Mikofski <bwana.marko@yahoo.com>

* Whatsnew entries

Co-Authored-By: Mark Mikofski <bwana.marko@yahoo.com>

* Linter

* Clear things, convert Mark's reference to a reference

* Linter

* Update according to changes at PSZA PR

* Another commit, another try

* Ahhh, I rebased too fast

* whatsnews

* Update v0.10.4.rst

* Update v0.10.3.rst

* Rename to `shaded_fraction1d`, change params to `surface_*` instead of `tracker_*`

* Left this tracker refs behind

* Change rename in rst entries

* Add another testcase

* Improve docs references, clarify nomenclature

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Update test_shading.py

* Remove linear_shade_loss

* First implementation of the new shaded fraction model (missing figure)

* Create Anderson_Jensen_2024_Fig3.png

* Update shading.py

* Update shading.py

* Update shading.py

* lintaaargggg

* Fill reference

* Next release 0.10.5?

* Fix tests

* Update test_shading.py

* Little improvement to table definitions

* Change `l` to `\ell`

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* `pvlib.tracking.projected_solar_zenith_angle` to `pvlib.shading.projected_solar_zenith_angle`

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* pitch references to `pitch`

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* `trackers_axis_azimuth` to `axis_azimuth`

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* whatsnews

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Update v0.10.5.rst

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Change `tilt`s to `rotation`s and add `axis_tilt`

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Forgot to update tests 💀

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Add examples section

* roles assumption messin w/ me docs 😲

* roles assumption messin w/ me docs 😲

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Update shading.py

* Update shading.py

* Add gallery example

* This was fixed in recent sphinx-gallery releases IIRC

* Extra empty line or admonition type unsupported

* Fix example link (hopefully 🙏  )

* Update shading.py

* Fix subsubsections?

* Nah, bulleted list didn't work

* tilted -> tracker, only affects text

* Typos and unreasonable physical values

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* See the Examples section below, not the unlinkable link

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* tracker -> row, param names, code and docs

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Fix broken example 🔧

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com>

* "the row axis/axes" instead of ``axis_azimuth``

* Unnecessary math mode

Co-Authored-By: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com>

* Example suggestions and text trimming

Co-Authored-By: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com>

* whatsmes

* Add test to fix coverage issue

* Initial work

* Can't test with the paper data, wtf

* Little things

* Update plot_martinez_shade_loss.py

* More improvements

* Be4 rebase

* Fix fixture

* Initial work

* Fix tests

* docstring

* whatsnew 📝

* Minor thingies

* Add figure, improve docs 💯

* Fix silently ignoring file path in `pvsystem.retrieve_sam` when `name` is provided (#2020)

* My approach to the issue

* Deprecate previous parameters

* No reason to over-engineer, right?

* Update v0.10.5.rst

* Update pvsystem.py

* Improve error handling

* Add ppl involved

* kevin's suggestions

* Fix Ixx equation in pvsystem.sapm (#2019)

* fix Ixx equation, use Aimp

* Update docs/sphinx/source/whatsnew/v0.10.5.rst

* lint

* lint

* get the spacing right

* more spacing

---------

Co-authored-by: Kevin Anderson <kevin.anderso@gmail.com>

* Increase python requirement to >= 3.8 (#2029)

* require python >=3.8

* update CI configurations

* whatsnew

* remove pre-3.8 cruft

* fix h5py/numpy versioning issue for py3.8-min

* update gallery examples for newer pandas

* update asv config for python 3.8

* fix asv config syntax error

* one more asv config edit

* Finalize 0.10.5 (#2035)

* whatsnew cleanup

* add v0.11.0 file

* forgot to include myself in the contributors

* update release date

* Comments from review

* update whatsnews

* Update test_shading.py

* Example

* Fix whatsmes

* Update v0.11.0.rst

* other img

* lintarrrrrr 😭

* docs

* docs refurbishment

* Update plot_martinez_shade_loss.py

* Fix parameter names

* More explicit 2D shaded fraction

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Explicitier explicit

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Update shading.py

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Only if life was VCS to revert my errors so easily

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Nix image in docstring

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Clear-up irrdiance loss, not pwr loss - yet again

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* rewording

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Remove figure of junction boxes in example

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Duplicated singleaxis call

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* When did I change this?

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Rename function

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Make times just one statement

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Fix uncomplete example in docstring

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* flake is a snowflake ❄️

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Delete Centralized_and_split_PV_junction_boxes_cesardd.jpg

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Remove example description

Co-Authored-By: Cliff Hansen <5393711+cwhanse@users.noreply.github.com>

* Change example title

Co-Authored-By: Cliff Hansen <5393711+cwhanse@users.noreply.github.com>

* Ints for number of blocks

Co-Authored-By: Cliff Hansen <5393711+cwhanse@users.noreply.github.com>

* Rephrasing of shaded fraction 2D

Co-Authored-By: Cliff Hansen <5393711+cwhanse@users.noreply.github.com>

* typo

* Code review from Ioannis

Co-Authored-By: Ioannis Sifnaios <88548539+IoannisSifnaios@users.noreply.github.com>

* no more noqa e501

* Will this work to hide code?

* Update plot_martinez_shade_loss.py

Co-Authored-By: Ioannis Sifnaios <88548539+IoannisSifnaios@users.noreply.github.com>

* play time with the matplotlib statements

Co-Authored-By: Ioannis Sifnaios <88548539+IoannisSifnaios@users.noreply.github.com>

* This fixes it (I believe 🙏 )

CC @IoannisSifnaios

Co-Authored-By: Ioannis Sifnaios <88548539+IoannisSifnaios@users.noreply.github.com>

* Update plot_martinez_shade_loss.py

Co-Authored-By: Ioannis Sifnaios <88548539+IoannisSifnaios@users.noreply.github.com>

* Nah, let's see how this does

Co-Authored-By: Ioannis Sifnaios <88548539+IoannisSifnaios@users.noreply.github.com>

* Revert attempt to colapse code

It doesn't work because sphinx-gallery closes the figure at the end of the cell
sphinx-gallery/sphinx-gallery#240

CC @IoannisSifnaios

Co-Authored-By: Ioannis Sifnaios <88548539+IoannisSifnaios@users.noreply.github.com>

* Power losses model

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>
Co-Authored-By: Cliff Hansen <5393711+cwhanse@users.noreply.github.com>
Co-Authored-By: Ioannis Sifnaios <88548539+IoannisSifnaios@users.noreply.github.com>

* equations rendering

* Change `poa_direct_and_circumsolar` to `poa_direct`

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Example link

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* `power_loss` -> `loss_fraction`

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Typo when applying Ioannis suggestion

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>
Co-Authored-By: Ioannis Sifnaios <88548539+IoannisSifnaios@users.noreply.github.com>

* Re-arrange POA to its own section in example

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Mis-redaction in normal/half-cut modules comparison

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Add edge cases

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Link yet again

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Fix link for sure

Co-Authored-By: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>

* Remove critical error from docs build

* Apply suggestions from code review (Cliff)

Co-authored-by: Cliff Hansen <cwhanse@sandia.gov>

* Linter

* Apply suggestions from Adam

Co-authored-by: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com>

* Rewording from code review

Co-Authored-By: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com>

* More unitless

Co-Authored-By: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com>

* Apply suggestions from Cliff

Co-authored-by: Cliff Hansen <cwhanse@sandia.gov>

---------

Co-authored-by: Kevin Anderson <57452607+kandersolar@users.noreply.github.com>
Co-authored-by: Anton Driesse <9001027+adriesse@users.noreply.github.com>
Co-authored-by: Will Holmgren <william.holmgren@gmail.com>
Co-authored-by: Mark Mikofski <bwana.marko@yahoo.com>
Co-authored-by: Cliff Hansen <5393711+cwhanse@users.noreply.github.com>
Co-authored-by: Adam R. Jensen <39184289+AdamRJensen@users.noreply.github.com>
Co-authored-by: Cliff Hansen <cwhanse@sandia.gov>
Co-authored-by: Kevin Anderson <kevin.anderso@gmail.com>
Co-authored-by: Ioannis Sifnaios <88548539+IoannisSifnaios@users.noreply.github.com>
  • Loading branch information
10 people authored Jun 21, 2024
1 parent 3f2daab commit 35599e7
Show file tree
Hide file tree
Showing 6 changed files with 477 additions and 1 deletion.
272 changes: 272 additions & 0 deletions docs/examples/shading/plot_martinez_shade_loss.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
"""
Modelling shading losses in modules with bypass diodes
======================================================
"""

# %%
# This example illustrates how to use the loss model proposed by Martinez et
# al. [1]_. The model proposes a power output losses factor by adjusting
# the incident direct and circumsolar beam irradiance fraction of a PV module
# based on the number of shaded *blocks*. A *block* is defined as a group of
# cells protected by a bypass diode. More information on *blocks* can be found
# in the original paper [1]_ and in the
# :py:func:`pvlib.shading.direct_martinez` documentation.
#
# The following key functions are used in this example:
#
# 1. :py:func:`pvlib.shading.direct_martinez` to calculate the power output
# losses fraction due to shading.
# 2. :py:func:`pvlib.shading.shaded_fraction1d` to calculate the fraction of
# shaded surface and consequently the number of shaded *blocks* due to
# row-to-row shading.
# 3. :py:func:`pvlib.tracking.singleaxis` to calculate the rotation angle of
# the trackers.
#
# .. sectionauthor:: Echedey Luis <echelual (at) gmail.com>
#
# Problem description
# -------------------
# Let's consider a PV system with the following characteristics:
#
# - Two north-south single-axis trackers, each one having 6 modules.
# - The rows have the same true-tracking tilt angles. True tracking
# is chosen in this example, so shading is significant.
# - Terrain slope is 7 degrees downward to the east.
# - Row axes are horizontal.
# - The modules are comprised of multiple cells. We will compare these cases:
# - modules with one bypass diode
# - modules with three bypass diodes
# - half-cut cell modules with three bypass diodes in portrait and landscape
#
# Setting up the system
# ----------------------
# Let's start by defining the system characteristics, location and the time
# range for the analysis.

import pvlib
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.dates import ConciseDateFormatter

pitch = 4 # meters
width = 1.5 # meters
gcr = width / pitch # ground coverage ratio
N_modules_per_row = 6
axis_azimuth = 180 # N-S axis
axis_tilt = 0 # flat because the axis is perpendicular to the slope
cross_axis_tilt = -7 # 7 degrees downward to the east

latitude, longitude = 40.2712, -3.7277
locus = pvlib.location.Location(
latitude,
longitude,
tz="Europe/Madrid",
altitude=pvlib.location.lookup_altitude(latitude, longitude),
)

times = pd.date_range("2001-04-11T04", "2001-04-11T20", freq="10min")

# %%
# True-tracking algorithm and shaded fraction
# -------------------------------------------
# Since this model is about row-to-row shading, we will use the true-tracking
# algorithm to calculate the trackers rotation. Back-tracking eliminates
# shading between rows, and since this example is about shading, we will not
# use it.
#
# Then, the next step is to calculate the fraction of shaded surface. This is
# done using :py:func:`pvlib.shading.shaded_fraction1d`. Using this function is
# straightforward with the variables we already have defined.
# Then, we can calculate the number of shaded blocks by rounding up the shaded
# fraction by the number of blocks along the shaded length.

# Calculate solar position to get single-axis tracker rotation and irradiance
solar_pos = locus.get_solarposition(times)
solar_apparent_zenith, solar_azimuth = (
solar_pos["apparent_zenith"],
solar_pos["azimuth"],
) # unpack for better readability

tracking_result = pvlib.tracking.singleaxis(
apparent_zenith=solar_apparent_zenith,
apparent_azimuth=solar_azimuth,
axis_tilt=axis_tilt,
axis_azimuth=axis_azimuth,
max_angle=(-90 + cross_axis_tilt, 90 + cross_axis_tilt), # (min, max)
backtrack=False,
gcr=gcr,
cross_axis_tilt=cross_axis_tilt,
)

tracker_theta, aoi, surface_tilt, surface_azimuth = (
tracking_result["tracker_theta"],
tracking_result["aoi"],
tracking_result["surface_tilt"],
tracking_result["surface_azimuth"],
) # unpack for better readability

# Calculate the shade fraction
shaded_fraction = pvlib.shading.shaded_fraction1d(
solar_apparent_zenith,
solar_azimuth,
axis_azimuth,
axis_tilt=axis_tilt,
shaded_row_rotation=tracker_theta,
shading_row_rotation=tracker_theta,
collector_width=width,
pitch=pitch,
cross_axis_slope=cross_axis_tilt,
)

# %%
# Number of shaded blocks
# -----------------------
# The number of shaded blocks depends on the module configuration and number
# of bypass diodes. For example,
# modules with one bypass diode will behave like one block.
# On the other hand, modules with three bypass diodes will have three blocks,
# except for the half-cut cell modules, which will have six blocks; 2x3 blocks
# where the two rows are along the longest side of the module.
# We can argue that the dimensions of the system change when you switch from
# portrait to landscape, but for this example, we will consider it the same.
#
# The number of shaded blocks is calculated by rounding up the shaded fraction
# by the number of blocks along the shaded length. So let's define the number
# of blocks for each module configuration:
#
# - 1 bypass diode: 1 block
# - 3 bypass diodes: 3 blocks in landscape; 1 in portrait
# - 3 bypass diodes half-cut cells:
# - 2 blocks in portrait
# - 3 blocks in landscape
#
# .. figure:: ../../_images/PV_module_layout_cesardd.jpg
# :align: center
# :width: 75%
# :alt: Normal and half-cut cells module layouts
#
# Left: common module layout. Right: half-cut cells module layout.
# Each module has three bypass diodes. On the left, they connect cell
# columns 1-2, 2-3 & 3-4. On the right, they connect cell columns 1-2, 3-4 &
# 5-6.
# *Source: César Domínguez. CC BY-SA 4.0, Wikimedia Commons*
#
# In the image above, each orange U-shaped string section is a block.
# By symmetry, the yellow inverted-U's of the subcircuit are also blocks.
# For this reason, the half-cut cell modules have 6 blocks in total: two along
# the longest side and three along the shortest side.

blocks_per_module = {
"1 bypass diode": 1,
"3 bypass diodes": 3,
"3 bypass diodes half-cut, portrait": 2,
"3 bypass diodes half-cut, landscape": 3,
}

# Calculate the number of shaded blocks during the day
shaded_blocks_per_module = {
k: np.ceil(blocks_N * shaded_fraction)
for k, blocks_N in blocks_per_module.items()
}

# %%
# Plane of array irradiance example data
# --------------------------------------
# To calculate the power output losses due to shading, we need the plane of
# array irradiance. For this example, we will use synthetic data:

clearsky = locus.get_clearsky(
times, solar_position=solar_pos, model="ineichen"
)
dni_extra = pvlib.irradiance.get_extra_radiation(times)
airmass = pvlib.atmosphere.get_relative_airmass(solar_apparent_zenith)
sky_diffuse = pvlib.irradiance.perez_driesse(
surface_tilt, surface_azimuth, clearsky["dhi"], clearsky["dni"],
solar_apparent_zenith, solar_azimuth, dni_extra, airmass,
) # fmt: skip
poa_components = pvlib.irradiance.poa_components(
aoi, clearsky["dni"], sky_diffuse, poa_ground_diffuse=0
) # ignore ground diffuse for brevity
poa_global, poa_direct = (
poa_components["poa_global"],
poa_components["poa_direct"],
)

# %%
# Results
# -------
# Now that we have the number of shaded blocks for each module configuration,
# we can apply the model and estimate the power loss due to shading.
#
# Note that this model is not linear with the shaded blocks ratio, so there is
# a difference between applying it to just a module or a whole row.

shade_losses_per_module = {
k: pvlib.shading.direct_martinez(
poa_global=poa_global,
poa_direct=poa_direct,
shaded_fraction=shaded_fraction,
shaded_blocks=module_shaded_blocks,
total_blocks=blocks_per_module[k],
)
for k, module_shaded_blocks in shaded_blocks_per_module.items()
}

shade_losses_per_row = {
k: pvlib.shading.direct_martinez(
poa_global=poa_global,
poa_direct=poa_direct,
shaded_fraction=shaded_fraction,
shaded_blocks=module_shaded_blocks * N_modules_per_row,
total_blocks=blocks_per_module[k] * N_modules_per_row,
)
for k, module_shaded_blocks in shaded_blocks_per_module.items()
}

# %%
# Plotting the results
# ^^^^^^^^^^^^^^^^^^^^

fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
fig.suptitle("Martinez power losses due to shading")
for k, shade_losses in shade_losses_per_module.items():
linestyle = "--" if k == "3 bypass diodes half-cut, landscape" else "-"
ax1.plot(times, shade_losses, label=k, linestyle=linestyle)
ax1.legend(loc="upper center")
ax1.grid()
ax1.set_xlabel("Time")
ax1.xaxis.set_major_formatter(
ConciseDateFormatter("%H:%M", tz="Europe/Madrid")
)
ax1.set_ylabel(r"$P_{out}$ losses")
ax1.set_title("Per module")

for k, shade_losses in shade_losses_per_row.items():
linestyle = "--" if k == "3 bypass diodes half-cut, landscape" else "-"
ax2.plot(times, shade_losses, label=k, linestyle=linestyle)
ax2.legend(loc="upper center")
ax2.grid()
ax2.set_xlabel("Time")
ax2.xaxis.set_major_formatter(
ConciseDateFormatter("%H:%M", tz="Europe/Madrid")
)
ax2.set_ylabel(r"$P_{out}$ losses")
ax2.set_title("Per row")
fig.tight_layout()
fig.show()

# %%
# Note how the half-cut cell module in portrait performs better than the
# normal module with three bypass diodes. This is because the number of shaded
# blocks is less along the shaded length is higher in the half-cut module.
# This is the reason why half-cut cell modules are preferred in portrait
# orientation.

# %%
# References
# ----------
# .. [1] F. Martínez-Moreno, J. Muñoz, and E. Lorenzo, 'Experimental model
# to estimate shading losses on PV arrays', Solar Energy Materials and
# Solar Cells, vol. 94, no. 12, pp. 2298-2303, Dec. 2010,
# :doi:`10.1016/j.solmat.2010.07.029`.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ Shading
shading.sky_diffuse_passias
shading.projected_solar_zenith_angle
shading.shaded_fraction1d

shading.direct_martinez
3 changes: 3 additions & 0 deletions docs/sphinx/source/whatsnew/v0.11.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ Enhancements
* Added extraterrestrial and direct spectra of the ASTM G173-03 standard with
the new function :py:func:`pvlib.spectrum.get_reference_spectra`.
(:issue:`1963`, :pull:`2039`)
* Added function :py:func:`pvlib.shading.direct_martinez` to calculate
shading losses by taking into account the amount of bypass diodes of a module.
(:issue:`2063`, :pull:`2070`)
* Add function :py:func:`pvlib.irradiance.diffuse_par_spitters` to calculate the
diffuse fraction of Photosynthetically Active Radiation (PAR) from the
global diffuse fraction and the solar zenith.
Expand Down
Loading

0 comments on commit 35599e7

Please sign in to comment.