Skip to content

Capital Costs Sub-Module

t3co.cost_models.capital_costs

CapitalCosts

Source code in src/t3co/cost_models/capital_costs.py
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
class CapitalCosts:
    glider_cost_dol: float = 0.0
    fuel_converter_cost_dol: float = 0.0
    fuel_storage_cost_dol: float = 0.0
    motor_control_power_elecs_cost_dol: float = 0.0
    plug_cost_dol: float = 0.0
    battery_cost_dol: float = 0.0
    purchase_tax_dol: float = 0.0
    msrp_total_dol: float = 0.0
    residual_cost_dol: float = 0.0
    purchasing_downpayment_dol: float = 0.0
    purchasing_initial_principal_dol: float = 0.0
    net_capital_cost_dol: float = None
    disc_residual_cost_dol: float = None

    def __new__(cls, *args, **kwargs):
        """
        Creates a new instance of the CapitalCosts class.
        """
        instance = super(CapitalCosts, cls).__new__(cls)
        return instance

    def __init__(
        self, vehicle: Vehicle, scenario: Scenario, msrp_total_dol: float = None
    ):
        """
        Initializes the CapitalCosts instance.

        Args:
            vehicle (Vehicle): The vehicle instance.
            scenario (Scenario): The scenario instance containing configuration data.
            msrp_total_dol (float, optional): MSRP in dollars as input.
        """
        if scenario.cost_toggles.msrp:
            if not msrp_total_dol and vehicle:
                self.set_glider_cost(scenario=scenario)
                self.set_fuel_converter_cost_dol(vehicle=vehicle, scenario=scenario)
                self.set_fuel_storage_cost(vehicle=vehicle, scenario=scenario)
                self.set_motor_control_power_elecs_cost(
                    vehicle=vehicle, scenario=scenario
                )
                self.set_plug_cost(vehicle=vehicle, scenario=scenario)
                self.set_battery_cost(vehicle=vehicle, scenario=scenario)
                self.set_msrp()
            else:
                self.msrp_total_dol = msrp_total_dol

        if scenario.cost_toggles.purchase_tax:
            self.set_purchase_tax(scenario=scenario)
        if scenario.cost_toggles.purchasing_downpayment:
            self.set_downpayment(scenario=scenario)
        if scenario.cost_toggles.residual_cost:
            self.set_residual_cost(scenario=scenario)
            self.set_disc_residual_cost(scenario=scenario)

        self.set_net_capital_cost()

    def set_glider_cost(self, scenario: Scenario) -> None:
        """
        Sets the glider cost for the vehicle.

        This method calculates the marked up glider cost based on the vehicle class and the base cost.

        Inputs from scenario:
        - vehicle_glider_cost_dol

        Estimated class variables:
        - glider_cost_dol

        Args:
            scenario (Scenario): The scenario instance containing configuration data, including the base cost for the glider.
        """
        self.glider_cost_dol = scenario.vehicle_glider_cost_dol
        self.glider_cost_dol = self.get_marked_up_value(self.glider_cost_dol, scenario)

    def set_fuel_converter_cost_dol(self, vehicle: Vehicle, scenario: Scenario) -> None:
        """
        Sets the fuel converter cost for the vehicle.

        This method calculates the marked up fuel converter cost based on the vehicle powertrain type and the cost per kW.

        Inputs from vehicle:
        - fc_max_kw

        Inputs from scenario:
        - fc_fuelcell_cost_dol_per_kw
        - fc_ice_cost_dol_per_kw
        - fc_cng_ice_cost_dol_per_kw
        - fc_ice_base_cost_dol

        Estimated class variables:
        - fuel_converter_cost_dol

        Args:
            vehicle (Vehicle): The vehicle instance.
            scenario (Scenario): The scenario instance containing configuration data, including the cost per kW for the fuel converter.
        """
        if vehicle.veh_pt_type == gl.BEV or vehicle.fc_max_kw == 0:
            self.fuel_converter_cost_dol = 0
        elif vehicle.veh_pt_type == gl.HEV:
            self.fuel_converter_cost_dol = (
                scenario.fc_fuelcell_cost_dol_per_kw * vehicle.fc_max_kw
            )
        elif vehicle.veh_pt_type == gl.CONV and scenario.fuel_type == "cng":
            self.fuel_converter_cost_dol = (
                scenario.fc_cng_ice_cost_dol_per_kw * vehicle.fc_max_kw
            ) + scenario.fc_ice_base_cost_dol
        else:
            self.fuel_converter_cost_dol = (
                scenario.fc_ice_cost_dol_per_kw * vehicle.fc_max_kw
            ) + scenario.fc_ice_base_cost_dol

        self.fuel_converter_cost_dol = self.get_marked_up_value(
            self.fuel_converter_cost_dol, scenario
        )

    def set_fuel_storage_cost(self, vehicle: Vehicle, scenario: Scenario) -> None:
        """
        Sets the fuel storage cost for the vehicle.

        This method calculates the marked up fuel storage cost based on the vehicle powertrain type and the cost per kWh.

        Inputs from vehicle:
        - fs_kwh

        Inputs from scenario:
        - fs_h2_cost_dol_per_kwh
        - fs_cng_cost_dol_per_kwh
        - fs_cost_dol_per_kwh

        Estimated class variables:
        - fuel_storage_cost_dol

        Args:
            vehicle (Vehicle): The vehicle instance.
            scenario (Scenario): The scenario instance containing configuration data, including the cost per kWh for the fuel storage.
        """
        if vehicle.veh_pt_type == gl.BEV:
            self.fuel_storage_cost_dol = 0
        elif vehicle.veh_pt_type == gl.HEV and scenario.fuel_type[0] == "hydrogen":
            self.fuel_storage_cost_dol = (
                scenario.fs_h2_cost_dol_per_kwh * vehicle.fs_kwh
            )
        elif (
            vehicle.veh_pt_type in [gl.CONV, gl.HEV] and scenario.fuel_type[0] == "cng"
        ):
            self.fuel_storage_cost_dol = (
                scenario.fs_cng_cost_dol_per_kwh * vehicle.fs_kwh
            )
        elif vehicle.veh_pt_type in [gl.CONV, gl.HEV]:
            self.fuel_storage_cost_dol = scenario.fs_cost_dol_per_kwh * vehicle.fs_kwh
        else:
            self.fuel_storage_cost_dol = 0

        self.fuel_storage_cost_dol = self.get_marked_up_value(
            self.fuel_storage_cost_dol, scenario
        )

    def set_motor_control_power_elecs_cost(
        self, vehicle: Vehicle, scenario: Scenario
    ) -> None:
        """
        Sets the motor control and power electronics cost for the vehicle.

        This method calculates the marked up motor control and power electronics cost based on the vehicle powertrain type and the cost per kW.

        Inputs from vehicle:
        - mc_max_kw

        Inputs from scenario:
        - pe_mc_base_cost_dol
        - pe_mc_cost_dol_per_kw

        Estimated class variables:
        - motor_control_power_elecs_cost_dol

        Args:
            vehicle (Vehicle): The vehicle instance.
            scenario (Scenario): The scenario instance containing configuration data, including the cost per kW for the motor control and power electronics.
        """
        if vehicle.mc_max_kw == 0 or vehicle.mc_max_kw is None:
            self.motor_control_power_elecs_cost_dol = 0
        else:
            self.motor_control_power_elecs_cost_dol = scenario.pe_mc_base_cost_dol + (
                scenario.pe_mc_cost_dol_per_kw * vehicle.mc_max_kw
            )
        self.motor_control_power_elecs_cost_dol = self.get_marked_up_value(
            self.motor_control_power_elecs_cost_dol, scenario
        )

    def set_plug_cost(self, vehicle: Vehicle, scenario: Scenario) -> None:
        """
        Sets the plug cost for the vehicle.

        This method calculates the marked up plug cost based on the base cost.

        Inputs from scenario:
        - plug_base_cost_dol

        Estimated class variables:
        - plug_cost_dol

        Args:
            vehicle (Vehicle): The vehicle instance.
            scenario (Scenario): The scenario instance containing configuration data, including the base cost for the plug.
        """
        if vehicle.veh_pt_type in [gl.BEV, gl.HEV] and vehicle.chg_eff:
            self.plug_cost_dol = scenario.plug_base_cost_dol
        else:
            self.plug_cost_dol = 0

        self.plug_cost_dol = self.get_marked_up_value(self.plug_cost_dol, scenario)

    def set_battery_cost(self, vehicle: Vehicle, scenario: Scenario) -> None:
        """
        Sets the battery cost for the vehicle.

        This method calculates the marked up battery cost based on the energy storage system (ESS) capacity and the cost per kWh.

        Inputs from vehicle:
        - ess_max_kwh

        Inputs from scenario:
        - ess_base_cost_dol
        - ess_cost_dol_per_kwh

        Estimated class variables:
        - battery_cost_dol

        Args:
            vehicle (Vehicle): The vehicle instance.
            scenario (Scenario): The scenario instance containing configuration data, including the cost per kWh for the battery.
        """
        if vehicle.ess_max_kwh == 0:
            self.battery_cost_dol = 0
        else:
            self.battery_cost_dol = scenario.ess_base_cost_dol + (
                scenario.ess_cost_dol_per_kwh * vehicle.ess_max_kwh
            )

        self.battery_cost_dol = self.get_marked_up_value(
            self.battery_cost_dol, scenario
        )

    def set_msrp(self) -> None:
        """
        Calculates the total MSRP (Manufacturer's Suggested Retail Price) for the vehicle.

        This method calculates the total MSRP by summing the costs of various components of the vehicle.
        The calculation uses the following CapitalCosts elements:
        - glider_cost_dol
        - fuel_storage_cost_dol
        - fuel_converter_cost_dol
        - motor_control_power_elecs_cost_dol
        - battery_cost_dol
        - plug_cost_dol

        Estimated class variables:
        - msrp_total_dol
        """

        self.msrp_total_dol = (
            self.glider_cost_dol
            + self.fuel_storage_cost_dol
            + self.fuel_converter_cost_dol
            + self.motor_control_power_elecs_cost_dol
            + self.battery_cost_dol
            + self.plug_cost_dol
        )

    def set_purchase_tax(self, scenario: Scenario) -> None:
        """
        Sets the purchase tax for the vehicle.

        This method calculates the purchase tax based on the total MSRP (Manufacturer's Suggested Retail Price) of the vehicle components.
        The calculations use the following CapitalCosts elements:
        - msrp_total_dol

        Inputs from scenario:
        - tax_rate_pct

        Estimated class variables:
        - purchase_tax_dol

        Args:
            scenario (Scenario): The scenario instance containing configuration data, including the tax rate.
        """
        self.purchase_tax_dol = self.msrp_total_dol * scenario.tax_rate_pct

    def set_downpayment(self, scenario: Scenario) -> None:
        """
        Sets the downpayment and initial principal for the vehicle purchase.

        This method calculates the downpayment and initial principal based on the purchasing method specified in the scenario.
        The calculations use the following CapitalCosts elements:
        - msrp_total_dol
        - purchase_tax_dol

        Inputs from scenario:
        - purchasing_method
        - purchasing_down_payment_pct
        - purchasing_interest_apr_pct_per_yr

        Estimated class variables:
        - purchasing_downpayment_dol
        - purchasing_initial_principal_dol

        Args:
            scenario (Scenario): The scenario instance containing configuration data, including the purchasing method, down payment percentage, and interest rate.
        """

        if scenario.purchasing_method == "loan":
            self.purchasing_downpayment_dol = (
                self.msrp_total_dol + self.purchase_tax_dol
            ) * scenario.purchasing_down_payment_pct
            self.purchasing_initial_principal_dol = (
                self.msrp_total_dol + self.purchase_tax_dol
            ) * (1 - scenario.purchasing_down_payment_pct)

        elif scenario.purchasing_method == "lease":
            scenario.leasing_money_factor = (
                scenario.purchasing_interest_apr_pct_per_yr / 24
            )
            self.purchasing_downpayment_dol = (
                self.msrp_total_dol + self.purchase_tax_dol
            ) * scenario.purchasing_down_payment_pct
            self.purchasing_initial_principal_dol = 0.0
        else:
            self.purchasing_downpayment_dol = (
                self.msrp_total_dol + self.purchase_tax_dol
            )
            self.purchasing_initial_principal_dol = 0.0

    def set_residual_cost(self, scenario: Scenario) -> None:
        """
        Sets the residual cost for the vehicle.

        This method calculates the residual cost based on the total MSRP (Manufacturer's Suggested Retail Price) of the vehicle components,
        the depreciation rates per year, and the vehicle's life span. The residual cost is the remaining value of the vehicle after depreciation.
        The calculation uses the following CapitalCosts elements:
        - msrp_total_dol

        Inputs from scenario:
        - depreciation_rates_pct_per_yr
        - vehicle_life_yr

        Estimated scenario variables:
        - residual_rate_pct

        Estimated class variables:
        - residual_cost_dol

        Args:
            scenario (Scenario): The scenario instance containing configuration data, including depreciation rates and vehicle life span.
        """

        scenario.residual_rate_pct *= np.prod(
            [
                (1 - scenario.depreciation_rates_pct_per_yr[i])
                for i in range(scenario.vehicle_life_yr)
            ]
        )
        self.residual_cost_dol = -self.msrp_total_dol * scenario.residual_rate_pct

    def set_net_capital_cost(self) -> None:
        """
        Sets the total capital cost for the vehicle.

        This method calculates the total capital cost by summing the costs of various components and applying the purchase tax.
        The calculation uses the following CapitalCosts elements:
        - purchasing_downpayment_dol

        Inputs from scenario:
        - tax_rate_pct

        Estimated class variables:
        - net_capital_cost_dol

        """
        self.net_capital_cost_dol = (
            self.purchasing_downpayment_dol
            if self.purchasing_downpayment_dol
            else (self.msrp_total_dol + self.purchase_tax_dol)
        )

    def set_disc_residual_cost(self, scenario: Scenario) -> None:
        """
        Sets the discounted residual cost for the vehicle.

        Args:
            scenario (Scenario): The scenario instance containing configuration data.
        """
        self.disc_residual_cost_dol = scenario.get_discounted_value(
            self.residual_cost_dol, year_number=scenario.vehicle_life_yr
        )

    def get_marked_up_value(self, value: float, scenario: Scenario) -> float:
        """
        Returns the marked up value.

        Args:
            value (float): The value to mark up.
            scenario (Scenario): The scenario instance containing configuration data.

        Returns:
            float: The marked up value.
        """
        return value * (scenario.markup_pct if scenario.markup_pct else 1)

