calphy 1.4.5__py3-none-any.whl → 1.4.12__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.4.5"
7
+ __version__ = "1.4.12"
8
8
 
9
9
  def addtest(a,b):
10
10
  return a+b
calphy/alchemy.py CHANGED
@@ -3,14 +3,14 @@ calphy: a Python library and command line interface for automated free
3
3
  energy calculations.
4
4
 
5
5
  Copyright 2021 (c) Sarath Menon^1, Yury Lysogorskiy^2, Ralf Drautz^2
6
- ^1: Max Planck Institut für Eisenforschung, Dusseldorf, Germany
6
+ ^1: Max Planck Institut für Eisenforschung, Dusseldorf, Germany
7
7
  ^2: Ruhr-University Bochum, Bochum, Germany
8
8
 
9
- calphy is published and distributed under the Academic Software License v1.0 (ASL).
10
- calphy is distributed in the hope that it will be useful for non-commercial academic research,
11
- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9
+ calphy is published and distributed under the Academic Software License v1.0 (ASL).
10
+ calphy is distributed in the hope that it will be useful for non-commercial academic research,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
12
  calphy API is published and distributed under the BSD 3-Clause "New" or "Revised" License
13
- See the LICENSE FILE for more details.
13
+ See the LICENSE FILE for more details.
14
14
 
15
15
  More information about the program can be found in:
16
16
  Menon, Sarath, Yury Lysogorskiy, Jutta Rogal, and Ralf Drautz.
@@ -27,11 +27,13 @@ Notes
27
27
 
28
28
  import numpy as np
29
29
  import yaml
30
+ import os
30
31
 
31
32
  from calphy.integrators import *
32
33
  import calphy.helpers as ph
33
34
  import calphy.phase as cph
34
35
 
36
+
35
37
  class Alchemy(cph.Phase):
36
38
  """
37
39
  Class for alchemical transformations
@@ -40,7 +42,7 @@ class Alchemy(cph.Phase):
40
42
  ----------
41
43
  options : dict
42
44
  dict of input options
43
-
45
+
44
46
  kernel : int
45
47
  the index of the calculation that should be run from
46
48
  the list of calculations in the input file
@@ -49,13 +51,13 @@ class Alchemy(cph.Phase):
49
51
  base folder for running calculations
50
52
 
51
53
  """
52
- def __init__(self, calculation=None, simfolder=None, log_to_screen=False):
53
54
 
54
- #call base class
55
- super().__init__(calculation=calculation,
56
- simfolder=simfolder,
57
- log_to_screen=log_to_screen)
55
+ def __init__(self, calculation=None, simfolder=None, log_to_screen=False):
58
56
 
57
+ # call base class
58
+ super().__init__(
59
+ calculation=calculation, simfolder=simfolder, log_to_screen=log_to_screen
60
+ )
59
61
 
60
62
  def run_averaging(self):
61
63
  """
@@ -76,53 +78,58 @@ class Alchemy(cph.Phase):
76
78
  If pressure is specified, MD simulations are run until the pressure converges within the given
77
79
  threshold value.
78
80
  Fix lattice option is not implemented at present.
79
- At the end of the run, the averaged box dimensions are calculated.
81
+ At the end of the run, the averaged box dimensions are calculated.
80
82
  """
81
- lmp = ph.create_object(self.cores, self.simfolder, self.calc.md.timestep,
82
- self.calc.md.cmdargs, self.calc.md.init_commands)
83
+ lmp = ph.create_object(
84
+ self.cores,
85
+ self.simfolder,
86
+ self.calc.md.timestep,
87
+ self.calc.md.cmdargs,
88
+ self.calc.md.init_commands,
89
+ )
83
90
 
84
- lmp.command(f'pair_style {self.calc._pair_style_with_options[0]}')
91
+ lmp.command(f"pair_style {self.calc._pair_style_with_options[0]}")
85
92
 
86
- #set up structure
93
+ # set up structure
87
94
  lmp = ph.create_structure(lmp, self.calc)
88
95
 
89
- #set up potential
90
- lmp.command(f'pair_coeff {self.calc.pair_coeff[0]}')
96
+ # set up potential
97
+ lmp.command(f"pair_coeff {self.calc.pair_coeff[0]}")
91
98
  lmp = ph.set_mass(lmp, self.calc)
92
99
 
93
- #add some computes
100
+ # add some computes
94
101
  lmp.command("variable mvol equal vol")
95
102
  lmp.command("variable mlx equal lx")
