calphy 1.4.5__tar.gz → 1.4.12__tar.gz

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.
Files changed (46) hide show
  1. {calphy-1.4.5/calphy.egg-info → calphy-1.4.12}/PKG-INFO +1 -1
  2. {calphy-1.4.5 → calphy-1.4.12}/calphy/__init__.py +1 -1
  3. calphy-1.4.12/calphy/alchemy.py +517 -0
  4. calphy-1.4.12/calphy/composition_transformation.py +577 -0
  5. {calphy-1.4.5 → calphy-1.4.12}/calphy/helpers.py +45 -29
  6. {calphy-1.4.5 → calphy-1.4.12}/calphy/input.py +81 -3
  7. {calphy-1.4.5 → calphy-1.4.12}/calphy/liquid.py +13 -0
  8. {calphy-1.4.5 → calphy-1.4.12}/calphy/phase.py +55 -4
  9. {calphy-1.4.5 → calphy-1.4.12}/calphy/phase_diagram.py +196 -53
  10. {calphy-1.4.5 → calphy-1.4.12}/calphy/routines.py +6 -0
  11. calphy-1.4.12/calphy/scheduler.py +229 -0
  12. {calphy-1.4.5 → calphy-1.4.12}/calphy/solid.py +243 -186
  13. {calphy-1.4.5 → calphy-1.4.12/calphy.egg-info}/PKG-INFO +1 -1
  14. {calphy-1.4.5 → calphy-1.4.12}/calphy.egg-info/SOURCES.txt +6 -0
  15. {calphy-1.4.5 → calphy-1.4.12}/setup.py +1 -1
  16. calphy-1.4.12/tests/test_composition_transformation_bug.py +734 -0
  17. calphy-1.4.12/tests/test_element_ordering.py +141 -0
  18. calphy-1.4.12/tests/test_meam_pair_coeff.py +135 -0
  19. calphy-1.4.12/tests/test_melting_temperature_n_iterations.py +212 -0
  20. calphy-1.4.12/tests/test_phase_diagram.py +242 -0
  21. calphy-1.4.12/tests/test_phase_diagram_validation.py +251 -0
  22. calphy-1.4.5/calphy/alchemy.py +0 -397
  23. calphy-1.4.5/calphy/composition_transformation.py +0 -415
  24. calphy-1.4.5/calphy/scheduler.py +0 -234
  25. {calphy-1.4.5 → calphy-1.4.12}/LICENSE +0 -0
  26. {calphy-1.4.5 → calphy-1.4.12}/MANIFEST.in +0 -0
  27. {calphy-1.4.5 → calphy-1.4.12}/README.md +0 -0
  28. {calphy-1.4.5 → calphy-1.4.12}/calphy/clitools.py +0 -0
  29. {calphy-1.4.5 → calphy-1.4.12}/calphy/errors.py +0 -0
  30. {calphy-1.4.5 → calphy-1.4.12}/calphy/integrators.py +0 -0
  31. {calphy-1.4.5 → calphy-1.4.12}/calphy/kernel.py +0 -0
  32. {calphy-1.4.5 → calphy-1.4.12}/calphy/postprocessing.py +0 -0
  33. {calphy-1.4.5 → calphy-1.4.12}/calphy/queuekernel.py +0 -0
  34. {calphy-1.4.5 → calphy-1.4.12}/calphy/splines.py +0 -0
  35. {calphy-1.4.5 → calphy-1.4.12}/calphy/utils.py +0 -0
  36. {calphy-1.4.5 → calphy-1.4.12}/calphy.egg-info/dependency_links.txt +0 -0
  37. {calphy-1.4.5 → calphy-1.4.12}/calphy.egg-info/entry_points.txt +0 -0
  38. {calphy-1.4.5 → calphy-1.4.12}/calphy.egg-info/not-zip-safe +0 -0
  39. {calphy-1.4.5 → calphy-1.4.12}/calphy.egg-info/requires.txt +0 -0
  40. {calphy-1.4.5 → calphy-1.4.12}/calphy.egg-info/top_level.txt +0 -0
  41. {calphy-1.4.5 → calphy-1.4.12}/setup.cfg +0 -0
  42. {calphy-1.4.5 → calphy-1.4.12}/tests/test_ex07.py +0 -0
  43. {calphy-1.4.5 → calphy-1.4.12}/tests/test_helpers.py +0 -0
  44. {calphy-1.4.5 → calphy-1.4.12}/tests/test_integrators.py +0 -0
  45. {calphy-1.4.5 → calphy-1.4.12}/tests/test_options.py +0 -0
  46. {calphy-1.4.5 → calphy-1.4.12}/tests/test_solid_methods.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: calphy
