Updated scripts to stuse standardized commands and automatic data caching
This commit is contained in:
parent
612e0f0c58
commit
583615ba4b
@ -1,424 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
from typing import List, Tuple, Dict
|
|
||||||
import argparse, math, numpy as np, os
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
import matplotlib.ticker as mtick
|
|
||||||
from multiprocessing import Pool, cpu_count
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import squish.ordered as order
|
|
||||||
from squish import Simulation, DomainParams
|
|
||||||
from squish.common import OUTPUT_DIR
|
|
||||||
|
|
||||||
|
|
||||||
def order_process(domain: DomainParams) -> Tuple[float, float, float]:
|
|
||||||
energies, isoparams = [], []
|
|
||||||
configs = order.configurations(domain)
|
|
||||||
for config in configs:
|
|
||||||
rbar = order.avg_radius(domain, config)
|
|
||||||
area = domain.w * domain.h / domain.n
|
|
||||||
|
|
||||||
energies.append(
|
|
||||||
2 * domain.w * domain.h
|
|
||||||
+ 2 * math.pi * domain.n * (domain.r ** 2 - 2 * domain.r * rbar)
|
|
||||||
)
|
|
||||||
|
|
||||||
isoparams.append(math.pi * rbar ** 2 / area)
|
|
||||||
|
|
||||||
return (domain.w, min(energies), max(energies), min(isoparams), max(isoparams))
|
|
||||||
|
|
||||||
|
|
||||||
def get_ordered_energies(orig_domain: DomainParams, widths: np.ndarray) -> Dict:
|
|
||||||
data = {}
|
|
||||||
domains = []
|
|
||||||
for w in widths:
|
|
||||||
aspect = w
|
|
||||||
domains.append(
|
|
||||||
DomainParams(
|
|
||||||
orig_domain.n,
|
|
||||||
math.sqrt(orig_domain.n * aspect),
|
|
||||||
math.sqrt(orig_domain.n / aspect),
|
|
||||||
orig_domain.r,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# domains = [
|
|
||||||
# DomainParams(orig_domain.n, w, orig_domain.h, orig_domain.r) for w in widths
|
|
||||||
# ]
|
|
||||||
|
|
||||||
with Pool(cpu_count()) as pool:
|
|
||||||
energy_mins, energy_maxes, isoparam_mins, isoparam_maxes = {}, {}, {}, {}
|
|
||||||
for i, res in enumerate(pool.imap_unordered(order_process, domains)):
|
|
||||||
energy_mins[res[0]] = res[1]
|
|
||||||
energy_maxes[res[0]] = res[2]
|
|
||||||
isoparam_mins[res[0]] = res[3]
|
|
||||||
isoparam_maxes[res[0]] = res[4]
|
|
||||||
|
|
||||||
hashes = int(21 * i / len(widths))
|
|
||||||
print(
|
|
||||||
f'Generating at width {res[0]:.02f}... |{"#"*hashes}{" "*(20-hashes)}|'
|
|
||||||
+ f" {i+1}/{len(widths)} completed.",
|
|
||||||
flush=True,
|
|
||||||
end="\r",
|
|
||||||
)
|
|
||||||
|
|
||||||
print(flush=True)
|
|
||||||
|
|
||||||
data["energy_min"] = list([x[1] for x in sorted(energy_mins.items())])
|
|
||||||
data["energy_max"] = list([x[1] for x in sorted(energy_maxes.items())])
|
|
||||||
data["isoparam_min"] = list([x[1] for x in sorted(isoparam_mins.items())])
|
|
||||||
data["isoparam_max"] = list([x[1] for x in sorted(isoparam_maxes.items())])
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
def eq_file_process(file: Path) -> Tuple[float, List[float], List[float]]:
|
|
||||||
sim, frames = Simulation.load(file)
|
|
||||||
|
|
||||||
alls = []
|
|
||||||
for frame_info in frames:
|
|
||||||
alls.append(
|
|
||||||
[
|
|
||||||
frame_info["energy"],
|
|
||||||
np.var(frame_info["stats"]["avg_radius"]) <= 1e-8,
|
|
||||||
np.count_nonzero(frame_info["stats"]["site_edge_count"] != 6),
|
|
||||||
sum(frame_info["stats"]["site_energies"][: sim.domain.n]),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
sim, frames = Simulation.load(file)
|
|
||||||
sim.frames = list(frames)
|
|
||||||
counts = sim.get_distinct()
|
|
||||||
|
|
||||||
distincts = []
|
|
||||||
for j, frame_info in enumerate(sim.frames):
|
|
||||||
distincts.append(
|
|
||||||
[
|
|
||||||
frame_info["energy"],
|
|
||||||
np.var(frame_info["stats"]["avg_radius"]) <= 1e-8,
|
|
||||||
np.count_nonzero(frame_info["stats"]["site_edge_count"] != 6),
|
|
||||||
sum(frame_info["stats"]["site_energies"][: sim.domain.n]),
|
|
||||||
counts[j],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
return sim.domain.w / sim.domain.h, alls, distincts
|
|
||||||
|
|
||||||
|
|
||||||
def get_equilibria_data(filepath: Path) -> Tuple[Dict, numpy.ndarray, DomainParams]:
|
|
||||||
data = {"all": {}, "distinct": {}}
|
|
||||||
files = list(Path(filepath).iterdir())
|
|
||||||
|
|
||||||
with Pool(cpu_count()) as pool:
|
|
||||||
for i, res in enumerate(pool.imap_unordered(eq_file_process, files)):
|
|
||||||
data["all"][res[0]] = res[1]
|
|
||||||
data["distinct"][res[0]] = res[2]
|
|
||||||
|
|
||||||
hashes = int(21 * i / len(files))
|
|
||||||
print(
|
|
||||||
f'Loading simulations... |{"#"*hashes}{" "*(20-hashes)}|'
|
|
||||||
+ f" {i+1}/{len(files)} simulations loaded.",
|
|
||||||
flush=True,
|
|
||||||
end="\r",
|
|
||||||
)
|
|
||||||
print(flush=True)
|
|
||||||
|
|
||||||
sim, frames = Simulation.load(files[0])
|
|
||||||
widths = np.asarray(sorted(data["all"]))
|
|
||||||
domain = DomainParams(sim.domain.n, widths[-1], sim.domain.h, sim.domain.r)
|
|
||||||
return data, widths, domain
|
|
||||||
|
|
||||||
|
|
||||||
def axis_settings(ax, widths):
|
|
||||||
ax.grid(zorder=0)
|
|
||||||
ax.set_xticks([round(w, 2) for w in widths[::2]])
|
|
||||||
ax.set_xticklabels([f"{round(w, 3):.2f}" for w in widths[::2]], rotation=90)
|
|
||||||
plt.subplots_adjust(0.07, 0.12, 0.97, 0.9)
|
|
||||||
|
|
||||||
|
|
||||||
def probability_of_disorder(data, widths, domain):
|
|
||||||
fig, ax = plt.subplots(figsize=(16, 8))
|
|
||||||
all_disorder_count = []
|
|
||||||
for width in widths:
|
|
||||||
equal_shape = list([c[1] for c in data["all"][width]])
|
|
||||||
all_disorder_count.append(
|
|
||||||
100 * equal_shape.count(False) / len(data["all"][width])
|
|
||||||
)
|
|
||||||
|
|
||||||
ax.plot(widths, all_disorder_count)
|
|
||||||
axis_settings(ax, widths)
|
|
||||||
|
|
||||||
ax.yaxis.set_major_formatter(mtick.PercentFormatter())
|
|
||||||
ax.title.set_text(f"Probability of Disorder - N{domain.n}")
|
|
||||||
ax.set_xlabel("Aspect Ratio")
|
|
||||||
ax.set_ylabel("Disordered Equilibria")
|
|
||||||
boa_y_min = round(min(all_disorder_count) / 20) * 20 - 5
|
|
||||||
ax.set_yticks(np.arange(boa_y_min, 100.01, 2.5))
|
|
||||||
|
|
||||||
return fig
|
|
||||||
|
|
||||||
|
|
||||||
def density_of_states(data, widths, domain):
|
|
||||||
fig, ax = plt.subplots(figsize=(16, 8))
|
|
||||||
distinct_ordered, distinct_unordered = [], []
|
|
||||||
for width in widths:
|
|
||||||
equal_shape = list([c[1] for c in data["distinct"][width]])
|
|
||||||
distinct_ordered.append(equal_shape.count(True))
|
|
||||||
distinct_unordered.append(equal_shape.count(False))
|
|
||||||
|
|
||||||
ax2 = ax.twinx()
|
|
||||||
ax.plot(widths, distinct_unordered, label="Unordered Equilibria", color="C0")
|
|
||||||
ax2.plot(widths, distinct_ordered, label="Ordered Equilibria", color="C1")
|
|
||||||
axis_settings(ax, widths)
|
|
||||||
plt.subplots_adjust(0.07, 0.12, 0.92, 0.9)
|
|
||||||
ax.title.set_text(f"Density of States - N{domain.n}")
|
|
||||||
ax.set_xlabel("Aspect Ratio")
|
|
||||||
ax.set_ylabel("Number of States (Disordered)", color="C0")
|
|
||||||
ax2.set_ylabel("Number of States (Ordered)", color="C1")
|
|
||||||
|
|
||||||
dos_y_max_unorder = 1.05 * max(distinct_unordered)
|
|
||||||
dos_y_max_order = 1.05 * max(distinct_ordered)
|
|
||||||
ax.set_yticks(np.linspace(0, dos_y_max_unorder, 20).astype(int))
|
|
||||||
# ax.set_yticks(np.arange(0, dos_y_max_unorder, round(dos_y_max_unorder/200, 1)*10))
|
|
||||||
ax2.set_yticks(np.arange(0, dos_y_max_order))
|
|
||||||
|
|
||||||
return fig
|
|
||||||
|
|
||||||
|
|
||||||
def defect_density(data, widths, domain):
|
|
||||||
fig, ax = plt.subplots(figsize=(16, 8))
|
|
||||||
|
|
||||||
defects = []
|
|
||||||
for width in widths:
|
|
||||||
defects.append(
|
|
||||||
sum([c[2] for c in data["all"][width] if not c[1]])
|
|
||||||
/ len(data["all"][width])
|
|
||||||
)
|
|
||||||
|
|
||||||
ax.plot(widths, defects)
|
|
||||||
axis_settings(ax, widths)
|
|
||||||
ax.title.set_text(f"Average Defects - N{domain.n}")
|
|
||||||
ax.set_xlabel("Aspect Ratio")
|
|
||||||
ax.set_ylabel("Defects")
|
|
||||||
ax.set_yticks(np.arange(0, 1 + max(defects), 0.5))
|
|
||||||
|
|
||||||
return fig
|
|
||||||
|
|
||||||
|
|
||||||
def circle_isoparam(data, widths, order_data, domain):
|
|
||||||
fig, ax = plt.subplots(figsize=(16, 8))
|
|
||||||
|
|
||||||
ax2 = ax.twinx()
|
|
||||||
axis_settings(ax, widths)
|
|
||||||
plt.subplots_adjust(0.07, 0.12, 0.92, 0.9)
|
|
||||||
ax.title.set_text(f"Circular Isoparametric Ratio - N{domain.n}")
|
|
||||||
ax.set_xlabel("Aspect Ratio")
|
|
||||||
ax.set_ylabel("Maximum Ratio", color="C0")
|
|
||||||
ax2.set_ylabel("Minimum Ratio", color="C1")
|
|
||||||
|
|
||||||
ax.plot(widths, order_data["isoparam_max"], label="Maximum", color="C0")
|
|
||||||
ax2.plot(widths, order_data["isoparam_min"], label="Minimum", color="C1")
|
|
||||||
|
|
||||||
return fig
|
|
||||||
|
|
||||||
|
|
||||||
def reduced_energy(data, widths, order_data, domain):
|
|
||||||
fig, ax = plt.subplots(figsize=(16, 8))
|
|
||||||
|
|
||||||
ordered_energies, unordered_energies = [], []
|
|
||||||
for width in widths:
|
|
||||||
ordered_energies.append([c[0] for c in data["distinct"][width] if c[1]])
|
|
||||||
unordered_energies.append([c[0] for c in data["distinct"][width] if not c[1]])
|
|
||||||
|
|
||||||
for i in range(len(order_data["energy_min"])):
|
|
||||||
ordered_energies[i].append(order_data["energy_min"][i])
|
|
||||||
ordered_energies[i].append(order_data["energy_max"][i])
|
|
||||||
|
|
||||||
min_order = np.asarray([min(width) for width in ordered_energies])
|
|
||||||
max_order = np.asarray([max(width) for width in ordered_energies])
|
|
||||||
min_unorder = np.asarray([min(width) for width in unordered_energies])
|
|
||||||
max_unorder = np.asarray([max(width) for width in unordered_energies])
|
|
||||||
|
|
||||||
offset = np.array(min_order)
|
|
||||||
|
|
||||||
min_unorder_off = min_unorder - offset
|
|
||||||
max_unorder_off = max_unorder - offset
|
|
||||||
ax.plot(widths, min_order - offset, color="C1")
|
|
||||||
# ax.plot(widths, max_order - offset, color='C1', linestyle='dotted')
|
|
||||||
ax.plot(widths, min_unorder_off, color="C0")
|
|
||||||
ax.plot(widths, max_unorder_off, color="C0", linestyle="dotted")
|
|
||||||
axis_settings(ax, widths)
|
|
||||||
|
|
||||||
ax.title.set_text(f"Reduced Energy vs. Width - N{domain.n}")
|
|
||||||
ax.set_xlabel("Aspect Ratio")
|
|
||||||
ax.set_ylabel("Reduced Energy")
|
|
||||||
bif_y_max = np.max(np.abs(np.concatenate((min_unorder_off, max_unorder_off))))
|
|
||||||
bif_top = np.arange(
|
|
||||||
0, bif_y_max, round(bif_y_max / 20, -math.floor(math.log10(bif_y_max / 20)))
|
|
||||||
)
|
|
||||||
ax.set_yticks(np.concatenate((-bif_top[1:][::-1], bif_top)))
|
|
||||||
|
|
||||||
return fig
|
|
||||||
|
|
||||||
|
|
||||||
def defect_energy(data, widths, order_data, domain):
|
|
||||||
fig, ax = plt.subplots(figsize=(16, 8))
|
|
||||||
|
|
||||||
ordered_energies, unordered_energies = [], []
|
|
||||||
for width in widths:
|
|
||||||
ordered_energies.append([c[0] for c in data["distinct"][width] if c[1]])
|
|
||||||
unordered_energies.append([c[0] for c in data["distinct"][width] if not c[1]])
|
|
||||||
|
|
||||||
for i in range(len(order_data["energy_min"])):
|
|
||||||
ordered_energies[i].append(order_data["energy_min"][i])
|
|
||||||
ordered_energies[i].append(order_data["energy_max"][i])
|
|
||||||
|
|
||||||
min_order = np.asarray([min(width) for width in ordered_energies])
|
|
||||||
max_order = np.asarray([max(width) for width in ordered_energies])
|
|
||||||
min_unorder = np.asarray([min(width) for width in unordered_energies])
|
|
||||||
max_unorder = np.asarray([max(width) for width in unordered_energies])
|
|
||||||
|
|
||||||
offset = np.array(min_order)
|
|
||||||
|
|
||||||
defect_a, defect_b = [], []
|
|
||||||
for width in widths:
|
|
||||||
num_defects = [c[2] for c in data["all"][width]]
|
|
||||||
defect_energy = [c[3] for c in data["all"][width]]
|
|
||||||
m, b = np.polyfit(num_defects, defect_energy, 1)
|
|
||||||
|
|
||||||
defect_a.append(m)
|
|
||||||
defect_b.append(b)
|
|
||||||
|
|
||||||
ax2 = ax.twinx()
|
|
||||||
ax.plot(widths, defect_a, label="Energy per Defect", color="C0")
|
|
||||||
ax2.plot(widths, defect_b - offset, label="Relative Initial Energy", color="C1")
|
|
||||||
axis_settings(ax, widths)
|
|
||||||
plt.subplots_adjust(0.07, 0.12, 0.92, 0.9)
|
|
||||||
ax.title.set_text(f"Defect Energy - N{domain.n}")
|
|
||||||
ax.set_xlabel("Aspect Ratio")
|
|
||||||
ax.set_ylabel("Energy per Defect", color="C0")
|
|
||||||
ax2.set_ylabel("Relative Initial Energy", color="C1")
|
|
||||||
|
|
||||||
return fig
|
|
||||||
|
|
||||||
|
|
||||||
def excess_energy(data, widths, order_data, domain):
|
|
||||||
fig, ax = plt.subplots(figsize=(16, 8))
|
|
||||||
|
|
||||||
ordered_energies, unordered_energies = [], []
|
|
||||||
for width in widths:
|
|
||||||
ordered_energies.append([c[0] for c in data["distinct"][width] if c[1]])
|
|
||||||
unordered_energies.append([c[0] for c in data["distinct"][width] if not c[1]])
|
|
||||||
|
|
||||||
for i in range(len(order_data["energy_min"])):
|
|
||||||
ordered_energies[i].append(order_data["energy_min"][i])
|
|
||||||
ordered_energies[i].append(order_data["energy_max"][i])
|
|
||||||
|
|
||||||
min_order = np.asarray([min(width) for width in ordered_energies])
|
|
||||||
max_order = np.asarray([max(width) for width in ordered_energies])
|
|
||||||
min_unorder = np.asarray([min(width) for width in unordered_energies])
|
|
||||||
max_unorder = np.asarray([max(width) for width in unordered_energies])
|
|
||||||
|
|
||||||
# Energy of regular hexagon with area 1
|
|
||||||
offset = (
|
|
||||||
2
|
|
||||||
- 2 * domain.r * (6 * 3 ** (-0.25) * math.sqrt(2) * math.atanh(0.5))
|
|
||||||
+ 2 * math.pi * domain.r ** 2
|
|
||||||
)
|
|
||||||
|
|
||||||
min_order_off = min_order / domain.n - offset
|
|
||||||
min_unorder_off = min_unorder / domain.n - offset
|
|
||||||
max_unorder_off = max_unorder / domain.n - offset
|
|
||||||
|
|
||||||
ax.plot(widths, min_order_off, color="C1", label="Minimum Ordered")
|
|
||||||
ax.plot(widths, min_unorder_off, color="C0", label="Minimum Disordered")
|
|
||||||
ax.plot(
|
|
||||||
widths,
|
|
||||||
max_unorder_off,
|
|
||||||
color="C0",
|
|
||||||
linestyle="dotted",
|
|
||||||
label="Maximum Disordered",
|
|
||||||
)
|
|
||||||
# ax.plot(
|
|
||||||
# [min(widths), max(widths)],
|
|
||||||
# [offset, offset],
|
|
||||||
# color="C1",
|
|
||||||
# linestyle="dotted",
|
|
||||||
# label="Regular Energy",
|
|
||||||
# )
|
|
||||||
|
|
||||||
axis_settings(ax, widths)
|
|
||||||
ax.title.set_text(f"Energy at Aspect Ratios - N{domain.n}")
|
|
||||||
ax.set_xlabel("Aspect Ratio")
|
|
||||||
ax.set_ylabel("Excess Energy per Site")
|
|
||||||
ax.legend()
|
|
||||||
|
|
||||||
start, end = ax.get_ylim()
|
|
||||||
ax.set_yticks(np.linspace(0, end, 20))
|
|
||||||
ax.ticklabel_format(axis="y", style="sci")
|
|
||||||
|
|
||||||
return fig
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
# Loading arguments.
|
|
||||||
parser = argparse.ArgumentParser("Outputs width search data into diagrams")
|
|
||||||
parser.add_argument(
|
|
||||||
"sims_path",
|
|
||||||
metavar="path/to/data",
|
|
||||||
help="folder that contains simulation files, or cached data file.",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"-q",
|
|
||||||
"--quiet",
|
|
||||||
dest="quiet",
|
|
||||||
action="store_true",
|
|
||||||
default=False,
|
|
||||||
help="suppress all normal output",
|
|
||||||
)
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
# Obtain data from simulation files and generate single shape data.
|
|
||||||
data, widths, domain = get_equilibria_data(Path(args.sims_path))
|
|
||||||
order_data = get_ordered_energies(domain, widths)
|
|
||||||
|
|
||||||
fig_folder = OUTPUT_DIR / Path(f"AspectDiagrams - N{domain.n}")
|
|
||||||
fig_folder.mkdir(exist_ok=True)
|
|
||||||
|
|
||||||
# Generating diagrams.
|
|
||||||
probability_of_disorder(data, widths, domain).savefig(
|
|
||||||
fig_folder / "Probability of Disorder.png"
|
|
||||||
)
|
|
||||||
|
|
||||||
density_of_states(data, widths, domain).savefig(
|
|
||||||
fig_folder / "Density Of States.png"
|
|
||||||
)
|
|
||||||
|
|
||||||
defect_density(data, widths, domain).savefig(fig_folder / "Defects.png")
|
|
||||||
|
|
||||||
reduced_energy(data, widths, order_data, domain).savefig(
|
|
||||||
fig_folder / "Reduced Energy.png"
|
|
||||||
)
|
|
||||||
|
|
||||||
defect_energy(data, widths, order_data, domain).savefig(
|
|
||||||
fig_folder / "Defect Energy.png"
|
|
||||||
)
|
|
||||||
|
|
||||||
circle_isoparam(data, widths, order_data, domain).savefig(
|
|
||||||
fig_folder / "Circular Isoparametric Ratio.png"
|
|
||||||
)
|
|
||||||
|
|
||||||
excess_energy(data, widths, order_data, domain).savefig(
|
|
||||||
fig_folder / "Excess Energy.png"
|
|
||||||
)
|
|
||||||
|
|
||||||
print(f"Wrote to {fig_folder}.")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
os.environ["QT_LOGGING_RULES"] = "*=false"
|
|
||||||
try:
|
|
||||||
main()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Program terminated by user.")
|
|
||||||
@ -1,113 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
from typing import List, Tuple, Dict
|
|
||||||
import argparse, math, numpy as np, os, pickle
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
import matplotlib.ticker as mtick
|
|
||||||
from multiprocessing import Pool, cpu_count
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import squish.ordered as order
|
|
||||||
from squish import Simulation, DomainParams
|
|
||||||
from squish.common import Energy, OUTPUT_DIR
|
|
||||||
|
|
||||||
|
|
||||||
def axis_settings(ax, widths):
|
|
||||||
ax.invert_xaxis()
|
|
||||||
ax.grid(zorder=0)
|
|
||||||
ax.set_xticks([round(w, 2) for w in widths[::-2]])
|
|
||||||
ax.set_xticklabels(ax.get_xticks(), rotation=90)
|
|
||||||
plt.subplots_adjust(0.07, 0.12, 0.97, 0.9)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
# Loading arguments.
|
|
||||||
parser = argparse.ArgumentParser("Outputs ordered equilibria lowest eigenvalues.")
|
|
||||||
parser.add_argument(
|
|
||||||
"n_objects",
|
|
||||||
metavar="N",
|
|
||||||
type=int,
|
|
||||||
help="folder that contains simulation files, or cached data file.",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"-q",
|
|
||||||
"--quiet",
|
|
||||||
dest="quiet",
|
|
||||||
action="store_true",
|
|
||||||
default=False,
|
|
||||||
help="suppress all normal output",
|
|
||||||
)
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
widths = np.round(np.linspace(3.0, 10.0, 141), 2)
|
|
||||||
|
|
||||||
values = []
|
|
||||||
with open("coercivity_eigs.pkl", "rb") as f:
|
|
||||||
store_data = pickle.load(f)
|
|
||||||
|
|
||||||
for width in widths:
|
|
||||||
eig_vals = []
|
|
||||||
for config, eigs in store_data[width].items():
|
|
||||||
zero_ind = np.where(np.isclose(eigs, 0, atol=1e-4))[0][0]
|
|
||||||
if zero_ind == 0:
|
|
||||||
eig_vals.append(eigs[2])
|
|
||||||
else:
|
|
||||||
eig_vals.append(eigs[0])
|
|
||||||
|
|
||||||
values.append(min(eig_vals))
|
|
||||||
|
|
||||||
# for i, width in enumerate(widths):
|
|
||||||
# domain = DomainParams(args.n_objects, width, 10, 4.0)
|
|
||||||
# eig_vals = []
|
|
||||||
# store_data[width] = {}
|
|
||||||
# configs = order.configurations(domain)
|
|
||||||
# for j, config in enumerate(configs):
|
|
||||||
# if config == (1,0):
|
|
||||||
# continue
|
|
||||||
# points = order.sites(domain, config)
|
|
||||||
|
|
||||||
# hess = Energy("radial-t").mode(*domain, points).hessian(10e-5)
|
|
||||||
# eigs = np.sort(np.linalg.eig(hess)[0])[::-1]
|
|
||||||
# store_data[width][config] = eigs
|
|
||||||
|
|
||||||
# zero_ind = np.where(np.isclose(eigs, 0))[0][0]
|
|
||||||
# if zero_ind == 0:
|
|
||||||
# eig_vals.append(eigs[2])
|
|
||||||
# else:
|
|
||||||
# eig_vals.append(eigs[0])
|
|
||||||
|
|
||||||
# hashes = int(21*j/len(widths))
|
|
||||||
# print(f'Generating at {width}, {i+1}/{len(widths)}... |{"#"*hashes}{" "*(20-hashes)}|' + \
|
|
||||||
# f' {j+1}/{len(configs)} configs done.', flush=True, end='\r')
|
|
||||||
|
|
||||||
# print(flush=True)
|
|
||||||
|
|
||||||
# with open("coercivity_eigs.pkl", "wb") as f:
|
|
||||||
# pickle.dump(store_data, f, pickle.HIGHEST_PROTOCOL)
|
|
||||||
|
|
||||||
# return
|
|
||||||
fig, ax = plt.subplots(figsize=(12, 8))
|
|
||||||
plt.subplots_adjust(0.07, 0.12, 0.97, 0.9)
|
|
||||||
|
|
||||||
ax.plot(widths, values)
|
|
||||||
|
|
||||||
ax.invert_xaxis()
|
|
||||||
ax.grid(zorder=0)
|
|
||||||
ax.set_xticks([round(w, 2) for w in widths[::-2]])
|
|
||||||
ax.set_xticklabels(ax.get_xticks(), rotation=90)
|
|
||||||
|
|
||||||
fig.suptitle("Coercivity")
|
|
||||||
# ax.set_xlim([0, 5])
|
|
||||||
ax.set_xlabel("Width")
|
|
||||||
ax.set_ylabel("Eigenvalue")
|
|
||||||
|
|
||||||
fig.savefig(OUTPUT_DIR / "Coercivity.png")
|
|
||||||
print(f"Wrote to {OUTPUT_DIR / 'Coercivity.png'}")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
os.environ["QT_LOGGING_RULES"] = "*=false"
|
|
||||||
try:
|
|
||||||
main()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Program terminated by user.")
|
|
||||||
97
scripts/cumulative_vee.py
Normal file
97
scripts/cumulative_vee.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
import numpy as np, os
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.ticker as mtick
|
||||||
|
|
||||||
|
from squish import Simulation, DomainParams, ordered
|
||||||
|
from squish.common import OUTPUT_DIR
|
||||||
|
from script_tools import (
|
||||||
|
RC_SETTINGS,
|
||||||
|
get_args,
|
||||||
|
get_data,
|
||||||
|
get_simulation_data,
|
||||||
|
get_ordered_data,
|
||||||
|
)
|
||||||
|
|
||||||
|
NAME = "Cumulative-VEE"
|
||||||
|
ALPHA = 1.0
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
sims_path, regen = get_args(
|
||||||
|
"Anti-cumulative distribution of VEE and percent of equilibria for fixed alpha",
|
||||||
|
"folders that contains various N simulations to plot",
|
||||||
|
)
|
||||||
|
|
||||||
|
packages = []
|
||||||
|
for fol in sims_path.iterdir():
|
||||||
|
if fol.is_file():
|
||||||
|
continue
|
||||||
|
|
||||||
|
data, n, r = get_data(
|
||||||
|
fol / "package.pkl", get_simulation_data, args=(fol,), regen=regen
|
||||||
|
)
|
||||||
|
domain, alphas = DomainParams(n, 1, 1, r), data["all"]["alpha"]
|
||||||
|
ordered_data = get_data(
|
||||||
|
OUTPUT_DIR / "OrderedCache" / f"{n}.pkl",
|
||||||
|
get_ordered_data,
|
||||||
|
args=(domain, alphas),
|
||||||
|
regen=regen,
|
||||||
|
)
|
||||||
|
|
||||||
|
packages.append([data, ordered_data, domain])
|
||||||
|
|
||||||
|
packages.sort(key=lambda x: x[2].n)
|
||||||
|
|
||||||
|
plt.rcParams.update(RC_SETTINGS)
|
||||||
|
|
||||||
|
fig = plt.figure(figsize=(15, 15))
|
||||||
|
gs = fig.add_gridspec(1, 1)
|
||||||
|
ax = fig.add_subplot(gs[0])
|
||||||
|
|
||||||
|
for j, package in enumerate(packages):
|
||||||
|
data, ordered_data, domain = package
|
||||||
|
e_hex = ordered.e_hex(domain)
|
||||||
|
|
||||||
|
alpha_index = np.where(data["all"]["alpha"] == ALPHA)[0][0]
|
||||||
|
|
||||||
|
energies = data["all"]["Energy"][alpha_index] / domain.n - e_hex
|
||||||
|
|
||||||
|
min_order = ordered_data["Energy"][alpha_index][0] / domain.n - e_hex
|
||||||
|
|
||||||
|
vees = np.linspace(0, 0.06, 10000)
|
||||||
|
index = np.argmin(np.abs(vees - min_order))
|
||||||
|
|
||||||
|
counts = np.empty(vees.shape, dtype=float)
|
||||||
|
for i, vee in enumerate(vees):
|
||||||
|
counts[i] = np.count_nonzero(energies >= vee)
|
||||||
|
counts = 100 * counts / len(energies)
|
||||||
|
|
||||||
|
ax.plot(
|
||||||
|
100 * vees[: index + 1],
|
||||||
|
counts[: index + 1],
|
||||||
|
label=f"N={domain.n}",
|
||||||
|
color=f"C{j}",
|
||||||
|
)
|
||||||
|
ax.plot(
|
||||||
|
100 * vees[index:],
|
||||||
|
counts[index:],
|
||||||
|
label=f"_nolegend_",
|
||||||
|
linestyle="dotted",
|
||||||
|
color=f"C{j}",
|
||||||
|
)
|
||||||
|
|
||||||
|
ax.set_xlim(0, 6.3)
|
||||||
|
ax.yaxis.set_major_formatter(mtick.PercentFormatter())
|
||||||
|
|
||||||
|
ax.set_xlabel(r"VEE $\left[\times 10^{2}\right]$")
|
||||||
|
ax.set_ylabel("Percent of Equilibria")
|
||||||
|
|
||||||
|
ax.grid(zorder=0)
|
||||||
|
ax.legend()
|
||||||
|
|
||||||
|
fig.savefig(OUTPUT_DIR / (NAME + ".png"))
|
||||||
|
print(f"Wrote to {OUTPUT_DIR / (NAME + '.png')}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
101
scripts/defect_energy.py
Normal file
101
scripts/defect_energy.py
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import numpy as np, os
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
from squish import Simulation, ordered
|
||||||
|
from squish.common import OUTPUT_DIR
|
||||||
|
from script_tools import RC_SETTINGS, get_args, get_data, format_data
|
||||||
|
|
||||||
|
NAME = "DefectEnergy"
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
sims_path, regen = get_args(
|
||||||
|
"Generates graph for Average Defects and Energy per Defect.",
|
||||||
|
"folder that contains simulations at various N",
|
||||||
|
)
|
||||||
|
|
||||||
|
def f():
|
||||||
|
data = {}
|
||||||
|
|
||||||
|
files = list(sims_path.iterdir())
|
||||||
|
for i, file in enumerate(files):
|
||||||
|
sim, frames = Simulation.load(file)
|
||||||
|
domain = sim.domain
|
||||||
|
e_hex = ordered.e_hex(domain)
|
||||||
|
|
||||||
|
defects, energy = [], []
|
||||||
|
for frame in frames:
|
||||||
|
if np.var(frame["stats"]["avg_radius"]) > 1e-8:
|
||||||
|
defects.append(
|
||||||
|
np.count_nonzero(frame["stats"]["site_edge_count"] != 6)
|
||||||
|
)
|
||||||
|
|
||||||
|
energy.append(100 * frame["energy"] / domain.n)
|
||||||
|
|
||||||
|
avg_defects = sum(defects) / (1 if len(defects) == 0 else len(defects))
|
||||||
|
m, b = np.polyfit(defects, energy, 1)
|
||||||
|
data[sim.domain.n] = [avg_defects, m]
|
||||||
|
|
||||||
|
hashes = int(21 * i / len(files))
|
||||||
|
print(
|
||||||
|
f'Processed N={sim.domain.n:03} |{"#"*hashes}{" "*(20-hashes)}|'
|
||||||
|
+ f" {i+1}/{len(files)} simulations processed.",
|
||||||
|
flush=True,
|
||||||
|
end="\r",
|
||||||
|
)
|
||||||
|
|
||||||
|
print(flush=True)
|
||||||
|
|
||||||
|
return format_data(
|
||||||
|
data, key_name="N", col_names=["Average Defects", "Energy Per Defect"]
|
||||||
|
)
|
||||||
|
|
||||||
|
plt.rcParams.update(RC_SETTINGS)
|
||||||
|
data = get_data(sims_path / (NAME + ".pkl"), f, regen=regen)
|
||||||
|
ns, defects, epds = data["N"], data["Average Defects"], data["Energy Per Defect"]
|
||||||
|
epds *= 100
|
||||||
|
|
||||||
|
fig = plt.figure(figsize=(18, 15))
|
||||||
|
gs = fig.add_gridspec(1, 1)
|
||||||
|
ax = fig.add_subplot(gs[0])
|
||||||
|
ax2 = ax.twinx()
|
||||||
|
ax3 = ax.twinx()
|
||||||
|
|
||||||
|
m0, b0 = np.polyfit(ns, defects, 1)
|
||||||
|
m1, b1 = np.polyfit(ns, defects * epds, 1)
|
||||||
|
|
||||||
|
ax.plot(ns, defects, color="C0", alpha=0.5)
|
||||||
|
ax.plot(ns, m0 * ns + b0, color="C0", linestyle="dashed")
|
||||||
|
|
||||||
|
ax2.plot(ns, epds, color="C1", alpha=0.5)
|
||||||
|
|
||||||
|
ax3.plot(ns, defects * epds / 10, color="C2", alpha=0.5)
|
||||||
|
ax3.plot(ns, (m1 * ns + b1) / 10, color="C2", linestyle="dashed")
|
||||||
|
|
||||||
|
ax.set_ylim(3, 37)
|
||||||
|
ax.set_yticks(np.arange(5, 40, 5))
|
||||||
|
|
||||||
|
ax2.set_ylim(-3 * 0.4, 18 + 3 * 0.4)
|
||||||
|
ax2.set_yticks(np.arange(0, 20, 3))
|
||||||
|
|
||||||
|
ax3.set_ylim(-3 * 0.5, 18 + 3 * 0.4)
|
||||||
|
ax3.set_yticks([])
|
||||||
|
ax3.spines["right"].set_visible(False)
|
||||||
|
ax3.spines.right.set_position(("axes", 1.11))
|
||||||
|
|
||||||
|
ax.grid(zorder=0)
|
||||||
|
ax.set_xlabel("N")
|
||||||
|
ax.set_ylabel("Average Defects", color="C0")
|
||||||
|
ax2.set_ylabel(r"Energy per Defect $\left[\times 10^{4} \right]$", color="C1")
|
||||||
|
ax3.set_ylabel(r"Defect Energy $\left[\times 10^{3} \right]$", color="C2")
|
||||||
|
|
||||||
|
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.")
|
||||||
@ -1,39 +0,0 @@
|
|||||||
from squish import Simulation
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
import os, numpy as np
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
sim, frames = Simulation.load(
|
|
||||||
"squish_output/Radial[T]Search - N11-400 - 10.00x10.00 - 500/Radial[T]Search - N397 - 10.00x10.00"
|
|
||||||
)
|
|
||||||
|
|
||||||
defect, energy = [], []
|
|
||||||
for frame_info in frames:
|
|
||||||
defect.append(np.count_nonzero(frame_info["stats"]["site_edge_count"] != 6))
|
|
||||||
energy.append(sum(frame_info["stats"]["site_energies"][:400]))
|
|
||||||
|
|
||||||
fig, ax = plt.subplots(1, figsize=(8, 8))
|
|
||||||
plt.subplots_adjust(0.1, 0.12, 0.97, 0.9)
|
|
||||||
|
|
||||||
fig.suptitle("Defects vs. Energy")
|
|
||||||
ax.set_xlabel("Defects")
|
|
||||||
ax.set_ylabel("Energy")
|
|
||||||
ax.grid(zorder=0)
|
|
||||||
ax.set_xticks(np.arange(0, 64, 2))
|
|
||||||
ax.scatter(defect, energy, zorder=3, color="C0", marker="*")
|
|
||||||
|
|
||||||
m, b = np.polyfit(defect, energy, 1)
|
|
||||||
ax.plot(
|
|
||||||
defect, np.array(defect) * m + b, zorder=3, color="C1", label=f"Slope: {m:.4f}"
|
|
||||||
)
|
|
||||||
ax.legend()
|
|
||||||
fig.savefig("DefectEnergyN397-10.00.png")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
os.environ["QT_LOGGING_RULES"] = "*=false"
|
|
||||||
try:
|
|
||||||
main()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Program terminated by user.")
|
|
||||||
@ -1,108 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
from typing import List
|
|
||||||
import argparse, pickle, numpy as np, os
|
|
||||||
from pathlib import Path
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
|
|
||||||
from squish import Simulation
|
|
||||||
from squish.common import OUTPUT_DIR
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = argparse.ArgumentParser("Graphs average defects at N.")
|
|
||||||
parser.add_argument(
|
|
||||||
"sims_path",
|
|
||||||
metavar="path/to/data",
|
|
||||||
help="folder that contains simulation files at various Ns.",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"-q",
|
|
||||||
"--quiet",
|
|
||||||
dest="quiet",
|
|
||||||
action="store_true",
|
|
||||||
default=False,
|
|
||||||
help="suppress all normal output",
|
|
||||||
)
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
data = {}
|
|
||||||
|
|
||||||
files = list(Path(args.sims_path).iterdir())
|
|
||||||
for i, file in enumerate(files):
|
|
||||||
sim, frames = Simulation.load(file)
|
|
||||||
avg_defects = 0
|
|
||||||
count = 0
|
|
||||||
|
|
||||||
for frame in frames:
|
|
||||||
if np.var(frame["stats"]["avg_radius"]) > 1e-8:
|
|
||||||
avg_defects += np.count_nonzero(frame["stats"]["site_edge_count"] != 6)
|
|
||||||
|
|
||||||
count += 1
|
|
||||||
|
|
||||||
avg_defects /= 1 if count == 0 else count
|
|
||||||
data[sim.domain.n] = avg_defects
|
|
||||||
|
|
||||||
hashes = int(21 * i / len(files))
|
|
||||||
print(
|
|
||||||
f'Processed N={sim.domain.n:03} |{"#"*hashes}{" "*(20-hashes)}|'
|
|
||||||
+ f" {i+1}/{len(files)} simulations processed.",
|
|
||||||
flush=True,
|
|
||||||
end="\r",
|
|
||||||
)
|
|
||||||
|
|
||||||
print(flush=True)
|
|
||||||
|
|
||||||
data = sorted(data.items())
|
|
||||||
ns, defects = np.array([x[0] for x in data]), np.array([x[1] for x in data])
|
|
||||||
|
|
||||||
corrected = []
|
|
||||||
for i, x in enumerate(defects):
|
|
||||||
if x == 0:
|
|
||||||
corrected.append(defects[i + 1])
|
|
||||||
else:
|
|
||||||
corrected.append(x)
|
|
||||||
|
|
||||||
fig, ax = plt.subplots(1, 2, figsize=(16, 8))
|
|
||||||
plt.subplots_adjust(0.07, 0.12, 0.97, 0.9)
|
|
||||||
|
|
||||||
fig.suptitle("Defects vs. Number of Sites (N)")
|
|
||||||
|
|
||||||
m0, b0 = np.polyfit(ns, defects, 1)
|
|
||||||
|
|
||||||
ax[0].plot(ns, defects)
|
|
||||||
ax[0].plot(ns, m0 * ns + b0, label=f"Slope: {m0:.5f}")
|
|
||||||
ax[0].grid(zorder=0)
|
|
||||||
ax[0].legend()
|
|
||||||
ax[0].set_xlabel("N")
|
|
||||||
ax[0].set_ylabel("Average Defects")
|
|
||||||
|
|
||||||
x, y = np.log(ns), np.log(corrected)
|
|
||||||
m, b = np.polyfit(x, y, 1)
|
|
||||||
|
|
||||||
x2, y2 = x[40:], np.log(defects[40:])
|
|
||||||
m2, b2 = np.polyfit(x2, y2, 1)
|
|
||||||
|
|
||||||
ax[1].plot(x, y, linestyle="dotted", color="C0")
|
|
||||||
ax[1].plot(x, np.log(defects))
|
|
||||||
|
|
||||||
# ax[1].plot(x, m*x+b, label=f"All N: {m:.5f}")
|
|
||||||
ax[1].plot(x2, m2 * x2 + b2, label=f"N $\\geq$ 40: {m2:.5f}")
|
|
||||||
ax[1].grid(zorder=0)
|
|
||||||
ax[1].legend()
|
|
||||||
ax[1].set_xticks(np.arange(3.75, 6.25, 0.25))
|
|
||||||
ax[1].set_yticks(np.arange(0, 4.5, 0.5))
|
|
||||||
ax[1].set_xlim(3.75, 6)
|
|
||||||
ax[1].set_ylim(0, 4)
|
|
||||||
ax[1].set_xlabel("$\\ln$ N")
|
|
||||||
ax[1].set_ylabel("$\\ln$ Average Defects")
|
|
||||||
|
|
||||||
fig.savefig(OUTPUT_DIR / "DefectsN.png")
|
|
||||||
print(f"Wrote to {OUTPUT_DIR / 'DefectsN.png'}")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
os.environ["QT_log10GING_RULES"] = "*=false"
|
|
||||||
try:
|
|
||||||
main()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Program terminated by user.")
|
|
||||||
96
scripts/density_of_states.py
Normal file
96
scripts/density_of_states.py
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
from typing import List, Tuple, Dict
|
||||||
|
import argparse, math, numpy as np, os, pickle, itertools
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.ticker as mtick
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from squish import Simulation, DomainParams
|
||||||
|
from squish.common import OUTPUT_DIR
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Loading arguments.
|
||||||
|
parser = argparse.ArgumentParser("Outputs width search data into diagrams")
|
||||||
|
parser.add_argument(
|
||||||
|
"sims_path",
|
||||||
|
metavar="path/to/data",
|
||||||
|
help="Path to simulation folders with generated data.pkl from aspect_diagrams.py",
|
||||||
|
)
|
||||||
|
|
||||||
|
packages = []
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
for fol in Path(args.sims_path).iterdir():
|
||||||
|
if fol.is_file():
|
||||||
|
continue
|
||||||
|
|
||||||
|
store = fol / "data.pkl"
|
||||||
|
if store.is_file():
|
||||||
|
with open(store, "rb") as f:
|
||||||
|
packages.append(pickle.load(f))
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
f"{store} not found! Use aspect_diagrams.py to generate this file first."
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(packages) == []:
|
||||||
|
print("No data.pkl files found, terminating")
|
||||||
|
return
|
||||||
|
|
||||||
|
plt.rcParams.update(
|
||||||
|
{
|
||||||
|
"axes.titlesize": 45,
|
||||||
|
"axes.labelsize": 45,
|
||||||
|
"xtick.labelsize": 40,
|
||||||
|
"ytick.labelsize": 40,
|
||||||
|
"xtick.major.width": 2,
|
||||||
|
"ytick.major.width": 2,
|
||||||
|
"xtick.major.size": 5,
|
||||||
|
"ytick.major.size": 5,
|
||||||
|
"xtick.minor.width": 1,
|
||||||
|
"ytick.minor.width": 1,
|
||||||
|
"xtick.minor.size": 3,
|
||||||
|
"ytick.minor.size": 3,
|
||||||
|
"legend.fontsize": 40,
|
||||||
|
"lines.linewidth": 3.5,
|
||||||
|
"font.family": "cm",
|
||||||
|
"font.size": 40,
|
||||||
|
"text.usetex": True,
|
||||||
|
"text.latex.preamble": r"\usepackage{amsmath}",
|
||||||
|
"figure.constrained_layout.use": True,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
fig = plt.figure(figsize=(18, 15))
|
||||||
|
gs = fig.add_gridspec(1, 1)
|
||||||
|
ax = fig.add_subplot(gs[0])
|
||||||
|
|
||||||
|
packages.sort(key=lambda x: x[0].n)
|
||||||
|
|
||||||
|
for j, package in enumerate(packages):
|
||||||
|
domain, data, order_data, widths = package
|
||||||
|
|
||||||
|
distinct_unordered = []
|
||||||
|
for width in widths:
|
||||||
|
equal_shape = list([c[1] for c in data["distinct"][width]])
|
||||||
|
distinct_unordered.append(equal_shape.count(False))
|
||||||
|
|
||||||
|
ax.plot(widths, distinct_unordered, label=f"N={domain.n}")
|
||||||
|
|
||||||
|
widths = packages[0][3]
|
||||||
|
ax.set_xticks([round(w, 2) for w in widths[::10]])
|
||||||
|
ax.set_xticklabels([f"{round(w, 3):.2f}" for w in widths[::10]], rotation=90)
|
||||||
|
ax.set_xlim(0.3, 1.0)
|
||||||
|
ax.set_xlabel("Aspect Ratio")
|
||||||
|
ax.set_ylabel("Number of Distinct Equilibria")
|
||||||
|
|
||||||
|
ax.grid(zorder=0)
|
||||||
|
ax.legend(loc="center right", fancybox=True, bbox_to_anchor=(1.34, 0.5))
|
||||||
|
fig.savefig(OUTPUT_DIR / "DoS.png")
|
||||||
|
|
||||||
|
print(f"Wrote to {OUTPUT_DIR / 'DoS.png'}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@ -1,302 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
from typing import List, Tuple, Dict
|
|
||||||
import argparse, math, numpy as np, os, pickle
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
import matplotlib.ticker as mtick
|
|
||||||
from scipy.optimize import curve_fit
|
|
||||||
from multiprocessing import Pool, cpu_count
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import squish.ordered as order
|
|
||||||
from squish import Simulation, DomainParams
|
|
||||||
from squish.common import OUTPUT_DIR
|
|
||||||
|
|
||||||
|
|
||||||
def order_process(domain: DomainParams) -> Tuple[float, float, float]:
|
|
||||||
energies, isoparams = [], []
|
|
||||||
configs = order.configurations(domain)
|
|
||||||
for config in configs:
|
|
||||||
rbar = order.avg_radius(domain, config)
|
|
||||||
area = domain.w * domain.h / domain.n
|
|
||||||
|
|
||||||
energies.append(
|
|
||||||
2 * domain.w * domain.h
|
|
||||||
+ 2 * math.pi * domain.n * (domain.r ** 2 - 2 * domain.r * rbar)
|
|
||||||
)
|
|
||||||
|
|
||||||
isoparams.append(math.pi * rbar ** 2 / area)
|
|
||||||
|
|
||||||
return domain.w, min(energies), max(energies), min(isoparams), max(isoparams)
|
|
||||||
|
|
||||||
|
|
||||||
def get_ordered_energies(orig_domain: DomainParams, widths: np.ndarray) -> Dict:
|
|
||||||
data = {}
|
|
||||||
domains = []
|
|
||||||
for w in widths:
|
|
||||||
aspect = w
|
|
||||||
domains.append(
|
|
||||||
DomainParams(
|
|
||||||
orig_domain.n,
|
|
||||||
math.sqrt(orig_domain.n * aspect),
|
|
||||||
math.sqrt(orig_domain.n / aspect),
|
|
||||||
orig_domain.r,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# domains = [
|
|
||||||
# DomainParams(orig_domain.n, w, orig_domain.h, orig_domain.r) for w in widths
|
|
||||||
# ]
|
|
||||||
|
|
||||||
with Pool(cpu_count()) as pool:
|
|
||||||
energy_mins, energy_maxes, isoparam_mins, isoparam_maxes = {}, {}, {}, {}
|
|
||||||
for i, res in enumerate(pool.imap_unordered(order_process, domains)):
|
|
||||||
energy_mins[res[0]] = res[1]
|
|
||||||
energy_maxes[res[0]] = res[2]
|
|
||||||
isoparam_mins[res[0]] = res[3]
|
|
||||||
isoparam_maxes[res[0]] = res[4]
|
|
||||||
|
|
||||||
hashes = int(21 * i / len(widths))
|
|
||||||
print(
|
|
||||||
f'Generating at width {res[0]:.02f}... |{"#"*hashes}{" "*(20-hashes)}|'
|
|
||||||
+ f" {i+1}/{len(widths)} completed.",
|
|
||||||
flush=True,
|
|
||||||
end="\r",
|
|
||||||
)
|
|
||||||
|
|
||||||
print(flush=True)
|
|
||||||
|
|
||||||
data["energy_min"] = list([x[1] for x in sorted(energy_mins.items())])
|
|
||||||
data["energy_max"] = list([x[1] for x in sorted(energy_maxes.items())])
|
|
||||||
data["isoparam_min"] = list([x[1] for x in sorted(isoparam_mins.items())])
|
|
||||||
data["isoparam_max"] = list([x[1] for x in sorted(isoparam_maxes.items())])
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
def eq_file_process(file: Path) -> Tuple[float, List[float], List[float]]:
|
|
||||||
sim, frames = Simulation.load(file)
|
|
||||||
|
|
||||||
alls = []
|
|
||||||
for frame_info in frames:
|
|
||||||
alls.append(
|
|
||||||
[
|
|
||||||
frame_info["energy"],
|
|
||||||
np.var(frame_info["stats"]["avg_radius"]) <= 1e-8,
|
|
||||||
np.count_nonzero(frame_info["stats"]["site_edge_count"] != 6),
|
|
||||||
sum(frame_info["stats"]["site_energies"][: sim.domain.n]),
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
sim, frames = Simulation.load(file)
|
|
||||||
sim.frames = list(frames)
|
|
||||||
counts = sim.get_distinct()
|
|
||||||
|
|
||||||
distincts = []
|
|
||||||
for j, frame_info in enumerate(sim.frames):
|
|
||||||
distincts.append(
|
|
||||||
[
|
|
||||||
frame_info["energy"],
|
|
||||||
np.var(frame_info["stats"]["avg_radius"]) <= 1e-8,
|
|
||||||
np.count_nonzero(frame_info["stats"]["site_edge_count"] != 6),
|
|
||||||
sum(frame_info["stats"]["site_energies"][: sim.domain.n]),
|
|
||||||
counts[j],
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
return sim.domain.w / sim.domain.h, alls, distincts
|
|
||||||
|
|
||||||
|
|
||||||
def get_equilibria_data(filepath: Path) -> Tuple[Dict, numpy.ndarray, DomainParams]:
|
|
||||||
data = {"all": {}, "distinct": {}}
|
|
||||||
files = list(Path(filepath).iterdir())
|
|
||||||
|
|
||||||
with Pool(cpu_count()) as pool:
|
|
||||||
for i, res in enumerate(pool.imap_unordered(eq_file_process, files)):
|
|
||||||
data["all"][res[0]] = res[1]
|
|
||||||
data["distinct"][res[0]] = res[2]
|
|
||||||
|
|
||||||
hashes = int(21 * i / len(files))
|
|
||||||
print(
|
|
||||||
f'Loading simulations... |{"#"*hashes}{" "*(20-hashes)}|'
|
|
||||||
+ f" {i+1}/{len(files)} simulations loaded.",
|
|
||||||
flush=True,
|
|
||||||
end="\r",
|
|
||||||
)
|
|
||||||
print(flush=True)
|
|
||||||
|
|
||||||
sim, frames = Simulation.load(files[0])
|
|
||||||
widths = np.asarray(sorted(data["all"]))
|
|
||||||
domain = DomainParams(sim.domain.n, widths[-1], sim.domain.h, sim.domain.r)
|
|
||||||
return data, widths, domain
|
|
||||||
|
|
||||||
|
|
||||||
def probability_of_disorder(data, widths, domain):
|
|
||||||
fig, ax = plt.subplots(figsize=(16, 8))
|
|
||||||
all_disorder_count = []
|
|
||||||
for width in widths:
|
|
||||||
equal_shape = list([c[1] for c in data["all"][width]])
|
|
||||||
all_disorder_count.append(
|
|
||||||
100 * equal_shape.count(False) / len(data["all"][width])
|
|
||||||
)
|
|
||||||
|
|
||||||
return all_disorder_count
|
|
||||||
|
|
||||||
|
|
||||||
def excess_energy(data, widths, order_data, domain):
|
|
||||||
fig, ax = plt.subplots(figsize=(16, 8))
|
|
||||||
|
|
||||||
ordered_energies, unordered_energies = [], []
|
|
||||||
for width in widths:
|
|
||||||
ordered_energies.append([c[0] for c in data["distinct"][width] if c[1]])
|
|
||||||
unordered_energies.append([c[0] for c in data["distinct"][width] if not c[1]])
|
|
||||||
|
|
||||||
for i in range(len(order_data["energy_min"])):
|
|
||||||
ordered_energies[i].append(order_data["energy_min"][i])
|
|
||||||
ordered_energies[i].append(order_data["energy_max"][i])
|
|
||||||
|
|
||||||
min_order = np.asarray([min(width) for width in ordered_energies])
|
|
||||||
max_order = np.asarray([max(width) for width in ordered_energies])
|
|
||||||
min_unorder = np.asarray([min(width) for width in unordered_energies])
|
|
||||||
max_unorder = np.asarray([max(width) for width in unordered_energies])
|
|
||||||
|
|
||||||
return min_order - min_unorder
|
|
||||||
|
|
||||||
|
|
||||||
def sigmoid(x, x0, k):
|
|
||||||
return 100 / (1 + np.exp(-k * (x - x0)))
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
# Loading arguments.
|
|
||||||
parser = argparse.ArgumentParser("Outputs width search data into diagrams")
|
|
||||||
parser.add_argument(
|
|
||||||
"sims_path",
|
|
||||||
metavar="path/to/data",
|
|
||||||
help="folder that contains simulation files of all searches for all N.",
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"-q",
|
|
||||||
"--quiet",
|
|
||||||
dest="quiet",
|
|
||||||
action="store_true",
|
|
||||||
default=False,
|
|
||||||
help="suppress all normal output",
|
|
||||||
)
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
fig_folder = OUTPUT_DIR
|
|
||||||
fig_folder.mkdir(exist_ok=True)
|
|
||||||
|
|
||||||
store = Path(args.sims_path) / "EEvsPoD.pkl"
|
|
||||||
|
|
||||||
if store.is_file():
|
|
||||||
with open(store, "rb") as f:
|
|
||||||
horiz, vert = pickle.load(f)
|
|
||||||
else:
|
|
||||||
horiz = []
|
|
||||||
vert = []
|
|
||||||
|
|
||||||
for file in Path(args.sims_path).iterdir():
|
|
||||||
# Obtain data from simulation files and generate single shape data.
|
|
||||||
data, widths, domain = get_equilibria_data(file)
|
|
||||||
order_data = get_ordered_energies(domain, widths)
|
|
||||||
|
|
||||||
vert.append(probability_of_disorder(data, widths, domain))
|
|
||||||
horiz.append(excess_energy(data, widths, order_data, domain))
|
|
||||||
|
|
||||||
horiz, vert = np.concatenate(horiz), np.concatenate(vert)
|
|
||||||
with open(store, "wb") as f:
|
|
||||||
pickle.dump((horiz, vert), f, pickle.HIGHEST_PROTOCOL)
|
|
||||||
|
|
||||||
fig, ax = plt.subplots(figsize=(10, 10))
|
|
||||||
|
|
||||||
for i in range(2):
|
|
||||||
ax.scatter(
|
|
||||||
horiz[i * 141 : (i + 1) * 141],
|
|
||||||
vert[i * 141 : (i + 1) * 141],
|
|
||||||
alpha=0.5,
|
|
||||||
color=f"C{i}",
|
|
||||||
s=5,
|
|
||||||
)
|
|
||||||
|
|
||||||
start, end = ax.get_xlim()
|
|
||||||
|
|
||||||
# popt, pcov = curve_fit(sigmoid, horiz, vert)
|
|
||||||
# x = np.linspace(start, end, 100)
|
|
||||||
# y = sigmoid(x, *popt)
|
|
||||||
# y = sigmoid(x, -1.35, 3)
|
|
||||||
# ax.plot(x, y, color="C1")
|
|
||||||
|
|
||||||
plt.subplots_adjust(0.1, 0.1, 0.97, 0.93)
|
|
||||||
|
|
||||||
ax.set_xticks(np.linspace(start, end, 10))
|
|
||||||
ax.set_yticks(np.arange(0, 105, 5))
|
|
||||||
ax.grid()
|
|
||||||
|
|
||||||
ax.yaxis.set_major_formatter(mtick.PercentFormatter())
|
|
||||||
ax.title.set_text("Excess Energy Difference vs. PoD")
|
|
||||||
ax.set_xlabel("Excess Energy Difference")
|
|
||||||
ax.set_ylabel("Probability of Disorder")
|
|
||||||
fig.savefig(OUTPUT_DIR / "Energy Diff and Probability")
|
|
||||||
return
|
|
||||||
|
|
||||||
# with open("testing.pkl", "rb") as f:
|
|
||||||
# disorder_dict = pickle.load(f)
|
|
||||||
# widths = np.linspace(3.0, 10.0, 141)
|
|
||||||
# min_n, max_n = 60, 80
|
|
||||||
|
|
||||||
disorder_dict = {}
|
|
||||||
for file in Path(args.sims_path).iterdir():
|
|
||||||
sim_data, widths, domain = get_equilibria_data(file)
|
|
||||||
|
|
||||||
disorder_count = []
|
|
||||||
for width in widths:
|
|
||||||
equal_shape = list([c[1] for c in sim_data["all"][width]])
|
|
||||||
disorder_count.append(
|
|
||||||
100 * equal_shape.count(False) / len(sim_data["all"][width])
|
|
||||||
)
|
|
||||||
|
|
||||||
disorder_dict[domain.n] = disorder_count
|
|
||||||
|
|
||||||
min_n, max_n = min(disorder_dict), max(disorder_dict)
|
|
||||||
filepath = f"Disorder Heatmap N{min_n}-{max_n}"
|
|
||||||
|
|
||||||
# with open("testing.pkl", "wb") as f:
|
|
||||||
# pickle.dump(disorder_dict, f, pickle.HIGHEST_PROTOCOL)
|
|
||||||
|
|
||||||
disorder_arr = np.zeros((max_n - min_n + 1, len(widths)))
|
|
||||||
for key, value in disorder_dict.items():
|
|
||||||
disorder_arr[key - min_n] = np.asarray(value)
|
|
||||||
|
|
||||||
fig, ax = plt.subplots(figsize=(12, 8))
|
|
||||||
|
|
||||||
extent = [min(widths), max(widths), min_n, max_n + 1]
|
|
||||||
ax.imshow(
|
|
||||||
disorder_arr,
|
|
||||||
cmap="plasma",
|
|
||||||
interpolation="nearest",
|
|
||||||
aspect="auto",
|
|
||||||
extent=extent,
|
|
||||||
)
|
|
||||||
|
|
||||||
ax.invert_xaxis()
|
|
||||||
ax.set_xticks([round(w, 2) for w in widths[::-2]])
|
|
||||||
ax.set_xticklabels(ax.get_xticks(), rotation=90)
|
|
||||||
ax.set_yticks(list(range(min_n, max_n + 1)))
|
|
||||||
plt.subplots_adjust(0.07, 0.12, 0.97, 0.9)
|
|
||||||
|
|
||||||
ax.title.set_text(filepath)
|
|
||||||
ax.set_xlabel("Width")
|
|
||||||
ax.set_ylabel("Number of Sites")
|
|
||||||
fig.savefig(OUTPUT_DIR / filepath)
|
|
||||||
|
|
||||||
print(f"Wrote to {OUTPUT_DIR / filepath}.")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
os.environ["QT_LOGGING_RULES"] = "*=false"
|
|
||||||
try:
|
|
||||||
main()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Program terminated by user.")
|
|
||||||
89
scripts/hexagon_alpha.py
Normal file
89
scripts/hexagon_alpha.py
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import argparse, numpy as np, os
|
||||||
|
from multiprocessing import Pool, cpu_count
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
from squish import ordered
|
||||||
|
from squish.common import OUTPUT_DIR
|
||||||
|
from script_tools import RC_SETTINGS, get_data, format_data
|
||||||
|
|
||||||
|
NAME = "RegHexTessRatios"
|
||||||
|
|
||||||
|
|
||||||
|
def get_ratios(n: int):
|
||||||
|
return (n, ordered.hexagon_alpha(n))
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Generates graph for regular hexagonal tessellation ratios"
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"max_n", metavar="N", type=int, help="maximum N of which to calculate"
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--regenerate",
|
||||||
|
dest="regen",
|
||||||
|
action="store_true",
|
||||||
|
help="regenerates the cache file for processed data",
|
||||||
|
)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
def f():
|
||||||
|
data = {"alpha": [], "N": []}
|
||||||
|
|
||||||
|
with Pool(cpu_count()) as pool:
|
||||||
|
for i, res in enumerate(
|
||||||
|
pool.imap_unordered(get_ratios, range(2, args.max_n + 1))
|
||||||
|
):
|
||||||
|
for ratio in res[1]:
|
||||||
|
data["N"].append(res[0])
|
||||||
|
data["alpha"].append(ratio)
|
||||||
|
|
||||||
|
hashes = int(21 * i / (args.max_n - 1))
|
||||||
|
print(
|
||||||
|
f'Processed N={res[0]} |{"#"*hashes}{" "*(20-hashes)}|'
|
||||||
|
+ f" {i+1}/{args.max_n-1}",
|
||||||
|
flush=True,
|
||||||
|
end="\r",
|
||||||
|
)
|
||||||
|
|
||||||
|
print(flush=True)
|
||||||
|
return data
|
||||||
|
|
||||||
|
data = get_data(OUTPUT_DIR / "OrderedCache" / (NAME + ".pkl"), f, regen=args.regen)
|
||||||
|
|
||||||
|
plt.rcParams.update(RC_SETTINGS)
|
||||||
|
|
||||||
|
fig = plt.figure(figsize=(15, 15))
|
||||||
|
gs = fig.add_gridspec(1, 1)
|
||||||
|
ax = fig.add_subplot(gs[0])
|
||||||
|
|
||||||
|
alphas, ns = [], []
|
||||||
|
for alpha, n in zip(data["alpha"], data["N"]):
|
||||||
|
if n <= args.max_n:
|
||||||
|
alphas.append(alpha)
|
||||||
|
ns.append(n)
|
||||||
|
|
||||||
|
ax.scatter(alphas, ns, s=5)
|
||||||
|
|
||||||
|
ax.set_xlim(-0.01, 1.1)
|
||||||
|
ax.set_xticks(np.arange(0, 1.01, 0.1))
|
||||||
|
ax.set_ylim(0, args.max_n)
|
||||||
|
|
||||||
|
ax.set_ylabel(r"$N$")
|
||||||
|
ax.set_xlabel("Aspect Ratio")
|
||||||
|
ax.grid(zorder=0)
|
||||||
|
|
||||||
|
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.")
|
||||||
@ -1,73 +1,102 @@
|
|||||||
from __future__ import annotations
|
import argparse, numpy as np, os
|
||||||
from typing import List
|
|
||||||
import argparse, pickle, numpy as np, os
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
from squish import Simulation
|
from squish import DomainParams, Simulation
|
||||||
from squish.common import OUTPUT_DIR
|
from squish.common import OUTPUT_DIR
|
||||||
|
from script_tools import RC_SETTINGS, get_data, format_data
|
||||||
|
|
||||||
|
NAME = "Perturbations"
|
||||||
|
|
||||||
|
|
||||||
|
def toroidal_distance(domain: DomainParams, x: np.ndarray, y: np.ndarray) -> float:
|
||||||
|
dim = np.array([domain.w, domain.h])
|
||||||
|
absdist = np.abs(y - x)
|
||||||
|
wrap = dim * (absdist >= np.array([domain.w, domain.h]) / 2)
|
||||||
|
return np.linalg.norm(wrap - absdist)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
"Graphs perturbation graphs for a collection of simulations."
|
description="Graphs perturbation graphs for a collection of simulations."
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"sims_path",
|
"sims_path",
|
||||||
metavar="path/to/data",
|
metavar="sim_dir",
|
||||||
help="folder that contains simulations of perturbations from an equilibrium.",
|
help="folder that contains of perturbations from an equilibrium",
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"end_path",
|
"end_path",
|
||||||
metavar="path/to/equilbrium",
|
metavar="eq_path",
|
||||||
help="NumPy binary (.npy) file that contains the equilibrium to compare to.",
|
help="simulation that contains the equilibrium to compare to.",
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-q",
|
"--regenerate",
|
||||||
"--quiet",
|
dest="regen",
|
||||||
dest="quiet",
|
|
||||||
action="store_true",
|
action="store_true",
|
||||||
default=False,
|
help="regenerates the cache file for processed data",
|
||||||
help="suppress all normal output",
|
|
||||||
)
|
)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
sims_path = Path(args.sims_path)
|
||||||
|
|
||||||
end = np.load(args.end_path)
|
end_sim = Simulation.from_file(args.end_path)
|
||||||
|
|
||||||
data = {}
|
def f():
|
||||||
for file in Path(args.sims_path).iterdir():
|
data = {}
|
||||||
k = float(file.name.split("k")[-1])
|
for file in sims_path.iterdir():
|
||||||
delta = 10 ** k
|
if "k" not in file.name or file.is_file():
|
||||||
|
continue
|
||||||
|
k = float(file.name.split("k")[-1])
|
||||||
|
delta = 10 ** k
|
||||||
|
|
||||||
sim, frames = Simulation.load(file)
|
sim, frames = Simulation.load(file)
|
||||||
data[delta] = {"norm": [], "time": [], "k": k}
|
data[delta] = {"norm": [], "time": [], "k": k}
|
||||||
|
|
||||||
for i, frame in enumerate(frames):
|
for i, frame in enumerate(frames):
|
||||||
adjusted = frame["arr"] + (end[0] - frame["arr"][0])
|
adjusted = frame["arr"] + (
|
||||||
|
end_sim.frames[0].site_arr[0] - frame["arr"][0]
|
||||||
|
)
|
||||||
|
|
||||||
data[delta]["norm"].append(np.linalg.norm(adjusted - end))
|
data[delta]["norm"].append(
|
||||||
data[delta]["time"].append(sim.step_size * i)
|
toroidal_distance(
|
||||||
|
end_sim.domain, adjusted, end_sim.frames[0].site_arr
|
||||||
|
)
|
||||||
|
)
|
||||||
|
data[delta]["time"].append(sim.step_size * i)
|
||||||
|
|
||||||
fig, ax = plt.subplots(figsize=(12, 8))
|
return data
|
||||||
plt.subplots_adjust(0.07, 0.12, 0.97, 0.9)
|
|
||||||
|
data = get_data(sims_path / "PerturbData.pkl", f, regen=args.regen)
|
||||||
|
|
||||||
|
plt.rcParams.update(RC_SETTINGS)
|
||||||
|
|
||||||
|
fig = plt.figure(figsize=(30, 8))
|
||||||
|
gs = fig.add_gridspec(1, 1)
|
||||||
|
ax = fig.add_subplot(gs[0])
|
||||||
|
|
||||||
for delta in sorted(data):
|
for delta in sorted(data):
|
||||||
ax.plot(
|
ax.plot(
|
||||||
np.log10(np.array(data[delta]["time"]) + 1),
|
np.array(data[delta]["time"]),
|
||||||
np.log10(data[delta]["norm"]),
|
np.array(data[delta]["norm"]),
|
||||||
label=f"k = {data[delta]['k']}",
|
label=f"k = {data[delta]['k']}",
|
||||||
)
|
)
|
||||||
|
|
||||||
fig.suptitle("Equilibrium Perturbations")
|
ax.set_title(r"Relaxation of Perturbations")
|
||||||
ax.grid(zorder=0)
|
|
||||||
# ax.set_xlim([0, 5])
|
|
||||||
ax.legend()
|
|
||||||
ax.set_xlabel("$\\log_{10}$ Time")
|
|
||||||
ax.set_ylabel("$\\log_{10}$ L2 Norm of Difference")
|
|
||||||
|
|
||||||
fig.savefig(OUTPUT_DIR / "Equilibrium Perturbations.png")
|
ax.set_xlim([0, 60])
|
||||||
print(f"Wrote to {OUTPUT_DIR / 'Equilibrium Perturbations.png'}")
|
ax.set_yscale("log")
|
||||||
|
|
||||||
|
ax.set_xlabel(r"Time")
|
||||||
|
ax.set_ylabel(r"$\|\mathbf{x}-\mathbf{x_e}\|_2$")
|
||||||
|
|
||||||
|
h, l = ax.get_legend_handles_labels()
|
||||||
|
ax.legend(h[::-1], l[::-1])
|
||||||
|
ax.grid(zorder=0)
|
||||||
|
|
||||||
|
fig.savefig(OUTPUT_DIR / (NAME + ".png"))
|
||||||
|
print(f"Wrote to {OUTPUT_DIR / (NAME + '.png')}")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
117
scripts/probability_of_disorder.py
Normal file
117
scripts/probability_of_disorder.py
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
import numpy as np, os
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.ticker as mtick
|
||||||
|
|
||||||
|
from squish import Simulation, DomainParams, Energy, ordered
|
||||||
|
from squish.common import OUTPUT_DIR
|
||||||
|
from script_tools import (
|
||||||
|
RC_SETTINGS,
|
||||||
|
get_args,
|
||||||
|
get_data,
|
||||||
|
get_simulation_data,
|
||||||
|
get_ordered_data,
|
||||||
|
)
|
||||||
|
|
||||||
|
NAME = "PoD"
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
sims_path, regen = get_args(
|
||||||
|
"Various graphs for single N data.",
|
||||||
|
"folder that contains simulation data at various aspect ratios for some N",
|
||||||
|
)
|
||||||
|
|
||||||
|
data, n, r = get_data(
|
||||||
|
sims_path / "package.pkl", get_simulation_data, args=(sims_path,), regen=regen
|
||||||
|
)
|
||||||
|
domain, alphas = DomainParams(n, 1, 1, r), data["all"]["alpha"]
|
||||||
|
ordered_data = get_data(
|
||||||
|
OUTPUT_DIR / "OrderedCache" / f"{n}.pkl",
|
||||||
|
get_ordered_data,
|
||||||
|
args=(domain, alphas),
|
||||||
|
regen=regen,
|
||||||
|
)
|
||||||
|
|
||||||
|
min_disorder, max_disorder = [], []
|
||||||
|
for i, energies in enumerate(data["distinct"]["Energy"]):
|
||||||
|
disorder_energies = []
|
||||||
|
for j, energy in enumerate(energies):
|
||||||
|
if not data["distinct"]["Ordered"][i][j]:
|
||||||
|
disorder_energies.append(energy)
|
||||||
|
min_disorder.append(min(disorder_energies))
|
||||||
|
max_disorder.append(max(disorder_energies))
|
||||||
|
|
||||||
|
min_order = []
|
||||||
|
for i, energies in enumerate(ordered_data["Energy"]):
|
||||||
|
min_order.append(energies[0])
|
||||||
|
|
||||||
|
e_hex = ordered.e_hex(domain)
|
||||||
|
min_disorder = np.array(min_disorder) / domain.n - e_hex
|
||||||
|
max_disorder = np.array(max_disorder) / domain.n - e_hex
|
||||||
|
min_order = np.array(min_order) / domain.n - e_hex
|
||||||
|
|
||||||
|
all_disorder_count = []
|
||||||
|
for disorders in data["all"]["Ordered"]:
|
||||||
|
all_disorder_count.append(
|
||||||
|
100 * np.count_nonzero(disorders == False) / len(disorders)
|
||||||
|
)
|
||||||
|
|
||||||
|
plt.rcParams.update(RC_SETTINGS)
|
||||||
|
fig = plt.figure(figsize=(15, 15))
|
||||||
|
gs = fig.add_gridspec(1, 1)
|
||||||
|
ax = fig.add_subplot(gs[0])
|
||||||
|
ax2 = ax.twinx()
|
||||||
|
|
||||||
|
ax.plot(alphas, 100 * (min_order - min_disorder), color="C2")
|
||||||
|
ax2.plot(alphas, all_disorder_count, color="C4")
|
||||||
|
|
||||||
|
ax.set_xlim(0.3, 1)
|
||||||
|
ax.set_xticks(np.arange(0.3, 1.01, 0.1))
|
||||||
|
|
||||||
|
start, end = ax.get_ylim()
|
||||||
|
# space = np.linspace(0, end, 20)
|
||||||
|
space = np.arange(-2.3, 3.3, 0.5)
|
||||||
|
ax.set_ylim(-2.5, 3.4)
|
||||||
|
ax.set_yticks(space)
|
||||||
|
ax.ticklabel_format(axis="y", style="sci")
|
||||||
|
|
||||||
|
# start, end = ax2.get_ylim()
|
||||||
|
# space = np.linspace(start, end, 20)
|
||||||
|
# space += 100 - space[-2]
|
||||||
|
space = np.linspace(50, 100, len(space))
|
||||||
|
ax2.set_ylim(
|
||||||
|
space[0] - (space[1] - space[0]) * 0.4, space[-1] + (space[1] - space[0]) * 0.6
|
||||||
|
)
|
||||||
|
ax2.set_yticks(space)
|
||||||
|
# ax2.set_ylim(start, space[-1])
|
||||||
|
# ax2.set_yticks(space[1:-1])
|
||||||
|
ax2.yaxis.set_major_formatter(mtick.PercentFormatter())
|
||||||
|
|
||||||
|
ax.set_xlabel("Aspect Ratio")
|
||||||
|
ax.set_ylabel(r"VEE $\left[\times 10^{2}\right]$", color="C2")
|
||||||
|
ax2.set_ylabel("Percent of Disordered Equilibria", color="C4")
|
||||||
|
|
||||||
|
# ax.legend(loc=(0.23, 0.5))
|
||||||
|
ax.grid(zorder=0)
|
||||||
|
|
||||||
|
props = dict(boxstyle="round", facecolor="white", alpha=0.8, zorder=20)
|
||||||
|
ax.text(
|
||||||
|
0.873,
|
||||||
|
0.97,
|
||||||
|
f"N={domain.n}",
|
||||||
|
transform=ax.transAxes,
|
||||||
|
verticalalignment="top",
|
||||||
|
bbox=props,
|
||||||
|
)
|
||||||
|
|
||||||
|
out = OUTPUT_DIR / f"{NAME}-N{domain.n}.png"
|
||||||
|
fig.savefig(out)
|
||||||
|
print(f"Wrote to {out}.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
os.environ["QT_LOGGING_RULES"] = "*=false"
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("Program terminated by user.")
|
||||||
206
scripts/script_tools.py
Normal file
206
scripts/script_tools.py
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
from typing import List
|
||||||
|
import argparse, pickle, numpy as np, math
|
||||||
|
from pathlib import Path
|
||||||
|
from multiprocessing import Pool, cpu_count
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
from squish import DomainParams, Simulation, Energy, ordered
|
||||||
|
from squish.common import OUTPUT_DIR
|
||||||
|
|
||||||
|
RC_SETTINGS = {
|
||||||
|
"axes.titlesize": 45,
|
||||||
|
"axes.labelsize": 45,
|
||||||
|
"xtick.labelsize": 40,
|
||||||
|
"ytick.labelsize": 40,
|
||||||
|
"xtick.major.width": 2,
|
||||||
|
"ytick.major.width": 2,
|
||||||
|
"xtick.major.size": 5,
|
||||||
|
"ytick.major.size": 5,
|
||||||
|
"xtick.minor.width": 1,
|
||||||
|
"ytick.minor.width": 1,
|
||||||
|
"xtick.minor.size": 3,
|
||||||
|
"ytick.minor.size": 3,
|
||||||
|
"legend.fontsize": 40,
|
||||||
|
"lines.linewidth": 3,
|
||||||
|
"font.family": "cm",
|
||||||
|
"font.size": 40,
|
||||||
|
"text.usetex": True,
|
||||||
|
"text.latex.preamble": r"\usepackage{amsmath}",
|
||||||
|
"figure.constrained_layout.use": True,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_args(
|
||||||
|
script_desc: str, path_desc: str, cache_file: bool = True
|
||||||
|
) -> Tuple[Path, bool]:
|
||||||
|
parser = argparse.ArgumentParser(description=script_desc)
|
||||||
|
parser.add_argument("sims_path", metavar="sim_dir", help=path_desc)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
"--regenerate",
|
||||||
|
dest="regen",
|
||||||
|
action="store_true",
|
||||||
|
help="regenerates the cache file for processed data",
|
||||||
|
)
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
return (Path(args.sims_path), args.regen)
|
||||||
|
|
||||||
|
|
||||||
|
def get_data(
|
||||||
|
path: Path, func: Callable[Any, Any], args: Tuple[Any] = (), regen: bool = False
|
||||||
|
) -> Any:
|
||||||
|
if path.is_file() and not regen:
|
||||||
|
with open(path, "rb") as f:
|
||||||
|
return pickle.load(f)
|
||||||
|
else:
|
||||||
|
data = func(*args)
|
||||||
|
with open(path, "wb") as f:
|
||||||
|
pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def format_data(
|
||||||
|
data: Dict[Any, Any], key_name: str, col_names=List[str]
|
||||||
|
) -> Dict[Any, Any]:
|
||||||
|
data = sorted(data.items())
|
||||||
|
new_data = {}
|
||||||
|
new_data[key_name] = np.array([x[0] for x in data])
|
||||||
|
for i, col_name in enumerate(col_names):
|
||||||
|
if type(data[0][1][i]) is list:
|
||||||
|
new_data[col_name] = [np.array(x[1][i]) for x in data]
|
||||||
|
else:
|
||||||
|
new_data[col_name] = np.array([x[1][i] for x in data])
|
||||||
|
return new_data
|
||||||
|
|
||||||
|
|
||||||
|
def get_ordered_data(orig_domain: DomainParams, asps: np.ndarray) -> Dict:
|
||||||
|
data = {}
|
||||||
|
domains = []
|
||||||
|
for alpha in asps:
|
||||||
|
domains.append(
|
||||||
|
[
|
||||||
|
DomainParams(
|
||||||
|
orig_domain.n,
|
||||||
|
math.sqrt(orig_domain.n * alpha),
|
||||||
|
math.sqrt(orig_domain.n / alpha),
|
||||||
|
orig_domain.r,
|
||||||
|
),
|
||||||
|
alpha,
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
with Pool(cpu_count()) as pool:
|
||||||
|
for i, res in enumerate(pool.imap_unordered(ordered_data_proc, domains)):
|
||||||
|
data[res[0]] = res[1:]
|
||||||
|
|
||||||
|
hashes = int(21 * i / len(asps))
|
||||||
|
print(
|
||||||
|
f'Generating at width {res[0]:.02f}... |{"#"*hashes}{" "*(20-hashes)}|'
|
||||||
|
+ f" {i+1}/{len(asps)} completed.",
|
||||||
|
flush=True,
|
||||||
|
end="\r",
|
||||||
|
)
|
||||||
|
|
||||||
|
print(flush=True)
|
||||||
|
|
||||||
|
return format_data(data, key_name="alpha", col_names=["Energy", "Coercivity"])
|
||||||
|
|
||||||
|
|
||||||
|
def ordered_data_proc(
|
||||||
|
dom_tup: Tuple[DomainParams, float]
|
||||||
|
) -> Tuple[float, float, float, float]:
|
||||||
|
domain, alpha = dom_tup
|
||||||
|
energies, coercivities = [], []
|
||||||
|
e_hex = ordered.e_hex(domain)
|
||||||
|
|
||||||
|
configs = ordered.configurations(domain)
|
||||||
|
for config in configs:
|
||||||
|
# Causes errors, so ignore.
|
||||||
|
if config[0] == 0 or config[1] == 0:
|
||||||
|
continue
|
||||||
|
# rbar = ordered.avg_radius(domain, config)
|
||||||
|
# area = domain.w * domain.h / domain.n
|
||||||
|
|
||||||
|
# energies.append(
|
||||||
|
# 2 * domain.w * domain.h
|
||||||
|
# + 2 * math.pi * domain.n * (domain.r ** 2 - 2 * domain.r * rbar)
|
||||||
|
# )
|
||||||
|
|
||||||
|
# isoparams.append(math.pi * rbar ** 2 / area)
|
||||||
|
|
||||||
|
sites = ordered.sites(domain, config)
|
||||||
|
frame = Energy("radial-t").mode(*domain, sites)
|
||||||
|
energies.append(frame.energy)
|
||||||
|
|
||||||
|
eigs = np.sort(np.linalg.eigvalsh(frame.hessian))
|
||||||
|
|
||||||
|
zero_ind = np.where(np.isclose(eigs, 0, atol=1e-8))[0]
|
||||||
|
if len(zero_ind) == 0:
|
||||||
|
coercivities.append(eigs[0])
|
||||||
|
elif zero_ind[0] == 0:
|
||||||
|
coercivities.append(eigs[2])
|
||||||
|
else:
|
||||||
|
coercivities.append(eigs[0])
|
||||||
|
|
||||||
|
return (alpha, sorted(energies), sorted(coercivities)[::-1])
|
||||||
|
|
||||||
|
|
||||||
|
def get_simulation_data(filepath: Path) -> Tuple[Dict, numpy.ndarray, DomainParams]:
|
||||||
|
data = {"all": {}, "distinct": {}}
|
||||||
|
files = list(Path(filepath).iterdir())
|
||||||
|
|
||||||
|
with Pool(cpu_count()) as pool:
|
||||||
|
for i, res in enumerate(pool.imap_unordered(simulation_data_proc, files)):
|
||||||
|
data["all"][res[0]] = res[1]
|
||||||
|
data["distinct"][res[0]] = res[2]
|
||||||
|
|
||||||
|
hashes = int(21 * i / len(files))
|
||||||
|
print(
|
||||||
|
f'Loading simulations... |{"#"*hashes}{" "*(20-hashes)}|'
|
||||||
|
+ f" {i+1}/{len(files)} simulations loaded.",
|
||||||
|
flush=True,
|
||||||
|
end="\r",
|
||||||
|
)
|
||||||
|
print(flush=True)
|
||||||
|
|
||||||
|
data["all"] = format_data(
|
||||||
|
data["all"], key_name="alpha", col_names=["Energy", "Ordered", "Defects"]
|
||||||
|
)
|
||||||
|
|
||||||
|
data["distinct"] = format_data(
|
||||||
|
data["distinct"],
|
||||||
|
key_name="alpha",
|
||||||
|
col_names=["Energy", "Ordered", "Defects", "Hits"],
|
||||||
|
)
|
||||||
|
|
||||||
|
sim, frames = Simulation.load(files[0])
|
||||||
|
return data, sim.domain.n, sim.domain.r
|
||||||
|
|
||||||
|
|
||||||
|
def simulation_data_proc(file: Path) -> Tuple[float, List[float], List[float]]:
|
||||||
|
sim, frames = Simulation.load(file)
|
||||||
|
|
||||||
|
alls = [[], [], []]
|
||||||
|
for frame_info in frames:
|
||||||
|
alls[0].append(frame_info["energy"])
|
||||||
|
alls[1].append(np.var(frame_info["stats"]["avg_radius"]) <= 1e-8)
|
||||||
|
alls[2].append(np.count_nonzero(frame_info["stats"]["site_edge_count"] != 6))
|
||||||
|
|
||||||
|
sim, frames = Simulation.load(file)
|
||||||
|
sim.frames = list(frames)
|
||||||
|
counts = sim.get_distinct()
|
||||||
|
|
||||||
|
distincts = [[], [], []]
|
||||||
|
for j, frame_info in enumerate(sim.frames):
|
||||||
|
distincts[0].append(frame_info["energy"])
|
||||||
|
distincts[1].append(np.var(frame_info["stats"]["avg_radius"]) <= 1e-8)
|
||||||
|
distincts[2].append(
|
||||||
|
np.count_nonzero(frame_info["stats"]["site_edge_count"] != 6)
|
||||||
|
)
|
||||||
|
|
||||||
|
distincts.append(counts)
|
||||||
|
|
||||||
|
return sim.domain.w / sim.domain.h, alls, distincts
|
||||||
103
scripts/torus.py
Normal file
103
scripts/torus.py
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
|
||||||
|
def torus_mesh(n, c, a):
|
||||||
|
theta = np.linspace(0, 2 * np.pi, n)
|
||||||
|
phi = np.linspace(0, 2 * np.pi, n)
|
||||||
|
theta, phi = np.meshgrid(theta, phi)
|
||||||
|
x = (c + a * np.cos(theta)) * np.cos(phi)
|
||||||
|
y = (c + a * np.cos(theta)) * np.sin(phi)
|
||||||
|
z = a * np.sin(theta)
|
||||||
|
return x, y, z
|
||||||
|
|
||||||
|
|
||||||
|
def torus_line(n, c, a, u, v):
|
||||||
|
phi = np.linspace(0, 2 * np.pi * u, n)
|
||||||
|
theta = (v / u) * phi
|
||||||
|
theta, phi = theta % (2 * np.pi), phi % (2 * np.pi)
|
||||||
|
|
||||||
|
x = (c + a * np.cos(theta)) * np.cos(phi)
|
||||||
|
y = (c + a * np.cos(theta)) * np.sin(phi)
|
||||||
|
z = a * np.sin(theta)
|
||||||
|
|
||||||
|
line = np.column_stack([x, y, z])
|
||||||
|
x, y, z = c * np.cos(phi), c * np.sin(phi), 0 * phi
|
||||||
|
norm = line - np.column_stack([x, y, z])
|
||||||
|
|
||||||
|
return line, norm
|
||||||
|
|
||||||
|
|
||||||
|
def torus_points(c, a, u, v, k):
|
||||||
|
phi = np.linspace(0, 2 * np.pi * u, k + 1)
|
||||||
|
theta = (v / u) * phi
|
||||||
|
theta, phi = theta % (2 * np.pi), phi % (2 * np.pi)
|
||||||
|
|
||||||
|
x = (c + a * np.cos(theta)) * np.cos(phi)
|
||||||
|
y = (c + a * np.cos(theta)) * np.sin(phi)
|
||||||
|
z = a * np.sin(theta)
|
||||||
|
|
||||||
|
return x, y, z
|
||||||
|
|
||||||
|
|
||||||
|
def get_obscure_segs(arr):
|
||||||
|
bounds = [0, 0]
|
||||||
|
seg = 1
|
||||||
|
for i in range(1, len(arr)):
|
||||||
|
if arr[i] != arr[i - 1]:
|
||||||
|
bounds[seg] = i
|
||||||
|
bounds.append(i)
|
||||||
|
seg += 1
|
||||||
|
return bounds + [len(arr) - 1]
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
fig = plt.figure(figsize=(10, 10), constrained_layout=True)
|
||||||
|
ax = fig.add_subplot(projection="3d")
|
||||||
|
ax.set_zlim(-2, 2)
|
||||||
|
ax.set_axis_off()
|
||||||
|
|
||||||
|
azim, elev = 0, 40
|
||||||
|
c, a = 2, 1
|
||||||
|
u, v = 4, 1
|
||||||
|
k = 10
|
||||||
|
|
||||||
|
ax.view_init(elev, azim)
|
||||||
|
|
||||||
|
ax.plot_surface(
|
||||||
|
*torus_mesh(100, c, a), rcount=200, ccount=200, color="white", alpha=0.4
|
||||||
|
)
|
||||||
|
|
||||||
|
# Calculate when surface is facing or away and apply dotted vs solid lines.
|
||||||
|
az, el = azim * np.pi / 180 - np.pi, elev * np.pi / 180 - np.pi / 2
|
||||||
|
camera_vec = np.array(
|
||||||
|
[np.sin(el) * np.cos(az), np.sin(el) * np.sin(az), np.cos(el)]
|
||||||
|
)
|
||||||
|
line, norm = torus_line(500, c, a, u, v)
|
||||||
|
cond = np.dot(norm, camera_vec) >= 0
|
||||||
|
bounds = get_obscure_segs(cond)
|
||||||
|
|
||||||
|
# Did not account for normal vectors intersecting with main body, so
|
||||||
|
# we have manual overrides...
|
||||||
|
print(bounds)
|
||||||
|
bounds[3] = 220
|
||||||
|
print(bounds)
|
||||||
|
|
||||||
|
for i in range(len(bounds) - 1):
|
||||||
|
seg = line[bounds[i] : bounds[i + 1] + 1, :]
|
||||||
|
lx, ly, lz = seg[:, 0], seg[:, 1], seg[:, 2]
|
||||||
|
style = "solid" if cond[bounds[i]] else "dashed"
|
||||||
|
if i == 3:
|
||||||
|
style = "dashed"
|
||||||
|
if i == 4:
|
||||||
|
style = "dashed"
|
||||||
|
ax.plot(lx, ly, lz, color="blue", linewidth=2, linestyle=style)
|
||||||
|
|
||||||
|
# Display points.
|
||||||
|
ax.scatter(*torus_points(c, a, u, v, k), color="purple", s=50)
|
||||||
|
# ax.plot(*torus_line(200, 2, 1, 2, 1), color="orange", linewidth=3)
|
||||||
|
plt.savefig(f"Torus - N{k}({u},{v}).png", bbox_inches="tight")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
112
scripts/vee.py
Normal file
112
scripts/vee.py
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
import numpy as np, os
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.ticker as mtick
|
||||||
|
|
||||||
|
from squish import Simulation, DomainParams, Energy, ordered
|
||||||
|
from squish.common import OUTPUT_DIR
|
||||||
|
from script_tools import (
|
||||||
|
RC_SETTINGS,
|
||||||
|
get_args,
|
||||||
|
get_data,
|
||||||
|
get_simulation_data,
|
||||||
|
get_ordered_data,
|
||||||
|
)
|
||||||
|
|
||||||
|
NAME = "VEE"
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
sims_path, regen = get_args(
|
||||||
|
"Various graphs for single N data.",
|
||||||
|
"folder that contains simulation data at various aspect ratios for some N",
|
||||||
|
)
|
||||||
|
|
||||||
|
data, n, r = get_data(
|
||||||
|
sims_path / "package.pkl", get_simulation_data, args=(sims_path,), regen=regen
|
||||||
|
)
|
||||||
|
domain, alphas = DomainParams(n, 1, 1, r), data["all"]["alpha"]
|
||||||
|
|
||||||
|
if regen:
|
||||||
|
os.remove(OUTPUT_DIR / "OrderedCache" / f"{n}".pkl)
|
||||||
|
|
||||||
|
ordered_data = get_data(
|
||||||
|
OUTPUT_DIR / "OrderedCache" / f"{n}.pkl",
|
||||||
|
get_ordered_data,
|
||||||
|
args=(domain, alphas),
|
||||||
|
regen=regen,
|
||||||
|
)
|
||||||
|
|
||||||
|
min_disorder, max_disorder = [], []
|
||||||
|
for i, energies in enumerate(data["distinct"]["Energy"]):
|
||||||
|
disorder_energies = []
|
||||||
|
for j, energy in enumerate(energies):
|
||||||
|
if not data["distinct"]["Ordered"][i][j]:
|
||||||
|
disorder_energies.append(energy)
|
||||||
|
min_disorder.append(min(disorder_energies))
|
||||||
|
max_disorder.append(max(disorder_energies))
|
||||||
|
|
||||||
|
min_order = []
|
||||||
|
for i, energies in enumerate(ordered_data["Energy"]):
|
||||||
|
min_order.append(energies[0])
|
||||||
|
|
||||||
|
e_hex = ordered.e_hex(domain)
|
||||||
|
min_disorder = np.array(min_disorder) / domain.n - e_hex
|
||||||
|
max_disorder = np.array(max_disorder) / domain.n - e_hex
|
||||||
|
min_order = np.array(min_order) / domain.n - e_hex
|
||||||
|
|
||||||
|
hex_ratios = ordered.hexagon_alpha(domain.n)
|
||||||
|
|
||||||
|
plt.rcParams.update(RC_SETTINGS)
|
||||||
|
fig = plt.figure(figsize=(15, 15))
|
||||||
|
gs = fig.add_gridspec(1, 1)
|
||||||
|
ax = fig.add_subplot(gs[0])
|
||||||
|
|
||||||
|
ax.plot(alphas, 100 * min_order, color="C1", label="Min Ordered", zorder=10)
|
||||||
|
ax.plot(alphas, 100 * min_disorder, color="C0", label="Min Disordered")
|
||||||
|
|
||||||
|
ax.plot(
|
||||||
|
alphas,
|
||||||
|
100 * max_disorder,
|
||||||
|
color="C0",
|
||||||
|
linestyle="dotted",
|
||||||
|
label="Max Disordered",
|
||||||
|
)
|
||||||
|
|
||||||
|
ax.set_xlim(0.3, 1)
|
||||||
|
|
||||||
|
# start, end = ax.get_ylim()
|
||||||
|
# space = np.linspace(0, end, 20)
|
||||||
|
|
||||||
|
space = np.arange(0, 6.6, 0.3)
|
||||||
|
ax.set_ylim(-0.15, 6.6)
|
||||||
|
ax.set_yticks(space[:-1])
|
||||||
|
ax.ticklabel_format(axis="y", style="sci")
|
||||||
|
|
||||||
|
ax.set_xlabel("Aspect Ratio")
|
||||||
|
ax.set_ylabel(r"VEE $\left[\times 10^{2}\right]$")
|
||||||
|
|
||||||
|
ax.legend(loc=(0.23, 0.5))
|
||||||
|
# ax.legend()
|
||||||
|
ax.grid(zorder=0)
|
||||||
|
|
||||||
|
props = dict(boxstyle="round", facecolor="white", alpha=0.8, zorder=20)
|
||||||
|
ax.text(
|
||||||
|
0.873,
|
||||||
|
0.97,
|
||||||
|
f"N={domain.n}",
|
||||||
|
transform=ax.transAxes,
|
||||||
|
verticalalignment="top",
|
||||||
|
bbox=props,
|
||||||
|
)
|
||||||
|
|
||||||
|
out = OUTPUT_DIR / f"{NAME}-N{domain.n}.png"
|
||||||
|
fig.savefig(out)
|
||||||
|
print(f"Wrote to {out}.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
os.environ["QT_LOGGING_RULES"] = "*=false"
|
||||||
|
try:
|
||||||
|
main()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("Program terminated by user.")
|
||||||
95
scripts/vee_diff_pod.py
Normal file
95
scripts/vee_diff_pod.py
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
import numpy as np, os
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.ticker as mtick
|
||||||
|
|
||||||
|
from squish import Simulation, DomainParams, ordered
|
||||||
|
from squish.common import OUTPUT_DIR
|
||||||
|
from script_tools import (
|
||||||
|
RC_SETTINGS,
|
||||||
|
get_args,
|
||||||
|
get_data,
|
||||||
|
get_simulation_data,
|
||||||
|
get_ordered_data,
|
||||||
|
)
|
||||||
|
|
||||||
|
NAME = "VEEDiff-PoD"
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
sims_path, regen = get_args(
|
||||||
|
"Scatter plot of VEE difference and disordered equilibria.",
|
||||||
|
"folders that contains various N simulations to plot",
|
||||||
|
)
|
||||||
|
|
||||||
|
packages = []
|
||||||
|
for fol in sims_path.iterdir():
|
||||||
|
if fol.is_file():
|
||||||
|
continue
|
||||||
|
|
||||||
|
data, n, r = get_data(
|
||||||
|
fol / "package.pkl", get_simulation_data, args=(fol,), regen=regen
|
||||||
|
)
|
||||||
|
domain, alphas = DomainParams(n, 1, 1, r), data["all"]["alpha"]
|
||||||
|
ordered_data = get_data(
|
||||||
|
OUTPUT_DIR / "OrderedCache" / f"{n}.pkl",
|
||||||
|
get_ordered_data,
|
||||||
|
args=(domain, alphas),
|
||||||
|
regen=regen,
|
||||||
|
)
|
||||||
|
|
||||||
|
packages.append([data, ordered_data, domain])
|
||||||
|
|
||||||
|
packages.sort(key=lambda x: x[2].n)
|
||||||
|
|
||||||
|
plt.rcParams.update(RC_SETTINGS)
|
||||||
|
|
||||||
|
fig = plt.figure(figsize=(15, 15))
|
||||||
|
gs = fig.add_gridspec(1, 1)
|
||||||
|
ax = fig.add_subplot(gs[0])
|
||||||
|
|
||||||
|
for j, package in enumerate(packages):
|
||||||
|
data, ordered_data, domain = package
|
||||||
|
|
||||||
|
min_disorder, max_disorder = [], []
|
||||||
|
for i, energies in enumerate(data["distinct"]["Energy"]):
|
||||||
|
disorder_energies = []
|
||||||
|
for j, energy in enumerate(energies):
|
||||||
|
if not data["distinct"]["Ordered"][i][j]:
|
||||||
|
disorder_energies.append(energy)
|
||||||
|
min_disorder.append(min(disorder_energies))
|
||||||
|
max_disorder.append(max(disorder_energies))
|
||||||
|
|
||||||
|
min_order = []
|
||||||
|
for i, energies in enumerate(ordered_data["Energy"]):
|
||||||
|
min_order.append(energies[0])
|
||||||
|
|
||||||
|
e_hex = ordered.e_hex(domain)
|
||||||
|
min_disorder = np.array(min_disorder) / domain.n - e_hex
|
||||||
|
max_disorder = np.array(max_disorder) / domain.n - e_hex
|
||||||
|
min_order = np.array(min_order) / domain.n - e_hex
|
||||||
|
|
||||||
|
all_disorder_count = []
|
||||||
|
for disorders in data["all"]["Ordered"]:
|
||||||
|
all_disorder_count.append(
|
||||||
|
100 * np.count_nonzero(disorders == False) / len(disorders)
|
||||||
|
)
|
||||||
|
|
||||||
|
ax.scatter(
|
||||||
|
100 * (min_order - min_disorder), all_disorder_count, label=f"N={domain.n}"
|
||||||
|
)
|
||||||
|
|
||||||
|
ax.set_ylabel("Probability of Disordered Equilibria")
|
||||||
|
ax.set_xlabel(r"VEE Difference $\left[\times 10^{2}\right]$")
|
||||||
|
ax.yaxis.set_major_formatter(mtick.PercentFormatter())
|
||||||
|
ax.set_ylim(48, 102)
|
||||||
|
ax.set_yticks(np.arange(50, 101, 5))
|
||||||
|
|
||||||
|
ax.grid(zorder=0)
|
||||||
|
ax.legend()
|
||||||
|
|
||||||
|
fig.savefig(OUTPUT_DIR / (NAME + ".png"))
|
||||||
|
print(f"Wrote to {OUTPUT_DIR / (NAME + '.png')}")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
335
squish/core.c
335
squish/core.c
File diff suppressed because it is too large
Load Diff
154
squish/energy.c
154
squish/energy.c
@ -1,4 +1,4 @@
|
|||||||
/* Generated by Cython 0.29.24 */
|
/* Generated by Cython 0.29.26 */
|
||||||
|
|
||||||
/* BEGIN: Cython Metadata
|
/* BEGIN: Cython Metadata
|
||||||
{
|
{
|
||||||
@ -34,8 +34,8 @@ END: Cython Metadata */
|
|||||||
#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)
|
#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)
|
||||||
#error Cython requires Python 2.6+ or Python 3.3+.
|
#error Cython requires Python 2.6+ or Python 3.3+.
|
||||||
#else
|
#else
|
||||||
#define CYTHON_ABI "0_29_24"
|
#define CYTHON_ABI "0_29_26"
|
||||||
#define CYTHON_HEX_VERSION 0x001D18F0
|
#define CYTHON_HEX_VERSION 0x001D1AF0
|
||||||
#define CYTHON_FUTURE_DIVISION 1
|
#define CYTHON_FUTURE_DIVISION 1
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#ifndef offsetof
|
#ifndef offsetof
|
||||||
@ -182,7 +182,7 @@ END: Cython Metadata */
|
|||||||
#ifndef CYTHON_USE_UNICODE_INTERNALS
|
#ifndef CYTHON_USE_UNICODE_INTERNALS
|
||||||
#define CYTHON_USE_UNICODE_INTERNALS 1
|
#define CYTHON_USE_UNICODE_INTERNALS 1
|
||||||
#endif
|
#endif
|
||||||
#if PY_VERSION_HEX < 0x030300F0
|
#if PY_VERSION_HEX < 0x030300F0 || PY_VERSION_HEX >= 0x030B00A2
|
||||||
#undef CYTHON_USE_UNICODE_WRITER
|
#undef CYTHON_USE_UNICODE_WRITER
|
||||||
#define CYTHON_USE_UNICODE_WRITER 0
|
#define CYTHON_USE_UNICODE_WRITER 0
|
||||||
#elif !defined(CYTHON_USE_UNICODE_WRITER)
|
#elif !defined(CYTHON_USE_UNICODE_WRITER)
|
||||||
@ -201,7 +201,7 @@ END: Cython Metadata */
|
|||||||
#define CYTHON_FAST_THREAD_STATE 1
|
#define CYTHON_FAST_THREAD_STATE 1
|
||||||
#endif
|
#endif
|
||||||
#ifndef CYTHON_FAST_PYCALL
|
#ifndef CYTHON_FAST_PYCALL
|
||||||
#define CYTHON_FAST_PYCALL 1
|
#define CYTHON_FAST_PYCALL (PY_VERSION_HEX < 0x030B00A1)
|
||||||
#endif
|
#endif
|
||||||
#ifndef CYTHON_PEP489_MULTI_PHASE_INIT
|
#ifndef CYTHON_PEP489_MULTI_PHASE_INIT
|
||||||
#define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000)
|
#define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000)
|
||||||
@ -220,7 +220,9 @@ END: Cython Metadata */
|
|||||||
#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1)
|
#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1)
|
||||||
#endif
|
#endif
|
||||||
#if CYTHON_USE_PYLONG_INTERNALS
|
#if CYTHON_USE_PYLONG_INTERNALS
|
||||||
#include "longintrepr.h"
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
#include "longintrepr.h"
|
||||||
|
#endif
|
||||||
#undef SHIFT
|
#undef SHIFT
|
||||||
#undef BASE
|
#undef BASE
|
||||||
#undef MASK
|
#undef MASK
|
||||||
@ -337,9 +339,68 @@ END: Cython Metadata */
|
|||||||
#define __Pyx_DefaultClassType PyClass_Type
|
#define __Pyx_DefaultClassType PyClass_Type
|
||||||
#else
|
#else
|
||||||
#define __Pyx_BUILTIN_MODULE_NAME "builtins"
|
#define __Pyx_BUILTIN_MODULE_NAME "builtins"
|
||||||
#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2
|
#define __Pyx_DefaultClassType PyType_Type
|
||||||
#define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\
|
#if PY_VERSION_HEX >= 0x030B00A1
|
||||||
PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
|
static CYTHON_INLINE PyCodeObject* __Pyx_PyCode_New(int a, int k, int l, int s, int f,
|
||||||
|
PyObject *code, PyObject *c, PyObject* n, PyObject *v,
|
||||||
|
PyObject *fv, PyObject *cell, PyObject* fn,
|
||||||
|
PyObject *name, int fline, PyObject *lnos) {
|
||||||
|
PyObject *kwds=NULL, *argcount=NULL, *posonlyargcount=NULL, *kwonlyargcount=NULL;
|
||||||
|
PyObject *nlocals=NULL, *stacksize=NULL, *flags=NULL, *replace=NULL, *call_result=NULL, *empty=NULL;
|
||||||
|
const char *fn_cstr=NULL;
|
||||||
|
const char *name_cstr=NULL;
|
||||||
|
PyCodeObject* co=NULL;
|
||||||
|
PyObject *type, *value, *traceback;
|
||||||
|
PyErr_Fetch(&type, &value, &traceback);
|
||||||
|
if (!(kwds=PyDict_New())) goto end;
|
||||||
|
if (!(argcount=PyLong_FromLong(a))) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_argcount", argcount) != 0) goto end;
|
||||||
|
if (!(posonlyargcount=PyLong_FromLong(0))) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_posonlyargcount", posonlyargcount) != 0) goto end;
|
||||||
|
if (!(kwonlyargcount=PyLong_FromLong(k))) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_kwonlyargcount", kwonlyargcount) != 0) goto end;
|
||||||
|
if (!(nlocals=PyLong_FromLong(l))) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_nlocals", nlocals) != 0) goto end;
|
||||||
|
if (!(stacksize=PyLong_FromLong(s))) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_stacksize", stacksize) != 0) goto end;
|
||||||
|
if (!(flags=PyLong_FromLong(f))) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_flags", flags) != 0) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_code", code) != 0) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_consts", c) != 0) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_names", n) != 0) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_varnames", v) != 0) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_freevars", fv) != 0) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_cellvars", cell) != 0) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_linetable", lnos) != 0) goto end;
|
||||||
|
if (!(fn_cstr=PyUnicode_AsUTF8AndSize(fn, NULL))) goto end;
|
||||||
|
if (!(name_cstr=PyUnicode_AsUTF8AndSize(name, NULL))) goto end;
|
||||||
|
if (!(co = PyCode_NewEmpty(fn_cstr, name_cstr, fline))) goto end;
|
||||||
|
if (!(replace = PyObject_GetAttrString((PyObject*)co, "replace"))) goto cleanup_code_too;
|
||||||
|
if (!(empty = PyTuple_New(0))) goto cleanup_code_too; // unfortunately __pyx_empty_tuple isn't available here
|
||||||
|
if (!(call_result = PyObject_Call(replace, empty, kwds))) goto cleanup_code_too;
|
||||||
|
Py_XDECREF((PyObject*)co);
|
||||||
|
co = (PyCodeObject*)call_result;
|
||||||
|
call_result = NULL;
|
||||||
|
if (0) {
|
||||||
|
cleanup_code_too:
|
||||||
|
Py_XDECREF((PyObject*)co);
|
||||||
|
co = NULL;
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
Py_XDECREF(kwds);
|
||||||
|
Py_XDECREF(argcount);
|
||||||
|
Py_XDECREF(posonlyargcount);
|
||||||
|
Py_XDECREF(kwonlyargcount);
|
||||||
|
Py_XDECREF(nlocals);
|
||||||
|
Py_XDECREF(stacksize);
|
||||||
|
Py_XDECREF(replace);
|
||||||
|
Py_XDECREF(call_result);
|
||||||
|
Py_XDECREF(empty);
|
||||||
|
if (type) {
|
||||||
|
PyErr_Restore(type, value, traceback);
|
||||||
|
}
|
||||||
|
return co;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\
|
#define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\
|
||||||
PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
|
PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
|
||||||
@ -577,10 +638,10 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) {
|
|||||||
#if PY_VERSION_HEX < 0x030200A4
|
#if PY_VERSION_HEX < 0x030200A4
|
||||||
typedef long Py_hash_t;
|
typedef long Py_hash_t;
|
||||||
#define __Pyx_PyInt_FromHash_t PyInt_FromLong
|
#define __Pyx_PyInt_FromHash_t PyInt_FromLong
|
||||||
#define __Pyx_PyInt_AsHash_t PyInt_AsLong
|
#define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsHash_t
|
||||||
#else
|
#else
|
||||||
#define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
|
#define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
|
||||||
#define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
|
#define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsSsize_t
|
||||||
#endif
|
#endif
|
||||||
#if PY_MAJOR_VERSION >= 3
|
#if PY_MAJOR_VERSION >= 3
|
||||||
#define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func))
|
#define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func))
|
||||||
@ -750,6 +811,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x);
|
|||||||
(likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj))
|
(likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj))
|
||||||
static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
|
static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
|
||||||
static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
|
static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
|
||||||
|
static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*);
|
||||||
#if CYTHON_ASSUME_SAFE_MACROS
|
#if CYTHON_ASSUME_SAFE_MACROS
|
||||||
#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
|
#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
|
||||||
#else
|
#else
|
||||||
@ -2046,6 +2108,7 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args,
|
|||||||
#ifndef Py_MEMBER_SIZE
|
#ifndef Py_MEMBER_SIZE
|
||||||
#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member)
|
#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member)
|
||||||
#endif
|
#endif
|
||||||
|
#if CYTHON_FAST_PYCALL
|
||||||
static size_t __pyx_pyframe_localsplus_offset = 0;
|
static size_t __pyx_pyframe_localsplus_offset = 0;
|
||||||
#include "frameobject.h"
|
#include "frameobject.h"
|
||||||
#define __Pxy_PyFrame_Initialize_Offsets()\
|
#define __Pxy_PyFrame_Initialize_Offsets()\
|
||||||
@ -2053,6 +2116,7 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args,
|
|||||||
(void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus)))
|
(void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus)))
|
||||||
#define __Pyx_PyFrame_GetLocalsplus(frame)\
|
#define __Pyx_PyFrame_GetLocalsplus(frame)\
|
||||||
(assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset))
|
(assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset))
|
||||||
|
#endif // CYTHON_FAST_PYCALL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* PyCFunctionFastCall.proto */
|
/* PyCFunctionFastCall.proto */
|
||||||
@ -22260,6 +22324,9 @@ static PyTypeObject __pyx_type_6squish_6energy_AreaEnergy = {
|
|||||||
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
||||||
0, /*tp_print*/
|
0, /*tp_print*/
|
||||||
#endif
|
#endif
|
||||||
|
#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
|
||||||
|
0, /*tp_pypy_flags*/
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
static struct __pyx_vtabstruct_6squish_6energy_RadialALEnergy __pyx_vtable_6squish_6energy_RadialALEnergy;
|
static struct __pyx_vtabstruct_6squish_6energy_RadialALEnergy __pyx_vtable_6squish_6energy_RadialALEnergy;
|
||||||
|
|
||||||
@ -22381,6 +22448,9 @@ static PyTypeObject __pyx_type_6squish_6energy_RadialALEnergy = {
|
|||||||
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
||||||
0, /*tp_print*/
|
0, /*tp_print*/
|
||||||
#endif
|
#endif
|
||||||
|
#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
|
||||||
|
0, /*tp_pypy_flags*/
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
static struct __pyx_vtabstruct_6squish_6energy_RadialTEnergy __pyx_vtable_6squish_6energy_RadialTEnergy;
|
static struct __pyx_vtabstruct_6squish_6energy_RadialTEnergy __pyx_vtable_6squish_6energy_RadialTEnergy;
|
||||||
|
|
||||||
@ -22502,6 +22572,9 @@ static PyTypeObject __pyx_type_6squish_6energy_RadialTEnergy = {
|
|||||||
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
||||||
0, /*tp_print*/
|
0, /*tp_print*/
|
||||||
#endif
|
#endif
|
||||||
|
#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
|
||||||
|
0, /*tp_pypy_flags*/
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
static struct __pyx_vtabstruct_array __pyx_vtable_array;
|
static struct __pyx_vtabstruct_array __pyx_vtable_array;
|
||||||
|
|
||||||
@ -22691,6 +22764,9 @@ static PyTypeObject __pyx_type___pyx_array = {
|
|||||||
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
||||||
0, /*tp_print*/
|
0, /*tp_print*/
|
||||||
#endif
|
#endif
|
||||||
|
#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
|
||||||
|
0, /*tp_pypy_flags*/
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
|
static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
|
||||||
@ -22810,6 +22886,9 @@ static PyTypeObject __pyx_type___pyx_MemviewEnum = {
|
|||||||
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
||||||
0, /*tp_print*/
|
0, /*tp_print*/
|
||||||
#endif
|
#endif
|
||||||
|
#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
|
||||||
|
0, /*tp_pypy_flags*/
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview;
|
static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview;
|
||||||
|
|
||||||
@ -23071,6 +23150,9 @@ static PyTypeObject __pyx_type___pyx_memoryview = {
|
|||||||
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
||||||
0, /*tp_print*/
|
0, /*tp_print*/
|
||||||
#endif
|
#endif
|
||||||
|
#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
|
||||||
|
0, /*tp_pypy_flags*/
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice;
|
static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice;
|
||||||
|
|
||||||
@ -23217,6 +23299,9 @@ static PyTypeObject __pyx_type___pyx_memoryviewslice = {
|
|||||||
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
||||||
0, /*tp_print*/
|
0, /*tp_print*/
|
||||||
#endif
|
#endif
|
||||||
|
#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
|
||||||
|
0, /*tp_pypy_flags*/
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyMethodDef __pyx_methods[] = {
|
static PyMethodDef __pyx_methods[] = {
|
||||||
@ -27336,7 +27421,7 @@ static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int
|
|||||||
}
|
}
|
||||||
if (!use_cline) {
|
if (!use_cline) {
|
||||||
c_line = 0;
|
c_line = 0;
|
||||||
PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False);
|
(void) PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False);
|
||||||
}
|
}
|
||||||
else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) {
|
else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) {
|
||||||
c_line = 0;
|
c_line = 0;
|
||||||
@ -27433,30 +27518,31 @@ static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
|
|||||||
static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
|
static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
|
||||||
const char *funcname, int c_line,
|
const char *funcname, int c_line,
|
||||||
int py_line, const char *filename) {
|
int py_line, const char *filename) {
|
||||||
PyCodeObject *py_code = 0;
|
PyCodeObject *py_code = NULL;
|
||||||
PyObject *py_srcfile = 0;
|
PyObject *py_funcname = NULL;
|
||||||
PyObject *py_funcname = 0;
|
|
||||||
#if PY_MAJOR_VERSION < 3
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
PyObject *py_srcfile = NULL;
|
||||||
py_srcfile = PyString_FromString(filename);
|
py_srcfile = PyString_FromString(filename);
|
||||||
#else
|
|
||||||
py_srcfile = PyUnicode_FromString(filename);
|
|
||||||
#endif
|
|
||||||
if (!py_srcfile) goto bad;
|
if (!py_srcfile) goto bad;
|
||||||
|
#endif
|
||||||
if (c_line) {
|
if (c_line) {
|
||||||
#if PY_MAJOR_VERSION < 3
|
#if PY_MAJOR_VERSION < 3
|
||||||
py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
|
py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
|
||||||
|
if (!py_funcname) goto bad;
|
||||||
#else
|
#else
|
||||||
py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
|
py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
|
||||||
|
if (!py_funcname) goto bad;
|
||||||
|
funcname = PyUnicode_AsUTF8(py_funcname);
|
||||||
|
if (!funcname) goto bad;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if PY_MAJOR_VERSION < 3
|
#if PY_MAJOR_VERSION < 3
|
||||||
py_funcname = PyString_FromString(funcname);
|
py_funcname = PyString_FromString(funcname);
|
||||||
#else
|
if (!py_funcname) goto bad;
|
||||||
py_funcname = PyUnicode_FromString(funcname);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (!py_funcname) goto bad;
|
#if PY_MAJOR_VERSION < 3
|
||||||
py_code = __Pyx_PyCode_New(
|
py_code = __Pyx_PyCode_New(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@ -27475,11 +27561,16 @@ static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
|
|||||||
__pyx_empty_bytes /*PyObject *lnotab*/
|
__pyx_empty_bytes /*PyObject *lnotab*/
|
||||||
);
|
);
|
||||||
Py_DECREF(py_srcfile);
|
Py_DECREF(py_srcfile);
|
||||||
Py_DECREF(py_funcname);
|
#else
|
||||||
|
py_code = PyCode_NewEmpty(filename, funcname, py_line);
|
||||||
|
#endif
|
||||||
|
Py_XDECREF(py_funcname); // XDECREF since it's only set on Py3 if cline
|
||||||
return py_code;
|
return py_code;
|
||||||
bad:
|
bad:
|
||||||
Py_XDECREF(py_srcfile);
|
|
||||||
Py_XDECREF(py_funcname);
|
Py_XDECREF(py_funcname);
|
||||||
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
Py_XDECREF(py_srcfile);
|
||||||
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
static void __Pyx_AddTraceback(const char *funcname, int c_line,
|
static void __Pyx_AddTraceback(const char *funcname, int c_line,
|
||||||
@ -29569,6 +29660,23 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
|
|||||||
Py_DECREF(x);
|
Py_DECREF(x);
|
||||||
return ival;
|
return ival;
|
||||||
}
|
}
|
||||||
|
static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) {
|
||||||
|
if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) {
|
||||||
|
return (Py_hash_t) __Pyx_PyIndex_AsSsize_t(o);
|
||||||
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
} else if (likely(PyInt_CheckExact(o))) {
|
||||||
|
return PyInt_AS_LONG(o);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
Py_ssize_t ival;
|
||||||
|
PyObject *x;
|
||||||
|
x = PyNumber_Index(o);
|
||||||
|
if (!x) return -1;
|
||||||
|
ival = PyInt_AsLong(x);
|
||||||
|
Py_DECREF(x);
|
||||||
|
return ival;
|
||||||
|
}
|
||||||
|
}
|
||||||
static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) {
|
static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) {
|
||||||
return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False);
|
return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -59,11 +59,16 @@ class Simulation:
|
|||||||
|
|
||||||
def normalize(self) -> None:
|
def normalize(self) -> None:
|
||||||
new_frames = []
|
new_frames = []
|
||||||
|
first = True
|
||||||
for frame in self.frames:
|
for frame in self.frames:
|
||||||
aspect = frame.w / frame.h
|
aspect = frame.w / frame.h
|
||||||
|
|
||||||
new_domain = DomainParams(
|
new_domain = DomainParams(
|
||||||
frame.n, sqrt(frame.n * aspect), sqrt(frame.n / aspect), frame.r
|
frame.n, sqrt(frame.n * aspect), sqrt(frame.n / aspect), frame.r
|
||||||
)
|
)
|
||||||
|
if first:
|
||||||
|
self.domain = new_domain
|
||||||
|
first = False
|
||||||
|
|
||||||
new_points = frame.site_arr * np.array(
|
new_points = frame.site_arr * np.array(
|
||||||
[new_domain.w / frame.w, new_domain.h / frame.h]
|
[new_domain.w / frame.w, new_domain.h / frame.h]
|
||||||
|
|||||||
148
squish/voronoi.c
148
squish/voronoi.c
@ -1,4 +1,4 @@
|
|||||||
/* Generated by Cython 0.29.24 */
|
/* Generated by Cython 0.29.26 */
|
||||||
|
|
||||||
/* BEGIN: Cython Metadata
|
/* BEGIN: Cython Metadata
|
||||||
{
|
{
|
||||||
@ -34,8 +34,8 @@ END: Cython Metadata */
|
|||||||
#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)
|
#elif PY_VERSION_HEX < 0x02060000 || (0x03000000 <= PY_VERSION_HEX && PY_VERSION_HEX < 0x03030000)
|
||||||
#error Cython requires Python 2.6+ or Python 3.3+.
|
#error Cython requires Python 2.6+ or Python 3.3+.
|
||||||
#else
|
#else
|
||||||
#define CYTHON_ABI "0_29_24"
|
#define CYTHON_ABI "0_29_26"
|
||||||
#define CYTHON_HEX_VERSION 0x001D18F0
|
#define CYTHON_HEX_VERSION 0x001D1AF0
|
||||||
#define CYTHON_FUTURE_DIVISION 1
|
#define CYTHON_FUTURE_DIVISION 1
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#ifndef offsetof
|
#ifndef offsetof
|
||||||
@ -182,7 +182,7 @@ END: Cython Metadata */
|
|||||||
#ifndef CYTHON_USE_UNICODE_INTERNALS
|
#ifndef CYTHON_USE_UNICODE_INTERNALS
|
||||||
#define CYTHON_USE_UNICODE_INTERNALS 1
|
#define CYTHON_USE_UNICODE_INTERNALS 1
|
||||||
#endif
|
#endif
|
||||||
#if PY_VERSION_HEX < 0x030300F0
|
#if PY_VERSION_HEX < 0x030300F0 || PY_VERSION_HEX >= 0x030B00A2
|
||||||
#undef CYTHON_USE_UNICODE_WRITER
|
#undef CYTHON_USE_UNICODE_WRITER
|
||||||
#define CYTHON_USE_UNICODE_WRITER 0
|
#define CYTHON_USE_UNICODE_WRITER 0
|
||||||
#elif !defined(CYTHON_USE_UNICODE_WRITER)
|
#elif !defined(CYTHON_USE_UNICODE_WRITER)
|
||||||
@ -201,7 +201,7 @@ END: Cython Metadata */
|
|||||||
#define CYTHON_FAST_THREAD_STATE 1
|
#define CYTHON_FAST_THREAD_STATE 1
|
||||||
#endif
|
#endif
|
||||||
#ifndef CYTHON_FAST_PYCALL
|
#ifndef CYTHON_FAST_PYCALL
|
||||||
#define CYTHON_FAST_PYCALL 1
|
#define CYTHON_FAST_PYCALL (PY_VERSION_HEX < 0x030B00A1)
|
||||||
#endif
|
#endif
|
||||||
#ifndef CYTHON_PEP489_MULTI_PHASE_INIT
|
#ifndef CYTHON_PEP489_MULTI_PHASE_INIT
|
||||||
#define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000)
|
#define CYTHON_PEP489_MULTI_PHASE_INIT (PY_VERSION_HEX >= 0x03050000)
|
||||||
@ -220,7 +220,9 @@ END: Cython Metadata */
|
|||||||
#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1)
|
#define CYTHON_FAST_PYCCALL (CYTHON_FAST_PYCALL && PY_VERSION_HEX >= 0x030600B1)
|
||||||
#endif
|
#endif
|
||||||
#if CYTHON_USE_PYLONG_INTERNALS
|
#if CYTHON_USE_PYLONG_INTERNALS
|
||||||
#include "longintrepr.h"
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
#include "longintrepr.h"
|
||||||
|
#endif
|
||||||
#undef SHIFT
|
#undef SHIFT
|
||||||
#undef BASE
|
#undef BASE
|
||||||
#undef MASK
|
#undef MASK
|
||||||
@ -337,9 +339,68 @@ END: Cython Metadata */
|
|||||||
#define __Pyx_DefaultClassType PyClass_Type
|
#define __Pyx_DefaultClassType PyClass_Type
|
||||||
#else
|
#else
|
||||||
#define __Pyx_BUILTIN_MODULE_NAME "builtins"
|
#define __Pyx_BUILTIN_MODULE_NAME "builtins"
|
||||||
#if PY_VERSION_HEX >= 0x030800A4 && PY_VERSION_HEX < 0x030800B2
|
#define __Pyx_DefaultClassType PyType_Type
|
||||||
#define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\
|
#if PY_VERSION_HEX >= 0x030B00A1
|
||||||
PyCode_New(a, 0, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
|
static CYTHON_INLINE PyCodeObject* __Pyx_PyCode_New(int a, int k, int l, int s, int f,
|
||||||
|
PyObject *code, PyObject *c, PyObject* n, PyObject *v,
|
||||||
|
PyObject *fv, PyObject *cell, PyObject* fn,
|
||||||
|
PyObject *name, int fline, PyObject *lnos) {
|
||||||
|
PyObject *kwds=NULL, *argcount=NULL, *posonlyargcount=NULL, *kwonlyargcount=NULL;
|
||||||
|
PyObject *nlocals=NULL, *stacksize=NULL, *flags=NULL, *replace=NULL, *call_result=NULL, *empty=NULL;
|
||||||
|
const char *fn_cstr=NULL;
|
||||||
|
const char *name_cstr=NULL;
|
||||||
|
PyCodeObject* co=NULL;
|
||||||
|
PyObject *type, *value, *traceback;
|
||||||
|
PyErr_Fetch(&type, &value, &traceback);
|
||||||
|
if (!(kwds=PyDict_New())) goto end;
|
||||||
|
if (!(argcount=PyLong_FromLong(a))) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_argcount", argcount) != 0) goto end;
|
||||||
|
if (!(posonlyargcount=PyLong_FromLong(0))) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_posonlyargcount", posonlyargcount) != 0) goto end;
|
||||||
|
if (!(kwonlyargcount=PyLong_FromLong(k))) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_kwonlyargcount", kwonlyargcount) != 0) goto end;
|
||||||
|
if (!(nlocals=PyLong_FromLong(l))) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_nlocals", nlocals) != 0) goto end;
|
||||||
|
if (!(stacksize=PyLong_FromLong(s))) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_stacksize", stacksize) != 0) goto end;
|
||||||
|
if (!(flags=PyLong_FromLong(f))) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_flags", flags) != 0) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_code", code) != 0) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_consts", c) != 0) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_names", n) != 0) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_varnames", v) != 0) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_freevars", fv) != 0) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_cellvars", cell) != 0) goto end;
|
||||||
|
if (PyDict_SetItemString(kwds, "co_linetable", lnos) != 0) goto end;
|
||||||
|
if (!(fn_cstr=PyUnicode_AsUTF8AndSize(fn, NULL))) goto end;
|
||||||
|
if (!(name_cstr=PyUnicode_AsUTF8AndSize(name, NULL))) goto end;
|
||||||
|
if (!(co = PyCode_NewEmpty(fn_cstr, name_cstr, fline))) goto end;
|
||||||
|
if (!(replace = PyObject_GetAttrString((PyObject*)co, "replace"))) goto cleanup_code_too;
|
||||||
|
if (!(empty = PyTuple_New(0))) goto cleanup_code_too; // unfortunately __pyx_empty_tuple isn't available here
|
||||||
|
if (!(call_result = PyObject_Call(replace, empty, kwds))) goto cleanup_code_too;
|
||||||
|
Py_XDECREF((PyObject*)co);
|
||||||
|
co = (PyCodeObject*)call_result;
|
||||||
|
call_result = NULL;
|
||||||
|
if (0) {
|
||||||
|
cleanup_code_too:
|
||||||
|
Py_XDECREF((PyObject*)co);
|
||||||
|
co = NULL;
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
Py_XDECREF(kwds);
|
||||||
|
Py_XDECREF(argcount);
|
||||||
|
Py_XDECREF(posonlyargcount);
|
||||||
|
Py_XDECREF(kwonlyargcount);
|
||||||
|
Py_XDECREF(nlocals);
|
||||||
|
Py_XDECREF(stacksize);
|
||||||
|
Py_XDECREF(replace);
|
||||||
|
Py_XDECREF(call_result);
|
||||||
|
Py_XDECREF(empty);
|
||||||
|
if (type) {
|
||||||
|
PyErr_Restore(type, value, traceback);
|
||||||
|
}
|
||||||
|
return co;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
#define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\
|
#define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\
|
||||||
PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
|
PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
|
||||||
@ -577,10 +638,10 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) {
|
|||||||
#if PY_VERSION_HEX < 0x030200A4
|
#if PY_VERSION_HEX < 0x030200A4
|
||||||
typedef long Py_hash_t;
|
typedef long Py_hash_t;
|
||||||
#define __Pyx_PyInt_FromHash_t PyInt_FromLong
|
#define __Pyx_PyInt_FromHash_t PyInt_FromLong
|
||||||
#define __Pyx_PyInt_AsHash_t PyInt_AsLong
|
#define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsHash_t
|
||||||
#else
|
#else
|
||||||
#define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
|
#define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
|
||||||
#define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t
|
#define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsSsize_t
|
||||||
#endif
|
#endif
|
||||||
#if PY_MAJOR_VERSION >= 3
|
#if PY_MAJOR_VERSION >= 3
|
||||||
#define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func))
|
#define __Pyx_PyMethod_New(func, self, klass) ((self) ? ((void)(klass), PyMethod_New(func, self)) : __Pyx_NewRef(func))
|
||||||
@ -750,6 +811,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x);
|
|||||||
(likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj))
|
(likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj))
|
||||||
static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
|
static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
|
||||||
static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
|
static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
|
||||||
|
static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*);
|
||||||
#if CYTHON_ASSUME_SAFE_MACROS
|
#if CYTHON_ASSUME_SAFE_MACROS
|
||||||
#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
|
#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
|
||||||
#else
|
#else
|
||||||
@ -1998,6 +2060,7 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args,
|
|||||||
#ifndef Py_MEMBER_SIZE
|
#ifndef Py_MEMBER_SIZE
|
||||||
#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member)
|
#define Py_MEMBER_SIZE(type, member) sizeof(((type *)0)->member)
|
||||||
#endif
|
#endif
|
||||||
|
#if CYTHON_FAST_PYCALL
|
||||||
static size_t __pyx_pyframe_localsplus_offset = 0;
|
static size_t __pyx_pyframe_localsplus_offset = 0;
|
||||||
#include "frameobject.h"
|
#include "frameobject.h"
|
||||||
#define __Pxy_PyFrame_Initialize_Offsets()\
|
#define __Pxy_PyFrame_Initialize_Offsets()\
|
||||||
@ -2005,6 +2068,7 @@ static PyObject *__Pyx_PyFunction_FastCallDict(PyObject *func, PyObject **args,
|
|||||||
(void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus)))
|
(void)(__pyx_pyframe_localsplus_offset = ((size_t)PyFrame_Type.tp_basicsize) - Py_MEMBER_SIZE(PyFrameObject, f_localsplus)))
|
||||||
#define __Pyx_PyFrame_GetLocalsplus(frame)\
|
#define __Pyx_PyFrame_GetLocalsplus(frame)\
|
||||||
(assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset))
|
(assert(__pyx_pyframe_localsplus_offset), (PyObject **)(((char *)(frame)) + __pyx_pyframe_localsplus_offset))
|
||||||
|
#endif // CYTHON_FAST_PYCALL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* PyObjectCall.proto */
|
/* PyObjectCall.proto */
|
||||||
@ -26678,6 +26742,9 @@ static PyTypeObject __pyx_type_6squish_7voronoi_VoronoiContainer = {
|
|||||||
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
||||||
0, /*tp_print*/
|
0, /*tp_print*/
|
||||||
#endif
|
#endif
|
||||||
|
#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
|
||||||
|
0, /*tp_pypy_flags*/
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
static struct __pyx_vtabstruct_array __pyx_vtable_array;
|
static struct __pyx_vtabstruct_array __pyx_vtable_array;
|
||||||
|
|
||||||
@ -26867,6 +26934,9 @@ static PyTypeObject __pyx_type___pyx_array = {
|
|||||||
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
||||||
0, /*tp_print*/
|
0, /*tp_print*/
|
||||||
#endif
|
#endif
|
||||||
|
#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
|
||||||
|
0, /*tp_pypy_flags*/
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
|
static PyObject *__pyx_tp_new_Enum(PyTypeObject *t, CYTHON_UNUSED PyObject *a, CYTHON_UNUSED PyObject *k) {
|
||||||
@ -26986,6 +27056,9 @@ static PyTypeObject __pyx_type___pyx_MemviewEnum = {
|
|||||||
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
||||||
0, /*tp_print*/
|
0, /*tp_print*/
|
||||||
#endif
|
#endif
|
||||||
|
#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
|
||||||
|
0, /*tp_pypy_flags*/
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview;
|
static struct __pyx_vtabstruct_memoryview __pyx_vtable_memoryview;
|
||||||
|
|
||||||
@ -27247,6 +27320,9 @@ static PyTypeObject __pyx_type___pyx_memoryview = {
|
|||||||
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
||||||
0, /*tp_print*/
|
0, /*tp_print*/
|
||||||
#endif
|
#endif
|
||||||
|
#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
|
||||||
|
0, /*tp_pypy_flags*/
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice;
|
static struct __pyx_vtabstruct__memoryviewslice __pyx_vtable__memoryviewslice;
|
||||||
|
|
||||||
@ -27393,6 +27469,9 @@ static PyTypeObject __pyx_type___pyx_memoryviewslice = {
|
|||||||
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
#if PY_VERSION_HEX >= 0x030800b4 && PY_VERSION_HEX < 0x03090000
|
||||||
0, /*tp_print*/
|
0, /*tp_print*/
|
||||||
#endif
|
#endif
|
||||||
|
#if CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM+0 >= 0x06000000
|
||||||
|
0, /*tp_pypy_flags*/
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyMethodDef __pyx_methods[] = {
|
static PyMethodDef __pyx_methods[] = {
|
||||||
@ -31881,7 +31960,7 @@ static int __Pyx_CLineForTraceback(CYTHON_NCP_UNUSED PyThreadState *tstate, int
|
|||||||
}
|
}
|
||||||
if (!use_cline) {
|
if (!use_cline) {
|
||||||
c_line = 0;
|
c_line = 0;
|
||||||
PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False);
|
(void) PyObject_SetAttr(__pyx_cython_runtime, __pyx_n_s_cline_in_traceback, Py_False);
|
||||||
}
|
}
|
||||||
else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) {
|
else if (use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) {
|
||||||
c_line = 0;
|
c_line = 0;
|
||||||
@ -31978,30 +32057,31 @@ static void __pyx_insert_code_object(int code_line, PyCodeObject* code_object) {
|
|||||||
static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
|
static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
|
||||||
const char *funcname, int c_line,
|
const char *funcname, int c_line,
|
||||||
int py_line, const char *filename) {
|
int py_line, const char *filename) {
|
||||||
PyCodeObject *py_code = 0;
|
PyCodeObject *py_code = NULL;
|
||||||
PyObject *py_srcfile = 0;
|
PyObject *py_funcname = NULL;
|
||||||
PyObject *py_funcname = 0;
|
|
||||||
#if PY_MAJOR_VERSION < 3
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
PyObject *py_srcfile = NULL;
|
||||||
py_srcfile = PyString_FromString(filename);
|
py_srcfile = PyString_FromString(filename);
|
||||||
#else
|
|
||||||
py_srcfile = PyUnicode_FromString(filename);
|
|
||||||
#endif
|
|
||||||
if (!py_srcfile) goto bad;
|
if (!py_srcfile) goto bad;
|
||||||
|
#endif
|
||||||
if (c_line) {
|
if (c_line) {
|
||||||
#if PY_MAJOR_VERSION < 3
|
#if PY_MAJOR_VERSION < 3
|
||||||
py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
|
py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
|
||||||
|
if (!py_funcname) goto bad;
|
||||||
#else
|
#else
|
||||||
py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
|
py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line);
|
||||||
|
if (!py_funcname) goto bad;
|
||||||
|
funcname = PyUnicode_AsUTF8(py_funcname);
|
||||||
|
if (!funcname) goto bad;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if PY_MAJOR_VERSION < 3
|
#if PY_MAJOR_VERSION < 3
|
||||||
py_funcname = PyString_FromString(funcname);
|
py_funcname = PyString_FromString(funcname);
|
||||||
#else
|
if (!py_funcname) goto bad;
|
||||||
py_funcname = PyUnicode_FromString(funcname);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (!py_funcname) goto bad;
|
#if PY_MAJOR_VERSION < 3
|
||||||
py_code = __Pyx_PyCode_New(
|
py_code = __Pyx_PyCode_New(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
@ -32020,11 +32100,16 @@ static PyCodeObject* __Pyx_CreateCodeObjectForTraceback(
|
|||||||
__pyx_empty_bytes /*PyObject *lnotab*/
|
__pyx_empty_bytes /*PyObject *lnotab*/
|
||||||
);
|
);
|
||||||
Py_DECREF(py_srcfile);
|
Py_DECREF(py_srcfile);
|
||||||
Py_DECREF(py_funcname);
|
#else
|
||||||
|
py_code = PyCode_NewEmpty(filename, funcname, py_line);
|
||||||
|
#endif
|
||||||
|
Py_XDECREF(py_funcname); // XDECREF since it's only set on Py3 if cline
|
||||||
return py_code;
|
return py_code;
|
||||||
bad:
|
bad:
|
||||||
Py_XDECREF(py_srcfile);
|
|
||||||
Py_XDECREF(py_funcname);
|
Py_XDECREF(py_funcname);
|
||||||
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
Py_XDECREF(py_srcfile);
|
||||||
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
static void __Pyx_AddTraceback(const char *funcname, int c_line,
|
static void __Pyx_AddTraceback(const char *funcname, int c_line,
|
||||||
@ -34343,6 +34428,23 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
|
|||||||
Py_DECREF(x);
|
Py_DECREF(x);
|
||||||
return ival;
|
return ival;
|
||||||
}
|
}
|
||||||
|
static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) {
|
||||||
|
if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) {
|
||||||
|
return (Py_hash_t) __Pyx_PyIndex_AsSsize_t(o);
|
||||||
|
#if PY_MAJOR_VERSION < 3
|
||||||
|
} else if (likely(PyInt_CheckExact(o))) {
|
||||||
|
return PyInt_AS_LONG(o);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
Py_ssize_t ival;
|
||||||
|
PyObject *x;
|
||||||
|
x = PyNumber_Index(o);
|
||||||
|
if (!x) return -1;
|
||||||
|
ival = PyInt_AsLong(x);
|
||||||
|
Py_DECREF(x);
|
||||||
|
return ival;
|
||||||
|
}
|
||||||
|
}
|
||||||
static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) {
|
static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) {
|
||||||
return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False);
|
return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user