96
103
  lmp.command("variable mly equal ly")
97
104
  lmp.command("variable mlz equal lz")
98
105
  lmp.command("variable mpress equal press")
99
106
 
100
- #add some computes
107
+ # add some computes
101
108
  if not self.calc._fix_lattice:
102
109
  if self.calc._pressure == 0:
103
110
  self.run_zero_pressure_equilibration(lmp)
104
111
  else:
105
112
  self.run_finite_pressure_equilibration(lmp)
106
113
 
107
-
108
- #this is when the averaging routine starts
114
+ # this is when the averaging routine starts
109
115
  self.run_pressure_convergence(lmp)
110
-
111
- #run if a constrained lattice is used
116
+
117
+ # run if a constrained lattice is used
112
118
  else:
113
- #routine in which lattice constant will not varied, but is set to a given fixed value
114
- self.run_constrained_pressure_convergence(lmp)
119
+ # routine in which lattice constant will not varied, but is set to a given fixed value
120
+ self.run_constrained_pressure_convergence(lmp)
115
121
 
116
- #check for melting
122
+ # check for melting
117
123
  self.dump_current_snapshot(lmp, "traj.equilibration_stage2.dat")
118
124
  self.check_if_melted(lmp, "traj.equilibration_stage2.dat")
119
125
 
120
- #close object and process traj
126
+ # close object and process traj
121
127
  lmp = ph.write_data(lmp, "conf.equilibration.data")
122
128
  lmp.close()
123
-
124
-
125
-
129
+ # Preserve log file
130
+ logfile = os.path.join(self.simfolder, "log.lammps")
131
+ if os.path.exists(logfile):
132
+ os.rename(logfile, os.path.join(self.simfolder, "averaging.log.lammps"))
126
133
 
127
134
  def run_integration(self, iteration=1):
128
135
  """
@@ -143,111 +150,186 @@ class Alchemy(cph.Phase):
143
150
  the lambda parameter. See algorithm 4 in publication.
144
151
  """
145
152
 
146
- #create lammps object
147
- lmp = ph.create_object(self.cores, self.simfolder, self.calc.md.timestep,
148
- self.calc.md.cmdargs, self.calc.md.init_commands)
149
-
153
+ # create lammps object
154
+ lmp = ph.create_object(
155
+ self.cores,
156
+ self.simfolder,
157
+ self.calc.md.timestep,
158
+ self.calc.md.cmdargs,
159
+ self.calc.md.init_commands,
160
+ )
161
+
150
162
  # Adiabatic switching parameters.
151
163
  lmp.command("variable li equal 1.0")
152
164
  lmp.command("variable lf equal 0.0")
153
165
 
154
- lmp.command(f'pair_style {self.calc._pair_style_with_options[0]}')
155
-
156
- #read dump file
157
- #conf = os.path.join(self.simfolder, "conf.equilibration.dump")
166
+ lmp.command(f"pair_style {self.calc._pair_style_with_options[0]}")
167
+
168
+ # read dump file
169
+ # conf = os.path.join(self.simfolder, "conf.equilibration.dump")
158
170
  conf = os.path.join(self.simfolder, "conf.equilibration.data")
159
171
  lmp = ph.read_data(lmp, conf)
160
172
 
161
- #set up hybrid potential
162
- #here we only need to set one potential
163
- lmp.command(f'pair_coeff {self.calc.pair_coeff[0]}')
173
+ # set up hybrid potential
174
+ # here we only need to set one potential
175
+ lmp.command(f"pair_coeff {self.calc.pair_coeff[0]}")
164
176
  lmp = ph.set_mass(lmp, self.calc)
165
177
 
166
- #NEW ADDED
178
+ # NEW ADDED
167
179
  lmp.command("group g1 type 1")
168
180
  lmp.command("group g2 type 2")
169
- #lmp = ph.set_double_hybrid_potential(lmp, self.options, self.calc._pressureair_style, self.calc._pressureair_coeff)
181
+ # lmp = ph.set_double_hybrid_potential(lmp, self.options, self.calc._pressureair_style, self.calc._pressureair_coeff)
170
182
 
171
- #remap the box to get the correct pressure
183
+ # remap the box to get the correct pressure
172
184
  lmp = ph.remap_box(lmp, self.lx, self.ly, self.lz)
173
185
 
174
- lmp.command("velocity all create %f %d mom yes rot yes dist gaussian"%(self.calc._temperature, np.random.randint(1, 10000)))
186
+ lmp.command(
187
+ "velocity all create %f %d mom yes rot yes dist gaussian"
188
+ % (self.calc._temperature, np.random.randint(1, 10000))
189
+ )
175
190
  # Integrator & thermostat.
176
191
  if self.calc.npt:
177
- lmp.command("fix f1 all npt temp %f %f %f %s %f %f %f"%(self.calc._temperature, self.calc._temperature,
178
- self.calc.md.thermostat_damping[1], self.iso, self.calc._pressure, self.calc._pressure, self.calc.md.barostat_damping[1]))
192
+ lmp.command(
193
+ "fix f1 all npt temp %f %f %f %s %f %f %f"
194
+ % (
195
+ self.calc._temperature,
196
+ self.calc._temperature,
197
+ self.calc.md.thermostat_damping[1],
198
+ self.iso,
199
+ self.calc._pressure,
200
+ self.calc._pressure,
201
+ self.calc.md.barostat_damping[1],
202
+ )
203
+ )
179
204
  else:
180
- lmp.command("fix f1 all nvt temp %f %f %f"%(self.calc._temperature, self.calc._temperature,
181
- self.calc.md.thermostat_damping[1]))
205
+ lmp.command(
206
+ "fix f1 all nvt temp %f %f %f"
207
+ % (
208
+ self.calc._temperature,
209
+ self.calc._temperature,
210
+ self.calc.md.thermostat_damping[1],
211
+ )
212
+ )
182
213
 
183
-
184
214
  lmp.command("thermo_style custom step pe")
185
215
  lmp.command("thermo 1000")
186
- lmp.command("run %d"%self.calc.n_equilibration_steps)
187
-
216
+ lmp.command("run %d" % self.calc.n_equilibration_steps)
217
+
218
+ # equilibration run is over
188
219
 
189
- #equilibration run is over
190
-
191
- #---------------------------------------------------------------
220
+ # ---------------------------------------------------------------
192
221
  # FWD cycle
193
- #---------------------------------------------------------------
222
+ # ---------------------------------------------------------------
194
223
  lmp.command("variable flambda equal ramp(${li},${lf})")
195
224
  lmp.command("variable blambda equal ramp(${lf},${li})")
196
-
197
- #lmp.command("pair_style hybrid/scaled v_flambda %s v_blambda ufm 7.5"%self.options["md"]["pair_style"])
198
-
225
+
226
+ # lmp.command("pair_style hybrid/scaled v_flambda %s v_blambda ufm 7.5"%self.options["md"]["pair_style"])
227
+
199
228
  # Compute pair definitions
200
229
  if self.calc.pair_style[0] == self.calc.pair_style[1]:
201
- pc = self.calc.pair_coeff[0]
230
+ pc = self.calc.pair_coeff[0]
202
231
  pcraw = pc.split()
203
- pc1 = " ".join([*pcraw[:2], *[self.calc._pair_style_names[0],], "1", *pcraw[2:]])
204
- pc = self.calc.pair_coeff[1]
232
+ pc1 = " ".join(
233
+ [
234
+ *pcraw[:2],
235
+ *[
236
+ self.calc._pair_style_names[0],
237
+ ],
238
+ "1",
239
+ *pcraw[2:],
240
+ ]
241
+ )
242
+ pc = self.calc.pair_coeff[1]
205
243
  pcraw = pc.split()
206
- pc2 = " ".join([*pcraw[:2], *[self.calc._pair_style_names[1],], "2", *pcraw[2:]])
244
+ pc2 = " ".join(
245
+ [
246
+ *pcraw[:2],
247
+ *[
248
+ self.calc._pair_style_names[1],
249
+ ],
250
+ "2",
251
+ *pcraw[2:],
252
+ ]
253
+ )
207
254
  else:
208
- pc = self.calc.pair_coeff[0]
255
+ pc = self.calc.pair_coeff[0]
209
256
  pcraw = pc.split()
210
- pc1 = " ".join([*pcraw[:2], *[self.calc._pair_style_names[0],], *pcraw[2:]])
211
- pc = self.calc.pair_coeff[1]
257
+ pc1 = " ".join(
258
+ [
259
+ *pcraw[:2],
260
+ *[
261
+ self.calc._pair_style_names[0],
262
+ ],
263
+ *pcraw[2:],
264
+ ]
265
+ )
266
+ pc = self.calc.pair_coeff[1]
212
267
  pcraw = pc.split()
