calphy 1.3.13__py3-none-any.whl → 1.4.3__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.13"
7
+ __version__ = "1.4.3"
8
8
 
9
9
  def addtest(a,b):
10
10
  return a+b
calphy/alchemy.py CHANGED
@@ -19,6 +19,10 @@ DOI: 10.1103/PhysRevMaterials.5.103801
19
19
 
20
20
  For more information contact:
21
21
  sarath.menon@ruhr-uni-bochum.de/yury.lysogorskiy@icams.rub.de
22
+
23
+ Notes
24
+ -----
25
+ - swapping is strictly only performed between types 1 and 2 at the moment; this needs to be refined further
22
26
  """
23
27
 
24
28
  import numpy as np
@@ -159,6 +163,9 @@ class Alchemy(cph.Phase):
159
163
  lmp.command(f'pair_coeff {self.calc.pair_coeff[0]}')
160
164
  lmp = ph.set_mass(lmp, self.calc)
161
165
 
166
+ #NEW ADDED
167
+ lmp.command("group g1 type 1")
168
+ lmp.command("group g2 type 2")
162
169
  #lmp = ph.set_double_hybrid_potential(lmp, self.options, self.calc._pressureair_style, self.calc._pressureair_coeff)
163
170
 
164
171
  #remap the box to get the correct pressure
@@ -173,9 +180,12 @@ class Alchemy(cph.Phase):
173
180
  lmp.command("fix f1 all nvt temp %f %f %f"%(self.calc._temperature, self.calc._temperature,
174
181
  self.calc.md.thermostat_damping[1]))
175
182
 
183
+
176
184
  lmp.command("thermo_style custom step pe")
177
185
  lmp.command("thermo 1000")
178
186
  lmp.command("run %d"%self.calc.n_equilibration_steps)
187
+
188
+
179
189
  #equilibration run is over
180
190
 
181
191
  #---------------------------------------------------------------
@@ -226,21 +236,41 @@ class Alchemy(cph.Phase):
226
236
  lmp.command("variable dU1 equal c_c1/atoms") # Driving-force obtained from NEHI procedure.
227
237
  lmp.command("variable dU2 equal c_c2/atoms")
228
238
 
239
+ #add swaps if n_swap is > 0
240
+ if self.calc.monte_carlo.n_swaps > 0:
241
+ self.logger.info(f'{self.calc.monte_carlo.n_swaps} swap moves are performed between {self.calc.monte_carlo.swap_types[0]} and {self.calc.monte_carlo.swap_types[1]} every {self.calc.monte_carlo.n_steps}')
242
+ lmp.command("fix swap all atom/swap %d %d %d %f ke no types %d %d"%(self.calc.monte_carlo.n_steps,
243
+ self.calc.monte_carlo.n_swaps,
244
+ np.random.randint(1, 10000),
245
+ self.calc._temperature,
246
+ self.calc.monte_carlo.swap_types[0],
247
+ self.calc.monte_carlo.swap_types[1]))
248
+ lmp.command("variable a equal f_swap[1]")
249
+ lmp.command("variable b equal f_swap[2]")
250
+ lmp.command("fix swap2 all print 1 \"${a} ${b} ${flambda}\" screen no file swap.forward_%d.dat"%iteration)
251
+
229
252
  # Thermo output.
230
- lmp.command("thermo_style custom step v_dU1 v_dU2")
253
+ if self.calc.monte_carlo.n_swaps > 0:
254
+ lmp.command("thermo_style custom step v_dU1 v_dU2 v_a v_b")
255
+ else:
256
+ lmp.command("thermo_style custom step v_dU1 v_dU2")
231
257
  lmp.command("thermo 1000")
232
258
 
233
-
259
+
234
260
  #save the necessary items to a file: first step
235
261
  lmp.command("fix f2 all print 1 \"${dU1} ${dU2} ${flambda}\" screen no file forward_%d.dat"%iteration)
236
- lmp.command("run %d"%self.calc._n_switching_steps)
237
-
262
+ lmp.command("run %d"%self.calc._n_switching_steps)
238
263
 
239
264
  #now equilibrate at the second potential
240
265
  lmp.command("unfix f2")
241
266
  lmp.command("uncompute c1")
242
267
  lmp.command("uncompute c2")
243
268
 
269
+ #NEW SWAP
270
+ if self.calc.monte_carlo.n_swaps > 0:
271
+ lmp.command("unfix swap")
272
+ lmp.command("unfix swap2")
273
+
244
274
 
245
275
  lmp.command("pair_style %s"%self.calc._pair_style_with_options[1])
246
276
  lmp.command("pair_coeff %s"%self.calc.pair_coeff[1])
@@ -248,7 +278,7 @@ class Alchemy(cph.Phase):
248
278
  # Thermo output.
249
279
  lmp.command("thermo_style custom step pe")
250
280
  lmp.command("thermo 1000")
251
-
281
+
252
282
  #run eqbrm run
253
283
  lmp.command("run %d"%self.calc.n_equilibration_steps)
254
284
 
@@ -278,11 +308,39 @@ class Alchemy(cph.Phase):
278
308
  lmp.command("variable dU1 equal c_c1/atoms") # Driving-force obtained from NEHI procedure.
279
309
  lmp.command("variable dU2 equal c_c2/atoms")
280
310
 
311
+ #add swaps if n_swap is > 0
312
+ if self.calc.monte_carlo.n_swaps > 0:
313
+ if self.calc.monte_carlo.reverse_swap:
314
+ self.logger.info(f'{self.calc.monte_carlo.n_swaps} swap moves are performed between {self.calc.monte_carlo.swap_types[1]} and {self.calc.monte_carlo.swap_types[0]} every {self.calc.monte_carlo.n_steps}')
315
+ lmp.command("fix swap all atom/swap %d %d %d %f ke no types %d %d"%(self.calc.monte_carlo.n_steps,
316
+ self.calc.monte_carlo.n_swaps,
317
+ np.random.randint(1, 10000),
318
+ self.calc._temperature,
319
+ self.calc.monte_carlo.swap_types[1],
320
+ self.calc.monte_carlo.swap_types[0]))
321
+ else:
322
+ self.logger.info(f'{self.calc.monte_carlo.n_swaps} swap moves are performed between {self.calc.monte_carlo.swap_types[0]} and {self.calc.monte_carlo.swap_types[1]} every {self.calc.monte_carlo.n_steps}')
323
+ self.logger.info('note that swaps are not reversed')
324
+ lmp.command("fix swap all atom/swap %d %d %d %f ke no types %d %d"%(self.calc.monte_carlo.n_steps,
325
+ self.calc.monte_carlo.n_swaps,
326
+ np.random.randint(1, 10000),
327
+ self.calc._temperature,
328
+ self.calc.monte_carlo.swap_types[0],
329
+ self.calc.monte_carlo.swap_types[1]))
330
+
331
+ lmp.command("variable a equal f_swap[1]")
332
+ lmp.command("variable b equal f_swap[2]")
333
+ lmp.command("fix swap2 all print 1 \"${a} ${b} ${blambda}\" screen no file swap.backward_%d.dat"%iteration)
334
+
281
335
  # Thermo output.
282
- lmp.command("thermo_style custom step v_dU1 v_dU2")
336
+ if self.calc.monte_carlo.n_swaps > 0:
337
+ lmp.command("thermo_style custom step v_dU1 v_dU2 v_a v_b")
338
+ else:
339
+ lmp.command("thermo_style custom step v_dU1 v_dU2")
283
340
  lmp.command("thermo 1000")
284
341
 
285
342
 
343
+
286
344
  #save the necessary items to a file: first step
287
345
  lmp.command("fix f2 all print 1 \"${dU1} ${dU2} ${flambda}\" screen no file backward_%d.dat"%iteration)
288
346
  lmp.command("run %d"%self.calc._n_switching_steps)
@@ -293,6 +351,8 @@ class Alchemy(cph.Phase):
293
351
  lmp.command("uncompute c1")
294
352
  lmp.command("uncompute c2")
295
353
 
354
+ if self.calc.monte_carlo.n_swaps > 0:
355
+ lmp.command("unfix swap")
296
356
  lmp.close()
297
357
 
298
358
 
@@ -329,8 +389,6 @@ class Alchemy(cph.Phase):
329
389
  return flambda_arr, w_arr, q_arr, qerr_arr
330
390
 
331
391
 
332
-
333
-
334
392
  def mass_integration(self, flambda, ref_mass, target_masses, target_counts):
335
393
  mcorarr, mcorsum = integrate_mass(flambda, ref_mass, target_masses, target_counts,
336
394
  self.calc._temperature, self.natoms)
calphy/clitools.py CHANGED
@@ -11,6 +11,7 @@ from calphy.input import read_inputfile, load_job, save_job, _convert_legacy_inp
11
11
  from calphy.liquid import Liquid
12
12
  from calphy.solid import Solid
13
13
  from calphy.alchemy import Alchemy
14
+ from calphy.phase_diagram import prepare_inputs_for_phase_diagram
14
15
 
15
16
  def _generate_job(calc, simfolder):
16
17
  if calc.mode == "alchemy" or calc.mode == "composition_scaling":
@@ -120,3 +121,8 @@ def convert_legacy_inputfile():
120
121
  yaml.safe_dump(data, fout)
121
122
 
122
123
 
124
+ def phase_diagram():
125
+ arg = ap.ArgumentParser()
126
+ arg.add_argument("-i", "--input", required=True, type=str,
127
+ help="name of the input file")
128
+ prepare_inputs_for_phase_diagram(args['input'])
@@ -30,6 +30,7 @@ from mendeleev import element
30
30
  from ase.io import read, write
31
31
  from ase.atoms import Atoms
32
32
  from pyscal3.core import element_dict
33
+ from calphy.integrators import kb
33
34
 
34
35
  class CompositionTransformation:
35
36
  """