3
- Version: 1.4.5
3
+ Version: 1.4.12
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
@@ -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
@@ -0,0 +1,517 @@
1
+ """
2
+ calphy: a Python library and command line interface for automated free
3
+ energy calculations.
4
+
5
+ Copyright 2021 (c) Sarath Menon^1, Yury Lysogorskiy^2, Ralf Drautz^2
6
+ ^1: Max Planck Institut für Eisenforschung, Dusseldorf, Germany
7
+ ^2: Ruhr-University Bochum, Bochum, Germany
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.
12
+ calphy API is published and distributed under the BSD 3-Clause "New" or "Revised" License
13
+ See the LICENSE FILE for more details.
14
+
15
+ More information about the program can be found in:
16
+ Menon, Sarath, Yury Lysogorskiy, Jutta Rogal, and Ralf Drautz.
17
+ “Automated Free Energy Calculation from Atomistic Simulations.” Physical Review Materials 5(10), 2021
18
+ DOI: 10.1103/PhysRevMaterials.5.103801
19
+
20
+ For more information contact:
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
26
+ """
27
+
28
+ import numpy as np
29
+ import yaml
30
+ import os
31
+
32
+ from calphy.integrators import *
33
+ import calphy.helpers as ph
34
+ import calphy.phase as cph
35
+
36
+
37
+ class Alchemy(cph.Phase):
38
+ """
39
+ Class for alchemical transformations
40
+
41
+ Parameters
42
+ ----------
43
+ options : dict
44
+ dict of input options
45
+
46
+ kernel : int
47
+ the index of the calculation that should be run from
48
+ the list of calculations in the input file
49
+
50
+ simfolder : string
51
+ base folder for running calculations
52
+
53
+ """
54
+
55
+ def __init__(self, calculation=None, simfolder=None, log_to_screen=False):
56
+
57
+ # call base class
58
+ super().__init__(
59
+ calculation=calculation, simfolder=simfolder, log_to_screen=log_to_screen
60
+ )
61
+
62
+ def run_averaging(self):
63
+ """
64
+ Run averaging routine
65
+
66
+ Parameters
67
+ ----------
68
+ None
69
+
70
+ Returns
71
+ -------
72
+ None
73
+
74
+ Notes
75
+ -----
76
+ Run averaging routine using LAMMPS. Starting from the initial lattice two different routines can
77
+ be followed:
78
+ If pressure is specified, MD simulations are run until the pressure converges within the given
79
+ threshold value.
80
+ Fix lattice option is not implemented at present.
81
+ At the end of the run, the averaged box dimensions are calculated.
82
+ """
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
+ )
90
+
91
+ lmp.command(f"pair_style {self.calc._pair_style_with_options[0]}")
92
+
93
+ # set up structure
94
+ lmp = ph.create_structure(lmp, self.calc)
95
+
96
+ # set up potential
97
+ lmp.command(f"pair_coeff {self.calc.pair_coeff[0]}")
98
+ lmp = ph.set_mass(lmp, self.calc)
99
+
100
+ # add some computes
101
+ lmp.command("variable mvol equal vol")
102
+ lmp.command("variable mlx equal lx")
103
+ lmp.command("variable mly equal ly")
104
+ lmp.command("variable mlz equal lz")
105
+ lmp.command("variable mpress equal press")
106
+
107
+ # add some computes
108
+ if not self.calc._fix_lattice:
109
+ if self.calc._pressure == 0:
110
+ self.run_zero_pressure_equilibration(lmp)
111
+ else:
112
+ self.run_finite_pressure_equilibration(lmp)
113
+
114
+ # this is when the averaging routine starts
115
+ self.run_pressure_convergence(lmp)
116
+
117
+ # run if a constrained lattice is used
118
+ else:
119
+ # routine in which lattice constant will not varied, but is set to a given fixed value
120
+ self.run_constrained_pressure_convergence(lmp)
121
+
122
+ # check for melting
123
+ self.dump_current_snapshot(lmp, "traj.equilibration_stage2.dat")
124
+ self.check_if_melted(lmp, "traj.equilibration_stage2.dat")
125
+
126
+ # close object and process traj
127
+ lmp = ph.write_data(lmp, "conf.equilibration.data")
128
+ lmp.close()
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"))
133
+
134
+ def run_integration(self, iteration=1):
135
+ """
136
+ Run integration routine
137
+
138
+ Parameters
139
+ ----------
140
+ iteration : int, optional
141
+ iteration number for running independent iterations
142
+
143
+ Returns
144
+ -------
145
+ None
146
+
147
+ Notes
148
+ -----
149
+ Run the integration routine where the initial and final systems are connected using
150
+ the lambda parameter. See algorithm 4 in publication.
151
+ """
152
+
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
+
162
+ # Adiabatic switching parameters.
163
+ lmp.command("variable li equal 1.0")
164
+ lmp.command("variable lf equal 0.0")
165
+
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")
170
+ conf = os.path.join(self.simfolder, "conf.equilibration.data")
171
+ lmp = ph.read_data(lmp, conf)
172
+
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]}")
176
+ lmp = ph.set_mass(lmp, self.calc)
177
+
178
+ # NEW ADDED
179
+ lmp.command("group g1 type 1")
180
+ lmp.command("group g2 type 2")
181
+ # lmp = ph.set_double_hybrid_potential(lmp, self.options, self.calc._pressureair_style, self.calc._pressureair_coeff)
182
+
183
+ # remap the box to get the correct pressure
184
+ lmp = ph.remap_box(lmp, self.lx, self.ly, self.lz)
185
+
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
+ )
190
+ # Integrator & thermostat.
191
+ if self.calc.npt:
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
+ )
204
+ else:
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
+ )
213
+
214
+ lmp.command("thermo_style custom step pe")
215
+ lmp.command("thermo 1000")
216
+ lmp.command("run %d" % self.calc.n_equilibration_steps)
217
+
218
+ # equilibration run is over
219
+
220
+ # ---------------------------------------------------------------
221
+ # FWD cycle
222
+ # ---------------------------------------------------------------
223
+ lmp.command("variable flambda equal ramp(${li},${lf})")
224
+ lmp.command("variable blambda equal ramp(${lf},${li})")
225
+
226
+ # lmp.command("pair_style hybrid/scaled v_flambda %s v_blambda ufm 7.5"%self.options["md"]["pair_style"])
227
+
228
+ # Compute pair definitions
229
+ if self.calc.pair_style[0] == self.calc.pair_style[1]:
230
+ pc = self.calc.pair_coeff[0]
231
+ pcraw = pc.split()
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]
243
+ pcraw = pc.split()
244
+ pc2 = " ".join(
245
+ [
246
+ *pcraw[:2],
247
+ *[
248
+ self.calc._pair_style_names[1],
249
+ ],
250
+ "2",
251
+ *pcraw[2:],
252
+ ]
253
+ )
254
+ else:
255
+ pc = self.calc.pair_coeff[0]
256
+ pcraw = pc.split()
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]
267
+ pcraw = pc.split()
268
+ pc2 = " ".join(
269
+ [
270
+ *pcraw[:2],
271
+ *[
272
+ self.calc._pair_style_names[1],
273
+ ],
274
+ *pcraw[2:],
275
+ ]
276
+ )
277
+
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],
283
+ )
284
+ )
285
+ lmp.command("pair_coeff %s" % pc1)
286
+ lmp.command("pair_coeff %s" % pc2)
287
+
288
+ # apply pair force commands
289
+ if self.calc._pair_style_names[0] == 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
+ )
296
+ else:
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
+ )
303
+
304
+ # Output variables.
305
+ lmp.command("variable step equal step")
306
+ lmp.command(
307
+ "variable dU1 equal c_c1/atoms"
308
+ ) # Driving-force obtained from NEHI procedure.
309
+ lmp.command("variable dU2 equal c_c2/atoms")
310
+
311
+ # add swaps if n_swap is > 0
312
+ if self.calc.monte_carlo.n_swaps > 0:
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
+ )
327
+ lmp.command("variable a equal f_swap[1]")
328
+ lmp.command("variable b equal f_swap[2]")
329
+ lmp.command(
330
+ 'fix swap2 all print 1 "${a} ${b} ${flambda}" screen no file swap.forward_%d.dat'
331
+ % iteration
332
+ )
333
+
334
+ # Thermo output.
335
+ if self.calc.monte_carlo.n_swaps > 0:
336
+ lmp.command("thermo_style custom step v_dU1 v_dU2 v_a v_b")
337
+ else:
338
+ lmp.command("thermo_style custom step v_dU1 v_dU2")
339
+ lmp.command("thermo 1000")
340
+
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)
347
+
348
+ # now equilibrate at the second potential
349
+ lmp.command("unfix f2")
350
+ lmp.command("uncompute c1")
351
+ lmp.command("uncompute c2")
352
+
353
+ # NEW SWAP
354
+ if self.calc.monte_carlo.n_swaps > 0:
355
+ lmp.command("unfix swap")
356
+ lmp.command("unfix swap2")
357
+
358
+ lmp.command("pair_style %s" % self.calc._pair_style_with_options[1])
359
+ lmp.command("pair_coeff %s" % self.calc.pair_coeff[1])
360
+
361
+ # Thermo output.
362
+ lmp.command("thermo_style custom step pe")
363
+ lmp.command("thermo 1000")
364
+
365
+ # run eqbrm run
366
+ lmp.command("run %d" % self.calc.n_equilibration_steps)
367
+
368
+ # reverse switching
369
+ lmp.command("variable flambda equal ramp(${lf},${li})")
370
+ lmp.command("variable blambda equal ramp(${li},${lf})")
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)
381
+
382
+ # apply pair force commands
383
+ if self.calc._pair_style_names[0] == 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
+ )
390
+ else:
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
+ )
397
+
398
+ # Output variables.
399
+ lmp.command("variable step equal step")
400
+ lmp.command(
401
+ "variable dU1 equal c_c1/atoms"
402
+ ) # Driving-force obtained from NEHI procedure.
403
+ lmp.command("variable dU2 equal c_c2/atoms")
404
+
405
+ # add swaps if n_swap is > 0
406
+ if self.calc.monte_carlo.n_swaps > 0:
407
+ if self.calc.monte_carlo.reverse_swap:
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
+ )
422
+ else:
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
+ )
438
+
439
+ lmp.command("variable a equal f_swap[1]")
440
+ lmp.command("variable b equal f_swap[2]")
441
+ lmp.command(
442
+ 'fix swap2 all print 1 "${a} ${b} ${blambda}" screen no file swap.backward_%d.dat'
443
+ % iteration
444
+ )
445
+
446
+ # Thermo output.
447
+ if self.calc.monte_carlo.n_swaps > 0:
448
+ lmp.command("thermo_style custom step v_dU1 v_dU2 v_a v_b")
449
+ else:
450
+ lmp.command("thermo_style custom step v_dU1 v_dU2")
451
+ lmp.command("thermo 1000")
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)
459
+
460
+ # now equilibrate at the second potential
461
+ lmp.command("unfix f2")
462
+ lmp.command("uncompute c1")
463
+ lmp.command("uncompute c2")
464
+
465
+ if self.calc.monte_carlo.n_swaps > 0:
466
+ lmp.command("unfix swap")
467
+ lmp.close()
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"))
472
+
473
+ def thermodynamic_integration(self):
474
+ """
475
+ Calculate free energy after integration step
476
+
477
+ Parameters
478
+ ----------
479
+ None
480
+
481
+ Returns
482
+ -------
483
+ None
484
+
485
+ Notes
486
+ -----
487
+ Calculates the final work, energy dissipation; In alchemical mode, there is reference system,
488
+ the calculated free energy is the same as the work.
489
+ """
490
+ w, q, qerr = find_w(self.simfolder, self.calc, full=True, solid=False)
491
+
492
+ self.w = w
493
+ self.ferr = qerr
494
+ self.fe = self.w
495
+
496
+ if self.calc.mode == "composition_scaling":
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
+ )
504
+
505
+ # now we need to process the comp scaling
506
+ return flambda_arr, w_arr, q_arr, qerr_arr
507
+
508
+ def mass_integration(self, flambda, ref_mass, target_masses, target_counts):
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