__new__(*args, **kwargs)

Creates a new instance of the CapitalCosts class.

Source code in src/t3co/cost_models/capital_costs.py
23
24
25
26
27
28
def __new__(cls, *args, **kwargs):
    """
    Creates a new instance of the CapitalCosts class.
    """
    instance = super(CapitalCosts, cls).__new__(cls)
    return instance

__init__(vehicle, scenario, msrp_total_dol=None)

Initializes the CapitalCosts instance.

Parameters:

Name Type Description Default
vehicle Vehicle

The vehicle instance.

required
scenario Scenario

The scenario instance containing configuration data.

required
msrp_total_dol float

MSRP in dollars as input.

None
Source code in src/t3co/cost_models/capital_costs.py
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
def __init__(
    self, vehicle: Vehicle, scenario: Scenario, msrp_total_dol: float = None
):
    """
    Initializes the CapitalCosts instance.

    Args:
        vehicle (Vehicle): The vehicle instance.
        scenario (Scenario): The scenario instance containing configuration data.
        msrp_total_dol (float, optional): MSRP in dollars as input.
    """
    if scenario.cost_toggles.msrp:
        if not msrp_total_dol and vehicle:
            self.set_glider_cost(scenario=scenario)
            self.set_fuel_converter_cost_dol(vehicle=vehicle, scenario=scenario)
            self.set_fuel_storage_cost(vehicle=vehicle, scenario=scenario)
            self.set_motor_control_power_elecs_cost(
                vehicle=vehicle, scenario=scenario
            )
            self.set_plug_cost(vehicle=vehicle, scenario=scenario)
            self.set_battery_cost(vehicle=vehicle, scenario=scenario)
            self.set_msrp()
        else:
            self.msrp_total_dol = msrp_total_dol

    if scenario.cost_toggles.purchase_tax:
        self.set_purchase_tax(scenario=scenario)
    if scenario.cost_toggles.purchasing_downpayment:
        self.set_downpayment(scenario=scenario)
    if scenario.cost_toggles.residual_cost:
        self.set_residual_cost(scenario=scenario)
        self.set_disc_residual_cost(scenario=scenario)

    self.set_net_capital_cost()

