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/calculations.py ADDED
@@ -0,0 +1,954 @@
1
+ # calculations.py
2
+
3
+ import pandas as pd
4
+ from datetime import date
5
+ import numpy as np
6
+ import datetime
7
+
8
+ import VolFe.melt_gas as mg
9
+ import VolFe.equilibrium_equations as eq
10
+ import VolFe.isotopes as iso
11
+ import VolFe.model_dependent_variables as mdv
12
+
13
+
14
+
15
+ ###########################
16
+ ### saturation pressure ###
17
+ ###########################
18
+
19
+ # for a given melt composition, calcualte the saturation pressure
20
+ def P_sat(PT,melt_wf,species,models,Ptol,nr_step,nr_tol):
21
+ ST = melt_wf["ST"]
22
+ #H2OT = melt_wf["H2OT"]
23
+ #CO2 = melt_wf["CO2"]
24
+ #HT = melt_wf["HT"]
25
+ #CT = melt_wf["CT"]
26
+ #XT = melt_wf["XT"]
27
+ #melt_wf1 = {"ST":ST,"CO2":CO2,"H2OT":H2OT,"HT":HT,"CT":CT, "XT":XT} # to work out P_sat
28
+ #melt_wf2 = {"ST":ST,"CO2":CO2,"H2OT":H2OT,"HT":HT,"CT":CT, "XT":XT} # to work out sulfur saturation
29
+ melt_wf1 = {'SiO2': melt_wf["SiO2"], 'TiO2': melt_wf["TiO2"], 'Al2O3': melt_wf["Al2O3"], 'FeOT': melt_wf["FeOT"], 'Fe2O3T': melt_wf["Fe2O3T"], 'FeO': melt_wf["FeO"], 'Fe2O3': melt_wf["Fe2O3"], 'MgO': melt_wf["MgO"], 'MnO': melt_wf["MnO"], 'CaO': melt_wf["CaO"], 'Na2O': melt_wf["Na2O"], 'K2O': melt_wf["K2O"], 'P2O5': melt_wf["P2O5"], 'logfO2_i': melt_wf["logfO2_i"], 'Fe3FeT_i': melt_wf["Fe3FeT_i"], 'DNNO': melt_wf["DNNO"], 'DFMQ': melt_wf["DFMQ"], 'S6ST_i': melt_wf["S6ST_i"], "ST":melt_wf["ST"],"CO2":melt_wf["CO2"],"H2OT":melt_wf["H2OT"],"HT":melt_wf["HT"],"CT":melt_wf["CT"], "XT":melt_wf["XT"]} # to work out P_sat
30
+ melt_wf2 = {'SiO2': melt_wf["SiO2"], 'TiO2': melt_wf["TiO2"], 'Al2O3': melt_wf["Al2O3"], 'FeOT': melt_wf["FeOT"], 'Fe2O3T': melt_wf["Fe2O3T"], 'FeO': melt_wf["FeO"], 'Fe2O3': melt_wf["Fe2O3"], 'MgO': melt_wf["MgO"], 'MnO': melt_wf["MnO"], 'CaO': melt_wf["CaO"], 'Na2O': melt_wf["Na2O"], 'K2O': melt_wf["K2O"], 'P2O5': melt_wf["P2O5"], 'logfO2_i': melt_wf["logfO2_i"], 'Fe3FeT_i': melt_wf["Fe3FeT_i"], 'DNNO': melt_wf["DNNO"], 'DFMQ': melt_wf["DFMQ"], 'S6ST_i': melt_wf["S6ST_i"], "ST":melt_wf["ST"],"CO2":melt_wf["CO2"],"H2OT":melt_wf["H2OT"],"HT":melt_wf["HT"],"CT":melt_wf["CT"], "XT":melt_wf["XT"]} # to work out sulfur saturation
31
+
32
+ def Pdiff(guess,melt_wf,species,models):
33
+ PT["P"] = guess
34
+ difference = abs(guess - mg.p_tot(PT,melt_wf,species,models))
35
+ return difference
36
+
37
+ guess0 = 40000. # initial guess for pressure
38
+ PT["P"] = guess0
39
+ melt_wf1["Fe3FeT"] = mg.Fe3FeT_i(PT,melt_wf,species,models)
40
+ melt_wf2["Fe3FeT"] = mg.Fe3FeT_i(PT,melt_wf,species,models)
41
+ #wt_C, wt_O, wt_H, wt_S, wt_Fe, wt_g, Wt = bulk_composition(run,PT,melt_wf1,setup,species,models)
42
+ #bulk_wf = {"H":wt_H,"C":wt_C,"S":wt_S}
43
+ ms_conc = eq.melt_speciation(PT,melt_wf1,species,models,nr_step,nr_tol)
44
+ ms_frac = melt_species_ratios(ms_conc,species)
45
+ melt_wf1["H2OT"] = ms_conc["wm_H2O"]
46
+ melt_wf2["H2OT"] = ms_conc["wm_H2O"]
47
+ melt_wf1["CO2"] = ms_conc["wm_CO2"]
48
+ melt_wf2["CO2"] = ms_conc["wm_CO2"]
49
+ melt_wf1["S2-"] = ms_conc["wm_S2m"]
50
+ melt_wf2["S2-"] = ms_conc["wm_S2m"]
51
+ melt_wf1["ST"] = ST
52
+ melt_wf2["ST"] = ST
53
+ if models.loc["sulfur_saturation","option"] == "yes": # must incorporate H2S concentration into S2- for SCSS
54
+ sulfsat = sulfur_saturation(PT,melt_wf2,species,models)
55
+ melt_wf1["ST"] = sulfsat["ST"]/1000000.
56
+ melt_wf2["ST"] = ST
57
+ delta1 = Pdiff(guess0,melt_wf1,species,models)
58
+ while delta1 > Ptol :
59
+ delta1 = Pdiff(guess0,melt_wf1,species,models)
60
+ guess0 = mg.p_tot(PT,melt_wf1,species,models)
61
+ guess0 = float(guess0)
62
+ PT["P"] = guess0
63
+ melt_wf1["Fe3FeT"] = mg.Fe3FeT_i(PT,melt_wf,species,models)
64
+ melt_wf2["Fe3FeT"] = mg.Fe3FeT_i(PT,melt_wf,species,models)
65
+ ms_conc = eq.melt_speciation(PT,melt_wf1,species,models,nr_step,nr_tol)
66
+ ms_frac = melt_species_ratios(ms_conc,species)
67
+ melt_wf1["H2OT"] = ms_conc["wm_H2O"]
68
+ melt_wf2["H2OT"] = ms_conc["wm_H2O"]
69
+ melt_wf1["CO2"] = ms_conc["wm_CO2"]
70
+ melt_wf2["CO2"] = ms_conc["wm_CO2"]
71
+ melt_wf1["S2-"] = ms_conc["wm_S2m"]
72
+ melt_wf2["S2-"] = ms_conc["wm_S2m"]
73
+ if models.loc["sulfur_saturation","option"] == "yes":
74
+ sulfsat = sulfur_saturation(PT,melt_wf2,species,models)
75
+ melt_wf1["ST"] = sulfsat["ST"]/1000000.
76
+ melt_wf2["ST"] = ST
77
+ else:
78
+ P_sat = guess0
79
+ ms_conc = eq.melt_speciation(PT,melt_wf1,species,models,nr_step,nr_tol)
80
+ ms_frac = melt_species_ratios(ms_conc,species)
81
+
82
+ melt_wf["ST"] = ST
83
+ return P_sat, ms_conc, ms_frac
84
+
85
+ # for a given melt composition, calcualte the saturation pressure
86
+ def P_sat_H2O_CO2(PT,melt_wf,species,models,Ptol,nr_step,nr_tol): # Pvsat with just H2O and CO2 in vapour
87
+
88
+ def p_tot_H2O_CO2(PT,melt_wf,species,models):
89
+ value = mg.p_H2O(PT,melt_wf,species,models) + mg.p_CO2(PT,melt_wf,species,models)
90
+ return value
91
+
92
+ def Pdiff(guess,melt_wf,species,models):
93
+ PT["P"] = guess
94
+ difference = abs(guess - p_tot_H2O_CO2(PT,melt_wf,species,models))
95
+ return difference
96
+
97
+ if melt_wf['CO2'] == 0 and melt_wf['H2OT'] == 0:
98
+ P_sat = ""
99
+ result = {"xg_H2O":0., "xg_CO2":0., "f_H2O":0., "f_CO2":0., "p_H2O":0., "p_CO2":0., "wm_H2O":0., "wm_CO2":0.}
100
+
101
+ else:
102
+ guess0 = 40000. # initial guess for pressure
103
+ PT["P"] = guess0
104
+ delta1 = Pdiff(guess0,melt_wf,species,models)
105
+ while delta1 > Ptol :
106
+ delta1 = Pdiff(guess0,melt_wf,species,models)
107
+ guess0 = p_tot_H2O_CO2(PT,melt_wf,species,models)
108
+ guess0 = float(guess0)
109
+ PT["P"] = guess0
110
+ else:
111
+ P_sat = guess0
112
+ xg_H2O_ = mg.xg_H2O(PT,melt_wf,species,models)
113
+ xg_CO2_ = mg.xg_CO2(PT,melt_wf,species,models)
114
+ p_H2O_ = mg.p_H2O(PT,melt_wf,species,models)
115
+ p_CO2_ = mg.p_CO2(PT,melt_wf,species,models)
116
+ f_H2O_ = mg.f_H2O(PT,melt_wf,species,models)
117
+ f_CO2_ = mg.f_CO2(PT,melt_wf,species,models)
118
+ xm_H2O_ = (mdv.C_H2O(PT,melt_wf,species,models)*f_H2O_)**0.5
119
+ xm_CO2_ = mdv.C_CO3(PT,melt_wf,species,models)*f_CO2_
120
+ M_m_ = mg.M_m_SO(melt_wf,species)
121
+ Xm_t = xm_CO2_*species.loc["CO2","M"] + xm_H2O_*species.loc["H2O","M"] + (1.0-xm_CO2_-xm_H2O_)*M_m_
122
+ wm_H2O_ = (xm_H2O_*species.loc["H2O","M"])/Xm_t
123
+ wm_CO2_ = (xm_CO2_*species.loc["CO2","M"])/Xm_t
124
+
125
+ result = {"xg_H2O":xg_H2O_, "xg_CO2":xg_CO2_, "f_H2O":f_H2O_, "f_CO2":f_CO2_, "p_H2O":p_H2O_, "p_CO2":p_CO2_, "wm_H2O":wm_H2O_, "wm_CO2":wm_CO2_}
126
+
127
+ return P_sat, result
128
+
129
+ # for a given fS2 and fO2, calculate Psat
130
+ def P_sat_fO2_fS2(PT,melt_wf,species,models,Ptol):
131
+
132
+ def Pdiff(guess,melt_wf,species,models):
133
+ PT["P"] = guess
134
+ result_fO2fS2 = eq.p_tot_fO2_fS2(PT,melt_wf,species,models)
135
+ difference = abs(guess - result_fO2fS2["P_tot"])
136
+ return difference
137
+
138
+ guess0 = 40000. # initial guess for pressure
139
+ PT["P"] = guess0
140
+ delta1 = Pdiff(guess0,melt_wf,species,models)
141
+
142
+ while delta1 > Ptol :
143
+ delta1 = Pdiff(guess0,melt_wf,species,models)
144
+ result_fO2fS2 = eq.p_tot_fO2_fS2(PT,melt_wf,species,models)
145
+ guess0 = result_fO2fS2["P_tot"]
146
+ guess0 = float(guess0)
147
+ PT["P"] = guess0
148
+ else:
149
+ result = eq.p_tot_fO2_fS2(PT,melt_wf,species,models)
150
+
151
+ return results
152
+
153
+
154
+
155
+ ###################
156
+ ### composition ###
157
+ ###################
158
+
159
+ # calculate bulk composition, including if a gas phase is present
160
+ def bulk_composition(run,PT,melt_wf,setup,species,models):
161
+ bulk_composition = models.loc["bulk_composition","option"]
162
+ eq_Fe = models.loc["eq_Fe","option"]
163
+ wm_CO2 = melt_wf["CO2"]
164
+ wm_H2O = melt_wf["H2OT"]
165
+ wm_H2 = melt_wf["H2"]
166
+ wm_CO = melt_wf["CO"]
167
+ wm_CH4 = melt_wf["CH4"]
168
+ wm_H2S = melt_wf["H2S"]
169
+ wm_S6p = melt_wf["S6+"]
170
+ wm_S2m = melt_wf["S2-"]
171
+ wm_ST = melt_wf["ST"]
172
+ wm_XT = melt_wf["XT"]
173
+ Fe3FeT = melt_wf["Fe3FeT"]
174
+ Fe3Fe2_ = mg.Fe3Fe2(melt_wf)
175
+ S6ST_ = mg.S6ST(PT,melt_wf,species,models)
176
+ #SCSS_,sulfide_sat,SCAS_,sulfate_sat = sulfur_saturation(wm_ST/100.0,S6ST_)
177
+ #print(P, S6ST_)
178
+
179
+ if bulk_composition == "yes":
180
+ wt_g = 0.
181
+ elif bulk_composition == "wtg":
182
+ wt_g = setup.loc[run,"wt_g"]/100.
183
+ elif bulk_composition == "CO2":
184
+ wt_C_ = ((species.loc['C','M']*(setup.loc[run,"initial_CO2wtpc"]/100.))/species.loc['CO2','M'])
185
+ wt_g = ((wt_C_/species.loc["C","M"]) - (wm_CO2/species.loc["CO2","M"]))/(((mg.xg_CO2(run,PT,melt_wf,setup,species,models)+mg.xg_CO(run,PT,melt_wf,setup,species,models)+mg.xg_CH4(run,PT,melt_wf,setup,species,models)+mg.xg_OCS(run,PT,melt_wf,setup,species,models))/mg.Xg_tot(run,PT,melt_wf,setup,species,models)) - (wm_CO2/species.loc["CO2","M"]))
186
+
187
+ if bulk_composition == "CO2":
188
+ wt_C = wt_C_
189
+ else:
190
+ wt_C = species.loc["C","M"]*((wt_g*(((mg.xg_CO2(PT,melt_wf,species,models)+
191
+ mg.xg_CO(PT,melt_wf,species,models)+
192
+ mg.xg_CH4(PT,melt_wf,species,models)+
193
+ mg.xg_OCS(PT,melt_wf,species,models))
194
+ /mg.Xg_tot(PT,melt_wf,species,models))
195
+ - (wm_CO2/species.loc["CO2","M"] - wm_CO/species.loc["CO","M"] -
196
+ wm_CH4/species.loc["CH4","M"]))) + (wm_CO2/species.loc["CO2","M"] +
197
+ wm_CO/species.loc["CO","M"] + wm_CH4/species.loc["CH4","M"]))
198
+
199
+ wt_H = 2.*species.loc["H","M"]*((wt_g*(((mg.xg_H2O(PT,melt_wf,species,models)+mg.xg_H2(PT,melt_wf,species,models)+2.*mg.xg_CH4(PT,melt_wf,species,models)+mg.xg_H2S(PT,melt_wf,species,models))/mg.Xg_tot(PT,melt_wf,species,models)) - (wm_H2O/species.loc["H2O","M"] - wm_H2/species.loc["H2","M"] - wm_H2S/species.loc["H2S","M"] - (2.*wm_CH4)/species.loc["CH4","M"]))) + (wm_H2O/species.loc["H2O","M"] + wm_H2/species.loc["H2","M"] + wm_H2S/species.loc["H2S","M"] + (2.*wm_CH4)/species.loc["CH4","M"]))
200
+
201
+ wt_S = species.loc["S","M"]*((wt_g*(((mg.xg_SO2(PT,melt_wf,species,models)
202
+ +2.0*mg.xg_S2(PT,melt_wf,species,models)
203
+ +mg.xg_H2S(PT,melt_wf,species,models)
204
+ +mg.xg_OCS(PT,melt_wf,species,models))
205
+ /mg.Xg_tot(PT,melt_wf,species,models))
206
+ - ((wm_S2m+wm_S6p)/species.loc["S","M"] - (wm_H2S/species.loc["H2S","M"]))))
207
+ + ((wm_S2m+wm_S6p)/species.loc["S","M"] + (wm_H2S/species.loc["H2S","M"])))
208
+
209
+ species_X = models.loc["species X","option"]
210
+ wt_X = species.loc[species_X,"M"]*((wt_g*(((mg.xg_X(PT,melt_wf,species,models))
211
+ /mg.Xg_tot(PT,melt_wf,species,models))
212
+ - wm_XT/species.loc[species_X,"M"]))
213
+ + wm_XT/species.loc[species_X,"M"])
214
+
215
+ if models.loc["mass_volume","option"] == "mass":
216
+ Wt = setup.loc[run, "total_mass_g"]
217
+ elif models.loc["mass_volume","option"] == "volume": ### THIS NEEDS FIXING ###
218
+ Wt = 0.
219
+
220
+ if eq_Fe == "no":
221
+ wt_Fe = 0.0
222
+ elif eq_Fe == "yes":
223
+ total_dissolved_volatiles = (wm_CO2 + wm_H2O + wm_ST*(1.-S6ST_) + (species.loc["SO3","M"]*((wm_ST*S6ST_)/species.loc["S","M"])))
224
+ wt_Fe = (1.-wt_g)*(((1.0-total_dissolved_volatiles)*mg.wm_Fe_nv(melt_wf,species))/100.0) # wt fraction of Fe
225
+
226
+ wt_O = species.loc["O","M"]*((wt_g*(((2.0*mg.xg_CO2(PT,melt_wf,species,models) + mg.xg_CO(PT,melt_wf,species,models) + 2.0*mg.xg_O2(PT,melt_wf,species,models) + mg.xg_H2O(PT,melt_wf,species,models) + 2.0*mg.xg_SO2(PT,melt_wf,species,models) + mg.xg_OCS(PT,melt_wf,species,models))/mg.Xg_tot(PT,melt_wf,species,models)) - (wm_H2O/species.loc["H2O","M"]) - ((2.0*wm_CO2)/species.loc["CO2","M"]) - (3.0*wm_S6p/species.loc["S","M"] - (wm_CO/species.loc["CO","M"])))) + (wm_H2O/species.loc["H2O","M"]) + ((2.0*wm_CO2)/species.loc["CO2","M"]) + (3.0*wm_S6p/species.loc["S","M"]) + (wm_CO/species.loc["CO","M"]) + (wt_Fe/species.loc["Fe","M"])*((1.5*Fe3Fe2_+1.0)/(Fe3Fe2_+1.0)))
227
+
228
+ result = {"wt_C":wt_C, "wt_O":wt_O, "wt_H":wt_H, "wt_S":wt_S, "wt_X":wt_X, "wt_Fe":wt_Fe, "wt_g":wt_g, "Wt":Wt}
229
+
230
+ return result
231
+
232
+ # calculate weight fraction of elements in the system when adding gas into a melt
233
+ def new_bulk_regas_open(PT,melt_wf,bulk_wf,gas_mf,dwtg,species,models):
234
+ me = mg.melt_elements(PT,melt_wf,bulk_wf,gas_mf,species,models)
235
+ mg = mg.gas_elements(gas_mf,species)
236
+ wt_C = (1.-dwtg)*me["wm_C"] + dwtg*ge["wg_C"]
237
+ wt_H = (1.-dwtg)*me["wm_H"] + dwtg*ge["wg_H"]
238
+ wt_O = (1.-dwtg)*me["wm_O"] + dwtg*ge["wg_O"]
239
+ wt_S = (1.-dwtg)*me["wm_S"] + dwtg*ge["wg_S"]
240
+ wt_X = (1.-dwtg)*me["wm_X"] + dwtg*ge["wg_X"]
241
+ wt_Fe = (1.-dwtg)*me["wm_Fe"]
242
+ Wt = bulk_wf['Wt']*(1. + dwtg)
243
+ result = {"wt_C":wt_C, "wt_H":wt_H, "wt_S":wt_S, "wt_Fe":wt_Fe, "wt_O":wt_O, "wt_X":wt_X, "Wt":Wt}
244
+ return result
245
+
246
+ # calculate mole fraction of species in the cumulated gas from open-system degassing
247
+ def gas_comp_all_open(xg,xg_all,models,species):
248
+ species_X = models.loc["species X","option"]
249
+ wt_g_before = xg_all["wt_g"]
250
+ wt_g_inst = xg["wt_g"]*(1.-wt_g_before)
251
+ wt_g_new = wt_g_before + wt_g_inst
252
+ f_before = wt_g_before/wt_g_new
253
+ f_inst = wt_g_inst/wt_g_new
254
+ wf_before = mg.gas_wf(xg_all,species,models)
255
+ wf_inst = mg.gas_wf(xg,species,models)
256
+ gas_wf_all_new = {"O2":wf_inst["wg_O2"]*f_inst+wf_before["wg_O2"]*f_before}
257
+ gas_wf_all_new["CO"] = wf_inst["wg_CO"]*f_inst+wf_before["wg_CO"]*f_before
258
+ gas_wf_all_new["S2"] = wf_inst["wg_S2"]*f_inst+wf_before["wg_S2"]*f_before
259
+ gas_wf_all_new["CO2"] = wf_inst["wg_CO2"]*f_inst+wf_before["wg_CO2"]*f_before
260
+ gas_wf_all_new["H2O"] = wf_inst["wg_H2O"]*f_inst+wf_before["wg_H2O"]*f_before
261
+ gas_wf_all_new["H2"] = wf_inst["wg_H2"]*f_inst+wf_before["wg_H2"]*f_before
262
+ gas_wf_all_new["CH4"] = wf_inst["wg_CH4"]*f_inst+wf_before["wg_CH4"]*f_before
263
+ gas_wf_all_new["SO2"] = wf_inst["wg_SO2"]*f_inst+wf_before["wg_SO2"]*f_before
264
+ gas_wf_all_new["H2S"] = wf_inst["wg_H2S"]*f_inst+wf_before["wg_H2S"]*f_before
265
+ gas_wf_all_new["OCS"] = wf_inst["wg_OCS"]*f_inst+wf_before["wg_OCS"]*f_before
266
+ gas_wf_all_new["X"] = wf_inst["wg_X"]*f_inst+wf_before["wg_X"]*f_before
267
+ tot = (gas_wf_all_new["X"]/species.loc[species_X,"M"]) + (gas_wf_all_new["OCS"]/species.loc["OCS","M"]) + (gas_wf_all_new["H2S"]/species.loc["H2S","M"]) + (gas_wf_all_new["SO2"]/species.loc["SO2","M"]) + (gas_wf_all_new["CH4"]/species.loc["CH4","M"]) + (gas_wf_all_new["H2"]/species.loc["H2","M"]) + (gas_wf_all_new["H2O"]/species.loc["H2O","M"]) + (gas_wf_all_new["CO2"]/species.loc["CO2","M"]) + (gas_wf_all_new["O2"]/species.loc["O2","M"]) + (gas_wf_all_new["CO"]/species.loc["CO","M"]) + (gas_wf_all_new["S2"]/species.loc["S2","M"])
268
+ gas_mf_all_new = {"O2":(gas_wf_all_new["O2"]/species.loc["O2","M"])/tot}
269
+ gas_mf_all_new["CO"] = (gas_wf_all_new["CO"]/species.loc["CO","M"])/tot
270
+ gas_mf_all_new["S2"] = (gas_wf_all_new["S2"]/species.loc["S2","M"])/tot
271
+ gas_mf_all_new["CO2"] = (gas_wf_all_new["CO2"]/species.loc["CO2","M"])/tot
272
+ gas_mf_all_new["H2O"] = (gas_wf_all_new["H2O"]/species.loc["H2O","M"])/tot
273
+ gas_mf_all_new["H2"] = (gas_wf_all_new["H2"]/species.loc["H2","M"])/tot
274
+ gas_mf_all_new["CH4"] = (gas_wf_all_new["CH4"]/species.loc["CH4","M"])/tot
275
+ gas_mf_all_new["SO2"] = (gas_wf_all_new["SO2"]/species.loc["SO2","M"])/tot
276
+ gas_mf_all_new["H2S"] = (gas_wf_all_new["H2S"]/species.loc["H2S","M"])/tot
277
+ gas_mf_all_new["OCS"] = (gas_wf_all_new["OCS"]/species.loc["OCS","M"])/tot
278
+ gas_mf_all_new["X"] = (gas_wf_all_new["X"]/species.loc[species_X,"M"])/tot
279
+ gas_mf_all_new["Xg_t"] = gas_mf_all_new["CO2"]*species.loc["CO2","M"] + gas_mf_all_new["CO"]*species.loc["CO","M"] + gas_mf_all_new["O2"]*species.loc["O2","M"] + gas_mf_all_new["H2O"]*species.loc["H2O","M"] + gas_mf_all_new["H2"]*species.loc["H2","M"] + gas_mf_all_new["CH4"]*species.loc["CH4","M"] + gas_mf_all_new["SO2"]*species.loc["SO2","M"] + gas_mf_all_new["S2"]*species.loc["S2","M"] + gas_mf_all_new["H2S"]*species.loc["H2S","M"] + gas_mf_all_new["OCS"]*species.loc["OCS","M"] + gas_mf_all_new["X"]*species.loc[species_X,"M"]
280
+ gas_mf_all_new["wt_g"] = wt_g_new
281
+ return gas_mf_all_new
282
+
283
+ # calculate ratios of volatile species in the melt
284
+ def melt_species_ratios(conc,species):
285
+
286
+ M_H = species.loc['H','M']
287
+ M_S = species.loc['S','M']
288
+ M_C = species.loc['C','M']
289
+ M_CO = species.loc['CO','M']
290
+ M_H2O = species.loc['H2O','M']
291
+ M_H2 = species.loc['H2','M']
292
+ M_CO2 = species.loc['CO2','M']
293
+ M_CH4 = species.loc['CH4','M']
294
+ M_H2S = species.loc['H2S','M']
295
+
296
+ wt_H = conc["wm_H2"] + ((2.*(conc["wm_H2O"]/M_H2O))*M_H) + ((4.*(conc["wm_CH4"]/M_CH4))*M_H) + ((2.*(conc["wm_H2S"]/M_H2S))*M_H)
297
+ if wt_H > 0.: # contains H
298
+ H2_HT = conc["wm_H2"]/wt_H
299
+ H2O_HT = ((2.*(conc["wm_H2O"]/M_H2O))*M_H)/wt_H
300
+ CH4_HT = ((4.*(conc["wm_CH4"]/M_CH4))*M_H)/wt_H
301
+ H2S_HT = ((2.*(conc["wm_H2S"]/M_H2S))*M_H)/wt_H
302
+
303
+ wt_C = ((conc["wm_CO"]/M_CO)*M_C) + ((conc["wm_CO2"]/M_CO2)*M_C) + ((conc["wm_CH4"]/M_CH4)*M_C)
304
+ if wt_C > 0.: # contains C
305
+ CO_CT = ((conc["wm_CO"]/M_CO)*M_C)/wt_C
306
+ CO2_CT = ((conc["wm_CO2"]/M_CO2)*M_C)/wt_C
307
+ CH4_CT = ((conc["wm_CH4"]/M_CH4)*M_C)/wt_C
308
+
309
+ wt_S = conc["wm_S2m"] + conc["wm_S6p"] + (M_S*(conc["wm_H2S"]/M_H2S))
310
+ if wt_S > 0.: # contains S
311
+ S2m_ST = conc["wm_S2m"]/wt_S
312
+ S6p_ST = conc["wm_S6p"]/wt_S
313
+ H2S_ST = (M_S*(conc["wm_H2S"]/M_H2S))/wt_S
314
+
315
+ frac = {"H2O_HT":H2O_HT, "H2_HT":H2_HT, "CH4_HT":CH4_HT, "CO2_CT":CO2_CT, "CO_CT":CO_CT, "CH4_CT":CH4_CT, "S6p_ST":S6p_ST, "S2m_ST":S2m_ST, "H2S_ST":H2S_ST, "H2S_HT":H2S_HT}
316
+
317
+ return frac
318
+
319
+
320
+ #########################
321
+ ### sulfur satuation ###
322
+ #########################
323
+
324
+ # check solid/immiscible liquid sulfur saturation
325
+ def sulfur_saturation(PT,melt_wf,species,models): # melt weight fraction of ST and S6/ST
326
+ wmST = melt_wf['ST']
327
+ S6T = mg.S6ST(PT,melt_wf,species,models)
328
+ wmS2 = wmST*100.0*10000.0*(1.0-S6T)
329
+ wmS6 = wmST*100.0*10000.0*S6T
330
+ SCSS_ = mdv.SCSS(PT,melt_wf,species,models)
331
+ SCAS_ = mdv.SCAS(PT,melt_wf,species,models)
332
+ StCSS = SCSS_/(1.-S6T)
333
+ StCAS = SCAS_/S6T
334
+ if wmS2 < SCSS_ and wmS6 < SCAS_:
335
+ sulfide_sat = "no"
336
+ sulfate_sat = "no"
337
+ ST = wmST*1000000.
338
+ elif wmS2 >= SCSS_ and wmS6 >= SCAS_:
339
+ sulfide_sat = "yes"
340
+ sulfate_sat = "yes"
341
+ ST = min(StCSS,StCAS)
342
+ elif wmS2 >= SCSS_ and wmS6 < SCAS_:
343
+ sulfide_sat = "yes"
344
+ sulfate_sat = "no"
345
+ ST = StCSS
346
+ elif wmS2 < SCSS_ and wmS6 >= SCAS_:
347
+ sulfide_sat = "no"
348
+ sulfate_sat = "yes"
349
+ ST = StCAS
350
+ else:
351
+ sulfide_sat = "nan"
352
+ sulfate_sat = "nan"
353
+ ST = wmST*1000000.
354
+ result = {"SCSS":SCSS_, "sulfide_sat":sulfide_sat, "SCAS":SCAS_, "sulfate_sat":sulfate_sat, "ST":ST}
355
+ return result
356
+
357
+ # fO2 and P of v+sulf+anh saturation
358
+ def fO2_P_VSA(PT,melt_wf,species,models,nr_step,nr_tol,Ptol):
359
+
360
+ def Pdiff(guess,melt_wf,species,models):
361
+ PT["P"] = guess
362
+ difference = abs(guess - mg.p_tot(PT,melt_wf,species,models))
363
+ return difference
364
+
365
+ def fO2_S(run,PT,melt_wf,setup,species,models):
366
+ SCSS_ = mdv.SCSS(PT,melt_wf,species,models)/1000000.
367
+ SCAS_ = mdv.SCAS(PT,melt_wf,species,models)/1000000.
368
+ CSO4 = mdv.C_SO4(PT,melt_wf,species,models)/1000000.
369
+ CS = mdv.C_S(PT,melt_wf,species,models)/1000000.
370
+
371
+ if models.loc["H2S_m","option"] == "no":
372
+ W = CSO4/CS
373
+ elif models.loc["H2S_m","option"] == "yes":
374
+ CH2S = mdv.C_H2S(PT,melt_wf,species,models)/1000000.
375
+ KHS = mdv.KHOSg(PT,models)
376
+ CH2OT = mdv.C_H2O(PT,melt_wf,species,models)
377
+ xmH2O = mg.xm_H2OT_so(melt_wf,species)
378
+ W = (CSO4/((KHS*CH2S*(xmH2O**2./CH2OT)) + CS))
379
+ fO2 = ((1./W)*(SCAS_/SCSS_))**0.5
380
+ ST = SCSS_ + SCAS_
381
+ return fO2, ST
382
+
383
+ guess0 = 40000. # initial guess for pressure
384
+ PT["P"] = guess0
385
+ fO2_, ST_ = fO2_S(PT,melt_wf,species,models)
386
+ melt_wf["ST"] = ST_
387
+ melt_wf["Fe3FeT"] = mdv.fO22Fe3FeT(fO2_,PT,melt_wf,species,models)
388
+ ms_conc = eq.melt_speciation(PT,melt_wf,species,models,nr_step,nr_tol)
389
+ ms_frac = melt_species_ratios(ms_conc,species)
390
+ melt_wf["H2OT"] = ms_cont["wm_H2O"]
391
+ melt_wf["CO2"] = ms_cont["wm_CO2"]
392
+ melt_wf["S2-"] = ms_cont["wm_S2m"]
393
+ delta1 = Pdiff(guess0,melt_wf,species,models)
394
+ while delta1 > Ptol :
395
+ delta1 = Pdiff(guess0,melt_wf,species,models)
396
+ guess0 = mg.p_tot(PT,melt_wf,species,models)
397
+ guess0 = float(guess0)
398
+ PT["P"] = guess0
399
+ fO2_, ST_ = fO2_S(PT,melt_wf,species,models)
400
+ melt_wf["ST"] = ST_
401
+ melt_wf["Fe3FeT"] = mdv.fO22Fe3FeT(fO2_,PT,melt_wf,species,models)
402
+ ms_conc = eq.melt_speciation(PT,melt_wf,species,models,nr_step,nr_tol)
403
+ ms_frac = melt_species_ratios(ms_conc,species)
404
+ melt_wf["H2OT"] = ms_conc["wm_H2O"]
405
+ melt_wf["CO2"] = ms_conc["wm_CO2"]
406
+ melt_wf["S2-"] = ms_conc["wm_S2m"]
407
+ else:
408
+ P_sat = guess0
409
+ ms_conc = eq.melt_speciation(PT,melt_wf,species,models,nr_step,nr_tol)
410
+ ms_frac = melt_species_ratios(ms_conc,species)
411
+ fO2_, ST_ = fO2_S(PT,melt_wf,species,models)
412
+ Fe3_FT = mdv.fO22Fe3FeT(fO2_,PT,melt_wf,species,models)
413
+
414
+ ms_frac["Fe3_FT"] = Fe3_FT
415
+
416
+ return P_sat, ms_conc, ms_frac
417
+
418
+ def P_VSA(PT,melt_wf,species,models,nr_step,nr_tol,Ptol):
419
+
420
+ #P_sat, pVSA_conc, pVSA_frac = fO2_P_VSA(PT,melt_wf,species,models,nr_step,nr_tol,Ptol)
421
+
422
+ def Pdiff(guess,melt_wf,species,models):
423
+ PT["P"] = guess
424
+ difference = abs(guess - mg.p_tot(PT,melt_wf,species,models))
425
+ return difference
426
+
427
+ guess0 = 40000. # initial guess for pressure
428
+ PT["P"] = guess0
429
+ melt_wf["Fe3FeT"] = mg.Fe3FeT_i(PT,melt_wf,species,models)
430
+ if melt_wf["Fe3FeT"] < Fe3_FT:
431
+ SCSS_ = mdv.SCSS(PT,melt_wf,species,models)/1000000.
432
+ S6T = mg.S6ST(PT,melt_wf,species,models)
433
+ ST_ = SCSS_/(1.-S6T)
434
+ else:
435
+ SCAS_ = mdv.SCAS(PT,melt_wf,species,models)/1000000.
436
+ S6T = mg.S6ST(PT,melt_wf,species,models)
437
+ ST_ = SCAS_/S6T
438
+ melt_wf["ST"] = ST_
439
+ ms_conc = eq.melt_speciation(PT,melt_wf,species,models,nr_step,nr_tol)
440
+ ms_frac = melt_species_ratios(ms_conc,species)
441
+ melt_wf["H2OT"] = ms_conc["wm_H2O"]
442
+ melt_wf["CO2"] = ms_conc["wm_CO2"]
443
+ melt_wf["S2-"] = ms_conc["wm_S2m"]
444
+ delta1 = Pdiff(guess0,melt_wf,species,models)
445
+ while delta1 > Ptol :
446
+ delta1 = Pdiff(guess0,melt_wf,species,models)
447
+ guess0 = mg.p_tot(PT,melt_wf,species,models)
448
+ guess0 = float(guess0)
449
+ PT["P"] = guess0
450
+ melt_wf["Fe3FeT"] = mg.Fe3FeT_i(PT,melt_wf,species,models)
451
+ if melt_wf["Fe3FeT"] < Fe3_FT:
452
+ SCSS_ = mdv.SCSS(PT,melt_wf,species,models)/1000000.
453
+ S6T = mg.S6ST(PT,melt_wf,species,models)
454
+ ST_ = SCSS_/(1.-S6T)
455
+ else:
456
+ SCAS_ = mdv.SCAS(PT,melt_wf,species,models)/1000000.
457
+ S6T = mg.S6ST(PT,melt_wf,species,models)
458
+ ST_ = SCAS_/S6T
459
+ melt_wf["ST"] = ST_
460
+ ms_conc = eq.melt_speciation(PT,melt_wf,species,models,nr_step,nr_tol)
461
+ ms_frac = melt_species_ratios(ms_conc,species)
462
+ melt_wf["H2OT"] = ms_conc["wm_H2O"]
463
+ melt_wf["CO2"] = ms_conc["wm_CO2"]
464
+ melt_wf["S2-"] = ms_conc["wm_S2m"]
465
+ else:
466
+ P_sat = guess0
467
+ melt_wf["Fe3FeT"] = mg.Fe3FeT_i(PT,melt_wf,species,models)
468
+ ms_conc = eq.melt_speciation(PT,melt_wf,species,models,nr_step,nr_tol)
469
+ ms_frac = melt_species_ratios(ms_conc,species)
470
+
471
+ return P_sat,ms_conc,ms_frac
472
+
473
+ # estimated fO2 from sulfur content given you are sulfide saturated and at Pvsat
474
+ def P_sat_sulf_anh(PT,melt_wf,species,models,Ptol,nr_step,nr_tol):
475
+ ST = melt_wf["ST"]
476
+ H2OT = melt_wf["H2OT"]
477
+ CO2 = melt_wf["CO2"]
478
+ HT = melt_wf["HT"]
479
+ CT = melt_wf["CT"]
480
+
481
+ def Pdiff(guess,melt_wf,species,models):
482
+ PT["P"] = guess
483
+ difference = abs(guess - mg.p_tot(PT,melt_wf,species,models))
484
+ return difference
485
+
486
+ def S62_2_Fe3T(PT,melt_wf,species,models,sat):
487
+ ST = melt_wf["ST"]
488
+ if sat == "sulf":
489
+ Ssat = mdv.SCSS(PT,melt_wf,species,models)/1000000.
490
+ S2m = Ssat
491
+ S6p = ST - S2m
492
+ elif sat == "anh":
493
+ Ssat = mdv.SCAS(PT,melt_wf,species,models)/1000000.
494
+ S6p = Ssat
495
+ S2m = ST - S6p
496
+ S62 = S6p/S2m
497
+ S6T = S6p/ST
498
+ if S62 < 0.:
499
+ return "not possible","","","",Ssat
500
+ else:
501
+ fO2 = mg.S6S2_2_fO2(S62,melt_wf,PT,species,models)
502
+ Fe3T = mdv.fO22Fe3FeT(fO2,PT,melt_wf,species,models)
503
+ DFMQ = mg.fO22Dbuffer(PT,fO2,"FMQ",models)
504
+ return Fe3T,fO2,S6T,DFMQ,Ssat
505
+
506
+ guess0 = 40000. # initial guess for pressure
507
+ PT["P"] = guess0
508
+
509
+ # assume it is sulfide saturated
510
+ melt_wf["Fe3FeT"] = 0.1
511
+ Fe3T_sulf,fO2_sulf,S6T_sulf,DFMQ_sulf,SCSS_ = S62_2_Fe3T(PT,melt_wf,species,models,"sulf")
512
+ if Fe3T_sulf == "not possible":
513
+ P_sat_sulf = ""
514
+ Fe3T_sulf = ""
515
+ sulfide_sat = "no"
516
+ else:
517
+ melt_wf["Fe3FeT"] = Fe3T_sulf
518
+ ms_conc = eq.melt_speciation(PT,melt_wf,species,models,nr_step,nr_tol)
519
+ ms_frac = melt_species_ratios(ms_conc,species)
520
+ melt_wf["H2OT"] = ms_conc["wm_H2O"]
521
+ melt_wf["CO2"] = ms_conc["wm_CO2"]
522
+ melt_wf["S2-"] = ms_conc["wm_S2m"]
523
+ melt_wf["ST"] = ST
524
+ delta1 = Pdiff(guess0,melt_wf,species,models)
525
+ while delta1 > Ptol :
526
+ delta1 = Pdiff(guess0,melt_wf,species,models)
527
+ guess0 = mg.p_tot(PT,melt_wf,species,models)
528
+ guess0 = float(guess0)
529
+ PT["P"] = guess0
530
+ Fe3T_sulf,fO2_sulf,S6T_sulf,DFMQ_sulf,SCSS_ = S62_2_Fe3T(PT,melt_wf,species,models,"sulf")
531
+ if Fe3T_sulf == "not possible":
532
+ P_sat_sulf = ""
533
+ Fe3T_sulf = ""
534
+ sulfide_sat = "no"
535
+ else:
536
+ melt_wf["Fe3FeT"] = Fe3T_sulf
537
+ ms_conc = eq.melt_speciation(PT,melt_wf,species,models,nr_step,nr_tol)
538
+ ms_frac = melt_species_ratios(ms_conc,species)
539
+ melt_wf["H2OT"] = ms_conc["wm_H2O"]
540
+ melt_wf["CO2"] = ms_conc["wm_CO2"]
541
+ melt_wf["S2-"] = ms_conc["wm_S2m"]
542
+ else:
543
+ P_sat_sulf = guess0
544
+ Fe3T_sulf,fO2_sulf,S6T_sulf,DFMQ_sulf,SCSS_ = S62_2_Fe3T(PT,melt_wf,species,models,"sulf")
545
+ sulfide_sat = "yes"
546
+
547
+ # assume it is anhydrite saturated
548
+ Fe3T_anh,fO2_anh,S6T_anh,DFMQ_anh,SCAS_ = S62_2_Fe3T(PT,melt_wf,species,models,"anh")
549
+ if Fe3T_anh == "not possible":
550
+ P_sat_anh = ""
551
+ Fe3T_anh = ""
552
+ anhydrite_sat = "no"
553
+ else:
554
+ melt_wf["Fe3FeT"] = Fe3T_anh
555
+ ms_conc = eq.melt_speciation(PT,melt_wf,species,models,nr_step,nr_tol)
556
+ ms_frac = melt_species_ratios(ms_conc,species)
557
+ melt_wf["H2OT"] = ms_conc["wm_H2O"]
558
+ melt_wf["CO2"] = ms_conc["wm_CO2"]
559
+ melt_wf["S2-"] = ms_conc["wm_S2m"]
560
+ melt_wf["ST"] = ST
561
+ delta1 = Pdiff(guess0,melt_wf,species,models)
562
+ while delta1 > Ptol :
563
+ delta1 = Pdiff(guess0,melt_wf,species,models)
564
+ guess0 = mg.p_tot(PT,melt_wf,species,models)
565
+ guess0 = float(guess0)
566
+ PT["P"] = guess0
567
+ Fe3T_anh,fO2_anh,S6T_anh,DFMQ_anh,SCAS_ = S62_2_Fe3T(PT,melt_wf,species,models,"anh")
568
+ if Fe3T_anh == "not possible":
569
+ P_sat_anh = ""
570
+ Fe3T_anh = ""
571
+ anhydrite_sat = "no"
572
+ else:
573
+ melt_wf["Fe3FeT"] = Fe3T_anh
574
+ ms_conc = eq.melt_speciation(PT,melt_wf,species,models,nr_step,nr_tol)
575
+ ms_frac = melt_species_ratios(ms_conc,species)
576
+ melt_wf["H2OT"] = ms_conc["wm_H2O"]
577
+ melt_wf["CO2"] = ms_conc["wm_CO2"]
578
+ melt_wf["S2-"] = ms_conc["wm_S2m"]
579
+ else:
580
+ P_sat_anh = guess0
581
+ Fe3T_anh,fO2_anh,S6T_anh,DFMQ_anh,SCAS_ = S62_2_Fe3T(PT,melt_wf,species,models,"anh")
582
+ anhydrite_sat = "yes"
583
+
584
+ result = {"P_sat_sulf":P_sat_sulf,"P_sat_anh":P_sat_anh,"SCAS":SCAS_*1000000.,"SCSS":SCSS_*1000000.,"sulf_sat":sulfide_sat,"DFMQ_sulf":DFMQ_sulf,"fO2_sulf":fO2_sulf,"Fe3T_sulf":Fe3T_sulf,"S6T_sulf":S6T_sulf,"anh_sat":anhydrite_sat,"DFMQ_anh":DFMQ_anh,"fO2_anh":fO2_anh,"Fe3T_anh":Fe3T_anh,"S6T_anh":S6T_anh}
585
+
586
+ return result
587
+
588
+ ##########################
589
+ ### graphite satuation ###
590
+ ##########################
591
+
592
+ # check graphite saturation
593
+ def graphite_saturation(PT,melt_wf,species,models): # needs finishing
594
+ K1 = mg.f_CO2(PT,melt_wf,species,models)/mdv.f_O2(PT,melt_wf,species,models)
595
+ K2 = mdv.KCOs(PT,models) # K for graphite saturation
596
+ if K1 < K2:
597
+ graphite_sat = "no"
598
+ else:
599
+ graphite_sat = "yes"
600
+ fCO2_ = K2*mdv.f_O2(PT,melt_wf,species,models)
601
+ xmCO2 = fCO2_*mdv.C_CO3(PT,melt_wf,species,models)
602
+ return graphite_sat
603
+
604
+
605
+ ######################################
606
+ ### fO2 range from sulfur content ###
607
+ ######################################
608
+
609
+ def fO2_range_from_S(PT,melt_wf,species,models):
610
+ SCSS_ = mdv.SCSS(PT,melt_wf,species,models)
611
+ SCAS_ = mdv.SCAS(PT,melt_wf,species,models)
612
+
613
+ if melt_wf["ST"]*1000000. > SCSS_:
614
+ sulfide_sat = "possible"
615
+ S6ST_1 = (melt_wf["ST"]*1000000. - SCSS_)/(melt_wf["ST"]*1000000.)
616
+ S6S2_1 = mg.overtotal2ratio(S6ST_1)
617
+ fO2_1 = mg.S6S2_2_fO2(S6S2_1,melt_wf,PT,species,models)
618
+ Fe3FeT_1 = mdv.fO22Fe3FeT(fO2_1,PT,melt_wf,species,models)
619
+ Fe3Fe2_1 = mg.overtotal2ratio(Fe3FeT_1)
620
+ DFMQ_1 = mg.fO22Dbuffer(PT,fO2_1,"FMQ",models)
621
+ else:
622
+ sulfide_sat = "no"
623
+ S6ST_1 = ""
624
+ S6S2_1 = ""
625
+ Fe3Fe2_1 = ""
626
+ Fe3FeT_1 = ""
627
+ fO2_1 = ""
628
+ DFMQ_1 = ""
629
+
630
+ if melt_wf["ST"]*1000000. > SCAS_:
631
+ anhydrite_sat = "possible"
632
+ S6ST_2 = SCAS_/(melt_wf["ST"]*1000000.)
633
+ S6S2_2 = mg.overtotal2ratio(S6ST_2)
634
+ fO2_2 = mg.S6S2_2_fO2(S6S2_2,melt_wf,PT,species,models)
635
+ Fe3FeT_2 = mdv.fO22Fe3FeT(fO2_2,PT,melt_wf,species,models)
636
+ Fe3Fe2_2 = mg.overtotal2ratio(Fe3FeT_2)
637
+ DFMQ_2 = mg.fO22Dbuffer(PT,fO2_2,"FMQ",models)
638
+ else:
639
+ anhydrite_sat = "no"
640
+ S6ST_2 = ""
641
+ S6S2_2 = ""
642
+ Fe3Fe2_2 = ""
643
+ Fe3FeT_2 = ""
644
+ fO2_2 = ""
645
+ DFMQ_2 = ""
646
+
647
+ result = {"SCAS":SCAS_, "SCSS":SCSS_, "sulf_sat":sulfide_sat, "DFMQ_sulf":DFMQ_1, "fO2_sulf":fO2_1, "Fe3FeT_sulf":Fe3FeT_1, "S6ST_sulf":S6ST_1, "anh_sat":anhydrite_sat, "DFMQ_anh":DFMQ_2, "fO2_anh":fO2_2, "Fe3FeT_anh":Fe3FeT_2, "S6ST_anh":S6ST_2}
648
+
649
+ return result
650
+
651
+
652
+ #################################
653
+ ### Mass, volume, and density ###
654
+ #################################
655
+
656
+ def mass_vol_rho(PT,melt_wf,gas_mf,bulk_wf,species,models):
657
+ gas_m = gas_mf['wt_g']*bulk_wf['Wt']
658
+ gas_v = mg.gas_volume(PT,gas_mf,bulk_wf,species,models)
659
+ gas_rho = mg.gas_density(PT,gas_mf,bulk_wf,species,models)
660
+ melt_m = (1.-gas_mf['wt_g'])*bulk_wf['Wt']
661
+ melt_v = mg.melt_volume(PT,melt_wf,bulk_wf,gas_mf,species)
662
+ melt_rho = mg.melt_density(PT,melt_wf,species)
663
+ tot_m = bulk_wf['Wt']
664
+ tot_v = gas_v + melt_v
665
+ tot_rho = mg.system_density(PT,melt_wf,gas_mf,bulk_wf,species,models)
666
+ result = {"tot_m":tot_m, "tot_v":tot_v, "tot_rho":tot_rho, "melt_m":melt_m, "melt_v":melt_v, "melt_rho":melt_rho, "gas_m":gas_m, "gas_v":gas_v, "gas_rho":gas_rho}
667
+ return result
668
+
669
+
670
+ ######################################################
671
+ ### mole fraction of elements in different species ###
672
+ ######################################################
673
+
674
+ def mf_S_species(melt_wf,gas_mf,species):
675
+ # weight of S in each sulfur-bearing species
676
+ W_S2m = melt_wf["ST"]*(1.-gas_mf["wt_g"])*(1.-melt_wf["S6ST"])
677
+ W_SO4 = melt_wf["ST"]*(1.-gas_mf["wt_g"])*melt_wf["S6ST"]
678
+ W_H2S = ((gas_mf["H2S"]*species.loc["S","M"])/(gas_mf["Xg_t"]))*gas_mf["wt_g"]
679
+ W_SO2 = ((gas_mf["SO2"]*species.loc["S","M"])/(gas_mf["Xg_t"]))*gas_mf["wt_g"]
680
+ W_S2 = ((gas_mf["S2"]*species.loc["S2","M"])/(gas_mf["Xg_t"]))*gas_mf["wt_g"]
681
+ W_OCS = ((gas_mf["OCS"]*species.loc["S","M"])/(gas_mf["Xg_t"]))*gas_mf["wt_g"]
682
+ W_total = W_S2m + W_SO4 + W_H2S + W_SO2 + W_S2 + W_OCS
683
+ # weight and mole fraction of S in each sulfur-bearing species compared to total S
684
+ w_S2m = W_S2m/W_total
685
+ w_SO4 = W_SO4/W_total
686
+ w_SO2 = W_SO2/W_total
687
+ w_H2S = W_H2S/W_total
688
+ w_S2 = W_S2/W_total
689
+ w_OCS = W_OCS/W_total
690
+ mf_S = {"S2-":w_S2m, "SO42-":w_SO4, "SO2":w_SO2, "H2S":w_H2S, "S2": w_S2, "OCS": w_OCS}
691
+ return mf_S
692
+
693
+ ##############################################
694
+ ### fO2 of silm+sulfm+anh at given T and P ###
695
+ ##############################################
696
+
697
+ def fO2_silm_sulf_anh(PT,melt_wf,species,models):
698
+ S6 = mdv.SCAS(PT,melt_wf,species)
699
+ S2 = mdv.SCSS(PT,melt_wf,species,models)
700
+ fO2 = ((S6*mdv.C_S(PT,melt_wf,species,models))/(S2*mdv.C_SO4(PT,melt_wf,species,models)))**0.5
701
+ DFMQ = mg.fO22Dbuffer(PT,fO2,"FMQ",models)
702
+ wmST = S6+S2
703
+ S6ST = S6/wmST
704
+ result = {"fO2":fO2, "DFMQ":DFMQ, "wmST":wmST, "S6ST":S6ST, "S6":S6, "S2":S2}
705
+ return result
706
+
707
+
708
+ ##############################################
709
+ ### S content at given T, P, fO2, C, and H ###
710
+ ##############################################
711
+
712
+ def S_given_T_P_fO2_C_H(PT,melt_wf,species,models,nr_step,nr_tol): # no dissolved H2S
713
+ P = PT["P"]
714
+
715
+ conc = eq.melt_speciation(PT,melt_wf,species,models,nr_step,nr_tol)
716
+
717
+ melt_wf["H2OT"] = conc["wm_H2O"]
718
+ melt_wf["CO2"] = conc["wm_CO2"]
719
+
720
+ xg_O2_ = mg.p_O2(PT,melt_wf,species,models)/P
721
+ xg_CO2_ = mg.p_CO2(PT,melt_wf,species,models)/P
722
+ xg_CO_ = mg.p_CO(PT,melt_wf,species,models)/P
723
+ xg_H2_ = mg.p_H2(PT,melt_wf,species,models)/P
724
+ xg_H2O_ = mg.p_H2O(PT,melt_wf,species,models)/P
725
+ xg_CH4_ = mg.p_CH4(PT,melt_wf,species,models)/P
726
+
727
+ K6_ = mdv.KOSg(PT,models)
728
+ K7_ = mdv.KHOSg(PT,models)
729
+ K8_ = mdv.C_S(PT,melt_wf,species,models)/1000000.0
730
+ K9_ = (mdv.C_SO4(PT,melt_wf,species,models)/1000000.0)
731
+ K10_ = mdv.KOCSg(PT,models)
732
+ y_S2_ = mdv.y_S2(PT,species,models)
733
+ y_SO2_ = mdv.y_SO2(PT,species,models)
734
+ y_H2S_ = mdv.y_H2S(PT,species,models)
735
+ y_O2_ = mdv.y_O2(PT,species,models)
736
+ y_H2O_ = mdv.y_H2O(PT,species,models)
737
+ y_CO2_ = mdv.y_CO2(PT,species,models)
738
+ y_CO_ = mdv.y_CO(PT,species,models)
739
+ y_OCS_ = mdv.y_OCS(PT,species,models)
740
+ M_S = species.loc['S','M']
741
+ M_SO3 = species.loc['SO3','M']
742
+
743
+ a = 1.
744
+ b = ((K6_*(y_S2_*P)**0.5*(xg_O2_*y_O2_))/y_SO2_) + ((K7_*xg_H2O_*y_H2O_*y_S2_**0.5)/((xg_O2_*y_O2_)**0.5*y_H2S_)) + ((K6_*(y_S2_*P)**0.5*xg_O2_*y_O2_*(xg_CO_*y_CO_)**3.*P)/(K10_*(xg_CO2_*y_CO2_)**2.*y_OCS_))
745
+ c = (xg_O2_ + xg_H2O_ + xg_H2_ + xg_CO_ + xg_CO2_ + xg_CH4_) - 1.
746
+ x = (-b + (b**2 - 4.*a*c)**0.5)/(2.*a)
747
+ xg_S2_ = x**2.
748
+ xg_SO2_ = (K6_*(xg_S2_*P*y_S2_)**0.5*(xg_O2_*P*y_O2_))/(y_SO2_*P)
749
+ wm_S_ = K8_*((y_S2_*xg_S2_)/(y_O2_*xg_O2_))**0.5
750
+ wm_S6p_ = (K9_*(y_S2_*xg_S2_*P)**0.5*(y_O2_*xg_O2_*P)**1.5)
751
+ wm_SO3_ = wm_S6p_*(M_SO3/M_S)
752
+ wm_ST_ = wm_S_ + wm_S6p_
753
+
754
+ conc["wm_ST"] = wm_ST_
755
+ conc["wm_S2m"] = wm_S_
756
+ conc["wm_S6p"] = wm_S6p_
757
+ conc["wm_SO3"] = wm_SO3_
758
+ conc["wm_H2S"] = 0.
759
+ frac = melt_species_ratios(conc,species)
760
+
761
+ return conc, frac
762
+
763
+
764
+ ###################################
765
+ ### concentration of insolubles ###
766
+ ###################################
767
+
768
+ def conc_insolubles(PT,melt_wf,species,models):
769
+ CO2 = melt_wf["CO2"] # weight fraction CO2
770
+ C_CO2_ = (species.loc["C","M"]*CO2)/species.loc["CO2","M"]
771
+ H2O = melt_wf["H2OT"] # weight fraction H2O
772
+ H_H2O = (2.*species.loc["H","M"]*H2O)/species.loc["H2O","M"]
773
+ H2 = (mg.C_H2(PT,melt_wf,species,models)*mg.f_H2(PT,melt_wf,species,models))/1000000. # weight fraction H2
774
+ H_H2 = (2.*species.loc["H","M"]*H2)/species.loc["H2","M"]
775
+ CH4 = (mg.C_CH4(PT,models)*mg.f_CH4(PT,melt_wf,species,models))/1000000. # weight fraction CH4
776
+ H_CH4 = (4.*species.loc["H","M"]*CH4)/species.loc["CH4","M"]
777
+ C_CH4_ = (species.loc["C","M"]*CH4)/species.loc["CH4","M"]
778
+ CO = (mg.C_CO(PT,models)*mg.f_CO(PT,melt_wf,species,models))/1000000. # weight fraction CO
779
+ C_CO_ = (species.loc["C","M"]*CO)/species.loc["CO","M"]
780
+ S2m = melt_wf["S2-"] # weight fraction of S2-
781
+ S6p = (mg.C_SO4(PT,melt_wf,species,models)*mdv.f_O2(PT,melt_wf,species,models)**2*S2m)/mg.C_S(PT,melt_wf,species,models) # weight fraction S6+
782
+ H2S = (mg.C_H2S(PT,melt_wf,species,models)*mg.f_H2S(PT,melt_wf,species,models))/1000000. # weight fraction H2S
783
+ S_H2S = (species.loc["S","M"]*H2S)/species.loc["H2S","M"]
784
+ H_H2S = (2.*species.loc["H","M"]*H2S)/species.loc["H2S","M"]
785
+ C_T = C_CO_ + C_CH4_ + C_CO2_
786
+ H_T = H_H2O + H_H2 + H_CH4 + H_H2S
787
+ S_T = S_H2S + S2m + S6p
788
+ H2O_HT = H_H2O/H_T
789
+ H2_HT = H_H2/H_T
790
+ CH4_HT = H_CH4/H_T
791
+ H2S_HT = H_H2S/H_T
792
+ CO2_CT = C_CO2_/C_T
793
+ CO_CT = C_CO_/C_T
794
+ CH4_CT = C_CH4_/C_T
795
+ S2m_ST = S2m/S_T
796
+ S6p_ST = S6p/S_T
797
+ H2S_ST = S_H2S/S_T
798
+
799
+ conc = {"H2":H2, "CH4":CH4, "CO":CO, "H2S":H2S, "S6p":S6p, "C_T":C_T, "H_T":H_T, "S_T":S_T}
800
+ frac = {"H2O_HT":H2O_HT, "H2_HT":H2_HT, "CH4_HT":CH4_HT, "H2S_HT":H2S_HT, "CO2_CT":CO2_CT, "CO_CT":CO_CT, "CH4_CT":CH4_CT, "S2m_ST":S2m_ST, "S6p_ST":S6p_ST, "H2S_ST":H2S_ST}
801
+
802
+ return conc, frac
803
+
804
+ ########################################
805
+ ### measured parameters within error ###
806
+ ########################################
807
+
808
+ def compositions_within_error(run,setup):
809
+ if setup.loc[run,"SiO2_sd_type"] == "A": # absolute
810
+ SiO2_sd = setup.loc[run,"SiO2_sd"]
811
+ else:
812
+ SiO2_sd = setup.loc[run,"SiO2_sd"]*setup.loc[run,"SiO2"]
813
+ SiO2 = float(np.random.normal(setup.loc[run,"SiO2"],SiO2_sd,1))
814
+
815
+ if setup.loc[run,"TiO2_sd_type"] == "A": # absolute
816
+ TiO2_sd = setup.loc[run,"TiO2_sd"]
817
+ else:
818
+ TiO2_sd = setup.loc[run,"TiO2_sd"]*setup.loc[run,"TiO2"]
819
+ TiO2 = float(np.random.normal(setup.loc[run,"TiO2"],TiO2_sd,1))
820
+
821
+ if setup.loc[run,"Al2O3_sd_type"] == "A": # absolute
822
+ Al2O3_sd = setup.loc[run,"Al2O3_sd"]
823
+ else:
824
+ Al2O3_sd = setup.loc[run,"Al2O3_sd"]*setup.loc[run,"Al2O3"]
825
+ Al2O3 = float(np.random.normal(setup.loc[run,"Al2O3"],Al2O3_sd,1))
826
+
827
+ if setup.loc[run,"FeOT_sd_type"] == "A": # absolute
828
+ FeOT_sd = setup.loc[run,"FeOT_sd"]
829
+ else:
830
+ FeOT_sd = setup.loc[run,"FeOT_sd"]*setup.loc[run,"FeOT"]
831
+ FeOT = float(np.random.normal(setup.loc[run,"FeOT"],FeOT_sd,1))
832
+
833
+ if setup.loc[run,"MnO_sd_type"] == "A": # absolute
834
+ MnO_sd = setup.loc[run,"MnO_sd"]
835
+ else:
836
+ MnO_sd = setup.loc[run,"MnO_sd"]*setup.loc[run,"MnO"]
837
+ MnO = float(np.random.normal(setup.loc[run,"MnO"],MnO_sd,1))
838
+
839
+ if setup.loc[run,"MgO_sd_type"] == "A": # absolute
840
+ MgO_sd = setup.loc[run,"MgO_sd"]
841
+ else:
842
+ MgO_sd = setup.loc[run,"MgO_sd"]*setup.loc[run,"MgO"]
843
+ MgO = float(np.random.normal(setup.loc[run,"MgO"],MgO_sd,1))
844
+
845
+ if setup.loc[run,"CaO_sd_type"] == "A": # absolute
846
+ CaO_sd = setup.loc[run,"CaO_sd"]
847
+ else:
848
+ CaO_sd = setup.loc[run,"CaO_sd"]*setup.loc[run,"CaO"]
849
+ CaO = float(np.random.normal(setup.loc[run,"CaO"],CaO_sd,1))
850
+
851
+ if setup.loc[run,"Na2O_sd_type"] == "A": # absolute
852
+ Na2O_sd = setup.loc[run,"Na2O_sd"]
853
+ else:
854
+ Na2O_sd = setup.loc[run,"Na2O_sd"]*setup.loc[run,"Na2O"]
855
+ Na2O = float(np.random.normal(setup.loc[run,"Na2O"],Na2O_sd,1))
856
+
857
+ if setup.loc[run,"K2O_sd_type"] == "A": # absolute
858
+ K2O_sd = setup.loc[run,"K2O_sd"]
859
+ else:
860
+ K2O_sd = setup.loc[run,"K2O_sd"]*setup.loc[run,"K2O"]
861
+ K2O = float(np.random.normal(setup.loc[run,"K2O"],K2O_sd,1))
862
+
863
+ if setup.loc[run,"P2O5_sd_type"] == "A": # absolute
864
+ P2O5_sd = setup.loc[run,"P2O5_sd"]
865
+ else:
866
+ P2O5_sd = setup.loc[run,"P2O5_sd"]*setup.loc[run,"P2O5"]
867
+ P2O5 = float(np.random.normal(setup.loc[run,"P2O5"],P2O5_sd,1))
868
+
869
+ if setup.loc[run,"H2O_sd_type"] == "A": # absolute
870
+ H2O_sd = setup.loc[run,"H2O_sd"]
871
+ else:
872
+ H2O_sd = setup.loc[run,"H2O_sd"]*setup.loc[run,"H2O"]
873
+ H2O = float(np.random.normal(setup.loc[run,"H2O"],H2O_sd,1))
874
+
875
+ if setup.loc[run,"CO2ppm_sd_type"] == "A": # absolute
876
+ CO2ppm_sd = setup.loc[run,"CO2ppm_sd"]
877
+ else:
878
+ CO2ppm_sd = setup.loc[run,"CO2ppm_sd"]*setup.loc[run,"CO2ppm"]
879
+ CO2ppm = float(np.random.normal(setup.loc[run,"CO2ppm"],CO2ppm_sd,1))
880
+
881
+ if setup.loc[run,"STppm_sd_type"] == "A": # absolute
882
+ STppm_sd = setup.loc[run,"STppm_sd"]
883
+ else:
884
+ STppm_sd = setup.loc[run,"STppm_sd"]*setup.loc[run,"STppm"]
885
+ STppm = float(np.random.normal(setup.loc[run,"STppm"],STppm_sd,1))
886
+
887
+ if setup.loc[run,"Fe3FeT_sd_type"] == "A": # absolute
888
+ Fe3FeT_sd = setup.loc[run,"Fe3FeT_sd"]
889
+ else:
890
+ Fe3FeT_sd = setup.loc[run,"Fe3FeT_sd"]*setup.loc[run,"Fe3FeT"]
891
+ Fe3FeT = float(np.random.normal(setup.loc[run,"Fe3FeT"],Fe3FeT_sd,1))
892
+
893
+ result = {"SiO2":SiO2, "TiO2":TiO2, "Al2O3":Al2O3, "FeOT":FeOT, "MnO":MnO, "MgO":MgO, "CaO":CaO, "Na2O":Na2O, "K2O":K2O, "P2O5":P2O5, "H2O":H2O, "CO2ppm":CO2ppm, "STppm":STppm, "Fe3FeT":Fe3FeT}
894
+ return result
895
+
896
+
897
+ def calc_isobar_CO2H2O(PT,melt_wf,species,models):
898
+ M_H2O = species.loc['H2O','M']
899
+ M_CO2 = species.loc['CO2','M']
900
+ M_m_ = mg.M_m_SO(melt_wf,species)
901
+
902
+ xm_CO2_ = PT["P"]*mdv.y_CO2(PT,species,models)*mdv.C_CO3(PT,melt_wf,species,models) # pure CO2
903
+ Xm_t = xm_CO2_*M_CO2 + (1.-xm_CO2_)*M_m_
904
+ wm_CO2_0 = (xm_CO2_*M_CO2)/Xm_t
905
+
906
+ if models.loc["Hspeciation","option"] == "none": # fH2O = xmH2OT^2/CH2O
907
+ xm_H2O_ = (PT["P"]*mdv.y_H2O(PT,species,models)*mdv.C_H2O(PT,melt_wf,species,models))**0.5 # pure H2O
908
+ else: # regular or ideal: fH2O = xmH2Omol/CH2O
909
+ print("need to sort")
910
+ Xm_t = xm_H2O_*M_H2O + (1.-xm_H2O_)*M_m_
911
+ wm_H2O_0 = (xm_H2O_*M_H2O)/Xm_t
912
+ xm_H2O_step = xm_H2O_/20.
913
+
914
+ results = pd.DataFrame([[PT["P"],0.,wm_CO2_0*1000000.]])
915
+
916
+ for m in range(1,20,1):
917
+ xm_H2O_ = xm_H2O_step*m
918
+ Xm_t = xm_H2O_*M_H2O + (1.-xm_H2O_)*M_m_
919
+ wm_H2O_ = (xm_H2O_*M_H2O)/Xm_t
920
+ melt_wf={"H2OT":wm_H2O_}
921
+ melt_wf["CO2"] = 0.
922
+ pH2O = mg.p_H2O(PT,melt_wf,species,models)
923
+ pCO2 = PT["P"] - pH2O
924
+ xm_CO2_ = pCO2*mdv.y_CO2(PT,species,models)*mdv.C_CO3(PT,melt_wf,species,models)
925
+ Xm_t = xm_CO2_*M_CO2 + xm_H2O_*M_H2O + (1.0-xm_CO2_-xm_H2O_)*M_m_
926
+ wf_CO2 = (xm_CO2_*M_CO2)/Xm_t
927
+ results1 = pd.DataFrame([[PT["P"],melt_wf["H2OT"]*100.,wf_CO2*1000000.]])
928
+ results = results.append(results1, ignore_index=True)
929
+
930
+ results1 = pd.DataFrame([[PT["P"],wm_H2O_0*100.,0.]])
931
+ results = results.append(results1, ignore_index=True)
932
+ return results
933
+
934
+ def calc_pure_solubility(PT,melt_wf,species,models):
935
+
936
+ M_H2O = species.loc['H2O','M']
937
+ M_CO2 = species.loc['CO2','M']
938
+ M_m_ = mg.M_m_SO(melt_wf,species)
939
+
940
+ xm_CO2_ = PT["P"]*mdv.y_CO2(PT,species,models)*mdv.C_CO3(PT,melt_wf,species,models) # pure CO2
941
+ Xm_t = xm_CO2_*M_CO2 + (1.-xm_CO2_)*M_m_
942
+ wm_CO2 = (xm_CO2_*M_CO2)/Xm_t
943
+
944
+ xm_H2O_ = (PT["P"]*mdv.y_H2O(PT,species,models)*mdv.C_H2O(PT,melt_wf,species,models))**0.5 # pure H2O
945
+ Xm_t = xm_H2O_*M_H2O + (1.-xm_H2O_)*M_m_
946
+ wm_H2O = (xm_H2O_*M_H2O)/Xm_t
947
+
948
+ results = pd.DataFrame([[PT["P"],wm_H2O*100.,wm_CO2*1000000.]])
949
+
950
+ return results
951
+
952
+ ###########################################################################
953
+ ### P given S content of melt after degassing given conditions of pvsat ### IN PROGRESS
954
+ ###########################################################################