-
-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Build circuit structures flexibly #153
Comments
Hi @HongRi0716 is this something you have started working on? |
@TomTranter No. We are just going to use reinforcement learning for reconfigurable batteries to achieve cell balancing. We are trying to establish a simulation environment for reconfigurable batteries, possibly through Python or MATLAB. |
@HongRi0716 sounds interesting, are you academia or industry? Re-configuring the grid would be reasonably straightforward I think |
I'm also interested in this feature. If you think it's a good fit for liionpack I could take a look at implementing it. Could you @TomTranter give me a hint for where to start digging? |
In the first instance it seems like the most straight-forward thing to do would be to increase the connection resistance along a string in order to bypass the branch. I have never tested the code doing this so may cause numerical issues but it should be ok. Then if that doesn't work the next easiest solution would be to run a simulation and save the results then generate a new netlist and instantiate the cell models from the previous results. Saving and restarting is something that should be introduced anyway. Question becomes what happens to the cells that have been disconnected. Are they still included in the simulation for modelling thermal and equilibriation. Ideally I guess we'd just define some extra electronic components like switches etc but I don't really want to go too far down that route as I think we'd be reinventing the wheel a lot of the time when maybe in future we can leverage spice or something to do all the circuit solving |
Seems doable, but there needs to be a way for the user to tell liionpack when to open/close the branches. Is it acceptable to expect the user to muck about with the netlist directly? Then we could extend Perhaps there is a way to do this without putting the onus on the user to supply a new netlist for every step, but if so I can't see it.
This to me seems like a more intuitive solution, though perhaps less performant? And it still requires the user to mess with the netlists directly. However, as I understand it only 0D variables can be output from the simulation, which means a lot of state would be lost between steps. What is the reason only 0D variables can be output? Can we change that to allow spatially distributed output (which I believe pybamm already supports)?
Agreed. |
I think at this point editing the netlist directly is acceptable because the netlist is not constrained to be a standard combination of parallel and series connections. For large packs that are constrained in this way is would be helpful to have a way of easily accessing specific connections between cells. This would involve implementing some more advanced graph notation or classes for the netlist which is currently just a dataframe but is not a bad idea because any more complex thermal simulations than we currently have will need this anyway for cell to cell connections that are not electrical. I am working on some changes to the backend to enable this but my time is quite limited right now. This is why I asked @HongRi0716 whether they are academic or industry. Same goes for you @bessman? If there is functionality you need pybamm team to develop we will soon be forming a consultancy company that can be contracted to do it. |
I'm in industry. |
@bessman 0D variables are output automatically and this was done for efficiency and simplicity. We could create an option to save the whole solution for each battery but this will quickly grow in memory for large packs |
I can change the resistance of a single branch by updating the Rc0 value in the netlist dataframe as shown below. Results show a cell current near zero and a constant cell voltage near 3.75 V. # Change Rc0 branch resistance to bypass cell
netlist.at[2, 'value'] = 10 |
@HongRi0716 @bessman Hi! I am trying it, too. Have you finished this yet? I'm interested in your final method. |
I haven't looked at it further, sorry. |
@Mingzefei I think @wigging suggestion about simply increasing the resistance of branches you want to switch off between steps should work without any code changes. |
Yes, I spent some time implementing the swithes today. def setup_Visairo_circuit(Nb,Ri=5e-2,V=4.0,I=5):
# 0. init from lp.setup_circuit
R_busbar = 1.5e-3
R_connection = 1e-2
Np = Nb
Ns = 1
netlist = lp.setup_circuit(
Np=Np, Ns=Ns,
Rb=R_busbar, Rc=R_connection,
Ri=Ri, V=V,
I=I
)
# 1. change Rci to Rcni ("desc")
for i in range(Np):
netlist.loc[netlist["desc"] == f"Rc{i}","desc"] = f"Rcn{i}"
# 2. add Rcmi
for i in range(Np-1):
elem = {
"desc" : f"Rcmi{i}",
"node1" : Np * 1 + 1 + i,
"node2" : Np * 3 + 2 + i,
}
netlist.loc[len(netlist)] = elem
# 3. move up Rbpi, Rtp1 and I0
elem_wait_move = ["Rtp1"] + [f"Rbp{i}" for i in range(Np-1, 2*Np-2)]
node_wait_move = (netlist["node1"] > Np*3) & netlist["desc"].isin(elem_wait_move)
netlist.loc[node_wait_move,"node1"] += Np
netlist.loc[node_wait_move,"node2"] += Np
netlist.loc[netlist["desc"] == "I0","node1"] += Np
# 4. add Rcpi
for i in range(Np):
elem = {
"desc" : f"Rcp{i}",
"node1" : Np * 4 + 1 + i,
"node2" : Np * 3 + 1 + i,
}
netlist.loc[len(netlist)] = elem
# 5. update node_x and node_y
def get_node_pos(node, Nc, Nr):
total_node = Nc * Nr + 1
if node == 0:
return -1, 0
if node == total_node:
return -1, Nr-1
pos_x = (node-1) % Np
pos_y = (node-1) // Np
return pos_x, pos_y
Nc = Np
Nr = Ns * 4 + 1
netlist["node1_x"] = netlist["node1"].apply(lambda x: get_node_pos(x, Nc, Nr)[0])
netlist["node1_y"] = netlist["node1"].apply(lambda x: get_node_pos(x, Nc, Nr)[1])
netlist["node2_x"] = netlist["node2"].apply(lambda x: get_node_pos(x, Nc, Nr)[0])
netlist["node2_y"] = netlist["node2"].apply(lambda x: get_node_pos(x, Nc, Nr)[1])
def reconfigure(switch_state_list):
def resistance_for_switch(switch_state):
if switch_state == 1: # close
return 1e-3
else: # open
return 1e3
# 1. reset Rtn1 value
netlist.loc[netlist["desc"] == "Rtn1","value"] = resistance_for_switch(switch_state_list[0])
# 2. reset Rcni value
for i in range(Np):
netlist.loc[netlist["desc"] == f"Rcn{i}","value"] = resistance_for_switch(switch_state_list[1+i])
# 3. reset Rcmi value
for i in range(Np-1):
netlist.loc[netlist["desc"] == f"Rcmi{i}","value"] = resistance_for_switch(switch_state_list[1+Np+i])
# 4. reset Rcpi value
for i in range(Np):
netlist.loc[netlist["desc"] == f"Rcp{i}","value"] = resistance_for_switch(switch_state_list[2*Np+i])
# 5. reset Rtp1 value
netlist.loc[netlist["desc"] == "Rtp1","value"] = resistance_for_switch(switch_state_list[3*Np])
return netlist
return reconfigure It can be used like: rbs_v = setup_Visairo_circuit(4)
print('open all switches')
print(rbs_v([0 for i in range(3*4+1)]))
print('close all switches')
print(rbs_v([1 for i in range(3*4+1)])) However, three issues remain to be addressed:
Looking forward to your suggestions or opinions. |
I did some tests today and found that the above solution did not achieve the expected results. So, I may try other tools like simulink later. |
Description
Different parallel branches can be set, and the battery on each branch can be arbitrarily bypassed .
Motivation
Simulate the behaviour of systems which combine aged/non-aged cells;
According to states of cells, reconfigure the circuit structures to achive cell balancing.
Possible Implementation
The circuit can be built by a similar association matrix or loop matrix.
Additional context
No response
The text was updated successfully, but these errors were encountered: