PetThermoTools 0.2.33__py3-none-any.whl → 0.2.34__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 CHANGED
@@ -27,29 +27,102 @@ from shapely.geometry import MultiPoint, Point, Polygon
27
27
  from functools import partial
28
28
  import concurrent.futures
29
29
 
30
+ import numpy as np
31
+ import pandas as pd
32
+ from joblib import Parallel, delayed
33
+ import multiprocessing
34
+ import time
35
+
36
+ def path_4_saturation(q, index, *, Model = None, P_bar = None, comp = None, T_maxdrop_C = None, dt_C = None, T_initial_C = None, fO2_buffer = None,
37
+ fO2_offset = 0.0, H2O_Sat = None, phases = None):
38
+ if "MELTS" in Model:
39
+ Results = path_MELTS(P_bar = P_bar,
40
+ Model=Model,
41
+ comp=comp,
42
+ T_maxdrop_C=T_maxdrop_C,
43
+ dt_C=dt_C,
44
+ T_initial_C=T_initial_C,
45
+ find_liquidus=True,
46
+ fO2_buffer=fO2_buffer,
47
+ fO2_offset=fO2_offset,
48
+ fluid_sat=H2O_Sat,
49
+ Suppress=['rutile', 'tridymite'],
50
+ phases=phases
51
+ )
52
+ q.put([index, Results])
53
+ return
54
+
55
+ def path_4_saturation_multi(q, index, *, Model = None, P_bar = None, comp = None, T_maxdrop_C = None, dt_C = None, T_initial_C = None, fO2_buffer = None,
56
+ fO2_offset = 0.0, H2O_Sat = None, phases = None):
57
+ results = {}
58
+ idx = []
59
+
60
+ if "MELTS" in Model:
61
+ from meltsdynamic import MELTSdynamic
30
62
 
