Skip to content

Commit

Permalink
Pitt and Gitt working
Browse files Browse the repository at this point in the history
  • Loading branch information
Ombrini committed May 22, 2024
1 parent 365316e commit bdb2115
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 45 deletions.
19 changes: 13 additions & 6 deletions Param_estim/instructions.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def sim_instructions():
optimization_method = 'GD' # 'DE' or 'GD'

ensable_system = [
[("Conductivity", "sig_carb_c"), ["1e-3", "1e-4"]],
[("Conductivity", "sig_carb_c"), ["1e-2", "1e-3"]],
[("Conductivity", "E_sig_carb_c"), ["0.1", "0.4"]],
# [("Electrodes", "k0_foil"), ["10","50"]],
]
Expand All @@ -21,17 +21,19 @@ def sim_instructions():
# Define C-rates and Temperatures


temperatures = [298, 268] # K
temperatures = [298] # K
# Possible protocols: 'cc', 'pitt', 'gitt'
protocols = ['gitt']
protocols = ['pitt']
# one list for each protocol and temperature
# it is important that the order of temperatures and conditions is the same
c_rates_cc = [[0.5,1,2],
[0.5,1]] # C-rates
c_rates_gitt = [[1],
[1]] # C-rates
cont_volts = [[3.377, 3.351, 3.326],
[3.376,3.352,3.271,3.221]] # V
# cont_volts = [[3.377, 3.351, 3.326],
# [3.376,3.352,3.271,3.221]] # V
cont_volts = [[3.376, 3.326],
] # V

# Define params_system file
params_system = 'params_system_wiring.cfg'
Expand Down Expand Up @@ -61,10 +63,15 @@ def discharge():
discharge = True
return discharge

def spec_cap():
def sp_cap():
spec_cap = 1 # mAh/cm2
return spec_cap

def gitt_protocol():
steps = 20
rest_time = 30 # min
# NB: the simulation will run for 70% of the real steps to avoid crashing
return steps, rest_time
# if it is necessary to neglect the first
# initial points of the voltage curve
def neglect_parts_volts():
Expand Down
86 changes: 68 additions & 18 deletions Param_estim/objective.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
import copy
import time
import matplotlib.pyplot as plt