set_glider_cost(scenario)

Sets the glider cost for the vehicle.

This method calculates the marked up glider cost based on the vehicle class and the base cost.

Inputs from scenario: - vehicle_glider_cost_dol

Estimated class variables: - glider_cost_dol

Parameters:

Name Type Description Default
scenario Scenario

The scenario instance containing configuration data, including the base cost for the glider.

required
Source code in src/t3co/cost_models/capital_costs.py
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
def set_glider_cost(self, scenario: Scenario) -> None:
    """
    Sets the glider cost for the vehicle.

    This method calculates the marked up glider cost based on the vehicle class and the base cost.

    Inputs from scenario:
    - vehicle_glider_cost_dol

    Estimated class variables:
    - glider_cost_dol

    Args:
        scenario (Scenario): The scenario instance containing configuration data, including the base cost for the glider.
    """
    self.glider_cost_dol = scenario.vehicle_glider_cost_dol
    self.glider_cost_dol = self.get_marked_up_value(self.glider_cost_dol, scenario)

set_fuel_converter_cost_dol(vehicle, scenario)

Sets the fuel converter cost for the vehicle.

This method calculates the marked up fuel converter cost based on the vehicle powertrain type and the cost per kW.

Inputs from vehicle: - fc_max_kw

Inputs from scenario: - fc_fuelcell_cost_dol_per_kw - fc_ice_cost_dol_per_kw - fc_cng_ice_cost_dol_per_kw - fc_ice_base_cost_dol

