Skip to content

Commit

Permalink
Merge branch 'f3/thermal-cal-bev' of github.com:NREL/fastsim into f3/…
Browse files Browse the repository at this point in the history
…thermal
  • Loading branch information
calbaker committed Jan 28, 2025
2 parents db272d4 + c4d1f84 commit 21bbaeb
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 5 deletions.
153 changes: 153 additions & 0 deletions cal_and_val/thermal/cal_bev.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
"""
Calibration script for 2020 Chevrolet Bolt EV
"""

# critical import
from pathlib import Path

# anticipated cricital imports
import numpy as np # noqa: F401
import matplotlib.pyplot as plt # noqa: F401
import seaborn as sns
import pandas as pd # noqa: F401
import polars as pl # noqa: F401

import fastsim as fsim

# Initialize seaborn plot configuration
sns.set_style()

veh = fsim.Vehicle.from_file(Path(__file__).parent / "f3-vehicles/2020 Chevrolet Bolt EV.yaml")

# Obtain the data from
# https://nrel.sharepoint.com/:f:/r/sites/EEMSCoreModelingandDecisionSupport2022-2024/Shared%20Documents/FASTSim/DynoTestData?csf=1&web=1&e=F4FEBp
# and then copy it to the local folder below
cyc_folder_path = Path(__file__) / "dyno_test_data/2020 Chevrolet Bolt EV/Extended Datasets"
assert cyc_folder_path.exists()

# See 2020_Chevrolet_Bolt_TestSummary_201005.xlsm for cycle-level data
cyc_files = [
# TODO: check for seat heater usage in cold cycles and account for that in model!
# 20F (heater maybe on? Col R in test summary), UDDS + HWY + UDDS + US06
"62009051 Test Data.txt"
# 20F (heater maybe on? Col R in test summary), US06 + UDDS + HWY + UDDS
"62009053 Test Data.txt"

# room temperature (no HVAC), UDDS + HWY + UDDS + US06
"62009019 Test Data.txt",
# room temperature (no HVAC), US06 + UDDS + HWY + UDDS
"62009021 Test Data.txt",

# TODO: check for solar load (should be around 1 kW / m^2) and implement or this somewhere (`drive_cycle`???)
# 95F (HVAC on), UDDS + HWY + UDDS
"62009040 Test Data.txt"
# 95F (HVAC on), US06
"62009041 Test Data.txt"
]
assert len(cyc_files) > 0
cyc_files = [cyc_folder_path / cyc_file for cyc_file in cyc_files]

# TODO: use random selection to retain ~70% of cycles for calibration, and
# reserve the remaining for validation
cyc_files_for_cal = [
# TOOD: populate this somehow -- e.g. random split of `cyc_files`
]
assert len(cyc_files_for_cal) > 0
dfs_for_cal = {}
for cyc_file in cyc_files_for_cal:
cyc_file: Path
# `delimiter="\t"` should work for tab separated variables
dfs_for_cal[cyc_file.stem] = pd.read_csv(cyc_file, delimiter="\t")
cycs_for_cal = {}
for (cyc_file_stem, df) in dfs_for_cal.items():
cyc_file_stem: str
df: pd.DataFrame
cyc_dict = df.to_dict()
# TODO: be ready to do some massaging of `cyc_dict`, like making sure that
# keys match expected, purging invalid keys, and massaging data types

# TODO: make sure this catches ambient temperature
cycs_for_cal[cyc_file_stem] = fsim.Cycle.from_pydict(cyc_dict)
sds_for_cal = {}
for (cyc_file_stem, cyc) in cycs_for_cal.items():
cyc_file_stem: str
cyc: fsim.Cycle
# TODO: clone veh and set up initial conditions for:
# - SOC
# - cabin temp
# - battery temp if available, else use cabin temp
# - engine temp for HEV
# NOTE: maybe change `save_interval` to 5
sds_for_cal[cyc_file_stem] = fsim.SimDrive(veh, cyc).to_pydict()

# TODO: flesh this out for validation stuff
# cyc_files_for_val = []

# Setup model objectives
## Parameter Functions
def new_em_eff_max(sd_dict, new_eff_peak):
"""
Set `new_eff_max` in `ElectricMachine`
"""
em = fsim.ElectricMachine.from_pydict(sd_dict['veh']['pt_type']['BatteryElectricVehicle']['em'])
em.set_eff_peak(new_eff_peak)
sd_dict['veh']['pt_type']['BatteryElectricVehicle']['em'] = em.to_pydict()
# TODO: check that `sd_dict` is mutably modified outside the scope of this function, e.g. with a debugger

