Commit e89b3562 authored by sfritschi's avatar sfritschi
Browse files

restored load_from function

parent f7470925
...@@ -12,7 +12,7 @@ def main(): ...@@ -12,7 +12,7 @@ def main():
nthreads = int(sys.argv[1]) nthreads = int(sys.argv[1])
print("Using %d thread(s)" % nthreads) print("Using %d thread(s)" % nthreads)
basenet = netflow.load_network_from('../netflow/network/network.h5', isBaseNet=True) basenet = netflow.load_network_from('../netflow/network/network.h5')
print("Network statistics:") print("Network statistics:")
pore_throat_counts = [len(pore.throats) for pore in basenet.pores] pore_throat_counts = [len(pore.throats) for pore in basenet.pores]
print("Max. number of throats per pore: %d" % max(pore_throat_counts)) print("Max. number of throats per pore: %d" % max(pore_throat_counts))
......
...@@ -56,14 +56,9 @@ class Network: ...@@ -56,14 +56,9 @@ class Network:
Lmax must be smaller than the smallest side length of the network ub-lb. Lmax must be smaller than the smallest side length of the network ub-lb.
""" """
throatIdx = 0
# Globals: Lengths and radii of all throats present in base network.
# Only used for the generate_dendrogram generator
throatL = []
throatR = []
def __init__(self, lb: List[float] = [], ub: List[float] = [], \ def __init__(self, lb: List[float] = [], ub: List[float] = [], \
pores: List[Pore] = None, throats: List[Throat] = None, \ pores: List[Pore] = None, throats: List[Throat] = None, \
Lmax: float = 0.0, label: str = None, isBaseNet: bool = False): Lmax: float = 0.0, label: str = None):
# lower/upper bounds for network volume # lower/upper bounds for network volume
self.lb = lb.copy(); self.ub = ub.copy() self.lb = lb.copy(); self.ub = ub.copy()
# sets with pores and throats # sets with pores and throats
...@@ -78,9 +73,6 @@ class Network: ...@@ -78,9 +73,6 @@ class Network:
self.label = datetime.today().isoformat(sep=' ',timespec='seconds') self.label = datetime.today().isoformat(sep=' ',timespec='seconds')
else: else:
self.label = label self.label = label
self.isBaseNet = isBaseNet
# Lengths of network domain
self.L = [ub-lb for lb,ub in zip(self.lb,self.ub)]
def __repr__(self): def __repr__(self):
# count in/out resp. labelled pores # count in/out resp. labelled pores
k = sum([int(pore.label != LABELS[0]) for pore in self.pores]) k = sum([int(pore.label != LABELS[0]) for pore in self.pores])
...@@ -109,17 +101,6 @@ class Network: ...@@ -109,17 +101,6 @@ class Network:
self.throats.add(throat) self.throats.add(throat)
pore1.throats.add(throat); pore2.throats.add(throat) pore1.throats.add(throat); pore2.throats.add(throat)
return throat return throat
def connect_pores_generator(self, pore1: Pore, pore2: Pore, r: float, \
throat_id: int = -1, label: str = LABELS[0]) -> Throat:
"""Establish a throat connection between two pores."""
throat = Throat(pore1, pore2, r, label, throat_id)
lt = distance(*throat_ends(throat, self.L))
Network.throatL.append(lt)
Network.throatR.append(r)
pore1.throats.add(Network.throatIdx)
pore2.throats.add(Network.throatIdx)
Network.throatIdx += 1
return throat
class CellList: class CellList:
"""CellList class dividing physical domain into equally-sized cells """CellList class dividing physical domain into equally-sized cells
...@@ -127,7 +108,8 @@ class CellList: ...@@ -127,7 +108,8 @@ class CellList:
find_candidates() assumes pore is located in interior of domain (non-periodic) find_candidates() assumes pore is located in interior of domain (non-periodic)
""" """
def __init__(self, pores: List[Pore], domainSize: List[float], cellSize: float, \ def __init__(self, pores: List[Pore], domainSize: List[float], cellSize: float, \
basenet: Network, nInterior: int): basenet: Network, throatL: List[float], throatR: List[float], \
nInterior: int):
from math import ceil from math import ceil
self.dim = len(domainSize) self.dim = len(domainSize)
self.Lmax = basenet.Lmax self.Lmax = basenet.Lmax
...@@ -143,6 +125,10 @@ class CellList: ...@@ -143,6 +125,10 @@ class CellList:
self.poresSorted = [set() for _ in range(self.totalCells)] self.poresSorted = [set() for _ in range(self.totalCells)]
# For each pore keep track of nbor pores connected to it # For each pore keep track of nbor pores connected to it
self.connPores = [set() for _ in range(nInterior)] self.connPores = [set() for _ in range(nInterior)]
# List of (target) throat lengths from base network
self.throatL = throatL
# List of throat radii from base network
self.throatR = throatR
throatTotal = 0 throatTotal = 0
for i, pore in enumerate(pores): for i, pore in enumerate(pores):
...@@ -183,7 +169,7 @@ class CellList: ...@@ -183,7 +169,7 @@ class CellList:
candidates = self.find_candidates(pore) candidates = self.find_candidates(pore)
# Find best candidate for each throat of pore # Find best candidate for each throat of pore
for idx, throatIdx in enumerate(pore.throats): for idx, throatIdx in enumerate(pore.throats):
lt = Network.throatL[throatIdx] lt = self.throatL[throatIdx]
if (len(candidates) == 0): if (len(candidates) == 0):
self.set_throat(pore.index, -1, idx) self.set_throat(pore.index, -1, idx)
...@@ -682,10 +668,23 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \ ...@@ -682,10 +668,23 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \
# check valid number of threads # check valid number of threads
if (nthreads < 1): if (nthreads < 1):
raise ValueError('Number of threads must be >= 1!') raise ValueError('Number of threads must be >= 1!')
# check network provided was initialized properly
if (not basenet.isBaseNet): # Initialize throat lengths and radii of base network to be used
raise ValueError('Provided network was not initialized as base network!') # later
throatIdxMap = {} # {int (throat id): int (throat index)}
throatBaseIdx = 0
throatL = []
throatR = []
baseL = [ub-lb for lb,ub in zip(basenet.lb,basenet.ub)]
for pore in basenet.pores:
for throat in pore.throats:
lt = distance(*throat_ends(throat, baseL))
throatL.append(lt)
throatR.append(throat.r)
throatIdxMap[throat] = throatBaseIdx
throatBaseIdx += 1
del baseL # no longer needed
# pores, distributed based on dendrogram of basenet # pores, distributed based on dendrogram of basenet
if (not mute): print("distributing pores...") if (not mute): print("distributing pores...")
# make indexable and discard in-/outflow pores # make indexable and discard in-/outflow pores
...@@ -701,8 +700,9 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \ ...@@ -701,8 +700,9 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \
for s in product(*[range(k) for k in targetsize]): for s in product(*[range(k) for k in targetsize]):
for k, pore in enumerate(basepores): for k, pore in enumerate(basepores):
pos = [random()*l for l in L] pos = [random()*l for l in L]
poreThroatIdx = set(throatIdxMap[throat] for throat in pore.throats)
pores.append(Pore(pos=pos, r=pore.r, label=LABELS[0], pores.append(Pore(pos=pos, r=pore.r, label=LABELS[0],
throats=pore.throats.copy(), index=runningIndex)) throats=poreThroatIdx, index=runningIndex))
runningIndex += 1 runningIndex += 1
else: # dendrogram-based else: # dendrogram-based
# extract cluster hierarchy from basenet # extract cluster hierarchy from basenet
...@@ -737,12 +737,18 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \ ...@@ -737,12 +737,18 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \
[ctr[j] - w1*dist/(w1+w2)*vec[j] for j in range(d)] [ctr[j] - w1*dist/(w1+w2)*vec[j] for j in range(d)]
touched[p1] = touched[p2] = True touched[p1] = touched[p2] = True
# add section pores in random order to pores of new network # add section pores in random order to pores of new network
baseThroatIdx = 0
for k, pore in enumerate(basepores): for k, pore in enumerate(basepores):
[throat in pore.throats]
pos = [c-lb + si*(ub-lb) \ pos = [c-lb + si*(ub-lb) \
for c,si,lb,ub in zip(centroids[k],s,basenet.lb,basenet.ub)] for c,si,lb,ub in zip(centroids[k],s,basenet.lb,basenet.ub)]
poreThroatIdx = set(throatIdxMap[throat] for throat in pore.throats)
pores.insert(randint(0,len(pores)), Pore(pos=pos, pores.insert(randint(0,len(pores)), Pore(pos=pos,
r=pore.r, label=LABELS[0], throats=pore.throats.copy())) r=pore.r, label=LABELS[0], throats=poreThroatIdx))
# Throat index map no longer needed
del throatIdxMap
print("left {0:d} of {1:d} clusters (incl. {2:d} pores) untouched".\ print("left {0:d} of {1:d} clusters (incl. {2:d} pores) untouched".\
format(sum([int(not j) for j in touched]), len(touched), len(basepores))) format(sum([int(not j) for j in touched]), len(touched), len(basepores)))
# flip pores outside back into domain and set respective index of all pores # flip pores outside back into domain and set respective index of all pores
...@@ -762,7 +768,8 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \ ...@@ -762,7 +768,8 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \
# Domain size including periodic buffer layers on all sides # Domain size including periodic buffer layers on all sides
trueDomainSize = [L[i] + 2 * basenet.Lmax for i in range(d)] trueDomainSize = [L[i] + 2 * basenet.Lmax for i in range(d)]
# Initialize cell-list; Place each pore in respective cell-set # Initialize cell-list; Place each pore in respective cell-set
cellList = CellList(pores, trueDomainSize, basenet.Lmax, basenet, n) cellList = CellList(pores, trueDomainSize, basenet.Lmax, basenet, \
throatL, throatR, n)
# Divide by two (since we are counting every throat twice) # Divide by two (since we are counting every throat twice)
totalThroats = len(cellList.poreMatchTable) // 2 totalThroats = len(cellList.poreMatchTable) // 2
...@@ -804,7 +811,6 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \ ...@@ -804,7 +811,6 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \
print("Throats left: %d Throats Unrealized: %d (%.2f%%)" % \ print("Throats left: %d Throats Unrealized: %d (%.2f%%)" % \
(throatsLeft, throatsUnrealized, throatsUnrealized / totalThroats * 100.)) (throatsLeft, throatsUnrealized, throatsUnrealized / totalThroats * 100.))
nRemain = len(poresRemain) nRemain = len(poresRemain)
if (nRemain > serialThresh): if (nRemain > serialThresh):
# Compute loads and displacements for all threads # Compute loads and displacements for all threads
...@@ -840,7 +846,6 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \ ...@@ -840,7 +846,6 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \
if (len(poreTtbr) == 0): continue # Nothing left to do if (len(poreTtbr) == 0): continue # Nothing left to do
# Set of indices of connected pores # Set of indices of connected pores
pConn = cellList.connPores[pore.index] pConn = cellList.connPores[pore.index]
matches = cellList.fetch_matches(pore) matches = cellList.fetch_matches(pore)
for throatIdx, match in zip(pore.throats, matches): for throatIdx, match in zip(pore.throats, matches):
...@@ -853,7 +858,6 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \ ...@@ -853,7 +858,6 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \
break break
nbor = pores[match] nbor = pores[match]
nborc = nbor # memorize potential periodic copy nborc = nbor # memorize potential periodic copy
# find original of buffer layer pore # find original of buffer layer pore
if (nbor.label != LABELS[0]): if (nbor.label != LABELS[0]):
...@@ -872,15 +876,15 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \ ...@@ -872,15 +876,15 @@ def generate_dendrogram(basenet: Network, targetsize: List[int], \
# Update sets of connected pores # Update sets of connected pores
cellList.update_connection(pore.index, nbor.index) cellList.update_connection(pore.index, nbor.index)
r = Network.throatR[throatIdx] r = throatR[throatIdx]
targetLen = Network.throatL[throatIdx] targetLen = throatL[throatIdx]
# Compute actual throat length between pores # Compute actual throat length between pores
lt = distance(pore.pos, nborc.pos) lt = distance(pore.pos, nborc.pos)
# connect pore to nbor # connect pore to nbor
throats.append([pore, nbor, lbl, r]) throats.append([pore, nbor, lbl, r])
# remove most similar throat of nbor # remove most similar throat of nbor
ranking = [(nborThroatIdx, abs(Network.throatL[nborThroatIdx] - lt)) \ ranking = [(nborThroatIdx, abs(throatL[nborThroatIdx] - lt)) \
for nborThroatIdx in nborTtbr] for nborThroatIdx in nborTtbr]
nborThroatIdx, _ = min(ranking, key=lambda il: il[1]) nborThroatIdx, _ = min(ranking, key=lambda il: il[1])
...@@ -1232,14 +1236,14 @@ def save_network_to(filename: str, network: Network): ...@@ -1232,14 +1236,14 @@ def save_network_to(filename: str, network: Network):
data=wrk) data=wrk)
def load_network_from(filename: str, isBaseNet: bool) -> Network: def load_network_from(filename: str) -> Network:
"""Load pore network from hdf5 file.""" """Load pore network from hdf5 file."""
import h5py import h5py
import numpy as np import numpy as np
f = h5py.File(filename, 'r') f = h5py.File(filename, 'r')
# global network properties # global network properties
network = Network(label=f['network_label'][0].decode('utf-8'), network = Network(label=f['network_label'][0].decode('utf-8'),
lb=list(f['lb']), ub=list(f['ub']), Lmax=f['Lmax'][0], isBaseNet=isBaseNet) lb=list(f['lb']), ub=list(f['ub']), Lmax=f['Lmax'][0])
# pores # pores
pid = np.array(f['pores/id']) pid = np.array(f['pores/id'])
...@@ -1258,11 +1262,6 @@ def load_network_from(filename: str, isBaseNet: bool) -> Network: ...@@ -1258,11 +1262,6 @@ def load_network_from(filename: str, isBaseNet: bool) -> Network:
if 'label' in f['pores']: # are there any labels != ''? if 'label' in f['pores']: # are there any labels != ''?
for id, strg in zip(f['pores/label/id'],f['pores/label/strg']): for id, strg in zip(f['pores/label/id'],f['pores/label/strg']):
pores[id].label = strg.decode('utf-8') pores[id].label = strg.decode('utf-8')
# pick appropriate connector method if generation algorithm is used
connector_method = network.connect_pores
if isBaseNet:
connector_method = network.connect_pores_generator
# throats # throats
tid = np.array(f['throats/id']) tid = np.array(f['throats/id'])
...@@ -1271,7 +1270,7 @@ def load_network_from(filename: str, isBaseNet: bool) -> Network: ...@@ -1271,7 +1270,7 @@ def load_network_from(filename: str, isBaseNet: bool) -> Network:
[pores[id] for id in np.array(f['throats/pore1'])], [pores[id] for id in np.array(f['throats/pore1'])],
[pores[id] for id in np.array(f['throats/pore2'])], [pores[id] for id in np.array(f['throats/pore2'])],
np.array(f['throats/r'])): np.array(f['throats/r'])):
throats[id] = connector_method(pore1, pore2, r, id) throats[id] = network.connect_pores(pore1, pore2, r, id)
# labels # labels
if 'label' in f['throats']: # are there any labels != ''? if 'label' in f['throats']: # are there any labels != ''?
......
...@@ -22,7 +22,7 @@ def main(): ...@@ -22,7 +22,7 @@ def main():
if (rank == root): if (rank == root):
netPath = sys.argv[1] netPath = sys.argv[1]
try: try:
net = netflow.load_network_from(netPath, isBaseNet=False) net = netflow.load_network_from(netPath)
except Exception as e: except Exception as e:
print("Error: {}".format(e)) print("Error: {}".format(e))
comm.Abort(1) comm.Abort(1)
......
...@@ -13,7 +13,7 @@ def coord_transform(pos: List[float], lb: float, ub: float): ...@@ -13,7 +13,7 @@ def coord_transform(pos: List[float], lb: float, ub: float):
return np.array(list(map(transform, pos))) return np.array(list(map(transform, pos)))
def main(): def main():
dendro = netflow.load_network_from("network/dendro.h5") dendro = netflow.load_network_from("../gen/networks/dendro_1_1_1.h5")
# Setup GUI # Setup GUI
vis = o3d.visualization.VisualizerWithKeyCallback() vis = o3d.visualization.VisualizerWithKeyCallback()
......
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