|
| 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