Changeset 1290
- Timestamp:
- May 6, 2005, 6:24:03 PM (20 years ago)
- Location:
- inundation/ga/storm_surge
- Files:
-
- 1 added
- 58 deleted
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
inundation/ga/storm_surge/analytical solutions/Hobart.py
r774 r1290 42 42 domain.default_order = 1 43 43 domain.smooth = True 44 domain.visualise = True 44 45 45 46 -
inundation/ga/storm_surge/pyvolution/domain.py
r1280 r1290 141 141 X: Compatible list, Numeric array, const or function (see below) 142 142 location: Where values are to be stored. 143 Permissible options are: vertices, edges, centroid 144 145 In case of location == 'centroid ' the dimension values must143 Permissible options are: vertices, edges, centroids 144 145 In case of location == 'centroids' the dimension values must 146 146 be a list of a Numerical array of length N, N being the number 147 147 of elements. Otherwise it must be of dimension Nx3. … … 152 152 internal ordering. 153 153 154 155 156 154 #FIXME (Ole): I suggest the following interface 155 set_quantity(name, X, location, region) 156 where 157 157 name: Name of quantity 158 158 X: … … 194 194 name: Name of quantity 195 195 196 In case of location == 'centroid ' the dimension values must196 In case of location == 'centroids' the dimension values must 197 197 be a list of a Numerical array of length N, N being the number 198 198 of elements. Otherwise it must be of dimension Nx3. -
inundation/ga/storm_surge/pyvolution/mesh.py
r1193 r1290 67 67 """ 68 68 69 69 70 70 71 71 from Numeric import array, zeros, Int, Float, maximum, sqrt, sum … … 113 113 #a triangle to the midpoint of the side of the triangle 114 114 #closest to the centroid 115 115 d0 = sqrt(sum( (centroid-m0)**2 )) 116 116 d1 = sqrt(sum( (centroid-m1)**2 )) 117 117 d2 = sqrt(sum( (centroid-m2)**2 )) … … 129 129 130 130 self.radii[i]=self.areas[i]/(2*(a+b+c)) 131 131 132 132 133 133 #Initialise Neighbours (-1 means that it is a boundary neighbour) … … 446 446 #Note: Could be arbitrary, but nice to have 447 447 #a unique way of selecting 448 449 448 dist_A = sqrt(sum( (A-pmin)**2 )) 449 dist_B = sqrt(sum( (B-pmin)**2 )) 450 450 451 451 #Find minimal point -
inundation/ga/storm_surge/pyvolution/netherlands.py
r1280 r1290 151 151 t0 = time.time() 152 152 153 for t in domain.evolve(yieldstep = 0. 01, finaltime = 10.0):153 for t in domain.evolve(yieldstep = 0.2, finaltime = 10.0): 154 154 domain.write_time() 155 155 -
inundation/ga/storm_surge/pyvolution/quantity.py
r1011 r1290 6 6 7 7 domain: Associated domain structure. Required. 8 8 9 9 vertex_values: N x 3 array of values at each vertex for each element. 10 10 Default None … … 28 28 29 29 if vertex_values is None: 30 N = domain.number_of_elements 30 N = domain.number_of_elements 31 31 self.vertex_values = zeros((N, 3), Float) 32 else: 32 else: 33 33 self.vertex_values = array(vertex_values).astype(Float) 34 34 … … 36 36 assert V == 3,\ 37 37 'Three vertex values per element must be specified' 38 38 39 39 40 40 msg = 'Number of vertex values (%d) must be consistent with'\ … … 42 42 msg += 'number of elements in specified domain (%d).'\ 43 43 %domain.number_of_elements 44 44 45 45 assert N == domain.number_of_elements, msg 46 46 47 self.domain = domain 47 self.domain = domain 48 48 49 49 #Allocate space for other quantities 50 50 self.centroid_values = zeros(N, Float) 51 self.edge_values = zeros((N, 3), Float) 51 self.edge_values = zeros((N, 3), Float) 52 52 53 53 #Intialise centroid and edge_values … … 56 56 def __len__(self): 57 57 return self.centroid_values.shape[0] 58 58 59 59 def interpolate(self): 60 60 """Compute interpolated values at edges and centroid … … 62 62 """ 63 63 64 N = self.vertex_values.shape[0] 64 N = self.vertex_values.shape[0] 65 65 for i in range(N): 66 66 v0 = self.vertex_values[i, 0] 67 67 v1 = self.vertex_values[i, 1] 68 68 v2 = self.vertex_values[i, 2] 69 69 70 70 self.centroid_values[i] = (v0 + v1 + v2)/3 71 71 … … 77 77 #(either from this module or C-extension) 78 78 interpolate_from_vertices_to_edges(self) 79 80 79 80 81 81 def set_values(self, X, location='vertices', indexes = None): 82 82 """Set values for quantity … … 84 84 X: Compatible list, Numeric array (see below), constant or function 85 85 location: Where values are to be stored. 86 Permissible options are: vertices, edges, centroid 86 Permissible options are: vertices, edges, centroids 87 87 Default is "vertices" 88 88 89 In case of location == 'centroid ' the dimension values must89 In case of location == 'centroids' the dimension values must 90 90 be a list of a Numerical array of length N, N being the number 91 91 of elements. Otherwise it must be of dimension Nx3 … … 96 96 If values are described a function, it will be evaluated at 97 97 specified points 98 98 99 99 If indexex is not 'unique vertices' Indexes is the set of element ids 100 100 that the operation applies to. 101 101 If indexex is 'unique vertices' Indexes is the set of vertex ids 102 102 that the operation applies to. 103 104 103 104 105 105 If selected location is vertices, values for centroid and edges 106 106 will be assigned interpolated values. … … 115 115 if X is None: 116 116 msg = 'Given values are None' 117 raise msg 117 raise msg 118 118 119 119 import types, Numeric … … 122 122 'Indices must be a list or None' 123 123 124 124 125 125 if callable(X): 126 126 #Use function specific method 127 self.set_function_values(X, location, indexes = indexes) 127 self.set_function_values(X, location, indexes = indexes) 128 128 elif type(X) in [types.FloatType, types.IntType, types.LongType]: 129 129 if location == 'centroids': … … 134 134 for i in indexes: 135 135 self.centroid_values[i,:] = X 136 136 137 137 elif location == 'edges': 138 138 if (indexes == None): … … 142 142 for i in indexes: 143 143 self.edge_values[i,:] = X 144 144 145 145 elif location == 'unique vertices': 146 146 if (indexes == None): … … 151 151 for unique_vert_id in indexes: 152 152 triangles = self.domain.vertexlist[unique_vert_id] 153 153 154 154 #In case there are unused points 155 if triangles is None: continue 155 if triangles is None: continue 156 156 157 157 #Go through all triangle, vertex pairs … … 159 159 for triangle_id, vertex_id in triangles: 160 160 self.vertex_values[triangle_id, vertex_id] = X 161 161 162 162 #Intialise centroid and edge_values 163 163 self.interpolate() … … 168 168 #Brute force 169 169 for i_vertex in indexes: 170 self.vertex_values[i_vertex,:] = X 170 self.vertex_values[i_vertex,:] = X 171 171 172 172 else: … … 177 177 #Intialise centroid and edge_values 178 178 self.interpolate() 179 179 180 180 if location == 'centroids': 181 181 #Extrapolate 1st order - to capture notion of area being specified 182 self.extrapolate_first_order() 183 182 self.extrapolate_first_order() 183 184 184 def get_values(self, location='vertices', indexes = None): 185 185 """get values for quantity … … 197 197 (N if indexes = None). Each value will be a list of the three 198 198 vertex values for this quantity. 199 199 200 200 Indexes is the set of element ids that the operation applies to. 201 201 202 202 """ 203 203 from Numeric import take … … 205 205 if location not in ['vertices', 'centroids', 'edges', 'unique vertices']: 206 206 msg = 'Invalid location: %s' %location 207 raise msg 208 207 raise msg 208 209 209 import types, Numeric 210 210 assert type(indexes) in [types.ListType, types.NoneType, 211 211 Numeric.ArrayType],\ 212 212 'Indices must be a list or None' 213 213 214 214 if location == 'centroids': 215 215 if (indexes == None): 216 216 indexes = range(len(self)) 217 return take(self.centroid_values,indexes) 217 return take(self.centroid_values,indexes) 218 218 elif location == 'edges': 219 219 if (indexes == None): 220 220 indexes = range(len(self)) 221 return take(self.edge_values,indexes) 221 return take(self.edge_values,indexes) 222 222 elif location == 'unique vertices': 223 223 if (indexes == None): … … 227 227 for unique_vert_id in indexes: 228 228 triangles = self.domain.vertexlist[unique_vert_id] 229 229 230 230 #In case there are unused points 231 if triangles is None: 232 msg = 'Unique vertex not associated with triangles' 233 raise msg 231 if triangles is None: 232 msg = 'Unique vertex not associated with triangles' 233 raise msg 234 234 235 235 # Go through all triangle, vertex pairs … … 280 280 raise 'Not implemented: %s' %location 281 281 282 282 283 283 def set_array_values(self, values, location='vertices', indexes = None): 284 284 """Set values for quantity … … 288 288 Permissible options are: vertices, edges, centroid, unique vertices 289 289 Default is "vertices" 290 290 291 291 indexes - if this action is carried out on a subset of 292 292 elements or unique vertices 293 293 The element/unique vertex indexes are specified here. 294 294 295 295 In case of location == 'centroid' the dimension values must 296 296 be a list of a Numerical array of length N, N being the number … … 315 315 indexes = array(indexes).astype(Int) 316 316 msg = 'Number of values must match number of indexes' 317 assert values.shape[0] == indexes.shape[0], msg 318 317 assert values.shape[0] == indexes.shape[0], msg 318 319 319 N = self.centroid_values.shape[0] 320 320 321 321 if location == 'centroids': 322 322 assert len(values.shape) == 1, 'Values array must be 1d' … … 325 325 msg = 'Number of values must match number of elements' 326 326 assert values.shape[0] == N, msg 327 327 328 328 self.centroid_values = values 329 329 else: 330 330 msg = 'Number of values must match number of indexes' 331 331 assert values.shape[0] == indexes.shape[0], msg 332 332 333 333 #Brute force 334 334 for i in range(len(indexes)): 335 335 self.centroid_values[indexes[i]] = values[i] 336 336 337 337 elif location == 'edges': 338 338 assert len(values.shape) == 2, 'Values array must be 2d' … … 340 340 msg = 'Number of values must match number of elements' 341 341 assert values.shape[0] == N, msg 342 343 msg = 'Array must be N x 3' 342 343 msg = 'Array must be N x 3' 344 344 assert values.shape[1] == 3, msg 345 345 346 346 self.edge_values = values 347 347 348 348 elif location == 'unique vertices': 349 349 assert len(values.shape) == 1 or allclose(values.shape[1:], 1),\ … … 360 360 # self.set_vertex_values(values) 361 361 #else: 362 # for element_index, value in map(None, indexes, values): 362 # for element_index, value in map(None, indexes, values): 363 363 # self.vertex_values[element_index, :] = value 364 364 365 365 elif len(values.shape) == 2: 366 366 #Vertex values are given as a triplet for each triangle 367 368 msg = 'Array must be N x 3' 367 368 msg = 'Array must be N x 3' 369 369 assert values.shape[1] == 3, msg 370 370 371 371 if indexes == None: 372 372 self.vertex_values = values 373 373 else: 374 for element_index, value in map(None, indexes, values): 374 for element_index, value in map(None, indexes, values): 375 375 self.vertex_values[element_index] = value 376 else: 376 else: 377 377 msg = 'Values array must be 1d or 2d' 378 378 raise msg 379 379 380 380 381 381 # FIXME have a get_vertex_values as well, so the 'stage' quantity can be … … 387 387 one value for each row in vertexlist. 388 388 389 indexes is the list of vertex_id's that will be set. 389 indexes is the list of vertex_id's that will be set. 390 390 391 391 Note: Functions not allowed … … 409 409 for i_index,unique_vert_id in enumerate(vertex_list): 410 410 triangles = self.domain.vertexlist[unique_vert_id] 411 411 412 412 if triangles is None: continue #In case there are unused points 413 413 … … 416 416 for triangle_id, vertex_id in triangles: 417 417 self.vertex_values[triangle_id, vertex_id] = A[i_index] 418 418 419 419 #Intialise centroid and edge_values 420 420 self.interpolate() 421 421 422 422 def smooth_vertex_values(self, value_array='field_values', 423 423 precision = None): … … 432 432 from Numeric import concatenate, zeros, Float, Int, array, reshape 433 433 434 434 435 435 A,V = self.get_vertex_values(xy=False, 436 436 value_array=value_array, … … 450 450 elif value_array == 'conserved_quantities': 451 451 Volume.interpolate_conserved_quantities() 452 453 452 453 454 454 #Method for outputting model results 455 455 #FIXME: Split up into geometric and numeric stuff. … … 457 457 #FIXME: STill remember to move XY to mesh 458 458 def get_vertex_values(self, 459 xy=True, 459 xy=True, 460 460 smooth = None, 461 461 precision = None, … … 465 465 The vertex values are returned as one sequence in the 1D float array A. 466 466 If requested the coordinates will be returned in 1D arrays X and Y. 467 467 468 468 The connectivity is represented as an integer array, V, of dimension 469 469 M x 3, where M is the number of volumes. Each row has three indices … … 474 474 reduction operator. In this case vertex coordinates will be 475 475 de-duplicated. 476 476 477 477 If no smoothings is required, vertex coordinates and values will 478 478 be aggregated as a concatenation of values at 479 479 vertices 0, vertices 1 and vertices 2 480 480 481 481 482 482 Calling convention 483 483 if xy is True: 484 484 X,Y,A,V = get_vertex_values 485 485 else: 486 A,V = get_vertex_values 487 486 A,V = get_vertex_values 487 488 488 """ 489 489 … … 499 499 if reduction is None: 500 500 reduction = self.domain.reduction 501 501 502 502 #Create connectivity 503 503 504 504 if smooth == True: 505 505 … … 511 511 for k in range(N): 512 512 L = self.domain.vertexlist[k] 513 513 514 514 #Go through all triangle, vertex pairs 515 515 #contributing to vertex k and register vertex value 516 516 517 517 if L is None: continue #In case there are unused points 518 518 519 519 contributions = [] 520 520 for volume_id, vertex_id in L: … … 522 522 contributions.append(v) 523 523 524 A[k] = reduction(contributions) 524 A[k] = reduction(contributions) 525 525 526 526 … … 528 528 X = self.domain.coordinates[:,0].astype(precision) 529 529 Y = self.domain.coordinates[:,1].astype(precision) 530 530 531 531 return X, Y, A, V 532 532 else: … … 540 540 M = 3*m #Total number of unique vertices 541 541 V = reshape(array(range(M)).astype(Int), (m,3)) 542 542 543 543 A = self.vertex_values.flat 544 544 545 #Do vertex coordinates 546 if xy is True: 545 #Do vertex coordinates 546 if xy is True: 547 547 C = self.domain.get_vertex_coordinates() 548 548 549 549 X = C[:,0:6:2].copy() 550 Y = C[:,1:6:2].copy() 551 552 return X.flat, Y.flat, A, V 550 Y = C[:,1:6:2].copy() 551 552 return X.flat, Y.flat, A, V 553 553 else: 554 554 return A, V 555 555 556 556 557 557 def extrapolate_first_order(self): 558 558 """Extrapolate conserved quantities from centroid to … … 560 560 first order scheme. 561 561 """ 562 562 563 563 qc = self.centroid_values 564 564 qv = self.vertex_values … … 566 566 for i in range(3): 567 567 qv[:,i] = qc 568 568 569 569 570 570 def get_integral(self): … … 574 574 for k in range(self.domain.number_of_elements): 575 575 area = self.domain.areas[k] 576 qc = self.centroid_values[k] 576 qc = self.centroid_values[k] 577 577 integral += qc*area 578 579 return integral 580 578 579 return integral 580 581 581 582 582 class Conserved_quantity(Quantity): … … 590 590 def __init__(self, domain, vertex_values=None): 591 591 Quantity.__init__(self, domain, vertex_values) 592 592 593 593 from Numeric import zeros, Float 594 594 … … 603 603 self.explicit_update = zeros(N, Float ) 604 604 self.semi_implicit_update = zeros(N, Float ) 605 605 606 606 607 607 def update(self, timestep): … … 615 615 #(either from this module or C-extension) 616 616 return compute_gradients(self) 617 617 618 618 619 619 def limit(self): … … 621 621 #(either from this module or C-extension) 622 622 limit(self) 623 624 623 624 625 625 def extrapolate_second_order(self): 626 626 #Call correct module function … … 629 629 630 630 631 def update(quantity, timestep): 631 def update(quantity, timestep): 632 632 """Update centroid values based on values stored in 633 633 explicit_update and semi_implicit_update as well as given timestep … … 642 642 domain.quantities['ymomentum'].explicit_update = ... 643 643 644 644 645 645 646 646 Explicit terms must have the form 647 647 648 648 G(q, t) 649 649 650 650 and explicit scheme is 651 651 652 652 q^{(n+1}) = q^{(n)} + delta_t G(q^{n}, n delta_t) 653 653 654 654 655 655 Semi implicit forcing terms are assumed to have the form 656 656 657 657 G(q, t) = H(q, t) q 658 658 659 659 and the semi implicit scheme will then be 660 660 661 661 q^{(n+1}) = q^{(n)} + delta_t H(q^{n}, n delta_t) q^{(n+1}) 662 662 663 663 664 664 """ 665 665 666 666 from Numeric import sum, equal, ones, Float 667 667 668 668 N = quantity.centroid_values.shape[0] 669 669 … … 673 673 674 674 for k in range(N): 675 x = quantity.centroid_values[k] 675 x = quantity.centroid_values[k] 676 676 if x == 0.0: 677 677 #FIXME: Is this right 678 quantity.semi_implicit_update[k] = 0.0 679 else: 680 quantity.semi_implicit_update[k] /= x 681 678 quantity.semi_implicit_update[k] = 0.0 679 else: 680 quantity.semi_implicit_update[k] /= x 681 682 682 #Explicit updates 683 683 quantity.centroid_values += timestep*quantity.explicit_update 684 684 685 685 #Semi implicit updates 686 686 denominator = ones(N, Float)-timestep*quantity.semi_implicit_update … … 702 702 q1 = quantity.vertex_values[k, 1] 703 703 q2 = quantity.vertex_values[k, 2] 704 704 705 705 quantity.edge_values[k, 0] = 0.5*(q1+q2) 706 quantity.edge_values[k, 1] = 0.5*(q0+q2) 706 quantity.edge_values[k, 1] = 0.5*(q0+q2) 707 707 quantity.edge_values[k, 2] = 0.5*(q0+q1) 708 708 709 709 710 710 711 def extrapolate_second_order(quantity): 711 def extrapolate_second_order(quantity): 712 712 """Extrapolate conserved quantities from centroid to 713 713 vertices for each volume using 714 714 second order scheme. 715 715 """ 716 716 717 717 a, b = quantity.compute_gradients() 718 718 … … 720 720 qc = quantity.centroid_values 721 721 qv = quantity.vertex_values 722 722 723 723 #Check each triangle 724 724 for k in range(quantity.domain.number_of_elements): 725 #Centroid coordinates 725 #Centroid coordinates 726 726 x, y = quantity.domain.centroid_coordinates[k] 727 727 728 728 #vertex coordinates 729 729 x0, y0, x1, y1, x2, y2 = X[k,:] 730 730 731 731 #Extrapolate 732 732 qv[k,0] = qc[k] + a[k]*(x0-x) + b[k]*(y0-y) 733 733 qv[k,1] = qc[k] + a[k]*(x1-x) + b[k]*(y1-y) 734 qv[k,2] = qc[k] + a[k]*(x2-x) + b[k]*(y2-y) 735 736 737 def compute_gradients(quantity): 734 qv[k,2] = qc[k] + a[k]*(x2-x) + b[k]*(y2-y) 735 736 737 def compute_gradients(quantity): 738 738 """Compute gradients of triangle surfaces defined by centroids of 739 739 neighbouring volumes. … … 744 744 from Numeric import zeros, Float 745 745 from util import gradient 746 746 747 747 centroid_coordinates = quantity.domain.centroid_coordinates 748 surrogate_neighbours = quantity.domain.surrogate_neighbours 749 centroid_values = quantity.centroid_values 750 number_of_boundaries = quantity.domain.number_of_boundaries 751 748 surrogate_neighbours = quantity.domain.surrogate_neighbours 749 centroid_values = quantity.centroid_values 750 number_of_boundaries = quantity.domain.number_of_boundaries 751 752 752 N = centroid_values.shape[0] 753 753 754 754 a = zeros(N, Float) 755 755 b = zeros(N, Float) 756 756 757 757 for k in range(N): 758 758 if number_of_boundaries[k] < 2: 759 759 #Two or three true neighbours 760 760 761 #Get indices of neighbours (or self when used as surrogate) 761 #Get indices of neighbours (or self when used as surrogate) 762 762 k0, k1, k2 = surrogate_neighbours[k,:] 763 763 764 #Get data 764 #Get data 765 765 q0 = centroid_values[k0] 766 766 q1 = centroid_values[k1] 767 q2 = centroid_values[k2] 767 q2 = centroid_values[k2] 768 768 769 769 x0, y0 = centroid_coordinates[k0] #V0 centroid … … 773 773 #Gradient 774 774 a[k], b[k] = gradient(x0, y0, x1, y1, x2, y2, q0, q1, q2) 775 775 776 776 elif number_of_boundaries[k] == 2: 777 777 #One true neighbour … … 789 789 790 790 x0, y0 = centroid_coordinates[k0] #V0 centroid 791 x1, y1 = centroid_coordinates[k1] #V1 centroid 791 x1, y1 = centroid_coordinates[k1] #V1 centroid 792 792 793 793 #Gradient … … 798 798 799 799 else: 800 #No true neighbours - 800 #No true neighbours - 801 801 #Fall back to first order scheme 802 802 pass 803 804 803 804 805 805 return a, b 806 807 808 809 def limit(quantity): 806 807 808 809 def limit(quantity): 810 810 """Limit slopes for each volume to eliminate artificial variance 811 811 introduced by e.g. second order extrapolator 812 812 813 813 This is an unsophisticated limiter as it does not take into 814 814 account dependencies among quantities. 815 815 816 816 precondition: 817 817 vertex values are estimated from gradient … … 823 823 824 824 N = quantity.domain.number_of_elements 825 825 826 826 beta_w = quantity.domain.beta_w 827 827 828 828 qc = quantity.centroid_values 829 829 qv = quantity.vertex_values 830 830 831 831 #Find min and max of this and neighbour's centroid values 832 832 qmax = zeros(qc.shape, Float) 833 qmin = zeros(qc.shape, Float) 834 833 qmin = zeros(qc.shape, Float) 834 835 835 for k in range(N): 836 836 qmax[k] = qmin[k] = qc[k] … … 839 839 if n >= 0: 840 840 qn = qc[n] #Neighbour's centroid value 841 841 842 842 qmin[k] = min(qmin[k], qn) 843 843 qmax[k] = max(qmax[k], qn) 844 845 844 845 846 846 #Diffences between centroids and maxima/minima 847 dqmax = qmax - qc 847 dqmax = qmax - qc 848 848 dqmin = qmin - qc 849 849 850 850 #Deltas between vertex and centroid values 851 851 dq = zeros(qv.shape, Float) … … 853 853 dq[:,i] = qv[:,i] - qc 854 854 855 #Phi limiter 855 #Phi limiter 856 856 for k in range(N): 857 857 858 858 #Find the gradient limiter (phi) across vertices 859 859 phi = 1.0 … … 862 862 if (dq[k,i] > 0): r = dqmax[k]/dq[k,i] 863 863 if (dq[k,i] < 0): r = dqmin[k]/dq[k,i] 864 865 phi = min( min(r*beta_w, 1), phi ) 864 865 phi = min( min(r*beta_w, 1), phi ) 866 866 867 867 #Then update using phi limiter 868 for i in range(3): 868 for i in range(3): 869 869 qv[k,i] = qc[k] + phi*dq[k,i] 870 870 … … 874 874 if compile.can_use_C_extension('quantity_ext.c'): 875 875 #Replace python version with c implementations 876 876 877 877 from quantity_ext import limit, compute_gradients,\ 878 extrapolate_second_order, interpolate_from_vertices_to_edges, update 879 878 extrapolate_second_order, interpolate_from_vertices_to_edges, update -
inundation/ga/storm_surge/pyvolution/realtime_visualisation_new.py
r1281 r1290 1 1 from visual import * 2 3 elevation_color = (0.3,0.4,0.5) 4 stage_color = (0.1,0.4,0.99) 2 5 3 6 class Surface: … … 8 11 self.frame = frame() 9 12 10 self.bed_model = faces(frame=self.frame)11 self.stage_model = faces(frame=self.frame)12 13 self.domain = domain 13 14 self.scale_z = scale_z 14 15 15 self.vertices = domain.vertex_coordinates 16 16 17 self.stage = domain.quantities['stage'].vertex_values 18 19 try: 20 self.bed = domain.quantities['elevation'].vertex_values 21 self.xmomentum = domain.quantities['xmomentum'].vertex_values 22 self.ymomentum = domain.quantities['ymomentum'].vertex_values 23 except: 24 self.bed = None 25 self.xmomentum = None 26 self.ymomentum = None 27 28 29 self.max_x = max(max(self.vertices[:,0],self.vertices[:,2],self.vertices[:,4])) 30 self.min_x = min(min(self.vertices[:,0],self.vertices[:,2],self.vertices[:,4])) 31 self.max_y = max(max(self.vertices[:,1],self.vertices[:,3],self.vertices[:,5])) 32 self.min_y = min(min(self.vertices[:,1],self.vertices[:,3],self.vertices[:,5])) 17 # models for each quantity 18 self.z_models = {} 19 keys = self.domain.quantities.keys() 20 #print keys 21 for key in keys: 22 self.z_models[key] = faces(frame= self.frame) 23 24 25 26 self.max_x = max(max(self.vertices[:,0]),max(self.vertices[:,2]),max(self.vertices[:,4])) 27 self.min_x = min(min(self.vertices[:,0]),min(self.vertices[:,2]),min(self.vertices[:,4])) 28 self.max_y = max(max(self.vertices[:,1]),max(self.vertices[:,3]),max(self.vertices[:,5])) 29 self.min_y = min(min(self.vertices[:,1]),min(self.vertices[:,3]),min(self.vertices[:,5])) 33 30 self.range_x = self.max_x - self.min_x 34 31 self.range_y = self.max_y - self.min_y 35 36 32 self.range_xy = max(self.range_x, self.range_y) 37 33 38 if self.bed != None and range_z == None: 39 self.max_z = max(max(self.bed)) 40 self.min_z = min(min(self.bed)) 41 self.range_z = max(self.max_z - self.min_z, 1.0e-10) 42 43 print 'min_bed=',self.min_z 44 print 'max_bed=',self.max_z 45 print 'range_z=',self.range_z 46 else: 47 self.max_z = range_z/2.0 48 self.min_z = -range_z/2.0 49 self.range_z = max(self.max_z - self.min_z, 1.0e-10) 34 # print 'min_x=',self.min_x 35 # print 'max_x=',self.max_x 36 # print 'range_x=',self.range_x 37 # print 'min_y=',self.min_y 38 # print 'max_y=',self.max_y 39 # print 'range_y',self.range_y 40 41 self.range_z = 1.0 42 self.max_z = self.range_z/2.0 43 self.min_z = -self.range_z/2.0 44 self.range_z = max(self.max_z - self.min_z, 1.0e-10) 50 45 51 46 … … 68 63 #scene.autoscale=0 69 64 #self.update_all() 65 #scene.uniform=0 66 self.setup_range_z() 67 68 def setup_range_z(self,qname1='elevation',qname2='stage'): 69 70 #print qname1 71 #print qname2 72 self.range_z = 1.0e-10 73 try: 74 q1 = self.domain.quantities[qname1].vertex_values 75 max_z = max(max(q1)) 76 min_z = min(min(q1)) 77 print max_z, min_z 78 self.range_z = max(self.range_z, max_z - min_z) 79 except: 80 print 'could not find range of '+qname1 81 pass 82 83 try: 84 q2 = self.domain.quantities[qname2].vertex_values 85 max_z = max(max(q2)) 86 min_z = min(min(q2)) 87 print max_z, min_z 88 self.range_z = max(self.range_z, max_z - min_z) 89 except: 90 print 'Visualisation: could not find range of '+qname2 91 pass 70 92 71 93 def update_all(self): 72 94 73 self.update_ bed()74 self.update_ stage()95 self.update_quantity('elevation',elevation_color) 96 self.update_quantity('stage',stage_color) 75 97 76 98 def update_timer(self): 77 99 self.timer.text='Time=%10.5e'%self.domain.time 78 100 79 def update_bed(self): 80 81 #print 'update bed arrays' 82 c0 = 0.3 83 c1 = 0.3 84 c2 = 0.3 85 if self.bed != None: 86 self.update_arrays(self.bed, (c0,c1,c2) ) 101 102 def update_quantity(self,qname,qcolor=None): 103 104 #print 'update '+qname+' arrays' 105 106 if qcolor is None: 107 if qname=='elevation': 108 qcolor = elevation_color 109 110 if qname=='stage': 111 qcolor = stage_color 112 113 114 try: 115 self.update_arrays(self.domain.quantities[qname].vertex_values, qcolor) 87 116 88 117 #print 'update bed image' 89 self.bed_model.pos = self.pos 90 self.bed_model.color = self.colour 91 self.bed_model.normal = self.normals 92 93 94 def update_stage(self): 95 c0 = 0.1 96 c1 = 0.4 97 c2 = 0.99 98 #print 'update stage arrays' 99 if self.stage != None: 100 self.update_arrays(self.stage, (c0,c1,c2) ) 101 #print 'update stage image' 102 self.stage_model.pos = self.pos 103 self.stage_model.color = self.colour 104 self.stage_model.normal = self.normals 105 106 def update_xmomentum(self): 107 c0 = 0.1 108 c1 = 0.4 109 c2 = 0.99 110 #print 'update stage arrays' 111 self.update_arrays(self.xmomentum, (c0,c1,c2) ) 112 #print 'update stage image' 113 self.stage_model.pos = self.pos 114 self.stage_model.color = self.colour 115 self.stage_model.normal = self.normals 116 117 def update_ymomentum(self): 118 c0 = 0.1 119 c1 = 0.4 120 c2 = 0.99 121 #print 'update stage arrays' 122 self.update_arrays(self.ymomentum, (c0,c1,c2) ) 123 #print 'update stage image' 124 self.stage_model.pos = self.pos 125 self.stage_model.color = self.colour 126 self.stage_model.normal = self.normals 118 self.z_models[qname].pos = self.pos 119 self.z_models[qname].color = self.colour 120 self.z_models[qname].normal = self.normals 121 except: 122 print 'Visualisation: Could not update quantity '+qname 123 pass 124 125 def update_quantity_color(self,qname,qcolor=None): 126 127 #print 'update '+qname+' arrays' 128 129 if qcolor is None: 130 if qname=='elevation': 131 qcolor = elevation_color 132 133 if qname=='stage': 134 qcolor = stage_color 135 136 137 try: 138 self.update_arrays_color(self.domain.quantities[qname].vertex_values, qcolor) 139 140 #print 'update bed image' 141 self.z_models[qname].pos = self.pos 142 self.z_models[qname].color = self.colour 143 self.z_models[qname].normal = self.normals 144 except: 145 print 'Visualisation: Could not update quantity '+qname 146 pass 147 127 148 128 149 def update_arrays(self,quantity,qcolor): … … 151 172 152 173 174 def update_arrays_color(self,quantity,qcolor): 175 176 col = asarray(qcolor) 177 178 N = len(self.domain) 179 180 scale_z = self.scale_z 181 min_x = self.min_x 182 min_y = self.min_y 183 range_xy = self.range_xy 184 range_z = self.range_z 185 186 vertices = self.vertices 187 pos = self.pos 188 normals = self.normals 189 colour = self.colour 190 191 try: 192 update_arrays_color_weave(vertices,quantity,col,pos,normals,colour,N, 193 min_x,min_y,range_xy,range_z,scale_z) 194 except: 195 update_arrays_color_python(vertices,quantity,col,pos,normals,colour,N, 196 min_x,min_y,range_xy,range_z,scale_z) 197 198 199 #================================================================================== 153 200 154 201 def update_arrays_python(vertices,quantity,col,pos,normals,colour,N, … … 277 324 type_converters = converters.blitz, compiler='gcc'); 278 325 326 def update_arrays_color_python(vertices,quantity,col,pos,normals,colour,N, 327 min_x,min_y,range_xy,range_z,scale_z): 328 329 from math import sqrt 330 normal = zeros( 3, Float) 331 v = zeros( (3,3), Float) 332 s = 1.0 333 334 for i in range( N ): 335 336 for j in range(3): 337 v[j,0] = (vertices[i,2*j ]-min_x)/range_xy 338 v[j,1] = (vertices[i,2*j+1]-min_y)/range_xy 339 v[j,2] = quantity[i,j]/range_z*scale_z*0.5 340 341 v10 = v[1,:]-v[0,:] 342 v20 = v[2,:]-v[0,:] 343 344 normal[0] = v10[1]*v20[2] - v20[1]*v10[2] 345 normal[1] = v10[2]*v20[0] - v20[2]*v10[0] 346 normal[2] = v10[0]*v20[1] - v20[0]*v10[1] 347 348 norm = sqrt( normal[0]**2 + normal[1]**2 + normal[2]**2) 349 350 normal[0] = normal[0]/norm 351 normal[1] = normal[1]/norm 352 normal[2] = normal[2]/norm 353 354 pos[6*i ,:] = v[0,:] 355 pos[6*i+1,:] = v[1,:] 356 pos[6*i+2,:] = v[2,:] 357 pos[6*i+3,:] = v[0,:] 358 pos[6*i+4,:] = v[2,:] 359 pos[6*i+5,:] = v[1,:] 360 361 s = abs(v(2,j)) 362 363 colour[6*i ,:] = s*col 364 colour[6*i+1,:] = s*col 365 colour[6*i+2,:] = s*col 366 colour[6*i+3,:] = s*col 367 colour[6*i+4,:] = s*col 368 colour[6*i+5,:] = s*col 369 370 s = 15.0/8.0 - s 371 372 normals[6*i ,:] = normal 373 normals[6*i+1,:] = normal 374 normals[6*i+2,:] = normal 375 normals[6*i+3,:] = -normal 376 normals[6*i+4,:] = -normal 377 normals[6*i+5,:] = -normal 378 379 380 381 def update_arrays_color_weave(vertices,quantity,col,pos,normals,colour, 382 N,min_x,min_y,range_xy,range_z,scale_z): 383 384 import weave 385 from weave import converters 386 387 from math import sqrt 388 normal = zeros( 3, Float) 389 v = zeros( (3,3), Float) 390 v10 = zeros( 3, Float) 391 v20 = zeros( 3, Float) 392 393 code1 = """ 394 double s = 1.0; 395 396 for (int i=0; i<N ; i++ ) { 397 for (int j=0; j<3 ; j++) { 398 v(j,0) = (vertices(i,2*j )-min_x)/range_xy; 399 v(j,1) = (vertices(i,2*j+1)-min_y)/range_xy; 400 v(j,2) = quantity(i,j)/range_z*scale_z*0.5; 401 } 402 403 404 for (int j=0; j<3; j++) { 405 v10(j) = v(1,j)-v(0,j); 406 v20(j) = v(2,j)-v(0,j); 407 } 408 409 normal(0) = v10(1)*v20(2) - v20(1)*v10(2); 410 normal(1) = v10(2)*v20(0) - v20(2)*v10(0); 411 normal(2) = v10(0)*v20(1) - v20(0)*v10(1); 412 413 double norm = sqrt(normal(0)*normal(0) + normal(1)*normal(1) + normal(2)*normal(2)); 414 415 normal(0) = normal(0)/norm; 416 normal(1) = normal(1)/norm; 417 normal(2) = normal(2)/norm; 418 419 s = 0.2+fabs((v(0,2)+v(1,2)+v(2,2))/3.0); 420 421 for (int j=0; j<3; j++) { 422 pos(6*i ,j) = v(0,j); 423 pos(6*i+1,j) = v(1,j); 424 pos(6*i+2,j) = v(2,j); 425 pos(6*i+3,j) = v(0,j); 426 pos(6*i+4,j) = v(2,j); 427 pos(6*i+5,j) = v(1,j); 428 429 430 431 432 colour(6*i ,j) = s*col(j); 433 colour(6*i+1,j) = s*col(j); 434 colour(6*i+2,j) = s*col(j); 435 colour(6*i+3,j) = s*col(j); 436 colour(6*i+4,j) = s*col(j); 437 colour(6*i+5,j) = s*col(j); 438 439 normals(6*i ,j) = normal(j); 440 normals(6*i+1,j) = normal(j); 441 normals(6*i+2,j) = normal(j); 442 normals(6*i+3,j) = -normal(j); 443 normals(6*i+4,j) = -normal(j); 444 normals(6*i+5,j) = -normal(j); 445 } 446 447 s = 15.0/8.0 - s; 448 } 449 450 """ 451 452 weave.inline(code1, ['vertices','quantity','col','pos','normals','colour','N', 453 'min_x','min_y','range_xy','range_z','scale_z','v','normal','v10','v20'], 454 type_converters = converters.blitz, compiler='gcc'); 279 455 280 456 scene.width = 1000 … … 282 458 283 459 #Original 284 scene.center = (0.5,0.5,0 )460 scene.center = (0.5,0.5,0.0) 285 461 scene.forward = vector(-0.1, 0.5, -0.5) 286 462 … … 304 480 305 481 306 def create_surface(domain, range_z=None):307 308 surface = Surface(domain, range_z=range_z)482 def create_surface(domain,scale_z=0.5,range_z=None): 483 484 surface = Surface(domain,scale_z=0.5,range_z=range_z) 309 485 domain.surface = surface 310 486 311 surface.update_bed() 312 surface.update_stage() 313 #surface.update_xmomentum() 314 #surface.update_ymomentum 487 surface.update_quantity('elevation') 488 surface.update_quantity('stage') 315 489 surface.update_timer() 316 490 317 491 def update(domain): 318 492 319 #print 'start visual update'320 493 surface = domain.surface 321 surface.update_stage() 322 #surface.update_xmomentum() 323 #surface.update_ymomentum() 494 surface.update_quantity('stage') 324 495 surface.update_timer() 325 #print 'end visual update' -
inundation/ga/storm_surge/pyvolution/view_tsh.py
r1278 r1290 40 40 41 41 surface = Surface(domain, scale_z = scale_z) 42 surface.update_bed() 43 44 42 surface.update_quantity('elevation') -
inundation/ga/storm_surge/steve/run_merimbula_lake.py
r1271 r1290 29 29 #------- 30 30 # Domain 31 filename = 'merimbula_interpolated.tsh' 31 filename = 'merimbula_interpolated.tsh' 32 filename = 'merimbula_10785_1.tsh' 32 33 print 'Creating domain from', filename 33 34 domain = pmesh_to_domain_instance(filename, Domain) … … 162 163 # All other boundaries are reflective 163 164 Br = Reflective_boundary(domain) 164 domain.set_boundary({'exter nal': Br, 'open': Bf})165 domain.set_boundary({'exterior': Br, 'open': Bf}) 165 166 166 167 #----------- … … 174 175 #-------------------------------- 175 176 # Initial water surface elevation 176 domain.set_quantity('stage', 1.0)177 domain.set_quantity('stage', 0.0) 177 178 178 179 #---------------------------------------------------------- -
inundation/ga/storm_surge/zeus/anuga-workspace.zwi
r1280 r1290 2 2 <workspace name="anuga-workspace"> 3 3 <mode>Debug</mode> 4 <active>parallel</active> 4 <active>pyvolution</active> 5 <project name="Merimbula">Merimbula.zpi</project> 5 6 <project name="parallel">parallel.zpi</project> 6 7 <project name="pyvolution">pyvolution.zpi</project> -
inundation/ga/storm_surge/zeus/steve.zpi
r1271 r1290 75 75 <file>..\steve\get_triangle_data.py</file> 76 76 <file>..\steve\get_triangle_data_new.py</file> 77 <file>..\steve\run_least_squares_merimbula.py</file>78 77 <file>..\pyvolution-parallel\vtk-pylab.py</file> 79 78 <folder name="Header Files" />
Note: See TracChangeset
for help on using the changeset viewer.