-
Notifications
You must be signed in to change notification settings - Fork 0
/
schl_alloc3.py
160 lines (126 loc) · 4.74 KB
/
schl_alloc3.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# Copyright Notice: This code is in Copyright. Any use leading to
# publication or
# financial gain is prohibited without the permission of the authors Simon
# O'Meara : simon.omeara@manchester.ac.uk. First published 2017.
# This file is part of diffusion_extend
# diffusion_extend
# is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# diffusion_extend
# is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with diffusion_extend
# (see the LICENSE file). If not, see
# <http://www.gnu.org/licenses/>.
# -------------------------------------------------------
# function to allocate required moles of components to/from schlieren
import numpy as np
from interp_Gamma import interp_Gam as int_Gam
import matplotlib.pyplot as plt
def schl_alloc(Nznew, nscnew, shn, gam0, M, rho, PS0, V1, V1sc):
# --------------------------------------------------------------------
# inputs:
# Nznew - number of moles in 1st phase
# nscnew - no. moles 2nd phase
# shn - no. shells
# gam0 - activity coefficients
# M - molar masses (g/mol)
# rho - densities (g/m3)
# V1 - volumes of 1st phase shells (m^3)
# V1sc - volumes of 2nd phase shells (m^3)
# --------------------------------------------------------------------
# sv mole fraction in all shells
xsv0 = Nznew[0,:]/(np.sum(Nznew[:,:],axis=0))
# shells without LLPS
is0 = nscnew[0,:]==0.0 # index
for ic in range(1,M[:,0].shape[0]): # component loop
is1 = (nscnew[ic,:]==0.0)
is0 = is0+is1
# mole fraction of sv in shells without LLPS
xsv = Nznew[0,is0]/(np.sum(Nznew[:,is0],axis=0))
# difference in Gibbs free energy between 1 phase and phase separated
# system (if positive, phase separation may be favourable)
delG=np.interp(xsv,PS0[:,0],PS0[:,1])
# return if no phase separation needed or separation has already
# happened
if np.sum(delG>0)==0 or np.sum(is0==0)>0:
return Nznew, nscnew, V1, V1sc
# sv mole fraction in shells where phase separation thermodynamically
# favourable
xsv=xsv[delG>0.0]
# shell index where partitioning could occur
is0 = (xsv0==xsv)
# semi-volatile (water) mole fractions of 2 phases
xsv1=np.zeros((1,xsv.shape[0]))
xsv2 = np.zeros((1,xsv.shape[0]))
xsv1[:,:] = np.interp(xsv,PS0[:,0],PS0[:,2]) # new phase
xsv2[:,:] = np.interp(xsv,PS0[:,0],PS0[:,3]) # existing phase
# the Gamma value at these mole fractions
Gam1 = np.zeros((1,xsv.shape[0]))
Gam2 = np.zeros((1,xsv.shape[0]))
Gam1[:,:] = np.interp(xsv1,gam0[2,:],gam0[1,:])
Gam2[:,:] = np.interp(xsv2,gam0[2,:],gam0[1,:])
# return if diffusion does not promote separation
ind1 = xsv1<xsv2
ind1 = ind1*((Gam1+Gam2)/2.0>0.0)
ind2 = xsv1>xsv2
ind2 = ind2*((Gam1+Gam2)/2.0<0.0)
if np.sum(ind1+ind2)==0:
return Nznew, nscnew, V1, V1sc
# shell index where partitioning does occur
is0 = np.squeeze((ind1+ind2)>0)
# otherwise do partitioning between phases:
# partition current moles between phases
# required mole fraction in 1st phase (1st row) and
# 2nd phase (2nd row) of partitioning shell
xreq = np.append(xsv2, xsv1,axis=0)
a = xreq[1,:] # mole fraction in 2nd phase
b = 0 # original moles sv in 2nd phase
d = 0 # original moles nv in 2nd phase
f = xreq[0,:] # mole fraction in 1st phase
g = Nznew[0,is0] # original moles sv in bulk (1 phase system)
h = Nznew[1,is0] # original moles nv in bulk (1 phase system)
ind = (xsv2==0.0)
if np.sum(ind)>0:
# number of moles sv to transfer
c = 0.0
# number of moles of non-volatile to transfer
if xsv1==1.0: # move all nv out
e=h
# rearrange mole fraction sv in phase 1 eq. to find
# no. moles nv needed in phase 1 and subtract from
# existing number
else:
e = h-g*((1.0-xsv1)/xsv1)
else:
# number of moles sv to transfer
c = (g+f*(-g-h+b/a-b-d))/(1.0-f/a)
# number of moles of non-volatile to transfer
e = b/a+c/a-b-c-d
nnvmove = e
nsvmove = c
Nznew[0,is0] = Nznew[0,is0]-nsvmove
Nznew[1,is0] = Nznew[1,is0]-nnvmove
nscnew[0,is0] = nscnew[0,is0]+nsvmove
nscnew[1,is0] = nscnew[1,is0]+nnvmove
# molar volume of components (m3/mol)
MV=M/rho
# new shell volumes
V1[0,:]=np.sum(Nznew[:,:]*MV, axis=0)
V1sc[0,:]=np.sum(nscnew[:,:]*MV, axis=0)
#print 'schl'
#print xsv
#print xsv1
#print xsv2
#print (Gam1+Gam2)/2.0
#print V1
#print V1sc
#print Nznew[0,:]/np.sum(Nznew[:,:],0)
#print nscnew[0,:]/np.sum(nscnew[:,:],0)
#return
return Nznew, nscnew, V1, V1sc