Added continuation for stopped simulation
This commit is contained in:
parent
0d65aa5366
commit
b4d6b5dbd8
@ -1,23 +0,0 @@
|
|||||||
from pathlib import Path
|
|
||||||
import numpy as np, pickle, sys
|
|
||||||
|
|
||||||
from squish import Simulation
|
|
||||||
|
|
||||||
def main():
|
|
||||||
n = int(sys.argv[1])
|
|
||||||
all_widths = set(np.round(np.arange(3, 10.05, 0.05), 2))
|
|
||||||
for file in Path(f"squish_output/Radial[T]Search - N{n} - 500").iterdir():
|
|
||||||
sim, frames = Simulation.load(file / 'data.squish')
|
|
||||||
|
|
||||||
if sim.domain.n == n:
|
|
||||||
try:
|
|
||||||
all_widths.remove(next(frames)["domain"][1])
|
|
||||||
except StopIteration:
|
|
||||||
pass
|
|
||||||
|
|
||||||
remain_widths = sorted(list(all_widths))[::-1]
|
|
||||||
print("Remaining:", remain_widths)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
[metadata]
|
[metadata]
|
||||||
name = squish
|
name = squish
|
||||||
version = 0.1.3
|
version = 0.1.4
|
||||||
author = Kenneth Jao
|
author = Kenneth Jao
|
||||||
author_email = ksjdragon@gmail.com
|
author_email = ksjdragon@gmail.com
|
||||||
description = squish is Python program which perform simulations for the flow of 'soft' or 'compressible' objects under some energy in a periodic domain.
|
description = squish is Python program which perform simulations for the flow of 'soft' or 'compressible' objects under some energy in a periodic domain.
|
||||||
|
|||||||
@ -6,7 +6,6 @@ from pathlib import Path
|
|||||||
from ._squish import VoronoiContainer, AreaEnergy, RadialALEnergy, RadialTEnergy
|
from ._squish import VoronoiContainer, AreaEnergy, RadialALEnergy, RadialTEnergy
|
||||||
|
|
||||||
OUTPUT_DIR = Path("squish_output")
|
OUTPUT_DIR = Path("squish_output")
|
||||||
OUTPUT_DIR.mkdir(exist_ok=True)
|
|
||||||
|
|
||||||
STR_TO_ENERGY = {
|
STR_TO_ENERGY = {
|
||||||
"area": AreaEnergy,
|
"area": AreaEnergy,
|
||||||
@ -17,7 +16,7 @@ STR_TO_ENERGY = {
|
|||||||
|
|
||||||
def generate_filepath(sim: SimulationMode, fol: Union[str, Path], prec: int = 2) -> Path:
|
def generate_filepath(sim: SimulationMode, fol: Union[str, Path], prec: int = 2) -> Path:
|
||||||
energy = sim.energy.title_str
|
energy = sim.energy.title_str
|
||||||
width, height = round(sim.domain.w, 2), round(sim.domain.h, 2)
|
width, height = round(sim.domain.w, prec), round(sim.domain.h, prec)
|
||||||
|
|
||||||
base_path = f"{fol}/{energy}{sim.title_str} - " + \
|
base_path = f"{fol}/{energy}{sim.title_str} - " + \
|
||||||
f"N{sim.domain.n} - {width:.{prec}f}x{height:.{prec}f}"
|
f"N{sim.domain.n} - {width:.{prec}f}x{height:.{prec}f}"
|
||||||
|
|||||||
@ -6,7 +6,7 @@ from matplotlib.ticker import MaxNLocator, FormatStrFormatter
|
|||||||
from scipy.spatial import Voronoi, voronoi_plot_2d
|
from scipy.spatial import Voronoi, voronoi_plot_2d
|
||||||
from multiprocessing import Pool, cpu_count
|
from multiprocessing import Pool, cpu_count
|
||||||
|
|
||||||
from .common import DomainParams
|
from .common import DomainParams, OUTPUT_DIR
|
||||||
|
|
||||||
SYMM = np.array([[0,0], [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]])
|
||||||
|
|
||||||
@ -302,6 +302,8 @@ class Diagram:
|
|||||||
|
|
||||||
|
|
||||||
def render_frames(self, frames: List[int], fol: str = 'frames') -> None:
|
def render_frames(self, frames: List[int], fol: str = 'frames') -> None:
|
||||||
|
OUTPUT_DIR.mkdir(exist_ok=True)
|
||||||
|
self.sim.path.mkdir(exist_ok=True)
|
||||||
(self.sim.path / fol).mkdir(exist_ok=True)
|
(self.sim.path / fol).mkdir(exist_ok=True)
|
||||||
combo_list = []
|
combo_list = []
|
||||||
for i in range(cpu_count()):
|
for i in range(cpu_count()):
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import pickle, numpy as np
|
|||||||
from math import log10
|
from math import log10
|
||||||
from scipy.linalg import null_space
|
from scipy.linalg import null_space
|
||||||
from timeit import default_timer as timer
|
from timeit import default_timer as timer
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from .common import DomainParams, Energy, generate_filepath, OUTPUT_DIR
|
from .common import DomainParams, Energy, generate_filepath, OUTPUT_DIR
|
||||||
|
|
||||||
@ -46,7 +47,7 @@ class Simulation:
|
|||||||
return len(self.frames)
|
return len(self.frames)
|
||||||
|
|
||||||
|
|
||||||
def add_frame(self, points: Optional[numpy.ndarray]) -> None:
|
def add_frame(self, points: Optional[numpy.ndarray] = None) -> None:
|
||||||
if points is None:
|
if points is None:
|
||||||
points = np.random.random_sample((self.domain.n, 2)) * self.domain.dim
|
points = np.random.random_sample((self.domain.n, 2)) * self.domain.dim
|
||||||
else:
|
else:
|
||||||
@ -91,6 +92,7 @@ class Simulation:
|
|||||||
|
|
||||||
|
|
||||||
def save(self, info: Dict, overwrite: bool = False) -> None:
|
def save(self, info: Dict, overwrite: bool = False) -> None:
|
||||||
|
OUTPUT_DIR.mkdir(exist_ok=True)
|
||||||
self.path.mkdir(exist_ok=True)
|
self.path.mkdir(exist_ok=True)
|
||||||
path = self.path / 'data.squish'
|
path = self.path / 'data.squish'
|
||||||
|
|
||||||
@ -117,8 +119,9 @@ class Simulation:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def load(path: str) -> Tuple[Simulation, Generator]:
|
def load(path: str) -> Tuple[Simulation, Generator]:
|
||||||
|
path = Path(path)
|
||||||
def frames() -> Dict:
|
def frames() -> Dict:
|
||||||
with open(path, 'rb') as infile:
|
with open(path / 'data.squish', 'rb') as infile:
|
||||||
first = True
|
first = True
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
@ -130,16 +133,26 @@ class Simulation:
|
|||||||
except EOFError:
|
except EOFError:
|
||||||
break
|
break
|
||||||
|
|
||||||
with open(path, 'rb') as infile:
|
with open(path / 'data.squish', 'rb') as infile:
|
||||||
sim_info = pickle.load(infile)
|
sim_info = pickle.load(infile)
|
||||||
|
|
||||||
domain = DomainParams(*sim_info["domain"])
|
domain = DomainParams(*sim_info["domain"])
|
||||||
energy = Energy(sim_info["energy"])
|
energy = Energy(sim_info["energy"])
|
||||||
sim = STR_TO_SIM[sim_info["mode"]](domain, energy, *list(sim_info.values())[3:])
|
sim = STR_TO_SIM[sim_info["mode"]](domain, energy, *list(sim_info.values())[3:])
|
||||||
|
sim.path = path
|
||||||
|
|
||||||
return sim, frames()
|
return sim, frames()
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_file(path: str) -> Simulation:
|
||||||
|
sim, frames = Simulation.load(path)
|
||||||
|
for frame in frames:
|
||||||
|
sim.frames.append(sim.energy.mode(*frame["domain"], frame["arr"]))
|
||||||
|
|
||||||
|
return sim
|
||||||
|
|
||||||
|
|
||||||
class Flow(Simulation):
|
class Flow(Simulation):
|
||||||
"""Finds an equilibrium from initial sites.
|
"""Finds an equilibrium from initial sites.
|
||||||
|
|
||||||
@ -177,12 +190,13 @@ class Flow(Simulation):
|
|||||||
return info
|
return info
|
||||||
|
|
||||||
|
|
||||||
def run(self, save: bool, log: bool, log_steps: int) -> None:
|
def run(self, save: bool, log: bool, log_steps: int,
|
||||||
|
new_sites: Optional[numpy.ndarray] = None) -> None:
|
||||||
if log: print(f"Find - {self.domain}", flush=True)
|
if log: print(f"Find - {self.domain}", flush=True)
|
||||||
if save: self.save(self.initial_data, True)
|
if save and len(self) == 0: self.save(self.initial_data, True)
|
||||||
if len(self) == 0: self.add_frame()
|
if len(self) == 0: self.add_frame(new_sites)
|
||||||
|
|
||||||
i, stop = 0, False
|
i, stop = len(self)-1, False
|
||||||
|
|
||||||
while not stop: # Get to threshold.
|
while not stop: # Get to threshold.
|
||||||
if save:
|
if save:
|
||||||
@ -262,17 +276,12 @@ class Search(Simulation):
|
|||||||
return info
|
return info
|
||||||
|
|
||||||
|
|
||||||
def run(self, save: bool, log: bool, log_steps: int) -> None:
|
def run(self, save: bool, log: bool, log_steps: int,
|
||||||
|
new_sites: Optional[numpy.ndarray] = None) -> None:
|
||||||
if log: print(f'Travel - {self.domain}', flush=True)
|
if log: print(f'Travel - {self.domain}', flush=True)
|
||||||
if save: self.save(self.initial_data, True)
|
if save and len(self) == 0: self.save(self.initial_data, True)
|
||||||
|
|
||||||
if len(self) != 0:
|
for i in range(len(self), self.count):
|
||||||
new_sites = self[0].site_arr
|
|
||||||
self.frames = []
|
|
||||||
else:
|
|
||||||
new_sites = None
|
|
||||||
|
|
||||||
for i in range(self.count):
|
|
||||||
# Get to equilibrium.
|
# Get to equilibrium.
|
||||||
sim = Flow(self.domain, self.energy, self.step_size, self.thres, self.adaptive)
|
sim = Flow(self.domain, self.energy, self.step_size, self.thres, self.adaptive)
|
||||||
sim.add_frame(new_sites)
|
sim.add_frame(new_sites)
|
||||||
@ -298,7 +307,6 @@ class Search(Simulation):
|
|||||||
new_sites = self.frames[i].add_sites(self.kernel_step*vec)
|
new_sites = self.frames[i].add_sites(self.kernel_step*vec)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Shrink(Simulation):
|
class Shrink(Simulation):
|
||||||
"""Shrinks width and finds nearest equilibrium.
|
"""Shrinks width and finds nearest equilibrium.
|
||||||
|
|
||||||
@ -343,17 +351,12 @@ class Shrink(Simulation):
|
|||||||
return info
|
return info
|
||||||
|
|
||||||
|
|
||||||
def run(self, save: bool, log: bool, log_steps: int) -> None:
|
def run(self, save: bool, log: bool, log_steps: int,
|
||||||
|
new_sites: Optional[numpy.ndarray] = None) -> None:
|
||||||
if log: print(f'Shrink - {self.domain}', flush=True)
|
if log: print(f'Shrink - {self.domain}', flush=True)
|
||||||
if save: self.save(self.initial_data, True)
|
if save and len(self) == 0: self.save(self.initial_data, True)
|
||||||
|
|
||||||
if len(self) != 0:
|
width = self.domain.w if len(self.frames) == 0 else self.frames[-1].w
|
||||||
new_sites = self[0].site_arr
|
|
||||||
self.frames = []
|
|
||||||
else:
|
|
||||||
new_sites = None
|
|
||||||
|
|
||||||
width = self.domain.w
|
|
||||||
i = 0
|
i = 0
|
||||||
while width >= self.stop_width:
|
while width >= self.stop_width:
|
||||||
# Get to equilibrium.
|
# Get to equilibrium.
|
||||||
@ -371,6 +374,7 @@ class Shrink(Simulation):
|
|||||||
width -= self.delta
|
width -= self.delta
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
|
|
||||||
STR_TO_SIM = {
|
STR_TO_SIM = {
|
||||||
"flow": Flow,
|
"flow": Flow,
|
||||||
"search": Search,
|
"search": Search,
|
||||||
|
|||||||
@ -5,7 +5,7 @@ from shutil import which
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from .common import DomainParams, Energy
|
from .common import DomainParams, Energy
|
||||||
from .simulation import Flow, Search, Shrink
|
from .simulation import Simulation, Flow, Search, Shrink
|
||||||
from .diagram import Diagram
|
from .diagram import Diagram
|
||||||
|
|
||||||
dia_presets = {
|
dia_presets = {
|
||||||
@ -45,13 +45,15 @@ def check_params(container: Dict, needed: List[str], valid: Dict) -> None:
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
# Loading configuration and settings.
|
# Loading configuration and settings.
|
||||||
parser = argparse.ArgumentParser("PackSim")
|
parser = argparse.ArgumentParser("Squish")
|
||||||
parser.add_argument('sim_conf', metavar='/path/to/config.json',
|
parser.add_argument('sim_conf', metavar='/path/to/config.json',
|
||||||
help="configuration file for a simulation")
|
help="configuration file for a simulation")
|
||||||
parser.add_argument('-q', '--quiet', dest='quiet', action='store_true', default=False,
|
parser.add_argument('-q', '--quiet', dest='quiet', action='store_true', default=False,
|
||||||
help="suppress all normal output")
|
help="suppress all normal output")
|
||||||
parser.add_argument('-l', '--log', dest='log_steps', default=50, type=int,
|
parser.add_argument('-l', '--log', dest='log_steps', default=50, type=int,
|
||||||
help="number of iterations before logging")
|
help="number of iterations before logging")
|
||||||
|
parser.add_argument('-i', dest='input_file', metavar='/path/to/sim',
|
||||||
|
help="folder that contains outputted simulation files.", default=None)
|
||||||
|
|
||||||
parser.add_argument('--n_objects', dest='n', type=int, help="objects in domain")
|
parser.add_argument('--n_objects', dest='n', type=int, help="objects in domain")
|
||||||
parser.add_argument('--width', dest='w', type=float, help="width of domain")
|
parser.add_argument('--width', dest='w', type=float, help="width of domain")
|
||||||
@ -60,17 +62,14 @@ def main():
|
|||||||
parser.add_argument('--energy', dest='energy', help="energy type of system")
|
parser.add_argument('--energy', dest='energy', help="energy type of system")
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
config_sim(args)
|
do_sim(args, args.input_file)
|
||||||
# if args.input_file is None:
|
|
||||||
# config_sim(args)
|
|
||||||
# else:
|
|
||||||
# loaded_sim(args)
|
|
||||||
|
|
||||||
|
|
||||||
def config_sim(args):
|
def do_sim(args, file):
|
||||||
with open(args.sim_conf) as f:
|
with open(args.sim_conf) as f:
|
||||||
params = json.load(f)
|
params = json.load(f)
|
||||||
|
|
||||||
|
|
||||||
check_params(params, ["domain", "simulation"], {})
|
check_params(params, ["domain", "simulation"], {})
|
||||||
dmn_params, sim_params = params["domain"], params["simulation"]
|
dmn_params, sim_params = params["domain"], params["simulation"]
|
||||||
|
|
||||||
@ -105,6 +104,7 @@ def config_sim(args):
|
|||||||
|
|
||||||
name = sim_params.get("name")
|
name = sim_params.get("name")
|
||||||
|
|
||||||
|
if file is None:
|
||||||
if mode == "flow":
|
if mode == "flow":
|
||||||
sim = Flow(domain, energy, step, thres, adaptive, name=name)
|
sim = Flow(domain, energy, step, thres, adaptive, name=name)
|
||||||
elif mode == "search":
|
elif mode == "search":
|
||||||
@ -119,6 +119,8 @@ def config_sim(args):
|
|||||||
})
|
})
|
||||||
sim = Shrink(domain, energy, step, thres, adaptive, sim_params["width_change"],
|
sim = Shrink(domain, energy, step, thres, adaptive, sim_params["width_change"],
|
||||||
sim_params["width_stop"], name=name)
|
sim_params["width_stop"], name=name)
|
||||||
|
else:
|
||||||
|
sim = Simulation.from_file(file)
|
||||||
|
|
||||||
save_diagram = False
|
save_diagram = False
|
||||||
if "diagram" in params:
|
if "diagram" in params:
|
||||||
@ -139,8 +141,7 @@ def config_sim(args):
|
|||||||
if "time" not in dia_params:
|
if "time" not in dia_params:
|
||||||
dia_params["time"] = 30
|
dia_params["time"] = 30
|
||||||
|
|
||||||
sim.add_frame(points)
|
sim.run(save_sim, not args.quiet, args.log_steps, points)
|
||||||
sim.run(save_sim, not args.quiet, args.log_steps)
|
|
||||||
|
|
||||||
if save_diagram:
|
if save_diagram:
|
||||||
diagram = Diagram(sim, dia_params["figures"])
|
diagram = Diagram(sim, dia_params["figures"])
|
||||||
@ -153,9 +154,6 @@ def config_sim(args):
|
|||||||
diagram.render_video(dia_params["time"], "use_all")
|
diagram.render_video(dia_params["time"], "use_all")
|
||||||
|
|
||||||
|
|
||||||
def loaded_sim(args):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def pre():
|
def pre():
|
||||||
os.environ["QT_LOGGING_RULES"] = "*=false"
|
os.environ["QT_LOGGING_RULES"] = "*=false"
|
||||||
try:
|
try:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user