213
- pc2 = " ".join([*pcraw[:2], *[self.calc._pair_style_names[1],], *pcraw[2:]])
214
-
268
+ pc2 = " ".join(
269
+ [
270
+ *pcraw[:2],
271
+ *[
272
+ self.calc._pair_style_names[1],
273
+ ],
274
+ *pcraw[2:],
275
+ ]
276
+ )
215
277
 
216
- lmp.command("pair_style hybrid/scaled v_flambda %s v_blambda %s"%(
217
- self.calc._pair_style_with_options[0],
218
- self.calc._pair_style_with_options[1]
278
+ lmp.command(
279
+ "pair_style hybrid/scaled v_flambda %s v_blambda %s"
280
+ % (
281
+ self.calc._pair_style_with_options[0],
282
+ self.calc._pair_style_with_options[1],
219
283
  )
220
284
  )
221
- lmp.command("pair_coeff %s"%pc1)
222
- lmp.command("pair_coeff %s"%pc2)
285
+ lmp.command("pair_coeff %s" % pc1)
286
+ lmp.command("pair_coeff %s" % pc2)
223
287
 
224
-
225
- #apply pair force commands
288
+ # apply pair force commands
226
289
  if self.calc._pair_style_names[0] == self.calc._pair_style_names[1]:
227
- lmp.command("compute c1 all pair %s 1"%self.calc._pair_style_names[0])
228
- lmp.command("compute c2 all pair %s 2"%self.calc._pair_style_names[1])
290
+ lmp.command(
291
+ "compute c1 all pair %s 1" % self.calc._pair_style_names[0]
292
+ )
293
+ lmp.command(
294
+ "compute c2 all pair %s 2" % self.calc._pair_style_names[1]
295
+ )
229
296
  else:
230
- lmp.command("compute c1 all pair %s"%self.calc._pair_style_names[0])
231
- lmp.command("compute c2 all pair %s"%self.calc._pair_style_names[1])
232
-
297
+ lmp.command(
298
+ "compute c1 all pair %s" % self.calc._pair_style_names[0]
299
+ )
300
+ lmp.command(
301
+ "compute c2 all pair %s" % self.calc._pair_style_names[1]
302
+ )
233
303
 
234
304
  # Output variables.
235
305
  lmp.command("variable step equal step")
236
- lmp.command("variable dU1 equal c_c1/atoms") # Driving-force obtained from NEHI procedure.
306
+ lmp.command(
307
+ "variable dU1 equal c_c1/atoms"
308
+ ) # Driving-force obtained from NEHI procedure.
237
309
  lmp.command("variable dU2 equal c_c2/atoms")
238
310
 
239
- #add swaps if n_swap is > 0
311
+ # add swaps if n_swap is > 0
240
312
  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]))
313
+ self.logger.info(
314
+ 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}"
315
+ )
316
+ lmp.command(
317
+ "fix swap all atom/swap %d %d %d %f ke no types %d %d"
318
+ % (
319
+ self.calc.monte_carlo.n_steps,
320
+ self.calc.monte_carlo.n_swaps,
321
+ np.random.randint(1, 10000),
322
+ self.calc._temperature,
323
+ self.calc.monte_carlo.swap_types[0],
324
+ self.calc.monte_carlo.swap_types[1],
325
+ )
326
+ )
248
327
  lmp.command("variable a equal f_swap[1]")
249
328
  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)
329
+ lmp.command(
330
+ 'fix swap2 all print 1 "${a} ${b} ${flambda}" screen no file swap.forward_%d.dat'
331
+ % iteration
332
+ )
251
333
 
252
334
  # Thermo output.
253
335
  if self.calc.monte_carlo.n_swaps > 0:
@@ -256,97 +338,126 @@ class Alchemy(cph.Phase):
256
338
  lmp.command("thermo_style custom step v_dU1 v_dU2")
257
339
  lmp.command("thermo 1000")
258
340
 
259
-
260
- #save the necessary items to a file: first step
261
- lmp.command("fix f2 all print 1 \"${dU1} ${dU2} ${flambda}\" screen no file forward_%d.dat"%iteration)
262
- lmp.command("run %d"%self.calc._n_switching_steps)
341
+ # save the necessary items to a file: first step
342
+ lmp.command(
343
+ 'fix f2 all print 1 "${dU1} ${dU2} ${flambda}" screen no file forward_%d.dat'
344
+ % iteration
345
+ )
346
+ lmp.command("run %d" % self.calc._n_switching_steps)
263
347
 
