PetThermoTools 0.2.39__py3-none-any.whl → 0.2.40__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.
- PetThermoTools/Barom.py +690 -575
- PetThermoTools/GenFuncs.py +7 -2
- PetThermoTools/Liq.py +0 -8
- PetThermoTools/MELTS.py +85 -57
- PetThermoTools/Path.py +181 -121
- PetThermoTools/Path_wrappers.py +448 -259
- PetThermoTools/PhaseDiagrams.py +30 -98
- PetThermoTools/Saturation.py +353 -2
- PetThermoTools/_version.py +1 -1
- {PetThermoTools-0.2.39.dist-info → PetThermoTools-0.2.40.dist-info}/METADATA +1 -1
- PetThermoTools-0.2.40.dist-info/RECORD +20 -0
- PetThermoTools-0.2.39.dist-info/RECORD +0 -20
- {PetThermoTools-0.2.39.dist-info → PetThermoTools-0.2.40.dist-info}/LICENSE.txt +0 -0
- {PetThermoTools-0.2.39.dist-info → PetThermoTools-0.2.40.dist-info}/WHEEL +0 -0
- {PetThermoTools-0.2.39.dist-info → PetThermoTools-0.2.40.dist-info}/top_level.txt +0 -0
PetThermoTools/Path.py
CHANGED
@@ -25,98 +25,80 @@ except:
|
|
25
25
|
def multi_path(cores = None, Model = None, bulk = None, comp = None, Frac_solid = None, Frac_fluid = None,
|
26
26
|
T_C = None, T_path_C = None, T_start_C = None, T_end_C = None, dt_C = None,
|
27
27
|
P_bar = None, P_path_bar = None, P_start_bar = None, P_end_bar = None, dp_bar = None,
|
28
|
-
Fe3Fet_Liq = None, H2O_Liq = None, CO2_Liq = None,
|
28
|
+
Fe3Fet_init = None, Fe3Fet_Liq = None, H2O_init = None, H2O_Liq = None, CO2_init = None, CO2_Liq = None,
|
29
29
|
isenthalpic = None, isentropic = None, isochoric = None, find_liquidus = None,
|
30
30
|
fO2_buffer = None, fO2_offset = None,
|
31
31
|
Print_suppress = None, fluid_sat = None, Crystallinity_limit = None, Combined = None,
|
32
|
-
label = None, timeout = None, print_label = True, Suppress = ['rutile', 'tridymite'], Suppress_except=False
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
Parameters:
|
37
|
-
----------
|
38
|
-
cores: int
|
39
|
-
number of processes to run in parallel. Default will be determined using Multiprocessing.cpu_count().
|
40
|
-
|
41
|
-
Model: string
|
42
|
-
"MELTS" or "Holland". Dictates whether MELTS or MAGEMin calculations are performed. Default "MELTS".
|
43
|
-
Version of melts can be specified "MELTSv1.0.2", "MELTSv1.1.0", "MELTSv1.2.0", or "pMELTS". Default "v.1.0.2".
|
44
|
-
|
45
|
-
bulk or comp: Dict or pd.DataFrame
|
46
|
-
Initial compositon for calculations. If type == Dict, the same initial composition will be used in all calculations.
|
47
|
-
|
48
|
-
Frac_solid: True/False
|
49
|
-
If True, solid phases will be removed from the system at the end of each step. Default False.
|
50
|
-
|
51
|
-
Frac_fluid: True/False
|
52
|
-
If True, fluid phases will be removed from the system at the end of each step. Default False.
|
53
|
-
|
54
|
-
T_C: float or np.ndarray
|
55
|
-
Calculation temperature - typically used when calculations are performed at a fixed T (e.g.,isothermal degassing).
|
56
|
-
|
57
|
-
T_path_C: np.ndarray
|
58
|
-
If a specified temperature path is to be used, T_path_C will be used to determine the T at each step of the model. If 2D, this indicates that multiple calculations with different T_path_C arrays are to be performed.
|
59
|
-
|
60
|
-
T_start_C: float or np.ndarray
|
61
|
-
Initial temperature used for path calculations.
|
62
|
-
|
63
|
-
T_end_C: float or np.ndarray
|
64
|
-
Final temperature in crystallisation calculations.
|
65
|
-
|
66
|
-
dt_C: float or np.ndarray
|
67
|
-
Temperature increment during crystallisation calculations.
|
68
|
-
|
69
|
-
P_bar: float or np.ndarray
|
70
|
-
Calculation pressure - typically used when calculations are performed at a fixed P (e.g.,isobaric crystallisation).
|
71
|
-
|
72
|
-
P_path_bar: np.ndarray
|
73
|
-
If a specified pressure path is to be used, P_path_bar will be used to determine the P at each step of the model. If 2D, this indicates that multiple calculations with different P_path_bar arrays are to be performed.
|
74
|
-
|
75
|
-
P_start_bar: float or np.ndarray
|
76
|
-
Initial pressure used for path calculations.
|
77
|
-
|
78
|
-
P_end_bar: float or np.ndarray
|
79
|
-
Final pressure in crystallisation calculations.
|
80
|
-
|
81
|
-
dp_bar: float or np.ndarray
|
82
|
-
Pressure increment during crystallisation calculations..
|
83
|
-
|
84
|
-
Fe3Fet_Liq: float or np.ndarray
|
85
|
-
Fe 3+/total ratio. If type(comp) == dict, and type(Fe3Fet_Liq) == np.ndarray a new DataFrame will be constructed with bulk compositions varying only in their Fe3Fet_Liq value. If comp is a pd.DataFrame, a single Fe3Fet_Liq value may be passed (float) and will be used as the Fe redox state for all starting compostions, or an array of Fe3Fet_Liq values, equal to the number of compositions specified in comp can specify a different Fe redox state for each sample. If None, the Fe redox state must be specified in the comp variable or an oxygen fugacity buffer must be chosen.
|
86
|
-
|
87
|
-
H2O_Liq: float or np.ndarray
|
88
|
-
H2O content of the initial melt phase. If type(comp) == dict, and type(H2O_Liq) = np.ndarray a new DataFrame will be constructed with bulk compositions varying only in their H2O_Liq value. If comp is a pd.DataFrame, a single H2O_Liq value may be passes (float) and will be used as the initial melt H2O content for all starting compositions. Alternatively, if an array of H2O_Liq values is passed, equal to the number of compositions specified in comp, a different initial melt H2O value will be passed for each sample. If None, H2O_Liq must be specified in the comp variable.
|
89
|
-
|
90
|
-
isenthalpic: True/False
|
91
|
-
If True, calculations will be performed at a constant enthalpy with T treated as a dependent variable.
|
32
|
+
label = None, timeout = None, print_label = True, Suppress = ['rutile', 'tridymite'], Suppress_except=False,
|
33
|
+
multi_processing = True):
|
34
|
+
"""
|
35
|
+
Perform single or multiple MELTS/MAGEMin crystallization or degassing calculations in series or parallel.
|
92
36
|
|
93
|
-
isentropic
|
94
|
-
|
95
|
-
|
96
|
-
isochoric: True/False
|
97
|
-
If True, the volume of the system will be held constant instead of the pressure. Default is False.
|
98
|
-
|
99
|
-
find_liquidus: True/False
|
100
|
-
If True, the calculations will start with a search for the melt liquidus temperature. Default is False.
|
101
|
-
|
102
|
-
fO2_buffer: string
|
103
|
-
If the oxygen fugacity of the system is to be buffered during crystallisation/decompression, then an offset to a known buffer must be specified. Here the user can define the known buffer as either "FMQ" or "NNO".
|
37
|
+
Supports isothermal, isenthalpic, isentropic, and isochoric processes over fixed or variable pressure and
|
38
|
+
temperature paths. Works with both MELTS and MAGEMin models. Automatically handles composition expansion when
|
39
|
+
using arrays for Fe3+/FeT, H2O, or CO2.
|
104
40
|
|
105
|
-
|
106
|
-
Offset from the buffer spcified in fO2_buffer (log units).
|
107
|
-
|
108
|
-
Print_suppress: True/False
|
109
|
-
If True, print messages concerning the status of the thermodynamic calculations will not be displayed.
|
110
|
-
|
111
|
-
Crystallinity_limit: float
|
112
|
-
If value given, calculation will stop when the volume mass fraction of the system (excludin fluids) exceeds this value.
|
113
|
-
|
114
|
-
Returns:
|
41
|
+
Parameters
|
115
42
|
----------
|
116
|
-
|
117
|
-
|
43
|
+
cores : int, optional
|
44
|
+
Number of CPU cores to use for multiprocessing. Defaults to total available.
|
45
|
+
Model : str
|
46
|
+
Thermodynamic model. MELTS variants: "MELTSv1.0.2", "MELTSv1.1.0", "MELTSv1.2.0", "pMELTS";
|
47
|
+
or MAGEMin: "Green2025", "Weller2024".
|
48
|
+
bulk or comp : dict or pd.DataFrame
|
49
|
+
Starting composition(s) for the model run(s). If `dict`, single composition for all runs.
|
50
|
+
Frac_solid : bool, optional
|
51
|
+
If True, remove solids at each step (fractional crystallization).
|
52
|
+
Frac_fluid : bool, optional
|
53
|
+
If True, remove fluids at each step.
|
54
|
+
T_C, P_bar : float or np.ndarray, optional
|
55
|
+
Fixed temperature/pressure values for isothermal/isobaric runs.
|
56
|
+
T_path_C, P_path_bar : np.ndarray or 2D array, optional
|
57
|
+
User-defined temperature/pressure paths for each model run.
|
58
|
+
T_start_C, T_end_C, dt_C : float or array, optional
|
59
|
+
Starting, ending, and increment temperature values for path calculations.
|
60
|
+
P_start_bar, P_end_bar, dp_bar : float or array, optional
|
61
|
+
Starting, ending, and increment pressure values for path calculations.
|
62
|
+
Fe3Fet_init : float or array, optional
|
63
|
+
Initial Fe3+/FeT ratio(s). Required if redox state is not specified in `comp` or `fO2_buffer`.
|
64
|
+
H2O_init, CO2_init : float or array, optional
|
65
|
+
Initial melt volatile contents. Required if not specified in `comp`.
|
66
|
+
isenthalpic, isentropic, isochoric : bool, optional
|
67
|
+
If True, applies respective thermodynamic constraint.
|
68
|
+
find_liquidus : bool, optional
|
69
|
+
If True, searches for the liquidus before starting.
|
70
|
+
fO2_buffer : {"FMQ", "NNO"}, optional
|
71
|
+
Specifies redox buffer for constraining oxygen fugacity.
|
72
|
+
fO2_offset : float or array, optional
|
73
|
+
Offset (in log units) from the specified fO2 buffer.
|
74
|
+
Print_suppress : bool, optional
|
75
|
+
If True, suppresses status messages.
|
76
|
+
fluid_sat : bool, optional
|
77
|
+
If True, starts the system at fluid saturation.
|
78
|
+
Crystallinity_limit : float, optional
|
79
|
+
Ends run when crystallinity (excluding fluids) exceeds this threshold.
|
80
|
+
Combined : unused
|
81
|
+
Placeholder for backwards compatibility.
|
82
|
+
label : str or array, optional
|
83
|
+
If provided, labels output dictionaries using `label`.
|
84
|
+
timeout : float, optional
|
85
|
+
Max allowed runtime for each subprocess (in seconds).
|
86
|
+
print_label : bool, default=True
|
87
|
+
If True, prints label with status updates.
|
88
|
+
Suppress : list of str
|
89
|
+
List of phases to exclude from results.
|
90
|
+
Suppress_except : bool
|
91
|
+
If True, `Suppress` acts as a whitelist instead of a blacklist.
|
92
|
+
multi_processing : bool
|
93
|
+
If False, run sequentially in main process.
|
94
|
+
|
95
|
+
Returns
|
96
|
+
-------
|
97
|
+
Results : dict
|
98
|
+
Dictionary with each run's label as key. Values are sub-dictionaries of phase/property DataFrames.
|
99
|
+
Includes `Input` key summarizing model configuration per run.
|
100
|
+
"""
|
118
101
|
|
119
|
-
'''
|
120
102
|
if timeout is None:
|
121
103
|
timeout = 180
|
122
104
|
|
@@ -141,6 +123,21 @@ def multi_path(cores = None, Model = None, bulk = None, comp = None, Frac_solid
|
|
141
123
|
except:
|
142
124
|
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')
|
143
125
|
|
126
|
+
if H2O_Liq is not None:
|
127
|
+
print('Warning - the kwarg "H2O_Liq" will be removed from v1.0.0 onwards. Please use "H2O_init" instead.')
|
128
|
+
if H2O_init is None:
|
129
|
+
H2O_init = H2O_Liq
|
130
|
+
|
131
|
+
if CO2_Liq is not None:
|
132
|
+
print('Warning - the kwarg "CO2_Liq" will be removed from v1.0.0 onwards. Please use "CO2_init" instead.')
|
133
|
+
if CO2_init is None:
|
134
|
+
CO2_init = CO2_Liq
|
135
|
+
|
136
|
+
if Fe3Fet_Liq is not None:
|
137
|
+
print('Warning - the kwarg "Fe3Fet_Liq" will be removed from v1.0.0 onwards. Please use "Fe3Fet_init" instead.')
|
138
|
+
if Fe3Fet_init is None:
|
139
|
+
Fe3Fet_init = Fe3Fet_Liq
|
140
|
+
|
144
141
|
# if comp is entered as a pandas series, it must first be converted to a dict
|
145
142
|
if type(comp) == pd.core.series.Series:
|
146
143
|
comp = comp.to_dict()
|
@@ -155,7 +152,7 @@ def multi_path(cores = None, Model = None, bulk = None, comp = None, Frac_solid
|
|
155
152
|
fO2_buffer = "qfm"
|
156
153
|
|
157
154
|
# ensure the bulk composition has the correct headers etc.
|
158
|
-
comp = comp_fix(Model = Model, comp = comp, Fe3Fet_Liq =
|
155
|
+
comp = comp_fix(Model = Model, comp = comp, Fe3Fet_Liq = Fe3Fet_init, H2O_Liq = H2O_init, CO2_Liq = CO2_init)
|
159
156
|
|
160
157
|
if type(comp) == dict:
|
161
158
|
if comp['H2O_Liq'] == 0.0 and "MELTS" in Model:
|
@@ -213,45 +210,57 @@ def multi_path(cores = None, Model = None, bulk = None, comp = None, Frac_solid
|
|
213
210
|
print("Running " + Model + " calculation...", end = "", flush = True)
|
214
211
|
s = time.time()
|
215
212
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
p.
|
213
|
+
if multi_processing:
|
214
|
+
p = Process(target = path, args = (q, 1),
|
215
|
+
kwargs = {'Model': Model, 'comp': comp, 'Frac_solid': Frac_solid, 'Frac_fluid': Frac_fluid,
|
216
|
+
'T_C': T_C, 'T_path_C': T_path_C, 'T_start_C': T_start_C, 'T_end_C': T_end_C, 'dt_C': dt_C,
|
217
|
+
'P_bar': P_bar, 'P_path_bar': P_path_bar, 'P_start_bar': P_start_bar, 'P_end_bar': P_end_bar, 'dp_bar': dp_bar,
|
218
|
+
'isenthalpic': isenthalpic, 'isentropic': isentropic, 'isochoric': isochoric, 'find_liquidus': find_liquidus,
|
219
|
+
'fO2_buffer': fO2_buffer, 'fO2_offset': fO2_offset, 'fluid_sat': fluid_sat, 'Crystallinity_limit': Crystallinity_limit,
|
220
|
+
'Suppress': Suppress, 'Suppress_except': Suppress_except})
|
221
|
+
|
222
|
+
p.start()
|
223
|
+
try:
|
224
|
+
ret = q.get(timeout = 180)
|
225
|
+
except:
|
226
|
+
ret = []
|
227
|
+
|
228
|
+
TIMEOUT = 5
|
229
|
+
start = time.time()
|
230
|
+
if p.is_alive():
|
231
|
+
while time.time() - start <= TIMEOUT:
|
232
|
+
if not p.is_alive():
|
233
|
+
p.join()
|
234
|
+
p.terminate()
|
235
|
+
break
|
236
|
+
time.sleep(.1)
|
237
|
+
else:
|
236
238
|
p.terminate()
|
237
|
-
|
238
|
-
time.sleep(.1)
|
239
|
+
p.join(5)
|
239
240
|
else:
|
241
|
+
p.join()
|
240
242
|
p.terminate()
|
241
|
-
p.join(5)
|
242
|
-
else:
|
243
|
-
p.join()
|
244
|
-
p.terminate()
|
245
243
|
|
246
|
-
|
247
|
-
|
244
|
+
if Print_suppress is None:
|
245
|
+
print(" Complete (time taken = " + str(round(time.time() - s,2)) + " seconds)", end = "", flush = True)
|
248
246
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
247
|
+
if len(ret) > 0:
|
248
|
+
Results, index = ret
|
249
|
+
Results = stich(Results, Model = Model, Frac_fluid = Frac_fluid, Frac_solid = Frac_solid)
|
250
|
+
return Results
|
251
|
+
else:
|
252
|
+
Results = {}
|
253
|
+
return Results
|
253
254
|
else:
|
254
|
-
Results =
|
255
|
+
Results = path_MELTS(Model = Model, comp = comp, Frac_solid = Frac_solid, Frac_fluid = Frac_fluid,
|
256
|
+
T_C = T_C, T_path_C = T_path_C, T_start_C = T_start_C, T_end_C = T_end_C,
|
257
|
+
dt_C = dt_C, P_bar = P_bar, P_path_bar = P_path_bar, P_start_bar = P_start_bar,
|
258
|
+
P_end_bar = P_end_bar, dp_bar = dp_bar, isenthalpic = isenthalpic,
|
259
|
+
isentropic = isentropic, isochoric = isochoric, find_liquidus = find_liquidus,
|
260
|
+
fO2_buffer = fO2_buffer, fO2_offset = fO2_offset, fluid_sat = fluid_sat,
|
261
|
+
Crystallinity_limit = Crystallinity_limit, Suppress = Suppress, Suppress_except = Suppress_except)
|
262
|
+
|
263
|
+
Results = stich(Results, Model = Model, Frac_fluid = Frac_fluid, Frac_solid = Frac_solid)
|
255
264
|
return Results
|
256
265
|
|
257
266
|
else: # perform multiple crystallisation calculations
|
@@ -363,7 +372,7 @@ def multi_path(cores = None, Model = None, bulk = None, comp = None, Frac_solid
|
|
363
372
|
Results = stich(Res=results, multi=True, Model=Model, Frac_fluid = Frac_fluid, Frac_solid = Frac_solid)
|
364
373
|
|
365
374
|
for r in Results:
|
366
|
-
i = int(r.split('
|
375
|
+
i = int(r.split(' ')[1].strip())
|
367
376
|
if type(comp) == dict:
|
368
377
|
Results[r]['Input'] = {'Model': Model, 'comp': comp, 'Frac_solid': Frac_solid, 'Frac_fluid': Frac_fluid,
|
369
378
|
'T_C': T_C[i], 'T_path_C': T_path_C[i], 'T_start_C': T_start_C[i], 'T_end_C': T_end_C[i], 'dt_C': dt_C[i],
|
@@ -391,6 +400,57 @@ def path_multi(q, index, *, Model = None, comp = None, Frac_solid = None, Frac_f
|
|
391
400
|
isenthalpic = None, isentropic = None, isochoric = None, find_liquidus = None,
|
392
401
|
fO2_buffer = None, fO2_offset = None, fluid_sat = None, Crystallinity_limit = None,
|
393
402
|
Suppress = None, Suppress_except = None, trail = True):
|
403
|
+
"""
|
404
|
+
Worker function to run a subset of crystallization/decompression models (MELTS or MAGEMin) in parallel.
|
405
|
+
|
406
|
+
This function is intended to be run in a separate process. It takes a set of indices representing model runs,
|
407
|
+
executes them using the appropriate model interface, and returns the results via a multiprocessing queue.
|
408
|
+
|
409
|
+
Parameters
|
410
|
+
----------
|
411
|
+
q : multiprocessing.Queue
|
412
|
+
Output queue for sending back results.
|
413
|
+
index : list of int
|
414
|
+
Indices of the simulations to be run by this worker.
|
415
|
+
Model : str
|
416
|
+
The thermodynamic model ("MELTSv1.0.2", "MELTSv1.1.0", "MELTSv1.2.0", "pMELTS", or MAGEMin variant: "Green2025" or "Weller2024").
|
417
|
+
comp : dict or pd.DataFrame
|
418
|
+
Starting compositions. Either a single dictionary or a DataFrame with one row per simulation.
|
419
|
+
Frac_solid : bool
|
420
|
+
If True, removes solids at each step.
|
421
|
+
Frac_fluid : bool
|
422
|
+
If True, removes fluids at each step.
|
423
|
+
T_C, T_path_C, T_start_C, T_end_C, dt_C : float or np.ndarray
|
424
|
+
Temperature constraints or paths for each simulation.
|
425
|
+
P_bar, P_path_bar, P_start_bar, P_end_bar, dp_bar : float or np.ndarray
|
426
|
+
Pressure constraints or paths for each simulation.
|
427
|
+
isenthalpic, isentropic, isochoric : bool
|
428
|
+
Apply respective thermodynamic constraints.
|
429
|
+
find_liquidus : bool
|
430
|
+
If True, finds the liquidus temperature before starting.
|
431
|
+
fO2_buffer : str
|
432
|
+
Oxygen fugacity buffer ("FMQ" or "NNO").
|
433
|
+
fO2_offset : float or array
|
434
|
+
Offset from specified fO2 buffer in log units.
|
435
|
+
fluid_sat : bool
|
436
|
+
If True, terminates runs at fluid saturation.
|
437
|
+
Crystallinity_limit : float
|
438
|
+
Ends run when crystallinity exceeds this value.
|
439
|
+
Suppress : list of str
|
440
|
+
Phases to exclude from results.
|
441
|
+
Suppress_except : bool
|
442
|
+
If True, treat `Suppress` as a whitelist.
|
443
|
+
trail : bool
|
444
|
+
If True, include trailing properties from model output.
|
445
|
+
|
446
|
+
Returns
|
447
|
+
-------
|
448
|
+
None
|
449
|
+
The function returns results using `q.put()`:
|
450
|
+
q.put([idx, results])
|
451
|
+
where `idx` is the list of completed indices and `results` is a dictionary of output per run.
|
452
|
+
"""
|
453
|
+
|
394
454
|
results = {}
|
395
455
|
idx = []
|
396
456
|
|
@@ -467,7 +527,7 @@ def path_multi(q, index, *, Model = None, comp = None, Frac_solid = None, Frac_f
|
|
467
527
|
idx.append(i)
|
468
528
|
|
469
529
|
|
470
|
-
results[f"
|
530
|
+
results[f"Run {i}"] = Results
|
471
531
|
|
472
532
|
if tr is False:
|
473
533
|
break
|