@@ -26,8 +26,8 @@ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2626#include " lib_financial.h"
2727#include " lib_util.h"
2828#include " common_financial.h"
29- #include < sstream>
3029using namespace libfin ;
30+ #include < sstream>
3131
3232static var_info vtab_cashloan[] = {
3333/* VARTYPE DATATYPE NAME LABEL UNITS META GROUP REQUIRED_IF CONSTRAINTS UI_HINTS*/
@@ -37,11 +37,13 @@ static var_info vtab_cashloan[] = {
3737
3838 { SSC_INPUT, SSC_NUMBER, " total_installed_cost" , " Total installed cost" , " $" , " " , " System Costs" , " *" , " MIN=0" , " " },
3939 { SSC_INPUT, SSC_NUMBER, " salvage_percentage" , " Salvage value percentage" , " %" , " " , " Financial Parameters" , " ?=0.0" , " MIN=0,MAX=100" , " " },
40-
40+ // { SSC_INPUT, SSC_NUMBER, "batt_salvage_percentage", "Net pre-tax cash battery salvage value", "%", "", "Financial Parameters", "?=0", "MIN=0,MAX=100", "" },
41+
4142 { SSC_INPUT, SSC_ARRAY, " annual_energy_value" , " Energy value" , " $" , " " , " System Output" , " *" , " " , " " },
4243 { SSC_INPUT, SSC_ARRAY, " annual_themal_value" , " Energy value" , " $" , " " , " System Output" , " " , " " , " " },
4344 { SSC_INPUT, SSC_ARRAY, " gen" , " Power generated by renewable resource" , " kW" , " " , " System Output" , " *" , " " , " " },
44- { SSC_INPUT, SSC_ARRAY, " degradation" , " Annual degradation" , " %" , " " , " System Output" , " *" , " " , " " },
45+
46+ { SSC_INPUT, SSC_ARRAY, " degradation" , " Annual degradation" , " %" , " " , " System Output" , " *" , " " , " " },
4547 { 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" , " " },
4648
4749 /* financial outputs */
@@ -52,12 +54,15 @@ static var_info vtab_cashloan[] = {
5254 { SSC_OUTPUT, SSC_NUMBER, " payback" , " Payback period" , " years" , " " , " Cash Flow" , " *" , " " , " " },
5355 // added 9/26/16 for Owen Zinaman Mexico
5456 { SSC_OUTPUT, SSC_NUMBER, " discounted_payback" , " Discounted payback period" , " years" , " " , " Cash Flow" , " *" , " " , " " },
55- { SSC_OUTPUT, SSC_NUMBER, " npv" , " Net present value" , " $" , " " , " Cash Flow" , " *" , " " , " " },
57+
58+ { SSC_OUTPUT, SSC_NUMBER, " npv" , " Net present value" , " $" , " " , " Cash Flow" , " *" , " " , " " },
5659
5760 { SSC_OUTPUT, SSC_NUMBER, " present_value_oandm" , " Present value of O&M expenses" , " $" , " " , " Financial Metrics" , " *" , " " , " " },
5861 { SSC_OUTPUT, SSC_NUMBER, " present_value_oandm_nonfuel" , " Present value of non-fuel O&M expenses" , " $" , " " , " Financial Metrics" , " *" , " " , " " },
5962 { SSC_OUTPUT, SSC_NUMBER, " present_value_fuel" , " Present value of fuel expenses" , " $" , " " , " Financial Metrics" , " *" , " " , " " },
6063 { SSC_OUTPUT, SSC_NUMBER, " present_value_insandproptax" , " Present value of insurance and property tax" , " $" , " " , " Financial Metrics" , " *" , " " , " " },
64+
65+ { SSC_OUTPUT, SSC_NUMBER, " npv_energy_lcos_nom" , " Present value of annual stored energy (nominal)" , " kWh" , " " , " LCOE calculations" , " " , " " , " " },
6166
6267 { SSC_OUTPUT, SSC_NUMBER, " adjusted_installed_cost" , " Net capital cost" , " $" , " " , " Financial Metrics" , " *" , " " , " " },
6368 { SSC_OUTPUT, SSC_NUMBER, " loan_amount" , " Debt" , " $" , " " , " Financial Metrics" , " *" , " " , " " },
@@ -162,7 +167,9 @@ extern var_info
162167 vtab_battery_replacement_cost[],
163168 vtab_fuelcell_replacement_cost[],
164169 vtab_tax_credits[],
165- vtab_payment_incentives[];
170+ vtab_payment_incentives[],
171+ vtab_lcos_inputs[];
172+
166173
167174enum {
168175 CF_degradation,
@@ -171,16 +178,6 @@ enum {
171178 CF_thermal_value,
172179 CF_value_added,
173180
174- CF_om_fixed_expense,
175- CF_om_production_expense,
176- CF_om_capacity_expense,
177- CF_om_fixed1_expense,
178- CF_om_production1_expense,
179- CF_om_capacity1_expense,
180- CF_om_fixed2_expense,
181- CF_om_production2_expense,
182- CF_om_capacity2_expense,
183- CF_om_fuel_expense,
184181
185182 CF_om_opt_fuel_2_expense,
186183 CF_om_opt_fuel_1_expense,
@@ -253,7 +250,29 @@ enum {
253250
254251 CF_nte,
255252
256- CF_max };
253+ CF_om_fixed_expense,
254+ CF_om_production_expense,
255+ CF_om_capacity_expense,
256+ CF_om_fixed1_expense,
257+ CF_om_production1_expense,
258+ CF_om_capacity1_expense,
259+ CF_om_fixed2_expense,
260+ CF_om_production2_expense,
261+ CF_om_capacity2_expense,
262+ CF_om_fuel_expense,
263+ CF_energy_charged_grid,
264+ CF_energy_charged_pv,
265+ CF_energy_discharged,
266+ CF_charging_cost_pv,
267+ CF_charging_cost_grid,
268+ CF_om_cost_lcos,
269+ CF_salvage_cost_lcos,
270+ CF_investment_cost_lcos,
271+ CF_annual_cost_lcos,
272+ CF_util_escal_rate,
273+
274+ CF_max,
275+ };
257276
258277
259278
@@ -262,6 +281,7 @@ class cm_cashloan : public compute_module
262281{
263282private:
264283 util::matrix_t <double > cf;
284+ util::matrix_t <double > cf_lcos;
265285 double ibi_fed_amount;
266286 double ibi_sta_amount;
267287 double ibi_uti_amount;
@@ -290,6 +310,7 @@ class cm_cashloan : public compute_module
290310 add_var_info (vtab_battery_replacement_cost);
291311 add_var_info (vtab_fuelcell_replacement_cost);
292312 add_var_info (vtab_cashloan);
313+ add_var_info (vtab_lcos_inputs);
293314 }
294315
295316 void exec ( )
@@ -299,7 +320,6 @@ class cm_cashloan : public compute_module
299320 bool is_commercial = (as_integer (" market" )==1 );
300321 bool is_mortgage = (as_integer (" mortgage" )==1 );
301322
302-
303323// throw exec_error("cmod_cashloan", "mortgage = " + util::to_string(as_integer("mortgage")));
304324// if (is_commercial) log("commercial market"); else log("residential market");
305325// if (is_mortgage) log("mortgage loan"); else log("standard loan");
@@ -309,6 +329,7 @@ class cm_cashloan : public compute_module
309329
310330 // initialize cashflow matrix
311331 cf.resize_fill ( CF_max, nyears+1 , 0.0 );
332+ cf_lcos.resize_fill (CF_max, nyears + 1 , 0.0 );
312333
313334 // initialize energy and revenue
314335 size_t count = 0 ;
@@ -476,17 +497,17 @@ class cm_cashloan : public compute_module
476497
477498 if (add_om_num_types > 0 )
478499 {
479- escal_or_annual (CF_om_fixed1_expense, nyears, " om_fixed1 " , inflation_rate, 1.0 , false , as_double (" om_fixed_escal" )* 0.01 );
480- escal_or_annual (CF_om_production1_expense, nyears, " om_production1 " , inflation_rate, 0.001 , false , as_double (" om_production_escal" )* 0.01 );
481- escal_or_annual (CF_om_capacity1_expense, nyears, " om_capacity1 " , inflation_rate, 1.0 , false , as_double (" om_capacity_escal" )* 0.01 );
482- nameplate1 = as_number (" om_capacity1_nameplate " );
500+ escal_or_annual (CF_om_fixed1_expense, nyears, " om_batt_fixed_cost " , inflation_rate, 1.0 , false , as_double (" om_fixed_escal" ) * 0.01 );
501+ escal_or_annual (CF_om_production1_expense, nyears, " om_batt_variable_cost " , inflation_rate, 0.001 , false , as_double (" om_production_escal" ) * 0.01 );
502+ escal_or_annual (CF_om_capacity1_expense, nyears, " om_batt_capacity_cost " , inflation_rate, 1.0 , false , as_double (" om_capacity_escal" ) * 0.01 );
503+ nameplate1 = as_number (" ui_batt_capacity " );
483504 }
484505 if (add_om_num_types > 1 )
485506 {
486- escal_or_annual (CF_om_fixed2_expense, nyears, " om_fixed2 " , inflation_rate, 1.0 , false , as_double (" om_fixed_escal" )*0.01 );
487- escal_or_annual (CF_om_production2_expense, nyears, " om_production2 " , inflation_rate, 0.001 , false , as_double (" om_production_escal" )*0.01 );
488- escal_or_annual (CF_om_capacity2_expense, nyears, " om_capacity2 " , inflation_rate, 1.0 , false , as_double (" om_capacity_escal" )*0.01 );
489- nameplate2 = as_number (" om_capacity2_nameplate " );
507+ escal_or_annual (CF_om_fixed2_expense, nyears, " om_fuelcell_fixed_cost " , inflation_rate, 1.0 , false , as_double (" om_fixed_escal" )*0.01 );
508+ escal_or_annual (CF_om_production2_expense, nyears, " om_fuelcell_variable_cost " , inflation_rate, 0.001 , false , as_double (" om_production_escal" )*0.01 );
509+ escal_or_annual (CF_om_capacity2_expense, nyears, " om_fuelcell_capacity_cost " , inflation_rate, 1.0 , false , as_double (" om_capacity_escal" )*0.01 );
510+ nameplate2 = as_number (" ui_fuelcell_capacity " );
490511 }
491512
492513 // battery cost - replacement from lifetime analysis
@@ -509,7 +530,7 @@ class cm_cashloan : public compute_module
509530 }
510531 double batt_cap = as_double (" batt_computed_bank_capacity" );
511532 // updated 10/17/15 per 10/14/15 meeting
512- 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 );
533+ 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 );
513534
514535 for (i = 0 ; i < nyears && i < (int )count; i++) {
515536 // batt_rep and the cash flow sheets are 1 indexed, replacement_percent is zero indexed
@@ -526,7 +547,7 @@ class cm_cashloan : public compute_module
526547 fuelcell_rep = as_array (" fuelcell_replacement" , &count); // replacements per year calculated
527548 else // user specified
528549 fuelcell_rep = as_array (" fuelcell_replacement_schedule" , &count); // replacements per year user-defined
529- escal_or_annual (CF_fuelcell_replacement_cost_schedule, nyears, " om_replacement_cost2 " , inflation_rate, nameplate2, false , as_double (" om_replacement_cost_escal" )*0.01 );
550+ 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 );
530551
531552 for ( i = 0 ; i < nyears && i < (int )count; i++) {
532553 cf.at (CF_fuelcell_replacement_cost, i + 1 ) = fuelcell_rep[i] *
@@ -1002,7 +1023,20 @@ class cm_cashloan : public compute_module
10021023 assign (" lcoptc_sta_nom" , var_data ((ssc_number_t ) lcoptc_sta_nom));
10031024 assign (" lcoptc_sta_real" , var_data ((ssc_number_t ) lcoptc_sta_real));
10041025
1005-
1026+ // /////////////////////////////////////////////////////////////////////
1027+ // LCOS Calculations
1028+ if (is_assigned (" battery_total_cost_lcos" ) && as_double (" battery_total_cost_lcos" ) != 0 ) {
1029+ for (int y = 0 ; y <= nyears; y++) {
1030+ cf_lcos.at (0 , y) = cf.at (CF_battery_replacement_cost, y);
1031+ cf_lcos.at (1 , y) = cf.at (CF_battery_replacement_cost_schedule, y);
1032+ cf_lcos.at (6 , y) = cf.at (CF_om_fixed1_expense, y); // Fixed OM Battery cost
1033+ cf_lcos.at (7 , y) = cf.at (CF_om_production1_expense, y); // Produciton OM Battery cost
1034+ cf_lcos.at (8 , y) = cf.at (CF_om_capacity1_expense, y); // Capacity OM Battery Cost
1035+ }
1036+ int grid_charging_cost_version = 0 ;
1037+ lcos_calc (this , cf_lcos, nyears, nom_discount_rate, inflation_rate, lcoe_real, total_cost, real_discount_rate, grid_charging_cost_version, 0 );
1038+ }
1039+ // ///////////////////////////////////////////////////////////////////////////////////////
10061040
10071041 double wacc = 0.0 ;
10081042 wacc = (1.0 - debt_frac)*nom_discount_rate + debt_frac*loan_rate*(1.0 - cf.at (CF_effective_tax_frac, 1 ));
0 commit comments