Commit b3e3f720 authored by sfritschi's avatar sfritschi
Browse files

Restrict next best neighbor search to current cell

parent a029a759
...@@ -198,7 +198,7 @@ class CellList: ...@@ -198,7 +198,7 @@ class CellList:
throatIdx += 1 throatIdx += 1
throatTotal = throatIdx throatTotal = offset
self.poreThroatTable = mp.RawArray('i', throatTotal) self.poreThroatTable = mp.RawArray('i', throatTotal)
# Helper for converting 3D index triple into 1D (flattened) index # Helper for converting 3D index triple into 1D (flattened) index
...@@ -242,6 +242,7 @@ class CellList: ...@@ -242,6 +242,7 @@ class CellList:
for idx, throatIdx in enumerate(throats): for idx, throatIdx in enumerate(throats):
lt = self.throatL[throatIdx] lt = self.throatL[throatIdx]
# Find best match among candidates
matchIdx, matchLen = min(candidates.items(), key=lambda il: abs(il[1] - lt)) matchIdx, matchLen = min(candidates.items(), key=lambda il: abs(il[1] - lt))
# Remove match from candidates # Remove match from candidates
del candidates[matchIdx] del candidates[matchIdx]
...@@ -256,36 +257,23 @@ class CellList: ...@@ -256,36 +257,23 @@ class CellList:
for cporeIdx in self.periodicCopies[originalIdx]: for cporeIdx in self.periodicCopies[originalIdx]:
if cporeIdx in candidates: if cporeIdx in candidates:
del candidates[cporeIdx] del candidates[cporeIdx]
# Put best match index in poreThroatTable
self.set_throat(poreIdx, matchIdx, idx) self.set_throat(poreIdx, matchIdx, idx)
# Compute dictionary of all nbor candidates of given pore # Compute dictionary of all nbor candidates of given pore
def find_candidates(self, poreIdx: int) -> Dict[int, float]: def find_candidates(self, poreIdx: int) -> Dict[int, float]:
candidates = {} candidates = {}
porePos = self.fetch_pos(poreIdx) porePos = self.fetch_pos(poreIdx)
cellIdxTrip = self.pore_to_triplet(poreIdx) cellIdxTrip = self.pore_to_triplet(poreIdx)
nearestCellIdx = self.flatten(*cellIdxTrip) nearestCellIdx = self.flatten(*cellIdxTrip)
for nborIdx in self.poresSorted[nearestCellIdx]: for nborIdx in self.poresSorted[nearestCellIdx]:
if (nborIdx == poreIdx): continue if (nborIdx == poreIdx): continue
l = distance(self.fetch_pos(nborIdx), porePos) l = distance(self.fetch_pos(nborIdx), porePos)
if (l < self.Lmax): if (l < self.Lmax):
candidates[nborIdx] = l candidates[nborIdx] = l
# TODO: Speed up finding of suitable candidates (e.g. multiprocessing)
for n in range(self.dim):
for i in [-1, 1]:
cellIdx = self.flatten(cellIdxTrip[0] + i * (n == 0), \
cellIdxTrip[1] + i * (n == 1), \
cellIdxTrip[2] + i * (n == 2))
# Check if valid cell index
#assert(self.is_valid_index(nborIdx))
# Check all pores within current neighbor-cell
for nborIdx in self.poresSorted[cellIdx]:
l = distance(self.fetch_pos(nborIdx), porePos)
if (l < self.Lmax):
candidates[nborIdx] = l
return candidates return candidates
def set_throat(self, poreIdx: int, matchIdx: int, idx: int): def set_throat(self, poreIdx: int, matchIdx: int, idx: int):
...@@ -307,26 +295,6 @@ class CellList: ...@@ -307,26 +295,6 @@ class CellList:
lb = self.dim * poreIdx lb = self.dim * poreIdx
ub = self.dim + lb ub = self.dim + lb
return self.poresPos[lb:ub] return self.poresPos[lb:ub]
def par_find_candidates(self, in_q: mp.SimpleQueue, out_q: mp.SimpleQueue):
while True:
# Retrieve payload from in-queue
payload = in_q.get()
if payload is None:
break # Terminate process
poreIdx = payload[0]
neighbors = payload[1]
porePos = self.fetch_pos(poreIdx)
candidates = {}
for nborIdx in neighbors:
if (nborIdx == poreIdx): continue
l = distance(porePos, self.fetch_pos(nborIdx))
if (l < self.Lmax):
candidates[nborIdx] = l
# Put result in out-queue
out_q.put(candidates)
# Only consider subset of all neighboring cells (closest 7) # Only consider subset of all neighboring cells (closest 7)
def nbor_indices(self, poreIdx: int) -> List[int]: def nbor_indices(self, poreIdx: int) -> List[int]:
...@@ -941,12 +909,15 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \ ...@@ -941,12 +909,15 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \
del cellList.poreThroatTable del cellList.poreThroatTable
# Finally, find next best candidates for left-out pores # Finally, find next best candidates for left-out pores
# in REVERSED order
if (not mute): print("finding next best candidates") if (not mute): print("finding next best candidates")
for poreIdx, pore in enumerate(pores[:n]): poreIdx = n
for it, pore in enumerate(reversed(pores[:n])):
poreIdx -= 1
if (not mute): if (not mute):
print(f"progress {((poreIdx+1) / n)*100.:.1f}%", end="\r", flush=True) print(f"progress {((it+1) / n)*100.:.1f}%", end="\r", flush=True)
ttbr = cellList.poreThroatIndices[poreIdx] ttbr = cellList.poreThroatIndices[poreIdx]
if (len(ttbr) == 0): if (len(ttbr) == 0):
...@@ -955,7 +926,9 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \ ...@@ -955,7 +926,9 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \
# Expensive: Find alternative (multiprocessing) # Expensive: Find alternative (multiprocessing)
candidates = cellList.find_candidates(poreIdx) candidates = cellList.find_candidates(poreIdx)
for throatIdx in ttbr.copy(): while ttbr:
throatIdx = ttbr.pop()
r = cellList.throatR[throatIdx] r = cellList.throatR[throatIdx]
targetLen = cellList.throatL[throatIdx] targetLen = cellList.throatL[throatIdx]
...@@ -1002,8 +975,6 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \ ...@@ -1002,8 +975,6 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \
# Remove throat from neighbor # Remove throat from neighbor
nborTtbr.remove(nborThroatIdx) nborTtbr.remove(nborThroatIdx)
# Successfully connected this throat
ttbr.remove(throatIdx)
# remove fully connected nbor from search neighborhood # remove fully connected nbor from search neighborhood
if (len(nborTtbr) == 0): if (len(nborTtbr) == 0):
...@@ -1019,6 +990,9 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \ ...@@ -1019,6 +990,9 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \
for cpore in copies[pore]: for cpore in copies[pore]:
cellList.expel(cpore) cellList.expel(cpore)
# Free memory associated with cellList (not needed anymore)
del cellList
percent = k / (k + len(throats)) * 100. percent = k / (k + len(throats)) * 100.
print("\b"*24 + "{0:d} throats in total, {1:d} unrealised ({2:.1f}%)".\ print("\b"*24 + "{0:d} throats in total, {1:d} unrealised ({2:.1f}%)".\
format(len(throats), k, percent)) format(len(throats), k, percent))
...@@ -1027,9 +1001,6 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \ ...@@ -1027,9 +1001,6 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \
print("Relative to Lmax: %.1f%%" % (avg_throat_diff / basenet.Lmax * 100.)) print("Relative to Lmax: %.1f%%" % (avg_throat_diff / basenet.Lmax * 100.))
print("Percentage where match was fully-connected: %.1f%%" % (n_already_taken / total * 100.)) print("Percentage where match was fully-connected: %.1f%%" % (n_already_taken / total * 100.))
# Free memory associated with cellList (not needed anymore)
del cellList
# assemble and return network # assemble and return network
network = Network(lb=[0.0 for k in range(d)], network = Network(lb=[0.0 for k in range(d)],
ub=L, Lmax=basenet.Lmax, label='from_' + basenet.label) ub=L, Lmax=basenet.Lmax, label='from_' + basenet.label)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment