Skip to content

Commit

Permalink
#920 make calls to processed var dimensional
Browse files Browse the repository at this point in the history
  • Loading branch information
rtimms committed May 27, 2020
1 parent bb5f204 commit aafaa55
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 84 deletions.
6 changes: 3 additions & 3 deletions examples/scripts/SPM_compare_particle_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,16 @@ def plot(t):
plt.xlabel(r"$r_n$")
plt.ylabel("Negative particle concentration [mol.m-3]")
for i, variables in enumerate(processed_variables):
r_n = meshes[i]["negative particle"][0].nodes
r_n = solutions[i]["r_n [m]"].entries[:, 0]
plt.plot(r_n, variables["c_n"](r=r_n, t=t), "-o", label=models[i].name)
plt.subplot(122)
plt.xlabel(r"$r_p$")
plt.ylabel("Positive particle concentration [mol.m-3]")
for i, variables in enumerate(processed_variables):
r_p = meshes[i]["positive particle"][0].nodes
r_p = solutions[i]["r_p [m]"].entries[:, 0]
plt.plot(r_p, variables["c_p"](r=r_p, t=t), "-o", label=models[i].name)
plt.legend()
plt.show()


plot(0.1)
plot(600)
11 changes: 6 additions & 5 deletions examples/scripts/SPMe_SOC.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,16 @@
xnsurf = sol["X-averaged negative particle surface concentration"]
time = sol["Time [h]"]
# Coulomb counting
time_hours = time(sol.t)
time_secs = sol.t * model.timescale_eval
time_hours = time(time_secs)
dc_time = np.around(time_hours[-1], 3)
# Capacity mAh
cap = np.absolute(I_app * 1000 * dc_time)
cap_time = np.absolute(I_app * 1000 * time_hours)
axes[enum].plot(cap_time, xnext(sol.t), "r-", label="Average Neg")
axes[enum].plot(cap_time, xpext(sol.t), "b-", label="Average Pos")
axes[enum].plot(cap_time, xnsurf(sol.t), "r--", label="Surface Neg")
axes[enum].plot(cap_time, xpsurf(sol.t), "b--", label="Surface Pos")
axes[enum].plot(cap_time, xnext(time_secs), "r-", label="Average Neg")
axes[enum].plot(cap_time, xpext(time_secs), "b-", label="Average Pos")
axes[enum].plot(cap_time, xnsurf(time_secs), "r--", label="Surface Neg")
axes[enum].plot(cap_time, xpsurf(time_secs), "b--", label="Surface Pos")
axes[enum].set_xlabel("Capacity [mAh]")
handles, labels = axes[enum].get_legend_handles_labels()
axes[enum].legend(handles, labels)
Expand Down
15 changes: 12 additions & 3 deletions examples/scripts/SPMe_step.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
# step model
dt = 500
time = 0
end_time = solution.t[-1]
timescale = model.timescale_eval
end_time = solution.t[-1] * timescale
step_solver = model.default_solver
step_solution = None
while time < end_time:
Expand All @@ -43,9 +44,17 @@
# plot
voltage = solution["Terminal voltage [V]"]
step_voltage = step_solution["Terminal voltage [V]"]
plt.plot(solution.t, voltage(solution.t), "b-", label="SPMe (continuous solve)")
plt.plot(
step_solution.t, step_voltage(step_solution.t), "ro", label="SPMe (stepped solve)"
solution.t * timescale,
voltage(solution.t * timescale),
"b-",
label="SPMe (continuous solve)",
)
plt.plot(
step_solution.t * timescale,
step_voltage(step_solution.t * timescale),
"ro",
label="SPMe (stepped solve)",
)
plt.xlabel(r"$t$")
plt.ylabel("Terminal voltage [V]")
Expand Down
7 changes: 4 additions & 3 deletions examples/scripts/compare_comsol/discharge_curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,19 @@
solution = pybamm.CasadiSolver(mode="fast").solve(
model, t, inputs={"Current function [A]": current}
)
time_in_seconds = solution.t * model.timescale_eval

