diff --git a/.gitignore b/.gitignore index 3999e65..51225fb 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ *.Rhistory *venv* *.DS_Store +/site diff --git a/docs/CodeFlow.md b/docs/CodeFlow.md index 381843a..e08faca 100644 --- a/docs/CodeFlow.md +++ b/docs/CodeFlow.md @@ -8,7 +8,7 @@ The `-scenarios` argument points to the scenarios input file. These two files are linked with an index column called `selection`, representing the row from each file to use. [`FASTSim Vehicles`](https://github.nrel.gov/MBAP/fastsim/blob/eacc527fff54223e5e4ee1a624959ddebbf315b8/python/fastsim/vehicle.py#L145) and [`Scenarios`](https://github.com/NREL/T3CO-private/blob/9c0b19327fb60672185f087bea195a059e919cf2/t3co/run_scenario.py#L113) are the core data structures in **T3CO** - Example of [Scenario inputs](./ScenarioFile.md). + Example of [Scenario inputs](./models/ScenarioFile.md). Example of [FASTSim vehicle inputs](https://github.nrel.gov/MBAP/fastsim/blob/eacc527fff54223e5e4ee1a624959ddebbf315b8/python/fastsim/resources/FASTSim_py_veh_db.csv). @@ -19,7 +19,7 @@ - `if optimizing` - `run_moo(selection int, scenarios DataFrame, *args, **kwargs)` [link](https://github.com/NREL/T3CO-private/blob/731d07d9b2b25f6faff583348467fb79c0d5ccf6/run_scripts/sweep.py#L187) - get [get knobs-bounds & curves](https://github.com/NREL/T3CO-private/blob/4a91dc12add268faaa08a092ef6c8f010cb99f86/run_scripts/sweep.py#L88) - - note: optimization parameters (knobs) are implicitly activated by their minimum and maximum bounds being populated. See [Scenario inputs](./ScenarioFile.md). For example, if the row for your selection has populated values in columns `knob_min_ess_kwh` and `knob_max_ess_kwh` then that tells the optimizer that battery size, `ess_kwh`, is an optimization parameter (knob). The curves work the same way, for example `eng_eff_imp_curve_sel` being populated means that the opimization parameter for engine efficiency should be used. + - note: optimization parameters (knobs) are implicitly activated by their minimum and maximum bounds being populated. See [Scenario inputs](./models/ScenarioFile.md). For example, if the row for your selection has populated values in columns `knob_min_ess_kwh` and `knob_max_ess_kwh` then that tells the optimizer that battery size, `ess_kwh`, is an optimization parameter (knob). The curves work the same way, for example `eng_eff_imp_curve_sel` being populated means that the opimization parameter for engine efficiency should be used. - get [objectives and constraints](https://github.com/NREL/T3CO-private/blob/4a91dc12add268faaa08a092ef6c8f010cb99f86/run_scripts/sweep.py#L170) - note: unlike knobs, constraints need to be explicitly turned on with `True`. For example: The Scenario file will have `constraint_range` value of `True`, and by necessity the target range must be specified as well, in `target_range_mi` - begin optimization [loop](https://github.com/NREL/T3CO-private/blob/731d07d9b2b25f6faff583348467fb79c0d5ccf6/t3co/moopack/moo.py#L361) diff --git a/docs/models/CodeFlow.md b/docs/models/CodeFlow.md deleted file mode 100644 index 7f08fed..0000000 --- a/docs/models/CodeFlow.md +++ /dev/null @@ -1,110 +0,0 @@ -# General Code Flow - -- Generally, start things off in `sweep.py` with a command like - ``` - python sweep.py -selections [23,24,25,26] -vehicles /path/to/vehiclesfile.csv -scenarios /path/to/scenariosfile.csv - ``` - The `-vehicles` argument points to the vehicles input file. - The `-scenarios` argument points to the scenarios input file. - These two files are linked with an index column called `selection`, representing the row from each file to use. [`FASTSim Vehicles`](https://github.com/NREL/fastsim/blob/5910d9d610dd0760b015d78274c97308d3696798/python/fastsim/vehicle.py#L145) and [`Scenarios`](https://github.com/NREL/T3CO-private/blob/52252a06fd16cc7bae377f169b78d02c30887b96/t3co/run/run_scenario.py#L271) are the core data structures in **T3CO** - - Example of [Scenario inputs](./ScenarioFile.md). - - Example of [FASTSim vehicle inputs](https://github.com/NREL/fastsim/blob/fastsim-2/python/fastsim/resources/FASTSim_py_veh_db.csv). - -- [Sweep Code](https://github.com/NREL/T3CO-private/blob/52252a06fd16cc7bae377f169b78d02c30887b96/t3co/sweep.py#L406C5-L406C26) sweeps through selected scenarios, in this case `[23,24,25,26]` -- `for selection, scenario_name in vehicles.index, vehicles.scenario_name` - - `if selection in [23,24,25,26]: optimize(selection, scenario_name)` [link](https://github.com/NREL/T3CO-private/blob/52252a06fd16cc7bae377f169b78d02c30887b96/t3co/sweep.py#L573) - - `optimize` can optimize the vehicle and scenario, or it can skip optimizing compute TCO from vehicle and scenario inputs and report that - - `if optimizing` - - `run_moo(selection int, scenarios DataFrame, *args, **kwargs)` [link](https://github.com/NREL/T3CO-private/blob/52252a06fd16cc7bae377f169b78d02c30887b96/t3co/sweep.py#L316) - - get [get knobs-bounds & curves](https://github.com/NREL/T3CO-private/blob/52252a06fd16cc7bae377f169b78d02c30887b96/t3co/sweep.py#L138) - - note: optimization parameters (knobs) are implicitly activated by their minimum and maximum bounds being populated. See [Scenario inputs](./ScenarioFile.md). For example, if the row for your selection has populated values in columns `knob_min_ess_kwh` and `knob_max_ess_kwh` then that tells the optimizer that battery size, `ess_kwh`, is an optimization parameter (knob). The curves work the same way, for example `eng_eff_imp_curve_sel` being populated means that the opimization parameter for engine efficiency should be used. - - get [objectives and constraints](https://github.com/NREL/T3CO-private/blob/52252a06fd16cc7bae377f169b78d02c30887b96/t3co/sweep.py#L274) - - note: unlike knobs, constraints need to be explicitly turned on with `True`. For example: The Scenario file will have `constraint_range` value of `True`, and by necessity the target range must be specified as well, in `target_range_mi` - - begin optimization [loop](https://github.com/NREL/T3CO-private/blob/52252a06fd16cc7bae377f169b78d02c30887b96/t3co/moopack/moo.py#L1123) - - -``` -while lowest TCO not found by PyMoo, for, say, vehicle & selection 23: - ______________________________ ┌────────────────┐ - ╱ ╲ │return optimized│ -╱ lowest TCO found while meeting ╲__________________________________________________________________________________________________│parameters │ -╲ grade and accel constraints ╱yes └────────┬───────┘ - ╲______________________________╱ - │no - ___________▽___________ ┌──────────────────────────────────────────────┐ - ╱ ╲ │try new chassis weight, code: │ - ╱ chassis light-weighting ╲___│weight_delta_percent_knob(wt_delta_perc_guess,│ - ╲ knob active ╱yes│optvehicle) │ - ╲_______________________╱ └───────────────────────┬──────────────────────┘ - │no │ - └──────────┬─────────────────────────────┘ - ______▽_______ ┌──────────────────────────────────────────┐ - ╱ ╲ │try new drag coeff, code: │ - ╱ CdA drag coeff ╲___│cda_percent_delta_knob(CdA_reduction_perc,│ - ╲ knob active ╱yes│optvehicle) │ - ╲______________╱ └─────────────────────┬────────────────────┘ - │no │ - └─────────┬────────────────────────┘ - ________▽________ ┌─────────────────────────────────────┐ - ╱ ╲ │try new peak engine efficiency, code:│ - ╱ engine efficiency ╲___│fc_peak_eff_knob(fc_peak_eff_guess, │ - ╲ knob active ╱yes│optvehicle) │ - ╲_________________╱ └──────────────────┬──────────────────┘ - │no │ - └────────┬───────────────────────┘ - _______▽________ ┌──────────────────────────────────────┐ - ╱ ╲ │try new engine size [kw], code: │ - ╱ engine size [kw] ╲___│run_scenario.set_max_fuel_converter_kw│ - ╲ knob active ╱yes└───────────────────┬──────────────────┘ - ╲________________╱ │ - │no │ - └────────┬────────────────────────┘ - ________▽________ ┌───────────────────────────────────────────┐ - ╱ ╲ │try new fuel store size [kwh], code: │ - ╱ fuel store size ╲___│run_scenario.set_fuel_store_kwh(optvehicle,│ - ╲ [kwh] knob active ╱yes│fs_kwh_guess) │ - ╲_________________╱ └─────────────────────┬─────────────────────┘ - │no │ - └─────────┬─────────────────────────┘ - ________▽________ ┌────────────────────────────────────────────┐ - ╱ ╲ │try new battery size [kwh], code: │ - ╱ battery size ╲___│run_scenario.set_max_battery_kwh(optvehicle,│ - ╲ [kwh] knob active ╱yes│max_ess_kwh_guess) │ - ╲_________________╱ └──────────────────────┬─────────────────────┘ - │no │ - └─────────┬──────────────────────────┘ - _______▽________ ┌─────────────────────────────────────────┐ - ╱ ╲ │try new motor power [kw], code: │ - ╱ motor power [kw] ╲___│run_scenario.set_max_motor_kw(optvehicle,│ - ╲ knob active ╱yes│self.opt_scenario, max_motor_kw_guess) │ - ╲________________╱ └────────────────────┬────────────────────┘ - │no │ - └─────────────────┬────────────────┴─ - ┌────────────▽───────────┐ - │compute TCO and, if │ - │applicable, acceleration│ - │and grade performance │ - └────────────┬───────────┘ - ┌────────────▽────────────┐ - │Optimizer keeps cycling │ - │trying to find lowest TCO│ - └─────────────────────────┘ -``` - - - - - - - - - - - - - - -diagrams generated with https://arthursonzogni.com/Diagon/#Flowchart - diff --git a/docs/models/PHEVs.md b/docs/models/PHEVs.md index 4c9679c..610ff95 100644 --- a/docs/models/PHEVs.md +++ b/docs/models/PHEVs.md @@ -6,11 +6,11 @@ Given that PHEVs follow along the same TCO and optimizaton path as other powertr - [Plug-in Hybrid Electric Vehicle Considerations](#plug-in-hybrid-electric-vehicle-considerations) - [Contents](#contents) - - [PHEV Fuel Economy CD/CS ](#phev-fuel-economy-cdcs-) - - [PHEV Fuel Costs and Utility Factor ](#phev-fuel-costs-and-utility-factor-) - - [PHEV Acceleration \& Grade Tests ](#phev-acceleration--grade-tests-) - - [PHEV Optimization ](#phev-optimization-) - - [PHEV Special Inputs ](#phev-special-inputs-) + - [PHEV Fuel Economy CD/CS ](#phev-fuel-econ) + - [PHEV Fuel Costs and Utility Factor ](#phev-fuel-costs) + - [PHEV Acceleration \& Grade Tests ](#phev-accel-grade) + - [PHEV Optimization ](#phev-optimization) + - [PHEV Special Inputs ](#phev-special-inputs) - [PHEVs Not Doing What You Want?](#phev-issues) ## PHEV Fuel Economy CD/CS @@ -99,11 +99,11 @@ It is worth noting that initial SOC inputs for grade and acceleration of PHEVs d init soc: 0.85 max speed at 6% grade achvd 67.793 init soc: 0.95 max speed at 6% grade achvd 67.793 -## PHEV Optimization +## PHEV Optimization PHEV optimization uses an optional, special input called `motor_power_override_kw_fc_demand_on_pct`. This is the percentage of motor power value set to the vehicle field `kw_fc_demand_on` to allow `kw_fc_demand_on` to increase or decrease proportionally with changes in `mc_max_kw` from the optimizer. This is described in more detail in the opimization docs. -## PHEV Special Inputs +## PHEV Special Inputs |**PHEV** scenario file inputs| description | required/optional | default | range | |--|--|--|--|--| diff --git a/docs/models/ScenarioFile.md b/docs/models/ScenarioFile.md index 846291a..c5193f5 100644 --- a/docs/models/ScenarioFile.md +++ b/docs/models/ScenarioFile.md @@ -60,10 +60,10 @@ Below is an example of a scenario file contents, in columnar format for readabil |`constraint_grade`| < > |`nan`| `True or False` Optimization setting. If True, then the constraint is applied and tests for grade must be met or exceeded Test threshold designated by value in `min_speed_at_6pct_grade_in_5min_mph and min_speed_at_125pct_grade_in_5min_mph`| |`objective_tco`| < > | `nan`| `True or False` Optimization setting. If True, then the objective to minimize Total Cost of Ownership is applied. | |`constraint_c_rate`| < > | `True`| `True or False` Optimization setting. If True, then the constraint for c rate is applied| -|`shifts_per_year`| < > | `260`| PHEVs only! See [PHEV Docs](./PHEVs.md#special-inputs)| -|`phev_utility_factor_override`| < > | `.6`| PHEVs only! See [PHEV Docs](./PHEVs.md#special-inputs)| -|`soc_norm_init_for_grade_pct`| < > | `.8`| PHEVs only! See [PHEV Docs](./PHEVs.md#special-inputs)| -|`soc_norm_init_for_accel_pct`| < > | `.85`| PHEVs only! See [PHEV Docs](./PHEVs.md#special-inputs)| -|`motor_power_override_kw_fc_demand_on_pct`| < > | `.95`| PHEV specific inputs. See [PHEV Docs](./PHEVs.md#special-inputs)| -|`ess_init_soc_grade`| < > | `.8`|`[0,1]` For BEV or HEV, during grade test, if initial SOC override is desired, rather than using the [FASTSim + T3CO intial SOC regime](acceleration_and_grade_tests.md#default-initial-socs-)| -|`ess_init_soc_accel`| < > |`.85`|`[0,1]` For BEV or HEV, during grade test, if initial SOC override is desired, rather than using the [FASTSim + T3CO intial SOC regime](acceleration_and_grade_tests.md#default-initial-socs-)| +|`shifts_per_year`| < > | `260`| PHEVs only! See [PHEV Docs](./PHEVs.md#phev-special-inputs)| +|`phev_utility_factor_override`| < > | `.6`| PHEVs only! See [PHEV Docs](./PHEVs.md#phev-special-inputs)| +|`soc_norm_init_for_grade_pct`| < > | `.8`| PHEVs only! See [PHEV Docs](./PHEVs.md#phev-special-inputs)| +|`soc_norm_init_for_accel_pct`| < > | `.85`| PHEVs only! See [PHEV Docs](./PHEVs.md#phev-special-inputs)| +|`motor_power_override_kw_fc_demand_on_pct`| < > | `.95`| PHEV specific inputs. See [PHEV Docs](./PHEVs.md#phev-special-inputs)| +|`ess_init_soc_grade`| < > | `.8`|`[0,1]` For BEV or HEV, during grade test, if initial SOC override is desired, rather than using the [FASTSim + T3CO intial SOC regime](acceleration_and_grade_tests.md#default-socs)| +|`ess_init_soc_accel`| < > |`.85`|`[0,1]` For BEV or HEV, during grade test, if initial SOC override is desired, rather than using the [FASTSim + T3CO intial SOC regime](acceleration_and_grade_tests.md#default-socs)| diff --git a/docs/models/TCO_calculations.md b/docs/models/TCO_calculations.md index ad5d094..4278cb5 100644 --- a/docs/models/TCO_calculations.md +++ b/docs/models/TCO_calculations.md @@ -5,13 +5,13 @@ - [MSRP Inputs](#msrp-inputs) - [MSRP Formula](#msrp-formula) - [MSRP Code](#msrp-code) - - [Fuel Costs ](#fuel-costs-) - - [Other Costs ](#other-costs-) - - [Payload Opportunity Costs ](#payload-opportunity-costs-) - - [Stock Model TCO Calculations ](#stock-model-tco-calculations-) - - [BEV considerations ](#bev-considerations-) - - [PHEV considerations ](#phev-considerations-) - - [Fuel Costs Table ](#fuel-costs-table-) + - [Fuel Costs ](#fuel-costs) + - [Other Costs ](#other-costs) + - [Payload Opportunity Costs ](#payload-opportunity-costs) + - [Stock Model TCO Calculations ](#stock-model-tco-calculations) + - [BEV considerations ](#bev-considerations) + - [PHEV considerations ](#phev-considerations) + - [Fuel Costs Table ](#fuel-costs-table) ## Overview The Total Cost of Ownership is a core metric calculated by T3CO. It is made up of a few parts. The first is **MSRP**, or the purchase cost of the vehicle. Then there is fuel cost for each operational year. Then there are "other costs" as well as Payload Opportunity Costs. @@ -56,7 +56,7 @@ The Glider and Plug costs are straight inputs from the T3CO scenario file. Batte |`fc_cng_ice_cost_dol_per_kw`|`55`|`float` | |`fs_cng_cost_dol_per_kwh`|`7.467735503`|`float` | |`vehicle_glider_cost_dol`|`112759`| `float`| -##### MSRP Formula +##### MSRP Formula vehicle_glider_cost_dol = scenario.vehicle_glider_cost_dol @@ -134,7 +134,7 @@ The Glider and Plug costs are straight inputs from the T3CO scenario file. Batte Code to [generate MSRP](https://github.com/NREL/T3CO-private/blob/ecad5e28523ac3e5a17c67b9ed747207f6162035/t3co/tco/tcocalc.py#L24) -## Fuel Costs +## Fuel Costs Fuel costs make up a plurality, if not the majority, of TCO. As one would expect, fuel costs per year are dependant on three things: The fuel efficiency of the vehicle, the miles travelled per year, and the cost per unit of fuel. All [fuel efficiencies](./fuel_efficiency_and_range.md) are converted to miles per gallon of gasoline equivalent (MPGGE). All fuel costs are converted to dollars per gallon of gasoline equivalent. ``` @@ -168,7 +168,7 @@ Then there is the annual travel table ([code](https://github.com/NREL/T3CO-priva |3|85,000| |4|80,000| -Finally, these are all joined with the fuel split table ([code](https://github.com/NREL/T3CO-private/blob/ecad5e28523ac3e5a17c67b9ed747207f6162035/t3co/tco/tcocalc.py#L425)), such that each fuel used is assessed pro rata based on the proportion of usage for driven miles. This comes into play for PHEVs and their [Utility Factor](PHEVs.md#phev-fuel-costs-and-utility-factor-) +Finally, these are all joined with the fuel split table ([code](https://github.com/NREL/T3CO-private/blob/ecad5e28523ac3e5a17c67b9ed747207f6162035/t3co/tco/tcocalc.py#L425)), such that each fuel used is assessed pro rata based on the proportion of usage for driven miles. This comes into play for PHEVs and their [Utility Factor](PHEVs.md#phev-fuel-costs) Usual **Conventional or HEV format**: |Vehicle|Fuel|Vocation|Fraction of Travel [mi/mi]| @@ -190,7 +190,7 @@ These joins happen in the [Stock Model Code](https://github.com/NREL/T3CO-privat -## Other Costs +## Other Costs There are other costs for vehicles during their TCO operational period ([code](https://github.com/NREL/T3CO-private/blob/ecad5e28523ac3e5a17c67b9ed747207f6162035/t3co/tco/tcocalc.py#L263)). These costs are, but not limited to, maintenance costs `$/mile`, for both conventional and advanced powertrains, denoted from the Scenario input file as `maint_oper_cost_dol_per_mi` provided as a list across the vehicle life @@ -206,25 +206,25 @@ There is also `payload opportunity cost` (under development), as well as optiona |United States|BOX TRUCK|MD BOX TRUCK|labor opp cost| 0 | -## Payload Opportunity Costs +## Payload Opportunity Costs **Payload Opportunity Cost** is the concept of applying an opportunity cost to payload capacity that might be lost due to increasing a vehicle vocation empty weight when electrifying the powertrain. In the example below, the empty weight of the vehicle increased by 11,958 pounds. This region, less the EV weight credit of 2,000 pounds, is shaded in red under the kernel density estimate, representing potential lost cargo due to electrification and added battery weight. ![image](./opp_cost_ex1.png) -## Stock Model TCO Calculations +## Stock Model TCO Calculations Total vehicle costs are compiled via a series elegant of table `INNER JOINS` in the stock model [code](https://github.com/NREL/T3CO-private/blob/master/t3co/tco/tco_stock_emissions.py). -## BEV considerations +## BEV considerations Vehicles that run on alternative fuels such as BEVs, FCEVs (treated as HEV by FASTSim), run on fuels, such as hydrogen or electricity, that need to be converted to a gallon of gasoline equivalent unit for fuel efficiency, `MPGGE`, and cost, `$/GGE`. The code where these conversions happen is [here](https://github.com/NREL/T3CO-private/blob/ecad5e28523ac3e5a17c67b9ed747207f6162035/t3co/tco/tcocalc.py#L339): -## PHEV considerations +## PHEV considerations PHEVs have the same considerations as BEVs, but with the added twist of Utility Factors, which can come in as a user input in the Scenario File, or get computed. See [PHEV Considerations](PHEVs.md#phev-fuel-costs-and-utility-factor). -## Fuel Costs Table +## Fuel Costs Table The default fuel costs table is located at `t3co.resources.FuelPrices.csv` ![image](https://github.nrel.gov/storage/user/1225/files/5f088c43-2e56-4c01-9388-f99a961769d6) diff --git a/t3co/tco/tcocalc.py b/t3co/tco/tcocalc.py index 6675259..c22b920 100644 --- a/t3co/tco/tcocalc.py +++ b/t3co/tco/tcocalc.py @@ -60,7 +60,7 @@ def calculate_dollar_cost( - Purchase tax Args: - vehicle (fastsim.vehicle.Vehicle): FASTSim vehicle object of analysis vehicle + veh (fastsim.vehicle.Vehicle): FASTSim vehicle object of analysis vehicle scenario (run_scenario.Scenario): Scenario object of current selection Returns: