From 13a589f13dfd773a7700634cd9c121acb0dfb192 Mon Sep 17 00:00:00 2001 From: JoeBell Date: Tue, 4 Mar 2025 20:47:02 -0500 Subject: [PATCH] Cleaned up Generate --- ShipGen/Generate.py | 200 ++++++++++++++++++++++---------------------- ShipGen/__init__.py | 4 +- 2 files changed, 103 insertions(+), 101 deletions(-) diff --git a/ShipGen/Generate.py b/ShipGen/Generate.py index e491b30..c966ebf 100644 --- a/ShipGen/Generate.py +++ b/ShipGen/Generate.py @@ -5,59 +5,126 @@ import torch from .tools import Guided_Cond_DDPM_Tools as GC_DDPM from .tools.HullParameterization import Hull_Parameterization as HP -from .__init__ import data_path, trained_models_path -from stl import mesh +from stl import Mesh +data_path = os.path.normpath(os.path.join(__file__,'../data')) +trained_models_path = os.path.normpath(os.path.join(__file__,'../TrainedModels')) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") -np.set_printoptions(suppress=True) # don't use scientific notation +class ShipCharacteristics: + LOA:float + Beam:float + Draft:float + Depth:float + Volume:float + U:float + def __init__(self, + LOA:float, + Beam:float, + Draft:float, + Depth:float, + Volume:float, + U:float): + self.LOA = LOA + self.Beam = Beam + self.Draft = Draft + self.Depth = Depth + self.Volume = Volume + self.U = U + def as_array(self) -> np.ndarray: + return np.array([self.LOA, self.Beam, self.Draft, self.Depth, self.Volume, self.U]) + +def generate_hulls(find_best:int, + out_of:int|None = None, + characteristics:ShipCharacteristics|None = None, + out_of_ratio:int = 10) -> list[Mesh]: + if characteristics is None: + Ship = np.array([333, 42.624, 11.28, 29.064, 97561,16]) + else: Ship = characteristics.as_array() + if out_of is None: num_samples = find_best * out_of_ratio + else: num_samples = out_of + + LOA:float = Ship[0] #in meters + BoL:float = Ship[1]/LOA #beam to length ratio + ToD:float = Ship[2]/Ship[3] #Draft to depth ratio + DoL:float = Ship[3]/LOA #Depth to length ratio + Vol:float = np.log10(Ship[4]/LOA**3) # to normalize Volume by LOA**3 -# Load in the Data: + U:float = Ship[5] # 12.86 #m/s = 25 knots -#Step 1: Load in the data -DesVec = np.load(f'{data_path}/DesVec_82k.npy', allow_pickle=True) + dim_d = np.array([[ToD, U, LOA]]) #Drag_conditioning is [ToD, U(m/s), LOA (m)] -DesVec_neg = np.load(f'{data_path}/Negative_DesVec_82k.npy', allow_pickle=True) + drag_cond = np.repeat(dim_d, num_samples, axis=0) #reapeat + dim_g = np.array([[ToD, BoL, DoL, Vol]]) -# Now lets clean up X + geom_cond = np.repeat(dim_g, num_samples, axis=0) #reapeat -idx_BBFactors = [33,34,35,36,37] -idx_BB = 31 + x_samples, unnorm = T.gen_vol_drag_guided_samples(geom_cond, drag_cond) -idx_SBFactors = [38,39,40,41,42,43,44] -idx_SB = 32 + Rt_guidance = T.Predict_Drag(unnorm, drag_cond) -for i in range(0,len(DesVec)): - DesVec[i,idx_BBFactors] = DesVec[i,idx_BB] * DesVec[i,idx_BBFactors] - DesVec[i,idx_SBFactors] = DesVec[i,idx_SB] * DesVec[i,idx_SBFactors] + valid_idx = check_feasibility(x_samples) + idxs = np.argsort(Rt_guidance[valid_idx].flatten()) + meshs:list[Mesh] = [] + for i in tqdm(range(0,find_best)): + Hull = HP(x_samples[valid_idx[idxs[i]]]) + #make the .stl file of the hull: + try: + meshs.append(Hull.gen_stl(NUM_WL=47, PointsPerWL=151, bit_AddTransom = 1, bit_AddDeckLid = 1, bit_RefineBowAndStern = 1,namepath = None)) + except: + print('Error at hull {}'.format(valid_idx[idxs[i]])) + return meshs -Y = np.load(f'{data_path}/GeometricMeasures.npy', allow_pickle=True) -LenRatios = np.load(f'{data_path}/Length_Ratios.npy', allow_pickle=True) +def load_data(): + # Load in the Data: -X_LIMITS = np.load(f'{data_path}/X_LIMITS.npy') + #Step 1: Load in the data + DesVec = np.load(f'{data_path}/DesVec_82k.npy', allow_pickle=True) -X_lower_lim = [X_LIMITS[:,0].tolist()] -X_upper_lim = [X_LIMITS[:,1].tolist()] + DesVec_neg = np.load(f'{data_path}/Negative_DesVec_82k.npy', allow_pickle=True) -#Set up Conditioning Vectors: -num_WL_Steps = 101 + # Now lets clean up X -old_err = np.seterr(all='ignore') -VolVec = np.log10(Y[:,1*num_WL_Steps:2*num_WL_Steps]) -idx = np.where(np.isnan(VolVec)) -VolVec[idx] = -6.0 #fix nan to dummy value -np.seterr(**old_err) + idx_BBFactors = [33,34,35,36,37] + idx_BB = 31 + idx_SBFactors = [38,39,40,41,42,43,44] + idx_SB = 32 -DdVec = DesVec[:,4] -BOAVec = np.amax(LenRatios[:,1:3], axis=1) + for i in range(0,len(DesVec)): + DesVec[i,idx_BBFactors] = DesVec[i,idx_BB] * DesVec[i,idx_BBFactors] + DesVec[i,idx_SBFactors] = DesVec[i,idx_SB] * DesVec[i,idx_SBFactors] -def create_network() -> GC_DDPM.GuidedDiffusionEnv: - # Set up the file for architecting the network, diffusion parameters, and training + Y = np.load(f'{data_path}/GeometricMeasures.npy', allow_pickle=True) + + LenRatios = np.load(f'{data_path}/Length_Ratios.npy', allow_pickle=True) + + X_LIMITS = np.load(f'{data_path}/X_LIMITS.npy') + + #Set up Conditioning Vectors: + num_WL_Steps = 101 + + old_err = np.seterr(all='ignore') + VolVec = np.log10(Y[:,1*num_WL_Steps:2*num_WL_Steps]) + idx = np.where(np.isnan(VolVec)) + VolVec[idx] = -6.0 #fix nan to dummy value + np.seterr(**old_err) + + + BOAVec = np.amax(LenRatios[:,1:3], axis=1) + return ( + (idx_BB, idx_SB, idx_BBFactors, idx_SBFactors), + (DesVec, X_LIMITS, DesVec_neg, VolVec, BOAVec) + ) + +def create_network(DesVec, X_LIMITS, DesVec_neg, VolVec, BOAVec) -> GC_DDPM.GuidedDiffusionEnv: + # Set up the file for architecting the network, diffusion parameters, and training + X_lower_lim = [X_LIMITS[:,0].tolist()] + X_upper_lim = [X_LIMITS[:,1].tolist()] DDPM_Dict = { 'xdim' : len(DesVec[0])-1, # Dimension of parametric design vector 'datalength': len(DesVec), # number of samples @@ -147,7 +214,7 @@ def create_network() -> GC_DDPM.GuidedDiffusionEnv: X_neg= DesVec_neg, VolVec = VolVec, BOAVec = BOAVec, - DdVec = DdVec) + DdVec = DesVec[:,4]) diffusion_path = f'{trained_models_path}/CShipGen_diffusion.pth' T.load_trained_diffusion_model(diffusion_path) @@ -161,34 +228,12 @@ def create_network() -> GC_DDPM.GuidedDiffusionEnv: T.load_trained_Drag_regression_models(PATHS) return T -T = create_network() - -class ShipCharacteristics: - LOA:float - Beam:float - Draft:float - Depth:float - Volume:float - U:float - def __init__(self, - LOA:float, - Beam:float, - Draft:float, - Depth:float, - Volume:float, - U:float): - self.LOA = LOA - self.Beam = Beam - self.Draft = Draft - self.Depth = Depth - self.Volume = Volume - self.U = U - def as_array(self) -> np.ndarray: - return np.array([self.LOA, self.Beam, self.Draft, self.Depth, self.Volume, self.U]) +feasibility_data, network_data = load_data() +T = create_network(*network_data) def check_feasibility(x_samples:np.ndarray): + idx_BB, idx_SB, idx_BBFactors, idx_SBFactors = feasibility_data for i in range(0,len(x_samples)): - x_samples[i,idx_BB] = (x_samples[i,idx_BB] + 0.5) // 1 #int rounds to 1 or 0 x_samples[i,idx_SB] = (x_samples[i,idx_SB] + 0.5) // 1 #int rounds to 1 or 0 @@ -205,44 +250,3 @@ def check_feasibility(x_samples:np.ndarray): valid_idx.append(i) return valid_idx -def generate_hulls(find_best:int, - out_of:int|None = None, - characteristics:ShipCharacteristics|None = None, - out_of_ratio:int = 10) -> list[mesh.Mesh]: - if characteristics is None: - Ship = np.array([333, 42.624, 11.28, 29.064, 97561,16]) - else: Ship = characteristics.as_array() - if out_of is None: num_samples = find_best * out_of_ratio - else: num_samples = out_of - - LOA:float = Ship[0] #in meters - BoL:float = Ship[1]/LOA #beam to length ratio - ToD:float = Ship[2]/Ship[3] #Draft to depth ratio - DoL:float = Ship[3]/LOA #Depth to length ratio - Vol:float = np.log10(Ship[4]/LOA**3) # to normalize Volume by LOA**3 - - U:float = Ship[5] # 12.86 #m/s = 25 knots - - dim_d = np.array([[ToD, U, LOA]]) #Drag_conditioning is [ToD, U(m/s), LOA (m)] - - drag_cond = np.repeat(dim_d, num_samples, axis=0) #reapeat - dim_g = np.array([[ToD, BoL, DoL, Vol]]) - - geom_cond = np.repeat(dim_g, num_samples, axis=0) #reapeat - - x_samples, unnorm = T.gen_vol_drag_guided_samples(geom_cond, drag_cond) - - Rt_guidance = T.Predict_Drag(unnorm, drag_cond) - - valid_idx = check_feasibility(x_samples) - - idxs = np.argsort(Rt_guidance[valid_idx].flatten()) - meshs:list[mesh.Mesh] = [] - for i in tqdm(range(0,find_best)): - Hull = HP(x_samples[valid_idx[idxs[i]]]) - #make the .stl file of the hull: - try: - meshs.append(Hull.gen_stl(NUM_WL=47, PointsPerWL=151, bit_AddTransom = 1, bit_AddDeckLid = 1, bit_RefineBowAndStern = 1,namepath = None)) - except: - print('Error at hull {}'.format(valid_idx[idxs[i]])) - return meshs \ No newline at end of file diff --git a/ShipGen/__init__.py b/ShipGen/__init__.py index 3a08d65..936643b 100644 --- a/ShipGen/__init__.py +++ b/ShipGen/__init__.py @@ -1,3 +1 @@ -import os -data_path = os.path.normpath(os.path.join(__file__,'../data')) -trained_models_path = os.path.normpath(os.path.join(__file__,'../TrainedModels')) \ No newline at end of file +from .Generate import generate_hulls, ShipCharacteristics \ No newline at end of file