Changeset 3684


Ignore:
Timestamp:
Oct 3, 2006, 5:47:08 PM (17 years ago)
Author:
ole
Message:

Work on get_boundary_polygon using (discontinuous) example that fails

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  
    8080            self.geo_reference = geo_reference
    8181
    82         #Input checks
     82        # Input checks
    8383        msg = 'Triangles must an Nx3 Numeric array or a sequence of 3-tuples. '
    8484        msg += 'The supplied array has the shape: %s'\
     
    9595
    9696
    97         #Register number of elements (N)
     97        # Register number of elements (N)
    9898        self.number_of_elements = N = self.triangles.shape[0]
    9999
     
    106106
    107107
    108         #Allocate space for geometric quantities
     108        # Allocate space for geometric quantities
    109109        self.normals = zeros((N, 6), Float)
    110110        self.areas = zeros(N, Float)
    111111        self.edgelengths = zeros((N, 3), Float)
    112112
    113         #Get x,y coordinates for all triangles and store
     113        # Get x,y coordinates for all triangles and store
    114114        self.vertex_coordinates = V = self.compute_vertex_coordinates()
    115115
    116116
    117         #Initialise each triangle
     117        # Initialise each triangle
    118118        if verbose:
    119119            print 'General_mesh: Computing areas, normals and edgelenghts'
     
    127127            x2 = V[i, 4]; y2 = V[i, 5]
    128128
    129             #Area
     129            # Area
    130130            self.areas[i] = abs((x1*y0-x0*y1)+(x2*y1-x1*y2)+(x0*y2-x2*y0))/2
    131131
     
    135135
    136136
    137             #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
     137            # 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
    146146
    147147            n0 = array([x2 - x1, y2 - y1])
     
    154154            l2 = sqrt(sum(n2**2))
    155155
    156             #Normalise
     156            # Normalise
    157157            n0 /= l0
    158158            n1 /= l1
    159159            n2 /= l2
    160160
    161             #Compute and store
     161            # Compute and store
    162162            self.normals[i, :] = [n0[1], -n0[0],
    163163                                  n1[1], -n1[0],
    164164                                  n2[1], -n2[0]]
    165165
    166             #Edgelengths
     166            # Edgelengths
    167167            self.edgelengths[i, :] = [l0, l1, l2]
    168168
    169169       
    170         #Build vertex list
     170        # Build vertex list
    171171        if verbose: print 'Building vertex list'         
    172172        self.build_vertexlist()
     
    178178
    179179    def __repr__(self):
    180         return 'Mesh: %d triangles, %d elements'\
     180        return 'Mesh: %d vertex coordinates, %d triangles'\
    181181               %(self.coordinates.shape[0], len(self))
    182182
  • anuga_core/source/anuga/abstract_2d_finite_volumes/neighbour_mesh.py

    r3616 r3684  
    175175
    176176    def __repr__(self):
    177         return 'Mesh: %d triangles, %d elements, %d boundary segments'\
     177        return 'Mesh: %d vertex_coordinates, %d triangles, %d boundary segments'\
    178178               %(self.coordinates.shape[0], len(self), len(self.boundary))
    179179
     
    491491
    492492
    493 
    494            
    495493        #Start with smallest point and follow boundary (counter clock wise)
    496494        polygon = [p0]      # Storage for final boundary polygon
     
    508506            candidate_list = segments[tuple(p0)]
    509507            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).
    511510                # Take the candidate that is furthest to the clockwise direction,
    512511                # as that will follow the boundary.
     
    521520                if len(polygon) > 1:   
    522521                    v_prev = p0 - polygon[-2] # Vector that leads to p0
     522
     523                    # Normalise
     524                    #v_prev /= sqrt(sum(v_prev**2)) 
    523525                else:
    524526                    # FIXME (Ole): What do we do if the first point has multiple
     
    527529                    # vector [1, 0], but I really don't know if this is completely
    528530                    # watertight.
    529                     # Another option might be v_prev = [1.0, 0.0]
    530531                    v_prev = [1.0, 0.0]
    531532                   
    532 
    533533                   
    534534                # Choose candidate with minimum angle   
     
    536536                for pc in candidate_list:
    537537                    vc = pc-p0  # Candidate vector
     538                    # Normalise
     539                    #vc /= sqrt(sum(vc**2))                     
    538540                   
    539541                    # Angle between each candidate and the previous vector
    540542                    # in [-pi, pi]
     543
    541544                    ac = angle(vc, v_prev)
    542545                    if ac > pi: ac = pi-ac
  • anuga_core/source/anuga/abstract_2d_finite_volumes/test_neighbour_mesh.py

    r3560 r3684  
    1313from mesh_factory import rectangular
    1414from anuga.config import epsilon
    15 from Numeric import allclose, array
     15from Numeric import allclose, array, Int
    1616
    1717from anuga.coordinate_transforms.geo_reference import Geo_reference
    1818from anuga.utilities.polygon import is_inside_polygon
     19from anuga.utilities.numerical_tools import ensure_numeric
    1920
    2021def distance(x, y):
     
    909910
    910911
     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
    9111091    def test_lone_vertices(self):
    9121092        a = [2.0, 1.0]
  • anuga_core/source/anuga/fit_interpolate/interpolate.py

    r3633 r3684  
    230230       
    231231        if verbose: print 'Getting indices inside mesh boundary'
    232         #print "self.mesh.get_boundary_polygon()",self.mesh.get_boundary_polygon()
    233232        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)
    237236        #print "self.inside_poly_indices",self.inside_poly_indices
    238237        #print "self.outside_poly_indices",self.outside_poly_indices
  • anuga_core/source/anuga/utilities/numerical_tools.py

    r3676 r3684  
    44"""
    55
     6from math import acos, pi, sqrt
     7from warnings import warn
    68
    79#Establish which Numeric package to use
     
    2123
    2224
     25def 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
     57def sign(x):
     58    if x > 0: return 1
     59    if x < 0: return -1
     60    if x == 0: return 0   
     61   
     62
    2363def angle(v1, v2=None):
    2464    """Compute angle between 2D vectors v1 and v2.
     
    2969    The angle is measured as a number in [0, 2pi] from v2 to v1.
    3070    """
    31     from math import acos, pi, sqrt
    3271 
    3372    # Prepare two Numeric vectors
     
    4180    v1 = v1/sqrt(sum(v1**2))
    4281    v2 = v2/sqrt(sum(v2**2))
    43    
     82
    4483    # Compute angle
    4584    p = innerproduct(v1, v2)
    4685    c = innerproduct(v1, normal_vector(v2)) # Projection onto normal
    4786                                            # (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)
    7089           
    71      #   print "problem with p",p
    72      # as p goes to 1 theta goes to 0
    7390   
    7491    # 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.