264
- #now equilibrate at the second potential
348
+ # now equilibrate at the second potential
265
349
  lmp.command("unfix f2")
266
350
  lmp.command("uncompute c1")
267
351
  lmp.command("uncompute c2")
268
352
 
269
- #NEW SWAP
353
+ # NEW SWAP
270
354
  if self.calc.monte_carlo.n_swaps > 0:
271
355
  lmp.command("unfix swap")
272
356
  lmp.command("unfix swap2")
273
357
 
274
-
275
- lmp.command("pair_style %s"%self.calc._pair_style_with_options[1])
276
- lmp.command("pair_coeff %s"%self.calc.pair_coeff[1])
358
+ lmp.command("pair_style %s" % self.calc._pair_style_with_options[1])
359
+ lmp.command("pair_coeff %s" % self.calc.pair_coeff[1])
277
360
 
278
361
  # Thermo output.
279
362
  lmp.command("thermo_style custom step pe")
280
363
  lmp.command("thermo 1000")
281
-
282
- #run eqbrm run
283
- lmp.command("run %d"%self.calc.n_equilibration_steps)
284
-
285
-
286
- #reverse switching
364
+
365
+ # run eqbrm run
366
+ lmp.command("run %d" % self.calc.n_equilibration_steps)
367
+
368
+ # reverse switching
287
369
  lmp.command("variable flambda equal ramp(${lf},${li})")
288
370
  lmp.command("variable blambda equal ramp(${li},${lf})")
289
-
290
-
291
- lmp.command("pair_style hybrid/scaled v_flambda %s v_blambda %s"%(self.calc._pair_style_with_options[0],
292
- self.calc._pair_style_with_options[1]))
293
- lmp.command("pair_coeff %s"%pc1)
294
- lmp.command("pair_coeff %s"%pc2)
295
371
 
372
+ lmp.command(
373
+ "pair_style hybrid/scaled v_flambda %s v_blambda %s"
374
+ % (
375
+ self.calc._pair_style_with_options[0],
376
+ self.calc._pair_style_with_options[1],
377
+ )
378
+ )
379
+ lmp.command("pair_coeff %s" % pc1)
380
+ lmp.command("pair_coeff %s" % pc2)
296
381
 
297
- #apply pair force commands
382
+ # apply pair force commands
298
383
  if self.calc._pair_style_names[0] == self.calc._pair_style_names[1]:
299
- lmp.command("compute c1 all pair %s 1"%self.calc._pair_style_names[0])
300
- lmp.command("compute c2 all pair %s 2"%self.calc._pair_style_names[1])
384
+ lmp.command(
385
+ "compute c1 all pair %s 1" % self.calc._pair_style_names[0]
386
+ )
387
+ lmp.command(
388
+ "compute c2 all pair %s 2" % self.calc._pair_style_names[1]
389
+ )
301
390
  else:
302
- lmp.command("compute c1 all pair %s"%self.calc._pair_style_names[0])
303
- lmp.command("compute c2 all pair %s"%self.calc._pair_style_names[1])
304
-
391
+ lmp.command(
392
+ "compute c1 all pair %s" % self.calc._pair_style_names[0]
393
+ )
394
+ lmp.command(
395
+ "compute c2 all pair %s" % self.calc._pair_style_names[1]
396
+ )
305
397
 
306
398
  # Output variables.
307
399
  lmp.command("variable step equal step")
308
- lmp.command("variable dU1 equal c_c1/atoms") # Driving-force obtained from NEHI procedure.
400
+ lmp.command(
401
+ "variable dU1 equal c_c1/atoms"
402
+ ) # Driving-force obtained from NEHI procedure.
309
403
  lmp.command("variable dU2 equal c_c2/atoms")
310
404
 
311
- #add swaps if n_swap is > 0
405
+ # add swaps if n_swap is > 0
312
406
  if self.calc.monte_carlo.n_swaps > 0:
313
407
  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]))
408
+ self.logger.info(
409
+ 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}"
410
+ )
411
+ lmp.command(
412
+ "fix swap all atom/swap %d %d %d %f ke no types %d %d"
413
+ % (
414
+ self.calc.monte_carlo.n_steps,
415
+ self.calc.monte_carlo.n_swaps,
416
+ np.random.randint(1, 10000),
417
+ self.calc._temperature,
418
+ self.calc.monte_carlo.swap_types[1],
419
+ self.calc.monte_carlo.swap_types[0],
420
+ )
421
+ )
321
422
  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]))
