Skip to content

Commit cfca092

Browse files
authored
First computational results (#58)
* Start Julianic API for notebooks * Half cell and symmetric cell notebooks * valuetype parameter to allow higher precision runs * update scaling parameters * Add first simulation result pngs for lake arrowhead workshop * update .gitignore * Add notebooks to CI tests * Bump patch version of package (not breaking) * check for not being in CI when saving figures * use adaptive solver steps
1 parent 0658c4c commit cfca092

21 files changed

Lines changed: 1163 additions & 150 deletions

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,14 @@ Manifest*.toml
33
__pycache__
44
condaenv
55
**/venv
6+
draftresults
7+
draft.pdf
8+
*.nav
9+
*.snm
10+
*.toc
11+
*.aux
12+
*.log
13+
*.bbl
14+
*.blg
15+
*.out
16+
*.tdo

Project.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,21 @@ DynamicQuantities = "06fc5a27-2a28-4c7c-a15d-362465fb6821"
1111
ExtendableGrids = "cfc395e8-590f-11e8-1f13-43a2532b2fa8"
1212
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
1313
HypertextLiteral = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2"
14+
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
1415
Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
1516
JuliaMPBSolver = "d8b18f01-5396-498d-b34d-247825c18ff0"
1617
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
1718
LessUnitful = "f29f6376-6e90-4d80-80c9-fb8ec61203d5"
1819
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
20+
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
1921
NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56"
2022
Pluto = "c3e4b0f8-55cb-11ea-2926-15256bba5781"
2123
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
2224
PreallocationTools = "d236fae5-4411-538c-8e31-a6e3d9e00b46"
2325
PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d"
2426
PythonPlot = "274fc56d-3b97-40fa-a1cd-1b4a50311bf9"
2527
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
28+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2629
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
2730
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
2831
VoronoiFVM = "82b139dc-5afc-11e9-35da-9b9bdfd336f3"
@@ -33,12 +36,15 @@ JuliaMPBSolver = {path = "packages/JuliaMPBSolver"}
3336
[compat]
3437
DoubleFloats = "1"
3538
DynamicQuantities = "1.10.0"
39+
ExampleJuggler = "2.4.0"
3640
ExtendableGrids = "1"
3741
ForwardDiff = "1"
3842
HypertextLiteral = "0.9"
43+
InteractiveUtils = "1.11.0"
3944
Interpolations = "0.16"
4045
LaTeXStrings = "1.0.1"
4146
LessUnitful = "1"
47+
Markdown = "1.11.0"
4248
PlutoUI = "0.7"
4349
PreallocationTools = "0.4"
4450
PythonCall = "0.9"
@@ -48,9 +54,10 @@ VoronoiFVM = "2.14"
4854
julia = "1.11"
4955

5056
[extras]
57+
ExampleJuggler = "3bbe58f8-ed81-4c4e-a134-03e85fcf4a1a"
5158
JuliaMPBSolver = "d8b18f01-5396-498d-b34d-247825c18ff0"
5259
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
5360
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
5461

5562
[targets]
56-
test = ["Pkg", "Test", "JuliaMPBSolver"]
63+
test = ["Pkg", "Test", "JuliaMPBSolver", "ExampleJuggler"]
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
### A Pluto.jl notebook ###
2+
# v0.20.19
3+
4+
using Markdown
5+
using InteractiveUtils
6+
7+
# ╔═╡ a70cef7d-2a2f-4155-bdf3-fec9df94c63f
8+
begin
9+
using Pkg
10+
Pkg.activate(joinpath(@__DIR__, ".."))
11+
using Revise
12+
using PlutoUI, HypertextLiteral, UUIDs
13+
using VoronoiFVM
14+
using ExtendableGrids
15+
using LinearAlgebra
16+
using LessUnitful
17+
using Test
18+
using DoubleFloats
19+
using PythonPlot
20+
using PythonCall
21+
using PythonPlot: pyplot
22+
using LaTeXStrings
23+
using Colors
24+
using JuliaMPBSolver.ICMPBP: ICMPBP, ICMPBData, AppliedPotentialHalfCell, set_molarity!, calc_cmol, calc_c0mol, calc_χ, get_E, get_φ, get_p, get_c0,
25+
set_κ!, set_φ!
26+
using DrWatson, PoissonBoltzmannIPAM2025
27+
28+
end
29+
30+
# ╔═╡ af6ae00d-f032-4743-878b-e575466b6e84
31+
md"""
32+
# Half cell with applied potential
33+
"""
34+
35+
# ╔═╡ 87d66a6f-b40d-4d76-afc6-4b4f086e80a4
36+
begin
37+
const nm = ufac"nm"
38+
const V = ufac"V"
39+
const cm = ufac"cm"
40+
const dm = ufac"dm"
41+
const μF = ufac"μF"
42+
const N_A = ph"N_A"
43+
const mol = ufac"mol"
44+
end
45+
46+
# ╔═╡ 087614cc-a4f6-4867-a6bd-201d1f2a7fc2
47+
begin
48+
const L = 10nm
49+
const n = 101
50+
end
51+
52+
# ╔═╡ c7a51cb9-790a-4818-95d7-c32f2252e8b3
53+
Xhalf = (10 .^ range(-3, 1, length = 101)) * nm;
54+
55+
# ╔═╡ 4ef3d13c-2f57-4575-bc88-c8092ae6910f
56+
gridhalf = simplexgrid(Xhalf)
57+
58+
# ╔═╡ 3a99a9bb-7862-41f8-a535-d3c580da6909
59+
md"""
60+
All values are given with respect to SI basic units (m, kg, s, V, A)
61+
"""
62+
63+
# ╔═╡ b24b7e23-61ea-41fc-a345-286e904c042b
64+
datavhalf = ICMPBData(χvar = true)
65+
66+
# ╔═╡ 1bb47749-edde-4bee-be9f-059a7652b354
67+
begin
68+
datavhalf.qscale = sqrt(datavhalf.qscale)
69+
halfcell = AppliedPotentialHalfCell(gridhalf, datavhalf, dielectric_decrement = false, valuetype = Float64)
70+
71+
halfcelldd = AppliedPotentialHalfCell(gridhalf, datavhalf, dielectric_decrement = true, valuetype = Float64)
72+
end;
73+
74+
75+
# ╔═╡ dd3c4807-3972-4e9c-a44a-3347b065d01c
76+
p3 = plotcells(halfcell, halfcelldd); p3
77+
78+
# ╔═╡ 935f8897-4d68-447b-8316-1a0fe0285d54
79+
@test isa(p3, Figure)
80+
81+
# ╔═╡ d07ac411-7985-4b5f-a88b-8aa4037b7d65
82+
function makecolors(V)
83+
h = 0.5 / length(V)
84+
return colors = [ (i * h, 0, 1 - i * h) for i in 1:length(V) ]
85+
end
86+
87+
# ╔═╡ 2cf54b71-d99b-40bd-b9a6-0a7cf919614b
88+
p1 = let
89+
molarities = [0.001, 0.01, 0.1, 1]
90+
φ_max = 0.5
91+
colors = makecolors(molarities)
92+
pyplot.close()
93+
clf()
94+
fig, ax = pyplot.subplots(1, 1)
95+
fig.set_size_inches(600 / 100, 300 / 100)
96+
κ = 10
97+
ax.set_title("Double layer capacitance, κ=$(κ)\n Dashed: witghout dielectric decrement")
98+
set_κ!(halfcell, κ)
99+
set_κ!(halfcelldd, κ)
100+
for i in 1:length(molarities)
101+
M = molarities[i]
102+
set_molarity!(halfcell, M)
103+
104+
volts, dlcaps = ICMPBP.dlcapsweep(halfcell; φ_max)
105+
plot(volts, dlcaps / (μF / cm^2), color = colors[i], linestyle = "--")
106+
107+
set_molarity!(halfcelldd, M)
108+
volts, dlcaps = ICMPBP.dlcapsweep(halfcelldd; φ_max, damp_initial = 0.5)
109+
plot(volts, dlcaps / (μF / cm^2), label = "M=$(M)", color = colors[i])
110+
end
111+
ax.set_xlabel("U/V")
112+
ax.set_ylabel(L"C_{dl}/(μF/cm^2)")
113+
ax.legend()
114+
ax.grid()
115+
tight_layout()
116+
117+
!haskey(ENV, "CI") && savefig(draftresultsdir("halfcell_dlcap_M"), dpi = 600)
118+
119+
gcf()
120+
end; p1
121+
122+
# ╔═╡ 52d5fb3c-072d-4a6e-a392-7e236b4ec933
123+
@test isa(p1, Figure)
124+
125+
# ╔═╡ cc8e8ba6-4cc6-4e8a-bbd6-07b9f61c2ef5
126+
p2 = let
127+
kappas = [1, 5, 10, 20]
128+
φ_max = 0.5
129+
M = 0.1
130+
colors = makecolors(kappas)
131+
pyplot.close()
132+
clf()
133+
fig, ax = pyplot.subplots(1, 1)
134+
fig.set_size_inches(600 / 100, 300 / 100)
135+
ax.set_title("Double layer capacitance, M=$(M)\n Dashed: without dielectric decrement")
136+
set_molarity!(halfcell, M)
137+
set_molarity!(halfcelldd, M)
138+
for i in 1:length(kappas)
139+
κ = kappas[i]
140+
set_κ!(halfcell, κ)
141+
set_κ!(halfcelldd, κ)
142+
143+
volts, dlcaps = ICMPBP.dlcapsweep(halfcelldd; φ_max, damp_initial = 0.5)
144+
plot(volts, dlcaps / (μF / cm^2), label = "κ=$(κ)", color = colors[i])
145+
146+
volts, dlcaps = ICMPBP.dlcapsweep(halfcell; φ_max)
147+
plot(volts, dlcaps / (μF / cm^2), color = colors[i], linestyle = "--")
148+
149+
end
150+
ax.set_xlabel("U/V")
151+
ax.set_ylabel(L"C_{dl}/(μF/cm^2)")
152+
ax.legend()
153+
ax.grid()
154+
tight_layout()
155+
!haskey(ENV, "CI") && savefig(draftresultsdir("halfcell_dlcap_kappa"), dpi = 600)
156+
157+
gcf()
158+
end; p2
159+
160+
# ╔═╡ 48896662-d87f-4606-9118-6471184b4dc7
161+
@test isa(p2, Figure)
162+
163+
# ╔═╡ 8af12f1c-d35b-4cc9-8185-1bb5adbb69e8
164+
html"""<hr>"""
165+
166+
# ╔═╡ 784b4c3e-bb2a-4940-a83a-ed5e5898dfd4
167+
html"""<style>.dont-panic{ display: none }</style>"""
168+
169+
# ╔═╡ afe4745f-f9f1-4e23-8735-cbec6fb79c41
170+
begin
171+
function floataside(text::Markdown.MD; top = 1)
172+
uuid = uuid1()
173+
return @htl(
174+
"""
175+
<style>
176+
177+
178+
@media (min-width: calc(700px + 30px + 300px)) {
179+
aside.plutoui-aside-wrapper-$(uuid) {
180+
181+
color: var(--pluto-output-color);
182+
position:fixed;
183+
right: 1rem;
184+
top: $(top)px;
185+
width: 400px;
186+
padding: 10px;
187+
border: 3px solid rgba(0, 0, 0, 0.15);
188+
border-radius: 10px;
189+
box-shadow: 0 0 11px 0px #00000010;
190+
/* That is, viewport minus top minus Live Docs */
191+
max-height: calc(100vh - 5rem - 56px);
192+
overflow: auto;
193+
z-index: 40;
194+
background-color: var(--main-bg-color);
195+
transition: transform 300ms cubic-bezier(0.18, 0.89, 0.45, 1.12);
196+
197+
}
198+
aside.plutoui-aside-wrapper > div {
199+
# width: 300px;
200+
}
201+
}
202+
</style>
203+
204+
<aside class="plutoui-aside-wrapper-$(uuid)">
205+
<div>
206+
$(text)
207+
</div>
208+
</aside>
209+
210+
"""
211+
)
212+
end
213+
floataside(stuff; kwargs...) = floataside(md"""$(stuff)"""; kwargs...)
214+
end;
215+
216+
217+
# ╔═╡ b8fd36a7-d8d1-45f7-b66e-df9132168bfc
218+
# https://discourse.julialang.org/t/adding-a-restart-process-button-in-pluto/76812/5
219+
restart_button() = html"""
220+
<script>
221+
const button = document.createElement("button")
222+
223+
button.addEventListener("click", () => {
224+
editor_state_set(old_state => ({
225+
notebook: {
226+
...old_state.notebook,
227+
process_status: "no_process",
228+
},
229+
})).then(() => {
230+
window.requestAnimationFrame(() => {
231+
document.querySelector("#process_status a").click()
232+
})
233+
})
234+
})
235+
button.innerText = "Restart notebook"
236+
237+
return button
238+
</script>
239+
""";
240+
241+
# ╔═╡ Cell order:
242+
# ╟─af6ae00d-f032-4743-878b-e575466b6e84
243+
# ╠═a70cef7d-2a2f-4155-bdf3-fec9df94c63f
244+
# ╠═87d66a6f-b40d-4d76-afc6-4b4f086e80a4
245+
# ╠═087614cc-a4f6-4867-a6bd-201d1f2a7fc2
246+
# ╠═c7a51cb9-790a-4818-95d7-c32f2252e8b3
247+
# ╠═4ef3d13c-2f57-4575-bc88-c8092ae6910f
248+
# ╟─3a99a9bb-7862-41f8-a535-d3c580da6909
249+
# ╠═b24b7e23-61ea-41fc-a345-286e904c042b
250+
# ╠═1bb47749-edde-4bee-be9f-059a7652b354
251+
# ╠═2cf54b71-d99b-40bd-b9a6-0a7cf919614b
252+
# ╠═52d5fb3c-072d-4a6e-a392-7e236b4ec933
253+
# ╠═cc8e8ba6-4cc6-4e8a-bbd6-07b9f61c2ef5
254+
# ╠═48896662-d87f-4606-9118-6471184b4dc7
255+
# ╠═dd3c4807-3972-4e9c-a44a-3347b065d01c
256+
# ╠═935f8897-4d68-447b-8316-1a0fe0285d54
257+
# ╠═d07ac411-7985-4b5f-a88b-8aa4037b7d65
258+
# ╟─8af12f1c-d35b-4cc9-8185-1bb5adbb69e8
259+
# ╟─784b4c3e-bb2a-4940-a83a-ed5e5898dfd4
260+
# ╟─afe4745f-f9f1-4e23-8735-cbec6fb79c41
261+
# ╟─b8fd36a7-d8d1-45f7-b66e-df9132168bfc

0 commit comments

Comments
 (0)