Estimated class variables: - fuel_converter_cost_dol

Parameters:

Name Type Description Default
vehicle Vehicle

The vehicle instance.

required
scenario Scenario

The scenario instance containing configuration data, including the cost per kW for the fuel converter.

required
Source code in src/t3co/cost_models/capital_costs.py
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
def set_fuel_converter_cost_dol(self, vehicle: Vehicle, scenario: Scenario) -> None:
    """
    Sets the fuel converter cost for the vehicle.

    This method calculates the marked up fuel converter cost based on the vehicle powertrain type and the cost per kW.

    Inputs from vehicle:
    - fc_max_kw

    Inputs from scenario:
    - fc_fuelcell_cost_dol_per_kw
    - fc_ice_cost_dol_per_kw
    - fc_cng_ice_cost_dol_per_kw
    - fc_ice_base_cost_dol

    Estimated class variables:
    - fuel_converter_cost_dol

    Args:
        vehicle (Vehicle): The vehicle instance.
        scenario (Scenario): The scenario instance containing configuration data, including the cost per kW for the fuel converter.
    """
    if vehicle.veh_pt_type == gl.BEV or vehicle.fc_max_kw == 0:
        self.fuel_converter_cost_dol = 0
    elif vehicle.veh_pt_type == gl.HEV:
        self.fuel_converter_cost_dol = (
            scenario.fc_fuelcell_cost_dol_per_kw * vehicle.fc_max_kw
        )
    elif vehicle.veh_pt_type == gl.CONV and scenario.fuel_type == "cng":
        self.fuel_converter_cost_dol = (
            scenario.fc_cng_ice_cost_dol_per_kw * vehicle.fc_max_kw
        ) + scenario.fc_ice_base_cost_dol
    else:
        self.fuel_converter_cost_dol = (
            scenario.fc_ice_cost_dol_per_kw * vehicle.fc_max_kw
        ) + scenario.fc_ice_base_cost_dol

    self.fuel_converter_cost_dol = self.get_marked_up_value(
        self.fuel_converter_cost_dol, scenario
    )

