Poisson disc for periodic situation
This commit is contained in:
parent
ec23ab8b61
commit
e5b414419a
|
@ -8,7 +8,7 @@ from . import grid_filters
|
||||||
def from_random(size,N_seeds,grid=None,seed=None):
|
def from_random(size,N_seeds,grid=None,seed=None):
|
||||||
"""
|
"""
|
||||||
Random seeding in space.
|
Random seeding in space.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : numpy.ndarray of shape (3)
|
||||||
|
@ -21,7 +21,7 @@ def from_random(size,N_seeds,grid=None,seed=None):
|
||||||
seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||||
A seed to initialize the BitGenerator. Defaults to None.
|
A seed to initialize the BitGenerator. Defaults to None.
|
||||||
If None, then fresh, unpredictable entropy will be pulled from the OS.
|
If None, then fresh, unpredictable entropy will be pulled from the OS.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
rng = _np.random.default_rng(seed)
|
rng = _np.random.default_rng(seed)
|
||||||
if grid is None:
|
if grid is None:
|
||||||
|
@ -31,13 +31,13 @@ def from_random(size,N_seeds,grid=None,seed=None):
|
||||||
coords = grid_coords[rng.choice(_np.prod(grid),N_seeds, replace=False)] \
|
coords = grid_coords[rng.choice(_np.prod(grid),N_seeds, replace=False)] \
|
||||||
+ _np.broadcast_to(size/grid,(N_seeds,3))*(rng.random((N_seeds,3))*.5-.25) # wobble without leaving grid
|
+ _np.broadcast_to(size/grid,(N_seeds,3))*(rng.random((N_seeds,3))*.5-.25) # wobble without leaving grid
|
||||||
|
|
||||||
coords
|
return coords
|
||||||
|
|
||||||
|
|
||||||
def from_Poisson_disc(size,N_seeds,N_candidates,distance,seed=None):
|
def from_Poisson_disc(size,N_seeds,N_candidates,distance,periodic=True,seed=None):
|
||||||
"""
|
"""
|
||||||
Seeding in space according to a Poisson disc distribution.
|
Seeding in space according to a Poisson disc distribution.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
size : numpy.ndarray of shape (3)
|
size : numpy.ndarray of shape (3)
|
||||||
|
@ -48,10 +48,12 @@ def from_Poisson_disc(size,N_seeds,N_candidates,distance,seed=None):
|
||||||
Number of candidates to consider for finding best candidate.
|
Number of candidates to consider for finding best candidate.
|
||||||
distance : float
|
distance : float
|
||||||
Minimum acceptable distance to other seeds.
|
Minimum acceptable distance to other seeds.
|
||||||
|
periodic : boolean, optional
|
||||||
|
Calculate minimum distance for periodically repeated grid.
|
||||||
seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||||
A seed to initialize the BitGenerator. Defaults to None.
|
A seed to initialize the BitGenerator. Defaults to None.
|
||||||
If None, then fresh, unpredictable entropy will be pulled from the OS.
|
If None, then fresh, unpredictable entropy will be pulled from the OS.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
rng = _np.random.default_rng(seed)
|
rng = _np.random.default_rng(seed)
|
||||||
coords = _np.empty((N_seeds,3))
|
coords = _np.empty((N_seeds,3))
|
||||||
|
@ -61,7 +63,8 @@ def from_Poisson_disc(size,N_seeds,N_candidates,distance,seed=None):
|
||||||
progress = util._ProgressBar(N_seeds+1,'',50)
|
progress = util._ProgressBar(N_seeds+1,'',50)
|
||||||
while i < N_seeds:
|
while i < N_seeds:
|
||||||
candidates = rng.random((N_candidates,3))*_np.broadcast_to(size,(N_candidates,3))
|
candidates = rng.random((N_candidates,3))*_np.broadcast_to(size,(N_candidates,3))
|
||||||
tree = _spatial.cKDTree(coords[:i])
|
tree = _spatial.cKDTree(coords[:i],boxsize=size) if periodic else \
|
||||||
|
_spatial.cKDTree(coords[:i])
|
||||||
distances, dev_null = tree.query(candidates)
|
distances, dev_null = tree.query(candidates)
|
||||||
best = distances.argmax()
|
best = distances.argmax()
|
||||||
if distances[best] > distance: # require minimum separation
|
if distances[best] > distance: # require minimum separation
|
||||||
|
@ -75,12 +78,12 @@ def from_Poisson_disc(size,N_seeds,N_candidates,distance,seed=None):
|
||||||
def from_geom(geom,selection=None,invert=False):
|
def from_geom(geom,selection=None,invert=False):
|
||||||
"""
|
"""
|
||||||
Create seed from existing geometry description.
|
Create seed from existing geometry description.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
geom : damask.Geom
|
geom : damask.Geom
|
||||||
...
|
...
|
||||||
|
|
||||||
"""
|
"""
|
||||||
material = geom.materials.reshape((-1,1),order='F')
|
material = geom.materials.reshape((-1,1),order='F')
|
||||||
mask = _np.full(geom.grid.prod(),True,dtype=bool) if selection is None else \
|
mask = _np.full(geom.grid.prod(),True,dtype=bool) if selection is None else \
|
||||||
|
|
|
@ -13,11 +13,13 @@ class TestSeeds:
|
||||||
coords = seeds.from_random(size,N_seeds,grid)
|
coords = seeds.from_random(size,N_seeds,grid)
|
||||||
assert (0<=coords).all() and (coords<size).all()
|
assert (0<=coords).all() and (coords<size).all()
|
||||||
|
|
||||||
def test_from_Poisson_disc(self):
|
@pytest.mark.parametrize('periodic',[True,False])
|
||||||
|
def test_from_Poisson_disc(self,periodic):
|
||||||
N_seeds = np.random.randint(30,300)
|
N_seeds = np.random.randint(30,300)
|
||||||
N_candidates = N_seeds//15
|
N_candidates = N_seeds//15
|
||||||
distance = np.random.random()
|
distance = np.random.random()
|
||||||
size = np.ones(3)*distance*N_seeds
|
size = np.ones(3)*distance*N_seeds
|
||||||
coords = seeds.from_Poisson_disc(size,N_seeds,N_candidates,distance)
|
coords = seeds.from_Poisson_disc(size,N_seeds,N_candidates,distance,periodic=periodic)
|
||||||
min_dists, _ = cKDTree(coords).query(coords, 2)
|
min_dists, _ = cKDTree(coords,boxsize=size).query(coords, 2) if periodic else \
|
||||||
|
cKDTree(coords).query(coords, 2)
|
||||||
assert (0<= coords).all() and (coords<size).all() and np.min(min_dists[:,1])>=distance
|
assert (0<= coords).all() and (coords<size).all() and np.min(min_dists[:,1])>=distance
|
||||||
|
|
Loading…
Reference in New Issue