source: inundation/ga/storm_surge/pyvolution/realtime_visualisation_new.py @ 1639

Last change on this file since 1639 was 1639, checked in by steve, 19 years ago
  • Property svn:executable set to *
File size: 18.6 KB
Line 
1
2from visual import *
3
4elevation_color = (0.3,0.4,0.5)
5stage_color     = (0.1,0.4,0.99)
6friction_color  = (0.1,0.99,0.1)
7other_color     = (0.99,0.4,0.1)
8
9
10class Visualiser:
11
12    def __init__(self,domain,scale_z=1.0,rect=None,title='Test'):
13        """Create visualisation of domain
14        """
15
16        self.scene = display(title=title)
17        self.scene.center = (0.5,0.5,0.0)
18        self.scene.forward = vector(-0.0, 0.5, -0.8)
19        self.scene.ambient = 0.4
20        self.scene.lights = [(0.6, 0.3, 0.2), (0.1, -0.5, 0.4)]
21
22        self.frame  = frame()
23
24        self.domain   = domain
25        self.scale_z  = scale_z
26        self.vertices = domain.vertex_coordinates
27
28
29        # models for each quantity
30        self.vpython_z_models = {}
31        #print keys
32        for key in self.domain.quantities:
33            self.vpython_z_models[key] = faces(frame=self.frame)
34
35        #print self.z_models
36
37        if rect is None:
38            self.max_x = max(max(self.vertices[:,0]),max(self.vertices[:,2]),max(self.vertices[:,4]))
39            self.min_x = min(min(self.vertices[:,0]),min(self.vertices[:,2]),min(self.vertices[:,4]))
40            self.max_y = max(max(self.vertices[:,1]),max(self.vertices[:,3]),max(self.vertices[:,5]))
41            self.min_y = min(min(self.vertices[:,1]),min(self.vertices[:,3]),min(self.vertices[:,5]))
42        else:
43            self.max_x = rect[2]
44            self.min_x = rect[0]
45            self.max_y = rect[3]
46            self.min_y = rect[1]
47
48
49        self.range_x = self.max_x - self.min_x
50        self.range_y = self.max_y - self.min_y
51        self.range_xy = max(self.range_x, self.range_y)
52
53
54#        print 'min_x=',self.min_x
55#        print 'max_x=',self.max_x
56#        print 'range_x=',self.range_x
57#        print 'min_y=',self.min_y
58#        print 'max_y=',self.max_y
59#        print 'range_y',self.range_y
60
61        self.stage_color     = stage_color
62        self.elevation_color = elevation_color
63        self.friction_color  = friction_color
64        self.other_color     = other_color
65
66        self.qcolor = {}
67        self.scale_z = {}
68        self.coloring = {}
69        self.updating = {}
70
71        self.qcolor['stage']  = self.stage_color
72        self.scale_z['stage']  = 1.0
73        self.coloring['stage'] = False
74        self.updating['stage'] = True
75
76        self.qcolor['elevation']  = self.elevation_color
77        self.scale_z['elevation']  = 1.0
78        self.coloring['elevation'] = False
79        self.updating['elevation'] = False
80
81        #print self.max_x, self.min_x, self.max_y, self.min_y,
82        #self.min_bed print self.max_bed, self.range_x, self.range_y,
83        #self.range_xy, self.range_bed
84        #print 'Calculating triangles'
85
86        self.pos     = zeros( (6*len(domain),3), Float)
87        self.colour  = zeros( (6*len(domain),3), Float)
88        self.normals = zeros( (6*len(domain),3), Float)
89
90        #print 'keys',self.domain.quantities.keys()
91        #print 'shape of stage',shape(self.stage)
92
93        self.border_model = curve(frame = self.frame,
94                                  pos=[(0,0),(0,1),(1,1),(1,0),(0,0)])
95        self.timer=label(pos=(0.75,0.75,0.5),text='Time=%10.5e'%self.domain.time,
96                         visible=False)
97
98
99        scene.autoscale=0
100        #self.update_all()
101        #scene.uniform=0
102        self.range_z  = 1.0
103        if domain.visualise_range_z == None:
104            self.setup_range_z()
105        else:
106            self.range_z = domain.visualise_range_z
107
108        self.max_z = self.range_z/2.0
109        self.min_z = -self.range_z/2.0
110        self.range_z = max(self.max_z - self.min_z, 1.0e-10)
111
112#        print self.range_z
113#        print self.max_z
114#        print self.min_z
115
116    def setup_range_z(self,qname1='elevation',qname2='stage'):
117
118        #print qname1
119        #print qname2
120        range_z = 1.0e-10
121        try:
122            q1 = self.domain.quantities[qname1].vertex_values
123            max_z = max(max(q1))
124            min_z = min(min(q1))
125            print max_z, min_z
126            range_z = max(range_z, max_z - min_z)
127        except:
128            #print 'Visualisation: could not find range of '+qname1
129            pass
130
131        try:
132            q2 = self.domain.quantities[qname2].vertex_values
133            max_z = max(max(q2))
134            min_z = min(min(q2))
135            print max_z, min_z
136            range_z = max(range_z, max_z - min_z)
137        except:
138            #print 'Visualisation: could not find range of '+qname2
139            pass
140
141        self.range_z = max(range_z,self.range_z)
142
143
144    def setup_all(self):
145
146        self.scene.select()
147
148        self.update_quantity('elevation')
149        self.update_quantity('stage')
150
151    def update_all(self):
152
153        self.scene.select()
154
155        if self.updating['elevation']:
156            self.update_quantity('elevation')
157
158        if self.updating['stage']:
159            self.update_quantity('stage')
160
161
162
163
164    def update_timer(self):
165
166        self.scene.select()
167
168        if self.domain.visualise_timer == True:
169            self.timer.visible = True
170            self.timer.text='Time=%10.5e'%self.domain.time
171
172
173    def update_quantity(self,qname):
174
175        #print 'update '+qname+' arrays'
176
177        qcolor   = self.qcolor[qname]
178        scale_z  = self.scale_z[qname]
179        coloring = self.coloring[qname]
180        updating = self.updating[qname]
181
182
183        if qcolor is None:
184            qcolor = self.other_color
185
186            if qname=='elevation':
187                qcolor = self.elevation_color
188
189            if qname=='stage':
190                qcolor = self.stage_color
191
192            if qname=='friction':
193                qcolor = self.friction_color
194
195        if scale_z is None:
196            scale_z = self.scale_z
197
198        #try:
199        if coloring:
200            self.update_arrays_color(self.domain.quantities[qname].vertex_values, qcolor, scale_z)
201        else:
202            self.update_arrays(self.domain.quantities[qname].vertex_values, qcolor, scale_z)
203
204        #print 'update bed image'
205        self.vpython_z_models[qname].pos    = self.pos
206        self.vpython_z_models[qname].color  = self.colour
207        self.vpython_z_models[qname].normal = self.normals
208        #except:
209        #    print 'Visualisation: Could not update quantity '+qname
210        #    pass
211
212    def update_quantity_color(self,qname,qcolor=None,scale_z=None):
213
214        #print 'update '+qname+' arrays'
215
216        if qcolor is None:
217            if qname=='elevation':
218                qcolor = self.elevation_color
219
220            if qname=='stage':
221                qcolor = self.stage_color
222
223            if qname=='friction':
224                qcolor = self.friction_color
225
226        if scale_z is None:
227            scale_z = self.scale_z
228
229        #try:
230        self.update_arrays_color(self.domain.quantities[qname].vertex_values, qcolor, scale_z)
231
232            #print 'update bed image'
233        self.vpython_z_models[qname].pos    = self.pos
234        self.vpython_z_models[qname].color  = self.colour
235        self.vpython_z_models[qname].normal = self.normals
236        #except:
237        #    print 'Visualisation: Could not update quantity '+qname
238        #    pass
239
240
241    def update_arrays(self,quantity,qcolor,scale_z):
242
243        col = asarray(qcolor)
244
245        N = len(self.domain)
246
247        min_x = self.min_x
248        min_y = self.min_y
249        range_xy = self.range_xy
250        range_z = self.range_z
251
252        vertices = self.vertices
253        pos      = self.pos
254        normals  = self.normals
255        colour   = self.colour
256
257        try:
258            update_arrays_weave(vertices,quantity,col,pos,normals,colour,N,
259                                min_x,min_y,range_xy,range_z,scale_z)
260        except:
261            update_arrays_python(vertices,quantity,col,pos,normals,colour,N,
262                                 min_x,min_y,range_xy,range_z,scale_z)
263
264
265
266    def update_arrays_color(self,quantity,qcolor,scale_z):
267
268        col = asarray(qcolor)
269
270        N = len(self.domain)
271
272        min_x = self.min_x
273        min_y = self.min_y
274        range_xy = self.range_xy
275        range_z = self.range_z
276
277        vertices = self.vertices
278        pos      = self.pos
279        normals  = self.normals
280        colour   = self.colour
281
282        #try:
283        update_arrays_color_python(vertices,quantity,col,pos,normals,colour,N,
284                                min_x,min_y,range_xy,range_z,scale_z)
285        #except:
286        #    update_arrays_color_python(vertices,quantity,col,pos,normals,colour,N,
287        #                         min_x,min_y,range_xy,range_z,scale_z)
288
289
290#==================================================================================
291
292def  update_arrays_python(vertices,quantity,col,pos,normals,colour,N,
293                          min_x,min_y,range_xy,range_z,scale_z):
294
295    from math import sqrt
296    normal = zeros( 3, Float)
297    v = zeros( (3,3), Float)
298    s = 1.0
299
300    for i in range( N ):
301
302        for j in range(3):
303            v[j,0] = (vertices[i,2*]-min_x)/range_xy
304            v[j,1] = (vertices[i,2*j+1]-min_y)/range_xy
305            v[j,2] = quantity[i,j]/range_z*scale_z*0.5
306
307        v10 = v[1,:]-v[0,:]
308        v20 = v[2,:]-v[0,:]
309
310        normal[0] = v10[1]*v20[2] - v20[1]*v10[2]
311        normal[1] = v10[2]*v20[0] - v20[2]*v10[0]
312        normal[2] = v10[0]*v20[1] - v20[0]*v10[1]
313
314        norm = sqrt( normal[0]**2 + normal[1]**2 + normal[2]**2)
315
316        normal[0] = normal[0]/norm
317        normal[1] = normal[1]/norm
318        normal[2] = normal[2]/norm
319
320        pos[6*,:] = v[0,:]
321        pos[6*i+1,:] = v[1,:]
322        pos[6*i+2,:] = v[2,:]
323        pos[6*i+3,:] = v[0,:]
324        pos[6*i+4,:] = v[2,:]
325        pos[6*i+5,:] = v[1,:]
326
327
328
329        colour[6*,:] = s*col
330        colour[6*i+1,:] = s*col
331        colour[6*i+2,:] = s*col
332        colour[6*i+3,:] = s*col
333        colour[6*i+4,:] = s*col
334        colour[6*i+5,:] = s*col
335
336        s =  15.0/8.0 - s
337
338        normals[6*,:] = normal
339        normals[6*i+1,:] = normal
340        normals[6*i+2,:] = normal
341        normals[6*i+3,:] = -normal
342        normals[6*i+4,:] = -normal
343        normals[6*i+5,:] = -normal
344
345
346
347def  update_arrays_weave(vertices,quantity,col,pos,normals,colour,
348                         N,min_x,min_y,range_xy,range_z,scale_z):
349
350    import weave
351    from weave import converters
352
353    from math import sqrt
354    normal = zeros( 3, Float)
355    v = zeros( (3,3), Float)
356    v10 = zeros( 3, Float)
357    v20 = zeros( 3, Float)
358
359    code1 = """
360
361        double s = 1.0;
362
363        for (int i=0; i<N ; i++ ) {
364            for (int j=0; j<3 ; j++) {
365                v(j,0) = (vertices(i,2*j  )-min_x)/range_xy;
366                v(j,1) = (vertices(i,2*j+1)-min_y)/range_xy;
367                v(j,2) = quantity(i,j)/range_z*scale_z*0.5;
368            }
369
370
371            for (int j=0; j<3; j++) {
372                v10(j) = v(1,j)-v(0,j);
373                v20(j) = v(2,j)-v(0,j);
374            }
375
376            normal(0) = v10(1)*v20(2) - v20(1)*v10(2);
377            normal(1) = v10(2)*v20(0) - v20(2)*v10(0);
378            normal(2) = v10(0)*v20(1) - v20(0)*v10(1);
379
380            double norm =  sqrt(normal(0)*normal(0) + normal(1)*normal(1) + normal(2)*normal(2));
381
382            normal(0) = normal(0)/norm;
383            normal(1) = normal(1)/norm;
384            normal(2) = normal(2)/norm;
385
386
387            for (int j=0; j<3; j++) {
388                pos(6*i  ,j) = v(0,j);
389                pos(6*i+1,j) = v(1,j);
390                pos(6*i+2,j) = v(2,j);
391                pos(6*i+3,j) = v(0,j);
392                pos(6*i+4,j) = v(2,j);
393                pos(6*i+5,j) = v(1,j);
394
395                colour(6*i  ,j) = s*col(j);
396                colour(6*i+1,j) = s*col(j);
397                colour(6*i+2,j) = s*col(j);
398                colour(6*i+3,j) = s*col(j);
399                colour(6*i+4,j) = s*col(j);
400                colour(6*i+5,j) = s*col(j);
401
402                normals(6*i  ,j) = normal(j);
403                normals(6*i+1,j) = normal(j);
404                normals(6*i+2,j) = normal(j);
405                normals(6*i+3,j) = -normal(j);
406                normals(6*i+4,j) = -normal(j);
407                normals(6*i+5,j) = -normal(j);
408                }
409
410            s =  15.0/8.0 - s;
411        }
412
413        """
414
415    weave.inline(code1, ['vertices','quantity','col','pos','normals','colour','N',
416                         'min_x','min_y','range_xy','range_z','scale_z','v','normal','v10','v20'],
417                 type_converters = converters.blitz, compiler='gcc');
418
419def  update_arrays_color_python(vertices,quantity,col,pos,normals,colour,N,
420                          min_x,min_y,range_xy,range_z,scale_z):
421
422    from math import sqrt
423    normal = zeros( 3, Float)
424    v = zeros( (3,3), Float)
425    s = 1.0
426
427    for i in range( N ):
428
429        for j in range(3):
430            v[j,0] = (vertices[i,2*]-min_x)/range_xy
431            v[j,1] = (vertices[i,2*j+1]-min_y)/range_xy
432            v[j,2] = quantity[i,j]/range_z*scale_z*0.5
433
434        v10 = v[1,:]-v[0,:]
435        v20 = v[2,:]-v[0,:]
436
437        normal[0] = v10[1]*v20[2] - v20[1]*v10[2]
438        normal[1] = v10[2]*v20[0] - v20[2]*v10[0]
439        normal[2] = v10[0]*v20[1] - v20[0]*v10[1]
440
441        norm = sqrt( normal[0]**2 + normal[1]**2 + normal[2]**2)
442
443        normal[0] = normal[0]/norm
444        normal[1] = normal[1]/norm
445        normal[2] = normal[2]/norm
446
447        pos[6*,:] = v[0,:]
448        pos[6*i+1,:] = v[1,:]
449        pos[6*i+2,:] = v[2,:]
450        pos[6*i+3,:] = v[0,:]
451        pos[6*i+4,:] = v[2,:]
452        pos[6*i+5,:] = v[1,:]
453
454        q0 = quantity[i,0]/0.4
455        q1 = quantity[i,1]/0.4
456        q2 = quantity[i,2]/0.4
457
458        q0r = min(q0,0.0)
459        q1r = min(q1,0.0)
460        q2r = min(q2,0.0)
461        q0b = max(q0,0.0)
462        q1b = max(q1,0.0)
463        q2b = max(q2,0.0)
464
465
466        colour[6*,:] = s*array([0.3 - q0r, 0.3 - q0, 0.3 + q0b])
467        colour[6*i+1,:] = s*array([0.3 - q1r, 0.3 - q1, 0.3 + q1b])
468        colour[6*i+2,:] = s*array([0.3 - q2r, 0.3 - q2, 0.3 + q2b])
469        colour[6*i+3,:] = s*array([0.3 - q0r, 0.3 - q0, 0.3 + q0b])
470        colour[6*i+4,:] = s*array([0.3 - q2r, 0.3 - q2, 0.3 + q2b])
471        colour[6*i+5,:] = s*array([0.3 - q1r, 0.3 - q1, 0.3 + q1b])
472
473        s =  15.0/8.0 - s
474
475        normals[6*,:] = normal
476        normals[6*i+1,:] = normal
477        normals[6*i+2,:] = normal
478        normals[6*i+3,:] = -normal
479        normals[6*i+4,:] = -normal
480        normals[6*i+5,:] = -normal
481
482
483
484def  update_arrays_color_weave(vertices,quantity,col,pos,normals,colour,
485                         N,min_x,min_y,range_xy,range_z,scale_z):
486
487    import weave
488    from weave import converters
489
490    from math import sqrt
491    normal = zeros( 3, Float)
492    v = zeros( (3,3), Float)
493    v10 = zeros( 3, Float)
494    v20 = zeros( 3, Float)
495
496    code1 = """
497        double s = 1.0;
498
499        for (int i=0; i<N ; i++ ) {
500            for (int j=0; j<3 ; j++) {
501                v(j,0) = (vertices(i,2*j  )-min_x)/range_xy;
502                v(j,1) = (vertices(i,2*j+1)-min_y)/range_xy;
503                v(j,2) = quantity(i,j)/range_z*scale_z*0.5;
504            }
505
506
507            for (int j=0; j<3; j++) {
508                v10(j) = v(1,j)-v(0,j);
509                v20(j) = v(2,j)-v(0,j);
510            }
511
512            normal(0) = v10(1)*v20(2) - v20(1)*v10(2);
513            normal(1) = v10(2)*v20(0) - v20(2)*v10(0);
514            normal(2) = v10(0)*v20(1) - v20(0)*v10(1);
515
516            double norm =  sqrt(normal(0)*normal(0) + normal(1)*normal(1) + normal(2)*normal(2));
517
518            normal(0) = normal(0)/norm;
519            normal(1) = normal(1)/norm;
520            normal(2) = normal(2)/norm;
521
522
523
524            for (int j=0; j<3; j++) {
525                pos(6*i  ,j) = v(0,j);
526                pos(6*i+1,j) = v(1,j);
527                pos(6*i+2,j) = v(2,j);
528                pos(6*i+3,j) = v(0,j);
529                pos(6*i+4,j) = v(2,j);
530                pos(6*i+5,j) = v(1,j);
531
532                normals(6*i  ,j) = normal(j);
533                normals(6*i+1,j) = normal(j);
534                normals(6*i+2,j) = normal(j);
535                normals(6*i+3,j) = -normal(j);
536                normals(6*i+4,j) = -normal(j);
537                normals(6*i+5,j) = -normal(j);
538                }
539
540            s = 0.2+fabs((v(0,2)+v(1,2)+v(2,2))/3.0);
541            for (int j=0; j<3; j++) {
542                colour(6*i  ,j) = s*col(j);
543                colour(6*i+1,j) = s*col(j);
544                colour(6*i+2,j) = s*col(j);
545                colour(6*i+3,j) = s*col(j);
546                colour(6*i+4,j) = s*col(j);
547                colour(6*i+5,j) = s*col(j);
548                }
549            s =  15.0/8.0 - s;
550        }
551
552        """
553
554    weave.inline(code1, ['vertices','quantity','col','pos','normals','colour','N',
555                         'min_x','min_y','range_xy','range_z','scale_z','v','normal','v10','v20'],
556                 type_converters = converters.blitz, compiler='gcc');
557
558
559def setup_scene():
560
561    #scene.width = 1000
562    #scene.height = 800
563
564    #Original
565    scene.center = (0.5,0.5,0.0)
566    scene.forward = vector(-0.0, 0.5, -0.8)
567
568    #Temporary (for bedslope)
569    #scene.forward = vector(0.0006, 0.7, -0.03)
570
571
572    #Temporary for hackett - begin
573    #scene.autoscale = 0
574    #scene.scale = (0.002, 0.002, 0.01) #Scale z so that countours stand out more
575    #scene.center = (300.0,500.0,-10)
576    #Temporary for hackett - end
577
578
579    scene.ambient = 0.4
580    #scene.lights = [(0.6, 0.3, 0.2), (0.1, -0.5, 0.4), (-0.1, 0.1, -0.4),
581    #               (-0.2, 0.2, 0.1)]
582
583    scene.lights = [(0.6, 0.3, 0.2), (0.1, -0.5, 0.4)]
584
585
586
587def create_surface(domain,scale_z=1.0):
588
589    domain.initialise_visualiser(scale_z)
590
591    domain.visualiser.update_quantity('elevation')
592    domain.visualiser.update_quantity('stage')
593    domain.visualiser.update_timer()
594
595def update(domain):
596
597    if domain.visualise_color_stage:
598        domain.visualiser.update_quantity_color('stage')
599    else:
600        domain.visualiser.update_quantity('stage')
601
602    domain.visualiser.update_timer()
603
604
605
606if __name__ == '__main__':
607
608    from advection import Domain as A_Domain
609    from shallow_water import Domain as SW_Domain
610    from mesh_factory import rectangular
611
612    points, vertices, boundary = rectangular(20, 20, len1=200, len2=200)
613    a_domain  = A_Domain(points, vertices, boundary)
614    sw_domain = SW_Domain(points, vertices, boundary)
615
616    a_domain.initialise_visualiser()
617    a_domain.visualiser.update_all()
618
619
620    sw_domain.initialise_visualiser()
621    sw_domain.visualiser.update_all()
622
623    #a_v = Visualiser(domain=a_domain, title='advection')
624    #a_v.update_all()
625
626
627    #sw_v = Visualiser(domain=sw_domain, title='shallow water')
628    #sw_v.update_all()
Note: See TracBrowser for help on using the repository browser.