set_fuel_storage_cost(vehicle, scenario)

Sets the fuel storage cost for the vehicle.

This method calculates the marked up fuel storage cost based on the vehicle powertrain type and the cost per kWh.

Inputs from vehicle: - fs_kwh

Inputs from scenario: - fs_h2_cost_dol_per_kwh - fs_cng_cost_dol_per_kwh - fs_cost_dol_per_kwh

Estimated class variables: - fuel_storage_cost_dol

Parameters:

Name Type Description Default
vehicle Vehicle

The vehicle instance.

required
scenario Scenario

The scenario instance containing configuration data, including the cost per kWh for the fuel storage.

required
Source code in src/t3co/cost_models/capital_costs.py
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
def set_fuel_storage_cost(self, vehicle: Vehicle, scenario: Scenario) -> None:
    """
    Sets the fuel storage cost for the vehicle.

    This method calculates the marked up fuel storage cost based on the vehicle powertrain type and the cost per kWh.

    Inputs from vehicle:
    - fs_kwh

    Inputs from scenario:
    - fs_h2_cost_dol_per_kwh
    - fs_cng_cost_dol_per_kwh
    - fs_cost_dol_per_kwh

    Estimated class variables:
    - fuel_storage_cost_dol

    Args:
        vehicle (Vehicle): The vehicle instance.
        scenario (Scenario): The scenario instance containing configuration data, including the cost per kWh for the fuel storage.
    """
    if vehicle.veh_pt_type == gl.BEV:
        self.fuel_storage_cost_dol = 0
    elif vehicle.veh_pt_type == gl.HEV and scenario.fuel_type[0] == "hydrogen":
        self.fuel_storage_cost_dol = (
            scenario.fs_h2_cost_dol_per_kwh * vehicle.fs_kwh
        )
    elif (
        vehicle.veh_pt_type in [gl.CONV, gl.HEV] and scenario.fuel_type[0] == "cng"
    ):
        self.fuel_storage_cost_dol = (
            scenario.fs_cng_cost_dol_per_kwh * vehicle.fs_kwh
        )
    elif vehicle.veh_pt_type in [gl.CONV, gl.HEV]:
        self.fuel_storage_cost_dol = scenario.fs_cost_dol_per_kwh * vehicle.fs_kwh
    else:
        self.fuel_storage_cost_dol = 0

    self.fuel_storage_cost_dol = self.get_marked_up_value(
        self.fuel_storage_cost_dol, scenario
    )