31
- def run_melts_single(Pin, Model, comp, T_maxdrop_C, dt_C, T_initial_C,
32
- fO2_buffer, fO2_offset, H2O_Sat, phases):
33
- try:
34
- return path_MELTS(
35
- Model=Model,
36
- comp=comp,
37
- T_maxdrop_C=T_maxdrop_C,
38
- dt_C=dt_C,
39
- T_initial_C=T_initial_C,
40
- P_bar=Pin,
41
- find_liquidus=True,
42
- fO2_buffer=fO2_buffer,
43
- fO2_offset=fO2_offset,
44
- fluid_sat=H2O_Sat,
45
- Suppress=['rutile', 'tridymite'],
46
- phases=phases
47
- )
48
- except Exception as e:
49
- print(f"Failed at {Pin} bar: {e}")
50
- return None
51
-
52
- def mineral_cosaturation(Model="MELTSv1.0.2", cores=int(np.floor(multiprocessing.cpu_count()/2)), bulk=None,
63
+ if Model is None or Model == "MELTSv1.0.2":
64
+ melts = MELTSdynamic(1)
65
+ elif Model == "pMELTS":
66
+ melts = MELTSdynamic(2)
67
+ elif Model == "MELTSv1.1.0":
68
+ melts = MELTSdynamic(3)
69
+ elif Model == "MELTSv1.2.0":
70
+ melts = MELTSdynamic(4)
71
+ else:
72
+ from juliacall import Main as jl, convert as jlconvert
73
+
74
+ jl.seval("using MAGEMinCalc")
75
+
76
+ comp_julia = jl.seval("Dict")(comp)
77
+
78
+ for i in index:
79
+ # try:
80
+ if "MELTS" in Model:
81
+ Results, tr = path_MELTS(P_bar = P_bar[i],
82
+ Model=Model,
83
+ comp=comp,
84
+ T_maxdrop_C=T_maxdrop_C,
85
+ dt_C=dt_C,
86
+ T_initial_C=T_initial_C,
87
+ find_liquidus=True,
88
+ fO2_buffer=fO2_buffer,
89
+ fO2_offset=fO2_offset,
90
+ fluid_sat=H2O_Sat,
91
+ Suppress=['rutile', 'tridymite'],
92
+ phases=phases,
93
+ trail = True,
94
+ melts = melts
95
+ )
96
+ else:
97
+ if fO2_offset is None:
98
+ fO2_offset = 0.0
99
+
100
+ Results_df = jl.MAGEMinCalc.path(
101
+ comp=comp_julia, dt_C=dt_C,
102
+ P_bar=P_bar[i], T_min_C = T_maxdrop_C,
103
+ Model=Model, fo2_buffer=fO2_buffer,
104
+ fo2_offset=fO2_offset, find_liquidus=True,
105
+ frac_xtal = False
106
+ )
107
+
108
+ Results = dict(Results_df)
109
+
110
+ tr = True
111
+
112
+ idx.append(i)
113
+
114
+
115
+ results[f"index = {i}"] = Results
116
+
117
+ if tr is False:
118
+ break
119
+ # except:
120
+ # idx.append(i)
121
+
122
+ q.put([idx, results])
123
+ return
124
+
125
+ def mineral_cosaturation(Model="MELTSv1.0.2", cores=int(np.floor(multiprocessing.cpu_count())), bulk=None,
53
126
  phases=['quartz1', 'alkali-feldspar1', 'plagioclase1'],
54
127
  P_bar=np.linspace(250, 5000, 32), Fe3Fet_init=None, H2O_init=None,
55
128
  CO2_init=None, H2O_Sat=False, T_initial_C=None, dt_C=2,
@@ -63,33 +136,105 @@ def mineral_cosaturation(Model="MELTSv1.0.2", cores=int(np.floor(multiprocessing
63
136
  comp = comp_fix(Model=Model, comp=comp, Fe3Fet_Liq=Fe3Fet_init,
64
137
  H2O_Liq=H2O_init, CO2_Liq=CO2_init)
65
138
 
66
- run_partial = partial(run_melts_single,
67
- Model=Model, comp=comp, T_maxdrop_C=T_maxdrop_C,
68
- dt_C=dt_C, T_initial_C=T_initial_C,
69
- fO2_buffer=fO2_buffer, fO2_offset=fO2_offset,
70
- H2O_Sat=H2O_Sat, phases=phases)
71
-
72
- results = {}
73
- with concurrent.futures.ProcessPoolExecutor(max_workers=cores) as executor:
74
- futures = {executor.submit(run_partial, p): i for i, p in enumerate(P_bar)}
75
-
76
- done, not_done = concurrent.futures.wait(
77
- futures.keys(), timeout=timeout, return_when=concurrent.futures.ALL_COMPLETED
78
- )
79
-
80
- for future in done:
81
- i = futures[future]
82
- try:
83
- results[f"P = {P_bar[i]:.2f} bars"] = future.result()
84
- except Exception as e:
85
- print(f"Failure at {P_bar[i]} bar: {e}")
86
- results[f"P = {P_bar[i]:.2f} bars"] = {}
87
-
88
- for future in not_done:
89
- i = futures[future]
90
- print(f"Timeout at {P_bar[i]} bar. Either the calculation was slow (increase timeout) or it failed.")
91
- results[f"P = {P_bar[i]:.2f} bars"] = {}
92
- future.cancel() # Cancel if still running
139
+ index_in = np.arange(len(P_bar))
140
+ # index_in = index
141
+ combined_results = {}
142
+ index_out = np.array([], dtype=int)
143
+
144
+ while len(index_out) < len(index_in):
145
+ index = np.setdiff1d(index_in, index_out)
146
+ groups = np.array_split(index, cores)
147
+
148
+ processes = []
149
+ for i in range(len(groups)):
150
+ q = Queue()
151
+ p = Process(target = path_4_saturation_multi, args = (q, groups[i]),
152
+ kwargs = {'Model': Model, 'comp': comp,
153
+ 'T_initial_C': T_initial_C, 'T_maxdrop_C': T_maxdrop_C,
154
+ 'dt_C': dt_C, 'P_bar': P_bar, 'phases': phases,
155
+ 'fO2_buffer': fO2_buffer, 'fO2_offset': fO2_offset})
156
+
157
+ processes.append((p, q))
158
+ p.start()
159
+
160
+ for p, q in processes:
161
+ res = q.get(timeout=timeout)
162
+ p.join(timeout = 2)
163
+ p.terminate()
164
+
165
+ idx_chunks, results = res
166
+
167
+ index_out = np.hstack((index_out, idx_chunks))
168
+ combined_results.update(results)
169
+
170
+ results = combined_results
171
+ # results = {}
172
+ # if len(P_bar) > 1:
173
+ # A = len(P_bar)//cores
174
+ # B = len(P_bar) % cores
175
+
176
+ # if A > 0:
177
+ # Group = np.zeros(A) + cores
178
+ # if B > 0:
179
+ # Group = np.append(Group, B)
180
+ # else:
181
+ # Group = np.array([B])
182
+
183
+ # # initialise queue
184
+ # qs = []
185
+ # q = Queue()
186
+
187
+
188
+ # # run calculations
189
+ # for k in range(len(Group)):
190
+ # ps = []
191
+
192
+ # for kk in range(int(cores*k), int(cores*k + Group[k])):
193
+ # p = Process(target = path_4_saturation, args = (q, kk),
194
+ # kwargs = {'Model': Model, 'comp': comp,
195
+ # 'T_initial_C': T_initial_C, 'T_maxdrop_C': T_maxdrop_C,
196
+ # 'dt_C': dt_C, 'P_bar': P_bar[kk], 'phases': phases,
197
+ # 'fO2_buffer': fO2_buffer, 'fO2_offset': fO2_offset})
198
+
199
+ # ps.append(p)
200
+ # p.start()
201
+
202
+ # start = time.time()
203
+ # for p in ps:
204
+ # if time.time() - start < timeout - 10:
205
+ # try:
206
+ # ret = q.get(timeout = timeout - (time.time()-start) + 10)
207
+ # except:
208
+ # ret = []
209
+ # else:
210
+ # try:
211
+ # ret = q.get(timeout = 10)
212
+ # except:
213
+ # ret = []
214
+
215
+ # qs.append(ret)
216
+
217
+ # TIMEOUT = 5
218
+ # start = time.time()
219
+ # for p in ps:
220
+ # if p.is_alive():
221
+ # while time.time() - start <= TIMEOUT:
222
+ # if not p.is_alive():
223
+ # p.join()
224
+ # p.terminate()
225
+ # break
226
+ # time.sleep(.1)
227
+ # else:
228
+ # p.terminate()
229
+ # p.join(5)
230
+ # else:
231
+ # p.join()
232
+ # p.terminate()
233
+
234
+ # for kk in range(len(qs)):
235
+ # if len(qs[kk]) > 0:
236
+ # index, res = qs[kk]
237
+ # results[f"P = {P_bar[index]:.2f} bars"] = res.copy()
93
238
 
94
239
  Results = stich(Res=results, multi=True, Model=Model)
95
240
 
@@ -131,7 +276,7 @@ def mineral_cosaturation(Model="MELTSv1.0.2", cores=int(np.floor(multiprocessing
131
276
 
132
277
  arr[:,3] = np.abs(arr[:,1] - arr[:,2])
133
278
 
134
- out = pd.DataFrame(data = r_arr, columns = columns)
279
+ out = pd.DataFrame(data = arr, columns = columns)
135
280
  out = out.sort_values('P_bar').reset_index(drop=True)
136
281
 
137
282
  if find_min:
PetThermoTools/MELTS.py CHANGED
@@ -808,7 +808,7 @@ def path_MELTS(Model = None, comp = None, Frac_solid = None, Frac_fluid = None,
808
808
  P_bar = None, P_path_bar = None, P_start_bar = None, P_end_bar = None, dp_bar = None,
809
809
  isenthalpic = None, isentropic = None, isochoric = None, find_liquidus = None,
810
810
  fO2_buffer = None, fO2_offset = None, fluid_sat = None, Crystallinity_limit = None,
811
- Suppress = ['rutile', 'tridymite'], Suppress_except=False, phases=None):
811
+ Suppress = ['rutile', 'tridymite'], Suppress_except=False, phases=None, trail = None, melts = None):
812
812
  '''
813
813
  Perform a single calculation in MELTS. WARNING! Running this function directly from the command land/jupyter notebook will initiate the MELTS C library in the main python process. Once this has been initiated the MELTS C library cannot be re-loaded and failures during the calculation will likely cause a terminal error to occur.
814
814
 
@@ -884,6 +884,8 @@ def path_MELTS(Model = None, comp = None, Frac_solid = None, Frac_fluid = None,
884
884
 
885
885
  '''
886
886
  Results = {}
887
+ if trail is not None:
888
+ trail = False
887
889
 
888
890
  if comp is None:
889
891
  raise Exception("No composition specified")
@@ -898,16 +900,17 @@ def path_MELTS(Model = None, comp = None, Frac_solid = None, Frac_fluid = None,
898
900
  if T_path_C is None and T_start_C is None and find_liquidus is None:
899
901
  raise Exception("Starting temperature must be specified or the liquidus must be found")
900
902
 
901
- from meltsdynamic import MELTSdynamic
903
+ if melts is None:
904
+ from meltsdynamic import MELTSdynamic
902
905
 
903
- if Model is None or Model == "MELTSv1.0.2":
904
- melts = MELTSdynamic(1)
905
- elif Model == "pMELTS":
906
- melts = MELTSdynamic(2)
907
- elif Model == "MELTSv1.1.0":
908
- melts = MELTSdynamic(3)
909
- elif Model == "MELTSv1.2.0":
910
- melts = MELTSdynamic(4)
906
+ if Model is None or Model == "MELTSv1.0.2":
907
+ melts = MELTSdynamic(1)
908
+ elif Model == "pMELTS":
909
+ melts = MELTSdynamic(2)
910
+ elif Model == "MELTSv1.1.0":
911
+ melts = MELTSdynamic(3)
912
+ elif Model == "MELTSv1.2.0":
913
+ melts = MELTSdynamic(4)
911
914
 
912
915
  bulk = [comp['SiO2_Liq'], comp['TiO2_Liq'], comp['Al2O3_Liq'], comp['Fe3Fet_Liq']*((159.59/2)/71.844)*comp['FeOt_Liq'], comp['Cr2O3_Liq'], (1- comp['Fe3Fet_Liq'])*comp['FeOt_Liq'], comp['MnO_Liq'], comp['MgO_Liq'], 0.0, 0.0, comp['CaO_Liq'], comp['Na2O_Liq'], comp['K2O_Liq'], comp['P2O5_Liq'], comp['H2O_Liq'], comp['CO2_Liq'], 0.0, 0.0, 0.0]
913
916
  bulk = list(100*np.array(bulk)/np.sum(bulk))
@@ -952,12 +955,18 @@ def path_MELTS(Model = None, comp = None, Frac_solid = None, Frac_fluid = None,
952
955
  else:
953
956
  Liq_Results = findLiq_MELTS(P_bar = P_path_bar, comp = bulk, melts = melts, fO2_buffer = fO2_buffer, fO2_offset = fO2_offset, T_C_init = T_initial_C)
954
957
  except:
955
- return Results
958
+ if trail is not None:
959
+ return Results, trail
960
+ else:
961
+ return Results
956
962
  elif P_start_bar is not None:
957
963
  try:
958
964
  Liq_Results = findLiq_MELTS(P_bar = P_start_bar, comp = bulk, melts = melts, fO2_buffer = fO2_buffer, fO2_offset = fO2_offset, T_C_init = T_initial_C)
959
965
  except:
960
- return Results
966
+ if trail is not None:
967
+ return Results, trail
968
+ else:
969
+ return Results
961
970
 
962
971
  print(Liq_Results)
963
972
  T_start_C = Liq_Results['T_Liq'] + 0.1
@@ -1039,6 +1048,10 @@ def path_MELTS(Model = None, comp = None, Frac_solid = None, Frac_fluid = None,
1039
1048
  Results['liquid1_prop'] = pd.DataFrame(data = np.zeros((length, 4)), columns = ['h', 'mass', 'v', 'rho'])
1040
1049
 
1041
1050
  for i in range(length):
1051
+ if i == 1:
1052
+ if trail is not None:
1053
+ trail = True
1054
+
1042
1055
  if type(T) == np.ndarray:
1043
1056
  melts.engine.temperature = T[i]
1044
1057
  if type(P) == np.ndarray:
@@ -1087,7 +1100,11 @@ def path_MELTS(Model = None, comp = None, Frac_solid = None, Frac_fluid = None,
1087
1100
  else:
1088
1101
  melts.engine.calcEquilibriumState(1,0)
1089
1102
  except:
1090
- return Results
1103
+ trail = False
1104
+ # if trail is not None:
1105
+ # return Results, trail
1106
+ # else:
1107
+ # return Results
1091
1108
  break
1092
1109
 
1093
1110
  if isenthalpic is not None:
@@ -1097,7 +1114,11 @@ def path_MELTS(Model = None, comp = None, Frac_solid = None, Frac_fluid = None,
1097
1114
  else:
1098
1115
  melts.engine.calcEquilibriumState(2,0)
1099
1116
  except:
1100
- # return Results
1117
+ trail = False
1118
+ # if trail is not None:
1119
+ # return Results, trail
1120
+ # else:
1121
+ # return Results
1101
1122
  break
1102
1123
 
1103
1124
  if isentropic is not None:
@@ -1107,6 +1128,7 @@ def path_MELTS(Model = None, comp = None, Frac_solid = None, Frac_fluid = None,
1107
1128
  else:
1108
1129
  melts.engine.calcEquilibriumState(3,0)
1109
1130
  except:
1131
+ trail = False
1110
1132
  # return Results
1111
1133
  break
1112
1134
 
@@ -1114,6 +1136,7 @@ def path_MELTS(Model = None, comp = None, Frac_solid = None, Frac_fluid = None,
1114
1136
  try:
1115
1137
  melts.engine.calcEquilibriumState(4,0)
1116
1138
  except:
1139
+ trail = False
1117
1140
  # return Results
1118
1141
  break
1119
1142
 
@@ -1133,7 +1156,8 @@ def path_MELTS(Model = None, comp = None, Frac_solid = None, Frac_fluid = None,
1133
1156
  try:
1134
1157
  PhaseList = ['liquid1'] + melts.engine.solidNames
1135
1158
  except:
1136
- return Results
1159
+ trail = False
1160
+ # return Results
1137
1161
  break
1138
1162
 
1139
1163
  for phase in PhaseList:
@@ -1171,7 +1195,11 @@ def path_MELTS(Model = None, comp = None, Frac_solid = None, Frac_fluid = None,
1171
1195
 
1172
1196
  melts = melts.addNodeAfter()
1173
1197
 
1174
- return Results
1198
+
1199
+ if trail is not None:
1200
+ return Results, trail
1201
+ else:
1202
+ return Results
1175
1203
 
1176
1204
  def findSatPressure_MELTS_multi(Model = None, comp = None, fO2_buffer = None, fO2_offset = None, P_bar = None, T_fixed_C = None):
1177
1205
  out = pd.DataFrame(columns = ['Sample_ID_Liq', 'SiO2_Liq', 'TiO2_Liq', 'Al2O3_Liq', 'Cr2O3_Liq', 'FeOt_Liq', 'MnO_Liq', 'MgO_Liq', 'CaO_Liq', 'Na2O_Liq', 'K2O_Liq', 'P2O5_Liq', 'H2O_Liq', 'CO2_Liq', 'Fe3Fet_Liq', 'P_bar', 'T_Liq'])
@@ -5,4 +5,4 @@
5
5
  # 1) we don't load dependencies by storing it in __init__.py
6
6
  # 2) we can import it in setup.py for the same reason
7
7
  # 3) we can import it into your module
8
- __version__ = '0.2.33'
8
+ __version__ = '0.2.34'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PetThermoTools
3
- Version: 0.2.33
3
+ Version: 0.2.34
4
4
  Summary: PetThermoTools
5
5
  Home-page: https://github.com/gleesonm1/PetThermoTools
6
6
  Author: Matthew Gleeson
@@ -1,10 +1,10 @@
1
- PetThermoTools/Barom.py,sha256=zfRgGnqInXP1B5oG_k5ZMJH3cylHcQXWiBRz7YlQjkw,36119
1
+ PetThermoTools/Barom.py,sha256=chxLZCCu0I8PLw0-TWsJboxiRqQJufKyVEVLk35dzVo,40494
2
2
  PetThermoTools/Compositions.py,sha256=65NzfduzWdfHJ8VmHBN1Cv7fMz7kF3QbDVLei-e4v00,1483
3
3
  PetThermoTools/GenFuncs.py,sha256=u2GWqH--Wmqd0WXHxfulEAatQb6uswjl1s9SyyoHSa8,16412
4
4
  PetThermoTools/Holland.py,sha256=udBFeVUyTBpSfLIhx7Hy6o0I8ApNCDvwU_gZa0diY5w,7251
5
5
  PetThermoTools/Installation.py,sha256=UfVOW1NZFdzMWPyID5u7t0KwvpJA0AqYohzidXIAwYs,6098
6
6
  PetThermoTools/Liq.py,sha256=2kdU8r00Y20khwvPvCvLr6P7y2HEOvCH2cwrF_qw5u8,35541
7
- PetThermoTools/MELTS.py,sha256=hqc5vSDwvnCyBwD7wbEOwemUNpDQGpsWdOOoVjNnMvE,72810
7
+ PetThermoTools/MELTS.py,sha256=CjUOJSUEoq4yXEojl77HgCj7aewhFDeSGt4ZGk3L3vs,73688
8
8
  PetThermoTools/Melting.py,sha256=h1-KchPFw5tI2xoOyNJUfVy_TJqTtcYiHtGuInIwzio,11017
9
9
  PetThermoTools/Path.py,sha256=FI_JkpCDXUVWsaKxA_PKOyKvXSzsQEBiLonGNiamcIM,33424
10
10
  PetThermoTools/Path_wrappers.py,sha256=_0pBs_cK2hICxAHkYxKXICUnUEBSiUg07-qhgBeuTdc,26555
@@ -12,9 +12,9 @@ PetThermoTools/PhaseDiagrams.py,sha256=8S_BcqggBzfUbiCPcsJRWFBenGL4tcCevte3-ATQj
12
12
  PetThermoTools/Plotting.py,sha256=IMYYusZy6REQATG9NI3dGlGs6h3vQ48aJHkZnHmSDDY,28924
13
13
  PetThermoTools/Saturation.py,sha256=XXY6fKVouQM3RLgQgXur4xSq7_uGp7bCw_k7NNlWYi8,14095
14
14
  PetThermoTools/__init__.py,sha256=PbiwQj_mNNEwuIZOLETmtMMshiXa50wjCA6mfvpOpOs,2393
15
- PetThermoTools/_version.py,sha256=i2Na-DPnshyTFid0Y6FmelIcA0OHEcYVuQdFt_mKzeI,296
16
- PetThermoTools-0.2.33.dist-info/LICENSE.txt,sha256=-mkx4iEw8Pk1RZUvncBhGLW87Uur5JB7FBQtOmX-VP0,1752
17
- PetThermoTools-0.2.33.dist-info/METADATA,sha256=MM-RsleOmZq3PfygLozR2VrdewAuBMezGJLwnGc9Km8,796
18
- PetThermoTools-0.2.33.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
19
- PetThermoTools-0.2.33.dist-info/top_level.txt,sha256=IqK8iYBR3YJozzMOTRZ8x8mU2k6x8ycoMBxZTm-I06U,15
20
- PetThermoTools-0.2.33.dist-info/RECORD,,
15
+ PetThermoTools/_version.py,sha256=ZyVKd7JEm_88aeNoezRSEHfFgAtOuHaYQWt8wmb4mgc,296
16
+ PetThermoTools-0.2.34.dist-info/LICENSE.txt,sha256=-mkx4iEw8Pk1RZUvncBhGLW87Uur5JB7FBQtOmX-VP0,1752
17
+ PetThermoTools-0.2.34.dist-info/METADATA,sha256=okQdLGfhCpo2f211FXt6szwCr2KrRHpqxAVKSl6kPec,796
18
+ PetThermoTools-0.2.34.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
19
+ PetThermoTools-0.2.34.dist-info/top_level.txt,sha256=IqK8iYBR3YJozzMOTRZ8x8mU2k6x8ycoMBxZTm-I06U,15
20
+ PetThermoTools-0.2.34.dist-info/RECORD,,