Commit de3091450482ef83b3d1f48ba02af33976cf31e4
Merge branch 'develop'
Showing
5 changed files
with
79 additions
and
15 deletions
atooms/backends/f90/f90.py
... | ... | @@ -62,9 +62,49 @@ class Interaction(_Interaction): |
62 | 62 | interaction='interaction.f90', |
63 | 63 | helpers='helpers.f90', |
64 | 64 | inline=True, debug=False): |
65 | + """ | |
66 | + The interaction model can be defined in three ways: | |
67 | + | |
68 | + 1) Passing a `model` string that matches any of the models | |
69 | + defined in the atooms-models database (ex. "lennard_jones" or | |
70 | + "gaussian_core") | |
71 | + | |
72 | + 2) Passing a `model` dictionary with "potential" and "cutoff" | |
73 | + keys and identical layout as the atooms-model database entries | |
74 | + (ex. https://gitlab.info-ufr.univ-montp2.fr/atooms/models/blob/master/atooms/models/lennard_jones.json) | |
75 | + | |
76 | + 3) Passing the `potential`, `cutoff`, `potential_parameters` | |
77 | + and `cutoff_parameters` parameters. The `potential` and | |
78 | + `cutoff` strings should match either | |
79 | + | |
80 | + a) potential and/or cutoff defined in atooms-models, such as | |
81 | + "lennard_jones" or "cut_and_shift", or | |
82 | + | |
83 | + b) paths to Fortran 90 source codes that implement appropriate | |
84 | + routines following the interfaces defined by the atooms-models | |
85 | + package, see for instance | |
86 | + https://gitlab.info-ufr.univ-montp2.fr/atooms/models/blob/master/atooms/models/lennard_jones.f90 | |
87 | + https://gitlab.info-ufr.univ-montp2.fr/atooms/models/blob/master/atooms/models/cut_shift.f90 | |
88 | + for an example of the interface the routines should implement. | |
89 | + | |
90 | + The parameters values are provided as dictionaries | |
91 | + (`potential_parameters` and `cutoff_parameters``) matching the | |
92 | + intent(in) variables entering the `setup()` routines of the | |
93 | + fortran modules. | |
94 | + """ | |
65 | 95 | _Interaction.__init__(self, None) |
66 | 96 | |
97 | + if model and not hasattr(model, 'get'): | |
98 | + # This may be a string, so we look for the model in the | |
99 | + # atooms-models database and replace the string with the dictionary | |
100 | + try: | |
101 | + from atooms.models import database | |
102 | + model = database[model] | |
103 | + except ImportError: | |
104 | + raise ValueError('could not find model {}'.format(model)) | |
105 | + | |
67 | 106 | if model: |
107 | + # At this stage we expect a model dictionary | |
68 | 108 | assert len(model.get('potential')) == 1 |
69 | 109 | assert len(model.get('cutoff')) == 1 |
70 | 110 | potential = model.get('potential')[0].get('path') | ... | ... |
atooms/core/_version.py
atooms/trajectory/xyz.py
... | ... | @@ -280,9 +280,10 @@ class TrajectoryXYZ(TrajectoryBase): |
280 | 280 | |
281 | 281 | else: |
282 | 282 | # The comment line contains self descriptive fields |
283 | - # TODO: accept extended xyz format | |
284 | 283 | # Remove spaces around : or = and replace = by : |
285 | 284 | data = re.sub(r'\s*[=:]\s*', ':', data) |
285 | + # Tolerate spaces between entries of vectors | |
286 | + data = re.sub(r'\s*,\s*', ',', data) | |
286 | 287 | |
287 | 288 | # Fill metadata dictionary |
288 | 289 | for e in data.split(): | ... | ... |
tests/test_f90.py
... | ... | @@ -31,8 +31,8 @@ class Test(unittest.TestCase): |
31 | 31 | db = atooms.models.load() |
32 | 32 | model = db["lennard_jones"] |
33 | 33 | particles = [Particle(position=[0.0, 0.0, 0.0], species=1), |
34 | - Particle(position=[1.0, 0.0, 0.0], species=1), | |
35 | - Particle(position=[2.0, 0.0, 0.0], species=1)] | |
34 | + Particle(position=[1.0, 0.0, 0.0], species=1), | |
35 | + Particle(position=[2.0, 0.0, 0.0], species=1)] | |
36 | 36 | cell = Cell([10., 10., 10.]) |
37 | 37 | system = System(particles, cell) |
38 | 38 | system.interaction = Interaction(model) |
... | ... | @@ -63,6 +63,11 @@ class Test(unittest.TestCase): |
63 | 63 | system = trajectory[0] |
64 | 64 | self.assertAlmostEqual(system.potential_energy(per_particle=True), -2.24379330538) |
65 | 65 | |
66 | + @unittest.skipIf(not HAS_MODELS, 'no atooms-models module') | |
67 | + def test_interface(self): | |
68 | + from atooms.backends.f90 import Interaction | |
69 | + interaction = Interaction("lennard_jones") | |
70 | + | |
66 | 71 | def tearDown(self): |
67 | 72 | self.trajectory.close() |
68 | 73 | ... | ... |
tests/test_xyz.py
... | ... | @@ -38,7 +38,7 @@ A -2.8 2.8 0.0 |
38 | 38 | with open(self.finp_meta, 'w') as fh: |
39 | 39 | fh.write("""\ |
40 | 40 | 2 |
41 | -metafmt:space,comma columns:id,x,y,z mass:1.0,2.0 step:1 cell:5.0,5.0,5.0 | |
41 | +metafmt:space,comma columns:id,x,y,z mass:1.0,2.0 step:1 cell:5.0,5.0,5.0 | |
42 | 42 | A 1.0 -1.0 0.0 |
43 | 43 | B 2.9 -2.9 0.0 |
44 | 44 | """) |
... | ... | @@ -89,6 +89,21 @@ columns:field step:1 |
89 | 89 | x = t[0].particle[0].field |
90 | 90 | self.assertEqual(x, 1.0) |
91 | 91 | |
92 | + def test_xyz_meta_with_spaces(self): | |
93 | + # Test fields | |
94 | + finp = '/tmp/test_xyz/spaces.xyz' | |
95 | + with open(finp, 'w') as fh: | |
96 | + fh.write("""\ | |
97 | +1 | |
98 | +columns:id step:1 cell: 1.0, 1.0, 1.0 | |
99 | +1 | |
100 | +""") | |
101 | + with self.Trajectory(finp) as t: | |
102 | + x = t[0].cell.side | |
103 | + self.assertEqual(x[0], 1.0) | |
104 | + self.assertEqual(x[1], 1.0) | |
105 | + self.assertEqual(x[2], 1.0) | |
106 | + | |
92 | 107 | def test_xyz_meta(self): |
93 | 108 | with self.Trajectory(self.finp_meta) as t: |
94 | 109 | meta = t._read_comment(0) |
... | ... | @@ -185,11 +200,11 @@ columns:field step:1 |
185 | 200 | with open(finp, 'w') as fh: |
186 | 201 | fh.write("""\ |
187 | 202 | 2 |
188 | -metafmt:space,comma columns:id,x,y,z step:1 cell:5.0,5.0,5.0 | |
203 | +metafmt:space,comma columns:id,x,y,z step:1 cell:5.0,5.0,5.0 | |
189 | 204 | B 1.0 -1.0 0.0 |
190 | 205 | A 2.9 -2.9 0.0 |
191 | 206 | 2 |
192 | -metafmt:space,comma columns:id,x,y,z step:2 cell:5.0,5.0,5.0 | |
207 | +metafmt:space,comma columns:id,x,y,z step:2 cell:5.0,5.0,5.0 | |
193 | 208 | C 1.0 -1.0 0.0 |
194 | 209 | B 2.9 -2.9 0.0 |
195 | 210 | """) |
... | ... | @@ -204,12 +219,12 @@ B 2.9 -2.9 0.0 |
204 | 219 | with open(finp, 'w') as fh: |
205 | 220 | fh.write("""\ |
206 | 221 | 3 |
207 | -metafmt:space,comma columns:id,x,y,z,radius mass:1.0,2.0,3.0 step:1 cell:5.0,5.0,5.0 | |
222 | +metafmt:space,comma columns:id,x,y,z,radius mass:1.0,2.0,3.0 step:1 cell:5.0,5.0,5.0 | |
208 | 223 | B 1.0 -1.0 0.0 0.5 |
209 | 224 | A 2.9 -2.9 0.0 0.6 |
210 | 225 | C 2.9 -2.9 0.0 0.7 |
211 | 226 | 3 |
212 | -metafmt:space,comma columns:id,x,y,z,radius mass:2.0,3.0 step:1 cell:5.0,5.0,5.0 | |
227 | +metafmt:space,comma columns:id,x,y,z,radius mass:2.0,3.0 step:1 cell:5.0,5.0,5.0 | |
213 | 228 | C 1.0 -1.0 0.0 0.5 |
214 | 229 | B 2.9 -2.9 0.0 0.6 |
215 | 230 | B 2.9 -2.9 0.0 0.7 |
... | ... | @@ -306,7 +321,7 @@ class TestNeighbors(unittest.TestCase): |
306 | 321 | step:1 columns:neighbors* |
307 | 322 | 2 4 |
308 | 323 | 1 3 |
309 | -2 | |
324 | +2 | |
310 | 325 | 1 |
311 | 326 | """) |
312 | 327 | with TrajectoryNeighbors('/tmp/test_xyz/neighbors.xyz', offset=0) as th: |
... | ... | @@ -352,6 +367,9 @@ class TestSimpleXYZ(TestXYZ): |
352 | 367 | def test_xyz_meta(self): |
353 | 368 | pass |
354 | 369 | |
370 | + def test_xyz_meta_with_spaces(self): | |
371 | + pass | |
372 | + | |
355 | 373 | def test_xyz_mass(self): |
356 | 374 | pass |
357 | 375 | |
... | ... | @@ -405,10 +423,10 @@ class TestUtils(unittest.TestCase): |
405 | 423 | metafmt:space,comma columns:id,x,y,z step:1 cell:5.0,5.0,5.0 |
406 | 424 | B 1.0 -1.0 0.0 |
407 | 425 | 1 |
408 | -metafmt:space,comma columns:id,x,y,z step:2 cell:5.0,5.0,5.0 | |
426 | +metafmt:space,comma columns:id,x,y,z step:2 cell:5.0,5.0,5.0 | |
409 | 427 | B 2.9 -2.9 0.0 |
410 | 428 | 1 |
411 | -metafmt:space,comma columns:id,x,y,z step:4 cell:5.0,5.0,5.0 | |
429 | +metafmt:space,comma columns:id,x,y,z step:4 cell:5.0,5.0,5.0 | |
412 | 430 | B 2.9 -2.9 0.0 |
413 | 431 | """) |
414 | 432 | with open('/tmp/test_xyz/2.xyz', 'w') as fh: |
... | ... | @@ -417,13 +435,13 @@ B 2.9 -2.9 0.0 |
417 | 435 | metafmt:space,comma columns:id,x,y,z step:2 cell:5.0,5.0,5.0 |
418 | 436 | B 1.0 -1.0 0.0 |
419 | 437 | 1 |
420 | -metafmt:space,comma columns:id,x,y,z step:3 cell:5.0,5.0,5.0 | |
438 | +metafmt:space,comma columns:id,x,y,z step:3 cell:5.0,5.0,5.0 | |
421 | 439 | B 2.9 -2.9 0.0 |
422 | 440 | 1 |
423 | -metafmt:space,comma columns:id,x,y,z step:4 cell:5.0,5.0,5.0 | |
441 | +metafmt:space,comma columns:id,x,y,z step:4 cell:5.0,5.0,5.0 | |
424 | 442 | B 2.9 -2.9 0.0 |
425 | 443 | 1 |
426 | -metafmt:space,comma columns:id,x,y,z step:5 cell:5.0,5.0,5.0 | |
444 | +metafmt:space,comma columns:id,x,y,z step:5 cell:5.0,5.0,5.0 | |
427 | 445 | B 2.9 -2.9 0.0 |
428 | 446 | """) |
429 | 447 | ... | ... |