def new_em_eff_range(sd_dict, new_eff_range):
"""
Set `new_eff_range` in `ElectricMachine`
"""
em = fsim.ElectricMachine.from_pydict(sd_dict['veh']['pt_type']['BatteryElectricVehicle']['em'])
em.set_eff_range(new_eff_range)
sd_dict['veh']['pt_type']['BatteryElectricVehicle']['em'] = em.to_pydict()
# TODO: check that `sd_dict` is mutably modified outside the scope of this function, e.g. with a debugger

## Model Objectives
cal_mod_obj = fsim.pymoo_api.ModelObjectives(
models = sds_for_cal,
dfs = dfs_for_cal,
obj_fns=(
(
lambda sd_dict: np.array(sd_dict['veh']['pt_type']['BatteryElectricVehicle']['res']['history']['soc']),
lambda df: df['HVBatt_SOC_CAN4__per']
),
# TODO: add objectives for:
# - battery temperature
(
lambda sd_dict: np.array(sd_dict['veh']['pt_type']['BatteryElectricVehicle']['res']['thermal']['RESLumpedThermal']['history']['temperature_kelvin']),
# HVBatt_cell_temp_1_CAN3__C (or average of temps?) or HVBatt_pack_average_temp_HPCM2__C?
lambda df: df['HVBatt_pack_average_temp_HPCM2__C']
),
# - cabin temperature
# - HVAC power, if available
),
param_fns=(
new_em_eff_max,
new_em_eff_range,
# TODO: make sure this has functions for modifying
# - HVAC PID controls for cabin (not for battery because Sonata has
# passive thermal management, but make sure to do battery thermal
# controls for BEV)
# - battery thermal
# - thermal mass
# - convection to ambient
# - convection to cabin
# - cabin thermal
# - thermal mass
# - length
# - htc to amb when stopped
# - set width from vehicle specs -- no need to calibrate
),
# must match order and length of `params_fns`
bounds=(
(0.80, 0.99),
(0.1, 0.6),
),

)

# Setup calibration problem
cal_prob = fsim.pymoo_api.CalibrationProblem(
mod_obj=cal_mod_obj,
)
4 changes: 2 additions & 2 deletions cal_and_val/thermal/f3-vehicles/2020 Chevrolet Bolt EV.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ year: 2020
cabin:
LumpedCabin:
# 0.05 is Chad's uncalibrated estimate
cab_shell_htc_to_amb_watts_per_square_meter_kelvin: 0.05
cab_shell_htc_to_amb_watts_per_square_meter_degree_celsius: 0.05
# 0.05 is Chad's uncalibrated estimate
cab_htc_to_amb_stop_watts_per_square_meter_kelvin: 0.05
cab_htc_to_amb_stop_watts_per_square_meter_degree_celsius: 0.05
# 200,000 is Chad's uncalibrated estimate
heat_capacitance_joules_per_kelvin: 200000
# TODO: get actual vehicle length, but calibrate this later
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ pt_type:
FuelConverterThermal:
heat_capacitance_joules_per_kelvin: 200000.0
length_for_convection_meters: 1.0
htc_to_amb_stop_watts_per_square_meter_kelvin: 50.0
htc_to_amb_stop_watts_per_square_meter_degree_celsius: 50.0
conductance_from_comb_watts_per_kelvin: 5.0
max_frac_from_comb: 0.5
tstat_te_sto_kelvin: 358.15
Expand Down Expand Up @@ -226,8 +226,8 @@ chassis:
cargo_mass_kilograms: ~
cabin:
LumpedCabin:
cab_shell_htc_to_amb_watts_per_square_meter_kelvin: 0.05
cab_htc_to_amb_stop_watts_per_square_meter_kelvin: 0.05
cab_shell_htc_to_amb_watts_per_square_meter_degree_celsius: 0.05
cab_htc_to_amb_stop_watts_per_square_meter_degree_celsius: 0.05
heat_capacitance_joules_per_kelvin: 200000.0
length_meters: 2.5
width_meters: 2.0
Expand Down

0 comments on commit 21bbaeb

Please sign in to comment.