PetThermoTools 0.2.40__tar.gz → 0.2.42__tar.gz
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.
- {PetThermoTools-0.2.40/src/PetThermoTools.egg-info → PetThermoTools-0.2.42}/PKG-INFO +1 -1
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/setup.py +1 -1
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools/Barom.py +24 -1
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools/GenFuncs.py +74 -24
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools/Liq.py +46 -4
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools/MELTS.py +3 -1
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools/Melting.py +105 -52
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools/Path.py +60 -18
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools/PhaseDiagrams.py +32 -1
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools/Plotting.py +395 -164
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools/Saturation.py +5 -0
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools/_version.py +1 -1
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42/src/PetThermoTools.egg-info}/PKG-INFO +1 -1
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools.egg-info/requires.txt +1 -1
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/LICENSE.txt +0 -0
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/README.md +0 -0
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/setup.cfg +0 -0
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools/Compositions.py +0 -0
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools/Holland.py +0 -0
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools/Installation.py +0 -0
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools/Path_wrappers.py +0 -0
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools/__init__.py +0 -0
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools.egg-info/SOURCES.txt +0 -0
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools.egg-info/dependency_links.txt +0 -0
- {PetThermoTools-0.2.40 → PetThermoTools-0.2.42}/src/PetThermoTools.egg-info/top_level.txt +0 -0
@@ -186,8 +186,31 @@ def mineral_cosaturation(Model="MELTSv1.0.2", cores=int(np.floor(multiprocessing
|
|
186
186
|
Results : dict
|
187
187
|
Raw simulation outputs for each pressure step.
|
188
188
|
"""
|
189
|
-
|
189
|
+
## make sure everything is a float
|
190
|
+
T_initial_C = to_float(T_initial_C)
|
191
|
+
T_maxdrop_C = to_float(T_maxdrop_C)
|
192
|
+
T_cut_C = to_float(T_cut_C)
|
193
|
+
|
194
|
+
P_bar = to_float(P_bar)
|
195
|
+
|
196
|
+
Fe3Fet_init= to_float(Fe3Fet_init)
|
197
|
+
H2O_init = to_float(H2O_init)
|
198
|
+
CO2_init = to_float(CO2_init)
|
199
|
+
fO2_offset = to_float(fO2_offset)
|
200
|
+
|
190
201
|
comp = bulk.copy()
|
202
|
+
|
203
|
+
if fO2_buffer is not None:
|
204
|
+
if fO2_buffer != "NNO":
|
205
|
+
if fO2_buffer != "FMQ":
|
206
|
+
raise Warning("fO2 buffer specified is not an allowed input. This argument can only be 'FMQ' or 'NNO' \n if you want to offset from these buffers use the 'fO2_offset' argument.")
|
207
|
+
|
208
|
+
if "MELTS" not in Model:
|
209
|
+
if fO2_buffer == "FMQ":
|
210
|
+
fO2_buffer = "qfm"
|
211
|
+
if fO2_buffer == "NNO":
|
212
|
+
fO2_buffer = "nno"
|
213
|
+
|
191
214
|
if H2O_Sat:
|
192
215
|
comp['H2O_Liq'] = 20
|
193
216
|
|
@@ -4,52 +4,64 @@ import pandas as pd
|
|
4
4
|
# from PetThermoTools.Liq import *
|
5
5
|
# from PetThermoTools.Crystallise import *
|
6
6
|
from PetThermoTools.MELTS import *
|
7
|
+
from PetThermoTools.Compositions import *
|
7
8
|
# try:
|
8
9
|
# from PetThermoTools.Holland import *
|
9
10
|
# except:
|
10
11
|
# pass
|
11
12
|
|
12
13
|
Names = {'liquid1': '_Liq',
|
13
|
-
'liquid2': '_Liq2',
|
14
|
-
'liquid3': '_Liq3',
|
15
|
-
'liquid4': '_Liq4',
|
16
14
|
'olivine1': '_Ol',
|
17
|
-
'
|
15
|
+
'orthopyroxene1': '_Opx',
|
18
16
|
'clinopyroxene1': '_Cpx',
|
19
|
-
'
|
17
|
+
'garnet1': '_Grt',
|
18
|
+
'spinel1': '_Sp',
|
19
|
+
'k-feldspar1': '_Kspar',
|
20
|
+
'quartz1': '_Qtz',
|
21
|
+
'rhm-oxide1': '_Rhm',
|
22
|
+
'apatite1': '_Apa',
|
23
|
+
'olivine2': '_Ol2',
|
20
24
|
'plagioclase1': '_Plag',
|
25
|
+
'clinopyroxene2': '_Cpx2',
|
21
26
|
'plagioclase2': '_Plag2',
|
22
|
-
'spinel1': '_Sp',
|
23
27
|
'spinel2': '_Sp2',
|
24
|
-
'k-feldspar1': '_Kspar',
|
25
28
|
'k-feldspar2': '_Kspar2',
|
26
|
-
'garnet1': '_Grt',
|
27
29
|
'garnet2': '_Grt2',
|
28
|
-
'rhm-oxide1': '_Rhm',
|
29
30
|
'rhm-oxide2': '_Rhm2',
|
30
|
-
'quartz1': '_Qtz',
|
31
31
|
'quartz2': '_Qtz2',
|
32
|
-
'orthopyroxene1': '_Opx',
|
33
32
|
'orthopyroxene2': '_Opx2',
|
34
|
-
'
|
35
|
-
'
|
33
|
+
'apatite2': '_Apa2',
|
34
|
+
'liquid2': '_Liq2',
|
35
|
+
'liquid3': '_Liq3',
|
36
|
+
'liquid4': '_Liq4'}
|
36
37
|
|
37
38
|
Names_MM = {'liq1': '_Liq',
|
38
|
-
'liq2': '_Liq2',
|
39
|
-
'liq3': '_Liq3',
|
40
|
-
'liq4': '_Liq4',
|
41
39
|
'ol1': '_Ol',
|
42
|
-
'
|
40
|
+
'opx1': '_Opx',
|
43
41
|
'cpx1': '_Cpx',
|
42
|
+
'g1': '_Grt',
|
43
|
+
'spl1': '_Sp',
|
44
|
+
'fsp1': '_Plag',
|
45
|
+
'ol2': '_Ol2',
|
44
46
|
'cpx2': '_Cpx2',
|
45
|
-
'opx1': '_Opx',
|
46
47
|
'opx2': '_Opx2',
|
47
|
-
'g1': '_Grt',
|
48
48
|
'g2': '_Grt2',
|
49
|
-
'fsp1': '_Plag',
|
50
49
|
'fsp2': '_Plag2',
|
51
|
-
'
|
52
|
-
'
|
50
|
+
'spl2': '_Sp2',
|
51
|
+
'liq2': '_Liq2',
|
52
|
+
'liq3': '_Liq3',
|
53
|
+
'liq4': '_Liq4'}
|
54
|
+
|
55
|
+
def to_float(x):
|
56
|
+
if x is None:
|
57
|
+
return None
|
58
|
+
if isinstance(x, (int, float)):
|
59
|
+
return float(x)
|
60
|
+
if isinstance(x, (list, tuple)):
|
61
|
+
return [float(v) for v in x]
|
62
|
+
if isinstance(x, np.ndarray):
|
63
|
+
return x.astype(float)
|
64
|
+
return x # leave unchanged if unexpected type
|
53
65
|
|
54
66
|
def label_results(Result,label):
|
55
67
|
Results = Result.copy()
|
@@ -93,6 +105,36 @@ def supCalc(Model = "MELTSv1.0.2", bulk = None, phase = None, T_C = None, P_bar
|
|
93
105
|
|
94
106
|
return Results
|
95
107
|
|
108
|
+
def comp_check(comp_lith, Model, MELTS_filter, Fe3Fet):
|
109
|
+
if type(comp_lith) == str:
|
110
|
+
if Model != "pyMelt":
|
111
|
+
comp = Compositions[comp_lith]
|
112
|
+
else:
|
113
|
+
comp = comp_lith
|
114
|
+
else:
|
115
|
+
comp = comp_lith.copy()
|
116
|
+
|
117
|
+
# if comp is entered as a pandas series, it must first be converted to a dict
|
118
|
+
if Model != "pyMelt":
|
119
|
+
if type(comp) == pd.core.series.Series:
|
120
|
+
comp = comp.to_dict()
|
121
|
+
|
122
|
+
comp = comp_fix(Model = Model, comp = comp, Fe3Fet_Liq = Fe3Fet)
|
123
|
+
|
124
|
+
if "MELTS" in Model and MELTS_filter == True:
|
125
|
+
if type(comp) == pd.core.frame.DataFrame:
|
126
|
+
comp['K2O_Liq'] = np.zeros(len(comp['SiO2_Liq']))
|
127
|
+
comp['P2O5_Liq'] = np.zeros(len(comp['SiO2_Liq']))
|
128
|
+
comp['H2O_Liq'] = np.zeros(len(comp['SiO2_Liq']))
|
129
|
+
comp['CO2_Liq'] = np.zeros(len(comp['SiO2_Liq']))
|
130
|
+
else:
|
131
|
+
comp['K2O_Liq'] = 0
|
132
|
+
comp['P2O5_Liq'] = 0
|
133
|
+
comp['H2O_Liq'] = 0
|
134
|
+
comp['CO2_Liq'] = 0
|
135
|
+
|
136
|
+
return comp
|
137
|
+
|
96
138
|
|
97
139
|
def comp_fix(Model = None, comp = None, Fe3Fet_Liq = None, H2O_Liq = None, CO2_Liq = None):
|
98
140
|
'''
|
@@ -345,12 +387,20 @@ def stich_work(Results = None, Order = None, Model = "MELTS", Frac_fluid = None,
|
|
345
387
|
Results_Mass['fluid1_cumsum'] = Results_Mass['fluid1'].cumsum()
|
346
388
|
elif Frac_fluid is None:
|
347
389
|
for n in SN:
|
348
|
-
if n != 'liquid1' and n!= 'fluid1':
|
390
|
+
if n != 'liquid1' and n!= 'fluid1' and n != 'liq1' and n != 'fl1':
|
349
391
|
Results_Mass[n + '_cumsum'] = Results_Mass[n].cumsum()
|
392
|
+
if 'liq1' in SN:
|
393
|
+
Results_Mass[n + '_cumsum'] = Results_Mass.loc[0, 'liq1'] - Results_Mass.loc[:,Results_Mass.columns.str.contains('_cumsum')].sum(axis = 1)
|
394
|
+
elif 'liquid1' in SN:
|
395
|
+
Results_Mass[n + '_cumsum'] = Results_Mass.loc[0, 'liquid1'] - Results_Mass.loc[:,Results_Mass.columns.str.contains('_cumsum')].sum(axis = 1)
|
350
396
|
else:
|
351
397
|
for n in SN:
|
352
|
-
if n != 'liquid1':
|
398
|
+
if n != 'liquid1' and n != 'liq1':
|
353
399
|
Results_Mass[n + '_cumsum'] = Results_Mass[n].cumsum()
|
400
|
+
if 'liq1' in SN:
|
401
|
+
Results_Mass[n + '_cumsum'] = Results_Mass.loc[0, 'liq1'] - Results_Mass.loc[:,Results_Mass.columns.str.contains('_cumsum')].sum(axis = 1)
|
402
|
+
elif 'liquid1' in SN:
|
403
|
+
Results_Mass[n + '_cumsum'] = Results_Mass.loc[0, 'liquid1'] - Results_Mass.loc[:,Results_Mass.columns.str.contains('_cumsum')].sum(axis = 1)
|
354
404
|
|
355
405
|
Results_All = Results['Conditions'].copy()
|
356
406
|
for R in Results:
|
@@ -16,6 +16,26 @@ def equilibrate_multi(cores = None, Model = None, bulk = None, T_C = None, P_bar
|
|
16
16
|
Fe3Fet_Liq = None, H2O_Liq = None, CO2_Liq = None, fO2_buffer = None, fO2_offset = None,
|
17
17
|
timeout = None, copy_columns = None, Suppress = None):
|
18
18
|
|
19
|
+
T_C = to_float(T_C)
|
20
|
+
|
21
|
+
P_bar = to_float(P_bar)
|
22
|
+
|
23
|
+
H2O_Liq = to_float(H2O_Liq)
|
24
|
+
CO2_Liq = to_float(CO2_Liq)
|
25
|
+
Fe3Fet_Liq = to_float(Fe3Fet_Liq)
|
26
|
+
fO2_offset = to_float(fO2_offset)
|
27
|
+
|
28
|
+
if fO2_buffer is not None:
|
29
|
+
if fO2_buffer != "NNO":
|
30
|
+
if fO2_buffer != "FMQ":
|
31
|
+
raise Warning("fO2 buffer specified is not an allowed input. This argument can only be 'FMQ' or 'NNO' \n if you want to offset from these buffers use the 'fO2_offset' argument.")
|
32
|
+
|
33
|
+
if "MELTS" not in Model:
|
34
|
+
if fO2_buffer == "FMQ":
|
35
|
+
fO2_buffer = "qfm"
|
36
|
+
if fO2_buffer == "NNO":
|
37
|
+
fO2_buffer = "nno"
|
38
|
+
|
19
39
|
if "MELTS" in Model:
|
20
40
|
try:
|
21
41
|
from meltsdynamic import MELTSdynamic
|
@@ -410,6 +430,17 @@ def findCO2_multi(cores = None, Model = None, bulk = None, T_initial_C = None, P
|
|
410
430
|
except:
|
411
431
|
Warning('alphaMELTS for Python files are not on the python path. \n Please add these files to the path running \n import sys \n sys.path.append(r"insert_your_path_to_melts_here") \n You are looking for the location of the meltsdynamic.py file')
|
412
432
|
|
433
|
+
if fO2_buffer is not None:
|
434
|
+
if fO2_buffer != "NNO":
|
435
|
+
if fO2_buffer != "FMQ":
|
436
|
+
raise Warning("fO2 buffer specified is not an allowed input. This argument can only be 'FMQ' or 'NNO' \n if you want to offset from these buffers use the 'fO2_offset' argument.")
|
437
|
+
|
438
|
+
if "MELTS" not in Model:
|
439
|
+
if fO2_buffer == "FMQ":
|
440
|
+
fO2_buffer = "qfm"
|
441
|
+
if fO2_buffer == "NNO":
|
442
|
+
fO2_buffer = "nno"
|
443
|
+
|
413
444
|
comp = bulk.copy()
|
414
445
|
|
415
446
|
if Model is None:
|
@@ -607,11 +638,22 @@ def findLiq_multi(cores = None, Model = None, bulk = None, T_initial_C = None, P
|
|
607
638
|
|
608
639
|
comp = bulk.copy()
|
609
640
|
|
641
|
+
if fO2_buffer is not None:
|
642
|
+
if fO2_buffer != "NNO":
|
643
|
+
if fO2_buffer != "FMQ":
|
644
|
+
raise Warning("fO2 buffer specified is not an allowed input. This argument can only be 'FMQ' or 'NNO' \n if you want to offset from these buffers use the 'fO2_offset' argument.")
|
645
|
+
|
646
|
+
if "MELTS" not in Model:
|
647
|
+
if fO2_buffer == "FMQ":
|
648
|
+
fO2_buffer = "qfm"
|
649
|
+
if fO2_buffer == "NNO":
|
650
|
+
fO2_buffer = "nno"
|
651
|
+
|
610
652
|
if Model is None:
|
611
653
|
Model = "MELTSv1.0.2"
|
612
654
|
|
613
|
-
if Model == "Holland":
|
614
|
-
|
655
|
+
# if Model == "Holland":
|
656
|
+
# import pyMAGEMINcalc as MM
|
615
657
|
|
616
658
|
# if comp is entered as a pandas series, it must first be converted to a dict
|
617
659
|
if type(comp) == pd.core.series.Series:
|
@@ -792,8 +834,8 @@ def findLiq_multi(cores = None, Model = None, bulk = None, T_initial_C = None, P
|
|
792
834
|
else:
|
793
835
|
return Res
|
794
836
|
else:
|
795
|
-
T_Liq = MM.findLiq_multi(P_bar = P_bar, T_initial_C = T_initial_C, comp = comp)
|
796
|
-
return
|
837
|
+
# T_Liq = MM.findLiq_multi(P_bar = P_bar, T_initial_C = T_initial_C, comp = comp)
|
838
|
+
return "find liquidus calculations are currently not available through the MAGEMin models. This is an issue I'm working to fix as soon as possible."
|
797
839
|
|
798
840
|
def findCO2(q, index, *, Model = None, P_bar = None, T_initial_C = None, comp = None, fO2_buffer = None, fO2_offset = None):
|
799
841
|
T_Liq = 0
|
@@ -1572,7 +1572,9 @@ def findSatPressure_MELTS(Model = None, T_C_init = None, T_fixed_C = None, P_bar
|
|
1572
1572
|
else:
|
1573
1573
|
return out
|
1574
1574
|
|
1575
|
-
def AdiabaticDecompressionMelting_MELTS(Model = None, comp = None, Tp_C = None,
|
1575
|
+
def AdiabaticDecompressionMelting_MELTS(Model = None, comp = None, Tp_C = None, Tp_Method = None,
|
1576
|
+
P_path_bar = None, P_start_bar = None, P_end_bar = None, dp_bar = None,
|
1577
|
+
Frac = False, fO2_buffer = None, fO2_offset = None):
|
1576
1578
|
try:
|
1577
1579
|
import pyMelt as m
|
1578
1580
|
Lithologies = {'KLB-1': m.lithologies.matthews.klb1(),
|
@@ -10,37 +10,6 @@ from multiprocessing import Process
|
|
10
10
|
import time
|
11
11
|
import sys
|
12
12
|
from tqdm.notebook import tqdm, trange
|
13
|
-
# import pyMelt as m
|
14
|
-
|
15
|
-
def comp_check(comp_lith, Model, MELTS_filter, Fe3Fet):
|
16
|
-
if type(comp_lith) == str:
|
17
|
-
if Model != "pyMelt":
|
18
|
-
comp = Compositions[comp_lith]
|
19
|
-
else:
|
20
|
-
comp = comp_lith
|
21
|
-
else:
|
22
|
-
comp = comp_lith.copy()
|
23
|
-
|
24
|
-
# if comp is entered as a pandas series, it must first be converted to a dict
|
25
|
-
if Model != "pyMelt":
|
26
|
-
if type(comp) == pd.core.series.Series:
|
27
|
-
comp = comp.to_dict()
|
28
|
-
|
29
|
-
comp = comp_fix(Model = Model, comp = comp, Fe3Fet_Liq = Fe3Fet)
|
30
|
-
|
31
|
-
if "MELTS" in Model and MELTS_filter == True:
|
32
|
-
if type(comp) == pd.core.frame.DataFrame:
|
33
|
-
comp['K2O_Liq'] = np.zeros(len(comp['SiO2_Liq']))
|
34
|
-
comp['P2O5_Liq'] = np.zeros(len(comp['SiO2_Liq']))
|
35
|
-
comp['H2O_Liq'] = np.zeros(len(comp['SiO2_Liq']))
|
36
|
-
comp['CO2_Liq'] = np.zeros(len(comp['SiO2_Liq']))
|
37
|
-
else:
|
38
|
-
comp['K2O_Liq'] = 0
|
39
|
-
comp['P2O5_Liq'] = 0
|
40
|
-
comp['H2O_Liq'] = 0
|
41
|
-
comp['CO2_Liq'] = 0
|
42
|
-
|
43
|
-
return comp
|
44
13
|
|
45
14
|
def AdiabaticDecompressionMelting(cores = multiprocessing.cpu_count(),
|
46
15
|
Model = "pMELTS", bulk = "KLB-1", comp_lith_1 = None,
|
@@ -48,22 +17,105 @@ def AdiabaticDecompressionMelting(cores = multiprocessing.cpu_count(),
|
|
48
17
|
P_start_bar = 30000, P_end_bar = 2000, dp_bar = 200,
|
49
18
|
P_path_bar = None, Frac = False, prop = None,
|
50
19
|
fO2_buffer = None, fO2_offset = None, Fe3Fet = None, MELTS_filter = True):
|
20
|
+
"""
|
21
|
+
Perform adiabatic decompression melting calculations using MELTS, MAGEMin, or pyMelt.
|
22
|
+
|
23
|
+
Simulates mantle melting along an adiabatic upwelling path (e.g., ridge or plume) with user-defined
|
24
|
+
starting potential temperature, pressure range, and step size. Supports single-lithology mantle sources
|
25
|
+
(e.g., KLB-1) at present, with expansion to multi-lithology systems in development.
|
26
|
+
|
27
|
+
Parameters
|
28
|
+
----------
|
29
|
+
cores : int, optional
|
30
|
+
Number of CPU cores to use for multiprocessing. Defaults to total available.
|
31
|
+
Model : str, optional
|
32
|
+
Thermodynamic model. MELTS variants: "MELTSv1.0.2", "MELTSv1.1.0", "MELTSv1.2.0", "pMELTS";
|
33
|
+
or MAGEMin: "Green2025", "Weller2024". Alternatively calculations can be performed using
|
34
|
+
pyMelt (Matthews et al. 2020): "pyMelt"
|
35
|
+
bulk : dict ot str, optional
|
36
|
+
Bulk composition name or composition dictionary.
|
37
|
+
Default is "KLB-1".
|
38
|
+
Tp_C : float or np.ndarray, optional
|
39
|
+
Mantle potential temperature(s) in °C. Default is 1350.
|
40
|
+
Tp_Method : str, optional
|
41
|
+
Method to calculate the starting pressure for adiabatic melting. Default is "pyMelt".
|
42
|
+
P_start_bar, P_end_bar, dp_bar : float or array, optional
|
43
|
+
Starting, ending, and step size pressures (in bar) for adiabatic decompression.
|
44
|
+
Defaults: 30000, 2000, and 200, respectively.
|
45
|
+
P_path_bar : np.ndarray, optional
|
46
|
+
User-specified pressure path (in bar). If given, overrides `P_start_bar`, `P_end_bar`, and `dp_bar`.
|
47
|
+
fO2_buffer : {"FMQ", "NNO"}, optional
|
48
|
+
Redox buffer for constraining oxygen fugacity.
|
49
|
+
fO2_offset : float, optional
|
50
|
+
Offset (log units) from the chosen fO2 buffer.
|
51
|
+
Fe3Fet : float, optional
|
52
|
+
Initial Fe³⁺/ΣFe ratio for the bulk composition. If None, values is taken from the "bulk" variable or set according to fO2 buffer positions.
|
53
|
+
MELTS_filter : bool, default=True
|
54
|
+
If True, filters oxide components to avoid issues in MELTS calculations (e.g., K2O content set to 0.0).
|
55
|
+
|
56
|
+
Returns
|
57
|
+
-------
|
58
|
+
Results : dict
|
59
|
+
Dictionary containing DataFrames for the system and phase compositions and properties.
|
60
|
+
|
61
|
+
Notes
|
62
|
+
-----
|
63
|
+
- Currently limited to single-lithology melting.
|
64
|
+
- Normalizes output mass so that total initial mass = 1.
|
65
|
+
|
66
|
+
Examples
|
67
|
+
--------
|
68
|
+
Run a single adiabatic decompression path from 3.0 GPa to 0.2 GPa:
|
69
|
+
|
70
|
+
>>> results = AdiabaticDecompressionMelting(Model="pMELTS", bulk="KLB-1",
|
71
|
+
... Tp_C=1350, P_start_bar=30000,
|
72
|
+
... P_end_bar=2000, dp_bar=200)
|
73
|
+
|
74
|
+
Run with an explicit pressure path:
|
75
|
+
|
76
|
+
>>> import numpy as np
|
77
|
+
>>> P_path = np.linspace(30000, 2000, 20)
|
78
|
+
>>> results = AdiabaticDecompressionMelting(Model="pMELTS", comp_lith_1="KLB-1",
|
79
|
+
... P_path_bar=P_path, Tp_C=1400)
|
80
|
+
"""
|
51
81
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
82
|
+
Tp_C = to_float(Tp_C)
|
83
|
+
|
84
|
+
P_path_bar = to_float(P_path_bar)
|
85
|
+
P_start_bar= to_float(P_start_bar)
|
86
|
+
P_end_bar = to_float(P_end_bar)
|
87
|
+
dp_bar = to_float(dp_bar)
|
88
|
+
|
89
|
+
Fe3Fet = to_float(Fe3Fet)
|
90
|
+
fO2_offset = to_float(fO2_offset)
|
91
|
+
|
92
|
+
if fO2_buffer is not None:
|
93
|
+
if fO2_buffer != "NNO":
|
94
|
+
if fO2_buffer != "FMQ":
|
95
|
+
raise Warning("fO2 buffer specified is not an allowed input. This argument can only be 'FMQ' or 'NNO' \n if you want to offset from these buffers use the 'fO2_offset' argument.")
|
96
|
+
|
97
|
+
if "MELTS" not in Model:
|
98
|
+
if fO2_buffer == "FMQ":
|
99
|
+
fO2_buffer = "qfm"
|
100
|
+
if fO2_buffer == "NNO":
|
101
|
+
fO2_buffer = "nno"
|
102
|
+
|
103
|
+
# if Tp_Method == "pyMelt":
|
104
|
+
# try:
|
105
|
+
# import pyMelt as m
|
106
|
+
# Lithologies = {'KLB-1': m.lithologies.matthews.klb1(),
|
107
|
+
# 'KG1': m.lithologies.matthews.kg1(),
|
108
|
+
# 'G2': m.lithologies.matthews.eclogite(),
|
109
|
+
# 'hz': m.lithologies.shorttle.harzburgite()}
|
110
|
+
# except ImportError:
|
111
|
+
# raise RuntimeError('You havent installed pyMelt or there is an error when importing pyMelt. pyMelt is currently required to estimate the starting point for the melting calculations.')
|
61
112
|
|
62
113
|
if bulk is not None and comp_lith_1 is None:
|
63
114
|
comp_lith_1 = bulk
|
64
115
|
|
65
116
|
comp_1 = comp_check(comp_lith_1, Model, MELTS_filter, Fe3Fet)
|
66
117
|
|
118
|
+
# place holders for when code is expanded to account for multi-lithology mantle
|
67
119
|
if comp_lith_2 is not None:
|
68
120
|
comp_2 = comp_check(comp_lith_2, Model, MELTS_filter, Fe3Fet)
|
69
121
|
else:
|
@@ -74,6 +126,8 @@ def AdiabaticDecompressionMelting(cores = multiprocessing.cpu_count(),
|
|
74
126
|
else:
|
75
127
|
comp_3 = None
|
76
128
|
|
129
|
+
|
130
|
+
# At present calculations only work for a single simulation - this represents a placeholder for when the code is expanded to account for multiple simulations
|
77
131
|
One = 0
|
78
132
|
if Model != "pyMelt":
|
79
133
|
if type(comp_1) == pd.core.frame.DataFrame: # simplest scenario - one calculation per bulk composition imported
|
@@ -114,7 +168,7 @@ def AdiabaticDecompressionMelting(cores = multiprocessing.cpu_count(),
|
|
114
168
|
if One == 1:
|
115
169
|
p = Process(target = AdiabaticMelt, args = (q, 1),
|
116
170
|
kwargs = {'Model': Model, 'comp_1': comp_1, 'comp_2': comp_2, 'comp_3': comp_3,
|
117
|
-
'Tp_C': Tp_C, 'P_path_bar': P_path_bar,
|
171
|
+
'Tp_C': Tp_C, 'Tp_Method': Tp_Method, 'P_path_bar': P_path_bar,
|
118
172
|
'P_start_bar': P_start_bar, 'P_end_bar': P_end_bar, 'dp_bar': dp_bar,
|
119
173
|
'fO2_buffer': fO2_buffer, 'fO2_offset': fO2_offset, 'Frac': Frac, 'prop': prop})
|
120
174
|
|
@@ -156,7 +210,7 @@ def AdiabaticDecompressionMelting(cores = multiprocessing.cpu_count(),
|
|
156
210
|
|
157
211
|
return Results
|
158
212
|
|
159
|
-
def AdiabaticMelt(q, index, *, Model = None, comp_1 = None, comp_2 = None, comp_3 = None,
|
213
|
+
def AdiabaticMelt(q, index, *, Model = None, comp_1 = None, comp_2 = None, comp_3 = None, Tp_Method = "pyMelt",
|
160
214
|
Tp_C = None, P_start_bar = None, P_end_bar = None, dp_bar = None, P_path_bar = None,
|
161
215
|
Frac = None, fO2_buffer = None, fO2_offset = None, prop = None):
|
162
216
|
'''
|
@@ -166,7 +220,7 @@ def AdiabaticMelt(q, index, *, Model = None, comp_1 = None, comp_2 = None, comp_
|
|
166
220
|
Results = {}
|
167
221
|
if "MELTS" in Model:
|
168
222
|
try:
|
169
|
-
Results = AdiabaticDecompressionMelting_MELTS(Model = Model, comp = comp_1, Tp_C = Tp_C,
|
223
|
+
Results = AdiabaticDecompressionMelting_MELTS(Model = Model, comp = comp_1, Tp_C = Tp_C, Tp_Method = "pyMelt",
|
170
224
|
P_path_bar = P_path_bar, P_start_bar = P_start_bar, P_end_bar = P_end_bar, dp_bar = dp_bar,
|
171
225
|
fO2_buffer = fO2_buffer, fO2_offset = fO2_offset)
|
172
226
|
q.put([Results, index])
|
@@ -239,10 +293,6 @@ def AdiabaticMelt(q, index, *, Model = None, comp_1 = None, comp_2 = None, comp_
|
|
239
293
|
return
|
240
294
|
|
241
295
|
else:
|
242
|
-
# import pyMAGEMINcalc as MM
|
243
|
-
# Results = MM.AdiabaticDecompressionMelting(comp = comp_1, T_p_C = Tp_C, P_start_kbar = P_start_bar/1000, P_end_kbar = P_end_bar/1000, dp_kbar = dp_bar/1000, Frac = 0)
|
244
|
-
# print('Note that the ability to use MAGEMin to performed adiabatic decompression melting in PetThermoTools has been temporarily disabled. The underlying issue will be fixed soon and this funciton will once again become available.')
|
245
|
-
|
246
296
|
try:
|
247
297
|
import pyMelt as m
|
248
298
|
Lithologies = {'KLB-1': m.lithologies.matthews.klb1(),
|
@@ -252,10 +302,13 @@ def AdiabaticMelt(q, index, *, Model = None, comp_1 = None, comp_2 = None, comp_
|
|
252
302
|
except ImportError:
|
253
303
|
raise RuntimeError('You havent installed pyMelt or there is an error when importing pyMelt. pyMelt is currently required to estimate the starting point for the melting calculations.')
|
254
304
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
305
|
+
if Tp_Method == "pyMelt":
|
306
|
+
lz = m.lithologies.matthews.klb1()
|
307
|
+
mantle = m.mantle([lz], [1], ['Lz'])
|
308
|
+
T_start_C = mantle.adiabat(P_start_bar/10000.0, Tp_C)
|
309
|
+
else:
|
310
|
+
T_start_C = None
|
311
|
+
|
259
312
|
from juliacall import Main as jl, convert as jlconvert
|
260
313
|
|
261
314
|
jl.seval("using MAGEMinCalc")
|
@@ -265,7 +318,7 @@ def AdiabaticMelt(q, index, *, Model = None, comp_1 = None, comp_2 = None, comp_
|
|
265
318
|
if type(comp_1) == dict:
|
266
319
|
comp_julia = jl.seval("Dict")(comp_1)
|
267
320
|
else:
|
268
|
-
comp_new = comp_1.loc[
|
321
|
+
comp_new = comp_1.loc[0].to_dict()
|
269
322
|
comp_julia = jl.seval("Dict")(comp_new)
|
270
323
|
|
271
324
|
Output_jl = jl.MAGEMinCalc.AdiabaticDecompressionMelting(comp = comp_julia, P_start_kbar = P_start_bar/1000.0,
|
@@ -98,6 +98,26 @@ def multi_path(cores = None, Model = None, bulk = None, comp = None, Frac_solid
|
|
98
98
|
Dictionary with each run's label as key. Values are sub-dictionaries of phase/property DataFrames.
|
99
99
|
Includes `Input` key summarizing model configuration per run.
|
100
100
|
"""
|
101
|
+
## make sure everything is a float
|
102
|
+
T_C = to_float(T_C)
|
103
|
+
T_path_C = to_float(T_path_C)
|
104
|
+
T_start_C = to_float(T_start_C)
|
105
|
+
T_end_C = to_float(T_end_C)
|
106
|
+
dt_C = to_float(dt_C)
|
107
|
+
|
108
|
+
P_bar = to_float(P_bar)
|
109
|
+
P_path_bar = to_float(P_path_bar)
|
110
|
+
P_start_bar= to_float(P_start_bar)
|
111
|
+
P_end_bar = to_float(P_end_bar)
|
112
|
+
dp_bar = to_float(dp_bar)
|
113
|
+
|
114
|
+
Fe3Fet_init= to_float(Fe3Fet_init)
|
115
|
+
Fe3Fet_Liq = to_float(Fe3Fet_Liq)
|
116
|
+
H2O_init = to_float(H2O_init)
|
117
|
+
H2O_Liq = to_float(H2O_Liq)
|
118
|
+
CO2_init = to_float(CO2_init)
|
119
|
+
CO2_Liq = to_float(CO2_Liq)
|
120
|
+
fO2_offset = to_float(fO2_offset)
|
101
121
|
|
102
122
|
if timeout is None:
|
103
123
|
timeout = 180
|
@@ -150,10 +170,12 @@ def multi_path(cores = None, Model = None, bulk = None, comp = None, Frac_solid
|
|
150
170
|
if "MELTS" not in Model:
|
151
171
|
if fO2_buffer == "FMQ":
|
152
172
|
fO2_buffer = "qfm"
|
173
|
+
if fO2_buffer == "NNO":
|
174
|
+
fO2_buffer = "nno"
|
153
175
|
|
154
176
|
# ensure the bulk composition has the correct headers etc.
|
155
177
|
comp = comp_fix(Model = Model, comp = comp, Fe3Fet_Liq = Fe3Fet_init, H2O_Liq = H2O_init, CO2_Liq = CO2_init)
|
156
|
-
|
178
|
+
|
157
179
|
if type(comp) == dict:
|
158
180
|
if comp['H2O_Liq'] == 0.0 and "MELTS" in Model:
|
159
181
|
raise Warning("Adding small amounts of H$_{2}$O may improve the ability of MELTS to accurately reproduce the saturation of oxide minerals. Additionally, sufficient H$_{2}$O is required in the model for MELTS to predict the crystallisation of apatite, rather than whitlockite.")
|
@@ -473,28 +495,48 @@ def path_multi(q, index, *, Model = None, comp = None, Frac_solid = None, Frac_f
|
|
473
495
|
|
474
496
|
jl.seval("using MAGEMinCalc")
|
475
497
|
|
476
|
-
|
477
498
|
for i in index:
|
478
499
|
try:
|
479
500
|
if "MELTS" in Model:
|
480
501
|
if type(comp) == dict:
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
502
|
+
if trail is not None:
|
503
|
+
Results, tr = path_MELTS(Model = Model, comp = comp, Frac_solid = Frac_solid, Frac_fluid = Frac_fluid,
|
504
|
+
T_initial_C = 1400, T_C = T_C[i], T_path_C = T_path_C[i], T_start_C = T_start_C[i],
|
505
|
+
T_end_C = T_end_C[i], dt_C = dt_C[i], P_bar = P_bar[i], P_path_bar = P_path_bar[i],
|
506
|
+
P_start_bar = P_start_bar[i], P_end_bar = P_end_bar[i], dp_bar = dp_bar[i],
|
507
|
+
isenthalpic = isenthalpic, isentropic = isentropic, isochoric = isochoric,
|
508
|
+
find_liquidus = find_liquidus, fO2_buffer = fO2_buffer, fO2_offset = fO2_offset[i],
|
509
|
+
fluid_sat = fluid_sat, Crystallinity_limit = Crystallinity_limit, Suppress = Suppress,
|
510
|
+
Suppress_except=Suppress_except, trail = trail, melts = melts)
|
511
|
+
else:
|
512
|
+
Results = path_MELTS(Model = Model, comp = comp, Frac_solid = Frac_solid, Frac_fluid = Frac_fluid,
|
513
|
+
T_initial_C = 1400, T_C = T_C[i], T_path_C = T_path_C[i], T_start_C = T_start_C[i],
|
514
|
+
T_end_C = T_end_C[i], dt_C = dt_C[i], P_bar = P_bar[i], P_path_bar = P_path_bar[i],
|
515
|
+
P_start_bar = P_start_bar[i], P_end_bar = P_end_bar[i], dp_bar = dp_bar[i],
|
516
|
+
isenthalpic = isenthalpic, isentropic = isentropic, isochoric = isochoric,
|
517
|
+
find_liquidus = find_liquidus, fO2_buffer = fO2_buffer, fO2_offset = fO2_offset[i],
|
518
|
+
fluid_sat = fluid_sat, Crystallinity_limit = Crystallinity_limit, Suppress = Suppress,
|
519
|
+
Suppress_except=Suppress_except, trail = trail, melts = melts)
|
520
|
+
|
489
521
|
else:
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
522
|
+
if trail is not None:
|
523
|
+
Results, tr = path_MELTS(Model = Model, comp = comp.loc[i].to_dict(), Frac_solid = Frac_solid, Frac_fluid = Frac_fluid,
|
524
|
+
T_initial_C = 1400, T_C = T_C[i], T_path_C = T_path_C[i], T_start_C = T_start_C[i],
|
525
|
+
T_end_C = T_end_C[i], dt_C = dt_C[i], P_bar = P_bar[i], P_path_bar = P_path_bar[i],
|
526
|
+
P_start_bar = P_start_bar[i], P_end_bar = P_end_bar[i], dp_bar = dp_bar[i],
|
527
|
+
isenthalpic = isenthalpic, isentropic = isentropic, isochoric = isochoric,
|
528
|
+
find_liquidus = find_liquidus, fO2_buffer = fO2_buffer, fO2_offset = fO2_offset[i],
|
529
|
+
fluid_sat = fluid_sat, Crystallinity_limit = Crystallinity_limit, Suppress = Suppress,
|
530
|
+
Suppress_except=Suppress_except, trail = trail, melts = melts)
|
531
|
+
else:
|
532
|
+
Results = path_MELTS(Model = Model, comp = comp.loc[i].to_dict(), Frac_solid = Frac_solid, Frac_fluid = Frac_fluid,
|
533
|
+
T_initial_C = 1400, T_C = T_C[i], T_path_C = T_path_C[i], T_start_C = T_start_C[i],
|
534
|
+
T_end_C = T_end_C[i], dt_C = dt_C[i], P_bar = P_bar[i], P_path_bar = P_path_bar[i],
|
535
|
+
P_start_bar = P_start_bar[i], P_end_bar = P_end_bar[i], dp_bar = dp_bar[i],
|
536
|
+
isenthalpic = isenthalpic, isentropic = isentropic, isochoric = isochoric,
|
537
|
+
find_liquidus = find_liquidus, fO2_buffer = fO2_buffer, fO2_offset = fO2_offset[i],
|
538
|
+
fluid_sat = fluid_sat, Crystallinity_limit = Crystallinity_limit, Suppress = Suppress,
|
539
|
+
Suppress_except=Suppress_except, trail = trail, melts = melts)
|
498
540
|
else:
|
499
541
|
if fO2_offset[i] is None:
|
500
542
|
fO2_offset[i] = 0.0
|