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.
@@ -0,0 +1,2033 @@
1
+ # batch_calculations.py
2
+
3
+ import pandas as pd
4
+ from datetime import date
5
+ import gmpy2 as gp
6
+ import numpy as np
7
+ import datetime
8
+ import math as math
9
+
10
+ import VolFe.melt_gas as mg
11
+ import VolFe.equilibrium_equations as eq
12
+ import VolFe.isotopes as iso
13
+
14
+ import VolFe.model_dependent_variables as mdv
15
+ import VolFe.calculations as c
16
+
17
+
18
+
19
+ # building results tables
20
+ # outputing sample name
21
+ def results_table_sample_name(setup,run):
22
+ results_headers = pd.DataFrame([["sample"]])
23
+ results_values = pd.DataFrame([[setup.loc[run,"Sample"]]])
24
+ return results_headers, results_values
25
+ # outputting melt composition, T, P
26
+ def results_table_melt_comp_etc(PT,melt_comp,conc,frac,melt_wf):
27
+ results_headers = pd.DataFrame([["T_C","P_bar",
28
+ "SiO2_wtpc", "TiO2_wtpc", "Al2O3_wtpc", "FeOT_wtpc", "MnO_wtpc", "MgO_wtpc", "CaO_wtpc", "Na2O_wtpc", "K2O_wtpc", "P2O5_wtpc",
29
+ "H2OT_wtpc","OH_wtpc","H2Omol_wtpc","H2_ppmw","CH4_ppmw","CO2T_ppmw","CO2mol_ppmw","CO32-_ppmw","CO_ppmw","S2-_ppmw","S6+_ppmw","H2S_ppmw",
30
+ "H_H2OT/HT", "H_H2/HT", "H_CH4/HT", "H_H2S/HT", "C_CO2T/CT", "C_CO/CT", "C_CH4/CT", "S2-/ST", "S6+/ST", "H2S/ST", "Fe3+/FeT"]])
31
+ results_values = pd.DataFrame([[PT["T"],PT["P"],
32
+ melt_comp["SiO2"]*100., melt_comp["TiO2"]*100., melt_comp["Al2O3"]*100., melt_comp["FeOT"]*100., melt_comp["MnO"]*100., melt_comp["MgO"]*100., melt_comp["CaO"]*100., melt_comp["Na2O"]*100., melt_comp["K2O"]*100., melt_comp["P2O5"]*100.,
33
+ conc["wm_H2O"]*100.,conc["wm_OH"]*100,conc["wm_H2Omol"]*100.,conc["wm_H2"]*1000000.,conc["wm_CH4"]*1000000.,conc["wm_CO2"]*1000000.,conc["wm_CO2mol"]*1000000,conc["wm_CO2carb"]*1000000,conc["wm_CO"]*1000000.,conc["wm_S2m"]*1000000.,conc["wm_S6p"]*1000000.,conc["wm_H2S"]*1000000.,
34
+ frac["H2O_HT"], frac["H2_HT"], frac["CH4_HT"], frac["H2S_HT"], frac["CO2_CT"], frac["CO_CT"], frac["CH4_CT"], frac["S2m_ST"], frac["S6p_ST"], frac["H2S_ST"],melt_wf["Fe3FeT"]]])
35
+ return results_headers, results_values
36
+ def results_table_melt_vol():
37
+ results_headers = pd.DataFrame([["H2OT-eq_wtpc","CO2T-eq_ppmw","ST_ppmw","X_ppmw"]])
38
+ return results_headers
39
+ # outputting model options used in the calculation
40
+ def results_table_model_options(models):
41
+ results_headers = pd.DataFrame([["setup opt","insoluble opt","H2S_m opt","species X opt","Hspeciation opt",
42
+ "fO2 opt","NNObuffer opt","FMQbuffer opt",
43
+ "carbon dioxide opt","water opt","hydrogen opt","sulfide opt","sulfate opt","hydrogen sulfide opt","methane opt","carbon monoxide opt","species X solubility opt","Cspeccomp opt","Hspeccomp opt",
44
+ "SCSS opt","SCAS opt","sulfur_saturation opt","sulfur_is_sat opt","graphite_saturation opt","ideal_gas opt",
45
+ "y_CO2 opt","y_SO2 opt","y_H2S opt","y_H2 opt","y_O2 opt","y_S2 opt","y_CO opt","y_CH4 opt","y_H2O opt","y_OCS opt","y_X opt",
46
+ "KHOg opt","KHOSg opt","KOSg opt","KOSg2 opt","KCOg opt","KCOHg opt","KOCSg opt","KCOs opt","carbonylsulfide opt",
47
+ "density opt","Date"]])
48
+ results_values = pd.DataFrame([[models.loc["setup","option"],models.loc["insolubles","option"], models.loc["H2S_m","option"], models.loc["species X","option"],models.loc["Hspeciation","option"],
49
+ models.loc["fO2","option"], models.loc["NNObuffer","option"], models.loc["FMQbuffer","option"],
50
+ models.loc["carbon dioxide","option"], models.loc["water","option"], models.loc["hydrogen","option"], models.loc["sulfide","option"], models.loc["sulfate","option"], models.loc["hydrogen sulfide","option"], models.loc["methane","option"], models.loc["carbon monoxide","option"], models.loc["species X solubility","option"], models.loc["Cspeccomp","option"], models.loc["Hspeccomp","option"],
51
+ models.loc["SCSS","option"], models.loc["SCAS","option"], models.loc["sulfur_saturation","option"], models.loc["sulfur_is_sat","option"], models.loc["graphite_saturation","option"], models.loc["ideal_gas","option"],
52
+ models.loc["y_CO2","option"], models.loc["y_SO2","option"], models.loc["y_H2S","option"], models.loc["y_H2","option"], models.loc["y_O2","option"], models.loc["y_S2","option"], models.loc["y_CO","option"], models.loc["y_CH4","option"], models.loc["y_H2O","option"],models.loc["y_OCS","option"], models.loc["y_X","option"],
53
+ models.loc["KHOg","option"], models.loc["KHOSg","option"], models.loc["KOSg","option"], models.loc["KOSg2","option"], models.loc["KCOg","option"], models.loc["KCOHg","option"],models.loc["KOCSg","option"], models.loc["KCOs","option"],models.loc["carbonylsulfide","option"],
54
+ models.loc["density","option"],datetime.datetime.now()]])
55
+ return results_headers, results_values
56
+ # outputting fugacities, partial pressures, gas mole fraction, fugacity coefficients, molecular masses, solubility constants, equilibrium constants, melt density
57
+ def results_table_f_p_xg_y_M_C_K_d(PT,melt_wf,species,models):
58
+ results_headers = pd.DataFrame([["fO2_DNNO","fO2_DFMQ",
59
+ "fO2_bar","fH2_bar","fH2O_bar","fS2_bar","fSO2_bar","fH2S_bar","fCO2_bar","fCO_bar","fCH4_bar","fOCS_bar","fX_bar",
60
+ "pO2_bar","pH2_bar","pH2O_bar","pS2_bar","pSO2_bar","pH2S_bar","pCO2_bar","pCO_bar","pCH4_bar","pOCS_bar","pX_bar",
61
+ "xgO2_mf","xgH2_mf","xgH2O_mf","xgS2_mf","xgSO2_mf","xgH2S_mf","xgCO2_mf","xgCO_mf","xgCH4_mf","xgOCS_mf","xgX_mf","xgC_S_mf",
62
+ "yO2","yH2","yH2O","yS2","ySO2","yH2S","yCO2","yCO","yCH4","yOCS","yX",
63
+ "M_m_SO","M_m_ox",
64
+ "C_H2O_mf_bar","C_H2_ppm_bar","C_CO2T_mf_bar","C_CO_ppm_bar","C_CH4_ppm_bar","C_S_ppm","C_SO4_ppm_bar","C_H2S_ppm_bar","C_X_ppm_bar",
65
+ "KHOg","KHOSg","KCOg","KCOHg","KOCSg","KSOg","KSOg2","KHOm","KCOm","KCOs",
66
+ "density_gcm3"]])
67
+ results_values = pd.DataFrame([[mg.fO22Dbuffer(PT,mdv.f_O2(PT,melt_wf,species,models),"NNO",models),mg.fO22Dbuffer(PT,mdv.f_O2(PT,melt_wf,species,models),"FMQ",models),
68
+ mdv.f_O2(PT,melt_wf,species,models),mg.f_H2(PT,melt_wf,species,models),mg.f_H2O(PT,melt_wf,species,models),mg.f_S2(PT,melt_wf,species,models),mg.f_SO2(PT,melt_wf,species,models),mg.f_H2S(PT,melt_wf,species,models),mg.f_CO2(PT,melt_wf,species,models),mg.f_CO(PT,melt_wf,species,models),mg.f_CH4(PT,melt_wf,species,models),mg.f_OCS(PT,melt_wf,species,models),mg.f_X(PT,melt_wf,species,models),
69
+ mg.p_O2(PT,melt_wf,species,models),mg.p_H2(PT,melt_wf,species,models),mg.p_H2O(PT,melt_wf,species,models),mg.p_S2(PT,melt_wf,species,models),mg.p_SO2(PT,melt_wf,species,models),mg.p_H2S(PT,melt_wf,species,models),mg.p_CO2(PT,melt_wf,species,models),mg.p_CO(PT,melt_wf,species,models),mg.p_CH4(PT,melt_wf,species,models),mg.p_OCS(PT,melt_wf,species,models),mg.p_X(PT,melt_wf,species,models),
70
+ mg.xg_O2(PT,melt_wf,species,models),mg.xg_H2(PT,melt_wf,species,models),mg.xg_H2O(PT,melt_wf,species,models),mg.xg_S2(PT,melt_wf,species,models),mg.xg_SO2(PT,melt_wf,species,models),mg.xg_H2S(PT,melt_wf,species,models),mg.xg_CO2(PT,melt_wf,species,models),mg.xg_CO(PT,melt_wf,species,models),mg.xg_CH4(PT,melt_wf,species,models),mg.xg_OCS(PT,melt_wf,species,models),mg.xg_X(PT,melt_wf,species,models),mg.gas_CS(PT,melt_wf,species,models),
71
+ mdv.y_O2(PT,species,models),mdv.y_H2(PT,species,models),mdv.y_H2O(PT,species,models),mdv.y_S2(PT,species,models),mdv.y_SO2(PT,species,models),mdv.y_H2S(PT,species,models),mdv.y_CO2(PT,species,models),mdv.y_CO(PT,species,models),mdv.y_CH4(PT,species,models),mdv.y_OCS(PT,species,models),mdv.y_X(PT,species,models),
72
+ mg.M_m_SO(melt_wf,species),mg.M_m_ox(melt_wf,species,models),
73
+ mdv.C_H2O(PT,melt_wf,species,models),mdv.C_H2(PT,melt_wf,species,models),mdv.C_CO3(PT,melt_wf,species,models),mdv.C_CO(PT,melt_wf,species,models),mdv.C_CH4(PT,melt_wf,species,models),mdv.C_S(PT,melt_wf,species,models),mdv.C_SO4(PT,melt_wf,species,models),mdv.C_H2S(PT,melt_wf,species,models),mdv.C_X(PT,melt_wf,species,models),
74
+ mdv.KHOg(PT,models),mdv.KHOSg(PT,models),mdv.KCOg(PT,models),mdv.KCOHg(PT,models),mdv.KOCSg(PT,models),mdv.KOSg(PT,models),mdv.KOSg2(PT,models),mdv.KHOm(PT,melt_wf,species,models),mdv.KCOm(PT,melt_wf,species,models),mdv.KCOs(PT,models),
75
+ mdv.melt_density(PT,melt_wf,species,models)]])
76
+ return results_headers, results_values
77
+ # headers for open system degassing all gas
78
+ def results_table_open_all_gas():
79
+ results_headers = pd.DataFrame([["xgO2_all_mf","xgH2_all_mf","xgH2O_all_mf","xgS2_all_mf","xgSO2_all_mf","xgH2S_all_mf","xgCO2_all_mf","xgCO_all_mf","xgCH4_all_mf","xgOCS_all_mf","xgX_all_mf","xgC_S_all_mf"]])
80
+ return results_headers
81
+ # saturation conditions
82
+ def results_table_sat(sulf_sat_result,PT,melt_wf,species,models):
83
+ results_headers = pd.DataFrame([["SCSS_ppm","sulfide saturated","SCAS_ppm","anhydrite saturated","ST melt if sat","graphite saturated"]])
84
+ results_values = pd.DataFrame([[sulf_sat_result["SCSS"],sulf_sat_result["sulfide_sat"],sulf_sat_result["SCAS"],sulf_sat_result["sulfate_sat"],sulf_sat_result["ST"],c.graphite_saturation(PT,melt_wf,species,models)]])
85
+ return results_headers, results_values
86
+
87
+ def options_from_setup(run,models,setup):
88
+ """
89
+ Allows model options to be read from the setup file rather than models file.
90
+
91
+
92
+ Parameters
93
+ ----------
94
+ run: float
95
+ Integer of the row in the setup file to read from (note the first row under the headers is row 0).
96
+ setup: pandas.DataFrame
97
+ Dataframe with melt compositions to be used, require header using the same labels as row labels from models file if you want to use that option.
98
+ models: pandas.DataFrame
99
+ Dataframe of models.csv file.
100
+
101
+ Returns
102
+ -------
103
+ results: pandas.DataFrame
104
+
105
+ """
106
+ if models.loc["setup","option"] == "no":
107
+ return models
108
+ elif models.loc["setup","option"] == "yes":
109
+ models = pd.read_csv("models.csv", index_col = [0])
110
+ # species
111
+ if models.loc["insolubles","option"] == "setup":
112
+ models.loc["insolubles","option"] = setup.loc[run,"insolubles"]
113
+ if models.loc["H2S_m","option"] == "setup":
114
+ models.loc["H2S_m","option"] = setup.loc[run,"H2S_m"]
115
+ if models.loc["species X","option"] == "setup":
116
+ models.loc["species X","option"] = setup.loc[run,"species X"]
117
+ if models.loc["Hspeciation","option"] == "setup":
118
+ models.loc["Hspeciation","option"] = setup.loc[run,"Hspeciation"]
119
+ # oxygen fugacity
120
+ if models.loc["fO2","option"] == "setup":
121
+ models.loc["fO2","option"] = setup.loc[run,"fO2"]
122
+ if models.loc["NNObuffer","option"] == "setup":
123
+ models.loc["NNObuffer","option"] = setup.loc[run,"NNObuffer"]
124
+ if models.loc["FMQbuffer","option"] == "setup":
125
+ models.loc["FMQbuffer","option"] = setup.loc[run,"FMQbuffer"]
126
+ # solubility constants
127
+ if models.loc["carbon dioxide","option"] == "setup":
128
+ models.loc["carbon dioxide","option"] = setup.loc[run,"carbon dioxide"]
129
+ if models.loc["water","option"] == "setup":
130
+ models.loc["water","option"] = setup.loc[run,"water"]
131
+ if models.loc["hydrogen","option"] == "setup":
132
+ models.loc["hydrogen","option"] = setup.loc[run,"hydrogen"]
133
+ if models.loc["sulfide","option"] == "setup":
134
+ models.loc["sulfide","option"] = setup.loc[run,"sulfide"]
135
+ if models.loc["sulfate","option"] == "setup":
136
+ models.loc["sulfate","option"] = setup.loc[run,"sulfate"]
137
+ if models.loc["hydrogen sulfide","option"] == "setup":
138
+ models.loc["hydrogen sulfide","option"] = setup.loc[run,"hydrogen sulfide"]
139
+ if models.loc["methane","option"] == "setup":
140
+ models.loc["methane","option"] = setup.loc[run,"methane"]
141
+ if models.loc["carbon monoxide","option"] == "setup":
142
+ models.loc["carbon monoxide","option"] = setup.loc[run,"carbon monoxide"]
143
+ if models.loc["species X solubility","option"] == "setup":
144
+ models.loc["species X solubility","option"] = setup.loc[run,"species X solubility"]
145
+ if models.loc["Cspeccomp","option"] == "setup":
146
+ models.loc["Cspeccomp","option"] = setup.loc[run,"Cspeccomp"]
147
+ if models.loc["Hspeccomp","option"] == "setup":
148
+ models.loc["Hspeccomp","option"] = setup.loc[run,"Hspeccomp"]
149
+ # saturation conditions
150
+ if models.loc["SCSS","option"] == "setup":
151
+ models.loc["SCSS","option"] = setup.loc[run,"SCSS"]
152
+ if models.loc["SCAS","option"] == "setup":
153
+ models.loc["SCAS","option"] = setup.loc[run,"SCAS"]
154
+ if models.loc["sulfur_saturation","option"] == "setup":
155
+ models.loc["sulfur_saturation","option"] = setup.loc[run,"sulfur_saturation"]
156
+ if models.loc["sulfur_is_sat","option"] == "setup":
157
+ models.loc["sulfur_is_sat","option"] = setup.loc[run,"sulfur_is_sat"]
158
+ if models.loc["graphite_saturation","option"] == "setup":
159
+ models.loc["graphite_saturation","option"] = setup.loc[run,"graphite_saturation"]
160
+ # fugacity coefficients
161
+ if models.loc["ideal_gas","option"] == "setup":
162
+ models.loc["ideal_gas","option"] = setup.loc[run,"ideal_gas"]
163
+ if models.loc["y_CO2","option"] == "setup":
164
+ models.loc["y_CO2","option"] = setup.loc[run,"y_CO2","option"]
165
+ if models.loc["y_SO2","option"] == "setup":
166
+ models.loc["y_SO2","option"] = setup.loc[run,"y_SO2","option"]
167
+ if models.loc["y_H2S","option"] == "setup":
168
+ models.loc["y_H2S","option"] = setup.loc[run,"y_H2S","option"]
169
+ if models.loc["y_H2","option"] == "setup":
170
+ models.loc["y_H2","option"] = setup.loc[run,"y_H2","option"]
171
+ if models.loc["y_O2","option"] == "setup":
172
+ models.loc["y_O2","option"] = setup.loc[run,"y_O2","option"]
173
+ if models.loc["y_S2","option"] == "setup":
174
+ models.loc["y_S2","option"] = setup.loc[run,"y_S2","option"]
175
+ if models.loc["y_CO","option"] == "setup":
176
+ models.loc["y_CO","option"] = setup.loc[run,"y_CO","option"]
177
+ if models.loc["y_CH4","option"] == "setup":
178
+ models.loc["y_CH4","option"] = setup.loc[run,"y_CH4","option"]
179
+ if models.loc["y_H2O","option"] == "setup":
180
+ models.loc["y_H2O","option"] = setup.loc[run,"y_H2O","option"]
181
+ if models.loc["y_OCS","option"] == "setup":
182
+ models.loc["y_OCS","option"] = setup.loc[run,"y_OCS","option"]
183
+ if models.loc["y_X","option"] == "setup":
184
+ models.loc["y_X","option"] = setup.loc[run,"y_X","option"]
185
+ # equilibrium constants
186
+ if models.loc["KHOg","option"] == "setup":
187
+ models.loc["KHOg","option"] = setup.loc[run,"KHOg","option"]
188
+ if models.loc["KHOSg","option"] == "setup":
189
+ models.loc["KHOSg","option"] = setup.loc[run,"KHOSg","option"]
190
+ if models.loc["KOSg","option"] == "setup":
191
+ models.loc["KOSg","option"], = setup.loc[run,"KOSg","option"]
192
+ if models.loc["KOSg2","option"] == "setup":
193
+ models.loc["KOSg2","option"] = setup.loc[run,"KOSg2","option"]
194
+ if models.loc["KCOg","option"] == "setup":
195
+ models.loc["KCOg","option"] = setup.loc[run,"KCOg","option"]
196
+ if models.loc["KCOHg","option"] == "setup":
197
+ models.loc["KCOHg","option"] = setup.loc[run,"KCOHg","option"]
198
+ if models.loc["KOCSg","option"] == "setup":
199
+ models.loc["KOCSg","option"] = setup.loc[run,"KOCSg","option"]
200
+ if models.loc["KCOs","option"] == "setup":
201
+ models.loc["KCOs","option"] = setup.loc[run,"KCOs","option"]
202
+ if models.loc["carbonylsulfide","option"] == "setup":
203
+ models.loc["carbonylsulfide","option"] = setup.loc[run,"carbonylsulfide","option"]
204
+ # other
205
+ if models.loc["density","option"] == "setup":
206
+ models.loc["density","option"] = setup.loc[run,"density","option"]
207
+ return models
208
+
209
+
210
+ # calculate the saturation pressure for multiple melt compositions in setup file
211
+ def P_sat_output(first_row,last_row,p_tol,nr_step,nr_tol,setup,species,models):
212
+
213
+ """
214
+ Calculates the pressure of vapor saturation for multiple melt compositions given volatile-free melt composition, volatile content, temperature, and an fO2 estimate.
215
+
216
+
217
+ Parameters
218
+ ----------
219
+ first_row: float
220
+ Integer of the first row in the setup file to run (note the first row under the headers is row 0).
221
+ last_row: float
222
+ Integer of the last row in the setup file to run (note the first row under the headers is row 0).
223
+ p_tol: float
224
+ Required tolerance for convergence of Pvsat in bars (0.1 bars is normally used).
225
+ nr_step: float
226
+ Step size for Newton-Raphson solver for melt speciation (typically 1 is fine, but this can be made smaller if there are problems with convergence.).
227
+ nr_tol: float
228
+ Tolerance for the Newton-Raphson solver for melt speciation in weight fraction (typically 1e-9 is sufficient but this can be made larger if there are problems with convergence).
229
+ setup: pandas.DataFrame
230
+ Dataframe with melt compositions to be used, requires following headers):
231
+ Sample, T_C,
232
+ DNNO or DFMQ or logfO2 or (Fe2O3 and FeO) or Fe3FeT or S6ST
233
+ SiO2, TiO2, Al2O3, (Fe2O3T or FeOT unless Fe2O3 and FeO given), MnO, MgO, CaO, Na2O, K2O, P2O5,
234
+ H2O and/or CO2ppm and/or STppm and/or Xppm
235
+ Note: concentrations (unless otherwise stated) are in wt%
236
+ species: pandas.DataFrame
237
+ Dataframe of species.csv file.
238
+ models: pandas.DataFrame
239
+ Dataframe of models.csv file.
240
+
241
+ Returns
242
+ -------
243
+ results: pandas.DataFrame
244
+
245
+ Outputs
246
+ -------
247
+ results_saturation_pressures: csv file (if output csv = yes in models)
248
+
249
+ """
250
+
251
+ for n in range(first_row,last_row,1): # n is number of rows of data in conditions file
252
+ run = n
253
+ PT={"T":setup.loc[run,"T_C"]}
254
+ melt_wf=mg.melt_comp(run,setup)
255
+ melt_wf['CO2'] = setup.loc[run,"CO2ppm"]/1000000.
256
+ melt_wf["H2OT"] = setup.loc[run,"H2O"]/100.
257
+
258
+ # check if any options need to be read from the setup file rather than the models file
259
+ models = options_from_setup(run,models,setup)
260
+
261
+ # calculate Pvsat assuming only H2O CO2 in vapour and melt
262
+ if setup.loc[run,"Fe3FeT"] > 0.:
263
+ melt_wf['Fe3FeT'] = setup.loc[run,"Fe3FeT"]
264
+ else:
265
+ melt_wf['Fe3FeT'] = 0.
266
+ P_sat_H2O_CO2_only, P_sat_H2O_CO2_result = c.P_sat_H2O_CO2(PT,melt_wf,species,models,p_tol,nr_step,nr_tol)
267
+
268
+ if models.loc["calc_sat","option"] == "fO2_fX":
269
+ P_sat_fO2_fS2_result = c.P_sat_fO2_fS2(PT,melt_wf,species,models,p_tol)
270
+ PT["P"] = P_sat_fO2_fS2_result["P_tot"]
271
+ else:
272
+ wm_ST = setup.loc[run,"STppm"]/1000000.
273
+ melt_wf['ST'] = wm_ST
274
+ melt_wf['CT'] = (melt_wf['CO2']/species.loc['CO2','M'])*species.loc['C','M']
275
+ melt_wf['HT'] = (melt_wf['H2OT']/species.loc['H2O','M'])*(2.*species.loc['H','M'])
276
+ wm_X = setup.loc[run,"Xppm"]/1000000.
277
+ melt_wf['XT'] = wm_X
278
+ if setup.loc[run,"S6ST"] > 0.:
279
+ melt_wf["S6ST"] = setup.loc[run,"S6ST"]
280
+ if models.loc["bulk_composition","option"] == "yes":
281
+ bulk_wf = {"H":(2.*species.loc["H","M"]*melt_wf["H2OT"])/species.loc["H2O","M"],"C":(species.loc["C","M"]*melt_wf["CO2"])/species.loc["CO2","M"],"S":wm_ST, "X":wm_X}
282
+ else:
283
+ raise TypeError('This is not currently possible')
284
+ if models.loc["sulfur_is_sat","option"] == "yes":
285
+ if melt_wf["XT"] > 0.:
286
+ raise TypeError('This is not currently possible')
287
+ P_sat_, conc, frac = c.fO2_P_VSA(PT,melt_wf,species,models,nr_step,nr_tol,p_tol)
288
+ elif models.loc["sulfur_saturation","option"] == "no":
289
+ P_sat_, conc, frac = c.P_sat(PT,melt_wf,species,models,p_tol,nr_step,nr_tol)
290
+ elif models.loc["sulfur_saturation","option"] == "yes":
291
+ if melt_wf["XT"] > 0.:
292
+ raise TypeError('This is not currently possible')
293
+ P_sat_, conc, frac = c.P_VSA(PT,melt_wf,species,models,nr_step,nr_tol,p_tol)
294
+ PT["P"] = P_sat_
295
+ melt_wf["H2OT"] = conc["wm_H2O"]
296
+ melt_wf["CO2"] = conc["wm_CO2"]
297
+ melt_wf["S2-"] = conc["wm_S2m"]
298
+ if models.loc["sulfur_is_sat","option"] == "yes":
299
+ melt_wf["Fe3FeT"] = frac["Fe3FeT"]
300
+ else:
301
+ melt_wf["Fe3FeT"] = mg.Fe3FeT_i(PT,melt_wf,species,models)
302
+
303
+ sulf_sat_result = c.sulfur_saturation(PT,melt_wf,species,models)
304
+ # gas_mf = {"O2":mg.xg_O2(PT,melt_wf,species,models),"CO":mg.xg_CO(PT,melt_wf,species,models),"CO2":mg.xg_CO2(PT,melt_wf,species,models),"H2":mg.xg_H2(PT,melt_wf,species,models),"H2O":mg.xg_H2O(PT,melt_wf,species,models),"CH4":mg.xg_CH4(PT,melt_wf,species,models),"S2":mg.xg_S2(PT,melt_wf,species,models),"SO2":mg.xg_SO2(PT,melt_wf,species,models),"H2S":mg.xg_H2S(PT,melt_wf,species,models),"OCS":mg.xg_OCS(PT,melt_wf,species,models),"X":mg.xg_X(PT,melt_wf,species,models),"Xg_t":mg.Xg_tot(PT,melt_wf,species,models),"wt_g":0.}
305
+ melt_comp = mg.melt_normalise_wf(melt_wf,species,"yes","no")
306
+
307
+ # create results
308
+ results_headers_table_sample_name, results_values_table_sample_name = results_table_sample_name(setup,run)
309
+ results_headers_table_melt_comp_etc, results_values_table_melt_comp_etc = results_table_melt_comp_etc(PT,melt_comp,conc,frac,melt_wf)
310
+ results_headers_table_model_options, results_values_table_model_options = results_table_model_options(models)
311
+ results_headers_table_f_p_xg_y_M_C_K_d, results_values_table_f_p_xg_y_M_C_K_d = results_table_f_p_xg_y_M_C_K_d(PT,melt_wf,species,models)
312
+ results_headers_table_sat, results_values_table_sat = results_table_sat(sulf_sat_result,PT,melt_wf,species,models)
313
+ results_headers_table_melt_vol = results_table_melt_vol() # "H2OT-eq_wtpc","CO2T-eq_ppmw","ST_ppmw","X_ppmw"
314
+ results_values_table_melt_vol = pd.DataFrame([[setup.loc[run,"H2O"],setup.loc[run,"CO2ppm"],setup.loc[run,"STppm"],setup.loc[run,"Xppm"]]])
315
+ results_headers_table_H2OCO2only = pd.DataFrame([["Pvsat (H2O CO2 only)", "xg_H2O (H2O CO2 only)", "xg_CO2 (H2O CO2 only)","f_H2O (H2O CO2 only)", "f_CO2 (H2O CO2 only)","p_H2O (H2O CO2 only)", "p_CO2 (H2O CO2 only)", "Pvsat_diff_bar"]])
316
+ results_values_table_H2OCO2only = pd.DataFrame([[P_sat_H2O_CO2_only, P_sat_H2O_CO2_result["xg_H2O"], P_sat_H2O_CO2_result["xg_CO2"], P_sat_H2O_CO2_result["f_H2O"], P_sat_H2O_CO2_result["f_CO2"], P_sat_H2O_CO2_result["p_H2O"], P_sat_H2O_CO2_result["p_CO2"], (P_sat_H2O_CO2_only-PT["P"])]])
317
+ results_headers = pd.concat([results_headers_table_sample_name,results_headers_table_melt_comp_etc,results_headers_table_melt_vol,results_headers_table_sat,results_headers_table_H2OCO2only,results_headers_table_f_p_xg_y_M_C_K_d,results_headers_table_model_options],axis=1)
318
+ results1 = pd.concat([results_values_table_sample_name,results_values_table_melt_comp_etc,results_values_table_melt_vol,results_values_table_sat,results_values_table_H2OCO2only,results_values_table_f_p_xg_y_M_C_K_d,results_values_table_model_options],axis=1)
319
+
320
+ if n == first_row:
321
+ results = pd.concat([results_headers, results1])
322
+ else:
323
+ results = pd.concat([results, results1])
324
+
325
+ if models.loc["print status","option"] == "yes":
326
+ print(n, setup.loc[run,"Sample"],PT["P"])
327
+
328
+ results.columns = results.iloc[0]
329
+ results = results[1:]
330
+ if models.loc["output csv","option"] == "yes":
331
+ results.to_csv('results_saturation_pressures.csv', index=False, header=True)
332
+
333
+ return results
334
+
335
+ ### NEEDS CHECKING ###
336
+ def P_sat_output_fS2(first_row,last_row,p_tol,nr_step,nr_tol,setup,species,models):
337
+ # set up results table
338
+ results = pd.DataFrame([["oxygen fugacity","carbon dioxide solubility","C speciation composition","water solubility","water speciation","water speciation composition","sulfide solubility","sulfate solubility","sulfide saturation","ideal gas","carbonylsulfide","mass_volume","insolubles","Saturation calculation","Date"]])
339
+ results1 = pd.DataFrame([[models.loc["fO2","option"],models.loc["carbon dioxide","option"],models.loc["Cspeccomp","option"],models.loc["water","option"],models.loc["Hspeciation","option"],models.loc["Hspeccomp","option"],models.loc["sulfide","option"],models.loc["sulfate","option"],models.loc["sulfur_saturation","option"],models.loc["ideal_gas","option"],models.loc["carbonylsulfide","option"],models.loc["mass_volume","option"],models.loc['insolubles','option'],models.loc['calc_sat','option'],date.today()]])
340
+ results = pd.concat([results, results1], ignore_index=True)
341
+ results1 = ([["Sample","Pressure (bar)","Saturation pressure (bars)","T ('C)","fO2 (DNNO)","fO2 (DFMQ)",
342
+ "SiO2 (wt%)","TiO2 (wt%)","Al2O3 (wt%)","FeOT (wt%)","MnO (wt%)","MgO (wt%)","CaO (wt%)","Na2O (wt%)","K2O (wt%)","P2O5 (wt%)","ST (ppm)","S6/ST","Fe3/FeT",
343
+ "SCSS (ppm)","sulfide saturated","SCAS (ppm)","anhydrite saturated","S melt (ppm)",
344
+ "f-fO2","f-fS2","f-fSO2","f-pO2","f-pS2","f-pSO2","f-xgO2","f-xgS2","f-xgSO2",
345
+ "b-fO2","b-fS2","b-fSO2","b-pO2","b-pS2","b-pSO2","b-xgO2","b-xgS2","b-xgSO2","ySO2"]])
346
+ results = pd.concat([results, results1], ignore_index=True)
347
+
348
+ for n in range(first_row,last_row,1): # n is number of rows of data in conditions file
349
+ run = n
350
+
351
+ PT={"T":setup.loc[run,"T_C"]}
352
+ melt_wf=mg.melt_comp(run,setup)
353
+ melt_wf['CO2'] = 0.
354
+ melt_wf["H2OT"] = 0.
355
+
356
+ # check if any options need to be read from the setup file rather than the models file
357
+ models = options_from_setup(run,models,setup)
358
+
359
+ P_sat_, wm_ST, fSO2, wm_S2m, wm_S6p, pS2, pO2, pSO2, xgS2, xgO2, xgSO2 = c.P_sat_fO2_fS2(PT,melt_wf,species,models,p_tol)
360
+ if setup.loc[run,"P_bar"] > 0.:
361
+ PT["P"] = setup.loc[run,"P_bar"]
362
+ else:
363
+ PT["P"] = P_sat_
364
+ melt_wf["ST"] = wm_ST
365
+ melt_wf["S2-"] = wm_S2m
366
+ melt_wf["Fe3FeT"] = mg.Fe3FeT_i(PT,melt_wf,species,models)
367
+ SCSS_,sulfide_sat,SCAS_,sulfate_sat, ss_ST = c.sulfur_saturation(PT,melt_wf,species,models)
368
+ gas_mf = {"O2":mg.xg_O2(PT,melt_wf,species,models),"S2":mg.xg_S2(PT,melt_wf,species,models),"SO2":mg.xg_SO2(PT,melt_wf,species,models)}
369
+
370
+ ### store results ###
371
+ results2 = pd.DataFrame([[setup.loc[run,"Sample"],PT["P"],P_sat_,
372
+ setup.loc[run,"T_C"],mg.fO22Dbuffer(PT,mdv.f_O2(PT,melt_wf,species,models),"NNO",models),mg.fO22Dbuffer(PT,mdv.f_O2(PT,melt_wf,species,models),"FMQ",models),setup.loc[run,"SiO2"],setup.loc[run,"TiO2"],setup.loc[run,"Al2O3"],mg.Wm_FeOT(melt_wf,species),setup.loc[run,"MnO"],setup.loc[run,"MgO"],setup.loc[run,"CaO"],setup.loc[run,"Na2O"],setup.loc[run,"K2O"],setup.loc[run,"P2O5"],wm_ST,mg.S6ST(PT,melt_wf,species,models),melt_wf["Fe3FeT"],SCSS_,sulfide_sat,SCAS_,sulfate_sat,ss_ST,
373
+ mdv.f_O2(PT,melt_wf,species,models),setup.loc[run,"fS2"],fSO2, pO2,pS2,pSO2, xgO2,xgS2,xgSO2,mdv.f_O2(PT,melt_wf,species,models),mg.f_S2(PT,melt_wf,species,models),mg.f_SO2(PT,melt_wf,species,models), mg.p_O2(PT,melt_wf,species,models),mg.p_S2(PT,melt_wf,species,models),mg.p_SO2(PT,melt_wf,species,models), mg.xg_O2(PT,melt_wf,species,models),mg.xg_S2(PT,melt_wf,species,models),mg.xg_SO2(PT,melt_wf,species,models),mg.y_SO2(PT,species,models)]])
374
+
375
+ results = pd.concat([results, results1], ignore_index=True)
376
+ if models.loc["output csv","option"] == "yes":
377
+ results.to_csv('saturation_pressures_fS2.csv', index=False, header=False)
378
+ if models.loc["print status","option"] == "yes":
379
+ print(n, setup.loc[run,"Sample"],PT["P"])
380
+
381
+ ###############
382
+ ### gassing ###
383
+ ###############
384
+
385
+ def gassing(run,gassing_inputs,setup,species,models):
386
+
387
+ """
388
+ Calculates the pressure of vapor saturation for multiple melt compositions given volatile-free melt composition, volatile content, temperature, and an fO2 estimate.
389
+
390
+
391
+ Parameters
392
+ ----------
393
+ run: float
394
+ Integer of the row in the setup file to run (note the first row under the headers is row 0).
395
+ gassing_inputs: pandas.DataFrame
396
+ Dataframe containing the following:
397
+ dp_step: Pressure step size for gassing calculation in bars
398
+ nr_step: Step size for Newton-Raphson solver for melt speciation (typically 1 is fine, but this can be made smaller if there are problems with convergence).
399
+ nr_tol: Tolerance for the Newton-Raphson solver for melt speciation in weight fraction (typically 1e-6 is sufficient but this can be made larger if there are problems with convergence).
400
+ psat_tol: Required tolerance for convergence of Pvsat in bars (0.1 bars is normally used).
401
+ dwtg: Amount of gas to add at each step if regassing in an open-system in wt fraction total system
402
+ i_nr_step = Step-size for newton-raphson convergence for isotopes (typically 1e-1 is fine, but this can be made smaller if there are problems with convergence).
403
+ i_nr_tol = Tolerance for newton-raphson convergence for isotopes (typically 1e-9 is sufficient but this can be made larger if there are problems with convergence).
404
+ setup: pandas.DataFrame
405
+ Dataframe with melt composition to be used, requires following headers (notes in [] are not part of the headers):
406
+ Sample, T_C,
407
+ DNNO or DFMQ or logfO2 or (Fe2O3 and FeO) or Fe3FeT or S6ST, [at initial pressure]
408
+ SiO2, TiO2, Al2O3, (Fe2O3T or FeOT unless Fe2O3 and FeO given), MnO, MgO, CaO, Na2O, K2O, P2O5, [concentrations are in wt%]
409
+ (H2O and/or CO2ppm and/or STppm and/or Xppm) [concentration of H2O in wt%]
410
+ P_bar [IF starting from a given pressure]
411
+ final_P [IF regassing, pressure calculation stops at in bars]
412
+ wt_g [IF starting from given pressure and gas is present, can specifiy the gas present in wt%]
413
+ initial_CO2wtpc [IF starting from given pressure and gas is present, can specifiy initial composition using initial CO2 dissolved in the melt in wt%]
414
+ xg_O2, xg_CO, xg_H2, xg_S2, xg_X [IF starting from a given pressure, need initial guesses for mole fraction of gas species]
415
+ species: pandas.DataFrame
416
+ Dataframe of species.csv file.
417
+ models: pandas.DataFrame
418
+ Dataframe of models.csv file.
419
+
420
+ Returns
421
+ -------
422
+ results: pandas.DataFrame
423
+
424
+ Outputs
425
+ -------
426
+ If output csv = yes in models
427
+ results_gassing_chemistry: csv file
428
+
429
+ """
430
+
431
+ if models.loc["print status","option"] == "yes":
432
+ print(setup.loc[run,"Sample"])
433
+
434
+ # check if any options need to be read from the setup file rather than the models file
435
+ models = options_from_setup(run,models,setup)
436
+
437
+ if models.loc["fO2","option"] != "Kress91A":
438
+ raise TypeError("Change 'fO2' option in models to 'Kress91A' (other fO2 options are not currently supported)")
439
+ if models.loc["gassing_direction","option"] == "regas" and models.loc["starting_P","option"] == "bulk":
440
+ raise TypeError("gassing_direction = regas and starting_P = bulk in models are not compatible")
441
+
442
+ # set T, volatile composition of the melt, and tolerances
443
+ PT={"T":setup.loc[run,"T_C"]}
444
+ melt_wf = mg.melt_comp(run,setup)
445
+ melt_wf['CO2'] = setup.loc[run,"CO2ppm"]/1000000.
446
+ melt_wf["H2OT"] = setup.loc[run,"H2O"]/100.
447
+ melt_wf["ST"] = setup.loc[run,"STppm"]/1000000.
448
+ melt_wf["H2"] = 0.
449
+ melt_wf["XT"] = setup.loc[run,"Xppm"]/1000000.
450
+ melt_wf["CT"] = (melt_wf["CO2"]/species.loc["CO2","M"])*species.loc["C","M"]
451
+ melt_wf["HT"] = (2.*melt_wf["H2OT"]/species.loc["H2O","M"])*species.loc["H","M"]
452
+ melt_wf["ST"] = melt_wf["ST"]
453
+ if setup.loc[run,"S6ST"] > 0.:
454
+ melt_wf["S6ST"] = setup.loc[run,"S6ST"]
455
+ nr_step = gassing_inputs["nr_step"]
456
+ nr_tol = gassing_inputs["nr_tol"]
457
+ dp_step = gassing_inputs["dp_step"]
458
+ psat_tol = gassing_inputs["psat_tol"]
459
+ if models.loc["gassing_style","option"] == "open":
460
+ dwtg = gassing_inputs["dwtg"]
461
+
462
+ # Calculate saturation pressure for composition given in setup file
463
+ if models.loc["insolubles","option"] == "H2O-CO2 only":
464
+ P_sat_, P_sat_H2O_CO2_result = c.P_sat_H2O_CO2(PT,melt_wf,species,models,psat_tol,nr_step,nr_tol)
465
+ conc = {"wm_H2O":P_sat_H2O_CO2_result["wm_H2O"], "wm_CO2":P_sat_H2O_CO2_result["wm_CO2"], "wm_H2":0., "wm_CO":0., "wm_CH4":0., "wm_H2S":0., "wm_S2m":0., "wm_S6p":0., "ST": 0.}
466
+ frac = c.melt_species_ratios(conc,species)
467
+ else:
468
+ P_sat_, conc, frac = c.P_sat(PT,melt_wf,species,models,psat_tol,nr_step,nr_tol)
469
+ PT["P"] = P_sat_
470
+ if models.loc["print status","option"] == "yes":
471
+ print(PT["T"],PT["P"],datetime.datetime.now())
472
+
473
+ # update melt composition at saturation pressure, check for sulfur saturation, and calculate some things
474
+ melt_wf["H2OT"] = conc["wm_H2O"]
475
+ melt_wf["CO2"] = conc["wm_CO2"]
476
+ melt_wf["CO"] = conc["wm_CO"]
477
+ melt_wf["CH4"] = conc["wm_CH4"]
478
+ melt_wf["H2"] = conc["wm_H2"]
479
+ melt_wf["S2-"] = conc["wm_S2m"]
480
+ melt_wf["S6+"] = conc["wm_S6p"]
481
+ melt_wf["H2S"] = conc["wm_H2S"]
482
+ melt_wf["Fe3FeT"] = mg.Fe3FeT_i(PT,melt_wf,species,models)
483
+ melt_wf["S6ST"] = mg.S6ST(PT,melt_wf,species,models)
484
+ sulf_sat_result = c.sulfur_saturation(PT,melt_wf,species,models)
485
+ wm_CO2eq, wm_H2Oeq = mg.melt_H2O_CO2_eq(melt_wf,species)
486
+ melt_comp = mg.melt_normalise_wf(melt_wf,species,"yes","no")
487
+
488
+ # Set bulk composition
489
+ bulk_comp = c.bulk_composition(run,PT,melt_wf,setup,species,models)
490
+ bulk_wf = {"C":bulk_comp["wt_C"],"H":bulk_comp["wt_H"],"O":bulk_comp["wt_O"],"S":bulk_comp["wt_S"],"Fe":bulk_comp["wt_Fe"],"Wt":bulk_comp["Wt"],"X":bulk_comp["wt_X"]}
491
+
492
+ # set system and initial guesses
493
+ system = eq.set_system(melt_wf,models)
494
+ guesses = eq.initial_guesses(run,PT,melt_wf,setup,species,models,system)
495
+
496
+ # create results
497
+ results_headers_table_sample_name, results_values_table_sample_name = results_table_sample_name(setup,run)
498
+ results_headers_table_melt_comp_etc, results_values_table_melt_comp_etc = results_table_melt_comp_etc(PT,melt_comp,conc,frac,melt_wf)
499
+ results_headers_table_model_options, results_values_table_model_options = results_table_model_options(models)
500
+ results_headers_table_f_p_xg_y_M_C_K_d, results_values_table_f_p_xg_y_M_C_K_d = results_table_f_p_xg_y_M_C_K_d(PT,melt_wf,species,models)
501
+ results_headers_table_sat, results_values_table_sat = results_table_sat(sulf_sat_result,PT,melt_wf,species,models)
502
+ results_headers_table_melt_vol = results_table_melt_vol() # "H2OT-eq_wtpc","CO2T-eq_ppmw","ST_ppmw","X_ppmw"
503
+ results_values_table_melt_vol = pd.DataFrame([[wm_H2Oeq*100.,wm_CO2eq*1000000.,conc["ST"]*1000000.,melt_wf["XT"]*1000000.]])
504
+ results_headers_table_wtg_etc = pd.DataFrame([["wt_g_wtpc","wt_g_O_wtf","wt_g_C_wtf","wt_g_H_wtf","wt_g_S_wtf","wt_g_X_wtf","wt_O_wtpc","wt_C_wtpc","wt_H_wtpc","wt_S_wtpc","wt_X_wtpc","Solving species"]])
505
+ results_values_table_wtg_etc = pd.DataFrame([[bulk_comp["wt_g"]*100.,"","","","","",bulk_wf["O"]*100.,bulk_wf["C"]*100.,bulk_wf["H"]*100.,bulk_wf["S"]*100.,bulk_wf["X"]*100.,""]])
506
+ if models.loc["gassing_style","option"] == "open" and models.loc["gassing_direction","option"] == "degas":
507
+ results_headers_table_open_all_gas = results_table_open_all_gas()
508
+ results_values_table_open_all_gas = pd.DataFrame([[mg.xg_O2(PT,melt_wf,species,models),mg.xg_H2(PT,melt_wf,species,models),mg.xg_H2O(PT,melt_wf,species,models),mg.xg_S2(PT,melt_wf,species,models),mg.xg_SO2(PT,melt_wf,species,models),mg.xg_H2S(PT,melt_wf,species,models),mg.xg_CO2(PT,melt_wf,species,models),mg.xg_CO(PT,melt_wf,species,models),mg.xg_CH4(PT,melt_wf,species,models),mg.xg_OCS(PT,melt_wf,species,models),mg.xg_X(PT,melt_wf,species,models),mg.gas_CS(PT,melt_wf,species,models)]])
509
+ results_headers = pd.concat([results_headers_table_sample_name,results_headers_table_melt_comp_etc,results_headers_table_melt_vol,results_headers_table_sat,results_headers_table_f_p_xg_y_M_C_K_d,results_headers_table_wtg_etc,results_headers_table_open_all_gas,results_headers_table_model_options],axis=1)
510
+ results1 = pd.concat([results_values_table_sample_name,results_values_table_melt_comp_etc,results_values_table_melt_vol,results_values_table_sat,results_values_table_f_p_xg_y_M_C_K_d,results_values_table_wtg_etc,results_values_table_open_all_gas,results_values_table_model_options],axis=1)
511
+ else:
512
+ results_headers = pd.concat([results_headers_table_sample_name,results_headers_table_melt_comp_etc,results_headers_table_melt_vol,results_headers_table_sat,results_headers_table_f_p_xg_y_M_C_K_d,results_headers_table_wtg_etc,results_headers_table_model_options],axis=1)
513
+ results1 = pd.concat([results_values_table_sample_name,results_values_table_melt_comp_etc,results_values_table_melt_vol,results_values_table_sat,results_values_table_f_p_xg_y_M_C_K_d,results_values_table_wtg_etc,results_values_table_model_options],axis=1)
514
+ results = pd.concat([results_headers, results1])
515
+
516
+ # results for isotope calculations...
517
+ if models.loc["isotopes","option"] == "yes":
518
+ raise TypeError("This is not currently supported")
519
+ a_H2S_S_,a_SO4_S_,a_S2_S_,a_SO2_S_,a_OCS_S_ = iso.i2s6_S_alphas(PT)
520
+ results_isotopes1 = pd.DataFrame([["P","T_C","xg_O2","xg_CO","xg_CO2","xg_H2","xg_H2O","xg_CH4","xg_S2","xg_SO2","xg_SO3","xg_H2S","xg_OCS","wt_g",
521
+ "wm_CO2","wm_H2O","wm_H2","wm_S","wm_SO3","wm_ST","Fe3T","S6T",
522
+ "DFMQ","DNNO","SCSS","sulfide sat?","SCAS","sulfate sat?",
523
+ "RS_S2-","RS_SO42-","RS_H2S","RS_SO2","RS_S2","R_OCS","R_m","R_g",
524
+ "dS_S2-","dS_SO42-","dS_H2S","dS_SO2","dS_S2","dS_OCS","dS_m","dS_g",
525
+ "a_H2S_S2-","a_SO42-_S2-","a_S2_S2-","a_SO2_S2-","a_OCS_S2-","a_g_m"]])
526
+ results_isotopes = results_header.append(results_isotopes1, ignore_index=True)
527
+ results1 = pd.DataFrame([[PT["P"],PT["T"],mg.xg_O2(PT,melt_wf,species,models),mg.xg_CO(PT,melt_wf,species,models),mg.xg_CO2(PT,melt_wf,species,models),mg.xg_H2(PT,melt_wf,species,models),mg.xg_H2O(PT,melt_wf,species,models),mg.xg_CH4(PT,melt_wf,species,models),mg.xg_S2(PT,melt_wf,species,models),mg.xg_SO2(PT,melt_wf,species,models),mg.xg_H2S(PT,melt_wf,species,models),mg.xg_OCS(PT,melt_wf,species,models),wt_g_,
528
+ melt_wf["CO2"],melt_wf["H2OT"],0,(mg.wm_S(PT,melt_wf,species,models)/100),(mg.wm_SO3(PT,melt_wf,species,models)/100),melt_wf["ST"],melt_wf["Fe3FeT"],mg.S6ST(PT,melt_wf,species,models),
529
+ mg.fO22Dbuffer(PT,mdv.f_O2(PT,melt_wf,species,models),"FMQ"),mg.fO22Dbuffer(PT,mdv.f_O2(PT,melt_wf,species,models),"NNO"),SCSS_,sulfide_sat,SCAS_,sulfate_sat,
530
+ R_S_S2_,R_S_SO4_,"","","","",R_i["S"],"",ratio2delta("VCDT",R_S_S2_),ratio2delta("VCDT",R_S_SO4_),"","","","",ratio2delta("VCDT",R_i["S"]),"",
531
+ a_H2S_S_,a_SO4_S_,a_S2_S_,a_SO2_S_,a_OCS_S_,""]])
532
+ results_isotopes = pd.concat([results_isotopes, results1], ignore_index=True)
533
+ if models.loc["output csv","option"] == "yes":
534
+ results_isotopes.to_csv('results_gassing_isotopes.csv', index=False, header=False)
535
+
536
+ if models.loc["P_variation","option"] == "polybaric":
537
+ # pressure ranges and options
538
+ starting_P = models.loc["starting_P","option"]
539
+ if starting_P == "bulk":
540
+ if models.loc["bulk_composition","option"] != "yes":
541
+ raise warning("not that if starting_P = bulk and bulk_composition != yes, Pvsat calculated is not for bulk system")
542
+ if starting_P == "set":
543
+ initial = int(setup.loc[run,"P_bar"])
544
+ else:
545
+ if models.loc["gassing_direction","option"] == "degas":
546
+ answer = PT["P"]/dp_step
547
+ answer = round(answer)
548
+ initial = round(answer*dp_step)
549
+ elif models.loc["gassing_direction","option"] == "regas":
550
+ answer = PT["P"]/dp_step
551
+ answer = round(answer)
552
+ answer = round(answer*dp_step)
553
+ initial = round(answer+dp_step)
554
+ if models.loc["gassing_direction","option"] == "degas":
555
+ step = int(-1*dp_step) # pressure step in bars
556
+ final = 0
557
+ elif models.loc["gassing_direction","option"] == "regas":
558
+ step = int(dp_step)
559
+ final = int(setup.loc[run,"final_P"])
560
+ elif models.loc["T_variation","option"] == "polythermal": # temperature ranges and options
561
+ PT["P"] = setup.loc[run,"P_bar"]
562
+ final = int(setup.loc[run,"final_T"])
563
+ if setup.loc[run,"final_T"] > setup.loc[run,"T_C"]:
564
+ initial = int(round(PT["T"]))
565
+ step = int(dp_step) # temperature step in 'C
566
+ elif setup.loc[run,"final_T"] < setup.loc[run,"T_C"]:
567
+ initial = int(round(PT["T"]))
568
+ step = int(-1.*dp_step) # temperature step in 'C
569
+
570
+ # add some gas to the system if doing open-system regassing
571
+ if models.loc["gassing_direction","option"] == "regas" and models.loc["gassing_style","option"] == "open":
572
+ gas_mf = {"O2":mg.xg_O2(PT,melt_wf,species,models),"CO":mg.xg_CO(PT,melt_wf,species,models),"CO2":mg.xg_CO2(run,PT,melt_wf,setup,species,models),"H2":mg.xg_H2(PT,melt_wf,species,models),"H2O":mg.xg_H2O(PT,melt_wf,species,models),"CH4":mg.xg_CH4(PT,melt_wf,species,models),"S2":mg.xg_S2(PT,melt_wf,species,models),"SO2":mg.xg_SO2(PT,melt_wf,species,models),"SO3":mg.xg_SO3(PT,melt_wf,species,models),"H2S":mg.xg_H2S(run,PT,melt_wf,setup,species,models),"OCS":mg.xg_OCS(PT,melt_wf,species,models),"X":mg.xg_X(PT,melt_wf,species,models),"Xg_t":mg.Xg_tot(PT,melt_wf,species,models),"wt_g":0.}
573
+ wt_C, wt_H, wt_S, wt_X, wt_Fe, wt_O, Wt = new_bulk_regas_open(PT,melt_wf,bulk_wf,gas_mf,dwtg,species,models)
574
+ bulk_wf = {"C":wt_C,"H":wt_H,"O":wt_O,"S":wt_S,"Fe":wt_Fe,"X":wt_X,"Wt":Wt}
575
+
576
+ # run over different pressures #
577
+ number_of_step = 0.
578
+ for i in range(initial,final,step): # P is pressure in bars or T is temperature in 'C
579
+ number_of_step = number_of_step + 1.
580
+ eq_Fe = models.loc["eq_Fe","option"]
581
+
582
+ if models.loc["gassing_style","option"] == "open": # check melt is still vapor-saturated
583
+ if models.loc["insolubles","option"] == "H2O-CO2 only":
584
+ P_sat_, P_sat_H2O_CO2_result = c.P_sat_H2O_CO2(PT,melt_wf,species,models,psat_tol,nr_step,nr_tol)
585
+ conc = {"wm_H2O":P_sat_H2O_CO2_result["wm_H2O"], "wm_CO2":P_sat_H2O_CO2_result["wm_CO2"], "wm_H2":0., "wm_CO":0., "wm_CH4":0., "wm_H2S":0., "wm_S2m":0., "wm_S6p":0., "ST": 0.}
586
+ frac = c.melt_species_ratios(conc,species)
587
+ else:
588
+ P_sat_, conc, frac = c.P_sat(PT,melt_wf,species,models,psat_tol,nr_step,nr_tol)
589
+ if models.loc["P_variation","option"] == "polybaric":
590
+ P = i - dp_step
591
+ if P < dp_step:
592
+ P = 1.
593
+ PT["P"] = P
594
+ elif models.loc["T_variation","option"] == "polythermal":
595
+ T = i - dp_step
596
+ PT["T"] = T
597
+ if P_sat_ > PT["P"]:
598
+ # work out equilibrium partitioning between melt and gas phase
599
+ xg, conc, melt_and_gas, guesses = eq.mg_equilibrium(PT,melt_wf,bulk_wf,species,models,nr_step,nr_tol,guesses)
600
+ # gas composition
601
+ gas_mf = {"O2":xg["xg_O2"],"CO":xg["xg_CO"],"S2":xg["xg_S2"],"CO2":xg["xg_CO2"],"H2O":xg["xg_H2O"],"H2":xg["xg_H2"],"CH4":xg["xg_CH4"],"SO2":xg["xg_SO2"],"H2S":xg["xg_H2S"],"OCS":xg["xg_OCS"],"X":xg["xg_X"],"Xg_t":xg["Xg_t"],"wt_g":melt_and_gas["wt_g"]}
602
+ if models.loc["gassing_style","option"] == "open" and models.loc["gassing_direction","option"] == "degas":
603
+ if i == initial:
604
+ gas_mf_all = gas_mf
605
+ else:
606
+ gas_mf_all = c.gas_comp_all_open(gas_mf,gas_mf_all,models,species)
607
+ if models.loc["insolubles","option"] == "H2O-CO2 only":
608
+ Fe3T = melt_wf["Fe3FeT"]
609
+ Fe32 = mg.overtotal2ratio(Fe3T)
610
+ else: # NEEDS SORTING ###
611
+ conc = eq.melt_speciation(PT,melt_wf,species,models,nr_step,nr_tol)
612
+ frac = c.melt_species_ratios(conc,species)
613
+ #wm_ST_ = wm_S_ + wm_S6p_
614
+ #S62 = S6T/S2m_ST
615
+ #Fe3T = melt_wf["Fe3FeT"]
616
+ #Fe32 = mg.overtotal2ratio(Fe3T)
617
+ xg_O2_, xg_H2_, xg_S2_, xg_H2O_, xg_CO_, xg_CO2_, xg_SO2_, xg_CH4_, xg_H2S_, xg_OCS_, xg_X, Xg_t, Xm_t, Xm_t_ox, wt_g_O, wt_g_C, wt_g_H, wt_g_S, wt_g = "","","","","","","","","","","","","","",0.,0.,0.,0.,0.
618
+ guesses = eq.initial_guesses(run,PT,melt_wf,setup,species,models,system)
619
+
620
+ # set melt composition for forward calculation
621
+ melt_wf["CO2"] = conc["wm_CO2"]
622
+ melt_wf["H2OT"] = conc["wm_H2O"]
623
+ melt_wf["H2"] = conc["wm_H2"]
624
+ melt_wf["CO"] = conc["wm_CO"]
625
+ melt_wf["CH4"] = conc["wm_CH4"]
626
+ melt_wf["H2S"] = conc["wm_H2S"]
627
+ melt_wf["S6+"] = (conc["wm_SO3"]/species.loc["SO3","M"])*species.loc["S","M"]
628
+ melt_wf["S2-"] = conc["wm_S"]
629
+ melt_wf["ST"] = conc["wm_ST"]
630
+ melt_wf["XT"] = conc["wm_X"]
631
+ melt_wf["Fe3FeT"] = conc["Fe3T"]
632
+ if P_sat_ < PT["P"]:
633
+ bulk_comp = c.bulk_composition(run,PT,melt_wf,setup,species,models)
634
+
635
+ # check for sulfur saturation and display warning in outputs
636
+ sulf_sat_result = c.sulfur_saturation(PT,melt_wf,species,models)
637
+ if sulf_sat_result["sulfide_sat"] == "yes":
638
+ warning = "WARNING: sulfide-saturated"
639
+ elif sulf_sat_result["sulfate_sat"] == "yes":
640
+ warning = "WARNING: sulfate-saturated"
641
+ else:
642
+ warning = ""
643
+
644
+ # calculate fO2
645
+ if eq_Fe == "yes":
646
+ fO2_ = mdv.f_O2(PT,melt_wf,species,models)
647
+ elif eq_Fe == "no":
648
+ fO2_ = (xg_O2_*mdv.y_O2(PT,models)*PT["P"])
649
+
650
+ wm_CO2eq, wm_H2Oeq = mg.melt_H2O_CO2_eq(melt_wf,species)
651
+ melt_comp = mg.melt_normalise_wf(melt_wf,species,"yes","no")
652
+ frac = c.melt_species_ratios(conc,species)
653
+
654
+ # store results
655
+ results_headers_table_sample_name, results_values_table_sample_name = results_table_sample_name(setup,run)
656
+ results_headers_table_melt_comp_etc, results_values_table_melt_comp_etc = results_table_melt_comp_etc(PT,melt_comp,conc,frac,melt_wf)
657
+ results_headers_table_model_options, results_values_table_model_options = results_table_model_options(models)
658
+ results_headers_table_f_p_xg_y_M_C_K_d, results_values_table_f_p_xg_y_M_C_K_d = results_table_f_p_xg_y_M_C_K_d(PT,melt_wf,species,models)
659
+ results_headers_table_sat, results_values_table_sat = results_table_sat(sulf_sat_result,PT,melt_wf,species,models)
660
+ results_values_table_melt_vol = pd.DataFrame([[wm_H2Oeq*100.,wm_CO2eq*1000000.,conc["wm_ST"]*1000000.,melt_wf["XT"]*1000000.]])
661
+ results_values_table_wtg_etc = pd.DataFrame([[melt_and_gas["wt_g"]*100.,melt_and_gas["wt_g_O"],melt_and_gas["wt_g_C"],melt_and_gas["wt_g_H"],melt_and_gas["wt_g_S"],melt_and_gas["wt_g_X"],melt_and_gas["wt_O"]*100.,melt_and_gas["wt_C"]*100.,melt_and_gas["wt_H"]*100.,melt_and_gas["wt_S"]*100.,melt_and_gas["wt_X"]*100.,models.loc["solve_species","option"]]])
662
+ if models.loc["gassing_style","option"] == "open" and models.loc["gassing_direction","option"] == "degas":
663
+ results_values_table_open_all_gas = pd.DataFrame([[gas_mf_all["O2"],gas_mf_all["H2"],gas_mf_all["H2O"],gas_mf_all["S2"],gas_mf_all["SO2"],gas_mf_all["H2S"],gas_mf_all["CO2"],gas_mf_all["CO"],gas_mf_all["CH4"],gas_mf_all["OCS"],gas_mf_all["X"],mg.gas_CS_alt(gas_mf_all)]])
664
+ results1 = pd.concat([results_values_table_sample_name,results_values_table_melt_comp_etc,results_values_table_melt_vol,results_values_table_sat,results_values_table_f_p_xg_y_M_C_K_d,results_values_table_wtg_etc,results_values_table_open_all_gas,results_values_table_model_options],axis=1)
665
+ else:
666
+ results1 = pd.concat([results_values_table_sample_name,results_values_table_melt_comp_etc,results_values_table_melt_vol,results_values_table_sat,results_values_table_f_p_xg_y_M_C_K_d,results_values_table_wtg_etc,results_values_table_model_options],axis=1)
667
+ results = pd.concat([results, results1])
668
+
669
+ # equilibrium isotope fractionation
670
+ if models.loc["isotopes", "option"] == "yes":
671
+ raise TypeError("This is not currently supported")
672
+ if models.loc["H2S","option"] == "yes":
673
+ print("not currently possible")
674
+ A, B = iso.i2s6("S",PT,R_i,melt_wf,gas_mf,species,i_nr_step,i_nr_tol,guessx)
675
+ RS_Sm, RS_H2S, RS_SO4, RS_S2, RS_SO2, RS_OCS = A
676
+ RS_m, RS_g = B
677
+ a_H2S_S_,a_SO4_S_,a_S2_S_,a_SO2_S_,a_OCS_S_ = iso.i2s6_S_alphas(PT)
678
+ xg_SO3_ = 0.
679
+ results2 = pd.DataFrame([[PT["P"],PT["T"],xg_O2_,xg_CO_,xg_CO2_,xg_H2_,xg_H2O_,xg_CH4_,xg_S2_,xg_SO2_,xg_SO3_,xg_H2S_,xg_OCS_,wt_g,
680
+ wm_CO2_,wm_H2O_,wm_H2_,wm_S_,wm_SO3_,wm_ST_,Fe3T,S6T,
681
+ mg.fO22Dbuffer(PT,fO2_,"FMQ"),mg.fO22Dbuffer(PT,fO2_,"NNO"),SCSS_,sulfide_sat,SCAS_,sulfate_sat,
682
+ RS_Sm, RS_SO4, RS_H2S, RS_SO2, RS_S2, RS_OCS, RS_m, RS_g, ratio2delta("VCDT",RS_Sm),ratio2delta("VCDT",RS_SO4),ratio2delta("VCDT",RS_H2S),ratio2delta("VCDT",RS_SO2),ratio2delta("VCDT",RS_S2),ratio2delta("VCDT",RS_OCS),ratio2delta("VCDT",RS_m),ratio2delta("VCDT",RS_g),a_H2S_S_,a_SO4_S_,a_S2_S_,a_SO2_S_,a_OCS_S_,RS_g/RS_m]])
683
+ results_isotopes = pd.concat([results_isotopes, results2], ignore_index=True)
684
+ if models.loc["output csv","option"] == "yes":
685
+ results_isotopes.to_csv('results_gassing_isotopes.csv', index=False, header=False)
686
+
687
+ if models.loc["print status","option"] == "yes":
688
+ if(number_of_step % 100==0):
689
+ print(PT["T"],PT["P"],mg.fO22Dbuffer(PT,fO2_,"FMQ",models),warning,datetime.datetime.now())
690
+
691
+ # recalculate bulk composition if needed
692
+ if models.loc["gassing_style","option"] == "open":
693
+ results_me = mg.melt_elements(PT,melt_wf,bulk_wf,gas_mf,species,models)
694
+ if models.loc["gassing_direction","option"] == "degas":
695
+ Wt_ = bulk_wf['Wt']
696
+ if results_me["wm_C"] < 1.e-6:
697
+ results_me["wm_C"] = 0.
698
+ bulk_wf = {"C":results_me["wm_C"],"H":results_me["wm_H"],"O":results_me["wm_O"],"S":results_me["wm_S"],"X":results_me["wm_X"],"Fe":results_me["wm_Fe"],"Wt":(Wt_*(1. - melt_and_gas["wt_g"]))}
699
+ melt_wf["CT"] = results_me["wm_C"]
700
+ melt_wf["HT"] = results_me["wm_H"]
701
+ melt_wf["ST"] = results_me["wm_S"]
702
+ melt_wf["XT"] = results_me["wm_X"]
703
+ elif models.loc["gassing_direction","option"] == "regas":
704
+ results_nbro = c.new_bulk_regas_open(PT,melt_wf,bulk_wf,gas_mf,dwtg,species,models)
705
+ bulk_wf = {"C":results_nbro["wt_C"],"H":results_nbro["wt_H"],"O":results_nbro["wt_O"],"S":results_nbro["wt_S"],"X":results_nbro["wt_X"],"Fe":results_nbro["wt_Fe"],"Wt":results_nbro["Wt"]}
706
+ melt_wf["CT"] = results_nbro["wm_C"]
707
+ melt_wf["HT"] = results_nbro["wm_H"]
708
+ melt_wf["ST"] = results_nbro["wm_S"]
709
+ melt_wf["XT"] = results_nbro["wm_X"]
710
+ if models.loc["crystallisation","option"] == "yes":
711
+ wt_C_ = bulk_wf["C"]
712
+ wt_H_ = bulk_wf["H"]
713
+ wt_O_ = bulk_wf["O"]
714
+ wt_S_ = bulk_wf["S"]
715
+ wt_X_ = bulk_wf["X"]
716
+ wt_Fe_ = bulk_wf["Fe"]
717
+ wt_ = bulk_wf["Wt"]
718
+ Xst = setup.loc[run,"crystallisation_pc"]/100.
719
+ bulk_wf = {"C":wt_C_*(1./(1.-Xst)),"H":wt_H_*(1./(1.-Xst)),"O":wt_O_*(1./(1.-Xst)),"S":wt_S_*(1./(1.-Xst)),"X":wt_X_*(1./(1.-Xst)),"Fe":wt_Fe_*(1./(1.-Xst)),"Wt":wt_*(1.-Xst)}
720
+
721
+ results.columns = results.iloc[0]
722
+ results = results[1:]
723
+ if models.loc["output csv","option"] == "yes":
724
+ results.to_csv('results_gassing_chemistry.csv', index=False, header=True)
725
+
726
+ if models.loc["print status","option"] == "yes":
727
+ print("done", datetime.datetime.now())
728
+
729
+ return results
730
+
731
+
732
+ ################
733
+ ### isotopes ###
734
+ ################
735
+
736
+ def isotopes(run,isotope_inputs,setup,species,models):
737
+
738
+ i_nr_step = gassing_inputs["i_nr_step"]
739
+ i_nr_tol = gassing_inputs["i_nr_tol"]
740
+ # calculating equilibrium isotopic fractionation?
741
+ if models.loc["isotopes","option"] == "yes":
742
+ if setup.loc[run,"bulk 34S/32S"] > 0.:
743
+ R_i = {"S": setup.loc[run,"bulk 34S/32S"]}
744
+ elif setup.loc[run,"bulk d34S"] >= 0.:
745
+ d = setup.loc[run,"bulk d34S"]
746
+ R_i = {"S": delta2ratio("VCDT",d)}
747
+ elif setup.loc[run,"bulk d34S"] <= 0.:
748
+ d = setup.loc[run,"bulk d34S"]
749
+ R_i = {"S": delta2ratio("VCDT",setup.loc[run,"bulk d34S"])}
750
+ else:
751
+ raise TypeError("input bulk isotope value for system or change 'isotopes' to 'no' in models")
752
+ return
753
+ R_S_SO4_, R_S_S2_ = iso.i2s2("S",PT,R_i,melt_wf)
754
+ else:
755
+ R_i = {"S":""}
756
+
757
+
758
+
759
+ def calc_isobar(run,setup,species,models,initial_P,final_P,step_P):
760
+
761
+ if models.loc["insolubles","option"] == "H2O-CO2 only":
762
+ PT={"T":setup.loc[run,"T_C"]}
763
+
764
+ # check if any options need to be read from the setup file rather than the models file
765
+ models = options_from_setup(run,models,setup)
766
+
767
+ # set up results table
768
+ results = pd.DataFrame([["P (bar)","H2O (wt%)","CO2 (ppm)"]])
769
+
770
+ initial_P = int(initial_P)
771
+ final_P = int(final_P+1)
772
+ step_P = int(step_P)
773
+
774
+ for n in range(initial_P,final_P,step_P):
775
+ PT["P"] = n # pressure in bars
776
+ melt_wf=mg.melt_comp(run,setup)
777
+ results1 = c.calc_isobar_CO2H2O(PT,melt_wf,species,models)
778
+ results = pd.concat([results, results1], ignore_index=True)
779
+ if models.loc["print status","option"] == "yes":
780
+ print(setup.loc[run,"Sample"],n)
781
+ else:
782
+ raise TypeError("insolubles must be H2O-CO2 only")
783
+ if models.loc["output csv","option"] == "yes":
784
+ results.to_csv('results_isobars.csv', index=False, header=False)
785
+
786
+ return results
787
+
788
+ def calc_pure_solubility(run,setup,species,models,initial_P):
789
+ if models.loc["print status","option"] == "yes":
790
+ print(setup.loc[run,"Sample"],initial_P)
791
+ PT={"T":setup.loc[run,"T_C"]}
792
+
793
+ # check if any options need to be read from the setup file rather than the models file
794
+ models = options_from_setup(run,models,setup)
795
+
796
+ # set up results table
797
+ results = pd.DataFrame([["P (bar)","H2O (wt%)","CO2 (ppm)"]])
798
+
799
+ initial_P = int(initial_P)
800
+
801
+ for n in range(initial_P,1,-1):
802
+ PT["P"] = n # pressure in bars
803
+ melt_wf=mg.melt_comp(run,setup)
804
+ results1 = c.calc_pure_solubility(PT,melt_wf,species,models)
805
+ results = pd.concat([results, results1], ignore_index=True)
806
+ if models.loc["output csv","option"] == "yes":
807
+ results.to_csv('results_pure_solubility.csv', index=False, header=False)
808
+ if models.loc["print status","option"] == "yes":
809
+ print("done")
810
+
811
+ return results
812
+
813
+
814
+ #########################
815
+ ### Sulfate capacity ###
816
+ #########################
817
+
818
+ # calculate the Csulfate for multiple melt compositions in input file
819
+ def Csulfate_output(first_row,last_row,setup,species,models):
820
+
821
+ # set up results table
822
+ results = pd.DataFrame([["oxygen fugacity","carbon dioxide solubility","C speciation composition","water solubility","water speciation","water speciation composition","sulfide solubility","sulfate solubility","sulfide saturation","ideal gas","carbonylsulfide","mass_volume","Date"]])
823
+ results1 = pd.DataFrame([[models.loc["fO2","option"],models.loc["carbon dioxide","option"],models.loc["Cspeccomp","option"],models.loc["water","option"],models.loc["Hspeciation","option"],models.loc["Hspeccomp","option"],models.loc["sulfide","option"],models.loc["sulfate","option"],models.loc["sulfur_saturation","option"],models.loc["ideal_gas","option"],models.loc["carbonylsulfide","option"],models.loc["mass_volume","option"],date.today()]])
824
+ results = pd.concat([results, results1], ignore_index=True)
825
+ results1 = ([["Sample","Pressure (bar)","T ('C)","SiO2","TiO2","Al2O3","FeOT","MnO","MgO","CaO","Na2O","K2O","P2O5",
826
+ "H2O","CO2 (ppm)","ST (ppm)","S6/ST","Fe3/FeT","ln[Csulfide]","ln[Csulfate]","fO2","DNNO","DFMQ"]])
827
+ results = pd.concat([results, results1], ignore_index=True)
828
+
829
+ for n in range(first_row,last_row,1): # n is number of rows of data in conditions file
830
+ run = n
831
+
832
+ # check if any options need to be read from the setup file rather than the models file
833
+ models = options_from_setup(run,models,setup)
834
+
835
+ PT={"T":setup.loc[run,"T_C"]}
836
+ melt_wf=mg.melt_comp(run,setup)
837
+ melt_wf['CO2'] = setup.loc[run,"CO2ppm"]/1000000.
838
+ melt_wf["H2OT"] = setup.loc[run,"H2O"]/100.
839
+ melt_wf["ST"] = setup.loc[run,"STppm"]/1000000.
840
+ PT["P"] = setup.loc[run,"P_bar"]
841
+ melt_wf["Fe3FeT"] = mg.Fe3FeT_i(PT,melt_wf,species,models)
842
+ if setup.loc[run,"S6ST"] >= 0.:
843
+ melt_wf["S6ST"] = setup.loc[run,"S6ST"]
844
+ else:
845
+ melt_wf["S6ST"] = ""
846
+ Csulfate_ = mdv.C_SO4(PT,melt_wf,species,models)
847
+
848
+ ### store results ###
849
+ results2 = pd.DataFrame([[setup.loc[run,"Sample"],setup.loc[run,"P_bar"],setup.loc[run,"T_C"],setup.loc[run,"SiO2"],setup.loc[run,"TiO2"],setup.loc[run,"Al2O3"],mg.Wm_FeOT(run,setup,species),setup.loc[run,"MnO"],setup.loc[run,"MgO"],setup.loc[run,"CaO"],setup.loc[run,"Na2O"],setup.loc[run,"K2O"],setup.loc[run,"P2O5"],setup.loc[run,"H2O"],setup.loc[run,"CO2ppm"],setup.loc[run,"STppm"],melt_wf["S6ST"],melt_wf["Fe3FeT"],gp.log(mg.C_S(PT,melt_wf,species,models)),gp.log(Csulfate_),mdv.f_O2(PT,melt_wf,species,models),mg.fO22Dbuffer(PT,mdv.f_O2(PT,melt_wf,species,models),"NNO"),mg.fO22Dbuffer(PT,mdv.f_O2(PT,melt_wf,species,models),"FMQ")]])
850
+ results = pd.concat([results, results2], ignore_index=True)
851
+ if models.loc["output csv","option"] == "yes":
852
+ results.to_csv('Csulfate.csv', index=False, header=False)
853
+ if models.loc["print status","option"] == "yes":
854
+ print(n, setup.loc[run,"Sample"],gp.log(Csulfate_),gp.log(mg.C_S(PT,melt_wf,species,models)))
855
+ return results
856
+
857
+ ##################
858
+ ### Capacities ###
859
+ ##################
860
+
861
+ # print capacities for multiple melt compositions in input file
862
+ def capacities_output(first_row,last_row,setup,species,models):
863
+ # set up results table
864
+ results = pd.DataFrame([["oxygen fugacity","carbon dioxide solubility","C speciation composition","water solubility","water speciation","water speciation composition","sulfide solubility","sulfate solubility","sulfide saturation","ideal gas","carbonylsulfide","mass_volume","Date"]])
865
+ results1 = pd.DataFrame([[models.loc["fO2","option"],models.loc["carbon dioxide","option"],models.loc["Cspeccomp","option"],models.loc["water","option"],models.loc["Hspeciation","option"],models.loc["Hspeccomp","option"],models.loc["sulfide","option"],models.loc["sulfate","option"],models.loc["sulfur_saturation","option"],models.loc["ideal_gas","option"],models.loc["carbonylsulfide","option"],models.loc["mass_volume","option"],date.today()]])
866
+ results = pd.concat([results, results1], ignore_index=True)
867
+ results1 = ([["Sample","Pressure (bar)","T ('C)","SiO2","TiO2","Al2O3","FeOT","MnO","MgO","CaO","Na2O","K2O","P2O5",
868
+ "H2O","CO2 (ppm)","ST (ppm)","Fe3+/FeT","fO2 DFMQ","ln[C_CO32-]","ln[C_H2OT]","ln[C_S2-]","ln[C_S6+]","ln[C_H2S]","ln[C_H2]","ln[C_CO]","ln[C_CH4]","ln[C_X]","M_m_SO",]])
869
+ results = pd.concat([results, results1], ignore_index=True)
870
+
871
+ for n in range(first_row,last_row,1): # n is number of rows of data in conditions file
872
+ run = n
873
+
874
+ # check if any options need to be read from the setup file rather than the models file
875
+ models = options_from_setup(run,models,setup)
876
+
877
+ PT={"T":setup.loc[run,"T_C"]}
878
+ melt_wf=mg.melt_comp(run,setup)
879
+ CO2 = setup.loc[run,"CO2ppm"]/1000000.
880
+ CT = (CO2/species.loc["CO2","M"])*species.loc["C","M"]
881
+ H2O = setup.loc[run,"H2O"]/100.
882
+ HT = (H2O/species.loc["H2O","M"])*species.loc["H2","M"]
883
+ XT = setup.loc[run,"Xppm"]/1000000.
884
+ ST = setup.loc[run,"STppm"]/1000000.
885
+ melt_wf = {'CO2':CO2,"H2OT":H2O,"ST":ST,"X":XT,"HT":HT,"CT":CT}
886
+ PT["P"] = setup.loc[run,"P_bar"]
887
+ melt_wf["Fe3FeT"] = mg.Fe3FeT_i(PT,melt_wf,species,models)
888
+ C_CO32 = mdv.C_CO3(PT,melt_wf,species,models)
889
+ C_H2OT = mdv.C_H2O(PT,melt_wf,species,models)
890
+ C_S2 = mdv.C_S(PT,melt_wf,species,models)
891
+ C_S6 = mdv.C_SO4(PT,melt_wf,species,models)
892
+ C_H2S = mdv.C_H2S(PT,melt_wf,species,models)
893
+ C_H2 = mdv.C_H2(PT,melt_wf,species,models)
894
+ C_CO = mdv.C_CO(PT,melt_wf,species,models)
895
+ C_CH4 = mdv.C_CH4(PT,melt_wf,species,models)
896
+ C_X = mdv.C_X(PT,melt_wf,species,models)
897
+ fO2_ = mg.fO22Dbuffer(PT,mdv.f_O2(PT,melt_wf,species,models),"FMQ",models)
898
+ M_m = mg.M_m_SO(melt_wf,species)
899
+
900
+ ### store results ###
901
+ results2 = pd.DataFrame([[setup.loc[run,"Sample"],setup.loc[run,"P_bar"],setup.loc[run,"T_C"],setup.loc[run,"SiO2"],setup.loc[run,"TiO2"],setup.loc[run,"Al2O3"],mg.Wm_FeOT(run,setup,species),setup.loc[run,"MnO"],setup.loc[run,"MgO"],setup.loc[run,"CaO"],setup.loc[run,"Na2O"],setup.loc[run,"K2O"],setup.loc[run,"P2O5"],setup.loc[run,"H2O"],setup.loc[run,"CO2ppm"],setup.loc[run,"STppm"],melt_wf["Fe3FeT"],fO2_,gp.log(C_CO32),gp.log(C_H2OT),gp.log(C_S2),gp.log(C_S6),gp.log(C_H2S),gp.log(C_H2),gp.log(C_CO),gp.log(C_CH4),gp.log(C_X),M_m]])
902
+ results = pd.concat([results, results2], ignore_index=True)
903
+ if models.loc["output csv","option"] == "yes":
904
+ results.to_csv('capacities.csv', index=False, header=False)
905
+ if models.loc["print status","option"] == "yes":
906
+ print(n, setup.loc[run,"Sample"],gp.log(C_CO32),gp.log(C_H2OT),gp.log(C_S2),gp.log(C_S6),gp.log(C_H2S),gp.log(C_H2),gp.log(C_CO),gp.log(C_CH4),M_m)
907
+ return results
908
+
909
+
910
+ ##########################
911
+ ### Fe3+/Fe2+ from fO2 ###
912
+ ##########################
913
+
914
+ def Fe3Fe2_output(first_row,last_row,setup,species,models):
915
+ # set up results table
916
+ results = pd.DataFrame([["oxygen fugacity","carbon dioxide solubility","C speciation composition","water solubility","water speciation","water speciation composition","sulfide solubility","sulfate solubility","sulfide saturation","ideal gas","carbonylsulfide","mass_volume","insolubles","Date"]])
917
+ results1 = pd.DataFrame([[models.loc["fO2","option"],models.loc["carbon dioxide","option"],models.loc["Cspeccomp","option"],models.loc["water","option"],models.loc["Hspeciation","option"],models.loc["Hspeccomp","option"],models.loc["sulfide","option"],models.loc["sulfate","option"],models.loc["sulfur_saturation","option"],models.loc["ideal_gas","option"],models.loc["carbonylsulfide","option"],models.loc["mass_volume","option"],models.loc['insolubles','option'],date.today()]])
918
+ results = pd.concat([results, results1], ignore_index=True)
919
+ results1 = ([["Sample","Pressure (bar)","T ('C)","fO2 (DNNO)","fO2 (DFMQ)",
920
+ "SiO2 (wt%)","TiO2 (wt%)","Al2O3 (wt%)","FeOT (wt%)","MnO (wt%)","MgO (wt%)","CaO (wt%)","Na2O (wt%)","K2O (wt%)","P2O5 (wt%)","Fe3/FeT"]])
921
+ results = pd.concat([results, results1], ignore_index=True)
922
+
923
+ for n in range(first_row,last_row,1): # n is number of rows of data in conditions file
924
+ run = n
925
+
926
+ # check if any options need to be read from the setup file rather than the models file
927
+ models = options_from_setup(run,models,setup)
928
+
929
+ PT={"T":setup.loc[run,"T_C"]}
930
+ PT["P"] = setup.loc[run,"P_bar"]
931
+ melt_wf=mg.melt_comp(run,setup)
932
+ melt_wf['Fe3FeT'] = mg.Fe3FeT_i(run,PT,melt_wf,setup,species,models)
933
+ ### store results ###
934
+ results2 = pd.DataFrame([[setup.loc[run,"Sample"],PT["P"],
935
+ setup.loc[run,"T_C"],mg.fO22Dbuffer(PT,mdv.f_O2(PT,melt_wf,species,models),"NNO"),mg.fO22Dbuffer(PT,mdv.f_O2(PT,melt_wf,species,models),"FMQ"),setup.loc[run,"SiO2"],setup.loc[run,"TiO2"],setup.loc[run,"Al2O3"],mg.Wm_FeOT(run,setup,species),setup.loc[run,"MnO"],setup.loc[run,"MgO"],setup.loc[run,"CaO"],setup.loc[run,"Na2O"],setup.loc[run,"K2O"],setup.loc[run,"P2O5"],melt_wf['Fe3FeT']]])
936
+ results = pd.concat([results, results2], ignore_index=True)
937
+ if models.loc["output csv","option"] == "yes":
938
+ results.to_csv('Fe3FeT_outputs.csv', index=False, header=False)
939
+ if models.loc["print status","option"] == "yes":
940
+ print(n, setup.loc[run,"Sample"],melt_wf['Fe3FeT'])
941
+ return results
942
+
943
+
944
+ #############################
945
+ ### fugacity coefficients ###
946
+ #############################
947
+
948
+ def fugacity_coefficients(first_row,last_row,setup,species,models):
949
+ # set up results table
950
+ results = pd.DataFrame([["oxygen fugacity","carbon dioxide solubility","C speciation composition","water solubility","water speciation","water speciation composition","sulfide solubility","sulfate solubility","sulfide saturation","ideal gas","carbonylsulfide","mass_volume","insolubles","Date"]])
951
+ results1 = pd.DataFrame([[models.loc["fO2","option"],models.loc["carbon dioxide","option"],models.loc["Cspeccomp","option"],models.loc["water","option"],models.loc["Hspeciation","option"],models.loc["Hspeccomp","option"],models.loc["sulfide","option"],models.loc["sulfate","option"],models.loc["sulfur_saturation","option"],models.loc["ideal_gas","option"],models.loc["carbonylsulfide","option"],models.loc["mass_volume","option"],models.loc['insolubles','option'],date.today()]])
952
+ results = pd.concat([results, results1], ignore_index=True)
953
+ results1 = ([["Sample","Pressure (bar)","T ('C)","yH2O","yCO2","yH2","yCO","yO2","yCH4","yS2","ySO2","yH2S","yOCS"]])
954
+ results = pd.concat([results, results1], ignore_index=True)
955
+
956
+ for n in range(first_row,last_row,1): # n is number of rows of data in conditions file
957
+ run = n
958
+
959
+ # check if any options need to be read from the setup file rather than the models file
960
+ models = options_from_setup(run,models,setup)
961
+
962
+ PT={"T":setup.loc[run,"T_C"]}
963
+ PT["P"] = setup.loc[run,"P_bar"]
964
+
965
+ ### store results ###
966
+ results2 = pd.DataFrame([[setup.loc[run,"Sample"],PT["P"],setup.loc[run,"T_C"],mdv.y_H2O(PT,species,models),mdv.y_CO2(PT,species,models),mdv.y_H2(PT,species,models),mdv.y_CO(PT,species,models),mdv.y_O2(PT,species,models),mdv.y_CH4(PT,species,models),mdv.y_S2(PT,species,models),mdv.y_SO2(PT,species,models),mdv.y_H2S(PT,species,models),mdv.y_OCS(PT,species,models)]])
967
+ results = pd.concat([results, results2], ignore_index=True)
968
+ if models.loc["output csv","option"] == "yes":
969
+ results.to_csv('fugacity_coefficients_outputs.csv', index=False, header=False)
970
+ if models.loc["print status","option"] == "yes":
971
+ print(n, setup.loc[run,"Sample"],mdv.y_H2O(PT,species,models))
972
+ return results
973
+
974
+ ######################################
975
+ ### fO2 range from sulfur content ###
976
+ ######################################
977
+
978
+ def fO2_range_from_S_output(first_row,last_row,setup,species,models,p_tol,nr_step,nr_tol):
979
+
980
+ # set up results table
981
+ results = pd.DataFrame([["oxygen fugacity","carbon dioxide solubility","C speciation composition","water solubility","water speciation","water speciation composition","sulfide solubility","sulfate solubility","SCSS","SCAS","ideal gas","carbonylsulfide","insolubles","H2S","species X","species X solubility","Date"]])
982
+ results1 = pd.DataFrame([[models.loc["fO2","option"],models.loc["carbon dioxide","option"],models.loc["Cspeccomp","option"],models.loc["water","option"],models.loc["Hspeciation","option"],models.loc["Hspeccomp","option"],models.loc["sulfide","option"],models.loc["sulfate","option"],models.loc["SCSS","option"],models.loc["SCAS","option"],models.loc["ideal_gas","option"],models.loc["carbonylsulfide","option"],models.loc['insolubles','option'],models.loc["H2S_m","option"],models.loc['species X','option'],models.loc['species X solubility','option'],date.today()]])
983
+ results = pd.concat([results, results1], ignore_index=True)
984
+ results1 = pd.DataFrame([["Sample","T ('C)","wm_STppm","wm_H2OT","wm_CO2ppm","P (bar) sulf","S2- SCSS","sulfide saturated?","DFMQ-sulfide","fO2-sulfide","Fe3FeT-sulfide","S6ST-sulfide","P (bar) anh","S6+ SCAS","sulfate saturated?","DFMQ-sulfate","fO2-sulfate","Fe3FeT-sulfate","S6ST-sulfate"]])
985
+ results = pd.concat([results, results1], ignore_index=True)
986
+
987
+ # run over rows in file
988
+ for n in range(first_row,last_row,1): # number of rows in the table
989
+
990
+ # Select run conditions
991
+ run = n # row number
992
+
993
+ # check if any options need to be read from the setup file rather than the models file
994
+ models = options_from_setup(run,models,setup)
995
+
996
+ PT = {"T":setup.loc[run,"T_C"]}
997
+ melt_wf=mg.melt_comp(run,setup)
998
+ melt_wf["H2OT"] = (setup.loc[run, "H2O"]/100.)
999
+ melt_wf["CO2"] = setup.loc[run, "CO2ppm"]/1000000.
1000
+ melt_wf["HT"] = ((setup.loc[run, "H2O"]/100.)/species.loc["H2O","M"])*species.loc["H2","M"]
1001
+ if setup.loc[run,"P_bar"] > 0.:
1002
+ PT["P"] = setup.loc[run,"P_bar"]
1003
+ P_sat_sulf, P_sat_anh = setup.loc[run,"P_bar"],setup.loc[run,"P_bar"]
1004
+ melt_wf["Fe3FeT"] = setup.loc[run, "Fe3FeT"]
1005
+ SCAS_,SCSS_,sulfide_sat,DFMQ_1,fO2_1,Fe3FeT_1,S6ST_1,sulfate_sat,DFMQ_2,fO2_2,Fe3FeT_2,S6ST_2 = c.fO2_range_from_S(PT,melt_wf,species,models)
1006
+ else:
1007
+ melt_wf["ST"] = setup.loc[run, "STppm"]/1000000.
1008
+ melt_wf["XT"] = setup.loc[run, "Xppm"]/1000000.
1009
+ melt_wf["CT"] = ((setup.loc[run, "CO2ppm"]/1000000.)/species.loc["CO2","M"])*species.loc["C","M"]
1010
+ P_sat_sulf,P_sat_anh,SCAS_,SCSS_,sulfide_sat,DFMQ_1,fO2_1,Fe3FeT_1,S6ST_1,sulfate_sat,DFMQ_2,fO2_2,Fe3FeT_2,S6ST_2 = c.P_sat_sulf_anh(PT,melt_wf,species,models,p_tol,nr_step,nr_tol)
1011
+
1012
+ # store results
1013
+ results1 = pd.DataFrame([[setup.loc[run,"Sample"],PT["T"],setup.loc[run,"STppm"],setup.loc[run,"H2O"],setup.loc[run,"CO2ppm"],P_sat_sulf,SCSS_,sulfide_sat,DFMQ_1,fO2_1,Fe3FeT_1,S6ST_1,P_sat_anh,SCAS_,sulfate_sat,DFMQ_2,fO2_2,Fe3FeT_2,S6ST_2]])
1014
+ results = pd.concat([results, results1], ignore_index=True)
1015
+ if models.loc["output csv","option"] == "yes":
1016
+ results.to_csv('fO2_range_from_S.csv', index=False, header=False)
1017
+ if models.loc["print status","option"] == "yes":
1018
+ print(setup.loc[run,"Sample"])
1019
+ return results
1020
+
1021
+ ############################################
1022
+ ### melt-vapour equilibrium at given fO2 ###
1023
+ ############################################
1024
+
1025
+ def eq_given_fO2(inputs,setup,species,models): # only S atm
1026
+
1027
+ option = inputs["option"]
1028
+
1029
+ # set T, volatile composition of the melt, and tolerances
1030
+ #nr_step = inputs["nr_step"]
1031
+ #nr_tol = inputs["nr_tol"]
1032
+
1033
+ if option == "loop":
1034
+ run = inputs["run"]
1035
+ PT={'T':setup.loc[run,"T_C"]}
1036
+ melt_wf=mg.melt_comp(run,setup)
1037
+ melt_wf['CO2'] = setup.loc[run,"CO2ppm"]/1000000.
1038
+ melt_wf["H2OT"] = setup.loc[run,"H2O"]/100.
1039
+ melt_wf["ST"] = setup.loc[run,"STppm"]/1000000.
1040
+ melt_wf["H2"] = 0.
1041
+ step = inputs["dfO2_step"]
1042
+ initial = inputs["fO2_i"]
1043
+ final = inputs["fO2_f"]
1044
+ start = 0
1045
+ end = inputs["no_steps"]
1046
+ difference = (final - initial) + 1
1047
+ step_size = difference/end
1048
+ # Set bulk composition
1049
+ wt_C = (melt_wf["CO2"]/species.loc["CO2","M"])*species.loc["C","M"]
1050
+ wt_H = (melt_wf["H2OT"]/species.loc["H2O","M"])*(2.*species.loc["H","M"])
1051
+ wt_S = melt_wf["ST"]
1052
+ bulk_wf = {"C":wt_C,"H":wt_H,"S":wt_S}
1053
+ system = eq.set_system(bulk_wf,models)
1054
+
1055
+ elif option == "spreadsheet":
1056
+ start = inputs["first row"]
1057
+ end = inputs["last row"]
1058
+
1059
+ # update Fe3+/FeT and water speciation at saturation pressure and check for sulfur saturation
1060
+ #melt_wf["Fe3FeT"] = mg.fO22Fe3FeT(10.**initial,run,PT,setup,species,models)
1061
+ #melt_wf["Fe3FeT"] = mg.Fe3FeT_i(run,PT,melt_wf,setup,species,models)
1062
+ #melt_wf["S6ST"] = mg.S6ST(run,PT,melt_wf,setup,species,models)
1063
+ #melt_wf["H2Omol"] = 0. #mg.wm_H2Omol(run,PT,melt_wf,setup,species,models)
1064
+ #melt_wf["OH"] = 0., #mg.wm_OH(run,PT,melt_wf,setup,species,models)
1065
+ #SCSS_,sulfide_sat,SCAS_,sulfate_sat,ST_ = sulfur_saturation(run,PT,melt_wf,setup,species,models)
1066
+
1067
+
1068
+ # create results table
1069
+ results_header1 = pd.DataFrame([["oxygen fugacity","carbon dioxide solubility","C speciation composition","water solubility","water speciation","water speciation composition","sulfide solubility","sulfur speciation","ideal gas","carbonylsulfide","bulk composition","equilibrate Fe","starting pressure","gassing direction","gassing style","mass_volume","crystallisation","isotopes","Date"]])
1070
+ results_header2 = pd.DataFrame([[
1071
+ models.loc["fO2","option"],models.loc["carbon dioxide","option"],models.loc["Cspeccomp","option"],models.loc["water","option"],models.loc["Hspeciation","option"],models.loc["Hspeccomp","option"],models.loc["sulfide","option"],models.loc["sulfate","option"],models.loc["ideal_gas","option"],models.loc["carbonylsulfide","option"],models.loc["bulk_composition","option"],models.loc["eq_Fe","option"],models.loc["starting_P","option"],models.loc["gassing_direction","option"],models.loc["gassing_style","option"],models.loc["mass_volume","option"],models.loc["crystallisation","option"],models.loc["isotopes","option"],date.today()]])
1072
+ results_header = pd.concat([results_header1, results_header2], ignore_index=True)
1073
+ results_chemistry1 = pd.DataFrame([["P","T('C)","System","run","Sample","H2O (mwf)","CO2 (mwf)","ST (mwf)","Fe3FeT","S6ST","O (twf)","C (twf)","H (wtf)","S (twf)","Fe (twf)",
1074
+ "SiO2 (wt%)","TiO2 (wt%)","Al2O3 (wt%)","FeOT (wt%)","MnO (wt%)","MgO (wt%)","CaO (wt%)","Na2O (wt%)","K2O (wt%)","P2O5 (wt%)","xg_O2","xg_CO","xg_CO2","xg_H2","xg_H2O","xg_CH4","xg_S2","xg_SO2","xg_SO3","xg_H2S","xg_OCS","Xg_t",
1075
+ "xm_CO2","xm_H2O","xm_H2Omol","xm_OH","xm_H2","Xm_t_SO","Xm_t_ox",
1076
+ "wm_CO2","wm_H2O","wm_H2Omol","wm_OH","wm_H2","wm_S","wm_SO3","wm_ST","Fe3T","S6T",
1077
+ "DFMQ","DNNO","SCSS","sulfide sat?","SCAS","sulfate sat?","wt_g","wt_O","wt_C","wt_H","wt_S",
1078
+ "fO2","fH2","fH2O","fS2","fSO2","fSO3","fH2S","fCO2","fCO","fCH4","fOCS",
1079
+ "yO2","yH2","yH2O","yS2","ySO2","ySO3","yH2S","yCO2","yCO","yCH4","yOCS",
1080
+ "M_m_SO","M_m_ox","C_H2O","C_H2","C_CO3","C_S","C_SO4",
1081
+ "KD1","KHOg","KHOm","KHOSg","KCOg","KCOHg","KOCSg","KSOg","KSOg2"]])
1082
+ results_chemistry = pd.concat([results_header, results_chemistry1], ignore_index=True)
1083
+
1084
+
1085
+ # run over different fO2 #
1086
+ for i in range(start,end,1):
1087
+ if option == "loop":
1088
+ i_ = (i*step_size)+initial # fO2 in log units
1089
+ fO2_ = 10.**i_
1090
+ PT["P"] = inputs["P"]
1091
+ if models.loc["print status","option"] == "yes":
1092
+ print(setup.loc[run,"Sample"],fO2_)
1093
+ elif option == "spreadsheet":
1094
+ run = i
1095
+ PT={'T':setup.loc[run,"T_C"]}
1096
+ melt_wf=mg.melt_comp(run,setup)
1097
+ melt_wf['CO2'] = setup.loc[run,"CO2ppm"]/1000000.
1098
+ melt_wf["H2OT"] = setup.loc[run,"H2O"]/100.
1099
+ melt_wf["ST"] = setup.loc[run,"STppm"]/1000000.
1100
+ melt_wf["H2"] = 0.
1101
+ PT["P"] = setup.loc[run,"P_bar"]
1102
+ melt_wf['Fe3FeT'] = mg.Fe3FeT_i(PT,melt_wf,species,models)
1103
+ fO2_ = mdv.f_O2(PT,melt_wf,species,models)
1104
+ # Set bulk composition
1105
+ wt_C = (melt_wf["CO2"]/species.loc["CO2","M"])*species.loc["C","M"]
1106
+ wt_H = (melt_wf["H2OT"]/species.loc["H2O","M"])*(2.*species.loc["H","M"])
1107
+ wt_S = melt_wf["ST"]
1108
+ bulk_wf = {"C":wt_C,"H":wt_H,"S":wt_S,"CT":wt_C,"HT":wt_H,"ST":wt_S}
1109
+ system = eq.set_system(bulk_wf,models)
1110
+ if models.loc["print status","option"] == "yes":
1111
+ print(setup.loc[run,"Sample"],fO2_,PT["P"])
1112
+
1113
+ # work out equilibrium partitioning between melt and gas phase
1114
+ melt_wf["Fe3FeT"] = mg.fO22Fe3FeT(fO2_,PT,species,models)
1115
+ Fe3T = melt_wf["Fe3FeT"]
1116
+ #xg_S2_, result1, result2, result3 = eq.eq_SOFe_fO2(run,PT,10.**i_,bulk_wf,melt_wf,species,setup,models,nr_step,nr_tol,guessx)
1117
+ #xg_SO2_, xg_O2_, Xg_t, Fe32, Fe3T, wm_S_, wm_SO3_, S62, S6T, wm_ST_ = result1
1118
+ #wt_g, wt_O_, wt_S_ = result3
1119
+ #guessx = xg_S2_
1120
+ #xg_O2_, xg_S2_, xg_SO2_, wm_S_, wm_SO3_, wm_ST_, S6T, Xg_t = eq.S_P_fO2_1(run,PT,fO2_,melt_wf,setup,species,models)
1121
+ #wm_CO2_, xm_CO2_, wm_H2O_, xm_H2O_, wm_H2_, xm_H2_, wm_H2Omol_, xm_H2Omol_, wm_OH_, xm_OH_, xg_CO_, xg_CO2_, xg_H2_, xg_H2O_, xg_CH4_, xg_H2S_, xg_OCS_, xg_SO3_, Xm_t, Xm_t_ox, wt_C_, wt_H_, wt_g = 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.
1122
+ xg_O2_, xg_S2_, xg_SO2_, xg_SO3_, xg_H2_, xg_H2O_, xg_H2S_, xg_CO_, xg_CO2_, xg_CH4_, xg_OCS_, wm_S_, wm_SO3_, wm_ST_, S6T, wm_H2O_, xm_H2O_, wm_H2_, xm_H2_, wm_H2Omol_, xm_H2Omol_, wm_OH_, xm_OH_, wm_CO2_, xm_CO2_, Xg_t, Xm_t, Xm_t_ox, wt_C_, wt_H_, wt_S_, wt_g = eq.S_P_fO2(PT,fO2_,melt_wf,species,models)
1123
+
1124
+ # set melt composition for forward calculation
1125
+ melt_wf = {"CO2":wm_CO2_,"H2OT":wm_H2O_,"ST":wm_ST_,"S6ST":S6T,"Fe3FeT":Fe3T,"H2":wm_H2_,"H2Omol":wm_H2Omol_,"OH":wm_OH_,"S2-":wm_S_}
1126
+
1127
+ # check for sulfur saturation and display warning in outputs
1128
+ SCSS_,sulfide_sat,SCAS_,sulfate_sat, ST_ = sulfur_saturation(PT,melt_wf,species,models)
1129
+ if sulfide_sat == "yes":
1130
+ warning = "WARNING: sulfide-saturated"
1131
+ elif sulfate_sat == "yes":
1132
+ warning = "WARNING: sulfate-saturated"
1133
+ else:
1134
+ warning = ""
1135
+
1136
+ # store results
1137
+
1138
+ results2 = pd.DataFrame([[PT["P"],PT["T"],system,run,setup.loc[run,"Sample"],melt_wf["H2OT"],melt_wf["CO2"],melt_wf["ST"],melt_wf["Fe3FeT"],"SORT","SORT",bulk_wf["C"],bulk_wf["H"],bulk_wf["S"],"SORT",
1139
+ setup.loc[run,"SiO2"],setup.loc[run,"TiO2"],setup.loc[run,"Al2O3"],mg.Wm_FeOT(melt_wf,species),setup.loc[run,"MnO"],setup.loc[run,"MgO"],setup.loc[run,"CaO"],setup.loc[run,"Na2O"],setup.loc[run,"K2O"],setup.loc[run,"P2O5"],xg_O2_,xg_CO_,xg_CO2_,xg_H2_,xg_H2O_,xg_CH4_,xg_S2_,xg_SO2_,xg_SO3_,xg_H2S_,xg_OCS_,Xg_t,
1140
+ xm_CO2_,xm_H2O_,xm_H2Omol_,xm_OH_,xm_H2_,Xm_t,Xm_t_ox,
1141
+ wm_CO2_,wm_H2O_,wm_H2Omol_,wm_OH_,wm_H2_,wm_S_,wm_SO3_,wm_ST_,Fe3T,S6T,
1142
+ mg.fO22Dbuffer(PT,fO2_,"FMQ"),mg.fO22Dbuffer(PT,fO2_,"NNO"),SCSS_,sulfide_sat,SCAS_,sulfate_sat,
1143
+ wt_g,"SORT",wt_C,wt_H,wt_S,
1144
+ fO2_,mg.f_H2(PT,melt_wf,species,models),mg.f_H2O(PT,melt_wf,species,models),mg.f_S2(PT,melt_wf,species,models),mg.f_SO2(PT,melt_wf,species,models),mg.f_SO3(PT,melt_wf,species,models),mg.f_H2S(PT,melt_wf,species,models),mg.f_CO2(PT,melt_wf,species,models),mg.f_CO(PT,melt_wf,species,models),mg.f_CH4(PT,melt_wf,species,models),mg.f_OCS(PT,melt_wf,species,models),
1145
+ mg.y_O2(PT,species,models),mg.y_H2(PT,species,models),mg.y_H2O(PT,species,models),mg.y_S2(PT,species,models),mg.y_SO2(PT,species,models),mg.y_SO3(PT,species,models),mdv.y_H2S(PT,species,models),mg.y_CO2(PT,species,models),mg.y_CO(PT,species,models),mg.y_CH4(PT,species,models),mg.y_OCS(PT,species,models),
1146
+ mg.M_m_SO(melt_wf,species),mg.M_m_ox(melt_wf,species,models),mg.C_H2O(PT,melt_wf,species,models),mg.C_H2(PT,melt_wf,species,models),mdv.C_CO3(PT,melt_wf,species,models),mg.C_S(PT,melt_wf,species,models),mg.C_SO4(PT,melt_wf,species,models),
1147
+ mg.KD1(PT,melt_wf,species,models),mg.KHOg(PT,models),mg.KHOm(PT,melt_wf,species,models),mg.KHOSg(PT,models),mg.KCOg(PT,models),mg.KCOHg(PT,models),mg.KOCSg(PT,models),mg.KOSg(PT,models),mg.KOSg2(PT,models)]])
1148
+ results_chemistry = pd.concat([results_chemistry, results2], ignore_index=True)
1149
+ if models.loc["output csv","option"] == "yes":
1150
+ results_chemistry.to_csv('results_fO2_chemistry.csv', index=False, header=False)
1151
+ return results_chemistry
1152
+
1153
+ ##############################################
1154
+ ### fO2 of silm+sulfm+anh at given T and P ###
1155
+ ##############################################
1156
+
1157
+ def fO2_SSA_output(first_row,last_row,setup,species,models):
1158
+ # set up results table
1159
+ results = pd.DataFrame([["Sample","P (bar)","T ('C)","fO2 (DFMQ)",
1160
+ "SiO2 (wt%)","TiO2 (wt%)","Al2O3 (wt%)","FeOT (wt%)","MnO (wt%)","MgO (wt%)","CaO (wt%)","Na2O (wt%)","K2O (wt%)","P2O5 (wt%)",
1161
+ "H2OT (wt%)","CO2 (ppm)","ST (ppm)","SCSS (ppm)","SCAS (ppm)", "S6+/ST","Fe3+/FeT"]])
1162
+
1163
+ for n in range(first_row,last_row,1): # n is number of rows of data in conditions file
1164
+ run = n
1165
+
1166
+ # check if any options need to be read from the setup file rather than the models file
1167
+ models = options_from_setup(run,models,setup)
1168
+
1169
+ PT={"T":setup.loc[run,"T_C"], "P":setup.loc[run,"P_bar"]}
1170
+ melt_wf = {'CO2':setup.loc[run,"CO2ppm"]/1000000.,"H2OT":setup.loc[run,"H2O"]/100.,"Fe3FeT":0.}
1171
+
1172
+ fO2, DFMQ, wmST, S6ST, S6, S2 = c.fO2_silm_sulf_anh(run,PT,melt_wf,setup,species,models)
1173
+
1174
+ Fe3FeT_n0 = melt_wf["Fe3FeT"]
1175
+ Fe3FeT_n1 = mdv.fO22Fe3FeT(fO2,run,PT,setup,species,models)
1176
+
1177
+ if ((Fe3FeT_n0 - Fe3FeT_n1)**2)**0.5 > 0.01:
1178
+ melt_wf["Fe3FeT"] = Fe3FeT_n1
1179
+ fO2, DFMQ, wmST, S6ST, S6, S2 = c.fO2_silm_sulf_anh(run,PT,melt_wf,setup,species,models)
1180
+ Fe3FeT_n0 = melt_wf["Fe3FeT"]
1181
+ Fe3FeT_n1 = mdv.fO22Fe3FeT(fO2,run,PT,setup,species,models)
1182
+
1183
+ ### store results ###
1184
+ results2 = pd.DataFrame([[setup.loc[run,"Sample"],PT["P"],setup.loc[run,"T_C"],DFMQ,setup.loc[run,"SiO2"],setup.loc[run,"TiO2"],setup.loc[run,"Al2O3"],mg.Wm_FeOT(run,setup,species),setup.loc[run,"MnO"],setup.loc[run,"MgO"],setup.loc[run,"CaO"],setup.loc[run,"Na2O"],setup.loc[run,"K2O"],setup.loc[run,"P2O5"],
1185
+ setup.loc[run,"H2O"],setup.loc[run,"CO2ppm"],wmST, S2, S6, S6ST, melt_wf["Fe3FeT"]]])
1186
+ results = pd.concat([results, results2], ignore_index=True)
1187
+ if models.loc["output csv","option"] == "yes":
1188
+ results.to_csv('fO2_silm_sulf_anh.csv', index=False, header=False)
1189
+ if models.loc["print status","option"] == "yes":
1190
+ print(n, setup.loc[run,"Sample"],PT["P"])
1191
+ return results
1192
+
1193
+ ##############################################
1194
+ ### S content at given T, P, fO2, C, and H ###
1195
+ ##############################################
1196
+
1197
+ def S_given_T_P_fO2_C_H_output(first_row,last_row,setup,species,models,nr_step,nr_tol):
1198
+
1199
+ if models.loc["H2S_m","option"] != "no":
1200
+ raise TypeError("This calculation assumes H2S is insoluble in the melt")
1201
+
1202
+ for n in range(first_row,last_row,1): # n is number of rows of data in conditions file
1203
+ run = n
1204
+
1205
+ # check if any options need to be read from the setup file rather than the models file
1206
+ models = options_from_setup(run,models,setup)
1207
+
1208
+ PT={"T":setup.loc[run,"T_C"], "P":setup.loc[run,"P_bar"]}
1209
+ melt_wf=mg.melt_comp(run,setup)
1210
+ melt_wf['CO2']= setup.loc[run,"CO2ppm"]/1000000.
1211
+ melt_wf["H2OT"] = setup.loc[run,"H2O"]/100.
1212
+ melt_wf["XT"] = setup.loc[run,"Xppm"]/1000000.
1213
+ melt_wf["ST"] = 0.
1214
+ melt_wf["CT"] = (melt_wf["CO2"]*species.loc['C','M'])/species.loc['CO2','M']
1215
+ melt_wf["HT"] = (melt_wf["H2OT"]*species.loc['H','M'])/species.loc['H2O','M']
1216
+ melt_wf["Fe3FeT"] = mg.Fe3FeT_i(PT,melt_wf,species,models)
1217
+
1218
+ conc, frac = c.S_given_T_P_fO2_C_H(PT,melt_wf,species,models,nr_step,nr_tol)
1219
+ melt_wf["ST"] = conc["wm_ST"]
1220
+ melt_wf["S2-"] = conc["wm_S2m"]
1221
+ melt_comp = mg.melt_normalise_wf(melt_wf,species,"yes","no")
1222
+ sulf_sat_result = c.sulfur_saturation(PT,melt_wf,species,models)
1223
+
1224
+ # create results
1225
+ results_headers_table_sample_name, results_values_table_sample_name = results_table_sample_name(setup,run)
1226
+ results_headers_table_melt_comp_etc, results_values_table_melt_comp_etc = results_table_melt_comp_etc(PT,melt_comp,conc,frac,melt_wf)
1227
+ results_headers_table_model_options, results_values_table_model_options = results_table_model_options(models)
1228
+ results_headers_table_f_p_xg_y_M_C_K_d, results_values_table_f_p_xg_y_M_C_K_d = results_table_f_p_xg_y_M_C_K_d(PT,melt_wf,species,models)
1229
+ results_headers_table_sat, results_values_table_sat = results_table_sat(sulf_sat_result,PT,melt_wf,species,models)
1230
+ results_headers_table_melt_vol = results_table_melt_vol() # "H2OT-eq_wtpc","CO2T-eq_ppmw","ST_ppmw","X_ppmw"
1231
+ results_values_table_melt_vol = pd.DataFrame([[setup.loc[run,"H2O"],setup.loc[run,"CO2ppm"],conc["wm_ST"]*1000000.,setup.loc[run,"Xppm"]]])
1232
+ results_headers = pd.concat([results_headers_table_sample_name,results_headers_table_melt_comp_etc,results_headers_table_melt_vol,results_headers_table_sat,results_headers_table_f_p_xg_y_M_C_K_d,results_headers_table_model_options],axis=1)
1233
+ results1 = pd.concat([results_values_table_sample_name,results_values_table_melt_comp_etc,results_values_table_melt_vol,results_values_table_sat,results_values_table_f_p_xg_y_M_C_K_d,results_values_table_model_options],axis=1)
1234
+
1235
+ if n == first_row:
1236
+ results = pd.concat([results_headers, results1])
1237
+ else:
1238
+ results = pd.concat([results, results1])
1239
+
1240
+ if models.loc["print status","option"] == "yes":
1241
+ print(n, setup.loc[run,"Sample"],PT["P"])
1242
+
1243
+ results.columns = results.iloc[0]
1244
+ results = results[1:]
1245
+ if models.loc["output csv","option"] == "yes":
1246
+ results.to_csv('results_S_given_T_P_fO2_C_H.csv', index=False, header=True)
1247
+
1248
+ return results
1249
+
1250
+ ########################################
1251
+ ### measured parameters within error ###
1252
+ ########################################
1253
+
1254
+
1255
+ def compositions_within_error_output(setup,run,iterations):
1256
+
1257
+ # set up results table
1258
+ results = pd.DataFrame([["Sample","T_C",
1259
+ "SiO2","TiO2","Al2O3","FeOT","MnO","MgO","CaO","Na2O","K2O","P2O5",
1260
+ "H2OT","CO2ppm","STppm","Fe3FeT"]])
1261
+ results1 = pd.DataFrame([[setup.loc[run,"Sample"],setup.loc[run,"T_C"],setup.loc[run,"SiO2"],setup.loc[run,"TiO2"],setup.loc[run,"Al2O3"],setup.loc[run,"FeOT"],setup.loc[run,"MnO"],setup.loc[run,"MgO"],setup.loc[run,"CaO"],setup.loc[run,"Na2O"],setup.loc[run,"K2O"],setup.loc[run,"P2O5"],
1262
+ setup.loc[run,"H2O"],setup.loc[run,"CO2ppm"],setup.loc[run,"STppm"], setup.loc[run,"Fe3FeT"]]])
1263
+
1264
+ results = pd.concat([results, results1], ignore_index=True)
1265
+ results1 = pd.DataFrame([["sds","",setup.loc[run,"SiO2_sd"],setup.loc[run,"TiO2_sd"],setup.loc[run,"Al2O3_sd"],setup.loc[run,"FeOT_sd"],setup.loc[run,"MnO_sd"],setup.loc[run,"MgO_sd"],setup.loc[run,"CaO_sd"],setup.loc[run,"Na2O_sd"],setup.loc[run,"K2O_sd"],setup.loc[run,"P2O5_sd"],
1266
+ setup.loc[run,"H2O_sd"],setup.loc[run,"CO2ppm_sd"],setup.loc[run,"STppm_sd"], setup.loc[run,"Fe3FeT_sd"]]])
1267
+
1268
+ results = pd.concat([results, results1], ignore_index=True)
1269
+ results1 = pd.DataFrame([["sd types","",setup.loc[run,"SiO2_sd_type"],setup.loc[run,"TiO2_sd_type"],setup.loc[run,"Al2O3_sd_type"],setup.loc[run,"FeOT_sd_type"],setup.loc[run,"MnO_sd_type"],setup.loc[run,"MgO_sd_type"],setup.loc[run,"CaO_sd_type"],setup.loc[run,"Na2O_sd_type"],setup.loc[run,"K2O_sd_type"],setup.loc[run,"P2O5_sd_type"],
1270
+ setup.loc[run,"H2O_sd_type"],setup.loc[run,"CO2ppm_sd_type"],setup.loc[run,"STppm_sd_type"], setup.loc[run,"Fe3FeT_sd_type"]]])
1271
+
1272
+ results = pd.concat([results, results1], ignore_index=True)
1273
+ for n in range(0,iterations,1): # n is number of rows of data in conditions file
1274
+ SiO2,TiO2,Al2O3,FeOT,MnO,MgO,CaO,Na2O,K2O,P2O5,H2O,CO2ppm,STppm,Fe3FeT = c.compositions_within_error(run,setup)
1275
+ results1 = pd.DataFrame([[run,setup.loc[run,"T_C"],SiO2,TiO2,Al2O3,FeOT,MnO,MgO,CaO,Na2O,K2O,P2O5,H2O,CO2ppm,STppm,Fe3FeT]])
1276
+ results = pd.concat([results, results1], ignore_index=True)
1277
+ if models.loc["output csv","option"] == "yes":
1278
+ results.to_csv('random_compositions.csv', index=False, header=False)
1279
+ if models.loc["print status","option"] == "yes":
1280
+ print(n, setup.loc[run,"Sample"],SiO2)
1281
+
1282
+ return results
1283
+
1284
+ ##################################################################################
1285
+ ### vapor undersaturated cooling for S2-, S6+, Fe3+, Fe2+, H2OT, CO32- cooling ###
1286
+ ##################################################################################
1287
+
1288
+ def cooling(run,cooling_inputs,setup,species,models):
1289
+
1290
+ if models.loc["print status","option"] == "yes":
1291
+ print(setup.loc[run,"Sample"])
1292
+
1293
+ # check if any options need to be read from the setup file rather than the models file
1294
+ models = options_from_setup(run,models,setup)
1295
+
1296
+ # set T, volatile composition of the melt, and tolerances
1297
+ PT={"P":setup.loc[run,"P_bar"]}
1298
+ PT["T"]=setup.loc[run,"T_C"]
1299
+ melt_wf = {'CO2':setup.loc[run,"CO2ppm"]/1000000.,"H2OT":setup.loc[run,"H2O"]/100.,"H2":0.}
1300
+ melt_wf["CT"] = (melt_wf["CO2"]/species.loc["CO2","M"])*species.loc["C","M"]
1301
+ melt_wf["HT"] = (2.*melt_wf["H2OT"]/species.loc["H2O","M"])*species.loc["H","M"]
1302
+ nr_step = cooling_inputs["nr_step"]
1303
+ nr_tol = cooling_inputs["nr_tol"]
1304
+ dt_step = cooling_inputs["dt_step"]
1305
+ psat_tol = cooling_inputs["psat_tol"]
1306
+
1307
+ # Calculate S and Fe composition at initial T and check for sulfur saturation
1308
+ melt_wf["Fe3FeT"] = mg.Fe3FeT_i(run,PT,melt_wf,setup,species,models)
1309
+ Fe3Fe2_ = mg.Fe3Fe2(melt_wf)
1310
+ melt_wf["CO"] = 0.
1311
+ melt_wf["CH4"] = 0.
1312
+ melt_wf["H2S"] = 0.
1313
+ wm_H2_, wm_CH4_, wm_H2S_, wm_CO_ = 0., 0., 0., 0.
1314
+
1315
+ if models.loc["bulk_O","option"] == "inc S":
1316
+ melt_wf["ST"] = setup.loc[run,"STppm"]/1000000.
1317
+ melt_wf["S6ST"] = mg.S6ST(run,PT,melt_wf,setup,species,models)
1318
+ melt_wf["S2-"] = (1.-melt_wf["S6ST"])*melt_wf["ST"]
1319
+ melt_wf["S6+"] = melt_wf["S6ST"]*melt_wf["ST"]
1320
+ elif models.loc["bulk_O","option"] == "exc S":
1321
+ melt_wf["ST"] = 0.
1322
+ melt_wf["S2-"] = 0.
1323
+ melt_wf["S6+"] = 0.
1324
+
1325
+ SCSS_,sulfide_sat,SCAS_,sulfate_sat,ST_ = c.sulfur_saturation(run,PT,melt_wf,setup,species,models)
1326
+ wm_S2m_ = melt_wf["S2-"]
1327
+ wm_S6p_ = melt_wf["S6+"]
1328
+ wm_SO3_ = (wm_S6p_/(species.loc["S","M"]))*(species.loc["S","M"] + 3.*species.loc["O","M"])
1329
+
1330
+ # Set bulk composition
1331
+ wt_C, wt_O, wt_H, wt_S, wt_Fe, wt_g_, Wt_ = c.bulk_composition(run,PT,melt_wf,setup,species,models)
1332
+
1333
+ if models.loc["bulk_O","option"] == "exc S":
1334
+ melt_wf["ST"] = setup.loc[run,"STppm"]/1000000.
1335
+ melt_wf["S6ST"] = mg.S6ST(run,PT,melt_wf,setup,species,models)
1336
+ melt_wf["S2-"] = (1.-melt_wf["S6ST"])*melt_wf["ST"]
1337
+ melt_wf["S6+"] = melt_wf["S6ST"]*melt_wf["ST"]
1338
+ wt_S = melt_wf["ST"]
1339
+
1340
+ bulk_wf = {"C":wt_C,"H":wt_H,"O":wt_O,"S":wt_S,"Fe":wt_Fe,"Wt":Wt_}
1341
+
1342
+ # set system and initial guesses
1343
+ system = eq.set_system(melt_wf,models)
1344
+ guessx = mdv.f_O2(run,PT,melt_wf,setup,species,models)
1345
+
1346
+ if models.loc["bulk_O","option"] == "exc S":
1347
+ fO2_, A, B, C = eq.eq_SOFe_melt(run,PT,bulk_wf,melt_wf,species,setup,models,nr_step/10.,nr_tol,guessx)
1348
+ Fe32, Fe3T, S62, S6T = A
1349
+ melt_wf["S6ST"] = S6T
1350
+ melt_wf["Fe3FeT"] = Fe3T
1351
+ melt_wf["S2-"] = (1.-melt_wf["S6ST"])*melt_wf["ST"]
1352
+ melt_wf["S6+"] = melt_wf["S6ST"]*melt_wf["ST"]
1353
+ guessx = mdv.f_O2(run,PT,melt_wf,setup,species,models)
1354
+
1355
+ # create results table
1356
+ results_header1 = pd.DataFrame([["System","run","Sample","H2O (mwf)","CO2 (mwf)","ST (mwf)","Fe3FeT","S6ST","O (twf)","C (twf)","H (wtf)","S (twf)","Fe (twf)",
1357
+ "SiO2 (wt%)","TiO2 (wt%)","Al2O3 (wt%)","FeOT (wt%)","MnO (wt%)","MgO (wt%)","CaO (wt%)","Na2O (wt%)","K2O (wt%)","P2O5 (wt%)",
1358
+ "oxygen fugacity","carbon dioxide solubility","C speciation composition","water solubility","water speciation","water speciation composition","sulfide solubility","sulfate solubility","ideal gas","carbonylsulfide","bulk composition","equilibrate Fe","starting pressure","gassing direction","gassing style","mass_volume","crystallisation","isotopes","Date"]])
1359
+ results_header2 = pd.DataFrame([[system,run,setup.loc[run,"Sample"],melt_wf["H2OT"],melt_wf["CO2"],melt_wf["ST"],melt_wf["Fe3FeT"],"SORT",bulk_wf["O"],bulk_wf["C"],bulk_wf["H"],bulk_wf["S"],bulk_wf["Fe"],
1360
+ setup.loc[run,"SiO2"],setup.loc[run,"TiO2"],setup.loc[run,"Al2O3"],mg.Wm_FeOT(run,setup,species),setup.loc[run,"MnO"],setup.loc[run,"MgO"],setup.loc[run,"CaO"],setup.loc[run,"Na2O"],setup.loc[run,"K2O"],setup.loc[run,"P2O5"],
1361
+ models.loc["fO2","option"],models.loc["carbon dioxide","option"],models.loc["Cspeccomp","option"],models.loc["water","option"],models.loc["Hspeciation","option"],models.loc["Hspeccomp","option"],models.loc["sulfide","option"],models.loc["sulfate","option"],models.loc["ideal_gas","option"],models.loc["carbonylsulfide","option"],models.loc["bulk_composition","option"],models.loc["eq_Fe","option"],models.loc["starting_P","option"],models.loc["gassing_direction","option"],models.loc["gassing_style","option"],models.loc["mass_volume","option"],models.loc["crystallisation","option"],models.loc["isotopes","option"],date.today()]])
1362
+ results_header = pd.concat([results_header1, results_header2], ignore_index=True)
1363
+ results_chemistry1 = pd.DataFrame([["P","T('C)","xg_O2","xg_CO","xg_CO2","xg_H2","xg_H2O","xg_CH4","xg_S2","xg_SO2","xg_H2S","xg_OCS","Xg_t",
1364
+ "xm_CO2","xm_H2O","Xm_t_SO","Xm_t_ox",
1365
+ "wm_CO2","wm_H2O","wm_H2","wm_CO","wm_CH4","wm_S","wm_SO3","wm_H2S","wm_ST","Fe32","Fe3T","S62","S6T",
1366
+ "DFMQ","DNNO","SCSS","sulfide sat?","SCAS","sulfate sat?","wt_g","wt_g_O","wt_g_C","wt_g_H","wt_g_S","wt_O","wt_C","wt_H","wt_S",
1367
+ "fO2","fH2","fH2O","fS2","fSO2","fH2S","fCO2","fCO","fCH4","fOCS",
1368
+ "yO2","yH2","yH2O","yS2","ySO2","yH2S","yCO2","yCO","yCH4","yOCS",
1369
+ "M_m_SO","M_m_ox","C_H2O","C_H2","C_CO3","C_CO","C_CH4","C_S","C_SO4","C_H2S",
1370
+ "KD1","KHOg","KHOm","KHOSg","KCOg","KCOHg","KOCSg","KSOg","KSOg2"]])
1371
+ results_chemistry = pd.concat([results_header, results_chemistry1], ignore_index=True)
1372
+ results1 = pd.DataFrame([[PT["P"],PT["T"],mg.xg_O2(run,PT,melt_wf,setup,species,models),mg.xg_CO(run,PT,melt_wf,setup,species,models),mg.xg_CO2(run,PT,melt_wf,setup,species,models),mg.xg_H2(run,PT,melt_wf,setup,species,models),mg.xg_H2O(run,PT,melt_wf,setup,species,models),mg.xg_CH4(run,PT,melt_wf,setup,species,models),mg.xg_S2(run,PT,melt_wf,setup,species,models),mg.xg_SO2(run,PT,melt_wf,setup,species,models),mg.xg_H2S(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),
1373
+ mg.xm_CO2_so(run,melt_wf,setup,species),mg.xm_H2OT_so(run,melt_wf,setup,species),mg.Xm_t_so(run,melt_wf,setup,species),mg.Xm_t_ox(run,melt_wf,setup,species),
1374
+ melt_wf["CO2"],melt_wf["H2OT"],wm_H2_,wm_CO_,wm_CH4_,wm_S2m_,wm_SO3_,wm_H2S_,melt_wf["ST"],mg.Fe3Fe2(melt_wf),melt_wf["Fe3FeT"],mg.S6S2(run,PT,melt_wf,setup,species,models),mg.S6ST(run,PT,melt_wf,setup,species,models),
1375
+ mg.fO22Dbuffer(PT,mdv.f_O2(run,PT,melt_wf,setup,species,models),"FMQ",models),mg.fO22Dbuffer(PT,mdv.f_O2(run,PT,melt_wf,setup,species,models),"NNO",models),SCSS_,sulfide_sat,SCAS_,sulfate_sat,wt_g_,"","","","",
1376
+ bulk_wf["O"],bulk_wf["C"],bulk_wf["H"],bulk_wf["S"],
1377
+ mdv.f_O2(run,PT,melt_wf,setup,species,models),mg.f_H2(run,PT,melt_wf,setup,species,models),mg.f_H2O(run,PT,melt_wf,setup,species,models),mg.f_S2(run,PT,melt_wf,setup,species,models),mg.f_SO2(run,PT,melt_wf,setup,species,models),mg.f_H2S(run,PT,melt_wf,setup,species,models),mg.f_CO2(run,PT,melt_wf,setup,species,models),mg.f_CO(run,PT,melt_wf,setup,species,models),mg.f_CH4(run,PT,melt_wf,setup,species,models),mg.f_OCS(run,PT,melt_wf,setup,species,models),
1378
+ mdv.y_O2(PT,species,models),mdv.y_H2(PT,species,models),mdv.y_H2O(PT,species,models),mdv.y_S2(PT,species,models),mdv.y_SO2(PT,species,models),mdv.y_SO3(PT,species,models),mdv.y_H2S(PT,species,models),mdv.y_CO2(PT,species,models),mdv.y_CO(PT,species,models),mdv.y_CH4(PT,species,models),mdv.y_OCS(PT,species,models),
1379
+ mg.M_m_SO(run,melt_wf,setup,species),mg.M_m_ox(run,melt_wf,setup,species,models),mdv.C_H2O(run,PT,melt_wf,setup,species,models),mdv.C_H2(run,PT,melt_wf,setup,species,models),mdv.C_CO3(run,PT,melt_wf,setup,species,models),mdv.C_CO(run,PT,melt_wf,setup,species,models),mdv.C_CH4(run,PT,melt_wf,setup,species,models),mdv.C_S(run,PT,melt_wf,setup,species,models),mdv.C_SO4(run,PT,melt_wf,setup,species,models),mdv.C_H2S(run,PT,melt_wf,setup,species,models),
1380
+ mg.KD1(run,PT,setup,species,models),mdv.KHOg(PT,models),mdv.KHOm(run,PT,melt_wf,setup,species,models),mdv.KHOSg(PT,models),mdv.KCOg(PT,models),mdv.KCOHg(PT,models),mdv.KOCSg(PT,models),mdv.KOSg(PT,models),mdv.KOSg2(PT,models)]])
1381
+ results_chemsitry = pd.concat([results_chemistry, results1], ignore_index=True)
1382
+ if models.loc["output csv","option"] == "yes":
1383
+ results_chemistry.to_csv('results_cooling_chemistry.csv', index=False, header=False)
1384
+
1385
+ if models.loc["bulk_O","option"] == "inc S":
1386
+ if setup.loc[run,"final_T"] > setup.loc[run,"T_C"]:
1387
+ initial = int(round(PT["T"])+1)
1388
+ step = 1 # temperature step in 'C
1389
+ elif setup.loc[run,"final_T"] < setup.loc[run,"T_C"]:
1390
+ initial = int(round(PT["T"])-1)
1391
+ final = int(round(setup.loc[run,"final_T"]))
1392
+ step = -1 # temperature step in 'C
1393
+ elif models.loc["bulk_O","option"] == "exc S":
1394
+ initial = 10
1395
+ final = 5000
1396
+ step = 10
1397
+
1398
+ # run over different temperatures #
1399
+ for i in range(initial,final,step): # P is pressure in bars or T is temperature in 'C
1400
+ eq_Fe = models.loc["eq_Fe","option"]
1401
+ if models.loc["bulk_O","option"] == "inc S":
1402
+ T = i/dt_step
1403
+ PT["T"] = T
1404
+ elif models.loc["bulk_O","option"] == "exc S":
1405
+ PT["T"] = setup.loc[run,"T_C"]
1406
+ melt_wf["ST"]=i/1000000.
1407
+ bulk_wf["S"]=i/1000000.
1408
+
1409
+ # work out equilibrium partitioning between melt and gas phase
1410
+ fO2_, A, B, C = eq.eq_SOFe_melt(run,PT,bulk_wf,melt_wf,species,setup,models,nr_step,nr_tol,guessx)
1411
+ Fe32, Fe3T, S62, S6T = A
1412
+
1413
+ # set melt composition for forward calculation
1414
+ wm_CO2_ = melt_wf["CO2"]
1415
+ wm_H2O_ = melt_wf["H2OT"]
1416
+ wm_H2_, wm_CO_, wm_CH4_, wm_H2S_ = "","","",""
1417
+ melt_wf["Fe3FeT"] = Fe3T
1418
+ melt_wf["S6ST"] = S6T
1419
+ if models.loc["bulk_O","option"] == "inc S":
1420
+ wm_ST_ = wt_S
1421
+ elif models.loc["bulk_O","option"] == "exc S":
1422
+ wm_ST_ = melt_wf["ST"]
1423
+ wm_S = wm_ST_
1424
+ melt_wf["S2-"] = wt_S*(1.-S6T)
1425
+ wm_S_ = wt_S*(1.-S6T)
1426
+ wm_SO3_ = ((wt_S*S6T)/species.loc["S","M"])*species.loc["SO3","M"]
1427
+
1428
+ # check for sulfur saturation and display warning in outputs
1429
+ SCSS_,sulfide_sat,SCAS_,sulfate_sat, ST_ = sulfur_saturation(run,PT,melt_wf,setup,species,models)
1430
+ if sulfide_sat == "yes":
1431
+ warning = "WARNING: sulfide-saturated"
1432
+ elif sulfate_sat == "yes":
1433
+ warning = "WARNING: sulfate-saturated"
1434
+ else:
1435
+ warning = ""
1436
+
1437
+ # calculate fO2
1438
+ if eq_Fe == "yes":
1439
+ fO2_ = mdv.f_O2(run,PT,melt_wf,setup,species,models)
1440
+ elif eq_Fe == "no":
1441
+ fO2_ = (xg_O2_*mg.y_O2(PT,models)*PT["P"])
1442
+
1443
+ guessx = fO2_
1444
+
1445
+ # volume, density, and mass
1446
+ #gas_mf = {"O2":xg_O2_,"CO":xg_CO_,"S2":xg_S2_,"CO2":xg_CO2_,"H2O":xg_H2O_,"H2":xg_H2_,"CH4":xg_CH4_,"SO2":xg_SO2_,"H2S":xg_H2S_,"OCS":xg_OCS_,"Xg_t":Xg_t,"wt_g":wt_g}
1447
+ xg_O2_,xg_CO_,xg_CO2_,xg_H2_,xg_H2O_,xg_CH4_,xg_S2_,xg_SO2_,xg_H2S_,xg_OCS_,Xg_t= "","","","","","","","","","",""
1448
+ wt_g,wt_g_O,wt_g_C,wt_g_H,wt_g_S = "","","","",""
1449
+ wt_O_,wt_C_,wt_H_,wt_S_ = wt_O, wt_C, wt_H, wt_S
1450
+
1451
+ if models.loc["print status","option"] == "yes":
1452
+ print(i,fO2_)
1453
+
1454
+ # store results
1455
+ results2 = pd.DataFrame([[PT["P"],PT["T"],xg_O2_,xg_CO_,xg_CO2_,xg_H2_,xg_H2O_,xg_CH4_,xg_S2_,xg_SO2_,xg_H2S_,xg_OCS_,Xg_t,
1456
+ "","","","",
1457
+ wm_CO2_,wm_H2O_,wm_H2_,wm_CO_,wm_CH4_,wm_S_,wm_SO3_,wm_H2S_,wm_ST_,Fe32,Fe3T,S62,S6T,
1458
+ mg.fO22Dbuffer(PT,fO2_,"FMQ",models),mg.fO22Dbuffer(PT,fO2_,"NNO",models),SCSS_,sulfide_sat,SCAS_,sulfate_sat,
1459
+ wt_g,wt_g_O,wt_g_C,wt_g_H,wt_g_S,wt_O_,wt_C_,wt_H_,wt_S_,
1460
+ fO2_,mg.f_H2(run,PT,melt_wf,setup,species,models),mg.f_H2O(run,PT,melt_wf,setup,species,models),mg.f_S2(run,PT,melt_wf,setup,species,models),mg.f_SO2(run,PT,melt_wf,setup,species,models),mg.f_SO3(run,PT,melt_wf,setup,species,models),mg.f_H2S(run,PT,melt_wf,setup,species,models),mg.f_CO2(run,PT,melt_wf,setup,species,models),mg.f_CO(run,PT,melt_wf,setup,species,models),mg.f_CH4(run,PT,melt_wf,setup,species,models),mg.f_OCS(run,PT,melt_wf,setup,species,models),
1461
+ mg.y_O2(PT,species,models),mg.y_H2(PT,species,models),mg.y_H2O(PT,species,models),mg.y_S2(PT,species,models),mg.y_SO2(PT,species,models),mg.y_SO3(PT,species,models),mdv.y_H2S(PT,species,models),mg.y_CO2(PT,species,models),mg.y_CO(PT,species,models),mg.y_CH4(PT,species,models),mg.y_OCS(PT,species,models),
1462
+ mg.M_m_SO(run,melt_wf,setup,species),mg.M_m_ox(run,melt_wf,setup,species,models),mg.C_H2O(run,PT,melt_wf,setup,species,models),mg.C_H2(run,PT,melt_wf,setup,species,models),mdv.C_CO3(run,PT,melt_wf,setup,species,models),mg.C_CO(run,PT,melt_wf,setup,species,models),mg.C_CH4(run,PT,melt_wf,setup,species,models),mg.C_S(run,PT,melt_wf,setup,species,models),mg.C_SO4(run,PT,melt_wf,setup,species,models),mg.C_H2S(run,PT,melt_wf,setup,species,models),
1463
+ mg.KD1(run,PT,setup,species,models),mg.KHOg(PT,models),mg.KHOm(run,PT,melt_wf,setup,species,models),mg.KHOSg(PT,models),mg.KCOg(PT,models),mg.KCOHg(PT,models),mg.KOCSg(PT,models),mg.KOSg(PT,models),mg.KOSg2(PT,models)]])
1464
+ results_chemsitry = pd.concat([results_chemsitry, results2], ignore_index=True)
1465
+ if models.loc["output csv","option"] == "yes":
1466
+ results_chemistry.to_csv('results_cooling_chemistry.csv', index=False, header=False)
1467
+
1468
+ return results
1469
+
1470
+ def titratingS(run,cooling_inputs,setup,species,models):
1471
+ if models.loc["print status","option"] == "yes":
1472
+ print(setup.loc[run,"Sample"])
1473
+
1474
+ # check if any options need to be read from the setup file rather than the models file
1475
+ models = options_from_setup(run,models,setup)
1476
+
1477
+ # set T, volatile composition of the melt, and tolerances
1478
+ PT={"P":setup.loc[run,"P_bar"]}
1479
+ PT["T"]=setup.loc[run,"T_C"]
1480
+ melt_wf = {'CO2':setup.loc[run,"CO2ppm"]/1000000.,"H2OT":setup.loc[run,"H2O"]/100.,"H2":0.}
1481
+ melt_wf["CT"] = (melt_wf["CO2"]/species.loc["CO2","M"])*species.loc["C","M"]
1482
+ melt_wf["HT"] = (2.*melt_wf["H2OT"]/species.loc["H2O","M"])*species.loc["H","M"]
1483
+ nr_step = cooling_inputs["nr_step"]
1484
+ nr_tol = cooling_inputs["nr_tol"]
1485
+ dt_step = cooling_inputs["dt_step"]
1486
+ psat_tol = cooling_inputs["psat_tol"]
1487
+
1488
+ # Calculate S and Fe composition at initial T and check for sulfur saturation
1489
+ melt_wf["Fe3FeT"] = mg.Fe3FeT_i(run,PT,melt_wf,setup,species,models)
1490
+ Fe3Fe2_ = mg.Fe3Fe2(melt_wf)
1491
+ melt_wf["CO"] = 0.
1492
+ melt_wf["CH4"] = 0.
1493
+ melt_wf["H2S"] = 0.
1494
+ wm_H2_, wm_CH4_, wm_H2S_, wm_CO_ = 0., 0., 0., 0.
1495
+ melt_wf["ST"] = 0.
1496
+ melt_wf["S2-"] = 0.
1497
+ melt_wf["S6+"] = 0.
1498
+
1499
+ SCSS_,sulfide_sat,SCAS_,sulfate_sat,ST_ = sulfur_saturation(run,PT,melt_wf,setup,species,models)
1500
+ wm_S2m_ = melt_wf["S2-"]
1501
+ wm_S6p_ = melt_wf["S6+"]
1502
+ wm_SO3_ = (wm_S6p_/(species.loc["S","M"]))*(species.loc["S","M"] + 3.*species.loc["O","M"])
1503
+
1504
+ # Set bulk composition
1505
+ wt_C, wt_O, wt_H, wt_S, wt_Fe, wt_g_, Wt_ = bulk_composition(run,PT,melt_wf,setup,species,models)
1506
+
1507
+ melt_wf["ST"] = setup.loc[run,"STppm"]/1000000.
1508
+ melt_wf["S6ST"] = mg.S6ST(run,PT,melt_wf,setup,species,models)
1509
+ melt_wf["S2-"] = (1.-melt_wf["S6ST"])*melt_wf["ST"]
1510
+ melt_wf["S6+"] = melt_wf["S6ST"]*melt_wf["ST"]
1511
+ wt_S = melt_wf["ST"]
1512
+
1513
+ bulk_wf = {"C":wt_C,"H":wt_H,"O":wt_O,"S":wt_S,"Fe":wt_Fe,"Wt":Wt_}
1514
+
1515
+ P_sat_, wm_H2O_psat, wm_CO2_psat, wm_H2_psat, wm_CO_psat, wm_CH4_psat, wm_S2m_psat, wm_S6p_psat, wm_H2S_psat, H2O_HTpsat, H2_HTpsat, CH4_HTpsat, H2S_HTpsat, CO2_CTpsat, CO_CTpsat, CH4_CTpsat, S6p_STpsat, S2m_STpsat, H2S_STpsat = P_sat(run,PT,melt_wf,setup,species,models,psat_tol,nr_step,nr_tol)
1516
+ PT["P"] = setup.loc[run,"P_bar"]
1517
+ if models.loc["print status","option"] == "yes":
1518
+ print(P_sat_, PT["P"])
1519
+
1520
+ # set system and initial guesses
1521
+ system = eq.set_system(melt_wf,models)
1522
+
1523
+ if PT["P"] > P_sat_:
1524
+ guessx = mdv.f_O2(run,PT,melt_wf,setup,species,models)
1525
+ fO2_, A, B, C = eq.eq_SOFe_melt(run,PT,bulk_wf,melt_wf,species,setup,models,nr_step/10.,nr_tol,guessx)
1526
+ Fe32, Fe3T, S62, S6T = A
1527
+ melt_wf["S6ST"] = S6T
1528
+ melt_wf["Fe3FeT"] = Fe3T
1529
+ melt_wf["S2-"] = (1.-melt_wf["S6ST"])*melt_wf["ST"]
1530
+ melt_wf["S6+"] = melt_wf["S6ST"]*melt_wf["ST"]
1531
+ guessx = mdv.f_O2(run,PT,melt_wf,setup,species,models)
1532
+ else:
1533
+ #PT["P"] = P_sat_
1534
+ #guessx, guessy, guessz = eq.initial_guesses(run,PT,melt_wf,setup,species,models,system)
1535
+ guessx, guessy, guessz = 3.28098558298437E-10,0.0485362525980284,0.
1536
+ #PT["P"] = setup.loc[run,"P_bar"]
1537
+ xg_O2_, xg_H2_, xg_S2_, xg_H2O_, xg_CO_, xg_CO2_, xg_SO2_, xg_CH4_, xg_H2S_, xg_OCS_, Xg_t, xm_H2O_, xm_CO2_, Xm_t, Xm_t_ox, wm_H2O_, wm_H2_, wm_CO2_, wm_CO_, wm_CH4_, wm_S_, wm_SO3_, wm_H2S_, wm_ST_, Fe32, Fe3T, S62, S6T, wt_g_O, wt_g_C, wt_g_H, wt_g_S, wt_g, wt_O_, wt_C_, wt_H_, wt_S_, guessx, guessy, guessz, guessw = eq.mg_equilibrium(run,PT,melt_wf,bulk_wf,setup,species,models,nr_step,nr_tol,guessx,guessy,guessz,guessw)
1538
+ guessz = 0.00139401157503231
1539
+
1540
+ # create results table
1541
+ results_header1 = pd.DataFrame([["System","run","Sample","H2O (mwf)","CO2 (mwf)","ST (mwf)","Fe3FeT","S6ST","O (twf)","C (twf)","H (wtf)","S (twf)","Fe (twf)",
1542
+ "SiO2 (wt%)","TiO2 (wt%)","Al2O3 (wt%)","FeOT (wt%)","MnO (wt%)","MgO (wt%)","CaO (wt%)","Na2O (wt%)","K2O (wt%)","P2O5 (wt%)",
1543
+ "oxygen fugacity","carbon dioxide solubility","C speciation composition","water solubility","water speciation","water speciation composition","sulfide solubility","sulfate solubility","ideal gas","carbonylsulfide","bulk composition","equilibrate Fe","starting pressure","gassing direction","gassing style","mass_volume","crystallisation","isotopes","Date"]])
1544
+ results_header2 = pd.DataFrame([[system,run,setup.loc[run,"Sample"],melt_wf["H2OT"],melt_wf["CO2"],melt_wf["ST"],melt_wf["Fe3FeT"],"SORT",bulk_wf["O"],bulk_wf["C"],bulk_wf["H"],bulk_wf["S"],bulk_wf["Fe"],
1545
+ setup.loc[run,"SiO2"],setup.loc[run,"TiO2"],setup.loc[run,"Al2O3"],mg.Wm_FeOT(run,setup,species),setup.loc[run,"MnO"],setup.loc[run,"MgO"],setup.loc[run,"CaO"],setup.loc[run,"Na2O"],setup.loc[run,"K2O"],setup.loc[run,"P2O5"],
1546
+ models.loc["fO2","option"],models.loc["carbon dioxide","option"],models.loc["Cspeccomp","option"],models.loc["water","option"],models.loc["Hspeciation","option"],models.loc["Hspeccomp","option"],models.loc["sulfide","option"],models.loc["sulfate","option"],models.loc["ideal_gas","option"],models.loc["carbonylsulfide","option"],models.loc["bulk_composition","option"],models.loc["eq_Fe","option"],models.loc["starting_P","option"],models.loc["gassing_direction","option"],models.loc["gassing_style","option"],models.loc["mass_volume","option"],models.loc["crystallisation","option"],models.loc["isotopes","option"],date.today()]])
1547
+ results_header = pd.concat([results_header1, results_header2], ignore_index=True)
1548
+ results_chemistry1 = pd.DataFrame([["P","T('C)","xg_O2","xg_CO","xg_CO2","xg_H2","xg_H2O","xg_CH4","xg_S2","xg_SO2","xg_H2S","xg_OCS","Xg_t",
1549
+ "xm_CO2","xm_H2O","Xm_t_SO","Xm_t_ox",
1550
+ "wm_CO2","wm_H2O","wm_H2","wm_CO","wm_CH4","wm_S","wm_SO3","wm_H2S","wm_ST","Fe32","Fe3T","S62","S6T",
1551
+ "DFMQ","DNNO","SCSS","sulfide sat?","SCAS","sulfate sat?","wt_g","wt_g_O","wt_g_C","wt_g_H","wt_g_S","wt_O","wt_C","wt_H","wt_S",
1552
+ "fO2","fH2","fH2O","fS2","fSO2","fSO3","fH2S","fCO2","fCO","fCH4","fOCS",
1553
+ "yO2","yH2","yH2O","yS2","ySO2","ySO3","yH2S","yCO2","yCO","yCH4","yOCS",
1554
+ "M_m_SO","M_m_ox","C_H2O","C_H2","C_CO3","C_CO","C_CH4","C_S","C_SO4","C_H2S",
1555
+ "KD1","KHOg","KHOm","KHOSg","KCOg","KCOHg","KOCSg","KSOg","KSOg2"]])
1556
+ results_chemistry = pd.concat([results_header, results_chemistry1], ignore_index=True)
1557
+ results1 = pd.DataFrame([[PT["P"],PT["T"],mg.xg_O2(run,PT,melt_wf,setup,species,models),mg.xg_CO(run,PT,melt_wf,setup,species,models),mg.xg_CO2(run,PT,melt_wf,setup,species,models),mg.xg_H2(run,PT,melt_wf,setup,species,models),mg.xg_H2O(run,PT,melt_wf,setup,species,models),mg.xg_CH4(run,PT,melt_wf,setup,species,models),mg.xg_S2(run,PT,melt_wf,setup,species,models),mg.xg_SO2(run,PT,melt_wf,setup,species,models),mg.xg_H2S(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),
1558
+ mg.xm_CO2_so(run,melt_wf,setup,species),mg.xm_H2OT_so(run,melt_wf,setup,species),mg.Xm_t_so(run,melt_wf,setup,species),mg.Xm_t_ox(run,melt_wf,setup,species),
1559
+ melt_wf["CO2"],melt_wf["H2OT"],wm_H2_,wm_CO_,wm_CH4_,wm_S2m_,wm_SO3_,wm_H2S_,melt_wf["ST"],mg.Fe3Fe2(melt_wf),melt_wf["Fe3FeT"],mg.S6S2(run,PT,melt_wf,setup,species,models),mg.S6ST(run,PT,melt_wf,setup,species,models),
1560
+ mg.fO22Dbuffer(PT,mdv.f_O2(run,PT,melt_wf,setup,species,models),"FMQ",models),mg.fO22Dbuffer(PT,mdv.f_O2(run,PT,melt_wf,setup,species,models),"NNO",models),SCSS_,sulfide_sat,SCAS_,sulfate_sat,wt_g_,"","","","",
1561
+ bulk_wf["O"],bulk_wf["C"],bulk_wf["H"],bulk_wf["S"],
1562
+ mdv.f_O2(run,PT,melt_wf,setup,species,models),mg.f_H2(run,PT,melt_wf,setup,species,models),mg.f_H2O(run,PT,melt_wf,setup,species,models),mg.f_S2(run,PT,melt_wf,setup,species,models),mg.f_SO2(run,PT,melt_wf,setup,species,models),mg.f_SO3(run,PT,melt_wf,setup,species,models),mg.f_H2S(run,PT,melt_wf,setup,species,models),mg.f_CO2(run,PT,melt_wf,setup,species,models),mg.f_CO(run,PT,melt_wf,setup,species,models),mg.f_CH4(run,PT,melt_wf,setup,species,models),mg.f_OCS(run,PT,melt_wf,setup,species,models),
1563
+ mg.y_O2(PT,species,models),mg.y_H2(PT,species,models),mg.y_H2O(PT,species,models),mg.y_S2(PT,species,models),mg.y_SO2(PT,species,models),mg.y_SO3(PT,species,models),mdv.y_H2S(PT,species,models),mg.y_CO2(PT,species,models),mg.y_CO(PT,species,models),mg.y_CH4(PT,species,models),mg.y_OCS(PT,species,models),
1564
+ mg.M_m_SO(run,melt_wf,setup,species),mg.M_m_ox(run,melt_wf,setup,species,models),mg.C_H2O(run,PT,melt_wf,setup,species,models),mg.C_H2(run,PT,melt_wf,setup,species,models),mdv.C_CO3(run,PT,melt_wf,setup,species,models),mg.C_CO(run,PT,melt_wf,setup,species,models),mg.C_CH4(run,PT,melt_wf,setup,species,models),mg.C_S(run,PT,melt_wf,setup,species,models),mg.C_SO4(run,PT,melt_wf,setup,species,models),mg.C_H2S(run,PT,melt_wf,setup,species,models),
1565
+ mg.KD1(run,PT,setup,species,models),mg.KHOg(PT,models),mg.KHOm(run,PT,melt_wf,setup,species,models),mg.KHOSg(PT,models),mg.KCOg(PT,models),mg.KCOHg(PT,models),mg.KOCSg(PT,models),mg.KOSg(PT,models),mg.KOSg2(PT,models)]])
1566
+ results_chemistry = pd.concat([results_chemistry, results1], ignore_index=True)
1567
+ if models.loc["output csv","option"] == "yes":
1568
+ results_chemistry.to_csv('results_titrating_chemistry.csv', index=False, header=False)
1569
+
1570
+ initial = 100
1571
+ final = 5000
1572
+ step = 100
1573
+
1574
+ # run over different S concentrations #
1575
+ for i in range(initial,final,step): # P is pressure in bars or T is temperature in 'C
1576
+ eq_Fe = models.loc["eq_Fe","option"]
1577
+
1578
+ melt_wf["ST"]=i/1000000.
1579
+ bulk_wf["S"]=i/1000000.
1580
+
1581
+ system = eq.set_system(melt_wf,models)
1582
+ P_sat_, wm_H2O_psat, wm_CO2_psat, wm_H2_psat, wm_CO_psat, wm_CH4_psat, wm_S2m_psat, wm_S6p_psat, wm_H2S_psat, H2O_HTpsat, H2_HTpsat, CH4_HTpsat, H2S_HTpsat, CO2_CTpsat, CO_CTpsat, CH4_CTpsat, S6p_STpsat, S2m_STpsat, H2S_STpsat = P_sat(run,PT,melt_wf,setup,species,models,psat_tol,nr_step,nr_tol)
1583
+ PT["P"]=setup.loc[run,"P_bar"]
1584
+
1585
+ # work out equilibrium partitioning between melt and gas phase
1586
+ if PT["P"] > P_sat_:
1587
+ fO2_, A, B, C = eq.eq_SOFe_melt(run,PT,bulk_wf,melt_wf,species,setup,models,nr_step,nr_tol,guessx)
1588
+ Fe32, Fe3T, S62, S6T = A
1589
+ wm_CO2_ = melt_wf["CO2"]
1590
+ wm_H2O_ = melt_wf["H2OT"]
1591
+ wm_H2_, wm_CO_, wm_CH4_, wm_H2S_ = "","","",""
1592
+ melt_wf["Fe3FeT"] = Fe3T
1593
+ melt_wf["S6ST"] = S6T
1594
+ wm_ST_ = melt_wf["ST"]
1595
+ wm_S = wm_ST_
1596
+ melt_wf["S2-"] = wt_S*(1.-S6T)
1597
+ wm_S_ = wt_S*(1.-S6T)
1598
+ wm_SO3_ = ((wt_S*S6T)/species.loc["S","M"])*species.loc["SO3","M"]
1599
+ xg_O2_,xg_CO_,xg_CO2_,xg_H2_,xg_H2O_,xg_CH4_,xg_S2_,xg_SO2_,xg_H2S_,xg_OCS_,Xg_t= "","","","","","","","","","",""
1600
+ wt_g,wt_g_O,wt_g_C,wt_g_H,wt_g_S = 0.,"","","",""
1601
+ wt_O_,wt_C_,wt_H_,wt_S_ = wt_O, wt_C, wt_H, wt_S
1602
+ else:
1603
+ xg_O2_, xg_H2_, xg_S2_, xg_H2O_, xg_CO_, xg_CO2_, xg_SO2_, xg_CH4_, xg_H2S_, xg_OCS_, Xg_t, xm_H2O_, xm_CO2_, Xm_t, Xm_t_ox, wm_H2O_, wm_H2_, wm_CO2_, wm_CO_, wm_CH4_, wm_S_, wm_SO3_, wm_H2S_, wm_ST_, Fe32, Fe3T, S62, S6T, wt_g_O, wt_g_C, wt_g_H, wt_g_S, wt_g, wt_O_, wt_C_, wt_H_, wt_S_, guessx, guessy, guessz, guessw = eq.mg_equilibrium(run,PT,melt_wf,bulk_wf,setup,species,models,nr_step,nr_tol,guessx,guessy,guessz,guessw)
1604
+ melt_wf["Fe3FeT"] = Fe3T
1605
+
1606
+ # check for sulfur saturation and display warning in outputs
1607
+ SCSS_,sulfide_sat,SCAS_,sulfate_sat, ST_ = sulfur_saturation(run,PT,melt_wf,setup,species,models)
1608
+ if sulfide_sat == "yes":
1609
+ warning = "WARNING: sulfide-saturated"
1610
+ elif sulfate_sat == "yes":
1611
+ warning = "WARNING: sulfate-saturated"
1612
+ else:
1613
+ warning = ""
1614
+
1615
+ # calculate fO2
1616
+ if eq_Fe == "yes":
1617
+ fO2_ = mdv.f_O2(run,PT,melt_wf,setup,species,models)
1618
+ elif eq_Fe == "no":
1619
+ fO2_ = (xg_O2_*mg.y_O2(PT,models)*PT["P"])
1620
+
1621
+ if PT["P"] > P_sat_:
1622
+ guessx = fO2_
1623
+
1624
+ if models.loc["print status","option"] == "yes":
1625
+ print(i,fO2_)
1626
+
1627
+ # store results
1628
+ results2 = pd.DataFrame([[PT["P"],PT["T"],xg_O2_,xg_CO_,xg_CO2_,xg_H2_,xg_H2O_,xg_CH4_,xg_S2_,xg_SO2_,xg_H2S_,xg_OCS_,Xg_t,
1629
+ "","","","",
1630
+ wm_CO2_,wm_H2O_,wm_H2_,wm_CO_,wm_CH4_,wm_S_,wm_SO3_,wm_H2S_,wm_ST_,Fe32,Fe3T,S62,S6T,
1631
+ mg.fO22Dbuffer(PT,fO2_,"FMQ",models),mg.fO22Dbuffer(PT,fO2_,"NNO",models),SCSS_,sulfide_sat,SCAS_,sulfate_sat,
1632
+ wt_g,wt_g_O,wt_g_C,wt_g_H,wt_g_S,wt_O_,wt_C_,wt_H_,wt_S_,
1633
+ fO2_,mg.f_H2(run,PT,melt_wf,setup,species,models),mg.f_H2O(run,PT,melt_wf,setup,species,models),mg.f_S2(run,PT,melt_wf,setup,species,models),mg.f_SO2(run,PT,melt_wf,setup,species,models),mg.f_SO3(run,PT,melt_wf,setup,species,models),mg.f_H2S(run,PT,melt_wf,setup,species,models),mg.f_CO2(run,PT,melt_wf,setup,species,models),mg.f_CO(run,PT,melt_wf,setup,species,models),mg.f_CH4(run,PT,melt_wf,setup,species,models),mg.f_OCS(run,PT,melt_wf,setup,species,models),
1634
+ mg.y_O2(PT,species,models),mg.y_H2(PT,species,models),mg.y_H2O(PT,species,models),mg.y_S2(PT,species,models),mg.y_SO2(PT,species,models),mg.y_SO3(PT,species,models),mdv.y_H2S(PT,species,models),mg.y_CO2(PT,species,models),mg.y_CO(PT,species,models),mg.y_CH4(PT,species,models),mg.y_OCS(PT,species,models),
1635
+ mg.M_m_SO(run,melt_wf,setup,species),mg.M_m_ox(run,melt_wf,setup,species,models),mg.C_H2O(run,PT,melt_wf,setup,species,models),mg.C_H2(run,PT,melt_wf,setup,species,models),mdv.C_CO3(run,PT,melt_wf,setup,species,models),mg.C_CO(run,PT,melt_wf,setup,species,models),mg.C_CH4(run,PT,melt_wf,setup,species,models),mg.C_S(run,PT,melt_wf,setup,species,models),mg.C_SO4(run,PT,melt_wf,setup,species,models),mg.C_H2S(run,PT,melt_wf,setup,species,models),
1636
+ mg.KD1(run,PT,setup,species,models),mg.KHOg(PT,models),mg.KHOm(run,PT,melt_wf,setup,species,models),mg.KHOSg(PT,models),mg.KCOg(PT,models),mg.KCOHg(PT,models),mg.KOCSg(PT,models),mg.KOSg(PT,models),mg.KOSg2(PT,models)]])
1637
+ results_chemistry = pd.concat([results_chemistry, results2], ignore_index=True)
1638
+ if models.loc["output csv","option"] == "yes":
1639
+ results_chemistry.to_csv('results_titrating_chemistry.csv', index=False, header=False)
1640
+
1641
+ return results_chemistry
1642
+
1643
+ ##########################
1644
+ ### X% sulfur degassed ###
1645
+ ##########################
1646
+
1647
+ def Xpc_S_degassed(first_row,last_row,inputs,setup,species,models):
1648
+
1649
+ if models.loc["fO2","option"] != "Kress91A":
1650
+ raise TypeError("Kress91A must be used for fO2 option to be used")
1651
+ if models.loc["P_variation","option"] == "isobaric":
1652
+ raise TypeError("P_variation must be polybaric")
1653
+
1654
+ nr_step = inputs["nr_step"]
1655
+ nr_tol = inputs["nr_tol"]
1656
+ psat_tol = inputs["psat_tol"]
1657
+ dp_step = inputs["dp_step"]
1658
+
1659
+ # create results table
1660
+ results_header1 = pd.DataFrame([["oxygen fugacity","carbon dioxide solubility","C speciation composition","water solubility","water speciation","water speciation composition","sulfide solubility","sulfate solubility","ideal gas","carbonylsulfide","bulk composition","equilibrate Fe","starting pressure","gassing direction","gassing style","mass_volume","crystallisation","isotopes","Date"]])
1661
+ results_header2 = pd.DataFrame([[models.loc["fO2","option"],models.loc["carbon dioxide","option"],models.loc["Cspeccomp","option"],models.loc["water","option"],models.loc["Hspeciation","option"],models.loc["Hspeccomp","option"],models.loc["sulfide","option"],models.loc["sulfate","option"],models.loc["ideal_gas","option"],models.loc["carbonylsulfide","option"],models.loc["bulk_composition","option"],models.loc["eq_Fe","option"],models.loc["starting_P","option"],models.loc["gassing_direction","option"],models.loc["gassing_style","option"],models.loc["mass_volume","option"],models.loc["crystallisation","option"],models.loc["isotopes","option"],date.today()]])
1662
+ results_header = pd.concat([results_header1, results_header2], ignore_index=True)
1663
+ results_chemistry1 = pd.DataFrame([["run","Sample","% S degassed","initial fO2 (DFMQ)","H2O (wt%)","CO2 (ppm)","ST (ppm)","X (ppm)","Fe3FeT","S6ST","O (twf)","C (twf)","H (wtf)","S (twf)","Fe (twf)","Saturation P (bars)",
1664
+ "SiO2 (wt%)","TiO2 (wt%)","Al2O3 (wt%)","FeOT (wt%)","MnO (wt%)","MgO (wt%)","CaO (wt%)","Na2O (wt%)","K2O (wt%)","P2O5 (wt%)","P","T('C)","xg_O2","xg_CO","xg_CO2","xg_H2","xg_H2O","xg_CH4","xg_S2","xg_SO2","xg_H2S","xg_OCS","xg_X","Xg_t","xg_CS",
1665
+ "xm_CO2","xm_H2O","Xm_t_SO","Xm_t_ox",
1666
+ "wm_CO2-eq","wm_H2O-eq","wm_CO2","wm_H2O","wm_H2","wm_CO","wm_CH4","wm_S","wm_SO3","wm_H2S","wm_ST","wm_X","Fe32","Fe3T","S62","S6T",
1667
+ "DFMQ","DNNO","wt_g",
1668
+ "fO2"]])
1669
+ results_chemistry = pd.concat([results_header, results_chemistry1], ignore_index=True)
1670
+
1671
+ for n in range(first_row,last_row,1): # n is number of rows of data in conditions file
1672
+ run = n
1673
+
1674
+ # check if any options need to be read from the setup file rather than the models file
1675
+ models = options_from_setup(run,models,setup)
1676
+
1677
+ # set T, volatile composition of the melt, and tolerances
1678
+ PT={"T":setup.loc[run,"T_C"]}
1679
+ melt_wf = {'CO2':setup.loc[run,"CO2ppm"]/1000000.,"H2OT":setup.loc[run,"H2O"]/100.,"ST":setup.loc[run,"STppm"]/1000000.,"H2":0.,"XT":setup.loc[run,"Xppm"]/1000000.}
1680
+ melt_wf["CT"] = (melt_wf["CO2"]/species.loc["CO2","M"])*species.loc["C","M"]
1681
+ melt_wf["HT"] = (2.*melt_wf["H2OT"]/species.loc["H2O","M"])*species.loc["H","M"]
1682
+ melt_wf["ST"] = melt_wf["ST"]
1683
+ target_S = melt_wf["ST"]*((100.-setup.loc[run,"Xpc"])/100.)
1684
+ if models.loc["print status","option"] == "yes":
1685
+ print(run,setup.loc[run,"Sample"],melt_wf["ST"]*1000000.,target_S*1000000.,datetime.datetime.now())
1686
+
1687
+ # Calculate saturation pressure
1688
+ P_sat_, wm_H2O_, wm_CO2_, wm_H2_, wm_CO_, wm_CH4_, wm_S2m_, wm_S6p_, wm_H2S_, H2O_HT, H2_HT, CH4_HT, H2S_HT, CO2_CT, CO_CT, CH4_CT, S6p_ST, S2m_ST, H2S_ST = c.P_sat(run,PT,melt_wf,setup,species,models,psat_tol,nr_step,nr_tol)
1689
+ wm_SO3_ = (wm_S6p_*species.loc["SO3","M"])/species.loc["S","M"]
1690
+ PT["P"] = P_sat_
1691
+
1692
+ # update melt composition at saturation pressure and check for sulfur saturation
1693
+ melt_wf["H2OT"] = wm_H2O_
1694
+ melt_wf["CO2"] = wm_CO2_
1695
+ melt_wf["CO"] = wm_CO_
1696
+ melt_wf["CH4"] = wm_CH4_
1697
+ melt_wf["H2"] = wm_H2_
1698
+ melt_wf["S2-"] = wm_S2m_
1699
+ melt_wf["S6+"] = wm_S6p_
1700
+ melt_wf["H2S"] = wm_H2S_
1701
+ melt_wf["Fe3FeT"] = mg.Fe3FeT_i(run,PT,melt_wf,setup,species,models)
1702
+ melt_wf["S6ST"] = mg.S6ST(run,PT,melt_wf,setup,species,models)
1703
+
1704
+ # Set bulk composition
1705
+ wt_C, wt_O, wt_H, wt_S, wt_X, wt_Fe, wt_g_, Wt_ = c.bulk_composition(run,PT,melt_wf,setup,species,models)
1706
+ bulk_wf = {"C":wt_C,"H":wt_H,"O":wt_O,"S":wt_S,"Fe":wt_Fe,"Wt":Wt_,"X":wt_X}
1707
+
1708
+ # set system and initial guesses
1709
+ system = eq.set_system(melt_wf,models)
1710
+ guessx, guessy, guessz, guessw = eq.initial_guesses(run,PT,melt_wf,setup,species,models,system)
1711
+
1712
+
1713
+ if models.loc["P_variation","option"] == "polybaric":
1714
+ # pressure ranges and options
1715
+ starting_P = models.loc["starting_P","option"]
1716
+ if starting_P == "set":
1717
+ initial = int(setup.loc[run,"P_bar"])
1718
+ else:
1719
+ if models.loc["gassing_direction","option"] == "degas":
1720
+ answer = PT["P"]/dp_step
1721
+ answer = round(answer)
1722
+ initial = round(answer*dp_step)
1723
+ elif models.loc["gassing_direction","option"] == "regas":
1724
+ initial = round(PT["P"])+1
1725
+ if models.loc["gassing_direction","option"] == "degas":
1726
+ step = int(-1*dp_step) # pressure step in bars
1727
+ final = 0
1728
+ elif models.loc["gassing_direction","option"] == "regas":
1729
+ step = int(dp_step)
1730
+ final = int(setup.loc[run,"final_P"])
1731
+
1732
+ # add some gas to the system if doing open-system regassing
1733
+ if models.loc["gassing_direction","option"] == "regas" and models.loc["gassing_style","option"] == "open":
1734
+ gas_mf = {"O2":mg.xg_O2(run,PT,melt_wf,setup,species,models),"CO":mg.xg_CO(run,PT,melt_wf,setup,species,models),"CO2":mg.xg_CO2(run,PT,melt_wf,setup,species,models),"H2":mg.xg_H2(run,PT,melt_wf,setup,species,models),"H2O":mg.xg_H2O(run,PT,melt_wf,setup,species,models),"CH4":mg.xg_CH4(run,PT,melt_wf,setup,species,models),"S2":mg.xg_S2(run,PT,melt_wf,setup,species,models),"SO2":mg.xg_SO2(run,PT,melt_wf,setup,species,models),"SO3":mg.xg_SO3(run,PT,melt_wf,setup,species,models),"H2S":mg.xg_H2S(run,PT,melt_wf,setup,species,models),"OCS":mg.xg_OCS(run,PT,melt_wf,setup,species,models),"X":mg.xg_X(run,PT,melt_wf,setup,species,models),"Xg_t":mg.Xg_tot(run,PT,melt_wf,setup,species,models),"wt_g":0.}
1735
+ wt_C, wt_H, wt_S, wt_X, wt_Fe, wt_O, Wt = new_bulk_regas_open(run,PT,melt_wf,bulk_wf,gas_mf,dwtg,setup,species,models)
1736
+ bulk_wf = {"C":wt_C,"H":wt_H,"O":wt_O,"S":wt_S,"Fe":wt_Fe,"X":wt_X,"Wt":Wt}
1737
+
1738
+ # run over different pressures #
1739
+ number_of_step = 0.
1740
+
1741
+ P = initial
1742
+ wm_ST_ = melt_wf["ST"]
1743
+ while wm_ST_ > target_S: # step size = initial
1744
+ eq_Fe = models.loc["eq_Fe","option"]
1745
+ if models.loc["gassing_style","option"] == "open": # check melt is still vapor-saturated
1746
+ P_sat_, wm_H2O_, wm_CO2_, wm_H2_, wm_CO_, wm_CH4_, wm_S2m_, wm_S6p_, wm_H2S_, H2O_HT, H2_HT, CH4_HT, H2S_HT, CO2_CT, CO_CT, CH4_CT, S6p_ST, S2m_ST, H2S_ST = c.P_sat(run,PT,melt_wf,setup,species,models,psat_tol,nr_step,nr_tol)
1747
+ wm_SO3_ = (wm_S6p_*species.loc["SO3","M"])/species.loc["S","M"]
1748
+ P_ = P
1749
+ wm_ST__ = wm_ST_
1750
+ P = P - dp_step
1751
+ PT["P"] = P
1752
+ if P_sat_ > PT["P"]:
1753
+ # work out equilibrium partitioning between melt and gas phase
1754
+ xg_O2_, xg_H2_, xg_S2_, xg_H2O_, xg_CO_, xg_CO2_, xg_SO2_, xg_CH4_, xg_H2S_, xg_OCS_, xg_X_, Xg_t, xm_H2O_, xm_CO2_, Xm_t, wm_H2O_, wm_H2_, wm_CO2_, wm_CO_, wm_CH4_, wm_S_, wm_SO3_, wm_H2S_, wm_ST_, wm_X_, Fe32, Fe3T, S62, S6T, wt_g_O, wt_g_C, wt_g_H, wt_g_S, wt_g_X, wt_g, wt_O_, wt_C_, wt_H_, wt_S_, wt_X_, guessx, guessy, guessz, guessw = eq.mg_equilibrium(run,PT,melt_wf,bulk_wf,setup,species,models,nr_step,nr_tol,guessx,guessy,guessz,guessw)
1755
+ # gas composition
1756
+ gas_mf = {"O2":xg_O2_,"CO":xg_CO_,"S2":xg_S2_,"CO2":xg_CO2_,"H2O":xg_H2O_,"H2":xg_H2_,"CH4":xg_CH4_,"SO2":xg_SO2_,"H2S":xg_H2S_,"OCS":xg_OCS_,"X":xg_X_,"Xg_t":Xg_t,"wt_g":wt_g}
1757
+
1758
+ else:
1759
+ conc = eq.melt_speciation(PT,melt_wf,species,models,nr_step,nr_tol)
1760
+ frac = c.melt_species_ratios(conc,species)
1761
+ wm_ST_ = wm_S_ + wm_S6p_
1762
+ S62 = S6T/S2m_ST
1763
+ Fe3T = melt_wf["Fe3FeT"]
1764
+ Fe32 = mg.overtotal2ratio(Fe3T)
1765
+ xg_O2_, xg_H2_, xg_S2_, xg_H2O_, xg_CO_, xg_CO2_, xg_SO2_, xg_CH4_, xg_H2S_, xg_OCS_, xg_X, Xg_t, Xm_t, Xm_t_ox, wt_g_O, wt_g_C, wt_g_H, wt_g_S, wt_g = "","","","","","","","","","","","","","",0.,0.,0.,0.,0.
1766
+ guessx, guessy, guessz, guessw = eq.initial_guesses(run,PT,melt_wf,setup,species,models,system)
1767
+
1768
+ P = P_
1769
+ wm_ST_ = wm_ST__
1770
+ while wm_ST_ > target_S: # step size = 1.
1771
+ eq_Fe = models.loc["eq_Fe","option"]
1772
+ if models.loc["gassing_style","option"] == "open": # check melt is still vapor-saturated
1773
+ P_sat_, wm_H2O_, wm_CO2_, wm_H2_, wm_CO_, wm_CH4_, wm_S2m_, wm_S6p_, wm_H2S_, H2O_HT, H2_HT, CH4_HT, H2S_HT, CO2_CT, CO_CT, CH4_CT, S6p_ST, S2m_ST, H2S_ST = c.P_sat(run,PT,melt_wf,setup,species,models,psat_tol,nr_step,nr_tol)
1774
+ wm_SO3_ = (wm_S6p_*species.loc["SO3","M"])/species.loc["S","M"]
1775
+ P_ = P
1776
+ P = P - 1.
1777
+ PT["P"] = P
1778
+ if P_sat_ > PT["P"]:
1779
+ # work out equilibrium partitioning between melt and gas phase
1780
+ xg_O2_, xg_H2_, xg_S2_, xg_H2O_, xg_CO_, xg_CO2_, xg_SO2_, xg_CH4_, xg_H2S_, xg_OCS_, xg_X_, Xg_t, xm_H2O_, xm_CO2_, Xm_t, wm_H2O_, wm_H2_, wm_CO2_, wm_CO_, wm_CH4_, wm_S_, wm_SO3_, wm_H2S_, wm_ST_, wm_X_, Fe32, Fe3T, S62, S6T, wt_g_O, wt_g_C, wt_g_H, wt_g_S, wt_g_X, wt_g, wt_O_, wt_C_, wt_H_, wt_S_, wt_X_, guessx, guessy, guessz, guessw = eq.mg_equilibrium(run,PT,melt_wf,bulk_wf,setup,species,models,nr_step,nr_tol,guessx,guessy,guessz,guessw)
1781
+ # gas composition
1782
+ gas_mf = {"O2":xg_O2_,"CO":xg_CO_,"S2":xg_S2_,"CO2":xg_CO2_,"H2O":xg_H2O_,"H2":xg_H2_,"CH4":xg_CH4_,"SO2":xg_SO2_,"H2S":xg_H2S_,"OCS":xg_OCS_,"X":xg_X_,"Xg_t":Xg_t,"wt_g":wt_g}
1783
+
1784
+ else:
1785
+ conc = eq.melt_speciation(PT,melt_wf,species,models,nr_step,nr_tol)
1786
+ frac = c.melt_species_ratios(conc,species)
1787
+ wm_ST_ = wm_S_ + wm_S6p_
1788
+ S62 = S6T/S2m_ST
1789
+ Fe3T = melt_wf["Fe3FeT"]
1790
+ Fe32 = mg.overtotal2ratio(Fe3T)
1791
+ xg_O2_, xg_H2_, xg_S2_, xg_H2O_, xg_CO_, xg_CO2_, xg_SO2_, xg_CH4_, xg_H2S_, xg_OCS_, xg_X, Xg_t, Xm_t, Xm_t_ox, wt_g_O, wt_g_C, wt_g_H, wt_g_S, wt_g = "","","","","","","","","","","","","","",0.,0.,0.,0.,0.
1792
+ guessx, guessy, guessz, guessw = eq.initial_guesses(run,PT,melt_wf,setup,species,models,system)
1793
+
1794
+
1795
+ # set melt composition for forward calculation
1796
+ melt_wf["CO2"] = wm_CO2_
1797
+ melt_wf["H2OT"] = wm_H2O_
1798
+ melt_wf["H2"] = wm_H2_
1799
+ melt_wf["CO"] = wm_CO_
1800
+ melt_wf["CH4"] = wm_CH4_
1801
+ melt_wf["H2S"] = wm_H2S_
1802
+ melt_wf["S6+"] = wm_S6p_
1803
+ melt_wf["S2-"] = wm_S_
1804
+ melt_wf["ST"] = wm_ST_
1805
+ melt_wf["XT"] = wm_X_
1806
+ melt_wf["Fe3FeT"] = Fe3T
1807
+
1808
+ if P_sat_ < PT["P"]:
1809
+ wt_C_, wt_O_, wt_H_, wt_S_, wt_X_, wt_Fe, wt_g_, Wt_ = c.bulk_composition(run,PT,melt_wf,setup,species,models)
1810
+
1811
+ # check for sulfur saturation and display warning in outputs
1812
+ SCSS_,sulfide_sat,SCAS_,sulfate_sat, ST_ = c.sulfur_saturation(run,PT,melt_wf,setup,species,models)
1813
+ if sulfide_sat == "yes":
1814
+ warning = "WARNING: sulfide-saturated"
1815
+ elif sulfate_sat == "yes":
1816
+ warning = "WARNING: sulfate-saturated"
1817
+ else:
1818
+ warning = ""
1819
+
1820
+ # calculate fO2
1821
+ if eq_Fe == "yes":
1822
+ fO2_ = mdv.f_O2(run,PT,melt_wf,setup,species,models)
1823
+ elif eq_Fe == "no":
1824
+ fO2_ = (xg_O2_*mdv.y_O2(PT,models)*PT["P"])
1825
+
1826
+ xg_CS = mg.gas_CS(run,PT,melt_wf,setup,species,models)
1827
+ wm_CO2eq, wm_H2Oeq = mg.melt_H2O_CO2_eq(melt_wf,species)
1828
+
1829
+ # store results
1830
+ results1 = pd.DataFrame([[run,setup.loc[run,"Sample"],setup.loc[run,"Xpc"],setup.loc[run,"DFMQ"],setup.loc[run,"H2O"],setup.loc[run,"CO2ppm"],setup.loc[run,"STppm"],setup.loc[run,"Xppm"],melt_wf["Fe3FeT"],"SORT",bulk_wf["O"],bulk_wf["C"],bulk_wf["H"],bulk_wf["S"],bulk_wf["Fe"],P_sat_,
1831
+ setup.loc[run,"SiO2"],setup.loc[run,"TiO2"],setup.loc[run,"Al2O3"],mg.Wm_FeOT(run,setup,species),setup.loc[run,"MnO"],setup.loc[run,"MgO"],setup.loc[run,"CaO"],setup.loc[run,"Na2O"],setup.loc[run,"K2O"],setup.loc[run,"P2O5"],PT["P"],PT["T"],mg.xg_O2(run,PT,melt_wf,setup,species,models),mg.xg_CO(run,PT,melt_wf,setup,species,models),mg.xg_CO2(run,PT,melt_wf,setup,species,models),mg.xg_H2(run,PT,melt_wf,setup,species,models),mg.xg_H2O(run,PT,melt_wf,setup,species,models),mg.xg_CH4(run,PT,melt_wf,setup,species,models),mg.xg_S2(run,PT,melt_wf,setup,species,models),mg.xg_SO2(run,PT,melt_wf,setup,species,models),mg.xg_H2S(run,PT,melt_wf,setup,species,models),mg.xg_OCS(run,PT,melt_wf,setup,species,models),mg.xg_X(run,PT,melt_wf,setup,species,models),mg.Xg_tot(run,PT,melt_wf,setup,species,models),xg_CS,
1832
+ mg.xm_CO2_so(run,melt_wf,setup,species),mg.xm_H2OT_so(run,melt_wf,setup,species),mg.Xm_t_so(run,melt_wf,setup,species),"",
1833
+ wm_CO2eq,wm_H2Oeq,melt_wf["CO2"],melt_wf["H2OT"],wm_H2_,wm_CO_,wm_CH4_,wm_S2m_,wm_SO3_,wm_H2S_,melt_wf["ST"],melt_wf["XT"],mg.Fe3Fe2(melt_wf),melt_wf["Fe3FeT"],mg.S6S2(run,PT,melt_wf,setup,species,models),mg.S6ST(run,PT,melt_wf,setup,species,models),
1834
+ mg.fO22Dbuffer(PT,mdv.f_O2(run,PT,melt_wf,setup,species,models),"FMQ",models),mg.fO22Dbuffer(PT,mdv.f_O2(run,PT,melt_wf,setup,species,models),"NNO",models),wt_g,
1835
+ mdv.f_O2(run,PT,melt_wf,setup,species,models)]])
1836
+ results_chemistry = pd.concat([results_chemistry, results1], ignore_index=True)
1837
+ if models.loc["output csv","option"] == "yes":
1838
+ results_chemistry.to_csv('results_XpcSdegasses.csv', index=False, header=False)
1839
+
1840
+ if models.loc["print status","option"] == "yes":
1841
+ print("done", datetime.datetime.now())
1842
+
1843
+ return results
1844
+
1845
+ ####################
1846
+ ### fO2 at 1 bar ###
1847
+ ####################
1848
+
1849
+ def fO2_at_1bar(first_row,last_row,inputs,setup,species,models):
1850
+
1851
+ if models.loc["fO2","option"] != "Kress91A":
1852
+ raise TypeError("Kress91A must be used for fO2 option")
1853
+ if models.loc["P_variation","option"] == "isobaric":
1854
+ raise TypeError("P_variation must be polybaric")
1855
+
1856
+ nr_step = inputs["nr_step"]
1857
+ nr_tol = inputs["nr_tol"]
1858
+ psat_tol = inputs["psat_tol"]
1859
+ P1 = inputs["P1"]
1860
+ P2 = inputs["P2"]
1861
+ dp_step = inputs["dp_step"]
1862
+
1863
+ # create results table
1864
+ results_header1 = pd.DataFrame([["oxygen fugacity","carbon dioxide solubility","C speciation composition","water solubility","water speciation","water speciation composition","sulfide solubility","sulfate solubility","ideal gas","carbonylsulfide","bulk composition","equilibrate Fe","starting pressure","gassing direction","gassing style","mass_volume","crystallisation","isotopes","Date"]])
1865
+ results_header2 = pd.DataFrame([[models.loc["fO2","option"],models.loc["carbon dioxide","option"],models.loc["Cspeccomp","option"],models.loc["water","option"],models.loc["Hspeciation","option"],models.loc["Hspeccomp","option"],models.loc["sulfide","option"],models.loc["sulfate","option"],models.loc["ideal_gas","option"],models.loc["carbonylsulfide","option"],models.loc["bulk_composition","option"],models.loc["eq_Fe","option"],models.loc["starting_P","option"],models.loc["gassing_direction","option"],models.loc["gassing_style","option"],models.loc["mass_volume","option"],models.loc["crystallisation","option"],models.loc["isotopes","option"],date.today()]])
1866
+ results_header = pd.concat([results_header1, results_header2], ignore_index=True)
1867
+ results_chemistry1 = pd.DataFrame([["run","Sample","initial fO2 (DFMQ)","H2O (wt%)","CO2 (ppm)","ST (ppm)","X (ppm)","Fe3FeT","S6ST","O (twf)","C (twf)","H (wtf)","S (twf)","Fe (twf)","Saturation P (bars)",
1868
+ "SiO2 (wt%)","TiO2 (wt%)","Al2O3 (wt%)","FeOT (wt%)","MnO (wt%)","MgO (wt%)","CaO (wt%)","Na2O (wt%)","K2O (wt%)","P2O5 (wt%)","P","T('C)","xg_O2","xg_CO","xg_CO2","xg_H2","xg_H2O","xg_CH4","xg_S2","xg_SO2","xg_H2S","xg_OCS","xg_X","Xg_t","xg_CS",
1869
+ "xm_CO2","xm_H2O","Xm_t_SO","Xm_t_ox",
1870
+ "wm_CO2-eq","wm_H2O-eq","wm_CO2","wm_H2O","wm_H2","wm_CO","wm_CH4","wm_S","wm_SO3","wm_H2S","wm_ST","wm_X","Fe32","Fe3T","S62","S6T",
1871
+ "DFMQ","DNNO","wt_g",
1872
+ "fO2","D-DFMQ"]])
1873
+ results_chemistry1 = pd.concat([results_header, results_chemistry1], ignore_index=True)
1874
+ results_chemistry_P1 = pd.concat([results_header, results_chemistry1], ignore_index=True)
1875
+ results_chemistry_P2 = pd.concat([results_header, results_chemistry1], ignore_index=True)
1876
+
1877
+ for n in range(first_row,last_row,1): # n is number of rows of data in conditions file
1878
+ run = n
1879
+
1880
+ # check if any options need to be read from the setup file rather than the models file
1881
+ models = options_from_setup(run,models,setup)
1882
+
1883
+ # set T, volatile composition of the melt, and tolerances
1884
+ PT={"T":setup.loc[run,"T_C"]}
1885
+ melt_wf = {'CO2':setup.loc[run,"CO2ppm"]/1000000.,"H2OT":setup.loc[run,"H2O"]/100.,"ST":setup.loc[run,"STppm"]/1000000.,"H2":0.,"XT":setup.loc[run,"Xppm"]/1000000.}
1886
+ melt_wf["CT"] = (melt_wf["CO2"]/species.loc["CO2","M"])*species.loc["C","M"]
1887
+ melt_wf["HT"] = (2.*melt_wf["H2OT"]/species.loc["H2O","M"])*species.loc["H","M"]
1888
+ melt_wf["ST"] = melt_wf["ST"]
1889
+ target_S = melt_wf["ST"]*((100.-setup.loc[run,"Xpc"])/100.)
1890
+ if models.loc["print status","option"] == "yes":
1891
+ print(run,setup.loc[run,"Sample"],melt_wf["ST"]*1000000.,target_S*1000000.,datetime.datetime.now())
1892
+
1893
+ # Calculate saturation pressure
1894
+ P_sat_, wm_H2O_, wm_CO2_, wm_H2_, wm_CO_, wm_CH4_, wm_S2m_, wm_S6p_, wm_H2S_, H2O_HT, H2_HT, CH4_HT, H2S_HT, CO2_CT, CO_CT, CH4_CT, S6p_ST, S2m_ST, H2S_ST = c.P_sat(run,PT,melt_wf,setup,species,models,psat_tol,nr_step,nr_tol)
1895
+ wm_SO3_ = (wm_S6p_*species.loc["SO3","M"])/species.loc["S","M"]
1896
+ PT["P"] = P_sat_
1897
+
1898
+ # update melt composition at saturation pressure and check for sulfur saturation
1899
+ melt_wf["H2OT"] = wm_H2O_
1900
+ melt_wf["CO2"] = wm_CO2_
1901
+ melt_wf["CO"] = wm_CO_
1902
+ melt_wf["CH4"] = wm_CH4_
1903
+ melt_wf["H2"] = wm_H2_
1904
+ melt_wf["S2-"] = wm_S2m_
1905
+ melt_wf["S6+"] = wm_S6p_
1906
+ melt_wf["H2S"] = wm_H2S_
1907
+ melt_wf["Fe3FeT"] = mg.Fe3FeT_i(run,PT,melt_wf,setup,species,models)
1908
+ melt_wf["S6ST"] = mg.S6ST(run,PT,melt_wf,setup,species,models)
1909
+
1910
+ # Set bulk composition
1911
+ wt_C, wt_O, wt_H, wt_S, wt_X, wt_Fe, wt_g_, Wt_ = c.bulk_composition(run,PT,melt_wf,setup,species,models)
1912
+ bulk_wf = {"C":wt_C,"H":wt_H,"O":wt_O,"S":wt_S,"Fe":wt_Fe,"Wt":Wt_,"X":wt_X}
1913
+
1914
+ # set system and initial guesses
1915
+ system = eq.set_system(melt_wf,models)
1916
+ guessx, guessy, guessz, guessw = eq.initial_guesses(run,PT,melt_wf,setup,species,models,system)
1917
+
1918
+
1919
+ if models.loc["P_variation","option"] == "polybaric":
1920
+ # pressure ranges and options
1921
+ starting_P = models.loc["starting_P","option"]
1922
+ if starting_P == "set":
1923
+ initial = int(setup.loc[run,"P_bar"])
1924
+ else:
1925
+ if models.loc["gassing_direction","option"] == "degas":
1926
+ answer = PT["P"]/dp_step
1927
+ answer = math.floor(answer)
1928
+ initial = round(answer*dp_step)
1929
+ elif models.loc["gassing_direction","option"] == "regas":
1930
+ initial = round(PT["P"])+1
1931
+ if models.loc["gassing_direction","option"] == "degas":
1932
+ step = int(-1*dp_step) # pressure step in bars
1933
+ final = 0
1934
+ elif models.loc["gassing_direction","option"] == "regas":
1935
+ step = int(dp_step)
1936
+ final = int(setup.loc[run,"final_P"])
1937
+
1938
+ # add some gas to the system if doing open-system regassing
1939
+ if models.loc["gassing_direction","option"] == "regas" and models.loc["gassing_style","option"] == "open":
1940
+ gas_mf = {"O2":mg.xg_O2(run,PT,melt_wf,setup,species,models),"CO":mg.xg_CO(run,PT,melt_wf,setup,species,models),"CO2":mg.xg_CO2(run,PT,melt_wf,setup,species,models),"H2":mg.xg_H2(run,PT,melt_wf,setup,species,models),"H2O":mg.xg_H2O(run,PT,melt_wf,setup,species,models),"CH4":mg.xg_CH4(run,PT,melt_wf,setup,species,models),"S2":mg.xg_S2(run,PT,melt_wf,setup,species,models),"SO2":mg.xg_SO2(run,PT,melt_wf,setup,species,models),"SO3":mg.xg_SO3(run,PT,melt_wf,setup,species,models),"H2S":mg.xg_H2S(run,PT,melt_wf,setup,species,models),"OCS":mg.xg_OCS(run,PT,melt_wf,setup,species,models),"X":mg.xg_X(run,PT,melt_wf,setup,species,models),"Xg_t":mg.Xg_tot(run,PT,melt_wf,setup,species,models),"wt_g":0.}
1941
+ wt_C, wt_H, wt_S, wt_X, wt_Fe, wt_O, Wt = new_bulk_regas_open(run,PT,melt_wf,bulk_wf,gas_mf,dwtg,setup,species,models)
1942
+ bulk_wf = {"C":wt_C,"H":wt_H,"O":wt_O,"S":wt_S,"Fe":wt_Fe,"X":wt_X,"Wt":Wt}
1943
+
1944
+ # run over different pressures #
1945
+ number_of_step = 0.
1946
+
1947
+ P = initial
1948
+ wm_ST_ = melt_wf["ST"]
1949
+ for i in range(initial,final,step):
1950
+ eq_Fe = models.loc["eq_Fe","option"]
1951
+ if models.loc["gassing_style","option"] == "open": # check melt is still vapor-saturated
1952
+ P_sat_, wm_H2O_, wm_CO2_, wm_H2_, wm_CO_, wm_CH4_, wm_S2m_, wm_S6p_, wm_H2S_, H2O_HT, H2_HT, CH4_HT, H2S_HT, CO2_CT, CO_CT, CH4_CT, S6p_ST, S2m_ST, H2S_ST = c.P_sat(run,PT,melt_wf,setup,species,models,psat_tol,nr_step,nr_tol)
1953
+ wm_SO3_ = (wm_S6p_*species.loc["SO3","M"])/species.loc["S","M"]
1954
+ P_ = P
1955
+ wm_ST__ = wm_ST_
1956
+ P = P - dp_step
1957
+ if P <= 0.:
1958
+ P = 1
1959
+ PT["P"] = P
1960
+ if P_sat_ > PT["P"]:
1961
+ # work out equilibrium partitioning between melt and gas phase
1962
+ xg_O2_, xg_H2_, xg_S2_, xg_H2O_, xg_CO_, xg_CO2_, xg_SO2_, xg_CH4_, xg_H2S_, xg_OCS_, xg_X_, Xg_t, xm_H2O_, xm_CO2_, Xm_t, wm_H2O_, wm_H2_, wm_CO2_, wm_CO_, wm_CH4_, wm_S_, wm_SO3_, wm_H2S_, wm_ST_, wm_X_, Fe32, Fe3T, S62, S6T, wt_g_O, wt_g_C, wt_g_H, wt_g_S, wt_g_X, wt_g, wt_O_, wt_C_, wt_H_, wt_S_, wt_X_, guessx, guessy, guessz, guessw = eq.mg_equilibrium(run,PT,melt_wf,bulk_wf,setup,species,models,nr_step,nr_tol,guessx,guessy,guessz,guessw)
1963
+ # gas composition
1964
+ gas_mf = {"O2":xg_O2_,"CO":xg_CO_,"S2":xg_S2_,"CO2":xg_CO2_,"H2O":xg_H2O_,"H2":xg_H2_,"CH4":xg_CH4_,"SO2":xg_SO2_,"H2S":xg_H2S_,"OCS":xg_OCS_,"X":xg_X_,"Xg_t":Xg_t,"wt_g":wt_g}
1965
+
1966
+ else:
1967
+ conc = eq.melt_speciation(PT,melt_wf,species,models,nr_step,nr_tol)
1968
+ frac = c.melt_species_ratios(conc,species)
1969
+ wm_ST_ = wm_S_ + wm_S6p_
1970
+ S62 = S6T/S2m_ST
1971
+ Fe3T = melt_wf["Fe3FeT"]
1972
+ Fe32 = mg.overtotal2ratio(Fe3T)
1973
+ xg_O2_, xg_H2_, xg_S2_, xg_H2O_, xg_CO_, xg_CO2_, xg_SO2_, xg_CH4_, xg_H2S_, xg_OCS_, xg_X, Xg_t, Xm_t, Xm_t_ox, wt_g_O, wt_g_C, wt_g_H, wt_g_S, wt_g = "","","","","","","","","","","","","","",0.,0.,0.,0.,0.
1974
+ guessx, guessy, guessz, guessw = eq.initial_guesses(run,PT,melt_wf,setup,species,models,system)
1975
+
1976
+ if P == 1 or P == P1 or P == P2:
1977
+ # set melt composition for forward calculation
1978
+ melt_wf["CO2"] = wm_CO2_
1979
+ melt_wf["H2OT"] = wm_H2O_
1980
+ melt_wf["H2"] = wm_H2_
1981
+ melt_wf["CO"] = wm_CO_
1982
+ melt_wf["CH4"] = wm_CH4_
1983
+ melt_wf["H2S"] = wm_H2S_
1984
+ melt_wf["S6+"] = wm_S6p_
1985
+ melt_wf["S2-"] = wm_S_
1986
+ melt_wf["ST"] = wm_ST_
1987
+ melt_wf["XT"] = wm_X_
1988
+ melt_wf["Fe3FeT"] = Fe3T
1989
+
1990
+ if P_sat_ < PT["P"]:
1991
+ wt_C_, wt_O_, wt_H_, wt_S_, wt_X_, wt_Fe, wt_g_, Wt_ = c.bulk_composition(run,PT,melt_wf,setup,species,models)
1992
+
1993
+ # check for sulfur saturation and display warning in outputs
1994
+ SCSS_,sulfide_sat,SCAS_,sulfate_sat, ST_ = c.sulfur_saturation(run,PT,melt_wf,setup,species,models)
1995
+ if sulfide_sat == "yes":
1996
+ warning = "WARNING: sulfide-saturated"
1997
+ elif sulfate_sat == "yes":
1998
+ warning = "WARNING: sulfate-saturated"
1999
+ else:
2000
+ warning = ""
2001
+
2002
+ # calculate fO2
2003
+ if eq_Fe == "yes":
2004
+ fO2_ = mdv.f_O2(run,PT,melt_wf,setup,species,models)
2005
+ elif eq_Fe == "no":
2006
+ fO2_ = (xg_O2_*mdv.y_O2(PT,models)*PT["P"])
2007
+
2008
+ xg_CS = mg.gas_CS(run,PT,melt_wf,setup,species,models)
2009
+ wm_CO2eq, wm_H2Oeq = mg.melt_H2O_CO2_eq(melt_wf,species)
2010
+
2011
+ # store results
2012
+ results1 = pd.DataFrame([[run,setup.loc[run,"Sample"],setup.loc[run,"DFMQ"],setup.loc[run,"H2O"],setup.loc[run,"CO2ppm"],setup.loc[run,"STppm"],setup.loc[run,"Xppm"],melt_wf["Fe3FeT"],"SORT",bulk_wf["O"],bulk_wf["C"],bulk_wf["H"],bulk_wf["S"],bulk_wf["Fe"],P_sat_,
2013
+ setup.loc[run,"SiO2"],setup.loc[run,"TiO2"],setup.loc[run,"Al2O3"],mg.Wm_FeOT(run,setup,species),setup.loc[run,"MnO"],setup.loc[run,"MgO"],setup.loc[run,"CaO"],setup.loc[run,"Na2O"],setup.loc[run,"K2O"],setup.loc[run,"P2O5"],PT["P"],PT["T"],mg.xg_O2(run,PT,melt_wf,setup,species,models),mg.xg_CO(run,PT,melt_wf,setup,species,models),mg.xg_CO2(run,PT,melt_wf,setup,species,models),mg.xg_H2(run,PT,melt_wf,setup,species,models),mg.xg_H2O(run,PT,melt_wf,setup,species,models),mg.xg_CH4(run,PT,melt_wf,setup,species,models),mg.xg_S2(run,PT,melt_wf,setup,species,models),mg.xg_SO2(run,PT,melt_wf,setup,species,models),mg.xg_H2S(run,PT,melt_wf,setup,species,models),mg.xg_OCS(run,PT,melt_wf,setup,species,models),mg.xg_X(run,PT,melt_wf,setup,species,models),mg.Xg_tot(run,PT,melt_wf,setup,species,models),xg_CS,
2014
+ mg.xm_CO2_so(run,melt_wf,setup,species),mg.xm_H2OT_so(run,melt_wf,setup,species),mg.Xm_t_so(run,melt_wf,setup,species),"",
2015
+ wm_CO2eq,wm_H2Oeq,melt_wf["CO2"],melt_wf["H2OT"],wm_H2_,wm_CO_,wm_CH4_,wm_S2m_,wm_SO3_,wm_H2S_,melt_wf["ST"],melt_wf["XT"],mg.Fe3Fe2(melt_wf),melt_wf["Fe3FeT"],mg.S6S2(run,PT,melt_wf,setup,species,models),mg.S6ST(run,PT,melt_wf,setup,species,models),
2016
+ mg.fO22Dbuffer(PT,mdv.f_O2(run,PT,melt_wf,setup,species,models),"FMQ",models),mg.fO22Dbuffer(PT,mdv.f_O2(run,PT,melt_wf,setup,species,models),"NNO",models),wt_g,
2017
+ mdv.f_O2(run,PT,melt_wf,setup,species,models),setup.loc[run,"DFMQ"]-mg.fO22Dbuffer(PT,mdv.f_O2(run,PT,melt_wf,setup,species,models),"FMQ",models)]])
2018
+
2019
+ if P == P1:
2020
+ results_chemistry_P1 = pd.concat([results_chemistry_P1, results1], ignore_index=True)
2021
+ if models.loc["output csv","option"] == "yes":
2022
+ results_chemistry_P1.to_csv('results_P1.csv', index=False, header=False)
2023
+ if P == P2:
2024
+ results_chemistry_P1 = pd.concat([results_chemistry_P2, results1], ignore_index=True)
2025
+ if models.loc["output csv","option"] == "yes":
2026
+ results_chemistry_P2.to_csv('results_P2.csv', index=False, header=False)
2027
+ if P == 1:
2028
+ results_chemistry_1 = pd.concat([results_chemistry_1, results1], ignore_index=True)
2029
+ if models.loc["output csv","option"] == "yes":
2030
+ results_chemistry_1.to_csv('results_1bar.csv', index=False, header=False)
2031
+ if models.loc["print status","option"] == "yes":
2032
+ print("done", datetime.datetime.now())
2033
+ return results_chemistry_P1, results_chemistry_P2, results_chemistry_1