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
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
1import numpy as np
2import ipywidgets as widgets
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
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)
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
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 )
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 )
57 self.slider = widgets.IntSlider(description='Frame:', max=self.play.max)
58 widgets.jslink((self.play, 'value'), (self.slider, 'value'))
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)
64 def display(self):
65 self.plot.display()
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]],
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)
94 def display_player(self):
95 display(widgets.HBox([self.play, self.slider, self.attribute_dropdown]))