@@ -124,6 +125,7 @@ class CompositionTransformation:
124
125
  self.atom_species = None
125
126
  self.mappings = None
126
127
  self.unique_mappings = None
128
+ self.mappingdict = None
127
129
  self.prepare_mappings()
128
130
 
129
131
  def dict_to_string(self, inputdict):
@@ -132,8 +134,32 @@ class CompositionTransformation:
132
134
  strlst.append(str(key))
133
135
  strlst.append(str(val))
134
136
  return "".join(strlst)
135
-
136
-
137
+
138
+ @property
139
+ def entropy_contribution(self):
140
+ """
141
+ Find the entropy entribution of the transformation. To get
142
+ free energies, multiply by -T.
143
+ """
144
+ def _log(val):
145
+ if val == 0:
146
+ return 0
147
+ else:
148
+ return np.log(val)
149
+ ents = []
150
+ for key, val in self.output_chemical_composition.items():
151
+ if key in self.input_chemical_composition.keys():
152
+ t1 = self.input_chemical_composition[key]/self.natoms
153
+ t2 = self.output_chemical_composition[key]/self.natoms
154
+ cont = t2*_log(t2) - t1*_log(t1)
155
+ else:
156
+ t1 = 0
157
+ t2 = self.output_chemical_composition[key]/self.natoms
158
+ cont = t2*_log(t2) - 0
159
+ ents.append(cont)
160
+ entropy_term = kb*np.sum(ents)
161
+ return entropy_term
162
+
137
163
  def convert_to_pyscal(self):
