Changeset 3684
- Timestamp:
- Oct 3, 2006, 5:47:08 PM (17 years ago)
- Location:
- anuga_core/source/anuga
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
anuga_core/source/anuga/abstract_2d_finite_volumes/general_mesh.py
r3624 r3684 80 80 self.geo_reference = geo_reference 81 81 82 # Input checks82 # Input checks 83 83 msg = 'Triangles must an Nx3 Numeric array or a sequence of 3-tuples. ' 84 84 msg += 'The supplied array has the shape: %s'\ … … 95 95 96 96 97 # Register number of elements (N)97 # Register number of elements (N) 98 98 self.number_of_elements = N = self.triangles.shape[0] 99 99 … … 106 106 107 107 108 # Allocate space for geometric quantities108 # Allocate space for geometric quantities 109 109 self.normals = zeros((N, 6), Float) 110 110 self.areas = zeros(N, Float) 111 111 self.edgelengths = zeros((N, 3), Float) 112 112 113 # Get x,y coordinates for all triangles and store113 # Get x,y coordinates for all triangles and store 114 114 self.vertex_coordinates = V = self.compute_vertex_coordinates() 115 115 116 116 117 # Initialise each triangle117 # Initialise each triangle 118 118 if verbose: 119 119 print 'General_mesh: Computing areas, normals and edgelenghts' … … 127 127 x2 = V[i, 4]; y2 = V[i, 5] 128 128 129 # Area129 # Area 130 130 self.areas[i] = abs((x1*y0-x0*y1)+(x2*y1-x1*y2)+(x0*y2-x2*y0))/2 131 131 … … 135 135 136 136 137 # Normals138 # The normal vectors139 # - point outward from each edge140 # - are orthogonal to the edge141 # - have unit length142 # - Are enumerated according to the opposite corner:143 # (First normal is associated with the edge opposite144 # the first vertex, etc)145 # - Stored as six floats n0x,n0y,n1x,n1y,n2x,n2y per triangle137 # Normals 138 # The normal vectors 139 # - point outward from each edge 140 # - are orthogonal to the edge 141 # - have unit length 142 # - Are enumerated according to the opposite corner: 143 # (First normal is associated with the edge opposite 144 # the first vertex, etc) 145 # - Stored as six floats n0x,n0y,n1x,n1y,n2x,n2y per triangle 146 146 147 147 n0 = array([x2 - x1, y2 - y1]) … … 154 154 l2 = sqrt(sum(n2**2)) 155 155 156 # Normalise156 # Normalise 157 157 n0 /= l0 158 158 n1 /= l1 159 159 n2 /= l2 160 160 161 # Compute and store161 # Compute and store 162 162 self.normals[i, :] = [n0[1], -n0[0], 163 163 n1[1], -n1[0], 164 164 n2[1], -n2[0]] 165 165 166 # Edgelengths166 # Edgelengths 167 167 self.edgelengths[i, :] = [l0, l1, l2] 168 168 169 169 170 # Build vertex list170 # Build vertex list 171 171 if verbose: print 'Building vertex list' 172 172 self.build_vertexlist() … … 178 178 179 179 def __repr__(self): 180 return 'Mesh: %d triangles, %d elements'\180 return 'Mesh: %d vertex coordinates, %d triangles'\ 181 181 %(self.coordinates.shape[0], len(self)) 182 182 -
anuga_core/source/anuga/abstract_2d_finite_volumes/neighbour_mesh.py
r3616 r3684 175 175 176 176 def __repr__(self): 177 return 'Mesh: %d triangles, %d elements, %d boundary segments'\177 return 'Mesh: %d vertex_coordinates, %d triangles, %d boundary segments'\ 178 178 %(self.coordinates.shape[0], len(self), len(self.boundary)) 179 179 … … 491 491 492 492 493 494 495 493 #Start with smallest point and follow boundary (counter clock wise) 496 494 polygon = [p0] # Storage for final boundary polygon … … 508 506 candidate_list = segments[tuple(p0)] 509 507 if len(candidate_list) > 1: 510 # Multiple points detected 508 # Multiple points detected (this will be the case for meshes with 509 # duplicate points as those used for discontinuous triangles). 511 510 # Take the candidate that is furthest to the clockwise direction, 512 511 # as that will follow the boundary. … … 521 520 if len(polygon) > 1: 522 521 v_prev = p0 - polygon[-2] # Vector that leads to p0 522 523 # Normalise 524 #v_prev /= sqrt(sum(v_prev**2)) 523 525 else: 524 526 # FIXME (Ole): What do we do if the first point has multiple … … 527 529 # vector [1, 0], but I really don't know if this is completely 528 530 # watertight. 529 # Another option might be v_prev = [1.0, 0.0]530 531 v_prev = [1.0, 0.0] 531 532 532 533 533 534 534 # Choose candidate with minimum angle … … 536 536 for pc in candidate_list: 537 537 vc = pc-p0 # Candidate vector 538 # Normalise 539 #vc /= sqrt(sum(vc**2)) 538 540 539 541 # Angle between each candidate and the previous vector 540 542 # in [-pi, pi] 543 541 544 ac = angle(vc, v_prev) 542 545 if ac > pi: ac = pi-ac -
anuga_core/source/anuga/abstract_2d_finite_volumes/test_neighbour_mesh.py
r3560 r3684 13 13 from mesh_factory import rectangular 14 14 from anuga.config import epsilon 15 from Numeric import allclose, array 15 from Numeric import allclose, array, Int 16 16 17 17 from anuga.coordinate_transforms.geo_reference import Geo_reference 18 18 from anuga.utilities.polygon import is_inside_polygon 19 from anuga.utilities.numerical_tools import ensure_numeric 19 20 20 21 def distance(x, y): … … 909 910 910 911 912 def xtest_boundary_polygon_VI(self): 913 """test_boundary_polygon_VI(self) 914 915 Create a discontinuous mesh (duplicate vertices) from a real situation that failed 916 and check that boundary is as expected 917 """ 918 919 920 from anuga.utilities.polygon import plot_polygons 921 922 # First do the continuous version of mesh 923 924 points = [[ 6626.85400391, 0. ], 925 [ 0. , 38246.4140625 ], 926 [ 9656.2734375 , 68351.265625 ], 927 [ 20827.25585938, 77818.203125 ], 928 [ 32755.59375 , 58126.9765625 ], 929 [ 35406.3359375 , 79332.9140625 ], 930 [ 31998.23828125, 88799.84375 ], 931 [ 23288.65820313, 104704.296875 ], 932 [ 32187.57617188, 109816.4375 ], 933 [ 50364.08984375, 110763.1328125 ], 934 [ 80468.9453125 , 96184.0546875 ], 935 [ 86149.1015625 , 129886.34375 ], 936 [ 118715.359375 , 129886.34375 ], 937 [ 117768.6640625 , 85770.4296875 ], 938 [ 101485.5390625 , 45251.9453125 ], 939 [ 49985.4140625 , 2272.06396484], 940 [ 51737.94140625, 90559.2109375 ], 941 [ 56659.0703125 , 65907.6796875 ], 942 [ 75735.4765625 , 23762.00585938], 943 [ 52341.70703125, 38563.39453125]] 944 945 triangles = [[19, 0,15], 946 [ 2, 4, 3], 947 [ 4, 2, 1], 948 [ 1,19, 4], 949 [15,18,19], 950 [18,14,17], 951 [19, 1, 0], 952 [ 6, 8, 7], 953 [ 8, 6,16], 954 [10, 9,16], 955 [17, 5, 4], 956 [16,17,10], 957 [17,19,18], 958 [ 5,17,16], 959 [10,14,13], 960 [10,17,14], 961 [ 8,16, 9], 962 [12,11,10], 963 [10,13,12], 964 [19,17, 4], 965 [16, 6, 5]] 966 967 mesh = Mesh(points, triangles) 968 mesh.check_integrity() 969 Pref = mesh.get_boundary_polygon() 970 971 plot_polygons([ensure_numeric(Pref)], 'goodP') 972 973 for p in points: 974 assert is_inside_polygon(p, Pref) 975 976 977 # Then do the discontinuous version 978 import warnings 979 warnings.filterwarnings('ignore') 980 981 982 points = [[ 52341.70703125, 38563.39453125], 983 [ 6626.85400391, 0. ], 984 [ 49985.4140625 , 2272.06396484], 985 [ 9656.2734375 , 68351.265625 ], 986 [ 32755.59375 , 58126.9765625 ], 987 [ 20827.25585938, 77818.203125 ], 988 [ 32755.59375 , 58126.9765625 ], 989 [ 9656.2734375 , 68351.265625 ], 990 [ 0. , 38246.4140625 ], 991 [ 0. , 38246.4140625 ], 992 [ 52341.70703125, 38563.39453125], 993 [ 32755.59375 , 58126.9765625 ], 994 [ 49985.4140625 , 2272.06396484], 995 [ 75735.4765625 , 23762.00585938], 996 [ 52341.70703125, 38563.39453125], 997 [ 75735.4765625 , 23762.00585938], 998 [ 101485.5390625 , 45251.9453125 ], 999 [ 56659.0703125 , 65907.6796875 ], 1000 [ 52341.70703125, 38563.39453125], 1001 [ 0. , 38246.4140625 ], 1002 [ 6626.85400391, 0. ], 1003 [ 31998.23828125, 88799.84375 ], 1004 [ 32187.57617188, 109816.4375 ], 1005 [ 23288.65820313, 104704.296875 ], 1006 [ 32187.57617188, 109816.4375 ], 1007 [ 31998.23828125, 88799.84375 ], 1008 [ 51737.94140625, 90559.2109375 ], 1009 [ 80468.9453125 , 96184.0546875 ], 1010 [ 50364.08984375, 110763.1328125 ], 1011 [ 51737.94140625, 90559.2109375 ], 1012 [ 56659.0703125 , 65907.6796875 ], 1013 [ 35406.3359375 , 79332.9140625 ], 1014 [ 32755.59375 , 58126.9765625 ], 1015 [ 51737.94140625, 90559.2109375 ], 1016 [ 56659.0703125 , 65907.6796875 ], 1017 [ 80468.9453125 , 96184.0546875 ], 1018 [ 56659.0703125 , 65907.6796875 ], 1019 [ 52341.70703125, 38563.39453125], 1020 [ 75735.4765625 , 23762.00585938], 1021 [ 35406.3359375 , 79332.9140625 ], 1022 [ 56659.0703125 , 65907.6796875 ], 1023 [ 51737.94140625, 90559.2109375 ], 1024 [ 80468.9453125 , 96184.0546875 ], 1025 [ 101485.5390625 , 45251.9453125 ], 1026 [ 117768.6640625 , 85770.4296875 ], 1027 [ 80468.9453125 , 96184.0546875 ], 1028 [ 56659.0703125 , 65907.6796875 ], 1029 [ 101485.5390625 , 45251.9453125 ], 1030 [ 32187.57617188, 109816.4375 ], 1031 [ 51737.94140625, 90559.2109375 ], 1032 [ 50364.08984375, 110763.1328125 ], 1033 [ 118715.359375 , 129886.34375 ], 1034 [ 86149.1015625 , 129886.34375 ], 1035 [ 80468.9453125 , 96184.0546875 ], 1036 [ 80468.9453125 , 96184.0546875 ], 1037 [ 117768.6640625 , 85770.4296875 ], 1038 [ 118715.359375 , 129886.34375 ], 1039 [ 52341.70703125, 38563.39453125], 1040 [ 56659.0703125 , 65907.6796875 ], 1041 [ 32755.59375 , 58126.9765625 ], 1042 [ 51737.94140625, 90559.2109375 ], 1043 [ 31998.23828125, 88799.84375 ], 1044 [ 35406.3359375 , 79332.9140625 ]] 1045 1046 #points = ensure_numeric(points, Int)/1000 # Simplify for ease of interpretation 1047 1048 triangles = [[ 0, 1, 2], 1049 [ 3, 4, 5], 1050 [ 6, 7, 8], 1051 [ 9,10,11], 1052 [12,13,14], 1053 [15,16,17], 1054 [18,19,20], 1055 [21,22,23], 1056 [24,25,26], 1057 [27,28,29], 1058 [30,31,32], 1059 [33,34,35], 1060 [36,37,38], 1061 [39,40,41], 1062 [42,43,44], 1063 [45,46,47], 1064 [48,49,50], 1065 [51,52,53], 1066 [54,55,56], 1067 [57,58,59], 1068 [60,61,62]] 1069 1070 mesh = Mesh(points, triangles) 1071 mesh.check_integrity() 1072 P = mesh.get_boundary_polygon() 1073 1074 plot_polygons([ensure_numeric(P)], 'badP') 1075 print P 1076 1077 for p in points: 1078 #assert is_inside_polygon(p, P) 1079 if not is_inside_polygon(p, P): 1080 print 'Point %s is not in P' %(p) 1081 else: 1082 print 'Point %s OK' %(p) 1083 1084 #for i in range(len(Pref)): 1085 # print P[i], Pref[i] 1086 # 1087 #print ensure_numeric(P) - ensure_numeric(Pref) 1088 1089 1090 911 1091 def test_lone_vertices(self): 912 1092 a = [2.0, 1.0] -
anuga_core/source/anuga/fit_interpolate/interpolate.py
r3633 r3684 230 230 231 231 if verbose: print 'Getting indices inside mesh boundary' 232 #print "self.mesh.get_boundary_polygon()",self.mesh.get_boundary_polygon()233 232 self.inside_poly_indices, self.outside_poly_indices = \ 234 in_and_outside_polygon(point_coordinates,235 self.mesh.get_boundary_polygon(),236 closed = True, verbose = verbose)233 in_and_outside_polygon(point_coordinates, 234 self.mesh.get_boundary_polygon(), 235 closed = True, verbose = verbose) 237 236 #print "self.inside_poly_indices",self.inside_poly_indices 238 237 #print "self.outside_poly_indices",self.outside_poly_indices -
anuga_core/source/anuga/utilities/numerical_tools.py
r3676 r3684 4 4 """ 5 5 6 from math import acos, pi, sqrt 7 from warnings import warn 6 8 7 9 #Establish which Numeric package to use … … 21 23 22 24 25 def safe_acos(x): 26 """Safely compute acos 27 28 Protect against cases where input argument x is outside the allowed 29 interval [-1.0, 1.0] by no more than machine precision 30 """ 31 32 error_msg = 'Input to acos is outside allowed domain [-1.0, 1.0]. I got %.12f' %x 33 warning_msg = 'Changing argument to acos from %.18f to %.1f' %(x, sign(x)) 34 35 # FIXME(Ole): Need function to compute machine precision as this is also 36 # used in fit_interpolate/search_functions.py 37 38 39 eps = 1.0e-15 # Machine precision 40 if x < -1.0: 41 if x < -1.0 - eps: 42 raise ValueError, errmsg 43 else: 44 warn(warning_msg) 45 x = -1.0 46 47 if x > 1.0: 48 if x > 1.0 + eps: 49 raise ValueError, errmsg 50 else: 51 print 'NOTE: changing argument to acos from %.18f to 1.0' %x 52 x = 1.0 53 54 return acos(x) 55 56 57 def sign(x): 58 if x > 0: return 1 59 if x < 0: return -1 60 if x == 0: return 0 61 62 23 63 def angle(v1, v2=None): 24 64 """Compute angle between 2D vectors v1 and v2. … … 29 69 The angle is measured as a number in [0, 2pi] from v2 to v1. 30 70 """ 31 from math import acos, pi, sqrt32 71 33 72 # Prepare two Numeric vectors … … 41 80 v1 = v1/sqrt(sum(v1**2)) 42 81 v2 = v2/sqrt(sum(v2**2)) 43 82 44 83 # Compute angle 45 84 p = innerproduct(v1, v2) 46 85 c = innerproduct(v1, normal_vector(v2)) # Projection onto normal 47 86 # (negative cross product) 48 #print "p",p 49 #print "v1", v1 50 #print "v2", v2 51 52 53 # Warning, this is a hack. It could cause code to go in loop forever 54 if False: 55 try: 56 theta = acos(p) 57 #print "theta",theta 58 except ValueError: 59 print "Doing a hack in numerical tools." 60 print "p",p 61 print "v1", v1 62 print "v2", v2 63 if p > (1.0 - 1e-12): #sus, checking a float 64 # Throw a warning 65 theta = 0.0 66 else: 67 raise 68 else: 69 theta = acos(p) 87 88 theta = safe_acos(p) 70 89 71 # print "problem with p",p72 # as p goes to 1 theta goes to 073 90 74 91 # Correct if v1 is in quadrant 3 or 4 with respect to v2 (as the x-axis)
Note: See TracChangeset
for help on using the changeset viewer.