Coverage for tests/test_topology.py: 98%

48 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-14 15:55 +0200

1def test_topology(): 

2 import gamdpy as gp 

3 import numpy as np 

4 import random 

5 

6 bond_length = 0.9 

7 cut_off=bond_length*1.1 

8 num_particles = 270 

9 positions = [] 

10 

11 factor = (1/3)**(1/2)*bond_length 

12 

13 for i in range(num_particles): 

14 positions.append( [ i*factor, i*factor, i*factor ] ) # x, y, z for this particle 

15 

16 random.shuffle(positions) 

17 

18 bonds = gp.bonds_from_positions(positions=positions, cut_off=cut_off, bond_type=0) 

19 assert len(bonds) == num_particles-1, f'Did not find the correct number of bonds: {len(bonds)=} != {num_particles-1=}' 

20 # add test: duplicated bonds, distance 

21 

22 bonds = [ [bond[1], bond[0], bond[2]] if random.choice([False, True]) else bond for bond in bonds] # revert ~half bonds 

23 bonds_without_type = [ bond[0:2] for bond in bonds ] 

24 

25 angles = gp.angles_from_bonds(bonds=bonds, angle_type=0) 

26 assert len(angles) == num_particles-2, f'Incorrect number of angles: {len(angles)=} != {num_particles-2=}' 

27 for index, angle in enumerate(angles): 

28 assert angle not in angles[index+1:], f'Duplicated angle found: {angle=}, \n{angles[index+1:]=}' 

29 reverse = [angle[2], angle[1], angle[0], angle[3]] 

30 assert reverse not in angles[index+1:], f'Duplicated angle (reversed) found: {angle=}, \n{angles[index+1:]=}' 

31 for angle in angles: 

32 bond0 = angle[0:2] 

33 reverse0 = bond0[::-1] 

34 bond1 = angle[1:3] 

35 reverse1 = bond1[::-1] 

36 assert bond0 != bond1 and bond0 != reverse1, f'Angle with duplicate bonds found {angle=}' 

37 assert bond0 in bonds_without_type or reverse0 in bonds_without_type, f'Angle has bond not found in bonds \n{angle=}, \n{bonds=}, \n{bonds_without_type=}, \n{bond0=}' 

38 assert bond1 in bonds_without_type or reverse1 in bonds_without_type, f'Angle has bond not found in bonds \n{angle=}, \n{bonds=}, \n{bonds_without_type=}, \n{bond1=}' 

39 

40 

41 

42 angles = [ [angle[2], angle[1], angle[0], angle[3]] if random.choice([False, True]) else angle for angle in angles] # revert ~half dihedrals 

43 angles_without_type = [ angle[0:3] for angle in angles ] 

44 

45 dihedrals = gp.dihedrals_from_angles(angles=angles, dihedral_type=0) 

46 assert len(dihedrals) == num_particles-3, f'Incorrect number of dihedrals: {len(dihedrals)=} != {num_particles-3=}' 

47 for index, dihedral in enumerate(dihedrals): 

48 assert dihedral not in dihedrals[index+1:], f'Duplicated dihedrals found: {dihedral=}, \n{dihedrals[index+1:]=}' 

49 reverse = [dihedral[3], dihedral[2], dihedral[1], dihedral[0], dihedral[4]] 

50 assert reverse not in dihedrals[index+1:], f'Duplicated dihedral (reversed) found: {dihedral}, \n{dihedrals[index+1:]=}' 

51 for dihedral in dihedrals: 

52 angle0 = dihedral[0:3] 

53 reverse0 = angle0[::-1] 

54 angle1 = dihedral[1:4] 

55 reverse1 = angle1[::-1] 

56 assert angle0 != angle1 and angle0 != reverse1, f'Dihedral with duplicate angles found {dihedral=}' 

57 assert angle0 in angles_without_type or reverse0 in angles_without_type, f'Dihedral has angle not found in angles \n{dihedral=}, \n{angles=}, \n{angles_without_type=}, \n{angle0=}' 

58 assert angle1 in angles_without_type or reverse1 in angles_without_type, f'Dihedral has angle not found in angles \n{dihedral=}, \n{angles=}, \n{angles_without_type=}, \n{angle1=}' 

59 

60 

61if __name__ == '__main__': 

62 test_topology()