calphy 1.3.10__py3-none-any.whl → 1.3.13__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.
calphy/__init__.py CHANGED
@@ -4,7 +4,7 @@ from calphy.solid import Solid
4
4
  from calphy.alchemy import Alchemy
5
5
  from calphy.routines import MeltingTemp
6
6
 
7
- __version__ = "1.3.10"
7
+ __version__ = "1.3.13"
8
8
 
9
9
  def addtest(a,b):
10
10
  return a+b
calphy/input.py CHANGED
@@ -40,19 +40,7 @@ from pyscal3.core import structure_dict, element_dict, _make_crystal
40
40
  from ase.io import read, write
41
41
  import shutil
42
42
 
43
- __version__ = "1.3.10"
44
-
45
- def read_report(folder):
46
- """
47
- Read the finished calculation report
48
- """
49
- repfile = os.path.join(folder, "report.yaml")
50
- if not os.path.exists(repfile):
51
- raise FileNotFoundError(f"file {repfile} not found")
52
-
53
- with open(repfile, 'r') as fin:
54
- data = yaml.safe_load(fin)
55
- return data
43
+ __version__ = "1.3.13"
56
44
 
57
45
  def _check_equal(val):
58
46
  if not (val[0]==val[1]==val[2]):
calphy/integrators.py CHANGED
@@ -38,12 +38,13 @@ from ase.io import read
38
38
 
39
39
  #Constants
40
40
  h = const.physical_constants["Planck constant in eV/Hz"][0]
41
+ hJ = const.physical_constants["Planck constant"][0]
41
42
  hbar = h/(2*np.pi)
42
43
  kb = const.physical_constants["Boltzmann constant in eV/K"][0]
43
44
  kbJ = const.physical_constants["Boltzmann constant"][0]
44
45
  Na = const.physical_constants["Avogadro constant"][0]
45
46
  eV2J = const.eV
46
-
47
+ J2eV = 6.242E18
47
48
 
48
49
  #--------------------------------------------------------------------
49
50
  # TI PATH INTEGRATION ROUTINES
@@ -469,23 +470,18 @@ def get_einstein_crystal_fe(
469
470
  calc,
470
471
  vol,
471
472
  k,
472
- cm_correction=True):
473
+ cm_correction=True,
474
+ return_contributions=False):
473
475
  """
474
476
  Get the free energy of einstein crystal
475
477
 
476
478
  Parameters
477
479
  ----------
478
- temp : temperature, float
479
- units - K
480
-
481
- natoms : int
482
- no of atoms in the system
483
-
484
- mass : float
485
- units - g/mol
480
+ calc : Calculation object
481
+ contains all input parameters
486
482
 
487
- a : lattice constant, float
488
- units - Angstrom
483
+ vol : float
484
+ converged volume per atom
489
485
 
490
486
  k : spring constant, float
491
487
  units - eV/Angstrom^2
@@ -493,40 +489,77 @@ def get_einstein_crystal_fe(
493
489
  cm_correction : bool, optional, default - True
494
490
  add the centre of mass correction to free energy
495
491
 
492
+ return_contributions: bool, optional, default - True
493
+ If True, return individual contributions to the reference free energy.
494
+
496
495
  Returns
497
496
  -------
498
- fe : float
499
- free energy of Einstein crystal
497
+ F_tot : float
498
+ total free energy of reference crystal
499
+
500
+ F_e : float
501
+ Free energy of Einstein crystal without centre of mass correction. Only if `return_contributions` is True.
502
+
503
+ F_cm : float
504
+ centre of mass correction. Only if `return_contributions` is True.
505
+
506
+ Notes
507
+ -----
508
+ The equations for free energy of Einstein crystal and centre of mass correction are from https://doi.org/10.1063/5.0044833.
500
509
 
501
510
  """
502
- #convert mass first for single particle in kg
503
- mass = np.array([calc._element_dict[x]['mass'] for x in calc.element])
504
- mass = (mass/Na)*1E-3
505
- natoms = np.sum([calc._element_dict[x]['count'] for x in calc.element])
506
- concentration = np.array([calc._element_dict[x]['composition'] for x in calc.element])
511
+ #temperature
512
+ temp = calc._temperature
507
513
 
508
- #convert k from ev/A2 to J/m2
509
- k = np.array(k)*(eV2J/1E-20)
510
- omega = np.sqrt(k/mass)
514
+ #natoms
515
+ natoms = np.sum([calc._element_dict[x]['count'] for x in calc.element])
511
516
 
512
517
  #convert a to m3
513
518
  vol = vol*1E-30
514
519
 
515
- F_harm = 0
516
- F_cm = 0
520
+ #whats the beta
521
+ beta = (1/(kbJ*temp))
517
522
 
518
- for count, om in enumerate(omega):
519
- if concentration[count] > 0:
520
- F_harm += concentration[count]*np.log((hbar*om)/(kb*calc._temperature))
521
- if cm_correction:
522
- F_cm += np.log((natoms*concentration[count]/vol)*(2*np.pi*kbJ*calc._temperature/(natoms*concentration[count]*k[count]))**1.5)
523
- #F_cm = 0
524
- F_harm = 3*kb*calc._temperature*F_harm
525
- F_cm = (kb*calc._temperature/natoms)*F_cm
526
-
527
- F_harm = F_harm + F_cm
523
+ #create an array of mass
524
+ mass = []
525
+ for x in calc.element:
526
+ for count in range(calc._element_dict[x]['count']):
527
+ mass.append(calc._element_dict[x]['mass'])
528
+ mass = np.array(mass)
529
+
530
+ #convert mass to kg
531
+ mass = (mass/Na)*1E-3
528
532
 
529
- return F_harm
533
+ #create an array of k as well
534
+ karr = []
535
+ for c, x in enumerate(calc.element):
536
+ for count in range(calc._element_dict[x]['count']):
537
+ karr.append(k[c])
538
+ k = np.array(karr)
539
+ #convert k from ev/A2 to J/m2
540
+ k = k*(eV2J/1E-20)
541
+
542
+ #fe of Einstein crystal
543
+ Z_e = ((beta**2*k*hJ**2)/(4*np.pi**2*mass))**1.5
544
+ F_e = np.log(Z_e)
545
+ F_e = kb*temp*np.sum(F_e)/natoms #*J2eV #convert back to eV
546
+
547
+ #now get the cm correction
548
+ if cm_correction:
549
+ mass_sum = np.sum(mass)
550
+ mu = mass/mass_sum
551
+ mu2_over_k = mu**2/k
552
+ mu2_over_k_sum = np.sum(mu2_over_k)
553
+ prefactor = vol
554
+ F_cm = np.log(prefactor*(beta/(2*np.pi*mu2_over_k_sum))**1.5)
555
+ F_cm = kb*temp*F_cm/natoms #convert to eV
556
+ else:
557
+ F_cm = 0
558
+
559
+ F_tot = F_e - F_cm
560
+ if return_contributions:
561
+ return F_e, -F_cm
562
+ return F_tot
530
563
 
531
564
  #--------------------------------------------------------------------
532
565
  # REF. STATE ROUTINES: LIQUID
calphy/phase.py CHANGED
@@ -163,6 +163,8 @@ class Phase:
163
163
 
164
164
  self.ferr = 0
165
165
  self.fref = 0
166
+ self.feinstein = 0
167
+ self.fcm = 0
166
168
  self.fideal = 0
167
169
 
168
170
  self.w = 0
@@ -596,8 +598,12 @@ class Phase:
596
598
 
597
599
  #now we can check if it converted
598
600
  file = os.path.join(self.simfolder, "avg.dat")
599
- lx, ly, lz, ipress = np.loadtxt(file, usecols=(1, 2, 3, 4), unpack=True)
600
- lxpc = ipress
601
+ #we have to clean the data, so as just the last block is selected
602
+ lx, ly, lz, lxpc = np.loadtxt(file, usecols=(1, 2, 3, 4), unpack=True)
603
+ lx = lx[-ncount+1:]
604
+ ly = ly[-ncount+1:]
605
+ lz = lx[-ncount+1:]
606
+ lxpc = lxpc[-ncount+1:]
601
607
  mean = np.mean(lxpc)
602
608
  std = np.std(lxpc)
603
609
  volatom = np.mean((lx*ly*lz)/self.natoms)
@@ -610,16 +616,20 @@ class Phase:
610
616
  ncount = int(self.calc.md.n_small_steps)//int(self.calc.md.n_every_steps*self.calc.md.n_repeat_steps)
611
617
 
612
618
  file = os.path.join(self.simfolder, "avg.dat")
