Added calculations for ordered sites
This commit is contained in:
parent
d748b25040
commit
d31029d95d
@ -1,6 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from typing import List, Union, Optional, Iterator, Generator
|
from typing import List, Tuple, Union, Optional, Iterator, Generator
|
||||||
import pickle, numpy as np
|
import pickle, numpy as np
|
||||||
|
from math import gcd
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from ._squish import AreaEnergy, RadialALEnergy, RadialTEnergy
|
from ._squish import AreaEnergy, RadialALEnergy, RadialTEnergy
|
||||||
|
|
||||||
@ -29,12 +30,6 @@ def generate_filepath(sim: SimulationMode, fol: Union[str, Path]) -> Path:
|
|||||||
return real_path
|
return real_path
|
||||||
|
|
||||||
|
|
||||||
def torus_sites(n: int, w: float, h: float, L: Tuple[int, int]) -> numpy.ndarray:
|
|
||||||
dim = np.array([[w, h]])
|
|
||||||
L = np.array(L)
|
|
||||||
return (np.array([1,1])/2 + np.concatenate([(i*dim*L/n) for i in range(n)])) % dim
|
|
||||||
|
|
||||||
|
|
||||||
class DomainParams:
|
class DomainParams:
|
||||||
"""Container for basic domain parameters
|
"""Container for basic domain parameters
|
||||||
|
|
||||||
|
|||||||
86
squish/ordered.py
Normal file
86
squish/ordered.py
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
from typing import List, Tuple
|
||||||
|
import numpy as np
|
||||||
|
from numpy.linalg import norm as mag
|
||||||
|
from math import gcd, sqrt, log, tan, atan, pi
|
||||||
|
|
||||||
|
Config = Tuple[int, int]
|
||||||
|
|
||||||
|
def configurations(domain: DomainParams) -> List[Config]:
|
||||||
|
n, w, h = domain.n, domain.w, domain.h
|
||||||
|
valid = []
|
||||||
|
mults = np.arange(n)
|
||||||
|
configs = np.dstack((np.repeat(mults,n).T, np.tile(mults, n).T))[0][1:]
|
||||||
|
for i in range(len(configs)):
|
||||||
|
eq_x = n if configs[i][0] == 0 else configs[i][0]
|
||||||
|
eq_y = n if configs[i][1] == 0 else configs[i][1]
|
||||||
|
|
||||||
|
if gcd(eq_x, eq_y) != 1:
|
||||||
|
continue
|
||||||
|
|
||||||
|
vecs = configs[i]*np.dstack((w*mults, h*mults)).swapaxes(0,1)/n % domain.dim
|
||||||
|
vmod2 = np.squeeze(np.matmul(vecs, vecs.transpose(0,2,1)))
|
||||||
|
vmodv = np.squeeze(vecs).dot(vecs[1].T).T.flatten()
|
||||||
|
|
||||||
|
if np.all(vmod2 >= vmodv):
|
||||||
|
valid.append(tuple(configs[i]))
|
||||||
|
|
||||||
|
return valid
|
||||||
|
|
||||||
|
|
||||||
|
def get_config_generators(domain: DomainParams, config: Config) -> Tuple[Config, Config]:
|
||||||
|
n, w, h = domain.n, domain.w, domain.h
|
||||||
|
q1 = sites(domain, config)
|
||||||
|
v = q1[1]
|
||||||
|
# Sites to check can ignore 0*v and v itself.
|
||||||
|
all_sites = np.concatenate((q1, q1-[w,0], q1-[w,h], q1-[0,h]))[2:]
|
||||||
|
|
||||||
|
# Checking 0 < ax + by < v*v to make the sites are within the region.
|
||||||
|
vdot = np.matmul(all_sites, v)
|
||||||
|
in_box = all_sites[np.where((0 <= vdot) & (vdot <= v.dot(v)))[0]]
|
||||||
|
in_box = np.expand_dims(in_box, 0).swapaxes(0,1) # Used for the next step, getting site*site
|
||||||
|
|
||||||
|
w = in_box[np.argmin(np.squeeze(np.matmul(in_box, in_box.transpose(0,2,1))))].flatten()
|
||||||
|
|
||||||
|
return tuple(v), tuple(w)
|
||||||
|
|
||||||
|
|
||||||
|
def sites(domain: DomainParams, config: Config) -> numpy.ndarray:
|
||||||
|
n, w, h = domain.n, domain.w, domain.h
|
||||||
|
config, mults = np.array(config), np.arange(domain.n)
|
||||||
|
return (config*np.dstack((w*mults, h*mults))[0]/n) % domain.dim
|
||||||
|
|
||||||
|
|
||||||
|
def area(domain: DomainParams, config: Config) -> float:
|
||||||
|
v, w = get_config_generators(domain, config)
|
||||||
|
v, w = np.array(v), np.array(w)
|
||||||
|
c = circumcenter(v, w)
|
||||||
|
|
||||||
|
return mag(v)*mag(v/2 - c) + mag(w)*mag(w/2-c) + mag(v-w)*mag((v+w)/2-c)
|
||||||
|
|
||||||
|
|
||||||
|
def avg_radius(domain: DomainParams, config: Config) -> float:
|
||||||
|
v, w = get_config_generators(domain, config)
|
||||||
|
v, w = np.array(v), np.array(w)
|
||||||
|
c = circumcenter(v, w)
|
||||||
|
|
||||||
|
return 2*(avg_rp(mag(v), 2*mag(v/2 - c)) + avg_rp(mag(w), 2*mag(w/2-c)) + \
|
||||||
|
avg_rp(mag(v-w),2*mag((v+w)/2-c)))
|
||||||
|
|
||||||
|
|
||||||
|
def avg_rp(d: float, l: float) -> float:
|
||||||
|
return (d/(4*pi))*log(tan(.5*(atan(l/d)+pi/2))**2)
|
||||||
|
|
||||||
|
|
||||||
|
def circumcenter(v: numpy.ndarray, w: numpy.ndarray) -> Config:
|
||||||
|
det = 1/(2*rot(v).dot(w))
|
||||||
|
v2, w2 = v.dot(v), w.dot(w)
|
||||||
|
c = np.empty((2,))
|
||||||
|
c[0], c[1] = w[1]*v2 - v[1]*w2,-w[0]*v2 + v[0]*w2
|
||||||
|
return det*c
|
||||||
|
|
||||||
|
|
||||||
|
def rot(v: numpy.ndarray) -> numpy.ndarray:
|
||||||
|
w = np.copy(v)
|
||||||
|
w[0], w[1] = -w[1], w[0]
|
||||||
|
return w
|
||||||
@ -87,6 +87,12 @@ class Simulation:
|
|||||||
pickle.dump(info, out, pickle.HIGHEST_PROTOCOL)
|
pickle.dump(info, out, pickle.HIGHEST_PROTOCOL)
|
||||||
|
|
||||||
|
|
||||||
|
def save_all(self) -> None:
|
||||||
|
self.save(self.initial_data)
|
||||||
|
for i in range(len(self.frames)):
|
||||||
|
self.save(self.frame_data(i))
|
||||||
|
|
||||||
|
|
||||||
def frame_data(self, index: int) -> None:
|
def frame_data(self, index: int) -> None:
|
||||||
f = self[index]
|
f = self[index]
|
||||||
info = {
|
info = {
|
||||||
@ -145,10 +151,13 @@ class Simulation:
|
|||||||
if type(sim_class) == str:
|
if type(sim_class) == str:
|
||||||
sim_class = {"flow": Flow, "search": Search, "shrink": Shrink}[sim_class]
|
sim_class = {"flow": Flow, "search": Search, "shrink": Shrink}[sim_class]
|
||||||
|
|
||||||
|
if all_info[0]["params"][0] in [53, 59, 61, 83, 131]:
|
||||||
sim = sim_class(*all_info[0]["params"], "radial-t", 0,0)
|
thres = 1e-5
|
||||||
|
else:
|
||||||
|
thres = 1e-6
|
||||||
|
sim = sim_class(DomainParams(*all_info[0]["params"]), Energy("radial-t"), 0.05, thres, True, 0.1, 500)
|
||||||
for frame_info in all_info:
|
for frame_info in all_info:
|
||||||
frames.append(sim.energy(*frame_info["params"], frame_info["arr"]))
|
frames.append(sim.energy.mode(*frame_info["params"], frame_info["arr"]))
|
||||||
#frames[-1].stats = frame_info["stats"]
|
#frames[-1].stats = frame_info["stats"]
|
||||||
|
|
||||||
sim.frames = frames
|
sim.frames = frames
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user