def run_mpet(scaled_parameters):
"""
Expand Down Expand Up @@ -43,20 +44,20 @@ def run_mpet(scaled_parameters):
dict_res[prot][temp] = {}
if prot == 'cc':
applied_conditions = c_rates_cc[i]
fold_name = "C="
fold_name = "C"
elif prot == 'gitt':
applied_conditions = c_rates_gitt[i]
fold_name = "C="
fold_name = "C"
elif prot == 'pitt':
applied_conditions = cont_volts[i]
fold_name = "V="
fold_name = "V"
else:
print('protocol not recognized')

for cond in applied_conditions:
print('running protocol: ', prot, ' at temperature: ', temp, ' at condition: ', cond)
dict_res[prot][temp][cond] = {}
store_folder = os.path.join(store_fold_mat, prot, "T=" + str(temps), fold_name + str(cond))
store_folder = os.path.join(store_fold_mat, prot, "T=" + str(temp), str(cond)+fold_name)

update_params_system(ensambles_tot_new,
params_system = config_files[0],
Expand Down Expand Up @@ -87,21 +88,17 @@ def run_mpet(scaled_parameters):
print('returning 0.25')
return 0.25
else:
ouput, spec_cap, tim = take_data_sim_out(mpet_folder())
volt, curr, spec_cap, tim = take_data_sim_out(mpet_folder())

else:
datetime = creation_time
# take data
ouput, spec_cap, tim = take_data_sim_out(mpet_folder())
volt, curr, spec_cap, tim = take_data_sim_out(mpet_folder())


# if simulation did not finish do it again with lower tolernace
if prot == 'cc' or prot == 'gitt':
volt = ouput
if prot == 'cc':
voltage_tolarenace = 0.1
elif prot == 'gitt':
voltage_tolarenace = 0.5
if prot == 'cc':
voltage_tolarenace = 0.1
if ((discharge()==True
and (cut_off_voltage(mpet_folder()) < (volt[-1] - voltage_tolarenace)))
or ((discharge()==False)
Expand All @@ -113,14 +110,27 @@ def run_mpet(scaled_parameters):
update_tolerance(ensambles_tot_new, config_files[0])
call_process(mpet_folder(), config_files[0])
reset_tolerance(ensambles_tot_new, config_files[0], relTol, absTol)
volt, spec_cap, tim = take_data_sim_out(mpet_folder())
volt, curr, spec_cap, tim = take_data_sim_out(mpet_folder())
voltage_tolarenace*=1.5
if ((discharge()==True
and (cut_off_voltage(mpet_folder()) < (volt[-1] - voltage_tolarenace)))
or ((discharge()==False)
and (cut_off_voltage(mpet_folder()) > (volt[-1] + voltage_tolarenace)))):
print('simulation did not finish again, returning 0.25')
return 0.25
elif prot == 'gitt':
if spec_cap[-1] < 0.5*sp_cap():
print('simulation did not finish')
print('decreasing tolerance and running again')
relTol, absTol = take_original_tolerance(config_files[0])
update_tolerance(ensambles_tot_new, config_files[0])
call_process(mpet_folder(), config_files[0])
reset_tolerance(ensambles_tot_new, config_files[0], relTol, absTol)
volt, curr, spec_cap, tim = take_data_sim_out(mpet_folder())
if spec_cap[-1] < 0.5*sp_cap():
print('simulation did not finish again, returning 0.25')
return 0.25

elif prot == 'pitt':
time_tolerance = 300*60 # seconds
if tim[-1] < 1e3-time_tolerance:
Expand All @@ -130,14 +140,18 @@ def run_mpet(scaled_parameters):
update_tolerance(ensambles_tot_new, config_files[0])
call_process(mpet_folder(), config_files[0])
reset_tolerance(ensambles_tot_new, config_files[0], relTol, absTol)
volt, spec_cap, tim = take_data_sim_out(mpet_folder())
volt, curr, spec_cap, tim = take_data_sim_out(mpet_folder())
time_tolerance*=1.5
if tim[-1] < 1e3-time_tolerance:
print('simulation did not finish again, returning 0.25')
return 0.25
else:
print('protocol not recognized')

if prot == 'cc' or prot == 'gitt':
ouput = volt
elif prot == 'pitt':
ouput = curr
dict_res[prot][temp][cond]["out"] = ouput
dict_res[prot][temp][cond]["spec_cap"] = spec_cap
dict_res[prot][temp][cond]["time"] = tim
Expand All @@ -147,6 +161,7 @@ def run_mpet(scaled_parameters):


def obj(parameters):

ensamble_tot, operating_conditions, config_files, optimization_method = sim_instructions()

protocols = operating_conditions[0]
Expand All @@ -161,7 +176,6 @@ def obj(parameters):
dict_res = run_mpet(parameters)
if dict_res == 0.25:
return 0.25


weighted_mse = 0
for prot in protocols:
Expand All @@ -175,19 +189,54 @@ def obj(parameters):
print('protocol not recognized')
# header = "Temp(K)\tCondition(C-Rate/Volts)\tSpecCap(mAh/cm2)\tStepTime(s)\tOutput(V/C-rate)\n"

for temp in temps:
for cond in applied_conditions:
for i, temp in enumerate(temps):
for cond in applied_conditions[i]:
print('calculating mse for protocol: ', prot, ' at temperature: ', temp, ' at condition: ', cond)
out_sim = dict_res[prot][temp][cond]["out"]
spcap_sim = dict_res[prot][temp][cond]["spec_cap"]
spcap_sim -= c0()
time_sim = dict_res[prot][temp][cond]["time"]

out_exp = dict_data[prot][temp][cond]['Output(V/C-rate)']
time_exp = dict_data[prot][temp][cond]['StepTime(s)']
spcap_exp = dict_data[prot][temp][cond]['SpecCap(mAh/cm2)']

if prot == 'cc' or prot == 'gitt':
last_sim_cap = spcap_sim[-1]
if last_sim_cap < spcap_exp[-1]:
index_exp = np.where(spcap_exp>last_sim_cap)[0][0]
spcap_exp = spcap_exp[:index_exp]
time_exp = time_exp[:index_exp]
out_exp = out_exp[:index_exp]
out_interp = np.interp(spcap_exp, spcap_sim, out_sim)
# plt.plot(spcap_exp, out_exp, 'o',label='exp')
# plt.plot(spcap_exp, out_interp, 'o',label='sim')
# plt.plot(spcap_sim, out_sim, label='sim')
# plt.legend()
# plt.show()

elif prot == 'pitt':
out_interp = np.interp(time_exp, time_sim, out_sim)
last_sim_time = time_sim[-1]
if last_sim_time < time_exp[-1]:
index_exp = np.where(time_exp>last_sim_time)[0][0]
spcap_exp = spcap_exp[:index_exp]
time_exp = time_exp[:index_exp]
out_exp = out_exp[:index_exp]

out_interp = np.interp(time_exp, time_sim, out_sim)\
# remove initialization point

out_interp = out_interp[1:]
time_sim = time_sim[1:]
out_sim = out_sim[1:]
time_exp = time_exp[1:]
out_exp = out_exp[1:]

# plt.plot(time_exp, out_exp, 'o',label='exp')
# plt.plot(time_exp, out_interp, 'o',label='sim')
# plt.plot(time_sim, out_sim, label='sim')
# plt.legend()
# plt.show()
else:
print('protocol not recognized')

Expand All @@ -196,6 +245,7 @@ def obj(parameters):

weighted_mse /= len(protocols)*len(temps)
root_weighted_mse = np.sqrt(weighted_mse)

# weighted_mse = weighted_mse*10
print('round done')
with open(os.path.join(save_folder(),"log_book.txt"), 'a') as f:
Expand Down
65 changes: 44 additions & 21 deletions Param_estim/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@


def import_data(temps, protocols, c_rates_cc, c_rates_gitt, cont_volts):
"""
Import the data from the csv files.
Input: list of temperatures, protocols, and conditions
The files must be in the folder exp_data within the Param_estim folder in mpet
Output: dictionary with data for each temperature, protocol and condition
"""
# csv file
# first raw is header
# header = "Temp(K)\tCondition(C-Rate/Volts)\tSpecCap(mAh/cm2)\tStepTime(s)\tOutput(V/C-rate)\n"
Expand All @@ -24,29 +30,26 @@ def import_data(temps, protocols, c_rates_cc, c_rates_gitt, cont_volts):
path = os.path.join(mpet_folder_path,'Param_estim' ,data_path)

data = pd.read_csv(path, header=0, sep="\t")
# select data for the specified temperatures and C-rates
# data = data.loc[data['Temp(K)'].isin(temps)]

# select data for the specified temperatures and C-rates
if protocol == 'cc':
applied_conditions = c_rates_cc
elif protocol == 'gitt':
applied_conditions = c_rates_gitt
elif protocol == 'pitt':
applied_conditions = cont_volts

# data = data.loc[data['Condition(C-Rate/Volts)'].isin(applied_conditions)]
# convert data to dictionary
t_ind = 0
for temp in temps:
for i, temp in enumerate(temps):
dict_data[protocol][temp] = {}
data_temp = data.loc[data['Temp(K)'] == temp]
for cond in applied_conditions[t_ind]:
for cond in applied_conditions[i]:
# for some reason 3.376 was not working, so I had to use > and < condition
data_cond_lower = data_temp.loc[data_temp['Condition(C-Rate/Volts)'] > (cond-0.02)]
data_cond = data_cond_lower.loc[data_cond_lower['Condition(C-Rate/Volts)'] < (cond+0.02)]
dict_data[protocol][temp][cond] = {}
data_crate = data_temp.loc[data_temp['Condition(C-Rate/Volts)'] == cond]
dict_data[protocol][temp][cond]['Output(V/C-rate)'] = np.array(data_crate['Output(V/C-rate)'])
dict_data[protocol][temp][cond]['StepTime(s)'] = np.array(data_crate['StepTime(s)'])
dict_data[protocol][temp][cond]['SpecCap(mAh/cm2)'] = np.array(data_crate['SpecCap(mAh/cm2)'])
t_ind += 1
dict_data[protocol][temp][cond]['Output(V/C-rate)'] = np.array(data_cond['Output(V/C-rate)'])
dict_data[protocol][temp][cond]['StepTime(s)'] = np.array(data_cond['StepTime(s)'])
dict_data[protocol][temp][cond]['SpecCap(mAh/cm2)'] = np.array(data_cond['SpecCap(mAh/cm2)'])

return dict_data


Expand Down Expand Up @@ -105,6 +108,18 @@ def get_voltage(sim_output, file_type, mpet_dir):

return volt

def get_current(sim_output, file_type, mpet_dir):
if file_type == 'mat':
curr = sim_output['current'][0]
elif file_type == 'hdf5':
curr = np.squeeze(sim_output['current'][...])

derived_values_pickle = os.path.join(mpet_dir,r'sim_output','input_dict_derived_values.p')
with open(derived_values_pickle, 'rb') as f:
dict_derived_values = pickle.load(f)
current = (curr * dict_derived_values['curr_ref'])
return current

def get_ff(sim_output, file_type, mpet_dir):
if file_type == 'mat':
ff = sim_output['ffrac_c'][0]
Expand All @@ -117,7 +132,7 @@ def get_specap(sim_output, file_type, mpet_dir):
ff = sim_output['ffrac_c'][0]
elif file_type == 'hdf5':
ff = np.squeeze(sim_output['ffrac_c'][...])
specap = ff*spec_cap()
specap = ff*sp_cap()
return specap

def get_time(sim_output, file_type, mpet_dir):
Expand All @@ -133,13 +148,14 @@ def get_time(sim_output, file_type, mpet_dir):

def take_data_sim_out(mpet_dir):
"""
Extract Voltage, Capacity and Times curves from the folders.
Extract Voltage, Current, Capacity and Times curves from the folders.
"""
sim_output, file_type = get_sim_out_data(mpet_dir)
volt = get_voltage(sim_output, file_type,mpet_dir)
curr = get_current(sim_output, file_type,mpet_dir)
spec_cap = get_specap(sim_output, file_type,mpet_dir)
time = get_time(sim_output, file_type,mpet_dir)
return volt, spec_cap, time
return volt, curr, spec_cap, time

def cut_off_voltage(mpet_dir):
"""
Expand All @@ -161,7 +177,7 @@ def build_gitt_segments(c_rate_gitt, numb_time_steps, ocv_time):