613
- lx, ly, lz, ipress = np.loadtxt(file, usecols=(1, 2, 3, 4), unpack=True)
614
- lxpc = ipress
619
+ lx, ly, lz, lxpc = np.loadtxt(file, usecols=(1, 2, 3, 4), unpack=True)
620
+ lx = lx[-ncount+1:]
621
+ ly = ly[-ncount+1:]
622
+ lz = lx[-ncount+1:]
623
+ lxpc = lxpc[-ncount+1:]
624
+
615
625
  mean = np.mean(lxpc)
616
626
  std = np.std(lxpc)
617
627
  volatom = np.mean((lx*ly*lz)/self.natoms)
618
628
 
619
629
  self.calc._pressure = mean
620
- self.lx = np.round(np.mean(lx[-ncount+1:]), decimals=3)
621
- self.ly = np.round(np.mean(ly[-ncount+1:]), decimals=3)
622
- self.lz = np.round(np.mean(lz[-ncount+1:]), decimals=3)
630
+ self.lx = np.round(np.mean(lx), decimals=3)
631
+ self.ly = np.round(np.mean(ly), decimals=3)
632
+ self.lz = np.round(np.mean(lz), decimals=3)
623
633
  self.volatom = volatom
624
634
  self.vol = self.lx*self.ly*self.lz
625
635
  self.rho = self.natoms/(self.lx*self.ly*self.lz)
@@ -682,6 +692,8 @@ class Phase:
682
692
  report["results"]["free_energy"] = float(self.fe)
683
693
  report["results"]["error"] = float(self.ferr)
684
694
  report["results"]["reference_system"] = float(self.fref)
695
+ report["results"]["einstein_crystal"] = float(self.feinstein)
696
+ report["results"]["com_correction"] = float(self.fcm)
685
697
  report["results"]["work"] = float(self.w)
686
698
  report["results"]["pv"] = float(self.pv)
687
699
  report["results"]["unit"] = "eV/atom"
