Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
dfcaf1b
Revert "Fix #364 error messaging for PV one-axis tracking and bifacial"
mjprilliman Jan 29, 2021
6669556
Got working version of lcos calculations working, output variables
mjprilliman Jan 29, 2021
ad34ea2
Troubleshooting LCOS calculations
mjprilliman Jan 29, 2021
3295da1
Adding LCOS calculations, inputs, outputs to financial models
mjprilliman Feb 1, 2021
6590313
Got LCOS demo working on all financial models, PV without battery should
mjprilliman Feb 1, 2021
b4a43ef
Changed assignment check from en_batt to battery_total_cost_lcos to
mjprilliman Feb 1, 2021
fed2e25
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Feb 4, 2021
7d742c7
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Feb 5, 2021
9d8749d
Fixed ppa price calculations for charging cost, added capacity
mjprilliman Feb 5, 2021
1f274b9
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Feb 9, 2021
ea783fa
Resolved potential merge commits with develop
mjprilliman Feb 9, 2021
cdb6b4e
Fixed battery cost assignment check for LCOS calculations
mjprilliman Feb 9, 2021
43cbb2f
moved CF_max to end to fix array intermittent error
mjprilliman Feb 10, 2021
b67b720
Moved CF_max for all financial models
mjprilliman Feb 10, 2021
fdbc484
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Feb 11, 2021
354f79b
Fixed electricity rate calculations for lcos grid charging costs
mjprilliman Feb 12, 2021
a944a21
Added util rate escalation for grid charging cost calcs, added
mjprilliman Feb 12, 2021
e3f28a6
Updated electricity purchases to include rate escalation for models with
mjprilliman Feb 12, 2021
5d8c39b
Added check for subhourly data, added output cash flows for other
mjprilliman Feb 17, 2021
750771b
Removed elec purchases variables from FOM models without electricity
mjprilliman Feb 17, 2021
99c98cd
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Feb 19, 2021
c8ef874
Changed lcoe for system charging to lcoe_real, added inflation
mjprilliman Feb 19, 2021
967fb85
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Feb 26, 2021
7c5e097
Started lcoe calc without battery costs
mjprilliman Mar 2, 2021
9dccc9e
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Mar 4, 2021
2f596d6
Added variables for new lcoe calculation into singleowner
mjprilliman Mar 4, 2021
d6102b5
Attempt at simple LCOE for system only to use in grid charging cost
mjprilliman Mar 5, 2021
a3b6253
Revert "Added variables for new lcoe calculation into singleowner"
mjprilliman Mar 5, 2021
13ab687
Notes for capex vs lcoe table for pv vs pv+batt
mjprilliman Mar 5, 2021
79eb3d7
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Mar 8, 2021
afa3399
Added separate battery and pv capex costs outputs for LCOE table
mjprilliman Mar 9, 2021
cc59f27
Added PV only lcoe for use in grid charging cost calculations
mjprilliman Mar 11, 2021
233f534
Updated variables for fuel cell om, battery om cost inputs
mjprilliman Mar 12, 2021
0fb4221
Changed battery replacement cost variable name in tests
mjprilliman Mar 15, 2021
5a98b80
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Mar 18, 2021
2fdafee
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Mar 19, 2021
c9316e4
Troubleshooting charging cost calculations
mjprilliman Mar 19, 2021
2c40bb3
Added time series output for time series buy rates, still testing
mjprilliman Mar 23, 2021
c5a3e7d
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Mar 23, 2021
611254a
buy rates need to be lifetime variable
mjprilliman Mar 23, 2021
c677d5f
Added buy rate time series output to ur_calc_timestep, works for non net
mjprilliman Mar 25, 2021
dd747d4
Added checks for lifetime vs single year calculations
mjprilliman Mar 25, 2021
4aa9e19
Added monthly outputs to and from grid for ratio used in energy charge
mjprilliman Mar 26, 2021
6f76995
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Mar 31, 2021
b6e90ea
Testing grid charging cost calculations
mjprilliman Apr 1, 2021
bebe98a
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Apr 5, 2021
bbe3d75
Testing monthly energy charge before credit for use in grid charging
mjprilliman Apr 5, 2021
f9223d4
Added utility rate function calls specific to battery charging only;
mjprilliman Apr 9, 2021
46e4ff3
Using monthly energy charge calcs to determine cost of grid charging in
mjprilliman Apr 13, 2021
e175c17
Moved lcos inputs and outputs to common, added new lcoe for system
mjprilliman Apr 19, 2021
00db5d0
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Apr 19, 2021
b93e446
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Apr 23, 2021
b9155fd
Moved lcos calcs to common, working for singleowner
mjprilliman Apr 23, 2021
8bbc2f7
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Apr 26, 2021
0794878
Added lcos_calc function to other financial models; need to move to
mjprilliman Apr 27, 2021
fb62642
Fixed lcos inputs for sale leaseback, added degradation to non-lifetime
mjprilliman Apr 29, 2021
b9e613d
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Apr 29, 2021
d9cf3dc
Merge branch 'develop' into lcos_cost_inputs
mjprilliman May 3, 2021
ee618d0
Moved lcos calcs to common_financial from common
mjprilliman May 3, 2021
70a407c
Merge branch 'develop' into lcos_cost_inputs
mjprilliman May 6, 2021
7b43e6d
Fixed battery salvage calculation in common, passed battery replacement
mjprilliman May 7, 2021
c46cc58
Merge branch 'develop' into lcos_cost_inputs
mjprilliman May 7, 2021
525fabb
Merge branch 'develop' into lcos_cost_inputs
mjprilliman May 11, 2021
d222890
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Jun 2, 2021
24442ec
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Jun 18, 2021
4ef19db
Attached OM cost cashflows to lcos_calc function, restored utility rate
mjprilliman Jun 18, 2021
99452e5
Added LCOS ssc tests, probably need more test coverage
mjprilliman Jun 21, 2021
1e46bd9
Reduced number of lcos function options from 4 to 3 by combining FOM
mjprilliman Jun 21, 2021
719fae7
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Jun 24, 2021
f2b456c
Unassigned battery cost variable for pvsamv1 residential test without
mjprilliman Jun 24, 2021
06e5a9f
Changed assignment check for merchant plant to load in prices for lcos
mjprilliman Jun 28, 2021
ba950d3
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Jun 30, 2021
a9735eb
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Jul 1, 2021
cc0a172
Merge branch 'develop' into lcos_cost_inputs
mjprilliman Jul 2, 2021
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
6 changes: 3 additions & 3 deletions ssc/cmod_battery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -399,18 +399,18 @@ battstor::battstor(var_table& vt, bool setup_model, size_t nrec, double dt_hr, c


// Battery bank replacement
if (vt.is_assigned("om_replacement_cost1"))
if (vt.is_assigned("om_batt_replacement_cost"))
{
std::vector<ssc_number_t> replacement_cost(nyears);
ssc_number_t* parr = vt.as_array("om_replacement_cost1", &cnt);
ssc_number_t* parr = vt.as_array("om_batt_replacement_cost", &cnt);
if (cnt == 1)
{
for (i = 0; i < nyears; i++)
replacement_cost[i] = parr[0] * (ssc_number_t)pow((double)(inflation_rate + 1), (double)i);
}
else if (cnt < nyears)
{
throw exec_error("battery", "Invalid number for om_replacement_cost1, must be 1 or equal to analysis_period.");
throw exec_error("battery", "Invalid number for om_batt_replacement_cost, must be 1 or equal to analysis_period.");
}
else {
for (i = 0; i < nyears; i++)
Expand Down
90 changes: 62 additions & 28 deletions ssc/cmod_cashloan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "lib_financial.h"
#include "lib_util.h"
#include "common_financial.h"
#include <sstream>
using namespace libfin;
#include <sstream>

static var_info vtab_cashloan[] = {
/* VARTYPE DATATYPE NAME LABEL UNITS META GROUP REQUIRED_IF CONSTRAINTS UI_HINTS*/
Expand All @@ -37,11 +37,13 @@ static var_info vtab_cashloan[] = {

{ SSC_INPUT, SSC_NUMBER, "total_installed_cost", "Total installed cost", "$", "", "System Costs", "*", "MIN=0", "" },
{ SSC_INPUT, SSC_NUMBER, "salvage_percentage", "Salvage value percentage", "%", "", "Financial Parameters", "?=0.0", "MIN=0,MAX=100", "" },

//{ SSC_INPUT, SSC_NUMBER, "batt_salvage_percentage", "Net pre-tax cash battery salvage value", "%", "", "Financial Parameters", "?=0", "MIN=0,MAX=100", "" },

{ SSC_INPUT, SSC_ARRAY, "annual_energy_value", "Energy value", "$", "", "System Output", "*", "", "" },
{ SSC_INPUT, SSC_ARRAY, "annual_themal_value", "Energy value", "$", "", "System Output", "", "", "" },
{ SSC_INPUT, SSC_ARRAY, "gen", "Power generated by renewable resource", "kW", "", "System Output", "*", "", "" },
{ SSC_INPUT, SSC_ARRAY, "degradation", "Annual degradation", "%", "", "System Output", "*", "", "" },

{ SSC_INPUT, SSC_ARRAY, "degradation", "Annual degradation", "%", "", "System Output", "*", "", "" },
{ SSC_INPUT, SSC_NUMBER, "system_use_lifetime_output","Lifetime hourly system outputs", "0/1", "0=hourly first year,1=hourly lifetime", "Lifetime", "*", "INTEGER,MIN=0", "" },

/* financial outputs */
Expand All @@ -52,12 +54,15 @@ static var_info vtab_cashloan[] = {
{ SSC_OUTPUT, SSC_NUMBER, "payback", "Payback period", "years", "", "Cash Flow", "*", "", "" },
// added 9/26/16 for Owen Zinaman Mexico
{ SSC_OUTPUT, SSC_NUMBER, "discounted_payback", "Discounted payback period", "years", "", "Cash Flow", "*", "", "" },
{ SSC_OUTPUT, SSC_NUMBER, "npv", "Net present value", "$", "", "Cash Flow", "*", "", "" },

{ SSC_OUTPUT, SSC_NUMBER, "npv", "Net present value", "$", "", "Cash Flow", "*", "", "" },

{ SSC_OUTPUT, SSC_NUMBER, "present_value_oandm", "Present value of O&M expenses", "$", "", "Financial Metrics", "*", "", "" },
{ SSC_OUTPUT, SSC_NUMBER, "present_value_oandm_nonfuel", "Present value of non-fuel O&M expenses", "$", "", "Financial Metrics", "*", "", "" },
{ SSC_OUTPUT, SSC_NUMBER, "present_value_fuel", "Present value of fuel expenses", "$", "", "Financial Metrics", "*", "", "" },
{ SSC_OUTPUT, SSC_NUMBER, "present_value_insandproptax", "Present value of insurance and property tax", "$", "", "Financial Metrics", "*", "", "" },

{ SSC_OUTPUT, SSC_NUMBER, "npv_energy_lcos_nom", "Present value of annual stored energy (nominal)", "kWh", "", "LCOE calculations", "", "", "" },

{ SSC_OUTPUT, SSC_NUMBER, "adjusted_installed_cost", "Net capital cost", "$", "", "Financial Metrics", "*", "", "" },
{ SSC_OUTPUT, SSC_NUMBER, "loan_amount", "Debt", "$", "", "Financial Metrics", "*", "", "" },
Expand Down Expand Up @@ -162,7 +167,9 @@ extern var_info
vtab_battery_replacement_cost[],
vtab_fuelcell_replacement_cost[],
vtab_tax_credits[],
vtab_payment_incentives[];
vtab_payment_incentives[],
vtab_lcos_inputs[];


enum {
CF_degradation,
Expand All @@ -171,16 +178,6 @@ enum {
CF_thermal_value,
CF_value_added,

CF_om_fixed_expense,
CF_om_production_expense,
CF_om_capacity_expense,
CF_om_fixed1_expense,
CF_om_production1_expense,
CF_om_capacity1_expense,
CF_om_fixed2_expense,
CF_om_production2_expense,
CF_om_capacity2_expense,
CF_om_fuel_expense,

CF_om_opt_fuel_2_expense,
CF_om_opt_fuel_1_expense,
Expand Down Expand Up @@ -253,7 +250,29 @@ enum {

CF_nte,

CF_max };
CF_om_fixed_expense,
CF_om_production_expense,
CF_om_capacity_expense,
CF_om_fixed1_expense,
CF_om_production1_expense,
CF_om_capacity1_expense,
CF_om_fixed2_expense,
CF_om_production2_expense,
CF_om_capacity2_expense,
CF_om_fuel_expense,
CF_energy_charged_grid,
CF_energy_charged_pv,
CF_energy_discharged,
CF_charging_cost_pv,
CF_charging_cost_grid,
CF_om_cost_lcos,
CF_salvage_cost_lcos,
CF_investment_cost_lcos,
CF_annual_cost_lcos,
CF_util_escal_rate,

CF_max,
};



Expand All @@ -262,6 +281,7 @@ class cm_cashloan : public compute_module
{
private:
util::matrix_t<double> cf;
util::matrix_t<double> cf_lcos;
double ibi_fed_amount;
double ibi_sta_amount;
double ibi_uti_amount;
Expand Down Expand Up @@ -290,6 +310,7 @@ class cm_cashloan : public compute_module
add_var_info(vtab_battery_replacement_cost);
add_var_info(vtab_fuelcell_replacement_cost);
add_var_info(vtab_cashloan);
add_var_info(vtab_lcos_inputs);
}

void exec( )
Expand All @@ -299,7 +320,6 @@ class cm_cashloan : public compute_module
bool is_commercial = (as_integer("market")==1);
bool is_mortgage = (as_integer("mortgage")==1);


// throw exec_error("cmod_cashloan", "mortgage = " + util::to_string(as_integer("mortgage")));
// if (is_commercial) log("commercial market"); else log("residential market");
// if (is_mortgage) log("mortgage loan"); else log("standard loan");
Expand All @@ -309,6 +329,7 @@ class cm_cashloan : public compute_module

// initialize cashflow matrix
cf.resize_fill( CF_max, nyears+1, 0.0 );
cf_lcos.resize_fill(CF_max, nyears + 1, 0.0);

// initialize energy and revenue
size_t count = 0;
Expand Down Expand Up @@ -476,17 +497,17 @@ class cm_cashloan : public compute_module

if (add_om_num_types > 0)
{
escal_or_annual(CF_om_fixed1_expense, nyears, "om_fixed1", inflation_rate, 1.0, false, as_double("om_fixed_escal")*0.01);
escal_or_annual(CF_om_production1_expense, nyears, "om_production1", inflation_rate, 0.001, false, as_double("om_production_escal")*0.01);
escal_or_annual(CF_om_capacity1_expense, nyears, "om_capacity1", inflation_rate, 1.0, false, as_double("om_capacity_escal")*0.01);
nameplate1 = as_number("om_capacity1_nameplate");
escal_or_annual(CF_om_fixed1_expense, nyears, "om_batt_fixed_cost", inflation_rate, 1.0, false, as_double("om_fixed_escal") * 0.01);
escal_or_annual(CF_om_production1_expense, nyears, "om_batt_variable_cost", inflation_rate, 0.001, false, as_double("om_production_escal") * 0.01);
escal_or_annual(CF_om_capacity1_expense, nyears, "om_batt_capacity_cost", inflation_rate, 1.0, false, as_double("om_capacity_escal") * 0.01);
nameplate1 = as_number("ui_batt_capacity");
}
if (add_om_num_types > 1)
{
escal_or_annual(CF_om_fixed2_expense, nyears, "om_fixed2", inflation_rate, 1.0, false, as_double("om_fixed_escal")*0.01);
escal_or_annual(CF_om_production2_expense, nyears, "om_production2", inflation_rate, 0.001, false, as_double("om_production_escal")*0.01);
escal_or_annual(CF_om_capacity2_expense, nyears, "om_capacity2", inflation_rate, 1.0, false, as_double("om_capacity_escal")*0.01);
nameplate2 = as_number("om_capacity2_nameplate");
escal_or_annual(CF_om_fixed2_expense, nyears, "om_fuelcell_fixed_cost", inflation_rate, 1.0, false, as_double("om_fixed_escal")*0.01);
escal_or_annual(CF_om_production2_expense, nyears, "om_fuelcell_variable_cost", inflation_rate, 0.001, false, as_double("om_production_escal")*0.01);
escal_or_annual(CF_om_capacity2_expense, nyears, "om_fuelcell_capacity_cost", inflation_rate, 1.0, false, as_double("om_capacity_escal")*0.01);
nameplate2 = as_number("ui_fuelcell_capacity");
}

// battery cost - replacement from lifetime analysis
Expand All @@ -509,7 +530,7 @@ class cm_cashloan : public compute_module
}
double batt_cap = as_double("batt_computed_bank_capacity");
// updated 10/17/15 per 10/14/15 meeting
escal_or_annual(CF_battery_replacement_cost_schedule, nyears, "om_replacement_cost1", inflation_rate, batt_cap, false, as_double("om_replacement_cost_escal") * 0.01);
escal_or_annual(CF_battery_replacement_cost_schedule, nyears, "om_batt_replacement_cost", inflation_rate, batt_cap, false, as_double("om_replacement_cost_escal") * 0.01);

for (i = 0; i < nyears && i < (int)count; i++) {
// batt_rep and the cash flow sheets are 1 indexed, replacement_percent is zero indexed
Expand All @@ -526,7 +547,7 @@ class cm_cashloan : public compute_module
fuelcell_rep = as_array("fuelcell_replacement", &count); // replacements per year calculated
else // user specified
fuelcell_rep = as_array("fuelcell_replacement_schedule", &count); // replacements per year user-defined
escal_or_annual(CF_fuelcell_replacement_cost_schedule, nyears, "om_replacement_cost2", inflation_rate, nameplate2, false, as_double("om_replacement_cost_escal")*0.01);
escal_or_annual(CF_fuelcell_replacement_cost_schedule, nyears, "om_fuelcell_replacement_cost", inflation_rate, nameplate2, false, as_double("om_replacement_cost_escal")*0.01);

for ( i = 0; i < nyears && i < (int)count; i++) {
cf.at(CF_fuelcell_replacement_cost, i + 1) = fuelcell_rep[i] *
Expand Down Expand Up @@ -1002,7 +1023,20 @@ class cm_cashloan : public compute_module
assign("lcoptc_sta_nom", var_data((ssc_number_t) lcoptc_sta_nom));
assign("lcoptc_sta_real", var_data((ssc_number_t) lcoptc_sta_real));


///////////////////////////////////////////////////////////////////////
//LCOS Calculations
if (is_assigned("battery_total_cost_lcos") && as_double("battery_total_cost_lcos") != 0) {
for (int y = 0; y <= nyears; y++) {
cf_lcos.at(0, y) = cf.at(CF_battery_replacement_cost, y);
cf_lcos.at(1, y) = cf.at(CF_battery_replacement_cost_schedule, y);
cf_lcos.at(6, y) = cf.at(CF_om_fixed1_expense, y); //Fixed OM Battery cost
cf_lcos.at(7, y) = cf.at(CF_om_production1_expense, y); //Produciton OM Battery cost
cf_lcos.at(8, y) = cf.at(CF_om_capacity1_expense, y); //Capacity OM Battery Cost
}
int grid_charging_cost_version = 0;
lcos_calc(this, cf_lcos, nyears, nom_discount_rate, inflation_rate, lcoe_real, total_cost, real_discount_rate, grid_charging_cost_version, 0);
}
/////////////////////////////////////////////////////////////////////////////////////////

double wacc = 0.0;
wacc = (1.0 - debt_frac)*nom_discount_rate + debt_frac*loan_rate*(1.0 - cf.at(CF_effective_tax_frac, 1));
Expand Down
Loading