Add files via upload

This commit is contained in:
Praveen Kumar ch authored and GitHub committed 2021-03-15 23:02:36 +05:30
1 parent 7766f40372
commit baa2ad9c18
9 files changed
+2417

No files matched your search

+33
View File
@@ -0,0 +1,33 @@
"""
************************************************************************************
File : ENV_PROP.py
File Purpose : Define the Class "ENV_PROP"
Class Purpose :
-> Reads and stores Environment properties from file "Set_EP.dat"
-> Environment Properties are defined in this class
App : PyNAT - Python Based Naval Architecture Tools
Version : 2021.0
Paradigm : Object Based Framework
Author : Praveen Kumar Ch
*************************************************************************************
"""
class ENV_PROP:
# --------------------------------------------------------------------------------------
# The Constructor
# --------------------------------------------------------------------------------------
def __init__(self,fs):
print("\n\t\tPyNAT: Reading File:\t...\\",fs.iep_path)
# Reading the Solver properties
fp=open(fs.iep_path,"rt")
lines=fp.readlines()
fp.close()
nums=lines[0].split('\t')
self.waterDensity = float(nums[0])
+85
View File
@@ -0,0 +1,85 @@
"""
************************************************************************************
File : HullGeometry.py
File Purpose : Define the Class "FileSystems"
Class Purpose :
-> Read the Hull Geometry definition data from the File "SetHullGeom.dat"
-> Create the data variables defining the ship Hull Geometry
-> Create and prepare a "SectionCurves" object for each station
-> Print the read Data to console
App : PyNAT - Python Based Naval Architecture Tools
Version : 2021.0
Paradigm : Object Based Framework
Author : Praveen Kumar Ch
*************************************************************************************
"""
import shutil
import os
class FileSystem:
# --------------------------------------------------------------------------------------
# The Constructor
# --------------------------------------------------------------------------------------
def __init__(self):
# The Directories for input and output files
self.in_dir = "in"
self.out_dir = "out"
self.sec_dnm = "sec"
self.sec_dir =os.path.join(self.out_dir,self.sec_dnm)
self.hs_dnm="hs"
self.hs_dir =os.path.join(self.out_dir,self.hs_dnm)
self.las_dnm="las"
self.las_dir =os.path.join(self.out_dir,self.las_dnm)
# Check if Output Directory exists and delete if exist
# if(os.path.isdir(self.out_dir)):
# shutil.rmtree(self.out_dir)
# Create the out directory
if not os.path.exists(self.out_dir):
os.makedirs(self.out_dir)
if not os.path.exists(self.sec_dir):
os.makedirs(self.sec_dir)
if not os.path.exists(self.hs_dir):
os.makedirs(self.hs_dir)
if not os.path.exists(self.las_dir):
os.makedirs(self.las_dir)
self.iep_file = "Set_EP.dat"
self.iep_path = os.path.join(self.in_dir,self.iep_file)
self.ihg_file = "Set_HG.dat"
self.ihg_path = os.path.join(self.in_dir,self.ihg_file)
self.ihs_file = "Set_HS.dat"
self.ihs_path = os.path.join(self.in_dir,self.ihs_file)
self.ikn_file = "Set_KN.dat"
self.ikn_path = os.path.join(self.in_dir,self.ikn_file)
self.ilc_file = "Set_LC.dat"
self.ilc_path = os.path.join(self.in_dir,self.ilc_file)
self.ohg_file = "Res_HG.dat"
self.ohg_path = os.path.join(self.sec_dir,self.ohg_file)
self.ohs_file = "Res_HS.dat"
self.ohs_path = os.path.join(self.hs_dir,self.ohs_file)
self.okn_file = "Res_KN.dat"
self.okn_path = os.path.join(self.las_dir,self.okn_file)
self.ogz_file = "Res_GZ.dat"
self.ogz_path = os.path.join(self.las_dir,self.ogz_file)
self.okn_fast_file = "Res_KN_FAST.dat"
self.okn_fast_path = os.path.join(self.las_dir,self.okn_fast_file)
self.ogz_fast_file = "Res_GZ_FAST.dat"
self.ogz_fast_path = os.path.join(self.las_dir,self.ogz_fast_file)
+363
View File
@@ -0,0 +1,363 @@
"""
************************************************************************************
File : HullGeometry.py
File Purpose : Define the Class "HullGeometry"
Class Purpose :
-> Read the Hull Geometry definition data from the File "Set_HG.dat"
-> Create the data variables defining the ship Hull Geometry
-> Create and prepare a "SectionCurves" object for each station
-> Print the read Data to console
-> Write the prepared data to "Res_HG.dat"
App : PyNAT - Python Based Naval Architecture Tools
Version : 2021a
Paradigm : Object Oriented Model
Author : Praveen Kumar Ch
*************************************************************************************
"""
import numpy as np
import scipy.interpolate as spi
import matplotlib.pyplot as plt
from SectionCurves import SectionCurves
import os
class HullGeometry:
# --------------------------------------------------------------------------------------
# The Constructor
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def __init__(self,fs):
self.tol=0.001
self.readFromFile(fs)
self.writeToFile(fs)
#self.printToConsol(fs)
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# Function to Read Hull Geometry Data from file
# Creates and Prepares SectionCurve Objects
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def readFromFile(self,fs):
print("\n\t\t PyNAT: Reading File : ...\\",fs.ihg_path)
fp=open(fs.ihg_path,"rt")
lines=fp.readlines()
fp.close()
# Reading the Main Dimensions
nums=lines[1].split("\t")
self.L=float(nums[0])
nums=lines[2].split("\t")
self.B=float(nums[0])
nums=lines[3].split("\t")
self.D=float(nums[0])
nums=lines[4].split("\t")
self.AP=float(nums[0])
self.FP=float(nums[1])
self.MS=(self.AP+self.FP)/2
x=list()
y=list()
z=list()
c=list()
nums=lines[5].rstrip("\n").split("\t")
tx=float(nums[0])
ty=float(nums[1])
tz=float(nums[2])
tc=1
if(len(nums)>=4):
if nums[3].count("k"):
tc=0
if nums[3].count("b"):
tc=-1
x.append(tx)
y.append(list([ty]))
z.append(list([tz]))
c.append(list([tc]))
# Reading the points and segregating into stations
# Py-NAT 2021a : PRAVEEN KUMAR CH
for i in range(6,len(lines),1):
nums=lines[i].rstrip("\n").split("\t")
tx=float(nums[0])
ty=float(nums[1])
tz=float(nums[2])
tc=1
if(len(nums)>=4):
if nums[3].count("k"):
tc=0
if nums[3].count("b"):
tc=-1
found=-1
loc=0
# check which station to add this point
for j in range(len(x)):
delx=tx-x[j]
if delx>0:
loc=j+1
if abs(delx)<=self.tol:
found=j
loc=j
break
if found<=-1:
# If the point dosent belong to exisitng station then add new station
x.insert(loc,tx)
y.insert(loc,list([ty]))
z.insert(loc,list([tz]))
c.insert(loc,list([tc]))
else:
# If the point belongs to existing station check were to place it
for j in range(len(z[loc]),0,-1):
delz=tz-z[loc][j-1]
if(delz>self.tol):
y[loc].insert(j,ty)
z[loc].insert(j,tz)
c[loc].insert(j,tc)
break
elif(abs(delz)<=self.tol):
dely=ty-y[loc][j-1]
if(dely>self.tol):
y[loc].insert(j,ty)
z[loc].insert(j,tz)
c[loc].insert(j,tc)
break
elif(abs(dely)<=self.tol):
break
# Dealing with Horizontal Lines due to points with same z values
# Py-NAT 2021a : PRAVEEN KUMAR CH
for i in range(len(x)):
# In each station
for j in range(len(z[i])-1):
# At each point
if abs(z[i][j]-z[i][j+1])<=self.tol:
# If two adjacent points have same z
z[i][j+1]=z[i][j]+self.tol
self.nst=len(x)
self.x=np.array(x)
self.y=list()
self.z=list()
self.c=list()
self.xms=np.array(range(self.nst))
self.npts=np.array(range(self.nst))
for i in range(self.nst):
self.y.append(np.array(y[i]))
self.z.append(np.array(z[i]))
self.c.append(np.array(c[i]))
self.npts[i]=self.y[i].size
# Py-NAT 2021a : PRAVEEN KUMAR CH
print("\n\t\t PyNAT : Preparing Section Curve Spline Fit Data")
self.secCrv=list()
for i in range(self.nst):
ind=np.argsort(self.z[i],axis=0)
self.z[i]=np.take_along_axis(self.z[i],ind,axis=0)
self.y[i]=np.take_along_axis(self.y[i],ind,axis=0)
self.c[i]=np.take_along_axis(self.c[i],ind,axis=0)
self.c[i][0]=-1
self.c[i][-1]=-1
self.secCrv.append(SectionCurves(self.x[i],self.y[i],self.z[i],self.c[i]))
# Compute X locations form Mid Ship
self.xms=self.x-self.MS
# ---------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# Function to write prepared hull geometry data to files
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def writeToFile(self, fs):
print("\n\t\tPy-NAT: Writing Prepared Hull Geometry Data to File : ...\\",fs.ohg_path)
if not os.path.exists(fs.sec_dir):
os.makedirs(fs.sec_dir)
fp=open(fs.ohg_path,'wt')
fp.write("\nPy-NAT: Hull Geometry Data")
# Printing the read data to Console
fp.write("\nLength =\t%12.4E"%(self.L))
fp.write("\nBreadth =\t%12.4E"%(self.B))
fp.write("\nDepth =\t%12.4E"%(self.D))
fp.write("\nX location of AP =\t%12.4E"%(self.AP))
fp.write("\nX location of FP =\t%12.4E"%(self.FP))
fp.write("\nX location of MS =\t%12.4E"%(self.MS))
fp.write("\nNo of Stations =\t%12.4E"%(self.nst))
fp.write("\n\n Printing Station Wise Data... \n\n")
for i in range(self.nst):
fp.write("\n-----------------------------------------------------------")
fp.write("\nStation no =\t%12.4E"%(i))
fp.write("\nX =\t%12.4E"%(self.x[i]))
fp.write("\nX frm MS =\t%12.4E"%(self.xms[i]))
fp.write("\nNo of pts =\t%12.4E"%(self.npts[i]))
fp.write("\n i \t Z \t Y \t C")
for j in range(self.npts[i]):
fp.write("\n%4d\t%12.4E\t%12.4E\t%12d"%(j,self.z[i][j],self.y[i][j],self.c[i][j]))
fp.write("\n\n Total No of Curvelets =%d"%(self.secCrv[i].nCrv))
for k in range(self.secCrv[i].nCrv):
fp.write("\n\n The Curve No: %d \t Start index= %10.5f \t End Index= %10.5f \n"%(k,self.secCrv[i].sCrv[k],self.secCrv[i].eCrv[k]))
fp.write("\nThe Spline curve Fit Y=F(z)")
tck=self.secCrv[i].y_fz[k]
fp.write("\nKnots, t=")
for l in range(len(tck[0])):
fp.write("%10.5f,"%(tck[0][l]))
fp.write("\nB-Spline Coeff, c=")
for l in range(len(tck[1])):
fp.write("%10.5f,"%(tck[1][l]))
fp.write("\nDegree, k=")
fp.write("%10.5f,"%(tck[2]))
fp.write("\nThe Spline curve Fit ZY=F(z)")
tck=self.secCrv[i].zy_fz[k]
fp.write("\nKnots, t=")
for l in range(len(tck[0])):
fp.write("%10.5f,"%(tck[0][l]))
fp.write("\nB-Spline Coeff, c=")
for l in range(len(tck[1])):
fp.write("%10.5f,"%(tck[1][l]))
fp.write("\nDegree, k=")
fp.write("%10.5f,"%(tck[2]))
fp.write("\nThe Spline curve Fit YY=F(z)")
tck=self.secCrv[i].yy_fz[k]
fp.write("\nKnots, t=")
for l in range(len(tck[0])):
fp.write("%10.5f,"%(tck[0][l]))
fp.write("\nB-Spline Coeff, c=")
for l in range(len(tck[1])):
fp.write("%10.5f,"%(tck[1][l]))
fp.write("\nDegree, k=")
fp.write("%10.5f,"%(tck[2]))
fp.write("\nThe Spline curve Fit L=F(z)")
tck=self.secCrv[i].L_fz[k]
fp.write("\nKnots, t=")
for l in range(len(tck[0])):
fp.write("%10.5f,"%(tck[0][l]))
fp.write("\nB-Spline Coeff, c=")
for l in range(len(tck[1])):
fp.write("%10.5f,"%(tck[1][l]))
fp.write("\nDegree, k=")
fp.write("%10.5f,"%(tck[2]))
fp.close()
#-------------------------------------------------------------------------------------------------
# Activate this Section to Plot Each individual Section
# Py-NAT 2021a : PRAVEEN KUMAR CH
# for i in range(self.nst):
# plt.figure(i)
# zs,ys=self.secCrv[i].getPoints(0.1)
# plt.plot(ys,zs)
# plt.plot(self.y[i],self.z[i],'o')
# xstr = format(self.x[i],"6.3f")
# istr = format(i,"3d")
# plt.title("Section @ X="+xstr)
# plt.xlabel("Y")
# plt.ylabel("Z")
# plt.grid(True)
# plt.axis('equal')
# #lg=plt.legend(bbox_to_anchor=(1.05, 1))
# plt.savefig(os.path.join(fs.sec_dir,"Sec_Curv_"+istr+".png"),
# dpi=300,
# format='png',
# bbox_extra_artists=(),
# bbox_inches='tight')
# plt.close()
#-------------------------------------------------------------------------------------------------
# Plot Section Curves from the Read Points
for i in range(self.nst):
plt.figure("Body Plan")
if(i<self.nst/2):
zs,ys=self.secCrv[i].getPoints(0.1)
hstr = format(i,"2d")
plt.plot(ys,zs,label='Sec:'+hstr)
plt.plot(self.y[i],self.z[i],'o')
else:
zs,ys=self.secCrv[i].getPoints(0.1)
hstr = format(i,"2d")
plt.plot(-ys,zs,label='Sec:'+hstr)
plt.plot(-self.y[i],self.z[i],'o')
plt.title("Body Plan")
plt.xlabel("Y")
plt.ylabel("Z")
plt.grid(True)
plt.axis('equal')
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.sec_dir,"Body_Plan.png"),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# Function to Print the data read from files
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def printToConsol(self, fs):
# Printing the read data to Console
print("Length =\t%12.4E"%(self.L))
print("Breadth =\t%12.4E"%(self.B))
print("Depth =\t%12.4E"%(self.D))
print("X location of AP =\t%12.4E"%(self.AP))
print("X location of FP =\t%12.4E"%(self.FP))
print("X location of MS =\t%12.4E"%(self.MS))
print("No of Stations =\t%12.4E"%(self.nst))
for i in range(self.nst):
print("-------------------------------------------------")
print("Station no =\t%12.4E"%(i))
print("X =\t%12.4E"%(self.x[i]))
print("No of pts =\t%12.4E"%(self.npts[i]))
print(" Z \t Y \t C")
for j in range(self.npts[i]):
print("%12.4E\t%12.4E\t%12d"%(self.z[i][j],self.y[i][j],self.c[i][j]))
for k in range(self.secCrv[i].nCrv):
print("The Spline curve Fit Y=F(z)")
print(self.secCrv[i].y_fz[k])
print("The Spline curve Fit ZY=F(z)")
print(self.secCrv[i].zy_fz[k])
print("The Spline curve Fit YY=F(z)")
print(self.secCrv[i].yy_fz[k])
print("The Spline curve Fit L=F(z)")
print(self.secCrv[i].L_fz[k])
# PLot Section Curves from the Read Points
plt.figure("Section Curves")
for i in range(self.nst):
if(i<self.nst/2):
zs,ys=self.secCrv[i].getPoints(0.5)
plt.plot(ys,zs,'g-')
plt.plot(self.y[i],self.z[i],'bo')
else:
zs,ys=self.secCrv[i].getPoints(0.5)
plt.plot(-ys,zs,'g-')
plt.plot(-self.y[i],self.z[i],'bo')
plt.title("The Section Curves")
plt.xlabel("Y")
plt.ylabel("Z")
plt.grid(True)
plt.savefig(os.path.join(fs.out_dir,"SectionCurves.png"))
# --------------------------------------------------------------------------------------
+579
View File
@@ -0,0 +1,579 @@
'''
************************************************************************************
File : HydroStatics.py
File Purpose : Define the Class "HydroStatics"
Class Purpose :
-> Contains Function to Compute Hydrostatics
-> Computations are done for Floating Conditions Defined by
-> Draft
-> Trim
-> The range of Drafts and Trim are read from the File "Set_HS.dat"
-> Computations are performed over a range of drafts at all Individual Sections
-> Section wise drafts are computed for each Floating Condition
-> Computations are performed for each trim and draft combination Entire Hull Volume
-> Functions to write the sectional and Hull Hydrostatics to File "Res_HS.dat"
-> Plots and Saves Hydrostatics as image files of format ".png"
App : PyNAT - Python Based Naval Architecture Tools
Version : 2021.0
Paradigm : Object Based Framework
Author : Praveen Kumar Ch
***************************************************************************************
'''
import numpy as np
from scipy.interpolate import interp1d
from scipy.integrate import quad
import matplotlib.pyplot as plt
from HullGeometry import HullGeometry
import math as math
import os
# ------------------------------------------------------------------------------------------
# The Class to Compute and Store Hydrostatic Data
# Py-NAT 2021a : PRAVEEN KUMAR CH
# ------------------------------------------------------------------------------------------
class HydroStatics:
# --------------------------------------------------------------------------------------
# The Constructor
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def __init__(self,fs,shipGrid,ep):
self.readFromFile(fs,shipGrid)
self.computeSectionalHydroStatics(shipGrid)
self.computeHullHydroStatics(shipGrid,ep)
self.writeSectionalHydrostaticsToFile(fs,shipGrid)
self.writeHullHydroStaticsToFile(fs,shipGrid)
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# Read The Hydrostatic Solver Settings File
# create list of arrays of sectional drafts for each floating condition
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def readFromFile(self,fs,shipGrid):
print("\n\t\tPyNAT : Reading File:\t...\\",fs.ihs_path)
# Reading the Solver properties
fp=open(fs.ihs_path,"rt")
lines=fp.readlines()
fp.close()
nums=lines[0].split(",")
self.nDraft=len(nums)
self.rangeDrafts = np.array(range(self.nDraft),dtype=np.float64)
for i in range(self.nDraft):
self.rangeDrafts[i] =float(nums[i])
nums=lines[1].split(",")
self.nTrims=len(nums)
self.rangeTrims = np.array(range(self.nTrims),dtype=np.float64)
for i in range(self.nTrims):
self.rangeTrims[i] =float(nums[i])*math.pi/180
# Compute Sectional Drafts for each FLoating condition
# For each floating condition the section drafts are stored in an array
# A list of all such arrays is created
self.FC=list()
for j in range(self.nTrims):
temp=list()
for i in range(self.nDraft):
drafts=np.array(range(shipGrid.nst),dtype=np.float64)
for k in range(shipGrid.nst):
drafts[k]=self.rangeDrafts[i]-shipGrid.xms[k]*math.tan(self.rangeTrims[j])
temp.append(drafts)
self.FC.append(temp)
self.nFC=self.nTrims*self.nDraft
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# Function to compute sectional hydrostatics over a range of drafts
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def computeSectionalHydroStatics(self,shipGrid):
print("\n\t\tPyNAT : Computing Section Wise Hydrostatic Properties")
# Initializing the Arrays to Hold the Sectional Data
# Each Row is for a particular station
# Each Column is for a particular draft
self.Bw=np.zeros((shipGrid.nst, self.nDraft))
self.Area=np.zeros((shipGrid.nst, self.nDraft))
self.VM=np.zeros((shipGrid.nst, self.nDraft))
self.TM=np.zeros((shipGrid.nst, self.nDraft))
self.LM=np.zeros((shipGrid.nst, self.nDraft))
self.CL=np.zeros((shipGrid.nst, self.nDraft))
self.YC=np.zeros((shipGrid.nst, self.nDraft))
self.ZC=np.zeros((shipGrid.nst, self.nDraft))
# Loop to Compute for Every section in the shipGrid
for i in range(shipGrid.nst):
print("\t\t\t\tStation:",i)
# Loop to compute for each draft in the range
for k in range(self.nDraft):
secData=shipGrid.secCrv[i].sectionHydroStatics(self.rangeDrafts[k])
self.Bw[i][k]=2*secData[0]
self.Area[i][k]=2*secData[1]
self.LM[i][k]=2*secData[2]
self.TM[i][k]=secData[3]
self.VM[i][k]=2*secData[4]
self.CL[i][k]=2*secData[5]
self.YC[i][k]=secData[5]
self.ZC[i][k]=secData[7]
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# Function to Compute Hull Volume Hydrostatics
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def computeHullHydroStatics(self,shipGrid,ep):
print("\n\t\tPyNAT : Computing the Hull Hydrostatic Properties")
# Initializing the arrays to hold hydrostatics
self.VOL=np.zeros((self.nTrims,self.nDraft))
self.WSA=np.zeros((self.nTrims,self.nDraft))
self.WPA=np.zeros((self.nTrims,self.nDraft))
self.LCF=np.zeros((self.nTrims,self.nDraft))
self.MASS=np.zeros((self.nTrims,self.nDraft))
self.VCB=np.zeros((self.nTrims,self.nDraft))
self.TCB=np.zeros((self.nTrims,self.nDraft))
self.LCB=np.zeros((self.nTrims,self.nDraft))
self.IXX0=np.zeros((self.nTrims,self.nDraft))
self.IXXG=np.zeros((self.nTrims,self.nDraft))
self.IYY0=np.zeros((self.nTrims,self.nDraft))
self.BMT=np.zeros((self.nTrims,self.nDraft))
self.BML=np.zeros((self.nTrims,self.nDraft))
self.KMT=np.zeros((self.nTrims,self.nDraft))
self.KML=np.zeros((self.nTrims,self.nDraft))
self.TPC=np.zeros((self.nTrims,self.nDraft))
self.MCT=np.zeros((self.nTrims,self.nDraft))
self.draftAP=np.zeros((self.nTrims,self.nDraft))
self.draftFP=np.zeros((self.nTrims,self.nDraft))
# Loop for each Floating Condition [List of Array of Sectional Drafts]
for itr in range(self.nTrims):
for idr in range(self.nDraft):
# Py-NAT 2021a : PRAVEEN KUMAR CH
Area=np.zeros(shipGrid.nst)
VM=np.zeros(shipGrid.nst)
TM=np.zeros(shipGrid.nst)
LM=np.zeros(shipGrid.nst)
CL=np.zeros(shipGrid.nst)
YC=np.zeros(shipGrid.nst)
ZC=np.zeros(shipGrid.nst)
y=np.arange(shipGrid.nst)
yx=np.arange(shipGrid.nst)
yxx=np.arange(shipGrid.nst)
yyy=np.arange(shipGrid.nst)
for j in range(shipGrid.nst):
secData=shipGrid.secCrv[j].sectionHydroStatics(self.FC[itr][idr][j])
y[j]=secData[0]
Area[j]=secData[1]
LM[j]=secData[2]
TM[j]=secData[3]
VM[j]=secData[4]
CL[j]=secData[5]
YC[j]=secData[6]
ZC[j]=secData[7]
yx[j]=y[j]*shipGrid.x[j]
yxx[j]=2*yx[j]*shipGrid.x[j]
yyy[j]=8*(y[j]**3)/12
Ar_fX=interp1d(shipGrid.x,Area,kind='cubic')
sq=quad(Ar_fX,shipGrid.x[0],shipGrid.x[-1])
self.VOL[itr][idr]=2*sq[0]
self.MASS[itr][idr]=self.VOL[itr][idr]*ep.waterDensity
Sa_fX=interp1d(shipGrid.x,CL,kind='cubic')
sq=quad(Sa_fX,shipGrid.x[0],shipGrid.x[-1])
self.WSA[itr][idr]=2*sq[0]
lm_fX=interp1d(shipGrid.x,LM,kind='cubic')
sq=quad(lm_fX,shipGrid.x[0],shipGrid.x[-1])
self.LCB[itr][idr]=2*sq[0]/self.VOL[itr][idr]
tm_fX=interp1d(shipGrid.x,TM-TM,kind='cubic')
sq=quad(tm_fX,shipGrid.x[0],shipGrid.x[-1])
self.TCB[itr][idr]=sq[0]/self.VOL[itr][idr]
vm_fX=interp1d(shipGrid.x,VM,kind='cubic')
sq=quad(vm_fX,shipGrid.x[0],shipGrid.x[-1])
self.VCB[itr][idr]=2*sq[0]/self.VOL[itr][idr]
wpa_fX=interp1d(shipGrid.x,y,kind='cubic')
sq=quad(wpa_fX,shipGrid.x[0],shipGrid.x[-1])
self.WPA[itr][idr]=2*sq[0]
wpm_fX=interp1d(shipGrid.x,yx,kind='cubic')
sq=quad(wpm_fX,shipGrid.x[0],shipGrid.x[-1])
self.LCF[itr][idr]=2*sq[0]/self.WPA[itr][idr]
IXX0_fx=interp1d(shipGrid.x,yxx,kind='cubic')
sq=quad(IXX0_fx,shipGrid.x[0],shipGrid.x[-1])
self.IXX0[itr][idr]=sq[0]
IYY0_fx=interp1d(shipGrid.x,yyy,kind='cubic')
sq=quad(IYY0_fx,shipGrid.x[0],shipGrid.x[-1])
self.IYY0[itr][idr]=sq[0]
self.IXXG[itr][idr]=self.IXX0[itr][idr]-self.WPA[itr][idr]*(self.LCF[itr][idr]**2)
self.draftAP[itr][idr]=self.rangeDrafts[idr]+(shipGrid.MS-shipGrid.AP)*math.tan(self.rangeTrims[itr])
self.draftFP[itr][idr]=self.rangeDrafts[idr]-(shipGrid.FP-shipGrid.MS)*math.tan(self.rangeTrims[itr])
# Py-NAT 2021a : PRAVEEN KUMAR CH
print("\n\t\t\tTrim=%f\tDraft=%f\tVolume=%f"%(self.rangeTrims[itr],self.rangeDrafts[idr],self.VOL[itr][idr]))
self.BML=self.IXXG/self.VOL
self.BMT=self.IYY0/self.VOL
self.KML=self.BML+self.VCB
self.KMT=self.BMT+self.VCB
self.TPC=self.WPA*ep.waterDensity/100000
self.MCT=self.MASS*self.BML/(shipGrid.L*100)
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# Function to Write Section wise Hydrostatics to file
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def writeSectionalHydrostaticsToFile(self,fs,shipGrid):
print("\n\t\tPyNAT : Writing Section wise Hydrostatic Data to File:\t...\\",fs.ohs_path)
if not os.path.exists(fs.hs_dir):
os.makedirs(fs.hs_dir)
fp=open(fs.ohs_path,"wt")
fp.write("\nPy-NAT: Hydrostatic Properties")
for i in range(shipGrid.nst):
fp.write('\n\n\nSection :\t'+str(i))
fp.write('\nDraft \tB/2 \tArea \tLong. Mom \tVert. Mom \tTrans. Mom\tCurv Leng ')
for k in range(self.nDraft):
fp.write("\n%10.3E\t%10.3E\t%10.3E\t%10.3E\t%10.3E\t%10.3E\t%10.3E"%(self.rangeDrafts[k],self.Bw[i,k],self.Area[i,k],self.LM[i,k],self.VM[i,k],self.TM[i,k],self.CL[i,k]))
fp.close()
# Py-NAT 2021a : PRAVEEN KUMAR CH
for i in range(shipGrid.nst):
plt.figure("Sec Ar vs Draft")
plt.plot(self.rangeDrafts,self.Area[i],label=str(i))
plt.title("Sectional Areas")
plt.xlabel("Draft")
plt.ylabel("Area")
plt.figure("Sec VM vs Draft")
plt.plot(self.rangeDrafts,self.VM[i],label=str(i))
plt.title("Vertical Moment abt BL")
plt.xlabel("Draft")
plt.ylabel("Moment")
plt.figure("Sec TM vs Draft")
plt.plot(self.rangeDrafts,self.TM[i],label=str(i))
plt.title("Transverse Moment abt CL (for Half Section only)")
plt.xlabel("Draft")
plt.ylabel("Moment")
plt.figure("Sec Girth vs Draft")
plt.plot(self.rangeDrafts,self.CL[i],label=str(i))
plt.title("Girth Length")
plt.xlabel("Draft")
plt.ylabel("Girth")
plt.figure("Sec Zc vs Draft")
plt.plot(self.rangeDrafts,self.ZC[i],label=str(i))
plt.title("Z Centroid from BL ")
plt.xlabel("Draft")
plt.ylabel("Zc")
plt.figure("Sec Yc vs Draft")
plt.plot(self.rangeDrafts,self.YC[i],label=str(i))
plt.title("Y Centroid from CL (for Half Section only)")
plt.xlabel("Draft")
plt.ylabel("Yc")
plt.figure("Sec Ar vs Draft")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,'Sect_Areas.png'),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("Sec VM vs Draft")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,'Sect_VertMom.png'),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("Sec TM vs Draft")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,'Sect_TransMom.png'),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("Sec Girth vs Draft")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,'Sect_Girth.png'),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("Sec Zc vs Draft")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,'Sect_ZCent.png'),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("Sec Yc vs Draft")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,'Sect_YCent.png'),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.close('all')
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# Function to Write HULL Hydrostatics to file
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def writeHullHydroStaticsToFile(self,fs,shipGrid):
# Py-NAT 2021a : PRAVEEN KUMAR CH
print("\n\t\tPyNAT : Writing Hull Hydrostatic Data to File:\t...\\",fs.ohs_path)
fp=open(fs.ohs_path,"at")
fp.write('\n\n\nHull Hydrostatics :\t')
fp.write('\nDraft MS \tTrim \t')
fp.write(' Draft AP \tDraft FP \t')
fp.write( 'Volume \tMass \tWet Hull Ar.\t')
fp.write( 'LCB \tTCB \tVCB \t')
fp.write( 'WPA \tLCF \t')
fp.write( 'IXX0 \tIXXG \tIYY0 \t')
fp.write( 'BM_L \tBM_T \tKM_L \tKM_T \t')
fp.write( 'TPC \tMCT \t')
fp.write( '')
for i in range(self.nTrims):
for k in range(self.nDraft):
fp.write("\n%10.3E\t%10.3E\t"%(self.rangeDrafts[k],self.rangeTrims[i]))
fp.write( "%10.3E\t%10.3E\t"%(self.draftAP[i][k],self.draftFP[i][k]))
fp.write( "%10.3E\t%10.3E\t%10.3E\t"%(self.VOL[i][k],self.MASS[i][k],self.WSA[i][k]))
fp.write( "%10.3E\t%10.3E\t%10.3E\t"%(self.LCB[i][k],self.TCB[i][k],self.VCB[i][k]))
fp.write( "%10.3E\t%10.3E\t"%(self.WPA[i][k],self.LCF[i][k]))
fp.write( "%10.3E\t%10.3E\t%10.3E\t"%(self.IXX0[i][k],self.IXXG[i][k],self.IYY0[i][k]))
fp.write( "%10.3E\t%10.3E\t%10.3E\t%10.3E\t"%(self.BML[i][k],self.BMT[i][k],self.KML[i][k],self.KMT[i][k]))
fp.write( "%10.3E\t%10.3E\t"%(self.TPC[i][k],self.MCT[i][k]))
fp.close()
plt.figure("Vol Disp vs Draft")
for i in range(self.nTrims):
hstr = format(self.rangeTrims[i],"6.4f")
plt.plot(self.rangeDrafts,self.VOL[i],label='Volume@Trim='+hstr)
plt.title("Vol Disp vs Draft")
plt.xlabel("Draft@MS")
plt.ylabel("Volume")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,"HS_VolDisp.png"),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("Mass Disp vs Draft")
for i in range(self.nTrims):
hstr = format(self.rangeTrims[i],"6.4f")
plt.plot(self.rangeDrafts,self.MASS[i],label='Mass@Trim='+hstr)
plt.title("Mass Disp vs Draft")
plt.xlabel("Draft@MS")
plt.ylabel("Mass")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,"HS_MassDisp.png"),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("Wet Area vs Draft")
for i in range(self.nTrims):
hstr = format(self.rangeTrims[i],"6.4f")
plt.plot(self.rangeDrafts,self.WSA[i],label='WSA@Trim='+hstr)
plt.title("Wetted Surface Area vs Draft")
plt.xlabel("Draft@MS")
plt.ylabel("Wet Surf Area")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,"HS_WetArea.png"),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("WPA vs Draft")
for i in range(self.nTrims):
hstr = format(self.rangeTrims[i],"6.4f")
plt.plot(self.rangeDrafts,self.WPA[i],label='Aw@Trim='+hstr)
plt.title("Water Plane Area vs Draft")
plt.xlabel("Draft@MS")
plt.ylabel("WPA")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,"HS_WPA.png"),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("LCB vs Draft")
for i in range(self.nTrims):
hstr = format(self.rangeTrims[i],"6.4f")
plt.plot(self.rangeDrafts,self.LCB[i]-shipGrid.MS,label='LCB@Trim='+hstr)
plt.title("LCB (Frm Mid Ship) vs Draft")
plt.xlabel("Draft@MS")
plt.ylabel("LCB")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,"HS_LCB.png"),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("LCF vs Draft")
for i in range(self.nTrims):
hstr = format(self.rangeTrims[i],"6.4f")
plt.plot(self.rangeDrafts,self.LCF[i]-shipGrid.MS,label='LCF@Trim='+hstr)
plt.title("LCF (Frm Mid Ship) vs Draft")
plt.xlabel("Draft@MS")
plt.ylabel("LCF")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,"HS_LCF.png"),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("VCB vs Draft")
for i in range(self.nTrims):
hstr = format(self.rangeTrims[i],"6.4f")
plt.plot(self.rangeDrafts,self.VCB[i],label='VCB@Trim='+hstr)
plt.title("VCB (Frm Base) vs Draft")
plt.xlabel("Draft@MS")
plt.ylabel("VCB")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,"HS_VCB.png"),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("TCB vs Draft")
for i in range(self.nTrims):
hstr = format(self.rangeTrims[i],"6.4f")
plt.plot(self.rangeDrafts,self.TCB[i],label='TCB@Trim='+hstr)
plt.title("TCB From CL vs Draft")
plt.xlabel("Draft@MS")
plt.ylabel("TCB")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,"HS_TCB.png"),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("TPC vs Draft")
for i in range(self.nTrims):
hstr = format(self.rangeTrims[i],"6.4f")
plt.plot(self.rangeDrafts,self.TPC[i],label='TPC@Trim='+hstr)
plt.title("Tons Per CM immersion vs Draft")
plt.xlabel("Draft@MS")
plt.ylabel("TPC")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,"HS_TPC.png"),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("MCT vs Draft")
for i in range(self.nTrims):
hstr = format(self.rangeTrims[i],"6.4f")
plt.plot(self.rangeDrafts,self.MCT[i],label='MCT@Trim='+hstr)
plt.title("Mom. to Change Trim vs Draft")
plt.xlabel("Draft@MS")
plt.ylabel("MCT")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,"HS_MCT.png"),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("KMT vs Draft")
for i in range(self.nTrims):
hstr = format(self.rangeTrims[i],"6.4f")
plt.plot(self.rangeDrafts,self.KMT[i],label='KMT@Trim='+hstr)
plt.title("KM Trans.")
plt.xlabel("Draft@MS")
plt.ylabel("KM_T")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,"HS_KMT.png"),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("KML vs Draft")
for i in range(self.nTrims):
hstr = format(self.rangeTrims[i],"6.4f")
plt.plot(self.rangeDrafts,self.KML[i],label='KML@Trim='+hstr)
plt.title("KM Long.")
plt.xlabel("Draft@MS")
plt.ylabel("KM_L")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,"HS_KML.png"),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("BMT vs Draft")
for i in range(self.nTrims):
hstr = format(self.rangeTrims[i],"6.4f")
plt.plot(self.rangeDrafts,self.BMT[i],label='BMT@Trim='+hstr)
plt.title("Trans. Metacentric Radius")
plt.xlabel("Draft@MS")
plt.ylabel("BM_T")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,"HS_BMT.png"),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.figure("BML vs Draft")
for i in range(self.nTrims):
hstr = format(self.rangeTrims[i],"6.4f")
plt.plot(self.rangeDrafts,self.BML[i],label='BML@Trim='+hstr)
plt.title("Long. Metacentric Radius")
plt.xlabel("Draft@MS")
plt.ylabel("BM_L")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.hs_dir,"HS_BML.png"),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.close('all')
# --------------------------------------------------------------------------------------
# Py-NAT 2021a : PRAVEEN KUMAR CH
# ------------------------------------------------------------------------------------------
+136
View File
@@ -0,0 +1,136 @@
'''
************************************************************************************
File : LAS_GZ.py
File Purpose : Define the Class "LAS_GZ"
Class Purpose :
-> Read the Load Case Data from the File set_LC.dat
-> Interpolate KN values at various heel angles for the given displacement
-> Compute GZ values
-> write GZ data to file
-> Plot GZ data in curves
App : PyNAT - Python Based Naval Architecture Tools
Version : 2021.0
Paradigm : Object Based Framework
Author : Praveen Kumar Ch
***************************************************************************************
'''
import numpy as np
from scipy import interpolate
import matplotlib.pyplot as plt
from HullGeometry import HullGeometry
import math as math
import os
# Py-NAT 2021a : PRAVEEN KUMAR CH
class LAS_GZ:
# --------------------------------------------------------------------------------------
# The Constructor
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def __init__(self,fs,GivenShip,knData,ep):
self.readFromFile(fs)
self.compute(GivenShip,knData,ep)
self.writeToFile(fs,knData)
# --------------------------------------------------------------------------------------
# Function to Read Load Case Data from File
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def readFromFile(self,fs):
print("\t\tReading Load Condition from file...")
# Reading the Solver properties
fp=open(fs.ilc_path,"rt")
lines=fp.readlines()
fp.close()
self.nCases=len(lines)
self.Mass=list()
self.KG=list()
for i in range(self.nCases):
nums=lines[i].split("\t")
self.Mass.append(float(nums[0].rstrip("\n")))
self.KG.append(float(nums[1].rstrip("\n")))
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# Function to Compute GZ Data
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def compute(self,GivenShip,knData,ep):
print("\n\t\tComputing GZ Data")
# Interpolate KN at each Heel
self.KN=np.ones((self.nCases,knData.nHeel),dtype=np.float64)
self.GZ=np.ones((self.nCases,knData.nHeel),dtype=np.float64)
# Py-NAT 2021a : PRAVEEN KUMAR CH
for iha in range(knData.nHeel):
x=np.copy(knData.MASS[iha,:])
y=np.copy(knData.KN[iha,:])
ind=np.argsort(x,axis=0)
x=np.take_along_axis(x,ind,axis=0)
y=np.take_along_axis(y,ind,axis=0)
kn_fMass=interpolate.splrep(x,y,k=3)
for ics in range(self.nCases):
self.KN[ics][iha]=interpolate.splev(self.Mass[ics],kn_fMass,der=0)
phi=abs(knData.rangeHeels[iha])
self.GZ[ics][iha]=self.KN[ics][iha]-self.KG[ics]*math.sin(phi)
#print("\n\t\t\tKN=",self.KN[ics][iha])
print("\n\t\t\tKG= %10.4f Disp=%10.4f Heel=%6.4f GZ=%10.4f"%(self.KG[ics],self.Mass[ics],knData.rangeHeels[iha],self.GZ[ics][iha]))
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# Function to Write GZ Data to File
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def writeToFile(self,fs,knData):
print("\n\t\tPyNAT: Writing GZ Data to File:\t...\\",fs.ogz_path)
if not os.path.exists(fs.las_dir):
os.makedirs(fs.las_dir)
# Py-NAT 2021a : PRAVEEN KUMAR CH
if(knData.techq=="DIRECT"):
filepath=fs.ogz_path
plotpath=os.path.join(fs.las_dir,"LAS_GZ.png")
else:
filepath=fs.ogz_fast_path
plotpath=os.path.join(fs.las_dir,"LAS_GZ_FAST.png")
fp=open(filepath,'wt')
fp.write("\nPyNAT: Righting Lever (GZ) Curve Data")
for ics in range(self.nCases):
fp.write("\nMass Displacement=%f"%(self.Mass[ics]))
fp.write("\nVCG (KG) = %f"%(self.KG[ics]))
fp.write('\nHeel Angle\tGZ \t')
for i in range(knData.nHeel):
fp.write("\n%10.3E\t%10.3E\t"%(knData.rangeHeels[i]*180/math.pi,self.GZ[ics][i]))
plt.figure("GZ Curve")
hst=format(ics,"2d")
plt.plot(knData.rangeHeels*180/math.pi,self.GZ[ics,:],label="Case No"+hst)
plt.title("Righting Lever (GZ) Curve")
plt.xlabel("Heel Angle")
plt.ylabel("GZ")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(plotpath,
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
fp.close()
plt.close('all')
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
+332
View File
@@ -0,0 +1,332 @@
'''
************************************************************************************
File : LAS_KN.py
File Purpose : Define the Class "LAS_KN"
with Direct Integration technique to compute heeled section prop.
Class Purpose :
-> Compute and store KN values over a gien range of heel angles for each given draft
-> Function to Compute Intersection of Water Line with Section Curves
at various floating conditions
-> Computations are done for Floating Conditions Defined by
-> Draft
-> Heel
-> The range of Drafts and Heel are read from the File "Set_LAS_KN.dat"
-> computations are performed for each draft and Heel combination
-> Functions to write the Large angle Stability Results to File "Res_LAS_KN.dat"
-> Plots and Saves KN curves and as image files of format ".png"
App : PyNAT - Python Based Naval Architecture Tools
Version : 2021.0
Paradigm : Object Based Framework
Author : Praveen Kumar Ch
***************************************************************************************
'''
import numpy as np
from scipy.interpolate import interp1d
from scipy.integrate import quad
import matplotlib.pyplot as plt
from HullGeometry import HullGeometry
import math as math
import os
# Py-NAT 2021a : PRAVEEN KUMAR CH
class LAS_KN_0B:
# --------------------------------------------------------------------------------------
# The Constructor
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def __init__(self,fs,GivenShip,ep):
self.techq="DIRECT"
self.readFromFile(fs)
self.compute(GivenShip,ep)
self.writeToFile(fs)
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# The Method to Read the Data from File
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def readFromFile(self,fs):
print("\n\t\tPyNAT: Reading File:\t...\\",fs.ikn_path)
# Reading the Solver properties
fp=open(fs.ikn_path,"rt")
lines=fp.readlines()
fp.close()
nums=lines[0].split(",")
self.nHeel=len(nums)
self.rangeHeels=np.array(range(self.nHeel),dtype=np.float64)
for i in range(self.nHeel):
self.rangeHeels[i] =float(nums[i])*math.pi/180
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# The Method to Compute KN Data
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def compute(self,GivenShip,ep):
print("\n\t\tPyNAT: Computing KN Curves Data")
# Finding the CL-WL intercept range for each heel angle
self.nDraft=11
self.rangeDrafts=np.zeros((self.nHeel,self.nDraft))
for iha in range(self.nHeel):
if(abs(self.rangeHeels[iha])%(math.pi/2)<=0.0001 and abs(self.rangeHeels[iha])>=0.0001):
self.rangeHeels[iha]-=0.017453292
# Finding the Limits of Draft at CL
dclmin=0
dclmax=0
for ist in range(GivenShip.nst):
for ipt in range(GivenShip.npts[ist]):
dcl=abs(GivenShip.y[ist][ipt]*math.tan(self.rangeHeels[iha]))
db=-dcl+GivenShip.z[ist][ipt]
da=dcl+GivenShip.z[ist][ipt]
if(db<dclmin):
dclmin=db
if(da>dclmax):
dclmax=da
delDraft=(dclmax-dclmin)/(self.nDraft-1)
dclmin=dclmin+delDraft/2
dclmax=dclmax-delDraft/2
# creating a range of drafts
self.rangeDrafts[iha,:]=np.linspace(dclmin,dclmax,self.nDraft,endpoint=True)
#print(self.rangeDrafts)
self.VOL=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.MASS=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.LCB=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.TCB=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.VCB=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.WPA=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.WSA=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.KN=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.m=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.c=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.zN=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.yN=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
# Compute the Water Line Intersections for each heel angle
for iha in range(self.nHeel):
# For each Draft
for idr in range(self.nDraft):
zd=self.rangeDrafts[iha][idr]
phi=self.rangeHeels[iha]
BR=np.zeros(GivenShip.nst,dtype=np.float64)
Ar=np.zeros(GivenShip.nst,dtype=np.float64)
LM=np.zeros(GivenShip.nst,dtype=np.float64)
TM=np.zeros(GivenShip.nst,dtype=np.float64)
VM=np.zeros(GivenShip.nst,dtype=np.float64)
CL=np.zeros(GivenShip.nst,dtype=np.float64)
#print("------\t------\t------\t------\t------\t------\t------\t------\t------\t------\t")
#print("\t\tZd=%12.6f\tphi=%12.6f"%(zd,phi*180/math.pi))
# Py-NAT 2 021a : PRAVEEN KUMAR CH
#print("------\t------\t------\t------\t------\t------\t------\t------\t------\t------\t")
for ist in range(GivenShip.nst):
if(phi<=0):
side=1
else:
side=-1
secData=self.compImmersedSectionProperties(GivenShip.secCrv[ist],zd,phi,side)
BR[ist]+=secData[0]
Ar[ist]+=secData[1]
LM[ist]+=secData[2]
TM[ist]+=secData[3]
VM[ist]+=secData[4]
CL[ist]+=secData[5]
#print("iSta=%5d, BRW=%10.5f, Ar=%10.5f, LM=%10.5f, TM=%10.5f, VM=%10.5f, CL=%10.5f"%(ist,BR[ist],Ar[ist],LM[ist],TM[ist],VM[ist],CL[ist]))
# Integrating the Areas and Moments over the length
Ar_fX=interp1d(GivenShip.x,Ar,kind='cubic')
sq=quad(Ar_fX,GivenShip.x[0],GivenShip.x[-1])
self.VOL[iha,idr]=sq[0]
self.MASS[iha,idr]=self.VOL[iha,idr]*ep.waterDensity
Sa_fX=interp1d(GivenShip.x,CL,kind='cubic')
sq=quad(Sa_fX,GivenShip.x[0],GivenShip.x[-1])
self.WSA[iha,idr]=sq[0]
if self.VOL[iha,idr]!=0:
lm_fX=interp1d(GivenShip.x,LM,kind='cubic')
sq=quad(lm_fX,GivenShip.x[0],GivenShip.x[-1])
self.LCB[iha,idr]=sq[0]/self.VOL[iha,idr]
tm_fX=interp1d(GivenShip.x,TM,kind='cubic')
sq=quad(tm_fX,GivenShip.x[0],GivenShip.x[-1])
self.TCB[iha,idr]=sq[0]/self.VOL[iha,idr]
vm_fX=interp1d(GivenShip.x,VM,kind='cubic')
sq=quad(vm_fX,GivenShip.x[0],GivenShip.x[-1])
self.VCB[iha,idr]=sq[0]/self.VOL[iha,idr]
else:
self.LCB[iha,idr]=0
self.TCB[iha,idr]=0
self.VCB[iha,idr]=0
wpa_fX=interp1d(GivenShip.x,BR,kind='cubic')
sq=quad(wpa_fX,GivenShip.x[0],GivenShip.x[-1])
self.WPA[iha,idr]=sq[0]
# Py-NAT 2021 a : PRAVEEN KUMAR CH
# Finding KN
self.m[iha,idr]=math.tan(math.pi/2-phi)
self.c[iha,idr]=self.VCB[iha,idr]-self.m[iha,idr]*self.TCB[iha,idr]
self.zN[iha,idr]=self.c[iha,idr]/(1+self.m[iha,idr]**2)
self.yN[iha,idr]=-self.m[iha,idr]*self.zN[iha,idr]
self.KN[iha,idr]=math.sqrt(self.zN[iha,idr]**2+self.yN[iha,idr]**2)
print("\n\t\t\tVol. Disp=%12.6f\tHeel=%12.6f\tKN=%12.6f"%(self.VOL[iha,idr],phi*180/math.pi,self.KN[iha,idr]))
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# Function to compute heeled and immersed half section properties
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def compImmersedSectionProperties(self,sec,zd,ang,side):
# Initialise return Variables with Default Values
hBw=0
Ar=0
LM=0
VM=0
TM=0
CL=0
YC=0
ZC=0
dz=0.25
z=np.arange(sec.Z[0],sec.Z[-1],dz)
da=np.arange(z.size,dtype=np.float64)
dtm=np.arange(z.size,dtype=np.float64)
dvm=np.arange(z.size,dtype=np.float64)
# print("\nThe Heeled Section Calculations for %f"%(sec.X))
# print("Zd=",zd)
# print("phi=",ang*180/math.pi)
# print("side=",side)
if ang!=0:
for i in range(z.size):
yw=(z[i]-zd)*math.tan(ang-math.pi/2)
ycp=sec.getHalfBreadth(z[i])
ycs=-ycp
if (side>=0):
# Measure strip ends Left Side of WL
ya=max(ycp,yw)
yb=max(ycs,yw)
else:
# Measure strip ends Right Side of WL
ya=min(ycp,yw)
yb=min(ycs,yw)
da[i]=max(ya-yb,0)
dtm[i]=da[i]*(ya+yb)/2
dvm[i]=da[i]*z[i]
# Py-NAT 2021a : PRAVEEN KUMAR CH
#print("yw=",yw,"yc=",yc,"ya=",ya,"yb=",yb,"da=",da[i])
a_fz=interp1d(z,da,kind='cubic')
sq=quad(a_fz,z[0],z[-1])
Ar=sq[0]
vm_fz=interp1d(z,dvm,kind='cubic')
sq=quad(vm_fz,z[0],z[-1])
VM=sq[0]
tm_fz=interp1d(z,dtm,kind='cubic')
sq=quad(tm_fz,z[0],z[-1])
TM=sq[0]
LM=Ar*sec.X
if Ar!=0:
YC=TM/Ar
ZC=VM/Ar
secData=list([hBw,Ar,LM,TM,VM,CL,YC,ZC])
else :
secData=sec.sectionHydroStatics(zd)
secData[0]=2*secData[0]
secData[1]=2*secData[1]
secData[2]=2*secData[2]
secData[3]=0
secData[4]=2*secData[4]
secData[5]=2*secData[5]
secData[6]=0
if secData[0]!=0:
secData[7]=secData[4]/secData[1]
else:
secData[7]=0
# print("SecData=",secData)
return secData
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# The Method to Read the Data from File
# Py-NAT 2021a : PRAVEEN KUMAR CH
# --------------------------------------------------------------------------------------
def writeToFile(self,fs):
print("\n\t\tPyNAT: Writing KN Curves Data to File:\t ...\\",fs.okn_path)
if not os.path.exists(fs.las_dir):
os.makedirs(fs.las_dir)
fp=open(fs.okn_path,"wt")
fp.write('\nPy-NAT: Large angle Stability - KN Curves :\t')
fp.write('\nDraft \tHeel \tKN \t')
fp.write( 'zN \tyN \t')
fp.write( 'm \tc \tWPA \t')
fp.write( 'LCB \tTCB \tVCB \t')
fp.write( 'Volume \tMass \tWet Area \t')
for i in range(self.nHeel):
for k in range(self.nDraft):
# Py-NAT 2021a : PRAVEEN KUMAR CH
fp.write("\n%10.3E\t%10.3E\t%10.3E\t"%(self.rangeDrafts[i][k],self.rangeHeels[i],self.KN[i][k]))
fp.write( "%10.3E\t%10.3E\t"%(self.zN[i][k],self.yN[i][k]))
fp.write( "%10.3E\t%10.3E\t%10.3E\t"%(self.m[i][k],self.c[i][k],self.WPA[i][k]))
fp.write( "%10.3E\t%10.3E\t%10.3E\t"%(self.LCB[i][k],self.TCB[i][k],self.VCB[i][k]))
fp.write( "%10.3E\t%10.3E\t%10.3E\t"%(self.VOL[i][k],self.MASS[i][k],self.WSA[i][k]))
fp.close()
plt.figure("KN CURVES")
# PyNAT 2021 a : PraveenKumarCH
for i in range(self.nHeel):
hstr = format(self.rangeHeels[i]*180/math.pi,"0.2f")
plt.plot(self.MASS[i,:],self.KN[i,:],label='KN@Heel='+hstr)
plt.title("Cross Curves of Stability")
plt.xlabel("Displacement")
plt.ylabel("KN")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.las_dir,"LAS_KN.png"),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.close('all')
# ----------------------------------------------------------------------------------------
+499
View File
@@ -0,0 +1,499 @@
'''
************************************************************************************
File : LAS_KN_1A.py
File Purpose : Define the Class "LAS_KN"
with hybrid technique to compute heeled section parameters
Class Purpose :
-> Compute and store KN values over a gien range of heel angles for each given draft
-> Function to Compute Intersection of Water Line with Section Curves
at various floating conditions
-> Computations are done for Floating Conditions Defined by
-> Draft
-> Heel
-> The range of Drafts and Heel are read from the File "Set_LAS_KN.dat"
-> computations are performed for each draft and Heel combination
-> Functions to write the Large angle Stability Results to File "Res_LAS_KN.dat"
-> Plots and Saves KN curves and as image files of format ".png"
App : PyNAT - Python Based Naval Architecture Tools
Version : 2021.0
Paradigm : Object Based Framework
Author : Praveen Kumar Ch
***************************************************************************************
'''
import numpy as np
from scipy.interpolate import interp1d
from scipy.integrate import quad
import matplotlib.pyplot as plt
from HullGeometry import HullGeometry
import math as math
import os
class LAS_KN_1A:
# --------------------------------------------------------------------------------------
# The Constructor
# PyNAT 2021 a : PraveenKumarCH
# --------------------------------------------------------------------------------------
def __init__(self,fs,GivenShip,ep):
self.techq="FAST"
self.readFromFile(fs)
self.compute(GivenShip,ep)
self.writeToFile(fs)
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# The Method to Read the Data from File
# PyNAT 2021 a : PraveenKumarCH
# --------------------------------------------------------------------------------------
def readFromFile(self,fs):
print("\n\t\tPyNAT: Reading File:\t...\\",fs.ikn_path)
# Reading the Solver properties
fp=open(fs.ikn_path,"rt")
lines=fp.readlines()
fp.close()
nums=lines[0].split(",")
self.nHeel=len(nums)
self.rangeHeels=np.array(range(self.nHeel),dtype=np.float64)
for i in range(self.nHeel):
self.rangeHeels[i] =float(nums[i])*math.pi/180
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# The Method to Compute KN Data
# PyNAT 2021 a : PraveenKumarCH
# --------------------------------------------------------------------------------------
def compute(self,GivenShip,ep):
print("\n\t\tPyNAT: Computing KN Curves Data")
# Finding the CL-WL intercept range for each heel angle
self.nDraft=11
self.rangeDrafts=np.zeros((self.nHeel,self.nDraft))
for iha in range(self.nHeel):
if(abs(self.rangeHeels[iha])%(math.pi/2)<=0.0001 and abs(self.rangeHeels[iha])>=0.0001):
self.rangeHeels[iha]-=0.017453292
# Finding the Limits of Draft at CL
dclmin=0
dclmax=0
for ist in range(GivenShip.nst):
for ipt in range(GivenShip.npts[ist]):
dcl=abs(GivenShip.y[ist][ipt]*math.tan(self.rangeHeels[iha]))
db=-dcl+GivenShip.z[ist][ipt]
da=dcl+GivenShip.z[ist][ipt]
if(db<dclmin):
dclmin=db
if(da>dclmax):
dclmax=da
delDraft=(dclmax-dclmin)/(self.nDraft-1)
dclmin=dclmin+delDraft/2
dclmax=dclmax-delDraft/2
# creating a range of drafts
self.rangeDrafts[iha,:]=np.linspace(dclmin,dclmax,self.nDraft,endpoint=True)
# print(iha,self.rangeDrafts[iha,:])
self.VOL=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.MASS=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.LCB=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.TCB=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.VCB=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.WPA=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.WSA=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.KN=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.m=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.c=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.zN=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
self.yN=np.zeros([self.nHeel,self.nDraft],dtype=np.float64)
# Compute for each heel angle
for iha in range(self.nHeel):
# For each Draft in the draft range
for idr in range(self.nDraft):
zd=self.rangeDrafts[iha][idr]
phi=self.rangeHeels[iha]
BR=np.zeros(GivenShip.nst,dtype=np.float64)
Ar=np.zeros(GivenShip.nst,dtype=np.float64)
LM=np.zeros(GivenShip.nst,dtype=np.float64)
TM=np.zeros(GivenShip.nst,dtype=np.float64)
VM=np.zeros(GivenShip.nst,dtype=np.float64)
CL=np.zeros(GivenShip.nst,dtype=np.float64)
for ist in range(GivenShip.nst):
pwli=self.computeIntersections(GivenShip.secCrv[ist],zd,phi)
swli=self.computeIntersections(GivenShip.secCrv[ist],zd,-phi)
# print("Station no =%5d Heel =%6.3f draft =%6.3f"%(ist,phi,zd),":\n")
# print("Port Side Intersection Points:",pwli)
# print("Starboard Side Intersection Points:",swli)
# print("Praveen Kumar CH PyNAT : HAULT")
# When WL intersects closed section at only two locations
if (len(pwli)==1 and len(swli)==1):
secData=GivenShip.secCrv[ist].sectionHydroStatics(pwli[0])
#print("The Section Prop at Draft Zp",pwli[0],"\n",secData)
ht=zd-pwli[0]
bt=abs(ht*math.tan(math.pi/2-(phi)))
Atr=0.5*ht*bt
hbw=math.sqrt(ht**2+bt**2)
tl=Atr*bt/3
vl=Atr*(zd-ht*2/3)
secData[0]=hbw
secData[1]+=Atr
secData[2]+=Atr*GivenShip.x[ist]
secData[3]+=tl
secData[4]+=vl
#print("ht=%10.5f\tbt=%10.5f\tAtr=%10.5f\tHb=%10.5f\ttl=%10.5f\tvl=%10.5f\t"%(ht,bt,Atr,hbw,tl,vl))
secData2=GivenShip.secCrv[ist].sectionHydroStatics(swli[0])
#print("The Section Prop at Draft Zp",swli[0],"\n",secData2)
ht=zd-swli[0]
bt=abs(ht*math.tan(math.pi/2-(phi)))
Atr=0.5*ht*bt
hbw=math.sqrt(ht**2+bt**2)
tl=Atr*bt/3
vl=Atr*(zd-ht*2/3)
secData2[0]=hbw
secData2[1]+=Atr
secData2[2]+=Atr*GivenShip.x[ist]
secData2[3]+=tl
secData2[4]+=vl
#print("ht=%10.5f\tbt=%10.5f\tAtr=%10.5f\tHb=%10.5f\ttl=%10.5f\tvl=%10.5f\t"%(ht,bt,Atr,hbw,tl,vl))
secData[0]+=secData2[0] # Breadth on WL
secData[1]+=secData2[1] # Area
secData[2]+=secData2[2] # LM
secData[3]-=secData2[3] # TM
secData[4]+=secData2[4] # VM
secData[5]+=secData2[5] # CL
if(abs(phi)>=math.pi/2):
# In case if the ship is at a capsizing heel angle...
fullSecData=GivenShip.secCrv[ist].sectionHydroStatics(GivenShip.secCrv[ist].Z[-1])
secData[1]=2*fullSecData[1]-secData[1]
secData[2]=2*fullSecData[2]-secData[2]
secData[3]=-secData[3]
secData[4]=2*fullSecData[4]-secData[4]
secData[5]=2*fullSecData[5]-secData[5]
if secData[1]!=0:
secData[6]=secData[3]/secData[1] # YC
secData[7]=secData[4]/secData[1] # ZC
else:
secData[6]=0 # YC
secData[7]=0 # ZC
#print("Section Data Computed using Plane Geometry:\n",secData)
else:
if(phi<=0):
side=1
else:
side=-1
secData=self.compImmersedSectionProperties(GivenShip.secCrv[ist],zd,phi,side)
# This portion of code for computation of Girth length of immersed section
# This is improper and needs to be improved...
# Since not a part of KN calculations so ignored for now
secData[5]=0
if(len(pwli)!=0):
secData[5]+=GivenShip.secCrv[ist].getGirthLength(pwli[-1])
if(len(swli)!=0):
secData[5]+=GivenShip.secCrv[ist].getGirthLength(swli[-1])
# This portion of code for computation of section Breadth on water plane
# This is improper and needs to be improved...
# Since not a part of KN calculations so ignored for now
secData[0]=0
pwli.extend(swli)
for i in range(0,len(pwli)-1,2):
dy=(pwli[i]-pwli[i+1])/abs(math.cos(phi-math.pi/2))
secData[0]+=dy
#print("Section Data Computed using Numerical Integration:\n",secData)
BR[ist]+=secData[0]
Ar[ist]+=secData[1]
LM[ist]+=secData[2]
TM[ist]+=secData[3]
VM[ist]+=secData[4]
CL[ist]+=secData[5]
#print("iSta=%5d, BRW=%10.5f, Ar=%10.5f, LM=%10.5f, TM=%10.5f, VM=%10.5f, CL=%10.5f"%(ist,BR[ist],Ar[ist],LM[ist],TM[ist],VM[ist],CL[ist]))
# Integrating the Areas and Moments over the length
Ar_fX=interp1d(GivenShip.x,Ar,kind='cubic')
sq=quad(Ar_fX,GivenShip.x[0],GivenShip.x[-1])
self.VOL[iha,idr]=sq[0]
self.MASS[iha,idr]=self.VOL[iha,idr]*ep.waterDensity
Sa_fX=interp1d(GivenShip.x,CL,kind='cubic')
sq=quad(Sa_fX,GivenShip.x[0],GivenShip.x[-1])
self.WSA[iha,idr]=sq[0]
if self.VOL[iha,idr]!=0:
lm_fX=interp1d(GivenShip.x,LM,kind='cubic')
sq=quad(lm_fX,GivenShip.x[0],GivenShip.x[-1])
self.LCB[iha,idr]=sq[0]/self.VOL[iha,idr]
tm_fX=interp1d(GivenShip.x,TM,kind='cubic')
sq=quad(tm_fX,GivenShip.x[0],GivenShip.x[-1])
self.TCB[iha,idr]=sq[0]/self.VOL[iha,idr]
vm_fX=interp1d(GivenShip.x,VM,kind='cubic')
sq=quad(vm_fX,GivenShip.x[0],GivenShip.x[-1])
self.VCB[iha,idr]=sq[0]/self.VOL[iha,idr]
else:
self.LCB[iha,idr]=0
self.TCB[iha,idr]=0
self.VCB[iha,idr]=0
wpa_fX=interp1d(GivenShip.x,BR,kind='cubic')
sq=quad(wpa_fX,GivenShip.x[0],GivenShip.x[-1])
self.WPA[iha,idr]=sq[0]
# Finding KN
self.m[iha,idr]=math.tan(math.pi/2-phi)
self.c[iha,idr]=self.VCB[iha,idr]-self.m[iha,idr]*self.TCB[iha,idr]
self.zN[iha,idr]=self.c[iha,idr]/(1+self.m[iha,idr]**2)
self.yN[iha,idr]=-self.m[iha,idr]*self.zN[iha,idr]
self.KN[iha,idr]=math.sqrt(self.zN[iha,idr]**2+self.yN[iha,idr]**2)
print("\n\t\t\tVol. Disp=%12.6f\tHeel=%12.6f\tKN=%12.6f"%(self.VOL[iha,idr],phi*180/math.pi,self.KN[iha,idr]))
print("\n\t\t\t\tyn=%10.5f \t zn=%10.5f"%(self.yN[iha,idr],self.zN[iha,idr]))
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# Function to compute heeled and immersed half section properties
# PyNAT 2021 a : PraveenKumarCH
# --------------------------------------------------------------------------------------
def compImmersedSectionProperties(self,sec,zd,ang,side):
# Initialise return Variables with Default Values
hBw=0
Ar=0
LM=0
VM=0
TM=0
CL=0
YC=0
ZC=0
dz=0.25
z=np.arange(sec.Z[0],sec.Z[-1],dz)
da=np.arange(z.size,dtype=np.float64)
dtm=np.arange(z.size,dtype=np.float64)
dvm=np.arange(z.size,dtype=np.float64)
# print("\nThe Heeled Section Calculations for %f"%(sec.X))
# print("Zd=",zd)
# print("phi=",ang*180/math.pi)
# print("side=",side)
# PyNAT 2021 a : PraveenKumarCH
if ang!=0:
for i in range(z.size):
yw=(z[i]-zd)*math.tan(ang-math.pi/2)
ycp=sec.getHalfBreadth(z[i])
ycs=-ycp
if (side>=0):
# Measure strip ends Left Side of WL
ya=max(ycp,yw)
yb=max(ycs,yw)
else:
# Measure strip ends Right Side of WL
ya=min(ycp,yw)
yb=min(ycs,yw)
da[i]=max(ya-yb,0)
dtm[i]=da[i]*(ya+yb)/2
dvm[i]=da[i]*z[i]
#print("yw=",yw,"yc=",yc,"ya=",ya,"yb=",yb,"da=",da[i])
a_fz=interp1d(z,da,kind='cubic')
sq=quad(a_fz,z[0],z[-1])
Ar=sq[0]
vm_fz=interp1d(z,dvm,kind='cubic')
sq=quad(vm_fz,z[0],z[-1])
VM=sq[0]
tm_fz=interp1d(z,dtm,kind='cubic')
sq=quad(tm_fz,z[0],z[-1])
TM=sq[0]
LM=Ar*sec.X
if Ar!=0:
YC=TM/Ar
ZC=VM/Ar
secData=list([hBw,Ar,LM,TM,VM,CL,YC,ZC])
else :
secData=sec.sectionHydroStatics(zd)
secData[0]=2*secData[0]
secData[1]=2*secData[1]
secData[2]=2*secData[2]
secData[3]=0
secData[4]=2*secData[4]
secData[5]=2*secData[5]
secData[6]=0
if secData[0]!=0:
secData[7]=secData[4]/secData[1]
else:
secData[7]=0
# print("SecData=",secData)
return secData
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# The Method to predict water line intersection of a heeled section
# PyNAT 2021 a : PraveenKumarCH
# --------------------------------------------------------------------------------------
def computeIntersections(self,sec,zd,ang):
# Tolerance to check intersection
tol=0.001
# List of Intersection Z coordinates
inPts=list()
# If angle is zero i.e., zero heel angle
if (math.tan(ang)==0):
inPts.append(zd)
return inPts
# pre calculation of slope of water line
tanang=math.tan(ang-math.pi/2)
# Check for Water line cutting the bottom base line of section
z1=sec.Z[0]
yC=sec.getHalfBreadth(z1)
yW=(z1-zd)*tanang
if(yW<(yC-tol) and yW>=0):
inPts.append(z1)
# Check for water line cutting the section curve
for i in range(sec.N-1):
# take each pair of consecutive points
z1=sec.Z[i]
z2=sec.Z[i+1]
dy1=sec.getHalfBreadth(z1)-(z1-zd)*tanang
dy2=sec.getHalfBreadth(z2)-(z2-zd)*tanang
#print("z1=%10.5f,yc1=%10.5f,yw1=%10.5f,dy1=%10.5f,z2=%10.5f,yc2=%10.5f,yw2=%10.5f,dy2=%10.5f"%(z1,yc1,yw1,dy1,z2,yc2,yw2,dy2))
if(dy1*dy2<0):
for _ in range(25):
if abs(dy1)<=tol:
inPts.append(z1)
#print("Appended z1",z1)
break
if abs(dy2)<=tol:
inPts.append(z2)
#print("Appended z2",z2)
break
zm=(z1+z2)/2
dym=sec.getHalfBreadth(zm)-(zm-zd)*tanang
if(dy1*dym<0):
z2=zm
dy2=dym
if(dy2*dym<0):
z1=zm
dy1=dym
#print("z1=%10.5f,dy1=%10.5f,z2=%10.5f,dy2=%10.5f"%(z1,dy1,z2,dy2))
# Check for Water line cutting the top deck line
z1=sec.Z[-1]
yC=sec.getHalfBreadth(z1)
yW=(z1-zd)*tanang
if(yW<(yC-tol) and yW>=0):
inPts.append(z1)
# Return List of Points
return inPts
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# The Method to Read the Data from File
# PyNAT 2021 a : PraveenKumarCH
# --------------------------------------------------------------------------------------
def writeToFile(self,fs):
print("\n\t\tPyNAT: Writing KN Curves Data to File:\t ...\\",fs.okn_fast_path)
if not os.path.exists(fs.las_dir):
os.makedirs(fs.las_dir)
fp=open(fs.okn_fast_path,"wt")
fp.write('\nPy-NAT: Large angle Stability - KN Curves :\t')
fp.write('\nDraft \tHeel \tKN \t')
fp.write( 'zN \tyN \t')
fp.write( 'm \tc \tWPA \t')
fp.write( 'LCB \tTCB \tVCB \t')
fp.write( 'Volume \tMass \tWet Area \t')
for i in range(self.nHeel):
for k in range(self.nDraft):
# PyNAT 2021 a : PraveenKumarCH
fp.write("\n%10.3E\t%10.3E\t%10.3E\t"%(self.rangeDrafts[i][k],self.rangeHeels[i],self.KN[i][k]))
fp.write( "%10.3E\t%10.3E\t"%(self.zN[i][k],self.yN[i][k]))
fp.write( "%10.3E\t%10.3E\t%10.3E\t"%(self.m[i][k],self.c[i][k],self.WPA[i][k]))
fp.write( "%10.3E\t%10.3E\t%10.3E\t"%(self.LCB[i][k],self.TCB[i][k],self.VCB[i][k]))
fp.write( "%10.3E\t%10.3E\t%10.3E\t"%(self.VOL[i][k],self.MASS[i][k],self.WSA[i][k]))
fp.close()
plt.figure("KN CURVES")
for i in range(self.nHeel):
hstr = format(self.rangeHeels[i]*180/math.pi,"0.2f")
plt.plot(self.MASS[i,:],self.KN[i,:],label='KN@Heel='+hstr)
plt.title("Cross Curves of Stability")
plt.xlabel("Displacement")
plt.ylabel("KN")
lg=plt.legend(bbox_to_anchor=(1.05, 1))
plt.savefig(os.path.join(fs.las_dir,"LAS_KN_FAST.png"),
dpi=300,
format='png',
bbox_extra_artists=(lg,),
bbox_inches='tight')
plt.close('all')
# ----------------------------------------------------------------------------------------
+137
View File
@@ -0,0 +1,137 @@
'''
****************************************************************
File : main.py
Purpose : The Base Scipt from where the execution begins
Class Objects are Created to perform analysis
App : PyNAT - Python Based Naval Architecture Tools
Version : 2021a
Paradigm : Object Oriented Model
Author : Praveen Kumar Ch
*****************************************************************
'''
from HullGeometry import HullGeometry
from HydroStatics import HydroStatics
from FileSystem import FileSystem
from LAS_KN_1A import LAS_KN_1A
from LAS_KN_0B import LAS_KN_0B
from LAS_GZ import LAS_GZ
from ENV_PROP import ENV_PROP
import matplotlib.pyplot as plt
import os
import msvcrt as m
import time
#-----------------------------------------------------------------------------
# Creation of 'FileSystem' Object
# Object Contains The File Names and paths to be utilized by program
# See "FileSystem.py"
#-----------------------------------------------------------------------------
t0=time.time()
print("\n\n*********************************************************************")
print(" Py-NAT 2021a")
print("*********************************************************************")
fs=FileSystem()
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Creation of 'ENV_PROP' Object
# Contains Environment properties like water density
#-----------------------------------------------------------------------------
print("\n\nThe Environemnt Properties are being read...\t...\t...\t...\t...")
ep=ENV_PROP(fs)
print("\nEnvironment Properties File Read")
#-----------------------------------------------------------------------------
# Creation of 'HullGeometry' Object
# Object Contains Data defining the ship hull geometry
# object Contains Script to read and prepare Hull Geometry
# Contians Script to fit Splines
# See the Script file "HullGeometry.py"
#-----------------------------------------------------------------------------
print("\n\nThe Hull Geometry is being read and prepared...\t...\t...\t...\t...")
givenShip=HullGeometry(fs)
tend=time.time()
print("\nThe Hull Geometry Data Preperation Complete.")
print("\nCheck the Prepared Hull Geometry Data in Directory:\t...\\",fs.sec_dir)
print("\nTotal Time Elapsed for Hull Geometry Preperations :\t",tend-t0)
print("\nClose Body Plan Plot to Continue.")
plt.show()
#----------------------------------------------------------------------------------
iLoops=0
maxLoops=50
while(iLoops<maxLoops):
# Loop Main Analysis
print("\n\n-----------------------------------------------------------------------")
print("\nAnalysis Loop %d of %d"%(iLoops,maxLoops))
print("\nChoose the Analysis to be Performed:\n")
print("\n\tPress '1' for Hydrostatics")
print("\n\tPress '2' for Large Angle Stability (KN Curves +GZ : Using Fast Technique) ")
print("\n\tPress '3' for Large Angle Stability (KN Curves +GZ : Using Direct Technique) ")
print("\n\tPress '4' for Performing All Calculations")
print("\n\tPress '0' or 'E' or 'e' or 'esc' to Exit")
char=m.getch()
print("\n\tPressed Key =",char)
#-----------------------------------------------------------------------------
# Creation of 'HydroStatics' Object
# Contains Data related to Hydrostatic Calculations
# Contains Code to perform hydrostatic calculations
# See the Script file "HydroStatics.py"
#-----------------------------------------------------------------------------
if char==b'1' or char ==b'4':
t0=time.time()
print("\nComputing Hydrostatics... \t...\t...\t...\t...")
hydrostatics = HydroStatics(fs,givenShip,ep)
print("\nHydrostatic Analysis Complete")
print("\nCheck Results in Directory:\t...\\",fs.hs_dir)
tend=time.time()
print("\nTotal Time Elapsed for Hydrostatic Calculations:\t",tend-t0)
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Creation of 'LAS_KN' Object
# Contains Data related to KN curves
# Contains Code to perform KN calculations
# See the Script file "LAS_KN.py"
#-----------------------------------------------------------------------------
if char==b'2' or char==b'3' or char==b'4':
t0=time.time()
print("\nComputing KN Curves Data...\t...\t...\t...\t...")
if char==b'2':
knData = LAS_KN_1A(fs,givenShip,ep)
else:
knData = LAS_KN_0B(fs,givenShip,ep)
print("\nCross Curves of Stability Calculation Complete")
print("\nCheck Results in Directory:\t...\\",fs.las_dir)
tend=time.time()
print("\nTotal Time Elapsed for KN Curve Calculations:\t",tend-t0)
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Creation of 'LAS_GZ' Object
# Contains Data related to KN curves
# Contains Code to perform KN calculations
# See the Script file "LAS_GZ.py"
#-----------------------------------------------------------------------------
if char==b'2' or char==b'3' or char==b'4':
t0=time.time()
print("\nComputing GZ Curves Data...\t...\t...\t...\t...")
gzData = LAS_GZ(fs,givenShip,knData,ep)
print("\nGZ Curve Calculation Complete")
print("\nCheck Results in Directory:\t...\\",fs.las_dir)
tend=time.time()
print("\nTotal Time Elapsed for GZ Curve Calculations=\t",tend-t0)
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Prompt User to Close the terminal
#-----------------------------------------------------------------------------
if char==b'0' or char==27 or char==b'E' or char==b'e' or char==b'\x1b':
exit()
#-----------------------------------------------------------------------------
# Counting Loops
#-----------------------------------------------------------------------------
iLoops+=1
+253
View File
@@ -0,0 +1,253 @@
'''
************************************************************************************
File : SectionCurves.py
File Purpose : Define the Class "SectionCurves"
Class Purpose :
-> Create and Store Curve Fitting Data for a Section Curve
-> Assumes symmetry: Stores and Computes for half sections only.
-> Section Data Stored
-> X location of the stations
-> Curve point coordinates (Y,Z)
-> Continuity Type at each point C
-> No. of Curvelets and Ends/Knuckle points
-> Spline Curve Fit Data of each Curvelet
-> Functions to compute and Return the Section Properties at a given draft
-> Follwing Section Properties computed at a given draft
-> Half Breadth
-> Area
-> Moments : Long., Trans. , Vertical.
-> Girth Lengths
App : PyNAT - Python Based Naval Architecture Tools
Version : 2021.0
Paradigm : Object Based Framework
Author : Praveen Kumar Ch
*************************************************************************************
'''
import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate
from scipy.integrate import quad
from scipy.misc import derivative
class SectionCurves:
# --------------------------------------------------------------------------------------
# The Constructor for a Section
# PyNAT 2021 a : PraveenKumarCH
# --------------------------------------------------------------------------------------
def __init__(self,X,Y,Z,C):
# Set Data from Arguments
self.N=Y.size
self.X=X
self.Y=Y
self.Z=Z
self.C=C
self.chined=0
self.fittype=1
self.sf=0.25
self.maxOrd=2
# Compute no of Curvelets and their end points
# temp=np.where(self.C==0)
# self.iCE=temp[0]
# self.nCP=self.iCE.size-1
#
self.nCrv=0
self.sCrv=list()
self.eCrv=list()
self.sCrv.append(0)
flag=1
for i in range(1,self.N):
if(flag==1 and self.C[i]==0):
self.nCrv+=1
self.eCrv.append(i)
self.sCrv.append(i)
flag=1
elif(flag ==1 and self.C[i]==-1):
self.nCrv+=1
self.eCrv.append(i)
flag=0
elif(flag==0):
self.sCrv.append(i)
flag=1
# Set Type to Chined Hull Section is all points are knuckles
if self.nCrv==(self.N-1):
self.chined=1
# Fit Splines Function for each curvelet
self.y_fz=list()
self.zy_fz=list()
self.yy_fz=list()
self.L_fz=list()
for i in range(self.nCrv):
s=self.sCrv[i]
e=self.eCrv[i]
if(self.fittype==0):
# Interpolation Function Cubic Spline Fit
e=e+1
self.y_fz.append(interpolate.interp1d(self.Z[s:e],self.Y[s:e],kind='cubic'))
self.zy_fz.append(interpolate.interp1d(self.Z[s:e],self.Z[s:e]*self.Y[s:e],kind='cubic'))
self.yy_fz.append(interpolate.interp1d(self.Z[s:e],self.Y[s:e]*self.Y[s:e]/2,kind='cubic'))
df=np.arange(e-s,dtype=np.float64)
df[0]=(self.y_fz[i](self.Z[s+1])-self.y_fz[i](self.Z[s]))/(self.Z[s+1]-self.Z[s])
df[1:-1]=(self.y_fz[i](self.Z[s+2:e])-self.y_fz[i](self.Z[s:e-2]))/(self.Z[s+2:e]-self.Z[s:e-2])
df[-1]=(self.y_fz[i](self.Z[e-1])-self.y_fz[i](self.Z[e-2]))/(self.Z[e-1]-self.Z[e-2])
self.L_fz.append(interpolate.interp1d(self.Z[s:e],np.sqrt(1+df**2),kind='cubic'))
if(self.fittype==1):
# Smoothing Function Cubic Spline Fit
if(e-s>self.maxOrd):
order=self.maxOrd
else:
order=e-s
e=e+1
self.y_fz.append(interpolate.splrep(self.Z[s:e],self.Y[s:e],k=order,s=self.sf))
self.zy_fz.append(interpolate.splrep(self.Z[s:e],self.Z[s:e]*self.Y[s:e],k=order,s=self.sf))
self.yy_fz.append(interpolate.splrep(self.Z[s:e],self.Y[s:e]*self.Y[s:e]/2,k=order,s=self.sf))
df=interpolate.splev(self.Z[s:e],self.y_fz[i],der=1)
self.L_fz.append(interpolate.splrep(self.Z[s:e],np.sqrt(1+df**2),k=order,s=self.sf))
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# Function to Compute half breadths at a given draft
# PyNAT 2021 a : PraveenKumarCH
# --------------------------------------------------------------------------------------
def getHalfBreadth(self,draft):
hBw=0.0
for i in range(self.nCrv):
if(self.Z[self.sCrv[i]]<=draft and self.Z[self.eCrv[i]]>=draft):
if(self.fittype==0):
tmp=self.y_fz[i](draft)
elif(self.fittype==1):
tmp=interpolate.splev(draft,self.y_fz[i],0)
hBw=tmp
break
return hBw
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# Function to Compute half breadths at a given draft
# PyNAT 2021 a : PraveenKumarCH
# --------------------------------------------------------------------------------------
def getGirthLength(self,draft):
CL=0
for i in range(self.nCrv):
if(self.Z[self.sCrv[i]]<=draft):
zs=self.Z[self.sCrv[i]]
ze=self.Z[self.eCrv[i]]
if draft<ze:
ze=draft
if (self.fittype==0):
sq=quad(self.L_fz[i],zs,ze)
CL+=sq[0]
if (self.fittype==1):
CL+=interpolate.splint(zs,ze,self.L_fz[i])
else:
break
return CL
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# Function to Compute sectional hydrostatics at a given draft
# PyNAT 2021 a : PraveenKumarCH
# --------------------------------------------------------------------------------------
def sectionHydroStatics(self,draft):
# Initialise return Variables with Default Values
hBw=0.0
Ar=0
LM=0
VM=0
TM=0
CL=0
YC=0
ZC=0
# Compute Area/Moment/Girth Length for each curvelets till given draft
# Sum the Area/Mom./Girth for all relavent Curvelets
for i in range(self.nCrv):
if(self.Z[self.sCrv[i]]<=draft):
zs=self.Z[self.sCrv[i]]
ze=self.Z[self.eCrv[i]]
if draft<ze:
ze=draft
if self.fittype==0:
# #Use the below integration for interp1d fit
sq=quad(self.y_fz[i],zs,ze)
Ar+=sq[0]
sq=quad(self.zy_fz[i],zs,ze)
VM+=sq[0]
sq=quad(self.yy_fz[i],zs,ze)
TM+=sq[0]
sq=quad(self.L_fz[i],zs,ze)
CL+=sq[0]
elif self.fittype==1:
#Use the below integration for Spline Fit
Ar+=interpolate.splint(zs,ze,self.y_fz[i])
VM+=interpolate.splint(zs,ze,self.zy_fz[i])
TM+=interpolate.splint(zs,ze,self.yy_fz[i])
CL+=interpolate.splint(zs,ze,self.L_fz[i])
else:
break
# Compute the Half Breadth at the given draft
for i in range(self.nCrv):
if(self.Z[self.sCrv[i]]<=draft and self.Z[self.eCrv[i]]>=draft):
if(self.fittype==0):
tmp=self.y_fz[i](draft)
elif(self.fittype==1):
tmp=interpolate.splev(draft,self.y_fz[i],0)
hBw=tmp
break
# Longitudinal Area moment of the Section till draft
LM=Ar*self.X
# Check against occurance of NaN
# PyNAT 2021 a : Praveen KumarCH
if(Ar!=0):
YC=TM/Ar
ZC=VM/Ar
# Create and return a list of computed section parameters till given draft
secData=list([hBw,Ar,LM,TM,VM,CL,YC,ZC])
return secData
# --------------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------
# Function to interpolate offset at given spacing of drafts
# PyNAT 2021 a : PraveenKumarCH
# --------------------------------------------------------------------------------------
def getPoints(self,sp):
pts=list()
zts=np.arange(self.Z[0],self.Z[-1],sp,dtype=np.float64)
yts=np.arange(zts.size,dtype=np.float64)
for i in range(zts.size):
yts[i]=self.getHalfBreadth(zts[i])
pts.append(zts)
pts.append(yts)
return pts
# --------------------------------------------------------------------------------------