@@ -0,0 +1,229 @@
1
+ import os
2
+ import numpy as np
3
+ import yaml
4
+ import matplotlib.pyplot as plt
5
+ import warnings
6
+
7
+ def read_report(folder):
8
+ """
9
+ Read the finished calculation report
10
+
11
+ Parameters
12
+ ----------
13
+ folder: string
14
+ folder from which calculation is to be read
15
+
16
+ Returns
17
+ -------
18
+ data: dict
19
+ dictionary with results
20
+
21
+ """
22
+ repfile = os.path.join(folder, "report.yaml")
23
+ if not os.path.exists(repfile):
24
+ raise FileNotFoundError(f"file {repfile} not found")
25
+
26
+ with open(repfile, 'r') as fin:
27
+ data = yaml.safe_load(fin)
28
+ return data
29
+
30
+ def _extract_error(errfile):
31
+ error_code = None
32
+ if os.path.exists(errfile):
33
+ with open(errfile, 'r') as fin:
34
+ for line in fin:
35
+ if 'calphy.errors' in line:
36
+ break
37
+ try:
38
+ error_code = line.split(':')[0].split('.')[-1]
39
+ except:
40
+ pass
41
+ return error_code
42
+
43
+ def gather_results(mainfolder):
44
+ """
45
+ Gather results from all subfolders in a given folder into a Pandas DataFrame
46
+
47
+ Parameters
48
+ ----------
49
+ mainfolder: string
50
+ folder where calculations are stored
51
+
52
+ Returns
53
+ -------
54
+ df: pandas DataFrame
55
+ DataFrame with results
56
+ """
57
+ try:
58
+ import pandas as pd
59
+ except ImportError:
60
+ raise ImportError('Please install pandas to use this function')
61
+
62
+ datadict = {}
63
+ datadict['mode'] = []
64
+ datadict['status'] = []
65
+ datadict['temperature'] = []
66
+ datadict['pressure'] = []
67
+ datadict['free_energy'] = []
68
+ datadict['reference_phase'] = []
69
+ datadict['error_code'] = []
70
+ datadict['composition'] = []
71
+ datadict['calculation'] = []
72
+
73
+ folders = next(os.walk(mainfolder))[1]
74
+ for folder in folders:
75
+ #adjust for pyiron folder, see
76
+ if folder.split('_')[-1] == 'hdf5':
77
+ #this could be a pyiron calc
78
+ withouthdf = folder.split('_hdf5')[0]
79
+ folder = f'{folder}/{withouthdf}'
80
+
81
+ inpfile = os.path.join(mainfolder, folder, 'input_file.yaml')
82
+ #print(inpfile)
83
+ if not os.path.exists(inpfile):
84
+ continue;
85
+
86
+ #ok, valid calculation, try to parse input file to get info
87
+ with open(inpfile, 'r') as fin:
88
+ inp = yaml.safe_load(fin)
89
+ #grab the first calculation
90
+ inp = inp['calculations'][0]
91
+ #mode
92
+ mode = inp['mode']
93
+ datadict['mode'].append(mode)
94
+ datadict['temperature'].append(inp['temperature'])
95
+ datadict['pressure'].append(inp['pressure'])
96
+ datadict['reference_phase'].append(inp['reference_phase'])
97
+ datadict['composition'].append(None)
98
+ datadict['calculation'].append(folder)
99
+
100
+ #check output file
101
+ outfile = os.path.join(mainfolder, folder, 'report.yaml')
102
+ datadict['error_code'].append(None)
103
+
104
+ #print(inpfile)
105
+ if not os.path.exists(outfile):
106
+ datadict['status'].append('False')
107
+ datadict['free_energy'].append(np.NaN)
108
+ #check if error file is found
109
+ errfile = os.path.join(os.getcwd(), mainfolder, folder+'.sub.err')
110
+ datadict['error_code'][-1] = _extract_error(errfile)
111
+ continue;
112
+
113
+ if mode in ['fe', 'alchemy', 'composition_scaling']:
114
+ datadict['status'].append('True')
115
+
116
+ #ok, valid calculation, try to parse input file to get info
117
+ with open(outfile, 'r') as fin:
118
+ out = yaml.safe_load(fin)
119
+
120
+ datadict['free_energy'].append(out['results']['free_energy'])
121
+
122
+ #add normal composition
123
+ el_arr = np.array(out['input']['element'].split(' ')).astype(str)
124
+ comp_arr = np.array(out['input']['concentration'].split(' ')).astype(float)
125
+ composition = {x:y for x,y in zip(el_arr, comp_arr)}
126
+ datadict['composition'][-1] = composition
127
+
128
+ if mode == 'composition_scaling':
129
+ #we need to update composition
130
+ compdict = inp['composition_scaling']['output_chemical_composition']
131
+ maxatoms = np.sum([val for key, val in compdict.items()])
132
+ for key, val in compdict.items():
133
+ compdict[key] = val/maxatoms
134
+ datadict['composition'][-1] = compdict
135
+
136
+ #parse extra info
137
+ if mode in ['ts', 'tscale']:
138
+ datafile = os.path.join(os.getcwd(), mainfolder, folder, 'temperature_sweep.dat')
139
+ if os.path.exists(datafile):
140
+ datadict['status'].append('True')
141
+ t, f = np.loadtxt(datafile, unpack=True, usecols=(0,1))
142
+ datadict['temperature'][-1] = t
143
+ datadict['free_energy'][-1] = f
144
+ else:
145
+ datadict['status'].append('False')
146
+ errfile = os.path.join(os.getcwd(), mainfolder, folder+'.sub.err')
147
+ datadict['error_code'][-1] = _extract_error(errfile)
148
+
149
+ df = pd.DataFrame(data=datadict)
150
+ return df
151
+
152
+ def find_transition_temperature(folder1, folder2, fit_order=4, plot=True):
153
+ """
154
+ Find transition temperature where free energy of two phases are equal.
155
+
156
+ Parameters
157
+ ----------
158
+ folder1: string
159
+ directory with temperature scale calculation
160
+
161
+ folder2: string
162
+ directory with temperature scale calculation
163
+
164
+ fit_order: int, optional
165
+ default 4. Order for polynomial fit of temperature vs free energy
166
+
167
+ plot: bool, optional
168
+ default True. Plot the results.
169
+ """
170
+ file1 = os.path.join(folder1, 'temperature_sweep.dat')
171
+ file2 = os.path.join(folder2, 'temperature_sweep.dat')
172
+ if not os.path.exists(file1):
173
+ raise FileNotFoundError(f'{file1} does not exist')
174
+ if not os.path.exists(file2):
175
+ raise FileNotFoundError(f'{file2} does not exist')
176
+
177
+ t1, f1 = np.loadtxt(file1, unpack=True, usecols=(0,1))
178
+ t2, f2 = np.loadtxt(file2, unpack=True, usecols=(0,1))
179
+
180
+ #do some fitting to determine temps
181
+ t1min = np.min(t1)
182
+ t2min = np.min(t2)
183
+ t1max = np.max(t1)
184
+ t2max = np.max(t2)
185
+
186
+ tmin = np.min([t1min, t2min])
187
+ tmax = np.max([t1max, t2max])
188
+
189
+ #warn about extrapolation
190
+ if not t1min == t2min:
191
+ warnings.warn(f'free energy is being extrapolated!')
192
+ if not t1max == t2max:
193
+ warnings.warn(f'free energy is being extrapolated!')
194
+
195
+ #now fit
196
+ f1fit = np.polyfit(t1, f1, fit_order)
197
+ f2fit = np.polyfit(t2, f2, fit_order)
198
+
199
+ #reevaluate over the new range
200
+ fit_t = np.arange(tmin, tmax+1, 1)
201
+ fit_f1 = np.polyval(f1fit, fit_t)
202
+ fit_f2 = np.polyval(f2fit, fit_t)
203
+
204
+ #now evaluate the intersection temp
205
+ arg = np.argsort(np.abs(fit_f1-fit_f2))[0]
206
+ transition_temp = fit_t[arg]
207
+
208
+ #warn if the temperature is shady
209
+ if np.abs(transition_temp-tmin) < 1E-3:
210
+ warnings.warn('It is likely there is no intersection of free energies')
211
+ elif np.abs(transition_temp-tmax) < 1E-3:
212
+ warnings.warn('It is likely there is no intersection of free energies')
213
+
214
+ #plot
215
+ if plot:
216
+ c1lo = '#ef9a9a'
217
+ c1hi = '#b71c1c'
218
+ c2lo = '#90caf9'
219
+ c2hi = '#0d47a1'
220
+
221
+ plt.plot(fit_t, fit_f1, color=c1lo, label=f'{folder1} fit')
222
+ plt.plot(fit_t, fit_f2, color=c2lo, label=f'{folder2} fit')
223
+ plt.plot(t1, f1, color=c1hi, label=folder1, ls='dashed')
224
+ plt.plot(t2, f2, color=c2hi, label=folder2, ls='dashed')
225
+ plt.axvline(transition_temp, ls='dashed', c='#37474f')
226
+ plt.ylabel('Free energy (eV/atom)')
227
+ plt.xlabel('Temperature (K)')
228
+ plt.legend(frameon=False)
229
+ return transition_temp
calphy/solid.py CHANGED
@@ -516,17 +516,20 @@ class Solid(cph.Phase):
516
516
  Calculates the final work, energy dissipation and free energy by
