Files
Py-NAT/Source_Script/LAS_KN_0B.py
T
2021-03-15 23:02:36 +05:30

332 lines
14 KiB
Python

'''
************************************************************************************
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')
# ----------------------------------------------------------------------------------------