Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/sphinx/source/reference/floating.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.. currentmodule:: pvlib

Floating
========

Functions
---------

.. autosummary::
:toctree: generated/

floating.daily_stream_temperature_stefan
1 change: 1 addition & 0 deletions docs/sphinx/source/reference/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ API reference
scaling
location
transformer
floating
1 change: 1 addition & 0 deletions pvlib/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
atmosphere,
bifacial,
clearsky,
floating,
iam,
inverter,
iotools,
Expand Down
60 changes: 60 additions & 0 deletions pvlib/floating.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""
The ``floating`` module contains functions for calculating parameters related
to floating PV systems.
"""

import numpy as np
import pandas as pd


def daily_stream_temperature_stefan(temp_air):
r"""
Estimation of daily stream water temperature based on ambient temperature.

Parameters
----------
temp_air : numeric
Ambient dry bulb temperature. [degrees C]

Returns
-------
daily_stream_temperature : numeric
Daily average stream water temperature. [degrees C]

Notes
-----
The equation for calculating the daily average stream water temperature
:math:`T_w` using the ambient air temperature :math:`T_{air}` is provided
in [1]_ and given by:

.. math::
:label: stream

T_w = 5 + 0.75 \cdot T_{air}

The predicted daily stream water temperatrues of this equation had a
standard deviation of 2.7 °C compared to measurements. Small, shallow
streams had smaller deviations than large, deep rivers.

It should be noted that this equation is limited to streams, i.e., water
bodies that are well mixed in vertical and transverse direction of a cross
section. Also, it is only tested on ice-free streams. Consequently, when
the mean ambient air temperature is lower than -6 °C, the surface stream
water temperature is assumed to be zero.

References
----------
.. [1] Stefan H. G., Preud'homme E. B. (1993). "Stream temperature
estimation from air temperature." IN: Journal of the American Water
Resources Association 29-1: 27-45.
:doi:`10.1111/j.1752-1688.1993.tb01502.x`
"""

temp_stream = 5 + 0.75 * temp_air

temp_stream = np.where(temp_stream < 0, 0, temp_stream)

if isinstance(temp_air, pd.Series):
temp_stream = pd.Series(temp_stream, index=temp_air.index)

return temp_stream
33 changes: 33 additions & 0 deletions pvlib/tests/test_floating.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import numpy as np
import pandas as pd
from pvlib import floating

from .conftest import assert_series_equal
from numpy.testing import assert_allclose


def test_daily_stream_temperature_stefan_default():
result = floating.daily_stream_temperature_stefan(temp_air=15)
assert_allclose(result, 16.25, 0.01)


def test_daily_stream_temperature_stefan_negative_temp():
result = floating.daily_stream_temperature_stefan(temp_air=-15)
assert_allclose(result, 0, 0.1)


def test_daily_stream_temperature_stefan_ndarray():
air_temps = np.array([-5, 2.5, 20, 30, 40])
result = floating.daily_stream_temperature_stefan(temp_air=air_temps)
expected = np.array([1.25, 6.875, 20, 27.5, 35])
assert_allclose(expected, result, atol=1e-3)


def test_daily_stream_temperature_stefan_series():
times = pd.date_range(start="2015-01-01 00:00", end="2015-01-05 00:00",
freq="1d")
air_temps = pd.Series([-5, 2.5, 20, 30, 40], index=times)

result = floating.daily_stream_temperature_stefan(temp_air=air_temps)
expected = pd.Series([1.25, 6.875, 20, 27.5, 35], index=times)
assert_series_equal(expected, result, atol=1e-3)