-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Lcoe branch #1687
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
Open
eccoope
wants to merge
50
commits into
pvlib:main
Choose a base branch
from
eccoope:lcoe_branch
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Lcoe branch #1687
Changes from 1 commit
Commits
Show all changes
50 commits
Select commit
Hold shift + click to select a range
49fd4e8
''
eccoope fb6ff2f
Merge branch 'main' of https://github.com/eccoope/pvlib-python-forked…
eccoope 2204f18
''
eccoope af4b00b
resolved stickler issues
eccoope d7c606d
resolved stickler issues
eccoope 9b86e11
resolved stickler issues
eccoope 9f1e090
updated to be consistent suggested changes
eccoope a4fa101
''
eccoope fdea1b5
''
eccoope 4c7cba8
''
eccoope 7fdb96f
''
eccoope 59df950
''
eccoope effdaa7
''
eccoope 4284990
Resolve stickler failures
eccoope 2bfba2e
Resolved stickler issues in simple_lcoe_calculator.py
eccoope e6f6938
Resolved stickler issues and linked references
eccoope b61a9cb
Resolved stickler failures
eccoope 49f2631
Changed variable names + real/nominal clarification
eccoope 388f9f4
Resolved stickler failure
eccoope a18f861
More stickler corrections
eccoope 582c974
Encourage use of real discount rates
eccoope 4161663
Encourage use of real discount rates
eccoope c0e31dc
Update pvlib/financial.py
eccoope 912969d
Update pvlib/financial.py
eccoope a0a7cf1
Update pvlib/financial.py
eccoope 17898a6
Update pvlib/financial.py
eccoope dce7e5f
Update pvlib/financial.py
eccoope 1ea12b5
Update pvlib/financial.py
eccoope e124027
Update pvlib/financial.py
eccoope 9d17c09
Apply suggestions from code review
eccoope 83d6e02
Update financial.py
eccoope 33c8238
Update test_financial.py
eccoope cd0ae02
Stickler for lcoe_sam_validation.py
eccoope 92d7258
More stickler for lcoe_sam_validation.py
eccoope cae3d7b
more stickler for lcoe_sam_validation.py
eccoope 7fc63e7
One last stickler thing
eccoope 00df4f8
Remove "real" from wacc docstring
eccoope ab47596
Added a line to index.rst
eccoope 7a039b7
Added last two authors to be consistent with version in main branch
eccoope ebec039
Merge branch 'main' into lcoe_branch
eccoope 7136b84
Merge branch 'main' of https://github.com/eccoope/pvlib-python-forked…
eccoope 41bde9c
Resolved conflicts in v0.9.5 and moved changes to v0.9.6
eccoope 8aff9f0
Merge branch 'main' into lcoe_branch
eccoope 925e155
Remove variable O&M caveatp
eccoope 42b7823
Merge branch 'main' into lcoe_branch
eccoope 0541e5b
Added system degradation rate to example
eccoope 1441de6
Delete v0.9.6.rst
eccoope d2205c3
Merge branch 'pvlib:main' into lcoe_branch
eccoope 77fb22c
Updated whatsnew v0.10.2.rst
eccoope b3c272e
Merge branch 'main' into lcoe_branch
eccoope File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
import numpy as np | ||
|
||
def lcoe(production=None, cap_cost=None, fixed_om=None): | ||
""" | ||
Levelized cost of electricity as described on pp.43 and 47-48 by [1] | ||
Parameters | ||
---------- | ||
production : np.array, or pd.Series, default None | ||
Annual production [kWh/kW installed] | ||
cap_cost : np.array, or pd.Series, default None | ||
Initial and annual payments on capital costs [$/kW installed] | ||
fixed_om : np.array, or pd.Series, default None | ||
Annual payments on operations and maintenance costs [$/kW installed] | ||
|
||
Returns | ||
---------- | ||
LCOE [cents/kWh] | ||
|
||
References | ||
---------- | ||
.. [1] W. Short, D. J. Packey, and T. Holt, "A Manual for the Economic Evaluation of Energy Efficiency and Renewable Energy Technologies", NREL/TP-462-5173, 1995. | ||
""" | ||
if len(production)!=len(cap_cost) or len(cap_cost)!=len(fixed_om): | ||
raise ValueError("Unequal input array lengths") | ||
mikofski marked this conversation as resolved.
Show resolved
Hide resolved
|
||
cost = cap_cost + fixed_om | ||
return np.round(np.nansum(cost)*100/np.nansum(production),2) | ||
mikofski marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
def crf(rate, n_years): | ||
""" | ||
Capital recovery factor as described on pp. 23 by [1] | ||
Parameters | ||
---------- | ||
rate : float | ||
Rate at which CRF is calculated | ||
n_years: int | ||
Number of years over which CRF is calculated | ||
|
||
Returns | ||
---------- | ||
crf : float | ||
Capital recovery factor | ||
References | ||
eccoope marked this conversation as resolved.
Show resolved
Hide resolved
|
||
---------- | ||
.. [1] W. Short, D. J. Packey, and T. Holt, "A Manual for the Economic Evaluation of Energy Efficiency and Renewable Energy Technologies", NREL/TP-462-5173, 1995. | ||
""" | ||
return np.round((rate*(1+rate)**n_years)/((1+rate)**n_years-1),8) | ||
mikofski marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
def nominal_to_real(nominal, rate): | ||
""" | ||
Inflation-adjusted rate described on pp. 6 by [1] | ||
Parameters | ||
---------- | ||
nominal : float | ||
Nominal rate (does not include adjustments for inflation) | ||
rate : float | ||
Inflation rate | ||
|
||
Returns | ||
---------- | ||
Real rate (includes adjustments for inflation) | ||
|
||
References | ||
---------- | ||
.. [1] W. Short, D. J. Packey, and T. Holt, "A Manual for the Economic Evaluation of Energy Efficiency and Renewable Energy Technologies", NREL/TP-462-5173, 1995. | ||
""" | ||
return np.round((1+nominal)/(1+rate)-1, 8) | ||
|
||
def real_to_nominal(real, rate): | ||
""" | ||
Rate without adjusting for inflation as described on pp. 6 by [1] | ||
Parameters | ||
---------- | ||
real : float | ||
Real rate (includes adjustments for inflation) | ||
rate : float | ||
Inflation rate | ||
|
||
Returns | ||
---------- | ||
Nominal rate (does not include adjustments for inflation) | ||
|
||
References | ||
---------- | ||
.. [1] W. Short, D. J. Packey, and T. Holt, "A Manual for the Economic Evaluation of Energy Efficiency and Renewable Energy Technologies", NREL/TP-462-5173, 1995. | ||
""" | ||
|
||
return np.round((real+1)*(1+rate)-1, 8) | ||
|
||
def wacc(loan_frac, rroi, rint, inflation_rate, tax_rate): | ||
""" | ||
Parameters | ||
---------- | ||
loan_frac : float | ||
Fraction of capital cost paid for with a loan | ||
rroi : float | ||
Real internal rate of return on investment | ||
rint : float | ||
Real interest rate | ||
inflation_rate : float | ||
Effective inflation rate | ||
tax_rate : float | ||
Tax rate | ||
|
||
Returns | ||
---------- | ||
wacc : float | ||
Weighted average cost of capital | ||
|
||
References | ||
---------- | ||
.. [1] S. Blumsack, "Weighted Average Cost of Capital", The Pennsylvania State University, Available: http://www.e-education.psu.edu/eme801/node/585 | ||
""" | ||
numerator = (1 + ((1 - loan_frac)*((1 + rroi)*(1 + inflation_rate)-1)) | ||
+ loan_frac*((1 + rint)*(1 + inflation_rate) - 1)*(1 - tax_rate)) | ||
denominator = 1 + inflation_rate | ||
return np.round(numerator/denominator -1, 8) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import pandas as pd | ||
import numpy as np | ||
import sys | ||
from pvlib import financial | ||
from numpy.testing import assert_allclose | ||
|
||
def test_lcoe_series(): | ||
n, cf = 20, 0.5 | ||
production = pd.Series(data=[cf*8670 for j in range(n)]) | ||
capex, loan_frac, my_crf, debt_tenor = 1000, 0.5, 0.05, n | ||
cap_cost = pd.Series(data=[capex*loan_frac*my_crf for i in range(debt_tenor)] + [0 for j in range(debt_tenor, n)]) | ||
base_om = 25 | ||
fixed_om = pd.Series(data=[base_om for j in range(n)]) | ||
|
||
expected = 1.15 | ||
out = financial.lcoe(production=production, cap_cost=cap_cost, fixed_om=fixed_om) | ||
|
||
assert_allclose(expected, out) | ||
|
||
def test_lcoe_arrays(): | ||
n, cf = 20, 0.5 | ||
production = np.full(n, cf*8670) | ||
capex, loan_frac, my_crf, debt_tenor = 1000, 0.5, 0.05, n | ||
cap_cost = np.array([capex*loan_frac*my_crf for i in range(debt_tenor)] + [0 for j in range(debt_tenor, n)]) | ||
base_om = 25 | ||
fixed_om = np.full(n, base_om) | ||
expected = 1.15 | ||
|
||
out = financial.lcoe(production=production, cap_cost=cap_cost, fixed_om=fixed_om) | ||
assert_allclose(expected, out) | ||
|
||
def test_lcoe_nans(): | ||
n, cf = 20, 0.5 | ||
production = np.full(n, cf*8670) | ||
capex, loan_frac, my_crf, debt_tenor = 1000, 0.5, 0.05, n | ||
cap_cost = np.array([capex*loan_frac*my_crf for i in range(debt_tenor)] + [0 for j in range(debt_tenor, n)]) | ||
base_om = 25. | ||
fixed_om = np.full(n, base_om) | ||
cap_cost[1] = np.nan | ||
fixed_om[2] = np.nan | ||
production[3] = np.nan | ||
expected = 1.09 | ||
|
||
out = financial.lcoe(production=production, cap_cost=cap_cost, fixed_om=fixed_om) | ||
assert_allclose(expected, out) | ||
|
||
def test_crf(): | ||
rate, n = 0.05, 20 | ||
expected = 0.08024259 | ||
|
||
out = financial.crf(rate, n) | ||
assert_allclose(expected, out) | ||
|
||
def test_nominal_to_real(): | ||
nominal, rate = 0.04, 0.025 | ||
expected = 0.01463415 | ||
|
||
out = financial.nominal_to_real(nominal, rate) | ||
assert_allclose(expected, out) | ||
|
||
def test_real_to_nominal(): | ||
real, rate = 0.04, 0.025 | ||
expected = 0.066 | ||
|
||
out = financial.real_to_nominal(real, rate) | ||
assert_allclose(expected, out) | ||
|
||
def test_wacc(): | ||
loan_frac = 0.5 | ||
rroi = 0.12 | ||
rint = 0.04 | ||
inflation_rate = 0.025 | ||
tax_rate = 0.28 | ||
expected = 0.07098537 | ||
|
||
out = financial.wacc(loan_frac, rroi, rint, inflation_rate, tax_rate) | ||
assert_allclose(expected, out) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.