-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsimulation_driver.jl
More file actions
243 lines (219 loc) · 8.58 KB
/
simulation_driver.jl
File metadata and controls
243 lines (219 loc) · 8.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#!/usr/bin/env julia
#=
Quick simulation runner script.
Usage from command line:
julia --project=. simulation_driver.jl [--param=value ...]
Examples:
julia --project=. simulation_driver.jl --mode=dw_growth --Lprl=100
julia --project=. simulation_driver.jl --mode=dw_history --save=true --border=8
julia --project=. simulation_driver.jl --rule=R --p=0.1 --rotate=true
Usage from REPL:
using Pkg
Pkg.activate(".")
using Revise # Automatically reloads changed files
include("simulation_driver.jl")
# To manually reload the module after changes:
# Revise.reload(SqueezingCA)
=#
try
using Revise
catch
@warn "Revise.jl not loaded: you'll need to restart the REPL to see changes to SqueezingCA module."
end
using SqueezingCA
### main parameters ###
mode = "dw_growth" # "dw_growth", "dw_roughness", "dw_history", or "history"
rule = "R" # "R", "F", "M", "Toom" (2D); "soldiers", "collapse" (1D)
p = 0.0 # noise probability parameter (2D)
q = 0.5 # growth/collapse probability parameter (1D collapse rule)
rotate = false # if true, rotate the system by 90 degrees
r = false # if true, reverse the spins in the initial configuration
# domain wall orientation (arrow points from + to - spins)
# (rotate, r)
# (F,F): →
# (F,T): ←
# (T,F): ↑
# (T,T): ↓
### other parameters ###
border = 2 # border thickness for active region padding
use_max_height = false # if true, defines height field in terms of the maximum height of a flipped spin, rather than a sum
final_state = false # if true, just saves the final state of the system to an image
pretty = ~false # if true, makes animations without adding any information other than the spins themselves
out_adj = "" # string to append to the filename before the .jld2 extension
reset_center = true #~(mode == "dw_history") # if true, reset domain wall center when it drifts too far
logtimes = false # if true, use log-spaced measurement times (up to 300 points) instead of linear (up to 500 points)
### parse command-line arguments ##
function parse_arg(key::String, default_value)
for arg in ARGS
if startswith(arg, "--$key=")
value_str = split(arg, "=", limit=2)[2]
# Handle "nothing" string for any type (allows setting to nothing)
if lowercase(value_str) == "nothing" || value_str == ""
return nothing
elseif default_value isa Bool
return lowercase(value_str) in ["true", "1", "yes"]
elseif default_value isa Int || (default_value === nothing && value_str != "")
return parse(Int, value_str)
elseif default_value isa Float64
return parse(Float64, value_str)
elseif default_value isa String
return value_str
else
return value_str
end
end
end
return default_value
end
# Parse mode first, then set mode-dependent defaults
mode = parse_arg("mode", mode)
rule = parse_arg("rule", rule)
p = parse_arg("p", p)
q = parse_arg("q", q)
rotate = parse_arg("rotate", rotate)
r = parse_arg("r", r)
# Set mode-dependent defaults (these are used unless overridden by command-line)
if mode == "dw_growth"
Lprl = 500 # system size parallel to domain wall
Lperp = Lprl # system size perpendicular to domain wall
n_trials = 100 # number of b trials
T_evolve = round(Int,0.4*Lprl^(1.5)) # number of time steps
elseif mode == "dw_roughness"
Lprl = 20 # system size parallel to domain wall
Lperp = 10*Lprl # system size perpendicular to domain wall
n_trials = 10 # number of trials
T_evolve = nothing # number of time steps
elseif mode == "dw_history"
Lprl = 75 # system size parallel to domain wall
Lperp = round(Int, Lprl * 9.0/16.0) # system size perpendicular to domain wall
T_evolve = max(1.5*Lprl, Lperp) # number of time steps to evolve the animation for
n_trials = nothing # number of trials
elseif mode == "history"
Lprl = 100 # system size parallel to domain wall
Lperp = Lprl # system size perpendicular to domain wall
T_evolve = 2*Lprl # number of time steps to evolve the animation for
n_trials = nothing # number of trials
else
error("Invalid mode: $mode")
end
# Parse remaining parameters (command-line arguments override mode-dependent defaults)
Lprl = parse_arg("Lprl", Lprl)
Lperp = parse_arg("Lperp", Lperp)
n_trials = parse_arg("n_trials", n_trials)
T_evolve = parse_arg("T_evolve", T_evolve)
# Parse save argument - supports both --save=value and --save value (without equals)
# For dw_history and history modes, save can be a filename string
# For other modes, save is a boolean
global save = nothing
global save_provided = false
# Check for --save=value format
for (i, arg) in enumerate(ARGS)
if startswith(arg, "--save=")
value_str = split(arg, "=", limit=2)[2]
if lowercase(value_str) == "true" || value_str == "1"
global save = true
elseif lowercase(value_str) == "false" || value_str == "0"
global save = false
else
# Treat as filename (add .gif if not present)
global save = endswith(value_str, ".gif") ? value_str : "$value_str.gif"
end
global save_provided = true
break
elseif arg == "--save"
if i < length(ARGS)
# Handle --save filename (without equals)
next_arg = ARGS[i + 1]
# Only treat as filename if next arg doesn't start with --
if !startswith(next_arg, "--")
# Add .gif extension if not present
global save = endswith(next_arg, ".gif") ? next_arg : "$next_arg.gif"
global save_provided = true
break
else
# If next arg is a flag, treat --save as boolean true
global save = true
global save_provided = true
break
end
else
# --save is the last argument, treat as boolean true
global save = true
global save_provided = true
break
end
end
end
# Set default save behavior if not provided
if !save_provided
if mode ∈ ["dw_roughness", "dw_growth"]
save = true # Boolean for these modes
else
save = nothing # No save by default for dw_history and history
end
end
border = parse_arg("border", border)
use_max_height = parse_arg("use_max_height", use_max_height)
final_state = parse_arg("final_state", final_state)
pretty = parse_arg("pretty", pretty)
out_adj = parse_arg("out_adj", out_adj)
reset_center = parse_arg("reset_center", reset_center)
logtimes = parse_arg("logtimes", logtimes)
# Track which parameters were explicitly provided as command-line arguments
provided_params = Set{Symbol}()
# Check each parameter to see if it was provided
for param in [:Lperp, :n_trials, :T_evolve, :rotate, :r, :p, :q, :border, :use_max_height,
:final_state, :pretty, :out_adj, :reset_center, :save, :logtimes]
if param == :save
# Special handling for --save (with or without equals)
save_found = false
for (i, arg) in enumerate(ARGS)
if startswith(arg, "--save=") || (arg == "--save" && i < length(ARGS))
save_found = true
break
end
end
if save_found
push!(provided_params, param)
end
else
if any(arg -> startswith(arg, "--$(param)="), ARGS)
push!(provided_params, param)
end
end
end
# gather kw
kwargs = Dict{Symbol, Any}()
kwargs[:Lprl] = Lprl
kwargs[:Lperp] = Lperp
kwargs[:n_trials] = n_trials
kwargs[:T_evolve] = T_evolve
kwargs[:rotate] = rotate
kwargs[:r] = r
kwargs[:p] = p
kwargs[:q] = q
kwargs[:border] = border
kwargs[:save] = save
kwargs[:use_max_height] = use_max_height
kwargs[:final_state] = final_state
kwargs[:pretty] = pretty
kwargs[:out_adj] = out_adj
kwargs[:reset_center] = reset_center
kwargs[:logtimes] = logtimes
kwargs[:provided_params] = provided_params # Pass the set of provided parameters
# Check thread count
n_threads = Threads.nthreads()
if n_threads == 1
@warn "Running with only 1 thread. For parallel trials, start Julia with: julia -t auto\n Or set JULIA_NUM_THREADS=auto in your shell profile."
end
# run simulation
println("Running simulation: mode=$mode, rule=$rule, Lprl=$Lprl, Lperp=$Lperp, rotate=$rotate, r=$r, p=$p, q=$q, border=$border, T_evolve=$T_evolve, threads=$n_threads")
orientation = ""
if rotate
orientation = r ? "↓" : "↑"
else
orientation = r ? "←" : "→"
end
println("Domain wall orientation: $orientation")
run_simulation(mode, Lprl, rule; kwargs...)
println("Simulation complete!")