time_per_step = 60/(c_rate_gitt*numb_time_steps)
segments = "["
for i in range(numb_time_steps-5):
for i in range(int(numb_time_steps*0.7)):
string = f"({c_rate_gitt},{time_per_step}), (0,{ocv_time}),"
segments += string
segments += "]"
Expand All @@ -187,17 +203,24 @@ def update_params_system(ensambles, params_system, param_c, param_a, protocol, t
new_params_system["Sim Params"]["Crate"] = str(condition)
new_params_system["Sim Params"]["T"] = str(temp)
new_params_system["Sim Params"]["tramp"] = "0.01"
new_params_system["Sim Params"]["relTol"] = "1e-6"
new_params_system["Sim Params"]["absTol"] = "1e-6"
elif protocol == 'gitt':
new_params_system["Sim Params"]["profileType"] = 'CCsegments'
new_params_system["Sim Params"]["segments"] = build_gitt_segments(condition, 10, 30)
steps, rest_time = gitt_protocol()
new_params_system["Sim Params"]["segments"] = build_gitt_segments(condition, steps, rest_time)
new_params_system["Sim Params"]["T"] = str(temp)
new_params_system["Sim Params"]["tramp"] = "1"
new_params_system["Sim Params"]["tramp"] = "0.5"
new_params_system["Sim Params"]["relTol"] = "1e-7"
new_params_system["Sim Params"]["absTol"] = "1e-7"
elif protocol == 'pitt':
new_params_system["Sim Params"]["profileType"] = 'CV'
new_params_system["Sim Params"]["V"] = str(condition)
new_params_system["Sim Params"]["Vset"] = str(condition)
new_params_system["Sim Params"]["tend"] = "1e3" # minutes
new_params_system["Sim Params"]["T"] = str(temp)
new_params_system["Sim Params"]["tramp"] = "0.001"
new_params_system["Sim Params"]["tramp"] = "0"
new_params_system["Sim Params"]["relTol"] = "1e-7"
new_params_system["Sim Params"]["absTol"] = "1e-7"
for val in ensambles_s:
section = val[0][0]
key = val[0][1]
Expand Down

0 comments on commit bdb2115

Please sign in to comment.