Skip to content

Commit c04f55b

Browse files
committed
fix n_iteration issue
1 parent 09252ad commit c04f55b

File tree

2 files changed

+218
-0
lines changed

2 files changed

+218
-0
lines changed

calphy/routines.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ def prepare_calcs(self):
9494
calc["mode"] = "ts"
9595
calc["temperature"] = [int(self.tmin), int(self.tmax)]
9696
calc["reference_phase"] = 'solid'
97+
# Preserve n_iterations from the original melting_temperature calculation
98+
if "n_iterations" in data["calculations"][int(self.calc.kernel)]:
99+
calc["n_iterations"] = data["calculations"][int(self.calc.kernel)]["n_iterations"]
97100
calculations["calculations"].append(calc)
98101

99102
with open(self.calc.inputfile, 'r') as fin:
@@ -103,6 +106,9 @@ def prepare_calcs(self):
103106
calc["mode"] = "ts"
104107
calc["temperature"] = [int(self.tmin), int(self.tmax)]
105108
calc["reference_phase"] = 'liquid'
109+
# Preserve n_iterations from the original melting_temperature calculation
110+
if "n_iterations" in data["calculations"][int(self.calc.kernel)]:
111+
calc["n_iterations"] = data["calculations"][int(self.calc.kernel)]["n_iterations"]
106112
calculations["calculations"].append(calc)
107113