set_motor_control_power_elecs_cost(vehicle, scenario)

Sets the motor control and power electronics cost for the vehicle.

This method calculates the marked up motor control and power electronics cost based on the vehicle powertrain type and the cost per kW.

Inputs from vehicle: - mc_max_kw

Inputs from scenario: - pe_mc_base_cost_dol - pe_mc_cost_dol_per_kw

Estimated class variables: - motor_control_power_elecs_cost_dol

Parameters:

Name Type Description Default
vehicle Vehicle

The vehicle instance.

required
scenario Scenario

The scenario instance containing configuration data, including the cost per kW for the motor control and power electronics.

required
Source code in src/t3co/cost_models/capital_costs.py
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
def set_motor_control_power_elecs_cost(
    self, vehicle: Vehicle, scenario: Scenario
) -> None:
    """
    Sets the motor control and power electronics cost for the vehicle.

    This method calculates the marked up motor control and power electronics cost based on the vehicle powertrain type and the cost per kW.

    Inputs from vehicle:
    - mc_max_kw

    Inputs from scenario:
    - pe_mc_base_cost_dol
    - pe_mc_cost_dol_per_kw

    Estimated class variables:
    - motor_control_power_elecs_cost_dol

    Args:
        vehicle (Vehicle): The vehicle instance.
        scenario (Scenario): The scenario instance containing configuration data, including the cost per kW for the motor control and power electronics.
    """
    if vehicle.mc_max_kw == 0 or vehicle.mc_max_kw is None:
        self.motor_control_power_elecs_cost_dol = 0
    else:
        self.motor_control_power_elecs_cost_dol = scenario.pe_mc_base_cost_dol + (
            scenario.pe_mc_cost_dol_per_kw * vehicle.mc_max_kw
        )
    self.motor_control_power_elecs_cost_dol = self.get_marked_up_value(
        self.motor_control_power_elecs_cost_dol, scenario
    )

set_plug_cost(vehicle, scenario)

Sets the plug cost for the vehicle.

This method calculates the marked up plug cost based on the base cost.

Inputs from scenario: - plug_base_cost_dol

Estimated class variables: - plug_cost_dol

Parameters:

Name Type Description Default
vehicle Vehicle

The vehicle instance.

required
scenario Scenario

The scenario instance containing configuration data, including the base cost for the plug.

required
Source code in src/t3co/cost_models/capital_costs.py
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
def set_plug_cost(self, vehicle: Vehicle, scenario: Scenario) -> None:
    """
    Sets the plug cost for the vehicle.

    This method calculates the marked up plug cost based on the base cost.

    Inputs from scenario:
    - plug_base_cost_dol

    Estimated class variables:
    - plug_cost_dol

    Args:
        vehicle (Vehicle): The vehicle instance.
        scenario (Scenario): The scenario instance containing configuration data, including the base cost for the plug.
    """
    if vehicle.veh_pt_type in [gl.BEV, gl.HEV] and vehicle.chg_eff:
        self.plug_cost_dol = scenario.plug_base_cost_dol
    else:
        self.plug_cost_dol = 0

    self.plug_cost_dol = self.get_marked_up_value(self.plug_cost_dol, scenario)

set_battery_cost(vehicle, scenario)

Sets the battery cost for the vehicle.

This method calculates the marked up battery cost based on the energy storage system (ESS) capacity and the cost per kWh.

Inputs from vehicle: - ess_max_kwh

Inputs from scenario: - ess_base_cost_dol - ess_cost_dol_per_kwh

Estimated class variables: - battery_cost_dol

Parameters:

Name Type Description Default
vehicle Vehicle

The vehicle instance.

required
scenario Scenario

The scenario instance containing configuration data, including the cost per kWh for the battery.

required
Source code in src/t3co/cost_models/capital_costs.py
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
def set_battery_cost(self, vehicle: Vehicle, scenario: Scenario) -> None:
    """
    Sets the battery cost for the vehicle.

    This method calculates the marked up battery cost based on the energy storage system (ESS) capacity and the cost per kWh.

    Inputs from vehicle:
    - ess_max_kwh

    Inputs from scenario:
    - ess_base_cost_dol
    - ess_cost_dol_per_kwh

    Estimated class variables:
    - battery_cost_dol

    Args:
        vehicle (Vehicle): The vehicle instance.
        scenario (Scenario): The scenario instance containing configuration data, including the cost per kWh for the battery.
    """
    if vehicle.ess_max_kwh == 0:
        self.battery_cost_dol = 0
    else:
        self.battery_cost_dol = scenario.ess_base_cost_dol + (
            scenario.ess_cost_dol_per_kwh * vehicle.ess_max_kwh
        )

    self.battery_cost_dol = self.get_marked_up_value(
        self.battery_cost_dol, scenario
    )