# discharge capacity
discharge_capacity = solution["Discharge capacity [A.h]"]
discharge_capacity_sol = discharge_capacity(solution.t)
discharge_capacity_sol = discharge_capacity(time_in_seconds)
comsol_discharge_capacity = comsol_time * current / 3600

# extract the voltage
voltage = solution["Terminal voltage [V]"]
voltage_sol = voltage(solution.t)
voltage_sol = voltage(time_in_seconds)

# calculate the difference between the two solution methods
end_index = min(len(solution.t), len(comsol_time))
end_index = min(len(time_in_seconds), len(comsol_time))
voltage_difference = np.abs(voltage_sol[0:end_index] - comsol_voltage[0:end_index])

# plot discharge curves and absolute voltage_difference
Expand Down
110 changes: 62 additions & 48 deletions pybamm/plotting/quick_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,13 @@ def __init__(

# Spatial scales (default to 1 if information not in model)
if spatial_unit == "m":
spatial_factor = 1
self.spatial_factor = 1
self.spatial_unit = "m"
elif spatial_unit == "mm":
spatial_factor = 1e3
self.spatial_factor = 1e3
self.spatial_unit = "mm"
elif spatial_unit == "um": # micrometers
spatial_factor = 1e6
self.spatial_factor = 1e6
self.spatial_unit = "$\mu m$"
else:
raise ValueError("spatial unit '{}' not recognized".format(spatial_unit))
Expand All @@ -145,24 +145,24 @@ def __init__(
if "x [m]" in variables and "x" in variables:
x_scale = (variables["x [m]"] / variables["x"]).evaluate()[
-1
] * spatial_factor
] * self.spatial_factor
self.spatial_scales.update({dom: x_scale for dom in variables["x"].domain})
if "y [m]" in variables and "y" in variables:
self.spatial_scales["current collector y"] = (
variables["y [m]"] / variables["y"]
).evaluate()[-1] * spatial_factor
).evaluate()[-1] * self.spatial_factor
if "z [m]" in variables and "z" in variables:
self.spatial_scales["current collector z"] = (
variables["z [m]"] / variables["z"]
).evaluate()[-1] * spatial_factor
).evaluate()[-1] * self.spatial_factor
if "r_n [m]" in variables and "r_n" in variables:
self.spatial_scales["negative particle"] = (
variables["r_n [m]"] / variables["r_n"]
).evaluate()[-1] * spatial_factor
).evaluate()[-1] * self.spatial_factor
if "r_p [m]" in variables and "r_p" in variables:
self.spatial_scales["positive particle"] = (
variables["r_p [m]"] / variables["r_p"]
).evaluate()[-1] * spatial_factor
).evaluate()[-1] * self.spatial_factor

