108 lines
2.8 KiB
Python
108 lines
2.8 KiB
Python
import numpy as np, os, math
|
|
import matplotlib.pyplot as plt
|
|
from scipy.optimize import curve_fit
|
|
from multiprocessing import Pool, cpu_count
|
|
|
|
from squish import Simulation, ordered, DomainParams
|
|
from squish.common import OUTPUT_DIR
|
|
from script_tools import RC_SETTINGS, get_args, get_data, format_data
|
|
|
|
NAME = "MinOrderVEE"
|
|
|
|
|
|
def get_min_vee(n):
|
|
domain = DomainParams(n, math.sqrt(n), math.sqrt(n), 4)
|
|
e_hex = ordered.e_hex(domain)
|
|
|
|
configs = ordered.configurations(domain)
|
|
min_vee, min_config = 1e10, None
|
|
|
|
for config in configs:
|
|
try:
|
|
rbar = ordered.avg_radius(domain, config)
|
|
except:
|
|
print(tuple(domain), config)
|
|
|
|
vee = (
|
|
2 * domain.w * domain.h
|
|
+ 2 * math.pi * domain.n * (domain.r ** 2 - 2 * domain.r * rbar)
|
|
) / domain.n - e_hex
|
|
|
|
if vee < min_vee and vee >= 0:
|
|
min_vee = vee
|
|
min_config = config
|
|
|
|
return (domain.n, min_vee, min_config)
|
|
|
|
|
|
def main():
|
|
def f():
|
|
data = {}
|
|
ns = list(range(1000, 5001))
|
|
with Pool(cpu_count()) as pool:
|
|
for i, res in enumerate(pool.imap_unordered(get_min_vee, ns)):
|
|
data[res[0]] = res[1:]
|
|
|
|
hashes = int(21 * i / len(ns))
|
|
print(
|
|
f'Processed N={res[0]} |{"#"*hashes}{" "*(20-hashes)}|'
|
|
+ f" {i+1}/{len(ns)} simulations processed.",
|
|
flush=True,
|
|
end="\r",
|
|
)
|
|
|
|
print(flush=True)
|
|
|
|
return format_data(
|
|
data, key_name="N", col_names=["Minimum Ordered VEE", "Config"]
|
|
)
|
|
|
|
plt.rcParams.update(RC_SETTINGS)
|
|
data = get_data(OUTPUT_DIR / "OrderedCache" / (NAME + ".pkl"), f)
|
|
ns, min_order, min_config = (
|
|
data["N"],
|
|
100 * data["Minimum Ordered VEE"],
|
|
data["Config"],
|
|
)
|
|
|
|
fig = plt.figure(figsize=(20, 15))
|
|
gs = fig.add_gridspec(1, 1)
|
|
ax = fig.add_subplot(gs[0])
|
|
|
|
pad = 5
|
|
mov_avgs = np.array(
|
|
[np.mean(min_order[max(0, i - pad) : i + pad]) for i in range(len(min_order))]
|
|
)
|
|
|
|
ax.scatter(ns, mov_avgs, s=8)
|
|
|
|
log_slope, _ = np.polyfit(np.log10(ns), np.log10(mov_avgs), 1)
|
|
print(log_slope)
|
|
|
|
def g(x, k):
|
|
return k * (x ** log_slope)
|
|
|
|
# return a * np.e ** (-b * (x - c))
|
|
params, covs = curve_fit(g, ns, min_order, p0=[5000])
|
|
ax.plot(np.arange(500, 5500), g(np.arange(500, 5500), *params), color="C1")
|
|
|
|
print(params)
|
|
|
|
ax.grid(zorder=0)
|
|
|
|
ax.set_xlim(800, 5200)
|
|
|
|
ax.set_xlabel("N")
|
|
ax.set_ylabel(r"VEE $\left[\times 10^{2}\right]$")
|
|
|
|
fig.savefig(OUTPUT_DIR / (NAME + ".png"))
|
|
print(f"Wrote to {OUTPUT_DIR / (NAME + '.png')}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
os.environ["QT_log10GING_RULES"] = "*=false"
|
|
try:
|
|
main()
|
|
except KeyboardInterrupt:
|
|
print("Program terminated by user.")
|