Coverage for gamdpy/visualization/k3d_.py: 17%

48 statements  

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

1import numpy as np 

2import ipywidgets as widgets 

3 

4class k3d_Visualization(): 

5 def __init__(self, simulation): 

6 import k3d 

7 from k3d.colormaps import matplotlib_color_maps 

8 self.simulation = simulation 

9 self.conf = simulation.configuration 

10 self.plt_points = k3d.points(positions=self.conf['r'], 

11 point_sizes=np.ones((self.conf.N),dtype=np.float32), 

12 shader='mesh', 

13 color_map=matplotlib_color_maps.Jet, 

14 attribute=self.conf.scalars[:,0], 

15 color_range=[-6, 0], 

16 name='Atoms' 

17 ) 

18 Lx, Ly, Lz = self.conf.simbox.lengths 

19 

20 self.plt_box = k3d.lines(vertices=[ [-Lx/2, -Ly/2, -Lz/2], [-Lx/2, -Ly/2, +Lz/2], 

21 [-Lx/2, +Ly/2, -Lz/2], [+Lx/2, -Ly/2, -Lz/2], 

22 [-Lx/2, +Ly/2, +Lz/2], [+Lx/2, -Ly/2, +Lz/2], 

23 [+Lx/2, +Ly/2, -Lz/2], [+Lx/2, +Ly/2, +Lz/2]], 

24 indices=[ [0,1], [0,2], [0,3], 

25 [1,4], [1,5], [2,4], [2,6], [3,5], [3,6], 

26 [7,4], [7,5], [7,6]], 

27 indices_type='segment', 

28 shader='mesh', width=min((Lx, Ly, Lz))/100, 

29 name='Simulation Box' 

30 ) 

31 self.plt_time_text = k3d.text2d('Time: ', position=[0.01, 0.15], is_html=True) 

32 self.plt_temp_text = k3d.text2d('Temperature: ', position=[0.01, 0.25], is_html=True,) 

33 self.plt_fn_text = k3d.text2d('Potential:', position=[0.01, 0.42], is_html=True) 

34 

35 self.plot = k3d.plot(camera_mode='orbit', camera_fov=3.0,) 

36 self.plot += self.plt_points 

37 self.plot += self.plt_box 

38 self.plot += self.plt_fn_text + self.plt_time_text + self.plt_temp_text 

39 

40 self.play = widgets.Play( 

41 value=self.simulation.num_blocks-1, 

42 min=0, 

43 max=self.simulation.num_blocks-1, 

44 step=1, 

45 interval=0, 

46 description="Press play", 

47 disabled=False 

48 ) 

49 

50 self.attribute_dropdown = widgets.Dropdown( 

51 options=[('Potential energy', 0), ('Virial', 1), ('Laplace U', 2), ('m', 3), ('Kinetic energy', 4), ('F^2', 5), ('Type', 6)], 

52 value=0, 

53 description='Color:', 

54 disabled=False, 

55 ) 

56 

57 self.slider = widgets.IntSlider(description='Frame:', max=self.play.max) 

58 widgets.jslink((self.play, 'value'), (self.slider, 'value')) 

59 

60 self.w0 = widgets.interactive(self.update, block=self.play, choice=self.attribute_dropdown) 

61 self.w1 = widgets.interactive(self.set_color_range, choice=self.attribute_dropdown) 

62 

63 

64 def display(self): 

65 self.plot.display() 

66 

67 def update(self, block, choice): 

68 self.plt_points.positions = self.simulation.vectors_list[block]['r'] 

69 model_time = (block+1)*self.simulation.dt*self.simulation.steps_per_block 

70 self.plt_time_text.text = f'Time: {model_time:.2f}' 

71 self.plt_temp_text.text = f'Temp: {self.simulation.integrator.temperature(model_time):.3f}' 

72 if choice==6: 

73 self.plt_points.attribute = np.float32(self.conf.ptype) 

74 else: 

75 self.plt_points.attribute = self.simulation.scalars_list[block][:,choice] 

76 Lx, Ly, Lz = self.simulation.simbox_data_list[block] 

77 self.plt_box.vertices=[[-Lx/2, -Ly/2, -Lz/2], [-Lx/2, -Ly/2, +Lz/2], 

78 [-Lx/2, +Ly/2, -Lz/2], [+Lx/2, -Ly/2, -Lz/2], 

79 [-Lx/2, +Ly/2, +Lz/2], [+Lx/2, -Ly/2, +Lz/2], 

80 [+Lx/2, +Ly/2, -Lz/2], [+Lx/2, +Ly/2, +Lz/2]], 

81 

82 def set_color_range(self, choice): 

83 labels = {0:'Potential:', 1:'Virial:', 2:'Laplace U:', 3:'m:', 4:'Kinetic nrg:', 5:'F^2', 6:'Type'} 

84 self.plt_fn_text.text = labels[choice] 

85 if choice == 6: 

86 minval, maxval = np.min(self.conf.ptype), np.max(self.conf.ptype) 

87 else: 

88 minval, maxval = np.percentile(self.simulation.scalars_list[:,:,choice], (1, 99)) 

89 if minval==maxval: 

90 minval -= abs(minval*.1) 

91 maxval += abs(maxval*.1) 

92 self.plt_points.color_range = (minval, maxval) 

93 

94 def display_player(self): 

95 display(widgets.HBox([self.play, self.slider, self.attribute_dropdown]))