# Time parameters
model_timescale_in_seconds = models[0].timescale_eval
Expand Down Expand Up @@ -258,8 +258,8 @@ def set_output_variables(self, output_variables, solutions):
# Set up output variables
self.variables = {}
self.spatial_variable_dict = {}
self.first_dimensional_spatial_variable = {}
self.second_dimensional_spatial_variable = {}
self.first_scaled_spatial_variable = {}
self.second_scaled_spatial_variable = {}
self.first_spatial_scale = {}
self.second_spatial_scale = {}
self.is_x_r = {}
Expand Down Expand Up @@ -314,8 +314,10 @@ def set_output_variables(self, output_variables, solutions):
) = self.get_spatial_var(variable_tuple, first_variable, "first")
self.spatial_variable_dict[variable_tuple] = {
spatial_var_name: spatial_var_value
* spatial_scale
/ self.spatial_factor
}
self.first_dimensional_spatial_variable[variable_tuple] = (
self.first_scaled_spatial_variable[variable_tuple] = (
spatial_var_value * spatial_scale
)
self.first_spatial_scale[variable_tuple] = spatial_scale
Expand All @@ -341,13 +343,17 @@ def set_output_variables(self, output_variables, solutions):
second_spatial_scale,
) = self.get_spatial_var(variable_tuple, first_variable, "second")
self.spatial_variable_dict[variable_tuple] = {
first_spatial_var_name: first_spatial_var_value,
second_spatial_var_name: second_spatial_var_value,
first_spatial_var_name: first_spatial_var_value
* first_spatial_scale
/ self.spatial_factor,
second_spatial_var_name: second_spatial_var_value
* second_spatial_scale
/ self.spatial_factor,
}
self.first_dimensional_spatial_variable[variable_tuple] = (
self.first_scaled_spatial_variable[variable_tuple] = (
first_spatial_var_value * first_spatial_scale
)
self.second_dimensional_spatial_variable[variable_tuple] = (
self.second_scaled_spatial_variable[variable_tuple] = (
second_spatial_var_value * second_spatial_scale
)
if first_spatial_var_name == "r" and second_spatial_var_name == "x":
Expand Down Expand Up @@ -377,6 +383,11 @@ def get_spatial_var(self, key, variable, dimension):
else:
domain = variable.auxiliary_domains["secondary"][0]

# Remove subscript "n" or "p" so spatial_var_name can be used in the
# call to a `ProcessedVariable`
if spatial_var_name in ["r_n", "r_p"]:
spatial_var_name = "r"

if domain == "current collector":
domain += " {}".format(spatial_var_name)

Expand Down Expand Up @@ -405,20 +416,20 @@ def reset_axis(self):
x_min = self.min_t
x_max = self.max_t
elif variable_lists[0][0].dimensions == 1:
x_min = self.first_dimensional_spatial_variable[key][0]
x_max = self.first_dimensional_spatial_variable[key][-1]
x_min = self.first_scaled_spatial_variable[key][0]
x_max = self.first_scaled_spatial_variable[key][-1]
elif variable_lists[0][0].dimensions == 2:
# different order based on whether the domains are x-r, x-z or y-z
if self.is_x_r[key] is True:
x_min = self.second_dimensional_spatial_variable[key][0]
x_max = self.second_dimensional_spatial_variable[key][-1]
y_min = self.first_dimensional_spatial_variable[key][0]
y_max = self.first_dimensional_spatial_variable[key][-1]
x_min = self.second_scaled_spatial_variable[key][0]
x_max = self.second_scaled_spatial_variable[key][-1]
y_min = self.first_scaled_spatial_variable[key][0]
y_max = self.first_scaled_spatial_variable[key][-1]
else:
x_min = self.first_dimensional_spatial_variable[key][0]
x_max = self.first_dimensional_spatial_variable[key][-1]
y_min = self.second_dimensional_spatial_variable[key][0]
y_max = self.second_dimensional_spatial_variable[key][-1]
x_min = self.first_scaled_spatial_variable[key][0]
x_max = self.first_scaled_spatial_variable[key][-1]
y_min = self.second_scaled_spatial_variable[key][0]
y_max = self.second_scaled_spatial_variable[key][-1]

# Create axis for contour plot
self.axis_limits[key] = [x_min, x_max, y_min, y_max]
Expand All @@ -429,14 +440,22 @@ def reset_axis(self):
spatial_vars = self.spatial_variable_dict[key]
var_min = np.min(
[
ax_min(var(self.ts[i], **spatial_vars, warn=False))
ax_min(
var(
self.ts[i] * self.time_scale, **spatial_vars, warn=False
)
)
for i, variable_list in enumerate(variable_lists)
for var in variable_list
]
)
var_max = np.max(
[
ax_max(var(self.ts[i], **spatial_vars, warn=False))
ax_max(
var(
self.ts[i] * self.time_scale, **spatial_vars, warn=False
)
)
for i, variable_list in enumerate(variable_lists)
for var in variable_list
]
Expand Down Expand Up @@ -512,7 +531,7 @@ def plot(self, t):
full_t = self.ts[i]
(self.plots[key][i][j],) = ax.plot(
full_t * self.time_scale,
variable(full_t, warn=False),
variable(full_t * self.time_scale, warn=False),
lw=2,
color=self.colors[i],
linestyle=linestyle,
Expand Down Expand Up @@ -543,8 +562,8 @@ def plot(self, t):
# variables (color differentiates models)
linestyle = self.linestyles[j]
(self.plots[key][i][j],) = ax.plot(
self.first_dimensional_spatial_variable[key],
variable(t, **spatial_vars, warn=False),
self.first_scaled_spatial_variable[key],
variable(t * self.time_scale, **spatial_vars, warn=False),
lw=2,
color=self.colors[i],
linestyle=linestyle,
Expand All @@ -569,15 +588,15 @@ def plot(self, t):
if self.is_x_r[key] is True:
x_name = list(spatial_vars.keys())[1][0]
y_name = list(spatial_vars.keys())[0][0]
x = self.second_dimensional_spatial_variable[key]
y = self.first_dimensional_spatial_variable[key]
var = variable(t, **spatial_vars, warn=False)
x = self.second_scaled_spatial_variable[key]
y = self.first_scaled_spatial_variable[key]
var = variable(t * self.time_scale, **spatial_vars, warn=False)
else:
x_name = list(spatial_vars.keys())[0][0]
y_name = list(spatial_vars.keys())[1][0]
x = self.first_dimensional_spatial_variable[key]
y = self.second_dimensional_spatial_variable[key]
var = variable(t, **spatial_vars, warn=False).T
x = self.first_scaled_spatial_variable[key]
y = self.second_scaled_spatial_variable[key]
var = variable(t * self.time_scale, **spatial_vars, warn=False).T
ax.set_xlabel(
"{} [{}]".format(x_name, self.spatial_unit), fontsize=fontsize
)
Expand Down Expand Up @@ -663,7 +682,6 @@ def slider_update(self, t):
"""
from matplotlib import cm, colors

t_dimensionless = t / self.time_scale
for k, (key, plot) in enumerate(self.plots.items()):
ax = self.axes[k]
if self.variables[key][0][0].dimensions == 0:
Expand All @@ -673,11 +691,7 @@ def slider_update(self, t):
var_max = -np.inf
for i, variable_lists in enumerate(self.variables[key]):
for j, variable in enumerate(variable_lists):
var = variable(
t_dimensionless,
**self.spatial_variable_dict[key],
warn=False
)
var = variable(t, **self.spatial_variable_dict[key], warn=False)
plot[i][j].set_ydata(var)
var_min = min(var_min, np.nanmin(var))
var_max = max(var_max, np.nanmax(var))
Expand All @@ -703,13 +717,13 @@ def slider_update(self, t):
variable = self.variables[key][0][0]
vmin, vmax = self.variable_limits[key]
if self.is_x_r[key] is True:
x = self.second_dimensional_spatial_variable[key]
y = self.first_dimensional_spatial_variable[key]
var = variable(t_dimensionless, **spatial_vars, warn=False)
x = self.second_scaled_spatial_variable[key]
y = self.first_scaled_spatial_variable[key]
var = variable(t, **spatial_vars, warn=False)
else:
x = self.first_dimensional_spatial_variable[key]
y = self.second_dimensional_spatial_variable[key]
var = variable(t_dimensionless, **spatial_vars, warn=False).T
x = self.first_scaled_spatial_variable[key]
y = self.second_scaled_spatial_variable[key]
var = variable(t, **spatial_vars, warn=False).T
ax.contourf(
x, y, var, levels=100, vmin=vmin, vmax=vmax, cmap="coolwarm"
)
Expand Down
Loading

0 comments on commit aafaa55

Please sign in to comment.