423
+ self.logger.info(
424
+ 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}"
425
+ )
426
+ self.logger.info("note that swaps are not reversed")
427
+ lmp.command(
428
+ "fix swap all atom/swap %d %d %d %f ke no types %d %d"
429
+ % (
430
+ self.calc.monte_carlo.n_steps,
431
+ self.calc.monte_carlo.n_swaps,
432
+ np.random.randint(1, 10000),
433
+ self.calc._temperature,
434
+ self.calc.monte_carlo.swap_types[0],
435
+ self.calc.monte_carlo.swap_types[1],
436
+ )
437
+ )
330
438
 
331
439
  lmp.command("variable a equal f_swap[1]")
332
440
  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)
441
+ lmp.command(
442
+ 'fix swap2 all print 1 "${a} ${b} ${blambda}" screen no file swap.backward_%d.dat'
443
+ % iteration
444
+ )
334
445
 
335
446
  # Thermo output.
336
447
  if self.calc.monte_carlo.n_swaps > 0:
337
448
  lmp.command("thermo_style custom step v_dU1 v_dU2 v_a v_b")
338
- else:
449
+ else:
339
450
  lmp.command("thermo_style custom step v_dU1 v_dU2")
340
451
  lmp.command("thermo 1000")
341
452
 
453
+ # save the necessary items to a file: first step
454
+ lmp.command(
455
+ 'fix f2 all print 1 "${dU1} ${dU2} ${flambda}" screen no file backward_%d.dat'
456
+ % iteration
457
+ )
458
+ lmp.command("run %d" % self.calc._n_switching_steps)
342
459
 
343
-
344
- #save the necessary items to a file: first step
345
- lmp.command("fix f2 all print 1 \"${dU1} ${dU2} ${flambda}\" screen no file backward_%d.dat"%iteration)
346
- lmp.command("run %d"%self.calc._n_switching_steps)
347
-
348
-
349
- #now equilibrate at the second potential
460
+ # now equilibrate at the second potential
350
461
  lmp.command("unfix f2")
351
462
  lmp.command("uncompute c1")
352
463
  lmp.command("uncompute c2")
@@ -354,8 +465,10 @@ class Alchemy(cph.Phase):
354
465
  if self.calc.monte_carlo.n_swaps > 0:
355
466
  lmp.command("unfix swap")
356
467
  lmp.close()
357
-
358
-
468
+ # Preserve log file
469
+ logfile = os.path.join(self.simfolder, "log.lammps")
470
+ if os.path.exists(logfile):
471
+ os.rename(logfile, os.path.join(self.simfolder, "integration.log.lammps"))
359
472
 
360
473
  def thermodynamic_integration(self):
361
474
  """
@@ -374,24 +487,31 @@ class Alchemy(cph.Phase):
374
487
  Calculates the final work, energy dissipation; In alchemical mode, there is reference system,
375
488
  the calculated free energy is the same as the work.
376
489
  """
377
- w, q, qerr = find_w(self.simfolder, self.calc,
378
- full=True, solid=False)
490
+ w, q, qerr = find_w(self.simfolder, self.calc, full=True, solid=False)
379
491
 
380
492
  self.w = w
381
493
  self.ferr = qerr
382
494
  self.fe = self.w
383
-
495
+
384
496
  if self.calc.mode == "composition_scaling":
385
- w_arr, q_arr, qerr_arr, flambda_arr = find_w(self.simfolder, self.calc,
386
- full=True, solid=False, composition_integration=True)
497
+ w_arr, q_arr, qerr_arr, flambda_arr = find_w(
498
+ self.simfolder,
499
+ self.calc,
500
+ full=True,
501
+ solid=False,
502
+ composition_integration=True,
503
+ )
387
504
 
388
- #now we need to process the comp scaling
505
+ # now we need to process the comp scaling
389
506
  return flambda_arr, w_arr, q_arr, qerr_arr
390
507
 
391
-
392
508
  def mass_integration(self, flambda, ref_mass, target_masses, target_counts):
393
- mcorarr, mcorsum = integrate_mass(flambda, ref_mass, target_masses, target_counts,
394
- self.calc._temperature, self.natoms)
395
- return mcorarr, mcorsum
396
-
397
-
509
+ mcorarr, mcorsum = integrate_mass(
510
+ flambda,
511
+ ref_mass,
512
+ target_masses,
513
+ target_counts,
514
+ self.calc._temperature,
515
+ self.natoms,
516
+ )
517
+ return mcorarr, mcorsum