import math
from DWSIM.Thermodynamics import *

## Shell,annulus side is ims1
## Tube,coil side is ims2
feedA = ims1
feedB = ims2

## Design inputs
#B=0.340
#C=0.460
#D=0.025
#Dh=0.4
#do=0.03
#p=0.045
#r=0.2
#Dh1=0.43
#Dh2=0.37
#Rt=8.2*(0.0001)
#Ra=8.2*(0.0001)
#kc=14.0
##Calculated inputs
#Nre_shell=833.0
#Nre_tube=36383.0
#ho=190.0
#hio=3093.0
#ToutA=100.0
#ToutB=47.0
##Material Property inputs
#M_A=1350.0
#M_B=2141.0
#TinA=127.0
#TinB=30.0
#Cp_A=1.0
#Cp_B=1.0
##Assigning input variables
B=B_od_inner_cyl
C=C_id_out_cyl
D=D_id_coil
do=do_od_coil
Tout_A=Tout_A_out_temp
Tout_B=Tout_B_out_temp
Ra=Ra_foulfactor_shellside
Rt=Rt_foulfactor_shellside
kc=kc_thermcond_coil
T_wall_A=T_wall_coil
T_wall_B=T_wall_annulus
cocurrent=zero_for_cocurrent_else_anything
##Input material values
Cp_A = feedA.GetProp("heatCapacity", "Overall", None, "","mass")
Cp_B = feedB.GetProp("heatCapacity", "Overall", None, "","mass")
k_A = feedA.GetProp("thermalConductivity", "Overall", None, "","")
k_B = feedB.GetProp("thermalConductivity", "Overall", None, "","")
rho_A= feedA.GetProp("density", "Overall", None, "","mole")
rho_B= feedB.GetProp("density", "Overall", None, "","mole")
M_A= feedA.GetProp("totalFlow", "Overall", None, "","mass")
M_B= feedB.GetProp("totalFlow", "Overall", None, "","mass")
Tin_A= feedA.GetProp("temperature", "Overall", None, "","")
Tin_B= feedB.GetProp("temperature", "Overall", None, "","")
mu_A = feedA.GetPhase("Liquid1").Properties.viscosity
mu_B = feedB.GetPhase("Liquid1").Properties.viscosity
pressure_A = feedA.GetProp("pressure","Overall",None,"","")
pressure_B = feedB.GetProp("pressure","Overall",None,"","")
mole_fraction_A = feedA.GetProp("fraction","Overall",None,"","mole")
mole_fraction_B = feedB.GetProp("fraction","Overall",None,"","mole")
##Testing input readings
#Flowsheet.WriteMessage(str(Cp_A))
#Flowsheet.WriteMessage(str(k_A))
#Flowsheet.WriteMessage(str(rho_A))
#Flowsheet.WriteMessage(str(M_A))
#Flowsheet.WriteMessage(str(Tin_A))
#Flowsheet.WriteMessage(str(mu_A))
#Flowsheet.WriteMessage(str(pressure_A))
#Flowsheet.WriteMessage(str(mole_fraction_A))
##Getting viscosity at wall temperatures
obj_A = Flowsheet.GetFlowsheetSimulationObject('MSTR-000')#use name of ims1
value_A = obj_A.ComponentIds
props_A = ['viscosityofliquid']
mu_w_A = obj_A.GetTDependentProperty(props_A, T_wall_A, value_A, None)
Flowsheet.WriteMessage(str(mu_w_A[0]))
obj_B = Flowsheet.GetFlowsheetSimulationObject('MSTR-001')#use name of ims2
value_B = obj_B.ComponentIds
props_B = ['viscosityofliquid']
mu_w_B = obj_B.GetTDependentProperty(props_B, T_wall_B, value_B, None)

## Model starts here
Dh=(B+C)/2
Dh1=Dh-do
Dh2=Dh+do
p=1.5*do
r=Dh/2