517
517
  matching with Einstein crystal
518
518
  """
519
- f1 = get_einstein_crystal_fe(
519
+ fe, fcm = get_einstein_crystal_fe(
520
520
  self.calc,
521
521
  self.vol,
522
- self.k)
522
+ self.k,
523
+ return_contributions=True)
523
524
 
524
525
  w, q, qerr = find_w(self.simfolder,
525
526
  self.calc,
526
527
  full=True,
527
528
  solid=True)
528
529
 
529
- self.fref = f1
530
+ self.fref = fe + fcm
531
+ self.feinstein = fe
532
+ self.fcm = fcm
530
533
  self.w = w
531
534
  self.ferr = qerr
532
535
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: calphy
3
- Version: 1.3.10
3
+ Version: 1.3.13
4
4
  Summary: free energy calculation for python
5
5
  Home-page: https://github.com/ICAMS/calphy
6
6
  Author: Sarath Menon, Yury Lysogorskiy, Ralf Drautz
@@ -1,24 +1,25 @@
1
- calphy/__init__.py,sha256=w9XLioZKvY0Z1pvwKo_2S1s8SsILErVXJOpojhsHbA4,234
1
+ calphy/__init__.py,sha256=O46MqskwAlD2DmoXB8prjLeuCUBlzHuKsv-SaqjTohY,234
2
2
  calphy/alchemy.py,sha256=epv_vJoAMVbj-S1TuPSbBGr4w_a9qEr4EIxKlgwdlSo,12893
3
3
  calphy/clitools.py,sha256=oDqaw0s-LJ7tAdW_Njk2SFljVx6K34Rs8sdMz48SNSI,4125
4
4
  calphy/composition_transformation.py,sha256=Hh240-iVGC8ATlJ3nQK757qVZIBrE2aw7dsF46mi3oo,15353
5
5
  calphy/errors.py,sha256=KN47RWTLbg1H_NZMrhCiJCbqjqJScJ1pgQAuzj1-l84,1268
6
6
  calphy/helpers.py,sha256=nj8g53H6ScohQtyV7Enzms8Rv_89PRrDDY1IHjFSZdQ,8292
7
- calphy/input.py,sha256=qI8BCx_zZ_909Jaa2sxePHQDcp4oDzychVaZKfUgAVM,29718
8
- calphy/integrators.py,sha256=pblWLGngLgjBbHwVsjl3K7pr3eh4z3oZ261XdLlQNOA,20774
7
+ calphy/input.py,sha256=836ifhhVHm6Nd9jMWLjMUYKukk_pcZwvoGcLzQXIWuU,29400
8
+ calphy/integrators.py,sha256=hJYmbznsgY-x-eZm7ng8gW0qsGbopERl5gGDnw5uLms,21719
9
9
  calphy/kernel.py,sha256=rd_-EfCiBhQjkxcVaoLtVJB2_qDgS-g-dQ0BZBTJQ_A,6190
10
10
  calphy/liquid.py,sha256=a5NTAjc3VsrPBQoEMGe9O1WXfv1vxGoB0xPguf0fOyM,13762
11
- calphy/phase.py,sha256=ukqad4MJ-MNGiyOsq2_jntG2s10UHbJVi2Ounpg_S2U,44787
11
+ calphy/phase.py,sha256=NBkOGkG3U9Uo-dbupFWndOaaCiiSRoD8WHUpunYZty0,45190
12
12
  calphy/phase_diagram.py,sha256=2EwmT_qkT5BEP6Sx0_rm09kPP2RWh5JY4sogIBK_AhA,12992
13
+ calphy/postprocessing.py,sha256=CztgekCvQ8lZPVfZ_hMAwlyvwetjSfADjTca8aVTftY,7602
13
14
  calphy/queuekernel.py,sha256=4GMIYnjMiAPipoLNKP5noYcfeEOI_vCqm84zgokk7Xw,5321
14
15
  calphy/routines.py,sha256=W6OZEPv6HEG11EYsoIbum2WVrO3Ly36i5UWsYQ4oBdQ,17473
15
16
  calphy/scheduler.py,sha256=IN8ogDedpTbZZsdpOj-hYZI05gWoD4bN7mHOb1z77Vo,8579
16
- calphy/solid.py,sha256=49gT0wNOP3h8lRDXarULP-bU09lIrnDCTUcyxE7X-UE,19795
17
+ calphy/solid.py,sha256=ZU_c4LqASoLzhjXX6eQY_8k_FNO9wjmMVTiOCKNsmis,19896
17
18
  calphy/splines.py,sha256=BGwUVz_qXQxUzpUCuZo6CsELcd5JVNWzI-Ttcz22G_E,61627
18
19
  calphy/utils.py,sha256=0UpsYoxjS5N-iGs-cdm0YDMkLF8IHvKO3smXDHrj3eg,3818
19
- calphy-1.3.10.dist-info/LICENSE,sha256=XIHGB5RZLIhOjjoO1bPf0II-qDbjhP5Cv5HJMRE9v1g,16651
20
- calphy-1.3.10.dist-info/METADATA,sha256=-Pgiun1WuVVvcxqipSbOcN5TSr9AdYRJ_CQWpAE1KG4,4216
21
- calphy-1.3.10.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
22
- calphy-1.3.10.dist-info/entry_points.txt,sha256=W9qq254koyWnAgo1jtfQP9bO5Q7sgZrzc8BMnfo3vf4,386
23
- calphy-1.3.10.dist-info/top_level.txt,sha256=w871dhMqPwgjjbifBWdkT9_aOnK1ek4Odrh8UnSG3PE,7
24
- calphy-1.3.10.dist-info/RECORD,,
20
+ calphy-1.3.13.dist-info/LICENSE,sha256=XIHGB5RZLIhOjjoO1bPf0II-qDbjhP5Cv5HJMRE9v1g,16651
21
+ calphy-1.3.13.dist-info/METADATA,sha256=JCQSN5W690zkuPLQ9vqmc8mSOr56K6GOq8EiqEaymWo,4216
22
+ calphy-1.3.13.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
23
+ calphy-1.3.13.dist-info/entry_points.txt,sha256=W9qq254koyWnAgo1jtfQP9bO5Q7sgZrzc8BMnfo3vf4,386
24
+ calphy-1.3.13.dist-info/top_level.txt,sha256=w871dhMqPwgjjbifBWdkT9_aOnK1ek4Odrh8UnSG3PE,7
25
+ calphy-1.3.13.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (72.1.0)
2
+ Generator: setuptools (75.6.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5