108114
outfile = f'{self.calc.create_identifier()}.{self.attempts}.yaml'
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
"""
2+
Test that n_iterations is properly preserved in melting_temperature mode.
3+
4+
This test verifies the fix for the bug where melting_temperature calculations
5+
with n_iterations > 1 would fail because n_iterations wasn't passed to the
6+
internal ts calculations.
7+
"""
8+
9+
import pytest
10+
import tempfile
11+
import os
12+
import yaml
13+
from calphy.routines import MeltingTemp
14+
from calphy.input import read_inputfile
15+
16+
17+
def test_melting_temperature_preserves_n_iterations():
18+
"""
19+
Test that n_iterations is preserved when melting_temperature creates
20+
internal ts calculations for solid and liquid phases.
21+
"""
22+
23+
with tempfile.TemporaryDirectory() as tmpdir:
24+
# Create a dummy structure file
25+
structure_file = os.path.join(tmpdir, "conf.data")
26+
with open(structure_file, 'w') as f:
27+
f.write("""LAMMPS data file
28+
29+
1 atoms
30+
1 atom types
31+
32+
0.0 4.05 xlo xhi
33+
0.0 4.05 ylo yhi
34+
0.0 4.05 zlo zhi
35+
36+
Masses
37+
38+
1 26.98
39+
40+
Atoms
41+
42+
1 1 0.0 0.0 0.0
43+
""")
44+
45+
# Create a minimal input file for melting_temperature with n_iterations > 1
46+
input_data = {
47+
"calculations": [
48+
{
49+
"mode": "melting_temperature",
50+
"lattice": structure_file,
51+
"state": "solid",
52+
"temperature": 1000,
53+
"pressure": 0,
54+
"n_iterations": 3, # This should be preserved
55+
"element": ["Al"],
56+
"mass": [26.98],
57+
"pair_style": ["eam/alloy"],
58+
"pair_coeff": ["* * Al.eam.alloy Al"],
59+
}
60+
]
61+
}
62+
63+
input_file = os.path.join(tmpdir, "input.yaml")
64+
with open(input_file, "w") as f:
65+
yaml.safe_dump(input_data, f)
66+
67+
# Read the input file
68+
calculations = read_inputfile(input_file)
69+
calc = calculations[0]
70+
71+
# Create MeltingTemp object
72+
melt = MeltingTemp(calculation=calc, simfolder=tmpdir)
73+
74+
# Prepare the internal calculations
75+
melt.prepare_calcs()
76+
77+
# Verify that both solid and liquid calculations have n_iterations = 3
78+
assert len(melt.calculations) == 2, "Should create 2 calculations (solid and liquid)"
79+
80+
solid_calc = melt.calculations[0]
81+
liquid_calc = melt.calculations[1]
82+
83+
assert solid_calc.mode == "ts", "First calculation should be ts mode"
84+
assert liquid_calc.mode == "ts", "Second calculation should be ts mode"
85+
86+
assert solid_calc.reference_phase == "solid", "First calculation should be solid"
87+
assert liquid_calc.reference_phase == "liquid", "Second calculation should be liquid"
88+
89+
# Critical assertion: n_iterations should be preserved
90+
assert solid_calc.n_iterations == 3, f"Solid calc should have n_iterations=3, got {solid_calc.n_iterations}"
91+
assert liquid_calc.n_iterations == 3, f"Liquid calc should have n_iterations=3, got {liquid_calc.n_iterations}"
92+
93+
94+
def test_melting_temperature_default_n_iterations():
95+
"""
96+
Test that when n_iterations is not specified, it defaults to 1.
97+
"""
98+
99+
with tempfile.TemporaryDirectory() as tmpdir:
100+
# Create a dummy structure file
101+
structure_file = os.path.join(tmpdir, "conf.data")
102+
with open(structure_file, 'w') as f:
103+
f.write("""LAMMPS data file
104+
105+
1 atoms
106+
1 atom types
107+
108+
0.0 4.05 xlo xhi
109+
0.0 4.05 ylo yhi
110+
0.0 4.05 zlo zhi
111+
112+
Masses
113+
114+
1 26.98
115+
116+
Atoms
117+
118+
1 1 0.0 0.0 0.0
119+
""")
120+
121+
# Create input without n_iterations specified
122+
input_data = {
123+
"calculations": [
124+
{
125+
"mode": "melting_temperature",
126+
"lattice": structure_file,
127+
"state": "solid",
128+
"temperature": 1000,
129+
"pressure": 0,
130+
# n_iterations not specified - should default to 1
131+
"element": ["Al"],
132+
"mass": [26.98],
133+
"pair_style": ["eam/alloy"],
134+
"pair_coeff": ["* * Al.eam.alloy Al"],
135+
}
136+
]
137+
}
138+
139+
input_file = os.path.join(tmpdir, "input.yaml")
140+
with open(input_file, "w") as f:
141+
yaml.safe_dump(input_data, f)
142+
143+
calculations = read_inputfile(input_file)
144+
calc = calculations[0]
145+
146+
melt = MeltingTemp(calculation=calc, simfolder=tmpdir)
147+
melt.prepare_calcs()
148+
149+
# Should default to 1
150+
assert melt.calculations[0].n_iterations == 1
151+
assert melt.calculations[1].n_iterations == 1
152+
153+
154+
def test_melting_temperature_n_iterations_values():
155+
"""
156+
Test various values of n_iterations to ensure they're all preserved correctly.
157+
"""
158+
159+
for n_iter in [1, 2, 5, 10]:
160+
with tempfile.TemporaryDirectory() as tmpdir:
161+
# Create a dummy structure file
162+
structure_file = os.path.join(tmpdir, "conf.data")
163+
with open(structure_file, 'w') as f:
164+
f.write("""LAMMPS data file
165+
166+
1 atoms
167+
1 atom types
168+
169+
0.0 4.05 xlo xhi
170+
0.0 4.05 ylo yhi
171+
0.0 4.05 zlo zhi
172+
173+
Masses
174+
175+
1 26.98
176+
177+
Atoms
178+
179+
1 1 0.0 0.0 0.0
180+
""")
181+
182+
input_data = {
183+
"calculations": [
184+
{
185+
"mode": "melting_temperature",
186+
"lattice": structure_file,
187+
"state": "solid",
188+
"temperature": 1000,
189+
"pressure": 0,
190+
"n_iterations": n_iter,
191+
"element": ["Al"],
192+
"mass": [26.98],
193+
"pair_style": ["eam/alloy"],
194+
"pair_coeff": ["* * Al.eam.alloy Al"],
195+
}
196+
]
197+
}
198+
199+
input_file = os.path.join(tmpdir, "input.yaml")
200+
with open(input_file, "w") as f:
201+
yaml.safe_dump(input_data, f)
202+
203+
calculations = read_inputfile(input_file)
204+
calc = calculations[0]
205+
206+
melt = MeltingTemp(calculation=calc, simfolder=tmpdir)
207+
melt.prepare_calcs()
208+
209+
assert melt.calculations[0].n_iterations == n_iter, \
210+
f"Solid calc should have n_iterations={n_iter}"
211+
assert melt.calculations[1].n_iterations == n_iter, \
212+
f"Liquid calc should have n_iterations={n_iter}"

0 commit comments

Comments
 (0)