138
164
  """
139
165
  Convert a given system to pyscal and give a dict of type mappings
@@ -159,7 +185,6 @@ class CompositionTransformation:
159
185
  self.maxtype = self.actual_species + 1 #+ self.new_species
160
186
  #print(self.typedict)
161
187
 
162
-
163
188
  def get_composition_transformation(self):
164
189
  """
165
190
  From the two given composition transformation, find the transformation dict
@@ -192,9 +217,10 @@ class CompositionTransformation:
192
217
  def mark_atoms(self):
193
218
  for i in range(self.natoms):
194
219
  self.atom_mark.append(False)
195
- self.atom_type = self.pyscal_structure.atoms.types
196
- self.mappings = [f"{x}-{x}" for x in self.atom_type]
197
-
220
+
221
+ self.atom_type = self.pyscal_structure.atoms.types
222
+ self.mappings = [f"{x}-{x}" for x in self.atom_type]
223
+
198
224
  def update_mark_atoms(self):
199
225
  self.marked_atoms = []
200
226
  for key, val in self.to_remove.items():
@@ -281,7 +307,7 @@ class CompositionTransformation:
281
307
  self.update_typedicts()
282
308
  self.compute_possible_mappings()
283
309
  self.update_mappings()
284
-
310
+
285
311
  def prepare_pair_lists(self):