pi=math.pi
L_N=math.sqrt((4*pi*pi*r*r + p*p))
V_coil= (pi/4)*do*do*L_N #divided by N (for 1 turn)
V_annulus= (pi/4)*(C*C-B*B)*p #divided by N (for 1 turn)
V_flow=V_annulus-V_coil #divided by N (for 1 turn)
D_eqv=4*V_flow/(pi*do*L_N)
#Gs=M_B[0]*4/(pi*((C**2-B**2)-(Dh1**2-Dh2**2)))

#Nre_shell = D_eqv*Gs/mu_B
#A_f = pi*D*D/4.0
#q= M_A[0]/rho_A[0]
#u=q/A_f
#Nre_tube = D*u*rho_A[0]/mu_A

A_a =pi*((C**2-B**2)-(Dh2**2-Dh1**2))/4
u_a=M_A[0]/(rho_A[0]*A_a)
Nre_shell = D_eqv*u_a*rho_A[0]/mu_A
Npr_shell = (Cp_A[0]*mu_A/k_A[0])

A_f = pi*D*D/4.0
u_f = M_B[0]/(rho_B[0]*A_f)
Nre_tube = D*u_f*rho_B[0]/mu_B
Npr_tube = (Cp_B[0]*mu_B/k_B[0])

if Nre_shell < 10000:
    ho = 0.6*(Nre_shell**0.5)*((Npr_shell)**(0.31))*(k_A[0]/D_eqv)
else:
    ho= 0.36*(Nre_shell**0.55)*(Npr_shell**(1.0/3.0))*(k_A[0]/D_eqv)*((mu_A/mu_w_A[0])**(0.14))

if Nre_tube < 10000:
    hio = 0.6*(Nre_tube**0.5)*((Npr_tube)**(0.31))*(k_B[0]/do)
else:
    hi= 0.027*(Nre_tube**0.8)*(Npr_tube**(1.0/3.0))*(k_B[0]/do)*((mu_B/mu_w_B[0])**(0.14))
    hic= hi*(1+3.5*(D/Dh))

x=(do-D)/2.0

U=1.0/(1.0/ho+1.0/hic+x*(1.0/kc)+Rt+Ra)
if cocurrent == 0:
    delta_t_lm=((Tin_A[0]-Tin_B[0])-(Tout_A-Tout_B))/math.log((Tin_A[0]-Tin_B[0])/(Tout_A-Tout_B))
else:
    delta_t_lm=((TinA[0]-ToutB)-(ToutA-TinB[0]))/math.log((TinA[0]-ToutB)/(ToutA-TinB[0]))

delta_t_c=0.99*delta_t_lm

Q=M_A[0]*Cp_A[0]*(Tin_A[0]-Tout_A)
A=Q/(U*delta_t_c)

N= A/(pi*do*L_N)
n=math.ceil(N)
H = n*p +do

## Printing the results
Flowsheet.WriteMessage("Overall heat transfer coefficient= "+str(U))
Flowsheet.WriteMessage("Heat load= "+str(Q))
Flowsheet.WriteMessage("Number of turns of coil needed= "+str(n))
Flowsheet.WriteMessage("Height of cylinder= "+str(H))

##Assigning output values stream
outA = oms1
outB = oms2

outA.Clear()
outA.Assign(feedA)
outA.Calculate()

outB.Clear()
outB.Assign(feedB)
outB.Calculate()

outA.ClearAllProps()
outB.ClearAllProps()

outA.OverrideSingleCompoundFlashBehavior = True
outB.OverrideSingleCompoundFlashBehavior = True
outA.SetTemperature(Tout_A)
outB.SetTemperature(Tout_B)
outA.SetProp("pressure","Overall",None,"","",pressure_A)
outB.SetProp("pressure","Overall",None,"","",pressure_B)
outA.SetProp("fraction","Overall",None,"","mole",mole_fraction_A)
outB.SetProp("fraction","Overall",None,"","mole",mole_fraction_B)
outA.SetProp("totalFlow","Overall",None,"","mass",M_A)
outB.SetProp("totalFlow","Overall",None,"","mass",M_B)