VolFe 0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
VolFe/melt_gas.py ADDED
@@ -0,0 +1,821 @@
1
+ # melt_gas.py
2
+
3
+ import pandas as pd
4
+ import numpy as np
5
+ import gmpy2 as gp
6
+ import math
7
+
8
+ #import model_dependent_variables as mdv
9
+ import VolFe.model_dependent_variables as mdv
10
+
11
+ ### TO SORT ###
12
+ # species X solubility
13
+ # species X fugacity coefficient
14
+
15
+ ################
16
+ ### Contents ###
17
+ ################
18
+
19
+ # Fugacity, mole fraction, partial pressure
20
+ # Speciation
21
+ # Converting gas and melt compositions
22
+ # Volume and density
23
+
24
+ #################################################################################################################################
25
+ ########################################### FUGACITY, MOLE FRACTION, PARTIAL PRESSURE ###########################################
26
+ #################################################################################################################################
27
+
28
+ def f_H2O(PT,melt_wf,species,models):
29
+
30
+ """
31
+ Calculates fugacity of water in the vapor from concentration of water in the melt
32
+
33
+
34
+ Parameters
35
+ ----------
36
+ PT: pandas.DataFrame
37
+ Dataframe of pressure-temperature conditions: pressure (bars) as "P" and temperature ('C) as "T".
38
+
39
+ melt_wf: pandas.DataFrame
40
+ Dataframe of melt composition. WHAT.
41
+
42
+ species: pandas.DataFrame
43
+ Dataframe of species.csv file.
44
+
45
+ models: pandas.DataFrame
46
+ Dataframe of models.csv file.
47
+
48
+ Returns
49
+ -------
50
+ fH2O in bars as <class 'mpfr'>
51
+
52
+ """
53
+
54
+ Hspeciation = models.loc["Hspeciation","option"]
55
+ if Hspeciation == "none": # fH2O = xmH2OT^2/CH2O
56
+ value = ((xm_H2OT_so(melt_wf,species))**2.0)/mdv.C_H2O(PT,melt_wf,species,models)
57
+ return value
58
+ elif Hspeciation == "linear": # fH2O = xmH2OT/CH2O
59
+ value = xm_H2OT_so(melt_wf,species)/mdv.C_H2O(PT,melt_wf,species,models)
60
+ return value
61
+ else: # regular or ideal: fH2O = xmH2Omol/CH2O
62
+ value = xm_H2Omol_so(PT,melt_wf,species,models)/mdv.C_H2O(PT,melt_wf,species,models)
63
+ return value
64
+
65
+ def f_CO2(PT,melt_wf,species,models):
66
+ CO3model = models.loc["carbon dioxide","option"]
67
+ wm_CO2 = 100.*melt_wf['CO2']
68
+ if CO3model == "Shishkina14": # wtppm CO2 modified from Shishkina et al. (2014) Chem. Geol. 388:112-129
69
+ f = (wm_CO2*10000.0)/mdv.C_CO3(PT,melt_wf,species,models)
70
+ else: # fCO2 = xmCO2/C_CO3
71
+ f = xm_CO2_so(melt_wf,species)/mdv.C_CO3(PT,melt_wf,species,models)
72
+ return f
73
+
74
+ def f_S2(PT,melt_wf,species,models): # wtppm S2- NOT mole fraction due to parameterisation by O'Neill (2020)
75
+ K = mdv.C_S(PT,melt_wf,species,models)/1000000.
76
+ fS2 = ((melt_wf["S2-"]/K)**2.)*mdv.f_O2(PT,melt_wf,species,models)
77
+ return fS2
78
+
79
+ def f_H2(PT,melt_wf,species,models):
80
+ K = mdv.KHOg(PT,models)
81
+ return f_H2O(PT,melt_wf,species,models)/(K*mdv.f_O2(PT,melt_wf,species,models)**0.5)
82
+
83
+ def f_CO(PT,melt_wf,species,models):
84
+ K = mdv.KCOg(PT,models)
85
+ return f_CO2(PT,melt_wf,species,models)/(K*mdv.f_O2(PT,melt_wf,species,models)**0.5)
86
+
87
+ def f_H2S(PT,melt_wf,species,models):
88
+ K = mdv.KHOSg(PT,models)
89
+ return (K*f_S2(PT,melt_wf,species,models)**0.5*f_H2O(PT,melt_wf,species,models))/mdv.f_O2(PT,melt_wf,species,models)**0.5
90
+
91
+ def f_SO2(PT,melt_wf,species,models):
92
+ K = mdv.KOSg(PT,models)
93
+ return K*mdv.f_O2(PT,melt_wf,species,models)*f_S2(PT,melt_wf,species,models)**0.5
94
+
95
+ def f_SO3(PT,melt_wf,species,models):
96
+ K = mdv.KOSg2(PT,models)
97
+ return K*(mdv.f_O2(PT,melt_wf,species,models))**1.5*(f_S2(PT,melt_wf,species,models))**0.5
98
+
99
+ def f_CH4(PT,melt_wf,species,models):
100
+ K = mdv.KCOHg(PT,models)
101
+ return (f_CO2(PT,melt_wf,species,models)*f_H2O(PT,melt_wf,species,models)**2.0)/(K*mdv.f_O2(PT,melt_wf,species,models)**2.0)
102
+
103
+ def f_OCS(PT,melt_wf,species,models):
104
+ OCSmodel = models.loc["carbonylsulfide","option"]
105
+ K = mdv.KOCSg(PT,models)
106
+ if OCSmodel == "COHS":
107
+ if f_H2O(PT,melt_wf,species,models) > 0.0:
108
+ return (f_CO2(PT,melt_wf,species,models)*f_H2S(PT,melt_wf,species,models))/(f_H2O(PT,melt_wf,species,models)*K)
109
+ else:
110
+ return 0.0
111
+ else:
112
+ if f_CO2(PT,melt_wf,species,models) > 0.0:
113
+ return ((f_CO(PT,melt_wf,species,models)**3.0)*f_SO2(PT,melt_wf,species,models))/((f_CO2(PT,melt_wf,species,models)**2.0)*K)
114
+ else:
115
+ return 0.0
116
+
117
+ def f_X(PT,melt_wf,species,models):
118
+ K = mdv.C_X(PT,melt_wf,species,models)/1000000.
119
+ f_X = melt_wf["XT"]/K
120
+ return f_X
121
+
122
+
123
+ #######################
124
+ ### oxygen fugacity ###
125
+ #######################
126
+
127
+ # buffers
128
+ def fO22Dbuffer(PT,fO2,buffer,models):
129
+ if buffer == "NNO":
130
+ return math.log10(fO2) - mdv.NNO(PT,models)
131
+ elif buffer == "FMQ":
132
+ return math.log10(fO2) - mdv.FMQ(PT,models)
133
+ def Dbuffer2fO2(PT,D,buffer,model):
134
+ if buffer == "NNO":
135
+ return 10.0**(D + mdv.NNO(PT,model))
136
+ elif buffer == "FMQ":
137
+ return 10.0**(D + mdv.FMQ(PT,model))
138
+
139
+ def S6S2_2_fO2(S62,melt_wf,PT,species,models):
140
+ CSO4 = mdv.C_SO4(PT,melt_wf,species,models)
141
+ CS = mdv.C_S(PT,melt_wf,species,models)
142
+ if models.loc["H2S_m","option"] == "no":
143
+ fO2 = ((S62*CS)/CSO4)**0.5
144
+ elif models.loc["H2S_m","option"] == "yes":
145
+ KHS = mdv.KHOSg(PT,models)
146
+ CH2S = mdv.C_H2S(PT,melt_wf,species,models)
147
+ CH2OT = mdv.C_H2O(PT,melt_wf,species,models)
148
+ xmH2O = xm_H2OT_so(melt_wf,species)
149
+ W = (CSO4/((KHS*CH2S*(xmH2O**2./CH2OT)) + CS))
150
+ fO2 = (S62/W)**0.5
151
+ return fO2
152
+
153
+
154
+ ########################
155
+ ### partial pressure ###
156
+ ########################
157
+
158
+ def p_H2(PT,melt_wf,species,models):
159
+ return f_H2(PT,melt_wf,species,models)/mdv.y_H2(PT,species,models)
160
+ def p_H2O(PT,melt_wf,species,models):
161
+ return f_H2O(PT,melt_wf,species,models)/mdv.y_H2O(PT,species,models)
162
+ def p_O2(PT,melt_wf,species,models):
163
+ return mdv.f_O2(PT,melt_wf,species,models)/mdv.y_O2(PT,species,models)
164
+ def p_SO2(PT,melt_wf,species,models):
165
+ return f_SO2(PT,melt_wf,species,models)/mdv.y_SO2(PT,species,models)
166
+ def p_S2(PT,melt_wf,species,models):
167
+ return f_S2(PT,melt_wf,species,models)/mdv.y_S2(PT,species,models)
168
+ def p_H2S(PT,melt_wf,species,models):
169
+ return f_H2S(PT,melt_wf,species,models)/mdv.y_H2S(PT,species,models)
170
+ def p_CO2(PT,melt_wf,species,models):
171
+ return f_CO2(PT,melt_wf,species,models)/mdv.y_CO2(PT,species,models)
172
+ def p_CO(PT,melt_wf,species,models):
173
+ return f_CO(PT,melt_wf,species,models)/mdv.y_CO(PT,species,models)
174
+ def p_CH4(PT,melt_wf,species,models):
175
+ return f_CH4(PT,melt_wf,species,models)/mdv.y_CH4(PT,species,models)
176
+ def p_OCS(PT,melt_wf,species,models):
177
+ return f_OCS(PT,melt_wf,species,models)/mdv.y_OCS(PT,species,models)
178
+ def p_X(PT,melt_wf,species,models):
179
+ return f_X(PT,melt_wf,species,models)/mdv.y_X(PT,species,models)
180
+
181
+ def p_tot(PT,melt_wf,species,models):
182
+ return p_H2(PT,melt_wf,species,models) + p_H2O(PT,melt_wf,species,models) + p_O2(PT,melt_wf,species,models) + p_SO2(PT,melt_wf,species,models) + p_S2(PT,melt_wf,species,models) + p_H2S(PT,melt_wf,species,models) + p_CO2(PT,melt_wf,species,models) + p_CO(PT,melt_wf,species,models) + p_CH4(PT,melt_wf,species,models) + p_OCS(PT,melt_wf,species,models) + p_X(PT,melt_wf,species,models)
183
+
184
+
185
+ ############################
186
+ ### vapor molar fraction ###
187
+ ############################
188
+
189
+ def xg_H2(PT,melt_wf,species,models):
190
+ return p_H2(PT,melt_wf,species,models)/PT['P']
191
+ def xg_H2O(PT,melt_wf,species,models):
192
+ return p_H2O(PT,melt_wf,species,models)/PT['P']
193
+ def xg_O2(PT,melt_wf,species,models):
194
+ return p_O2(PT,melt_wf,species,models)/PT['P']
195
+ def xg_SO2(PT,melt_wf,species,models):
196
+ return p_SO2(PT,melt_wf,species,models)/PT['P']
197
+ def xg_S2(PT,melt_wf,species,models):
198
+ return p_S2(PT,melt_wf,species,models)/PT['P']
199
+ def xg_H2S(PT,melt_wf,species,models):
200
+ return p_H2S(PT,melt_wf,species,models)/PT['P']
201
+ def xg_CO2(PT,melt_wf,species,models):
202
+ return p_CO2(PT,melt_wf,species,models)/PT['P']
203
+ def xg_CO(PT,melt_wf,species,models):
204
+ return p_CO(PT,melt_wf,species,models)/PT['P']
205
+ def xg_CH4(PT,melt_wf,species,models):
206
+ return p_CH4(PT,melt_wf,species,models)/PT['P']
207
+ def xg_OCS(PT,melt_wf,species,models):
208
+ return p_OCS(PT,melt_wf,species,models)/PT['P']
209
+ def xg_X(PT,melt_wf,species,models):
210
+ return p_X(PT,melt_wf,species,models)/PT['P']
211
+ def Xg_tot(PT,melt_wf,species,models):
212
+ species_X = models.loc["species X","option"]
213
+ Xg_t = xg_CO2(PT,melt_wf,species,models)*species.loc["CO2","M"] + xg_CO(PT,melt_wf,species,models)*species.loc["CO","M"] + xg_O2(PT,melt_wf,species,models)*species.loc["O2","M"] + xg_H2O(PT,melt_wf,species,models)*species.loc["H2O","M"] + xg_H2(PT,melt_wf,species,models)*species.loc["H2","M"] + xg_CH4(PT,melt_wf,species,models)*species.loc["CH4","M"] + xg_SO2(PT,melt_wf,species,models)*species.loc["SO2","M"] + xg_S2(PT,melt_wf,species,models)*species.loc["S2","M"] + xg_H2S(PT,melt_wf,species,models)*species.loc["H2S","M"] + xg_OCS(PT,melt_wf,species,models)*species.loc["OCS","M"] + xg_X(PT,melt_wf,species,models)*species.loc[species_X,"M"]
214
+ return Xg_t
215
+
216
+
217
+ ##########################
218
+ ### melt mole fraction ###
219
+ ##########################
220
+
221
+ # totals
222
+ def wm_vol(melt_wf): # wt% total volatiles in the melt
223
+ wm_H2OT = 100.*melt_wf["H2OT"]
224
+ wm_CO2 = 100.*melt_wf["CO2"]
225
+ return wm_H2OT + wm_CO2 #+ wm_S(wm_ST) + wm_SO3(wm_ST,species)
226
+ def wm_nvol(melt_wf): # wt% total of non-volatiles in the melt
227
+ return 100. - wm_vol(melt_wf)
228
+
229
+ # molecular mass on a singular oxygen basis
230
+ def M_m_SO(melt_wf,species):
231
+ # single oxide, no volatiles, all Fe as FeOT
232
+ melt_comp = melt_single_O(melt_wf,species,"no","no")
233
+ M_m = 1./melt_comp["Xmtot"]
234
+ return M_m
235
+
236
+ # molecular mass on a oxide basis
237
+ def M_m_ox(melt_wf,species,models): # no volatiles, all Fe as FeOT
238
+ melt_comp = melt_mole_fraction(melt_wf,species,models,"no","no")
239
+ M_m = 1./melt_comp["mol_tot"]
240
+ return M_m
241
+
242
+ # Number of moles in the melt
243
+ def Xm_H2OT(melt_wf,species):
244
+ wm_H2OT = 100.*melt_wf['H2OT']
245
+ return wm_H2OT/species.loc["H2O","M"]
246
+ def Xm_CO2(melt_wf,species):
247
+ wm_CO2 = 100.*melt_wf['CO2']
248
+ return wm_CO2/species.loc["CO2","M"]
249
+
250
+ # Mole fraction in the melt based on mixing between volatile-free melt on a singular oxygen basis and volatiles
251
+ def Xm_m_so(melt_wf,species): # singular oxygen basis
252
+ return wm_nvol(melt_wf)/M_m_SO(melt_wf,species)
253
+ def Xm_tot_so(melt_wf,species):
254
+ return Xm_H2OT(melt_wf,species) + Xm_CO2(melt_wf,species) + Xm_m_so(melt_wf,species)
255
+ def xm_H2OT_so(melt_wf,species):
256
+ return Xm_H2OT(melt_wf,species)/Xm_tot_so(melt_wf,species)
257
+ def xm_CO2_so(melt_wf,species):
258
+ return Xm_CO2(melt_wf,species)/Xm_tot_so(melt_wf,species)
259
+ def xm_melt_so(melt_wf,species):
260
+ return Xm_m_so(melt_wf,species)/Xm_tot_so(melt_wf,species)
261
+ def Xm_t_so(melt_wf,species):
262
+ return xm_H2OT_so(melt_wf,species)*species.loc["H2O","M"] + xm_CO2_so(melt_wf,species)*species.loc["CO2","M"] + xm_melt_so(melt_wf,species)*M_m_SO(melt_wf,species)
263
+
264
+ ################################################################################################################################
265
+ ########################################################## SPECIATION ##########################################################
266
+ ################################################################################################################################
267
+
268
+ def ratio2overtotal(x):
269
+ return x/x+1.
270
+
271
+ def overtotal2ratio(x):
272
+ return x/(1.-x)
273
+
274
+ ###########################
275
+ ### hydrogen speciation ###
276
+ ###########################
277
+
278
+ def xm_OH_so(PT,melt_wf,species,models):
279
+ Hspeciation = models.loc["Hspeciation","option"]
280
+ Hspeccomp = models.loc["Hspeccomp","option"]
281
+ T_K = PT['T']+273.15
282
+ wm_H2OT = 100.*melt_wf['H2OT']
283
+
284
+ Z = xm_H2OT_so(melt_wf,species)
285
+
286
+ def f(A, B, C, Z, x): # regular solution model rearranged to equal 0 to solve for xm_OH
287
+ return (A + B*x + C*(Z - 0.5*x) + gp.log((x**2.0)/((Z - 0.5*x)*(1.0 - Z - 0.5*x))))
288
+
289
+ def df(B, C, Z, x): # derivative of above
290
+ return (B - 0.5*C - (2.0/x) + (0.5/(Z-0.5*x) + (0.5/(1.0-Z-0.5*x))))
291
+
292
+ def dx(A,B,C,x):
293
+ return (abs(0-f(A, B, C, Z, x)))
294
+
295
+ def nr(A,B,C,x0,e1):
296
+ delta1 = dx(A,B,C,x0)
297
+ while delta1 > e1:
298
+ x0 = x0 - f(A, B, C, Z, x0)/df(B, C, Z, x0)
299
+ delta1 = dx(A,B,C,x0)
300
+ return x0
301
+
302
+ if Z == 0.0:
303
+ return 0.0
304
+ elif Hspeciation == "ideal": # ideal mixture from Silver & Stolper (1985) J. Geol. 93(2) 161-177
305
+ K = mdv.KHOm(T,melt_wf,species,models)
306
+ return (0.5 - (0.25 - ((K - 4.0)/K)*(Z - Z**2.0))**0.5)/((K - 4.0)/(2.0*K))
307
+ elif Hspeciation == "none": # all OH-
308
+ return 0.0
309
+
310
+ elif Hspeciation == "regular": # else use regular solution model from Silver & Stolper (1989) J.Pet. 30(3)667-709
311
+ tol = 0.000001 #tolerance
312
+ K = mdv.KHOm(PT,melt_wf,species,models)
313
+ x0 = (0.5 - (0.25 - ((K - 4.0)/K)*(Z - Z**2.0))**0.5)/((K - 4.0)/(2.0*K))
314
+ R = 83.15 #cm3.bar/mol.K
315
+ A, B, C = mdv.KregH2O(PT,melt_wf,species,models)
316
+ return nr(A,B,C,x0,tol)
317
+
318
+ def xm_H2Omol_so(PT,melt_wf,species,models):
319
+ Z = xm_H2OT_so(melt_wf,species)
320
+ return Z - 0.5*xm_OH_so(PT,melt_wf,species,models)
321
+
322
+ def wm_H2Omol_OH(PT,melt_wf,species,models): # wt fraction
323
+ H2Omol = xm_H2Omol_so(PT,melt_wf,species,models)*species.loc["H2O","M"]
324
+ OH = xm_OH_so(PT,melt_wf,species,models)*species.loc["OH","M"]
325
+ melt = xm_melt_so(melt_wf,species)*M_m_SO(melt_wf,species)
326
+ CO2T = xm_CO2_so(melt_wf,species)
327
+ wm_H2Omol = H2Omol/(H2Omol + OH + melt + CO2T)
328
+ wm_OH = OH/(H2Omol + OH + melt + CO2T)
329
+ return wm_H2Omol, wm_OH
330
+
331
+ #########################
332
+ ### carbon speciation ###
333
+ #########################
334
+
335
+ def xm_CO32_CO2mol(PT,melt_wf,species,models): # mole fraction
336
+ xm_CO2T = xm_CO2_so(melt_wf,species)
337
+ xm_H2OT = xm_H2OT_so(melt_wf,species)
338
+ if models.loc["Cspeccomp","option"] == "basalt":
339
+ xm_CO32 = xm_CO2T
340
+ xm_CO2mol = 0.
341
+ elif models.loc["Cspeccomp","option"] == "rhyolite":
342
+ xm_CO32 = 0.
343
+ xm_CO2mol = xm_CO2T
344
+ else:
345
+ K = mdv.KCOm(PT,melt_wf,species,models)
346
+ xm_CO32 = (K*xm_CO2T*(1.-xm_CO2T-xm_H2OT))/(1.+ K*(1.-xm_CO2T-xm_H2OT))
347
+ xm_CO2mol = xm_CO2T - xm_CO32
348
+ return xm_CO32, xm_CO2mol
349
+
350
+ def wm_CO32_CO2mol(PT,melt_wf,species,models): # wt fraction
351
+ xm_CO32, xm_CO2mol = xm_CO32_CO2mol(PT,melt_wf,species,models)
352
+ CO2mol = xm_CO2mol*species.loc["CO2","M"]
353
+ CO2carb = xm_CO32*species.loc["CO2","M"]
354
+ melt = xm_melt_so(melt_wf,species)*M_m_SO(melt_wf,species)
355
+ H2OT = xm_H2OT_so(melt_wf,species)*species.loc["H2O","M"]
356
+ wm_CO2mol = CO2mol/(CO2mol + CO2carb + H2OT + melt)
357
+ wm_CO2carb = CO2carb/(CO2mol + CO2carb + H2OT + melt)
358
+ return wm_CO2carb, wm_CO2mol
359
+
360
+ ##########################
361
+ ### sulfur speciation ###
362
+ ##########################
363
+
364
+ def S6S2(PT,melt_wf,species,models):
365
+ T_K = PT['T']+273.15
366
+ model = models.loc["sulfate","option"]
367
+ if model == "Nash19":
368
+ A, B = mdv.S_Nash19_terms(PT)
369
+ result = 10.**(A*math.log10(Fe3Fe2(melt_wf)) + B)
370
+ else:
371
+ CSO4 = mdv.C_SO4(PT,melt_wf,species,models)
372
+ CS = mdv.C_S(PT,melt_wf,species,models)
373
+ fO2 = mdv.f_O2(PT,melt_wf,species,models)
374
+ if models.loc["H2S_m","option"] == "no":
375
+ result = (CSO4/CS)*fO2**2.
376
+ elif models.loc["H2S_m","option"] == "yes":
377
+ KHS = mdv.KHOSg(PT,models)
378
+ CH2S = mdv.C_H2S(PT,melt_wf,species,models)
379
+ CH2OT = mdv.C_H2O(PT,melt_wf,species,models)
380
+ xmH2O = xm_H2OT_so(melt_wf,species)
381
+ result = (CSO4/((KHS*CH2S*(xmH2O**2./CH2OT)) + CS))*fO2**2.
382
+ return result
383
+
384
+ def S6ST(PT,melt_wf,species,models):
385
+ S6S2_ = S6S2(PT,melt_wf,species,models)
386
+ return S6S2_/(S6S2_+1.)
387
+
388
+ def wm_S(PT,melt_wf,species,models):
389
+ wm_ST = 100.*melt_wf['ST']
390
+ S6ST_ = S6ST(PT,melt_wf,species,models)
391
+ return wm_ST*(1.0-S6ST_)
392
+
393
+ def wm_SO3(PT,melt_wf,species,models):
394
+ wm_ST = 100.*melt_wf['ST']
395
+ S6ST_ = S6ST(PT,melt_wf,species,models)
396
+ return ((wm_ST*S6ST_)/species.loc["S","M"])*species.loc["SO3","M"]
397
+
398
+
399
+ #######################
400
+ ### iron speciation ###
401
+ #######################
402
+
403
+ def Fe3Fe2(melt_wf):
404
+ Fe3FeT = melt_wf['Fe3FeT']
405
+ return Fe3FeT/(1.0 - Fe3FeT)
406
+
407
+ def Wm_FeT(melt_wf,species):
408
+ if melt_wf["FeOT"] > 0.0:
409
+ return (melt_wf["FeOT"]/species.loc["FeO","M"])*species.loc["Fe","M"]
410
+ elif melt_wf["Fe2O3T"] > 0.0:
411
+ return (melt_wf["Fe2O3T"]/species.loc["Fe2O3","M"])*species.loc["Fe","M"]
412
+ else:
413
+ return ((melt_wf["FeO"]/species.loc["FeO","M"]) + (melt_wf["Fe2O3"]/species.loc["Fe2O3","M"]))*species.loc["Fe","M"]
414
+
415
+ def Wm_FeO(melt_wf,species):
416
+ Fe3FeT = melt_wf['Fe3FeT']
417
+ return (Wm_FeT(melt_wf,species)/species.loc["Fe","M"])*(1.0-Fe3FeT)*species.loc["FeO","M"]
418
+
419
+ def Wm_Fe2O3(melt_wf,species):
420
+ Fe3FeT = melt_wf['Fe3FeT']
421
+ return (Wm_FeT(melt_wf,species)/species.loc["Fe","M"])*Fe3FeT*species.loc["Fe2O3","M"]
422
+
423
+ def Wm_FeOT(melt_wf,species):
424
+ return (Wm_FeT(melt_wf,species)/species.loc["Fe","M"])*species.loc["FeO","M"]
425
+
426
+ def wm_Fe_nv(melt_wf,species): # no volatiles
427
+ Wm_tot = melt_wf["SiO2"] + melt_wf["TiO2"] + melt_wf["Al2O3"] + melt_wf["MnO"] + melt_wf["MgO"] + melt_wf["MnO"] + melt_wf["CaO"] + melt_wf["Na2O"] + melt_wf["K2O"] + melt_wf["P2O5"] + Wm_FeO(melt_wf,species) + Wm_Fe2O3(melt_wf,species)
428
+ FeT = species.loc["Fe","M"]*((2.0*Wm_Fe2O3(melt_wf,species)/species.loc["Fe2O3","M"]) + (Wm_FeO(melt_wf,species)/species.loc["FeO","M"]))
429
+ return 100.0*FeT/Wm_tot
430
+
431
+ def Fe3FeT_i(PT,melt_wf,species,models):
432
+ model = models.loc["fO2","option"]
433
+ T_K = PT['T']+273.15
434
+
435
+ if model == "buffered":
436
+ fO2 = 10**(melt_wf["logfO2_i"])
437
+ return mdv.fO22Fe3FeT(fO2,PT,melt_wf,species,models)
438
+ else:
439
+ if pd.isnull(melt_wf["Fe3FeT_i"]) == False:
440
+ return melt_wf["Fe3FeT_i"]
441
+ elif pd.isnull(melt_wf["logfO2_i"]) == False:
442
+ fO2 = 10.0**(melt_wf["logfO2_i"])
443
+ return mdv.fO22Fe3FeT(fO2,PT,melt_wf,species,models)
444
+ elif pd.isnull(melt_wf["DNNO"]) == False:
445
+ D = melt_wf["DNNO"]
446
+ fO2 = Dbuffer2fO2(PT,D,"NNO",models)
447
+ return mdv.fO22Fe3FeT(fO2,PT,melt_wf,species,models)
448
+ elif pd.isnull(melt_wf["DFMQ"]) == False:
449
+ D = melt_wf["DFMQ"]
450
+ fO2 = Dbuffer2fO2(PT,D,"FMQ",models)
451
+ return mdv.fO22Fe3FeT(fO2,PT,melt_wf,species,models)
452
+ elif pd.isnull(melt_wf["S6ST_i"]) == False:
453
+ S6T = melt_wf["S6ST_i"]
454
+ S62 = overtotal2ratio(S6T)
455
+ fO2 = S6S2_2_fO2(S62,melt_wf,PT,species,models)
456
+ return mdv.fO22Fe3FeT(fO2,PT,melt_wf,species,models)
457
+ else:
458
+ return ((2.0*melt_wf["Fe2O3"])/species.loc["Fe2O3","M"])/(((2.0*melt_wf["Fe2O3"])/species.loc["Fe2O3","M"]) + (melt_wf["FeO"]/species.loc["FeO","M"]))
459
+
460
+
461
+ #################################################################################################################################
462
+ ############################################## converting gas and melt compositions #############################################
463
+ #################################################################################################################################
464
+
465
+ # C/S ratio of the vapor
466
+ def gas_CS(PT,melt_wf,species,models):
467
+ S_values = ((2.*xg_S2(PT,melt_wf,species,models))+xg_SO2(PT,melt_wf,species,models)+xg_OCS(PT,melt_wf,species,models)+xg_H2S(PT,melt_wf,species,models))
468
+ if S_values > 0:
469
+ xgCS = (xg_CO(PT,melt_wf,species,models)+xg_CO2(PT,melt_wf,species,models)+xg_OCS(PT,melt_wf,species,models)+xg_CH4(PT,melt_wf,species,models))/S_values
470
+ else:
471
+ xgCS = ""
472
+ return xgCS
473
+
474
+ def gas_CS_alt(xg):
475
+ S_values = ((2.*xg["S2"])+xg["SO2"]+xg["OCS"]+xg["H2S"])
476
+ if S_values > 0:
477
+ xgCS = (xg["CO"]+xg["CO2"]+xg["OCS"]+xg["CH4"])/S_values
478
+ else:
479
+ xgCS = ""
480
+ return xgCS
481
+
482
+ # all carbon as CO2 and all hydrogen as H2O
483
+ def melt_H2O_CO2_eq(melt_wf,species):
484
+ wmCO2eq = melt_wf["CO2"] + species.loc["CO2","M"]*((melt_wf["CO"]/species.loc["CO","M"])+(melt_wf["CH4"]/species.loc["CH4","M"]))
485
+ wmH2Oeq = melt_wf["H2OT"] + species.loc["H2O","M"]*((melt_wf["H2"]/species.loc["H2","M"])+(2.*melt_wf["CH4"]/species.loc["CH4","M"])+(melt_wf["H2S"]/species.loc["H2S","M"]))
486
+ return wmCO2eq, wmH2Oeq
487
+
488
+ # calculate weight fraction of species in the gas
489
+ def gas_wf(gas_mf,species,models):
490
+ wg_O2 = (species.loc["O2","M"]*gas_mf["O2"])/gas_mf["Xg_t"]
491
+ wg_H2 = (species.loc["H2","M"]*gas_mf["H2"])/gas_mf["Xg_t"]
492
+ wg_H2O = (species.loc["H2O","M"]*gas_mf["H2O"])/gas_mf["Xg_t"]
493
+ wg_H2S = (species.loc["H2S","M"]*gas_mf["H2S"])/gas_mf["Xg_t"]
494
+ wg_S2 = (species.loc["S2","M"]*gas_mf["S2"])/gas_mf["Xg_t"]
495
+ wg_SO2 = (species.loc["SO2","M"]*gas_mf["SO2"])/gas_mf["Xg_t"]
496
+ wg_CO2 = (species.loc["CO2","M"]*gas_mf["CO2"])/gas_mf["Xg_t"]
497
+ wg_CO = (species.loc["CO","M"]*gas_mf["CO"])/gas_mf["Xg_t"]
498
+ wg_CH4 = (species.loc["CH4","M"]*gas_mf["CH4"])/gas_mf["Xg_t"]
499
+ wg_OCS = (species.loc["OCS","M"]*gas_mf["OCS"])/gas_mf["Xg_t"]
500
+ species_X = models.loc["species X","option"]
501
+ wg_X = (species.loc[species_X,"M"]*gas_mf["X"])/gas_mf["Xg_t"]
502
+ result = {"wg_O2":wg_O2, "wg_H2":wg_H2, "wg_H2O":wg_H2O, "wg_H2S":wg_H2S, "wg_S2":wg_S2, "wg_SO2":wg_SO2, "wg_CO2":wg_CO2, "wg_CO":wg_CO, "wg_CH4":wg_CH4, "wg_OCS":wg_OCS, "wg_X":wg_X}
503
+ return result
504
+
505
+ # calculate weight fraction of species in the gas relative to total system
506
+ def gas_wft(gas_mf,species):
507
+ gaswf = gas_wf(gas_mf,species,models)
508
+ wgt_O2 = gaswf["wg_O2"]*gas_mf['wt_g']
509
+ wgt_H2 = gaswf["wg_H2"]*gas_mf['wt_g']
510
+ wgt_H2O = gaswf["wg_H2O"]*gas_mf['wt_g']
511
+ wgt_H2S = gaswf["wg_H2S"]*gas_mf['wt_g']
512
+ wgt_S2 = gaswf["wg_S2"]*gas_mf['wt_g']
513
+ wgt_SO2 = gaswf["wg_SO2"]*gas_mf['wt_g']
514
+ wgt_CO2 = gaswf["wg_CO2"]*gas_mf['wt_g']
515
+ wgt_CO = gaswf["wg_CO"]*gas_mf['wt_g']
516
+ wgt_CH4 = gaswf["wg_CH4"]*gas_mf['wt_g']
517
+ wgt_OCS = gaswf["wg_OCS"]*gas_mf['wt_g']
518
+ wgt_X = gaswf["wg_X"]*gas_mf['wt_g']
519
+ result = {"wgt_O2":wgt_O2, "wgt_H2":wgt_H2, "wgt_H2O":wgt_H2O, "wgt_H2S":wgt_H2S, "wgt_S2":wgt_S2, "wgt_SO2":wgt_SO2, "wgt_CO2":wgt_CO2, "wgt_CO":wgt_CO, "wgt_CH4":wgt_CH4, "wgt_OCS":wgt_OCS, "wgt_X":wgt_X}
520
+ return result
521
+
522
+ def gas_weight(gas_mf,bulk_wf,species):
523
+ gaswft = gas_wft(gas_mf,species)
524
+ Wg_O2 = gaswtf["wgt_O2"]*bulk_wf['Wt']
525
+ Wg_H2 = gaswtf["wgt_H2"]*bulk_wf['Wt']
526
+ Wg_H2O = gaswtf["wgt_H2O"]*bulk_wf['Wt']
527
+ Wg_H2S = gaswtf["wgt_H2S"]*bulk_wf['Wt']
528
+ Wg_S2 = gaswtf["wgt_S2"]*bulk_wf['Wt']
529
+ Wg_SO2 = gaswtf["wgt_SO2"]*bulk_wf['Wt']
530
+ Wg_CO2 = gaswtf["wgt_CO2"]*bulk_wf['Wt']
531
+ Wg_CO = gaswtf["wgt_CO"]*bulk_wf['Wt']
532
+ Wg_CH4 = gaswtf["wgt_CH4"]*bulk_wf['Wt']
533
+ Wg_OCS = gaswtf["wgt_OCS"]*bulk_wf['Wt']
534
+ Wg_X = gaswtf["wgt_X"]*bulk_wf['Wt']
535
+ Wg_t = gas_mf['wt_g']*bulk_wf['Wt']
536
+ result = {"Wg_O2":Wg_O2, "Wg_H2":Wg_H2, "Wg_H2O":Wg_H2O, "Wg_H2S":Wg_H2S, "Wg_S2":Wg_S2, "Wg_SO2":Wg_SO2, "Wg_CO2":Wg_CO2, "Wg_CO":Wg_CO, "Wg_CH4":Wg_CH4, "Wg_OCS":Wg_OCS, "Wg_X":Wg_X,"Wg_t":Wg_t}
537
+ return result
538
+
539
+ def gas_moles(gas_mf,bulk_wf,species,models):
540
+ gasw = gas_weight(gas_mf,bulk_wf,species)
541
+ Xg_O2 = gasw["Wg_O2"]/species.loc["O2","M"]
542
+ Xg_H2O = gasw["Wg_H2O"]/species.loc["H2O","M"]
543
+ Xg_H2 = gasw["Wg_H2"]/species.loc["H2","M"]
544
+ Xg_H2S = gasw["Wg_H2S"]/species.loc["H2S","M"]
545
+ Xg_S2 = gasw["Wg_S2"]/species.loc["S2","M"]
546
+ Xg_SO2 = gasw["Wg_SO2"]/species.loc["SO2","M"]
547
+ Xg_CO2 = gasw["Wg_CO2"]/species.loc["CO2","M"]
548
+ Xg_CO = gasw["Wg_CO"]/species.loc["CO","M"]
549
+ Xg_CH4 = gasw["Wg_CH4"]/species.loc["CH4","M"]
550
+ Xg_OCS = gasw["g_OCS"]/species.loc["OCS","M"]
551
+ species_X = models.loc["species X","option"]
552
+ Xg_X = gasw["Wg_X"]/species.loc[species_X,"M"]
553
+ Xt_g = Xg_O2 + Xg_H2 + Xg_H2O + Xg_H2S + Xg_S2 + Xg_SO2 + Xg_CO2 + Xg_CO + Xg_CH4 + Xg_OCS + Xg_X
554
+ result = {"Xg_O2":Xg_O2, "Xg_H2":Xg_H2, "Xg_H2O":Xg_H2O, "Xg_H2S":Xg_H2S, "Xg_S2":Xg_S2, "Xg_SO2":Xg_SO2, "Xg_CO2":Xg_CO2, "Xg_CO":Xg_CO, "Xg_CH4":Xg_CH4, "Xg_OCS":Xg_OCS, "Xg_X":Xg_X,"Xg_t":Xg_t}
555
+ return result
556
+
557
+ # calculate weight fraction of elements in the gas
558
+ def gas_elements(gas_mf,species):
559
+ gaswf = gas_wf(gas_mf,species)
560
+ wg_O = gaswf["wg_O2"] + species.loc["O","M"]*((gaswf["wg_H2O"]/species.loc["H2O","M"]) + (2.*gaswf["wg_SO2"]/species.loc["SO2","M"]) + (2.*gaswf["wg_CO2"]/species.loc["CO2","M"]) + (gaswf["wg_CO"]/species.loc["CO","M"]) + (gaswf["wg_OCS"]/species.loc["OCS","M"]))
561
+ wg_H = gaswf["wg_H2"] + species.loc["H","M"]*((2.*gaswf["wg_H2O"]/species.loc["H2O","M"]) + (2.*gaswf["wg_H2S"]/species.loc["H2S","M"]) + (4.*gaswf["wg_CH4"]/species.loc["CH4","M"]))
562
+ wg_S = gaswf["wg_S2"] + species.loc["S","M"]*((gaswf["wg_H2S"]/species.loc["H2S","M"]) + (gaswf["wg_SO2"]/species.loc["SO2","M"]) + (gaswf["wg_OCS"]/species.loc["OCS","M"]))
563
+ wg_C = species.loc["S","M"]*((gaswf["wg_CO2"]/species.loc["CO2","M"]) + (gaswf["wg_CO"]/species.loc["CO","M"]) + (gaswf["wg_OCS"]/species.loc["OCS","M"]) + (gaswf["wg_CH4"]/species.loc["CH4","M"]))
564
+ result = {"wg_O":wg_O,"wg_H":wg_H, "wg_S":wg_S, "wg_C":wg_C, "wg_X":wg_X}
565
+ return result
566
+
567
+ # calculate weight fraction of elements in the melt
568
+ def melt_elements(PT,melt_wf,bulk_wf,gas_comp,species,models):
569
+ wm_C = species.loc["C","M"]*((melt_wf["CO2"]/species.loc["CO2","M"] +
570
+ melt_wf["CO"]/species.loc["CO","M"] + melt_wf["CH4"]/species.loc["CH4","M"]))
571
+ wm_H = 2.*species.loc["H","M"]*((melt_wf["H2OT"]/species.loc["H2O","M"] + melt_wf["H2"]/species.loc["H2","M"] + melt_wf["H2S"]/species.loc["H2S","M"] + (2.*melt_wf["CH4"])/species.loc["CH4","M"]))
572
+ wm_S = species.loc["S","M"]*(((melt_wf["S2-"]+melt_wf["S6+"])/species.loc["S","M"] + (melt_wf["H2S"]/species.loc["H2S","M"])))
573
+ wm_Fe = bulk_wf["Fe"]/(1.-gas_comp["wt_g"])
574
+ Fe32 = overtotal2ratio(melt_wf["Fe3FeT"])
575
+ wm_O = species.loc["O","M"]*((melt_wf["H2OT"]/species.loc["H2O","M"]) + ((2.0*melt_wf["CO2"])/species.loc["CO2","M"]) + (3.0*melt_wf["S6+"]/species.loc["S","M"]) + (melt_wf["CO"]/species.loc["CO","M"]) + (wm_Fe/species.loc["Fe","M"])*((1.5*Fe32+1.0)/(Fe32+1.0)))
576
+ wm_X = melt_wf["XT"]
577
+ result = {"wm_C":wm_C, "wm_H":wm_H, "wm_S":wm_S, "wm_Fe":wm_Fe, "wm_O":wm_O, "wm_X":wm_X}
578
+ return result
579
+
580
+
581
+
582
+ #################################################################################################################################
583
+ ###################################################### VOLUME AND DENSITY #######################################################
584
+ #################################################################################################################################
585
+
586
+ # molar volume of individual gas species (J/mol/bar - *10 for cm3/bar)
587
+ def gas_molar_volume(gas_species,PT,species,models):
588
+ P = PT['P']
589
+ T = PT['T']+273.15
590
+ Pr = P/species.loc[gas_species,"Pcr"]
591
+ Tr = T/species.loc[gas_species,"Tcr"]
592
+ PTr = {"P":Pr,"T":Tr}
593
+ R = 8.3145 # J/mol/K
594
+ if gas_species == "O2" or "CO2" or "OCS" or "CH4" or "CO":
595
+ y = mdv.y_SS(PT,species,models)
596
+ elif gas_species == "SO2":
597
+ y = mdv.y_SO2(PT,species,models)
598
+ elif gas_species == "H2S":
599
+ y = mdv.y_H2S(PT,species,models)
600
+ elif gas_species == "H2":
601
+ y = mdv.y_H2(PT,species,models)
602
+ elif gas_species == "H2O":
603
+ y = mdv.y_H2O(PT,species,models)
604
+ Vm = (R*T*y)/P
605
+ PT = {"P":P,"T":T-273.15}
606
+ return Vm
607
+
608
+ def Vm_O2(PT,species,models):
609
+ gas_species = "O2"
610
+ Vm = gas_molar_volume(gas_species,PT,species,models)
611
+ return Vm
612
+
613
+ def Vm_H2(PT,species,models):
614
+ gas_species = "H2"
615
+ Vm = gas_molar_volume(gas_species,PT,species,models)
616
+ return Vm
617
+
618
+ def Vm_H2O(PT,species,models):
619
+ gas_species = "H2O"
620
+ Vm = gas_molar_volume(gas_species,PT,species,models)
621
+ return Vm
622
+
623
+ def Vm_CO2(PT,species,models):
624
+ gas_species = "CO2"
625
+ Vm = gas_molar_volume(gas_species,PT,species,models)
626
+ return Vm
627
+
628
+ def Vm_CH4(PT,species,models):
629
+ gas_species = "CH4"
630
+ Vm = gas_molar_volume(gas_species,PT,species,models)
631
+ return Vm
632
+
633
+ def Vm_CO(PT,species,models):
634
+ gas_species = "CO"
635
+ Vm = gas_molar_volume(gas_species,PT,species,models)
636
+ return Vm
637
+
638
+ def Vm_S2(PT,species,models):
639
+ gas_species = "S2"
640
+ Vm = gas_molar_volume(gas_species,PT,species,models)
641
+ return Vm
642
+
643
+ def Vm_SO2(PT,species,models):
644
+ gas_species = "SO2"
645
+ Vm = gas_molar_volume(gas_species,PT,species,models)
646
+ return Vm
647
+
648
+ def Vm_H2S(PT,species,models):
649
+ gas_species = "H2S"
650
+ Vm = gas_molar_volume(gas_species,PT,species,models)
651
+ return Vm
652
+
653
+ def Vm_OCS(PT,species,models):
654
+ gas_species = "OCS"
655
+ Vm = gas_molar_volume(gas_species,PT,species,models)
656
+ return Vm
657
+
658
+ # molar volume of the gas in J/bar/mol
659
+ def Vm_gas(gas_mf,PT,species,models):
660
+ Vm = gas_mf["O2"]*Vm_O2(PT,species,models) + gas_mf["H2"]*Vm_H2(PT,species,models) + gas_mf["H2O"]*Vm_H2O(PT,species,models) + gas_mf["CO2"]*Vm_CO2(PT,species,models) + gas_mf["CO"]*Vm_CO(PT,species,models) + gas_mf["CH4"]*Vm_CH4(PT,species,models) + gas_mf["S2"]*Vm_S2(PT,species,models) + gas_mf["H2S"]*Vm_H2S(PT,species,models) + gas_mf["SO2"]*Vm_SO2(PT,species,models) + gas_mf["OCS"]*Vm_OCS(PT,species,models)
661
+ return Vm
662
+
663
+ # volume of the gas in cm3
664
+ def gas_volume(PT,gas_mf,bulk_wf,species,models):
665
+ Xg_O2, Xg_H2, Xg_H2O, Xg_H2S, Xg_S2, Xg_SO2, Xg_CO2, Xg_CO, Xg_CH4, Xg_OCS, Xt_g = gas_moles(gas_mf,bulk_wf,species)
666
+ volume = Xt_g*Vm_gas(gas_mf,PT,species,models) # in J/bar
667
+ volume_cm3 = volume*10.
668
+ return volume_cm3
669
+
670
+ # density of the gas in g/cm3
671
+ def gas_density(PT,gas_mf,bulk_wf,species,models):
672
+ volume = gas_volume(PT,gas_mf,bulk_wf,species,models) # cm3
673
+ mass = (gas_mf['wt_g']*bulk_wf['Wt']) # g
674
+ density = mass/volume
675
+ return density
676
+
677
+
678
+ # volume of the melt in cm3
679
+ def melt_volume(run,PT,melt_wf,bulk_wf,gas_mf,setup,species):
680
+ density = mdv.melt_density(run,PT,melt_wf,setup,species)
681
+ mass = bulk_wf['Wt']*(1-gas_mf['wt_g'])
682
+ volume = mass/density
683
+ return volume
684
+
685
+ # volume of the system (melt + gas)
686
+ def system_density(run,PT,melt_wf,gas_mf,bulk_wf,setup,species,models):
687
+ wt_g_ = gas_mf['wt_g']
688
+ wt_m_ = 1. - wt_g_
689
+ density_m = mdv.melt_density(run,PT,melt_wf,setup,species)
690
+ if wt_g_ > 0.:
691
+ density_g = gas_density(PT,gas_mf,bulk_wf,species,models)
692
+ else:
693
+ density_g = 0.
694
+ density_sys = density_m*wt_m_ + density_g*wt_g_
695
+ return density_sys
696
+
697
+ ##################################################################################################################################
698
+ ######################################################## melt composition ########################################################
699
+ ##################################################################################################################################
700
+
701
+ def melt_comp(run,setup):
702
+ melt_wf = {'SiO2':setup.loc[run,"SiO2"],'TiO2':setup.loc[run,"TiO2"],'Al2O3':setup.loc[run,"Al2O3"],'FeOT':setup.loc[run,"FeOT"],'Fe2O3T':setup.loc[run,"Fe2O3T"],'FeO':setup.loc[run,"FeO"],'Fe2O3':setup.loc[run,"Fe2O3"],'MgO':setup.loc[run,"MgO"],'MnO':setup.loc[run,"MnO"],'CaO':setup.loc[run,"CaO"],'Na2O':setup.loc[run,"Na2O"],'K2O':setup.loc[run,"K2O"],'P2O5':setup.loc[run,"P2O5"],"logfO2_i":setup.loc[run,"logfO2"],"Fe3FeT_i":setup.loc[run,"Fe3FeT"],"DNNO":setup.loc[run,"DNNO"],"DFMQ":setup.loc[run,"DFMQ"],"S6ST_i":setup.loc[run,"S6ST"]}
703
+ return melt_wf
704
+
705
+ # normalise melt composition in weight fraction
706
+ def melt_normalise_wf(melt_wf,species,volatiles,Fe_speciation):
707
+ if volatiles == "yes": # assumes all H is H2O, all C is CO2, all S is S, all X is X
708
+ H2O = (melt_wf["HT"]/species.loc["H2","M"])*species.loc["H2O","M"]
709
+ CO2 = (melt_wf["CT"]/species.loc["C","M"])*species.loc["CO2","M"]
710
+ S = melt_wf["ST"]
711
+ X = melt_wf["XT"]
712
+ elif volatiles == "water": # assumes all H is H2O
713
+ H2O = (melt_wf["HT"]/species.loc["H2","M"])*species.loc["H2O","M"]
714
+ CO2, S, X = 0.,0.,0.
715
+ elif volatiles == "no":
716
+ H2O, CO2, S, X = 0.,0.,0.,0.
717
+ volatiles = H2O + CO2 + S + X
718
+ if Fe_speciation == "no":
719
+ Wm_FeOT_ = Wm_FeOT(melt_wf,species)
720
+ Wm_FeO_ = 0.
721
+ Wm_Fe2O3_ = 0.
722
+ elif Fe_speciation == "yes":
723
+ Wm_FeOT_ = 0.
724
+ Wm_FeO_ = Wm_FeO(melt_wf,species)
725
+ Wm_Fe2O3_ = Wm_Fe2O3(melt_wf,species)
726
+ tot = (melt_wf["SiO2"] + melt_wf["TiO2"] + melt_wf["Al2O3"] + Wm_FeOT_ + Wm_FeO_ + Wm_Fe2O3_ + melt_wf["MgO"] + melt_wf["MnO"] + melt_wf["CaO"] + melt_wf["Na2O"] + melt_wf["K2O"] + melt_wf["P2O5"])
727
+ result = {"SiO2":(melt_wf["SiO2"]/tot)*(1.-volatiles)}
728
+ result["TiO2"] = (melt_wf["TiO2"]/tot)*(1.-volatiles)
729
+ result["Al2O3"] = (melt_wf["Al2O3"]/tot)*(1.-volatiles)
730
+ result["FeOT"] = (Wm_FeOT_/tot)*(1.-volatiles)
731
+ result["FeO"] = (Wm_FeO_/tot)*(1.-volatiles)
732
+ result["Fe2O3"] = (Wm_Fe2O3_/tot)*(1.-volatiles)
733
+ result["MgO"] = (melt_wf["MgO"]/tot)*(1.-volatiles)
734
+ result["MnO"] = (melt_wf["MnO"]/tot)*(1.-volatiles)
735
+ result["CaO"] = (melt_wf["CaO"]/tot)*(1.-volatiles)
736
+ result["Na2O"] = (melt_wf["Na2O"]/tot)*(1.-volatiles)
737
+ result["K2O"] = (melt_wf["K2O"]/tot)*(1.-volatiles)
738
+ result["P2O5"] = (melt_wf["P2O5"]/tot)*(1.-volatiles)
739
+ result["H2O"] = H2O
740
+ result["CO2"] = CO2
741
+ result["S"] = S
742
+ result["X"] = X
743
+ return result
744
+
745
+ # calculate cation proportions
746
+ def melt_cation_proportion(melt_wf,species,volatiles,Fe_speciation):
747
+ melt_comp = melt_normalise_wf(melt_wf,species,volatiles,Fe_speciation)
748
+ tot = ((species.loc["SiO2","no_cat"]*melt_comp["SiO2"])/species.loc["SiO2","M"]) + ((species.loc["TiO2","no_cat"]*melt_comp["TiO2"])/species.loc["TiO2","M"]) + ((species.loc["Al2O3","no_cat"]*melt_comp["Al2O3"])/species.loc["Al2O3","M"]) + ((species.loc["FeO","no_cat"]*melt_comp["FeOT"])/species.loc["FeO","M"]) + ((species.loc["FeO","no_cat"]*melt_comp["FeO"])/species.loc["FeO","M"]) + ((species.loc["Fe2O3","no_cat"]*melt_comp["Fe2O3"])/species.loc["Fe2O3","M"]) + ((species.loc["MgO","no_cat"]*melt_comp["MgO"])/species.loc["MgO","M"]) + ((species.loc["MnO","no_cat"]*melt_comp["MnO"])/species.loc["MnO","M"]) + ((species.loc["CaO","no_cat"]*melt_comp["CaO"])/species.loc["CaO","M"]) + ((species.loc["Na2O","no_cat"]*melt_comp["Na2O"])/species.loc["Na2O","M"]) + ((species.loc["K2O","no_cat"]*melt_comp["K2O"])/species.loc["K2O","M"]) + ((species.loc["P2O5","no_cat"]*melt_comp["P2O5"])/species.loc["P2O5","M"]) + ((species.loc["H2O","no_cat"]*melt_comp["H2O"])/species.loc["H2O","M"]) + ((species.loc["CO2","no_cat"]*melt_comp["CO2"])/species.loc["CO2","M"])
749
+ result = {"Si":((species.loc["SiO2","no_cat"]*melt_comp["SiO2"])/species.loc["SiO2","M"])/tot}
750
+ result["Ti"] = ((species.loc["TiO2","no_cat"]*melt_comp["TiO2"])/species.loc["TiO2","M"])/tot
751
+ result["Al"] = ((species.loc["Al2O3","no_cat"]*melt_comp["Al2O3"])/species.loc["Al2O3","M"])/tot
752
+ result["FeT"] = ((species.loc["FeO","no_cat"]*melt_comp["FeOT"])/species.loc["FeO","M"])/tot
753
+ result["Fe2"] = ((species.loc["FeO","no_cat"]*melt_comp["FeO"])/species.loc["FeO","M"])/tot
754
+ result["Fe3"] = ((species.loc["Fe2O3","no_cat"]*melt_comp["Fe2O3"])/species.loc["Fe2O3","M"])/tot
755
+ result["Mg"] = ((species.loc["MgO","no_cat"]*melt_comp["MgO"])/species.loc["MgO","M"])/tot
756
+ result["Mn"] = ((species.loc["MgO","no_cat"]*melt_comp["MnO"])/species.loc["MnO","M"])/tot
757
+ result["Ca"] = ((species.loc["CaO","no_cat"]*melt_comp["CaO"])/species.loc["CaO","M"])/tot
758
+ result["Na"] = ((species.loc["Na2O","no_cat"]*melt_comp["Na2O"])/species.loc["Na2O","M"])/tot
759
+ result["K"] = ((species.loc["K2O","no_cat"]*melt_comp["K2O"])/species.loc["K2O","M"])/tot
760
+ result["P"] = ((species.loc["P2O5","no_cat"]*melt_comp["P2O5"])/species.loc["P2O5","M"])/tot
761
+ result["H"] = ((species.loc["H2O","no_cat"]*melt_comp["H2O"])/species.loc["H2O","M"])/tot
762
+ result["C"] = ((species.loc["CO2","no_cat"]*melt_comp["CO2"])/species.loc["CO2","M"])/tot
763
+ return result
764
+
765
+ # calculate mole fractions in the melt
766
+ def melt_mole_fraction(melt_wf,species,models,volatiles,Fe_speciation):
767
+ melt_comp = melt_normalise_wf(melt_wf,species,volatiles,Fe_speciation)
768
+ species_X = models.loc["species X","option"]
769
+ mol_tot = (melt_comp["SiO2"]/species.loc["SiO2","M"]) + (melt_comp["TiO2"]/species.loc["TiO2","M"]) + (melt_comp["Al2O3"]/species.loc["Al2O3","M"]) + (melt_comp["FeOT"]/species.loc["FeO","M"]) + (melt_comp["FeO"]/species.loc["FeO","M"]) + (melt_comp["Fe2O3"]/species.loc["Fe2O3","M"]) + (melt_comp["MnO"]/species.loc["MnO","M"]) + (melt_comp["MgO"]/species.loc["MgO","M"]) + (melt_comp["CaO"]/species.loc["CaO","M"]) + (melt_comp["Na2O"]/species.loc["Na2O","M"]) + (melt_comp["K2O"]/species.loc["K2O","M"]) + (melt_comp["P2O5"]/species.loc["P2O5","M"]) + (melt_comp["H2O"]/species.loc["H2O","M"]) + (melt_comp["CO2"]/species.loc["CO2","M"]) + (melt_comp["S"]/species.loc["S","M"]) + (melt_comp["X"]/species.loc[species_X,"M"])
770
+ result = {"SiO2":(melt_comp["SiO2"]/species.loc["SiO2","M"])/mol_tot}
771
+ result["TiO2"] = (melt_comp["TiO2"]/species.loc["TiO2","M"])/mol_tot
772
+ result["Al2O3"] = (melt_comp["Al2O3"]/species.loc["Al2O3","M"])/mol_tot
773
+ result["FeOT"] = (melt_comp["FeOT"]/species.loc["FeO","M"])/mol_tot
774
+ result["FeO"] = (melt_comp["FeO"]/species.loc["FeO","M"])/mol_tot
775
+ result["Fe2O3"] = (melt_comp["Fe2O3"]/species.loc["Fe2O3","M"])/mol_tot
776
+ result["MnO"] = (melt_comp["MnO"]/species.loc["MnO","M"])/mol_tot
777
+ result["MgO"] = (melt_comp["MgO"]/species.loc["MgO","M"])/mol_tot
778
+ result["CaO"] = (melt_comp["CaO"]/species.loc["CaO","M"])/mol_tot
779
+ result["Na2O"] = (melt_comp["Na2O"]/species.loc["Na2O","M"])/mol_tot
780
+ result["K2O"] = (melt_comp["K2O"]/species.loc["K2O","M"])/mol_tot
781
+ result["P2O5"] = (melt_comp["P2O5"]/species.loc["P2O5","M"])/mol_tot
782
+ result["H2O"] = (melt_comp["H2O"]/species.loc["H2O","M"])/mol_tot
783
+ result["CO2"] = (melt_comp["CO2"]/species.loc["CO2","M"])/mol_tot
784
+ result["S"] = (melt_comp["S"]/species.loc["S","M"])/mol_tot
785
+ result["X"] = (melt_comp["X"]/species.loc[species_X,"M"])/mol_tot
786
+ result["mol_tot"] = mol_tot
787
+ return result
788
+
789
+ def melt_single_O(melt_wf,species,volatiles,Fe_speciation):
790
+ melt_comp = melt_normalise_wf(melt_wf,species,volatiles,Fe_speciation)
791
+ Xmtot = (melt_comp["SiO2"]/(species.loc["SiO2","M"]/species.loc["SiO2","no_O"])) + (melt_comp["TiO2"]/(species.loc["TiO2","M"]/species.loc["TiO2","no_O"])) + (melt_comp["Al2O3"]/(species.loc["Al2O3","M"]/species.loc["Al2O3","no_O"])) + (melt_comp["MnO"]/(species.loc["MnO","M"]/species.loc["MnO","no_O"])) + (melt_comp["MgO"]/(species.loc["MgO","M"]/species.loc["MgO","no_O"])) + (melt_comp["CaO"]/(species.loc["CaO","M"]/species.loc["CaO","no_O"])) + (melt_comp["Na2O"]/(species.loc["Na2O","M"]/species.loc["Na2O","no_O"])) + (melt_comp["K2O"]/(species.loc["K2O","M"]/species.loc["K2O","no_O"])) + (melt_comp["P2O5"]/(species.loc["P2O5","M"]/species.loc["P2O5","no_O"])) + (melt_comp["FeOT"]/(species.loc["FeO","M"]/species.loc["FeO","no_O"])) + (melt_comp["FeO"]/(species.loc["FeO","M"]/species.loc["FeO","no_O"])) + (melt_comp["Fe2O3"]/(species.loc["Fe2O3","M"]/species.loc["Fe2O3","no_O"])) + (melt_comp["H2O"]/(species.loc["H2O","M"]/species.loc["H2O","no_O"])) + (melt_comp["CO2"]/(species.loc["CO2","M"]/species.loc["CO2","no_O"]))
792
+ result = {"SiO2": (melt_comp["SiO2"]/(species.loc["SiO2","M"]/species.loc["SiO2","no_O"]))/Xmtot}
793
+ result["TiO2"] = (melt_comp["TiO2"]/(species.loc["TiO2","M"]/species.loc["TiO2","no_O"]))/Xmtot
794
+ result["Al2O3"] = (melt_comp["Al2O3"]/(species.loc["Al2O3","M"]/species.loc["Al2O3","no_O"]))/Xmtot
795
+ result["FeOT"] = (melt_comp["FeOT"]/(species.loc["FeO","M"]/species.loc["FeO","no_O"]))/Xmtot
796
+ result["FeO"] = (melt_comp["FeO"]/(species.loc["FeO","M"]/species.loc["FeO","no_O"]))/Xmtot
797
+ result["Fe2O3"] = (melt_comp["Fe2O3"]/(species.loc["Fe2O3","M"]/species.loc["Fe2O3","no_O"]))/Xmtot
798
+ result["MnO"] = (melt_comp["MnO"]/(species.loc["MnO","M"]/species.loc["MnO","no_O"]))/Xmtot
799
+ result["MgO"] = (melt_comp["MgO"]/(species.loc["MgO","M"]/species.loc["MgO","no_O"]))/Xmtot
800
+ result["CaO"] = (melt_comp["CaO"]/(species.loc["CaO","M"]/species.loc["CaO","no_O"]))/Xmtot
801
+ result["P2O5"] = (melt_comp["P2O5"]/(species.loc["P2O5","M"]/species.loc["P2O5","no_O"]))/Xmtot
802
+ result["Na2O"] = (melt_comp["Na2O"]/(species.loc["Na2O","M"]/species.loc["Na2O","no_O"]))/Xmtot
803
+ result["K2O"] = (melt_comp["K2O"]/(species.loc["K2O","M"]/species.loc["K2O","no_O"]))/Xmtot
804
+ result["H2O"] = (melt_comp["H2O"]/species.loc["H2O","M"])/Xmtot
805
+ result["CO2"] = (melt_comp["CO2"]/species.loc["CO2","M"])/Xmtot
806
+ result["Xmtot"] = Xmtot
807
+ return result
808
+
809
+ def melt_pysulfsat(melt_wf,species): # output dataframe for pysulfsat
810
+ comp = {'SiO2_Liq': [melt_wf["SiO2"]],
811
+ 'TiO2_Liq': [melt_wf["TiO2"]],
812
+ 'Al2O3_Liq': [melt_wf["Al2O3"]],
813
+ 'FeOt_Liq': [Wm_FeOT(melt_wf,species)],
814
+ 'MnO_Liq': [melt_wf["MnO"]],
815
+ 'MgO_Liq': [melt_wf["MgO"]],
816
+ 'CaO_Liq': [melt_wf["CaO"]],
817
+ 'Na2O_Liq': [melt_wf["Na2O"]],
818
+ 'K2O_Liq': [melt_wf["K2O"]],
819
+ 'P2O5_Liq': [melt_wf["P2O5"]]}
820
+ comp = pd.DataFrame(comp)
821
+ return comp