286
312
  self.pair_list_old = []
287
313
  self.pair_list_new = []
@@ -300,8 +326,12 @@ class CompositionTransformation:
300
326
  def update_types(self):
301
327
  for x in range(len(self.atom_type)):
302
328
  self.atom_type[x] = self.mappingdict[self.mappings[x]]
303
- for count in range(len(self.pyscal_structure.atoms.types)):
304
- self.pyscal_structure.atoms.types[count] = self.atom_type[count]
329
+
330
+ #smartify these loops
331
+ #npyscal = len(self.pyscal_structure.atoms.types)
332
+ self.pyscal_structure.atoms.types = self.atom_type
333
+ #for count in range(npyscal)):
334
+ # self.pyscal_structure.atoms.types[count] = self.atom_type[count]
305
335
 
306
336
  def iselement(self, symbol):
307
337
  try:
@@ -331,6 +361,30 @@ class CompositionTransformation:
331
361
  pc_old = " ".join([*pc_before, *self.pair_list_old, *pc_after])
332
362
  pc_new = " ".join([*pc_before, *self.pair_list_new, *pc_after])
333
363
  return pc_old, pc_new
364
+
365
+ def get_swap_types(self):
366
+ """
367
+ Get swapping types
368
+ """
369
+ swap_list = []
370
+ for mapping in self.unique_mappings:
371
+ map_split = mapping.split("-")
372
+ #conserved atom
373
+ if (map_split[0]==map_split[1]):
374
+ pass
375
+ else:
376
+ first_type = map_split[0]
377
+ second_type = map_split[1]
378
+ first_map = f'{first_type}-{first_type}'
379
+ second_map = mapping
380
+
381
+ #get the numbers from dict
382
+ first_swap_type = self.mappingdict[first_map]
383
+ second_swap_type = self.mappingdict[second_map]
384
+
385
+ swap_list.append([first_swap_type, second_swap_type])
386
+ return swap_list[0]
387
+
334
388
 
335
389
  def write_structure(self, outfilename):
336
390
  #create some species dict
calphy/helpers.py CHANGED
@@ -121,8 +121,12 @@ def create_structure(lmp, calc):
121
121
 
122
122
 
123
123
  def set_mass(lmp, options):
124
- for i in range(options.n_elements):
125
- lmp.command(f'mass {i+1} {options.mass[i]}')
124
+ if options.mode == 'composition_scaling':
125
+ lmp.command(f'mass * {options.mass[-1]}')
126
+
127
+ else:
128
+ for i in range(options.n_elements):
129
+ lmp.command(f'mass {i+1} {options.mass[i]}')
126
130
  return lmp
127
131
 
128
132