From 3841e6fe6b245b0c8e7a82af05daceab8cce52b9 Mon Sep 17 00:00:00 2001 From: Kenneth Jao Date: Fri, 24 Sep 2021 05:02:07 -0400 Subject: [PATCH] Small fixes for diagrams and simulations --- .gitignore | 3 +-- src/squish/common.py | 2 +- src/squish/diagram.py | 58 +++++++++++++++++++++++----------------- src/squish/simulation.py | 13 +++++---- src/squish/squish.py | 2 +- 5 files changed, 45 insertions(+), 33 deletions(-) diff --git a/.gitignore b/.gitignore index 347b18e..8c88623 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,4 @@ src/packsim.c *.so *.json -figures/ -simulations/ +squish_output/ diff --git a/src/squish/common.py b/src/squish/common.py index 226bb70..8462776 100644 --- a/src/squish/common.py +++ b/src/squish/common.py @@ -142,7 +142,7 @@ class Simulation: def add_frame(self, points: Optional[numpy.ndarray]) -> None: if points is None: - points = np.random.random_sample((self.domain.n, 2)) + points = np.random.random_sample((self.domain.n, 2)) * self.domain.dim else: if points.shape[1] != 2 or len(points.shape) > 2: raise ValueError("Sites should be 2 dimensional!") diff --git a/src/squish/diagram.py b/src/squish/diagram.py index 803a6b9..71d5d95 100644 --- a/src/squish/diagram.py +++ b/src/squish/diagram.py @@ -8,7 +8,7 @@ from multiprocessing import Pool, cpu_count from .common import DomainParams -SYMM = np.array([[1,0], [1,1], [0,1], [-1,1], [-1,0], [-1,-1], [0,-1], [1,-1]]) +SYMM = np.array([[0,0], [1,0], [1,1], [0,1], [-1,1], [-1,0], [-1,-1], [0,-1], [1,-1]]) class SimData: """Stores diagram information for a simulation. @@ -54,7 +54,7 @@ class SimData: Tuple[numpy.ndarray, numpy.ndarray]: the histogram and its bins. """ - if cumulative: + if cumul: values = np.concatenate([f[stat] for f in self.stats[:(i+1)]]) else: values = self.stats[i][stat] @@ -70,7 +70,7 @@ class SimData: hist, bin_edges = np.histogram(values, bins=bins, range=bounds) bin_list = np.array([(bin_edges[i] + bin_edges[i+1])/2 for i in range(len(bin_edges)-1)]) - if avg and cumulative: + if avg and cumul: return hist / (i+1), bin_list return hist, bin_list @@ -122,7 +122,7 @@ class Diagram: def voronoi_plot(self, i: int, ax: AxesSubplot) -> None: domain = self.sim.domains[i] - n,w,h = domain.n, domain.w, domain.h + n, w, h = domain.n, domain.w, domain.h scale = 1.5 area = n <= 60 @@ -138,14 +138,27 @@ class Diagram: props = dict(boxstyle='round', facecolor='wheat', alpha=0.8) - if area: - global SYMM - for j in range(n): - for s in np.concatenate(([[0,0]], SYMM)): - txt = ax.text(*(self.sim.voronois[i].points[j] + s*self.sim.domains[i].dim), - str(round(self.sim.stats[i]["site_areas"][j], 3))) + defects = {5: {"x": [], "y": []}, 7: {"x": [], "y": []}} + + for j in range(n): + for s in SYMM: + vec = (self.sim.voronois[i].points[j] + s*self.sim.domains[i].dim) + + if area: + txt = ax.text(*vec, str(round(self.sim.stats[i]["site_areas"][j], 3))) txt.set_clip_on(True) + if self.sim.stats[i]["site_edge_count"][j] == 5: + defects[5]["x"].append(vec[0]) + defects[5]["y"].append(vec[1]) + elif self.sim.stats[i]["site_edge_count"][j] == 7: + defects[7]["x"].append(vec[0]) + defects[7]["y"].append(vec[1]) + + ax.scatter(defects[5]["x"], defects[5]["y"], marker="p", color="red") + ax.scatter(defects[7]["x"], defects[7]["y"], marker="*", color="red") + + ax.text(0.05, 0.95, f'Energy: {self.sim.energies[i]}', transform=ax.transAxes, fontsize=14, verticalalignment='top', bbox=props) @@ -208,7 +221,7 @@ class Diagram: def site_energies_plot(self, i: int, ax: AxesSubplot) -> None: - y, x = self.sim.hist("site_energies", i, self.cumulative, avg=True) + y, x = self.sim.hist("site_energies", i, cumul=self.cumulative, avg=True) ax.bar(x, y, width=0.8*(x[1]-x[0])) ax.title.set_text('Site Energies') @@ -220,7 +233,7 @@ class Diagram: def avg_radius_plot(self, i: int, ax: AxesSubplot) -> None: - y, x = self.sim.hist("avg_radius", i, self.cumulative, avg=True) + y, x = self.sim.hist("avg_radius", i, cumul=self.cumulative, avg=True) ax.bar(x, y, width=0.8*(x[1]-x[0])) ax.title.set_text('Site Average Radii') @@ -232,7 +245,7 @@ class Diagram: def isoparam_avg_plot(self, i: int, ax: AxesSubplot) -> None: - y, x = self.sim.hist("isoparam_avg", i, self.cumulative, avg=True) + y, x = self.sim.hist("isoparam_avg", i, cumul=self.cumulative, avg=True) ax.bar(x,y, width=0.8*(x[1]-x[0])) ax.title.set_text('Site Isoperimetric Averages') @@ -261,9 +274,13 @@ class Diagram: def eigs_plot(self, i: int, ax: AxesSubplot) -> None: - eigs = self.sim.stats[i]["eigs"] - ax.plot(list(range(len(eigs))), eigs, marker='o', linestyle='dashed', color='C0') - ax.plot([0,len(eigs)], [0, 0], color="red") + try: + eigs = self.sim.stats[i]["eigs"] + ax.plot(list(range(len(eigs))), eigs, marker='o', linestyle='dashed', color='C0') + ax.plot([0,len(eigs)], [0, 0], color="red") + except KeyError: + ax.text(0.5, 0.5, "Not Computed") + ax.title.set_text('Hessian Eigenvalues') ax.set_xlabel("") ax.set_ylabel("Value") @@ -272,7 +289,6 @@ class Diagram: def render_frames(self, frames: List[int], fol: str = 'frames') -> None: (self.sim.path / fol).mkdir(exist_ok=True) combo_list = [] - print(cpu_count()) for i in range(cpu_count()): combo_list.append((self, frames[:int((i+1)*len(frames)/cpu_count())], fol, len(frames))) @@ -281,14 +297,8 @@ class Diagram: for _ in pool.imap_unordered(render_frame_range, combo_list): pass - # for i, frame in enumerate(frames): - # self.generate_frame(frame, "save", fol) - # hashes = int(21*i/len(frames)) - # print(f'Generating frames... |{"#"*hashes}{" "*(20-hashes)}|' + \ - # f' {i+1}/{len(frames)} frames rendered.', flush=True, end='\r') - print(flush=True) - + print(f'Wrote to \"{self.sim.path / fol}\".', flush=True) def render_video(self, time: int, mode: str) -> None: if mode not in ["use_all", "sample"]: diff --git a/src/squish/simulation.py b/src/squish/simulation.py index dbcd5d1..04acc67 100644 --- a/src/squish/simulation.py +++ b/src/squish/simulation.py @@ -198,7 +198,7 @@ class Shrink(Simulation): name: Optional[str] = None) -> None: super().__init__(domain, energy, name=name) self.step_size, self.thres, self.accel = step_size, thres, accel - self.delta, self.stop_width = self.domain.w*delta, self.domain.w*stop_width + self.delta, self.stop_width = self.domain.w*delta/100, self.domain.w*stop_width @property @@ -208,8 +208,8 @@ class Shrink(Simulation): "step_size": self.step_size, "thres": self.thres, "accel": self.accel, - "kernel_step": self.kernel_step, - "count": self.count + "delta": self.delta, + "stop_width": self.stop_width } return info @@ -225,9 +225,11 @@ class Shrink(Simulation): new_sites = None width = self.domain.w + i = 0 while width >= self.stop_width: # Get to equilibrium. - sim = Flow(self.domain, self.energy, self.thres, self.step_size, self.accel) + new_domain = DomainParams(self.domain.n, width, self.domain.h, self.domain.r) + sim = Flow(new_domain, self.energy, self.thres, self.step_size, self.accel) sim.add_frame(new_sites) sim.run(False, log, log_steps) new_sites = sim[-1].site_arr @@ -235,6 +237,7 @@ class Shrink(Simulation): self.frames.append(sim[-1]) if save: self.save(self.frame_data(i)) - if log: print(f'Width: {self.w:.4f}\n') + if log: print(f'Width: {width:.4f}\n') width -= self.delta + i += 1 diff --git a/src/squish/squish.py b/src/squish/squish.py index 20eb145..dd41ef8 100644 --- a/src/squish/squish.py +++ b/src/squish/squish.py @@ -148,7 +148,7 @@ def config_sim(args): if save_diagram: diagram = Diagram(sim, dia_params["figures"]) if dia_params["filetype"] == "img": - diagram.render_frames() + diagram.render_frames(range(len(sim))) elif dia_params["filetype"] == "mp4": if mode == "flow": diagram.render_video(dia_params["time"], "sample")