From 63074fa7cf1ef1e9a65079227b1e15d7b1db7437 Mon Sep 17 00:00:00 2001 From: kolosret <95316526+kolosret@users.noreply.github.com> Date: Fri, 1 Nov 2024 17:50:25 -0400 Subject: [PATCH 1/5] Add files via upload --- chrest/fileinterpolate.py | 198 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 chrest/fileinterpolate.py diff --git a/chrest/fileinterpolate.py b/chrest/fileinterpolate.py new file mode 100644 index 0000000..8ba1af7 --- /dev/null +++ b/chrest/fileinterpolate.py @@ -0,0 +1,198 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Oct 29 11:23:33 2024 + +@author: rkolo +""" + +# File convert +#The aim of this file is to convert between two files using nearest nodes + + +import argparse +import pathlib +import sys, os +import pandas + +import numpy as np +import h5py +import time + +from chrestData import ChrestData +from supportPaths import expand_path +from scipy.spatial import KDTree + + +class Fieldconvert: + """ + Creates a new class from hdf5 chrest formatted file(s). + """ + + def __init__(self): + + self.dimension=0 + + self.SSfilePath=[] + self.cellSS=[] + self.vertSS=[] + self.solSS=[] + + self.newfilePath=[] + self.cellnew=[] + self.vertnew=[] + self.solnew=[] + self.points=[] + + self.vertindSS=[] + self.cellindSS=[] + + self.savedata=False + + def parsedata(self): + + hdf5SS = h5py.File(self.SSfilePath, 'r') + + self.cellSS=hdf5SS['/viz/topology/cells'][()] + self.vertSS=hdf5SS['/geometry/vertices'][()] + self.solSS=hdf5SS['/fields/solution'][()] + self.dimensionSS=self.vertSS.shape[1] + hdf5SS.close() + + hdf5new = h5py.File(self.newfilePath, 'r') + self.cellnew=hdf5new['/viz/topology/cells'][()] + self.vertnew=hdf5new['/geometry/vertices'][()] + self.solnew=hdf5new['/fields/solution'][()] + self.dimensionnew=self.vertnew.shape[1] + hdf5new.close() + + + self.vertindSS=np.zeros([len(self.vertSS),1]) + self.cellindSS=np.zeros([len(self.cellSS),1]) + self.newmat=[] + + self.serial=True + + return 0 + + def compute_cell_centers(self,cells,vertices, dimensions=-1): + # create a new np array based upon the dim + number_cells = cells.shape[0] + # vertices = vertices[:] + vertices_dim = 1 + if len(vertices.shape) > 1: + vertices_dim = vertices.shape[1] + if dimensions < 0: + dimensions = vertices_dim + + coords = np.zeros((number_cells, dimensions)) + + # march over each cell + for c in range(len(coords)): + cell_vertices = vertices.take(cells[c], axis=0) + + # take the average + cell_center = np.sum(cell_vertices, axis=0) + cell_center = cell_center / len(cell_vertices) + + # put back + coords[c, 0:vertices_dim] = cell_center + + # if this is one d, flatten + if dimensions == 1: + coords = coords[:, 0] + + return coords + + + + def findcells(self): + + cell_centersSS = self.compute_cell_centers(self.cellSS,self.vertSS[:],self.dimensionSS) + cell_centersnew = self.compute_cell_centers(self.cellnew,self.vertnew[:],self.dimensionnew) + + if cell_centersSS.shape[1] != cell_centersnew.shape[1]: + print('The dimensions of the two files dont match. The only thing currently supported is a 3D->3D and 2D->3D 2D->2D') + + if cell_centersSS.shape[1] == 2 and cell_centersnew.shape[1] == 3: + print('SS shape is 2D and new shape is 3D. The code is assuming the 2D mesh is on the xy-plane') + b=np.zeros(cell_centersSS.shape[0]) + cell_centersSS=np.append(cell_centersSS,b.reshape(b.shape[0],1),1) + + + tree = KDTree(cell_centersSS) + dist, self.points = tree.query(cell_centersnew, workers=-1) + + return 0 + + + def reorder(self): + self.newmat=np.zeros_like(self.solnew) + for i in range(len(self.cellnew)): + print(self.points[i]) + self.newmat[0,i,:]=self.solSS[0,self.points[i],:] + return 0 + + def writedata(self): + + hdf5new = h5py.File(self.newfilePath, 'r+') + + solnew=hdf5new['/fields/solution'][()] + solnew[...] = self.newmat + + hdf5new['/fields/solution'][()]=self.newmat + + hdf5new.close() + + + hdf5new = h5py.File(self.newfilePath, 'r+') + b=hdf5new['/fields/solution'][()] + # solnew[...] = self.newmat + hdf5new.close() + + return 0 + + + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Generate a chrest data file from an ablate file') + + parser.add_argument('--fileSS', dest='fileSS', type=pathlib.Path, required=True, + help='The steady state file path' + 'to supply more than one file.') + + parser.add_argument('--filenew', dest='filenew', type=pathlib.Path, required=True, + help='The steady state file path' + 'to supply more than one file.') + + parser.add_argument('--parallel', dest='parallel', action='store_true', + help="running it in parallel", + ) + + print("Start reordering the fields") + args = parser.parse_args() + + convert=Fieldconvert() + + if args.parallel: + convert.serial=False + + convert.SSfilePath=args.fileSS + convert.newfilePath=args.filenew + + #Step 1 parse data + convert.parsedata() + + #Step 2 Calculate the cell centers, make tree, find closest + convert.findcells() + + #Step 3 Check all fields + + #Step 4 Reorder the data + convert.reorder() + + #Step 5 Write out files + convert.writedata() + + + print("Finished reordering the fields") \ No newline at end of file From 291e5e20029c98b00bb3c98f7363b19b61255a45 Mon Sep 17 00:00:00 2001 From: kolosret <95316526+kolosret@users.noreply.github.com> Date: Sat, 2 Nov 2024 12:40:23 -0400 Subject: [PATCH 2/5] Adding fixes for 2D->3D, check for mechanisms --- chrest/fileinterpolate.py | 106 +++++++++++++++++++++++++------------- 1 file changed, 69 insertions(+), 37 deletions(-) diff --git a/chrest/fileinterpolate.py b/chrest/fileinterpolate.py index 8ba1af7..516c50a 100644 --- a/chrest/fileinterpolate.py +++ b/chrest/fileinterpolate.py @@ -11,15 +11,9 @@ import argparse import pathlib -import sys, os -import pandas - +from sys import exit import numpy as np import h5py -import time - -from chrestData import ChrestData -from supportPaths import expand_path from scipy.spatial import KDTree @@ -55,6 +49,17 @@ def parsedata(self): self.cellSS=hdf5SS['/viz/topology/cells'][()] self.vertSS=hdf5SS['/geometry/vertices'][()] self.solSS=hdf5SS['/fields/solution'][()] + self.speciesSS = [None] * hdf5SS['/cell_fields/solution_densityYi'].shape[2] + # Determine the species + for k in hdf5SS['/cell_fields/solution_densityYi'].attrs.keys(): + print(f"{k} => {hdf5SS['/cell_fields/solution_densityYi'].attrs[k]}") + if isinstance(hdf5SS['/cell_fields/solution_densityYi'].attrs[k],np.bytes_): + #get the order right... + if k[0:13]=='componentName': + idx=''.join(filter(lambda i: i.isdigit(), k)) + self.speciesSS[int(idx)]=hdf5SS['/cell_fields/solution_densityYi'].attrs[k].decode('UTF-8') + + self.dimensionSS=self.vertSS.shape[1] hdf5SS.close() @@ -62,16 +67,48 @@ def parsedata(self): self.cellnew=hdf5new['/viz/topology/cells'][()] self.vertnew=hdf5new['/geometry/vertices'][()] self.solnew=hdf5new['/fields/solution'][()] + self.speciesnew = [None] * hdf5new['/cell_fields/solution_densityYi'].shape[2] + # Determine the species + for k in hdf5new['/cell_fields/solution_densityYi'].attrs.keys(): + print(f"{k} => {hdf5new['/cell_fields/solution_densityYi'].attrs[k]}") + if isinstance(hdf5new['/cell_fields/solution_densityYi'].attrs[k],np.bytes_): + #get the order right... + if k[0:13]=='componentName': + idx=''.join(filter(lambda i: i.isdigit(), k)) + self.speciesnew[int(idx)]=hdf5new['/cell_fields/solution_densityYi'].attrs[k].decode('UTF-8') self.dimensionnew=self.vertnew.shape[1] hdf5new.close() - - self.vertindSS=np.zeros([len(self.vertSS),1]) - self.cellindSS=np.zeros([len(self.cellSS),1]) self.newmat=[] - self.serial=True - + #checking if the mechanisms are the same + self.samemech=True + for i,x in enumerate(self.speciesSS): + self.samemech=x==self.speciesnew[i] + + + #TODO change this in the future at some point... + if not self.samemech: + raise Exception("I can only do the same mechnisms for now...") + exit() + + if self.dimensionSS != self.dimensionnew: + print('The dimensions of the two files dont match. The only thing currently supported is a 3D->3D and 2D->3D 2D->2D') + + if self.dimensionSS ==3: + raise Exception('The steady state file has 3 dimensions') + exit() + else: + self.addzmom=True + + if (self.dimensionSS+2+len(self.speciesSS)!=self.solSS.shape[2]): + raise Exception('You got extra variables in the SS files bubba...') + exit() + + if (self.dimensionnew+2+len(self.speciesnew)!=self.solnew.shape[2]): + raise Exception('You got extra variables in the new files bubba...') + exit() + return 0 def compute_cell_centers(self,cells,vertices, dimensions=-1): @@ -102,22 +139,18 @@ def compute_cell_centers(self,cells,vertices, dimensions=-1): coords = coords[:, 0] return coords - - def findcells(self): cell_centersSS = self.compute_cell_centers(self.cellSS,self.vertSS[:],self.dimensionSS) cell_centersnew = self.compute_cell_centers(self.cellnew,self.vertnew[:],self.dimensionnew) if cell_centersSS.shape[1] != cell_centersnew.shape[1]: - print('The dimensions of the two files dont match. The only thing currently supported is a 3D->3D and 2D->3D 2D->2D') if cell_centersSS.shape[1] == 2 and cell_centersnew.shape[1] == 3: print('SS shape is 2D and new shape is 3D. The code is assuming the 2D mesh is on the xy-plane') b=np.zeros(cell_centersSS.shape[0]) - cell_centersSS=np.append(cell_centersSS,b.reshape(b.shape[0],1),1) - + cell_centersSS=np.append(cell_centersSS,b.reshape(b.shape[0],1),1) tree = KDTree(cell_centersSS) dist, self.points = tree.query(cell_centersnew, workers=-1) @@ -127,10 +160,20 @@ def findcells(self): def reorder(self): self.newmat=np.zeros_like(self.solnew) - for i in range(len(self.cellnew)): - print(self.points[i]) - self.newmat[0,i,:]=self.solSS[0,self.points[i],:] - return 0 + + if self.addzmom: + for i in range(len(self.cellnew)): + # print(self.points[i]) + #assume z momentum is 0 + self.newmat[0,i,:]=np.insert(self.solSS[0,self.points[i],:],4,0) + return 0 + else: + #for simple 3D->3D same mechanism + for i in range(len(self.cellnew)): + # print(self.points[i]) + self.newmat[0,i,:]=self.solSS[0,self.points[i],:] + return 0 + def writedata(self): @@ -142,18 +185,10 @@ def writedata(self): hdf5new['/fields/solution'][()]=self.newmat hdf5new.close() - - - hdf5new = h5py.File(self.newfilePath, 'r+') - b=hdf5new['/fields/solution'][()] - # solnew[...] = self.newmat - hdf5new.close() - + return 0 - - if __name__ == "__main__": parser = argparse.ArgumentParser(description='Generate a chrest data file from an ablate file') @@ -185,14 +220,11 @@ def writedata(self): #Step 2 Calculate the cell centers, make tree, find closest convert.findcells() - - #Step 3 Check all fields - - #Step 4 Reorder the data + + #Step 3 Reorder the data convert.reorder() - #Step 5 Write out files + #Step 4 Write out files convert.writedata() - - print("Finished reordering the fields") \ No newline at end of file + print("Finished reordering the fields") From ed1e1286badcd1e1f4a164795e09fefaef462e2f Mon Sep 17 00:00:00 2001 From: kolosret <95316526+kolosret@users.noreply.github.com> Date: Wed, 13 Nov 2024 08:51:11 -0500 Subject: [PATCH 3/5] Fixing issues with extra variables Now the fileinterpolate file allows for extra variables as long as both files has them --- chrest/fileinterpolate.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/chrest/fileinterpolate.py b/chrest/fileinterpolate.py index 516c50a..014ac0a 100644 --- a/chrest/fileinterpolate.py +++ b/chrest/fileinterpolate.py @@ -105,9 +105,10 @@ def parsedata(self): raise Exception('You got extra variables in the SS files bubba...') exit() - if (self.dimensionnew+2+len(self.speciesnew)!=self.solnew.shape[2]): - raise Exception('You got extra variables in the new files bubba...') + if (self.dimensionnew+2+len(self.speciesnew)!=self.solnew.shape[2]) == (self.dimensionnew+2+len(self.speciesnew)!=self.solnew.shape[2]) : + raise Exception('Only one file has extra variables bubba...') exit() + return 0 From bd130f0a1f80afce5784cc0ae3faaafbf1e4c2fa Mon Sep 17 00:00:00 2001 From: kolosret <95316526+kolosret@users.noreply.github.com> Date: Wed, 13 Nov 2024 08:53:29 -0500 Subject: [PATCH 4/5] bigfix in fileinterpolate --- chrest/fileinterpolate.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/chrest/fileinterpolate.py b/chrest/fileinterpolate.py index 014ac0a..61c4db0 100644 --- a/chrest/fileinterpolate.py +++ b/chrest/fileinterpolate.py @@ -101,12 +101,8 @@ def parsedata(self): else: self.addzmom=True - if (self.dimensionSS+2+len(self.speciesSS)!=self.solSS.shape[2]): - raise Exception('You got extra variables in the SS files bubba...') - exit() - if (self.dimensionnew+2+len(self.speciesnew)!=self.solnew.shape[2]) == (self.dimensionnew+2+len(self.speciesnew)!=self.solnew.shape[2]) : - raise Exception('Only one file has extra variables bubba...') + raise Exception('Only one of the files has extra variables bubba...') exit() From ace9993064ac76585fd2e0a6ff8483d4c8f56c2e Mon Sep 17 00:00:00 2001 From: kolosret <95316526+kolosret@users.noreply.github.com> Date: Wed, 13 Nov 2024 09:10:00 -0500 Subject: [PATCH 5/5] More Bugfixes --- chrest/fileinterpolate.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chrest/fileinterpolate.py b/chrest/fileinterpolate.py index 61c4db0..5d14916 100644 --- a/chrest/fileinterpolate.py +++ b/chrest/fileinterpolate.py @@ -39,7 +39,8 @@ def __init__(self): self.vertindSS=[] self.cellindSS=[] - + + self.addzmom=False self.savedata=False def parsedata(self): @@ -100,12 +101,11 @@ def parsedata(self): exit() else: self.addzmom=True - - if (self.dimensionnew+2+len(self.speciesnew)!=self.solnew.shape[2]) == (self.dimensionnew+2+len(self.speciesnew)!=self.solnew.shape[2]) : + + if (self.dimensionnew+2+len(self.speciesnew)!=self.solnew.shape[2]) != (self.dimensionSS+2+len(self.speciesSS)!=self.solSS.shape[2]) : raise Exception('Only one of the files has extra variables bubba...') exit() - return 0 def compute_cell_centers(self,cells,vertices, dimensions=-1):