|
22 | 22 | import pytest |
23 | 23 |
|
24 | 24 | from diffpy.structure.spacegroups import GetSpaceGroup |
| 25 | +from diffpy.structure.structureerrors import SymmetryError |
25 | 26 | from diffpy.structure.symmetryutilities import ( |
26 | 27 | ExpandAsymmetricUnit, |
27 | 28 | GeneratorSite, |
@@ -960,6 +961,69 @@ def test_posparSymbols_and_posparValues(self): |
960 | 961 | assert expected_symbols == actual_symbols |
961 | 962 | assert expected_values == actual_values |
962 | 963 |
|
| 964 | + def test_positionFormulas(self): |
| 965 | + sg225 = GetSpaceGroup(225) |
| 966 | + eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) |
| 967 | + sc = SymmetryConstraints(sg225, eau.expandedpos) |
| 968 | + # C1: Simulate the "not enough symbols" branch |
| 969 | + sc.pospars = [("x1", 0.12), ("y1", 0.34), ("z1", 0.56)] |
| 970 | + sc.poseqns = [ |
| 971 | + {"x": "x1", "y": "y1 +0.5", "z": "-z1 +0.25"}, |
| 972 | + {"x": "-x1 +0.5", "y": "y1", "z": "z1 +0.5"}, |
| 973 | + ] |
| 974 | + with pytest.raises(SymmetryError): |
| 975 | + sc.positionFormulas(["x1"]) # too few custom symbols |
| 976 | + # C2: Normal case, does substitution of x0/y0/z0 tokens in formulas |
| 977 | + # Make pospars consistent with what positionFormulas expects to replace |
| 978 | + actual = sc.positionFormulas(["xA", "yA", "zA"]) |
| 979 | + expected = [ |
| 980 | + {"x": "xA", "y": "yA +0.5", "z": "-zA +0.25"}, |
| 981 | + {"x": "-xA +0.5", "y": "yA", "z": "zA +0.5"}, |
| 982 | + ] |
| 983 | + assert actual == expected |
| 984 | + |
| 985 | + def test_positionFormulasPruned(self): |
| 986 | + sg225 = GetSpaceGroup(225) |
| 987 | + eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) |
| 988 | + sc = SymmetryConstraints(sg225, eau.expandedpos) |
| 989 | + # C1: Remove any key-value pairs with constant values |
| 990 | + sc.pospars = [("x1", 0.12), ("y1", 0.34), ("z1", 0.56)] |
| 991 | + sc.poseqns = [ |
| 992 | + {"x": "x1", "y": "0.25", "z": "-z1 +0.5"}, |
| 993 | + {"x": "0", "y": "y1 +0.5", "z": "0.125"}, |
| 994 | + ] |
| 995 | + actual = sc.positionFormulasPruned(["xA", "yA", "zA"]) |
| 996 | + expected = [ |
| 997 | + {"x": "xA", "z": "-zA +0.5"}, |
| 998 | + {"y": "yA +0.5"}, |
| 999 | + ] |
| 1000 | + assert actual == expected |
| 1001 | + |
| 1002 | + def test_UFormulasPruned(self): |
| 1003 | + """Check SymmetryConstraints.UFormulasPruned()""" |
| 1004 | + u_formulas = { |
| 1005 | + "U11": "A", |
| 1006 | + "U22": "A", |
| 1007 | + "U33": "C", |
| 1008 | + "U12": "0.5*A", |
| 1009 | + "U13": "0", |
| 1010 | + "U23": "0", |
| 1011 | + } |
| 1012 | + expected = [ |
| 1013 | + { |
| 1014 | + "U11": "A", |
| 1015 | + "U22": "A", |
| 1016 | + "U33": "C", |
| 1017 | + "U12": "0.5*A", |
| 1018 | + } |
| 1019 | + ] |
| 1020 | + sg225 = GetSpaceGroup(225) |
| 1021 | + eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) |
| 1022 | + sc = SymmetryConstraints(sg225, eau.expandedpos) |
| 1023 | + sc.Ueqns = [u_formulas] |
| 1024 | + actual = sc.UFormulasPruned(u_formulas) |
| 1025 | + assert actual == expected |
| 1026 | + |
963 | 1027 |
|
964 | 1028 | # def test_UFormulas(self): |
965 | 1029 | # """check SymmetryConstraints.UFormulas() |
@@ -1113,5 +1177,112 @@ def test_pospar_symbols_and_pospar_values(params, expected_symbols, expected_val |
1113 | 1177 | assert actual_values == expected_values |
1114 | 1178 |
|
1115 | 1179 |
|
| 1180 | +@pytest.mark.parametrize( |
| 1181 | + "params", |
| 1182 | + [ |
| 1183 | + pytest.param(["x1"]), |
| 1184 | + ], |
| 1185 | +) |
| 1186 | +def test_position_formulas_raises_SymmetryError(params): |
| 1187 | + sg225 = GetSpaceGroup(225) |
| 1188 | + eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) |
| 1189 | + sc = SymmetryConstraints(sg225, eau.expandedpos) |
| 1190 | + sc.pospars = [("x1", 0.12), ("y1", 0.34), ("z1", 0.56)] |
| 1191 | + sc.poseqns = [ |
| 1192 | + {"x": "x1", "y": "y1 +0.5", "z": "-z1 +0.25"}, |
| 1193 | + {"x": "-x1 +0.5", "y": "y1", "z": "z1 +0.5"}, |
| 1194 | + ] |
| 1195 | + # C1: Simulate the "not enough symbols" in position_formula |
| 1196 | + with pytest.raises(SymmetryError): |
| 1197 | + sc.position_formulas(params) |
| 1198 | + |
| 1199 | + |
| 1200 | +@pytest.mark.parametrize( |
| 1201 | + "params, expected", |
| 1202 | + [ |
| 1203 | + pytest.param( # C2: Normal case, does substitution of x1/y1/z1 tokens in formulas |
| 1204 | + # Make pospars consistent with what position_formulas expects to replace |
| 1205 | + ["xA", "yA", "zA"], |
| 1206 | + [ |
| 1207 | + {"x": "xA", "y": "yA +0.5", "z": "-zA +0.25"}, |
| 1208 | + {"x": "-xA +0.5", "y": "yA", "z": "zA +0.5"}, |
| 1209 | + ], |
| 1210 | + ), |
| 1211 | + ], |
| 1212 | +) |
| 1213 | +def test_position_formulas(params, expected): |
| 1214 | + sg225 = GetSpaceGroup(225) |
| 1215 | + eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) |
| 1216 | + sc = SymmetryConstraints(sg225, eau.expandedpos) |
| 1217 | + sc.pospars = [("x1", 0.12), ("y1", 0.34), ("z1", 0.56)] |
| 1218 | + sc.poseqns = [ |
| 1219 | + {"x": "x1", "y": "y1 +0.5", "z": "-z1 +0.25"}, |
| 1220 | + {"x": "-x1 +0.5", "y": "y1", "z": "z1 +0.5"}, |
| 1221 | + ] |
| 1222 | + actual = sc.position_formulas(params) |
| 1223 | + assert actual == expected |
| 1224 | + |
| 1225 | + |
| 1226 | +@pytest.mark.parametrize( |
| 1227 | + "poseqns, expected", |
| 1228 | + [ |
| 1229 | + pytest.param( |
| 1230 | + [ |
| 1231 | + {"x": "x1", "y": "0.25", "z": "-z1 +0.5"}, |
| 1232 | + {"x": "0", "y": "y1 +0.5", "z": "0.125"}, |
| 1233 | + ], |
| 1234 | + [ |
| 1235 | + {"x": "xA", "z": "-zA +0.5"}, |
| 1236 | + {"y": "yA +0.5"}, |
| 1237 | + ], |
| 1238 | + ) |
| 1239 | + ], |
| 1240 | +) |
| 1241 | +def test_position_formulas_pruned(poseqns, expected): |
| 1242 | + sg225 = GetSpaceGroup(225) |
| 1243 | + eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) |
| 1244 | + sc = SymmetryConstraints(sg225, eau.expandedpos) |
| 1245 | + |
| 1246 | + sc.pospars = [("x1", 0.12), ("y1", 0.34), ("z1", 0.56)] |
| 1247 | + sc.poseqns = poseqns |
| 1248 | + |
| 1249 | + actual = sc.position_formulas_pruned(["xA", "yA", "zA"]) |
| 1250 | + assert actual == expected |
| 1251 | + |
| 1252 | + |
| 1253 | +@pytest.mark.parametrize( |
| 1254 | + "u_formulas, expected", |
| 1255 | + [ |
| 1256 | + pytest.param( |
| 1257 | + [ |
| 1258 | + { |
| 1259 | + "U11": "A", |
| 1260 | + "U22": "A", |
| 1261 | + "U33": "C", |
| 1262 | + "U12": "0.5*A", |
| 1263 | + "U13": "0", |
| 1264 | + "U23": "0", |
| 1265 | + } |
| 1266 | + ], |
| 1267 | + [ |
| 1268 | + { |
| 1269 | + "U11": "A", |
| 1270 | + "U22": "A", |
| 1271 | + "U33": "C", |
| 1272 | + "U12": "0.5*A", |
| 1273 | + } |
| 1274 | + ], |
| 1275 | + ) |
| 1276 | + ], |
| 1277 | +) |
| 1278 | +def test_u_formula_pruned(u_formulas, expected): |
| 1279 | + sg225 = GetSpaceGroup(225) |
| 1280 | + eau = ExpandAsymmetricUnit(sg225, [[0, 0, 0]]) |
| 1281 | + sc = SymmetryConstraints(sg225, eau.expandedpos) |
| 1282 | + sc.Ueqns = u_formulas |
| 1283 | + actual = sc.u_formulas_pruned(u_formulas) |
| 1284 | + assert actual == expected |
| 1285 | + |
| 1286 | + |
1116 | 1287 | if __name__ == "__main__": |
1117 | 1288 | unittest.main() |
0 commit comments