Open ejfdickinson opened 1 year ago
@jeromtom @rtimms @tinosulzer @ejfdickinson Can you let me know more about this? I have the basic function ready below.
def write_bpx_file(param_values, filename, metadata):
# Create a dictionary with the necessary data
bpx_data = {
"metadata": metadata,
"parameters": param_values.as_dict()
}
# Serialize the dictionary into a JSON-formatted string
bpx_json = json.dumps(bpx_data, indent=2)
# Write the JSON-formatted string to a file
with open(filename, "w") as f:
f.write(bpx_json)
@jaskiratsingh2000
That's the basic idea. When it comes to practical implementation, there are some small items and some more substantial challenges though:
@rtimms @tinosulzer
I made a start on this and could share the code I have at present, which does the easier things but not the harder things (viz lookups, functions). I doubt I'll have time to take it further while remaining aligned to the main branch, so it would be a good time for someone else to round this out for general use. I'll DM to make sure I understand the GitHub alignment properly.
Thanks @ejfdickinson this is a good summary. I agree, mapping the constant is easy. The functions are more complicated. Tackling this probably requires some battery knowledge too. As highlighted, the really hard part is that functions in ParameterValues
can contain arbitrary expressions. What do I do if I have a function like
def electrolyte_conductivity_base_Landesfeind2019(c_e, T):
coeffs = np.array([5.21e-1, 2.28e2, -1.06, 3.53e-1, -3.59e-3, 1.48e-3])
c = c_e / 1000 # mol.m-3 -> mol.l
p1, p2, p3, p4, p5, p6 = coeffs
A = p1 * (1 + (T - p2))
B = 1 + p3 * pybamm.sqrt(c) + p4 * (1 + p5 * pybamm.exp(1000 / T)) * c
C = 1 + c**4 * (p6 * pybamm.exp(1000 / T))
sigma_e = A * c * B / C # mS.cm-1
return sigma_e / 10
but BPX expects a function of concentration only, multiplied by an Arrhenius dependence?
@ejfdickinson it would be great if you could push what you have so far to a branch somewhere.
@rtimms @tinosulzer
Please see code here:
@jaskiratsingh2000 If you can support the core team, please liaise with them!
At this stage I think it's better to take it up at your side - we are aiming for some workaround approaches here but they are based on imposing upstream restrictions on what can go into a ParameterValues
object in the first place, on which this method would be called - so they're not generalisable. I don't have the skills to do the remainder efficiently.
I guess that a successful solution will be able to strictly analyse callables and refuse to convert them to BPX unless they are sufficiently simple (e.g., no recursion or function nesting). At that level, handling a function like the above becomes just a case of token substitution with values.
As BPX only allows linear temperature dependence, maybe it could be handled by taking numerical derivatives from the functions i.e. evaluate (f(T+dT) - f(T-dT)) / 2 / dT.
Related to #3909
Description
A method to write a valid BPX .json to file from a ParameterValues instance.
May require options for:
This is recommended as a meaningful paired functionality to the ParameterValues.create_from_bpx() static method.
Motivation
No response
Possible Implementation
No response
Additional context
No response