set_msrp()

Calculates the total MSRP (Manufacturer's Suggested Retail Price) for the vehicle.

This method calculates the total MSRP by summing the costs of various components of the vehicle. The calculation uses the following CapitalCosts elements: - glider_cost_dol - fuel_storage_cost_dol - fuel_converter_cost_dol - motor_control_power_elecs_cost_dol - battery_cost_dol - plug_cost_dol

Estimated class variables: - msrp_total_dol

Source code in src/t3co/cost_models/capital_costs.py
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
def set_msrp(self) -> None:
    """
    Calculates the total MSRP (Manufacturer's Suggested Retail Price) for the vehicle.

    This method calculates the total MSRP by summing the costs of various components of the vehicle.
    The calculation uses the following CapitalCosts elements:
    - glider_cost_dol
    - fuel_storage_cost_dol
    - fuel_converter_cost_dol
    - motor_control_power_elecs_cost_dol
    - battery_cost_dol
    - plug_cost_dol

    Estimated class variables:
    - msrp_total_dol
    """

    self.msrp_total_dol = (
        self.glider_cost_dol
        + self.fuel_storage_cost_dol
        + self.fuel_converter_cost_dol
        + self.motor_control_power_elecs_cost_dol
        + self.battery_cost_dol
        + self.plug_cost_dol
    )

set_purchase_tax(scenario)

Sets the purchase tax for the vehicle.

This method calculates the purchase tax based on the total MSRP (Manufacturer's Suggested Retail Price) of the vehicle components. The calculations use the following CapitalCosts elements: - msrp_total_dol

Inputs from scenario: - tax_rate_pct

Estimated class variables: - purchase_tax_dol

Parameters:

Name Type Description Default
scenario Scenario

The scenario instance containing configuration data, including the tax rate.

required
Source code in src/t3co/cost_models/capital_costs.py
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
def set_purchase_tax(self, scenario: Scenario) -> None:
    """
    Sets the purchase tax for the vehicle.

    This method calculates the purchase tax based on the total MSRP (Manufacturer's Suggested Retail Price) of the vehicle components.
    The calculations use the following CapitalCosts elements:
    - msrp_total_dol

    Inputs from scenario:
    - tax_rate_pct

    Estimated class variables:
    - purchase_tax_dol

    Args:
        scenario (Scenario): The scenario instance containing configuration data, including the tax rate.
    """
    self.purchase_tax_dol = self.msrp_total_dol * scenario.tax_rate_pct

set_downpayment(scenario)

Sets the downpayment and initial principal for the vehicle purchase.

This method calculates the downpayment and initial principal based on the purchasing method specified in the scenario. The calculations use the following CapitalCosts elements: - msrp_total_dol - purchase_tax_dol

Inputs from scenario: - purchasing_method - purchasing_down_payment_pct - purchasing_interest_apr_pct_per_yr

Estimated class variables: - purchasing_downpayment_dol - purchasing_initial_principal_dol

Parameters:

Name Type Description Default
scenario Scenario

The scenario instance containing configuration data, including the purchasing method, down payment percentage, and interest rate.

required
Source code in src/t3co/cost_models/capital_costs.py
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
def set_downpayment(self, scenario: Scenario) -> None:
    """
    Sets the downpayment and initial principal for the vehicle purchase.

    This method calculates the downpayment and initial principal based on the purchasing method specified in the scenario.
    The calculations use the following CapitalCosts elements:
    - msrp_total_dol
    - purchase_tax_dol

    Inputs from scenario:
    - purchasing_method
    - purchasing_down_payment_pct
    - purchasing_interest_apr_pct_per_yr

    Estimated class variables:
    - purchasing_downpayment_dol
    - purchasing_initial_principal_dol

    Args:
        scenario (Scenario): The scenario instance containing configuration data, including the purchasing method, down payment percentage, and interest rate.
    """

    if scenario.purchasing_method == "loan":
        self.purchasing_downpayment_dol = (
            self.msrp_total_dol + self.purchase_tax_dol
        ) * scenario.purchasing_down_payment_pct
        self.purchasing_initial_principal_dol = (
            self.msrp_total_dol + self.purchase_tax_dol
        ) * (1 - scenario.purchasing_down_payment_pct)

    elif scenario.purchasing_method == "lease":
        scenario.leasing_money_factor = (
            scenario.purchasing_interest_apr_pct_per_yr / 24
        )
        self.purchasing_downpayment_dol = (
            self.msrp_total_dol + self.purchase_tax_dol
        ) * scenario.purchasing_down_payment_pct
        self.purchasing_initial_principal_dol = 0.0
    else:
        self.purchasing_downpayment_dol = (
            self.msrp_total_dol + self.purchase_tax_dol
        )
        self.purchasing_initial_principal_dol = 0.0

set_residual_cost(scenario)

Sets the residual cost for the vehicle.

This method calculates the residual cost based on the total MSRP (Manufacturer's Suggested Retail Price) of the vehicle components, the depreciation rates per year, and the vehicle's life span. The residual cost is the remaining value of the vehicle after depreciation. The calculation uses the following CapitalCosts elements: - msrp_total_dol

Inputs from scenario: - depreciation_rates_pct_per_yr - vehicle_life_yr

Estimated scenario variables: - residual_rate_pct

Estimated class variables: - residual_cost_dol

Parameters:

Name Type Description Default
scenario Scenario

The scenario instance containing configuration data, including depreciation rates and vehicle life span.

required
Source code in src/t3co/cost_models/capital_costs.py
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
def set_residual_cost(self, scenario: Scenario) -> None:
    """
    Sets the residual cost for the vehicle.

    This method calculates the residual cost based on the total MSRP (Manufacturer's Suggested Retail Price) of the vehicle components,
    the depreciation rates per year, and the vehicle's life span. The residual cost is the remaining value of the vehicle after depreciation.
    The calculation uses the following CapitalCosts elements:
    - msrp_total_dol

    Inputs from scenario:
    - depreciation_rates_pct_per_yr
    - vehicle_life_yr

    Estimated scenario variables:
    - residual_rate_pct

    Estimated class variables:
    - residual_cost_dol

    Args:
        scenario (Scenario): The scenario instance containing configuration data, including depreciation rates and vehicle life span.
    """

    scenario.residual_rate_pct *= np.prod(
        [
            (1 - scenario.depreciation_rates_pct_per_yr[i])
            for i in range(scenario.vehicle_life_yr)
        ]
    )
    self.residual_cost_dol = -self.msrp_total_dol * scenario.residual_rate_pct

set_net_capital_cost()

Sets the total capital cost for the vehicle.

This method calculates the total capital cost by summing the costs of various components and applying the purchase tax. The calculation uses the following CapitalCosts elements: - purchasing_downpayment_dol

Inputs from scenario: - tax_rate_pct

Estimated class variables: - net_capital_cost_dol

Source code in src/t3co/cost_models/capital_costs.py
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
def set_net_capital_cost(self) -> None:
    """
    Sets the total capital cost for the vehicle.

    This method calculates the total capital cost by summing the costs of various components and applying the purchase tax.
    The calculation uses the following CapitalCosts elements:
    - purchasing_downpayment_dol

    Inputs from scenario:
    - tax_rate_pct

    Estimated class variables:
    - net_capital_cost_dol

    """
    self.net_capital_cost_dol = (
        self.purchasing_downpayment_dol
        if self.purchasing_downpayment_dol
        else (self.msrp_total_dol + self.purchase_tax_dol)
    )

set_disc_residual_cost(scenario)

Sets the discounted residual cost for the vehicle.

Parameters:

Name Type Description Default
scenario Scenario

The scenario instance containing configuration data.

required
Source code in src/t3co/cost_models/capital_costs.py
393
394
395
396
397
398
399
400
401
402
def set_disc_residual_cost(self, scenario: Scenario) -> None:
    """
    Sets the discounted residual cost for the vehicle.

    Args:
        scenario (Scenario): The scenario instance containing configuration data.
    """
    self.disc_residual_cost_dol = scenario.get_discounted_value(
        self.residual_cost_dol, year_number=scenario.vehicle_life_yr
    )

get_marked_up_value(value, scenario)

Returns the marked up value.

Parameters:

Name Type Description Default
value float

The value to mark up.

required
scenario Scenario

The scenario instance containing configuration data.

required

Returns:

Name Type Description
float float

The marked up value.

Source code in src/t3co/cost_models/capital_costs.py
404
405
406
407
408
409
410
411
412
413
414
415
def get_marked_up_value(self, value: float, scenario: Scenario) -> float:
    """
    Returns the marked up value.

    Args:
        value (float): The value to mark up.
        scenario (Scenario): The scenario instance containing configuration data.

    Returns:
        float: The marked up value.
    """
    return value * (scenario.markup_pct if scenario.markup_pct else 1)