source: anuga_core/source/anuga/pmesh/mesh_interface.py @ 3719

Last change on this file since 3719 was 3719, checked in by steve, 18 years ago

Adding holes to create_mesh_from_regions

File size: 9.4 KB
Line 
1
2#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3# Assume that the root AnuGA dir (inundation) is included in your pythonpath
4#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
5
6from anuga.coordinate_transforms.geo_reference import Geo_reference,DEFAULT_ZONE
7from anuga.utilities.polygon import  point_in_polygon ,populate_polygon
8from anuga.utilities.numerical_tools import ensure_numeric
9from Numeric import Float
10from anuga.utilities.polygon import inside_polygon
11
12# This is due to pmesh being a package and a module and
13# the current dir being unknown
14try:
15    from anuga.pmesh.mesh import Mesh
16except ImportError: 
17    from mesh import Mesh
18
19import exceptions
20class PolygonError(exceptions.Exception): pass
21
22def create_mesh_from_regions(bounding_polygon,
23                             boundary_tags,
24                             maximum_triangle_area=None,
25                             filename=None,
26                             interior_regions=None,
27                             interior_holes=None,
28                             poly_geo_reference=None,
29                             mesh_geo_reference=None,
30                             minimum_triangle_angle=28.0,
31                             use_cache=False,
32                             verbose=True):
33    """Create mesh from bounding polygons, and resolutions.
34
35    bounding_polygon is a list of points in Eastings and Northings,
36    relative to the poly_geo_reference.
37
38    Boundary tags is a dictionary of symbolic tags. For every tag there
39    is a list of indices referring to segments associated with that tag
40
41    maximum_triangle_area is the maximal area per triangle
42    for the bounding polygon, excluding the  interior regions.
43
44    Interior_regions is a list of tuples consisting of (polygon, resolution)
45    for each region to be separately refined.
46   
47    Interior_holes is a list of ploygons for each hole.
48
49    This function does not allow segments to share points - use underlying
50    pmesh functionality for that
51
52    poly_geo_reference is the geo_reference of the bounding polygon and
53    the interior polygons.
54    If none, assume absolute.  Please pass one though, since absolute
55    references have a zone.
56   
57    mesh_geo_reference is the geo_reference of the mesh to be created.
58    If none is given one will be automatically generated.  It was use
59    the lower left hand corner of  bounding_polygon (absolute)
60    as the x and y values for the geo_ref.
61   
62    Returns the mesh instance if no finename is given
63
64    Note, interior regions should be fully nested, as overlaps may cause
65    unintended resolutions.
66   
67    """
68
69    # Build arguments and keyword arguments for use with caching or apply.
70    args = (bounding_polygon,
71            boundary_tags)
72   
73    kwargs = {'maximum_triangle_area': maximum_triangle_area,
74              'filename': filename,
75              'interior_regions': interior_regions,
76              'interior_holes': interior_holes,
77              'poly_geo_reference': poly_geo_reference,
78              'mesh_geo_reference': mesh_geo_reference,
79              'minimum_triangle_angle': minimum_triangle_angle,
80              'verbose': verbose}   # FIXME (Ole): Should be bypassed one day
81
82
83    #print 'kwargs', kwargs
84
85    # Call underlying engine with or without caching
86    if use_cache is True:
87        try:
88            from caching import cache
89        except:
90            msg = 'Caching was requested, but caching module'+\
91                  'could not be imported'
92            raise msg
93
94
95        res = cache(_create_mesh_from_regions,
96                    args, kwargs,
97                    verbose=verbose,
98                    compression=False)
99    else:
100        res = apply(_create_mesh_from_regions,
101                    args, kwargs)
102
103    return res
104
105
106
107def _create_mesh_from_regions(bounding_polygon,
108                              boundary_tags,
109                              maximum_triangle_area=None,
110                              filename=None,
111                              interior_regions=None,
112                              interior_holes=None,
113                              poly_geo_reference=None,
114                              mesh_geo_reference=None,
115                              minimum_triangle_angle=28.0,
116                              verbose=True):
117    """_create_mesh_from_regions - internal function.
118
119    See create_mesh_from_regions for documentation.
120    """
121    #FIXME (OLE-DSG)
122    # check the segment indexes - throw an error if they are out of bounds
123    #(DSG) Yes!
124
125   
126    #In addition I reckon the polygons could be of class Geospatial_data
127    #(DSG) Yes!
128
129    # First check that interior polygons are fully contained in bounding
130    # polygon
131    #Note, Both poly's have the same geo_ref, therefore don't take into account
132    # geo_ref
133
134    # Simple check
135    bounding_polygon = ensure_numeric(bounding_polygon, Float)
136    msg = 'Bounding polygon must be a list of points or an Nx2 array'
137    assert len(bounding_polygon.shape) == 2, msg
138    assert bounding_polygon.shape[1] == 2, msg   
139
140
141    #
142    if interior_regions is not None:       
143        # Test that all the interior polygons are inside the bounding_poly
144        for interior_polygon, res in interior_regions:
145            indices = inside_polygon(interior_polygon, bounding_polygon,
146                                     closed = True, verbose = False)
147   
148            if len(indices) <> len(interior_polygon): 
149                msg = 'Interior polygon %s is outside bounding polygon: %s'\
150                      %(str(interior_polygon), str(bounding_polygon))
151                raise PolygonError, msg
152
153    if interior_holes is not None:       
154        # Test that all the interior polygons are inside the bounding_poly
155        for interior_polygon, res in interior_holes:
156            indices = inside_polygon(interior_polygon, bounding_polygon,
157                                     closed = True, verbose = False)
158   
159            if len(indices) <> len(interior_polygon): 
160                msg = 'Interior polygon %s is outside bounding polygon: %s'\
161                      %(str(interior_polygon), str(bounding_polygon))
162                raise PolygonError, msg
163
164    # Resolve geo referencing       
165    if mesh_geo_reference is None:
166        xllcorner = min(bounding_polygon[:,0])
167        yllcorner = min(bounding_polygon[:,1])   
168        #
169        if poly_geo_reference is None:
170            zone = DEFAULT_ZONE
171        else:
172            zone = poly_geo_reference.get_zone()
173            [(xllcorner,yllcorner)] = poly_geo_reference.get_absolute( \
174            [(xllcorner,yllcorner)])
175        # create a geo_ref, based on the llc of the bounding_polygon
176        mesh_geo_reference = Geo_reference(xllcorner = xllcorner,
177                                           yllcorner = yllcorner,
178                                           zone = zone)
179
180    m = Mesh(geo_reference=mesh_geo_reference)
181
182    # Do bounding polygon
183    m.add_region_from_polygon(bounding_polygon,
184                              tags=boundary_tags,
185                              geo_reference=poly_geo_reference)
186
187    # Find one point inside region automatically
188    if interior_regions is not None:
189        excluded_polygons = []       
190        for polygon, res in interior_regions:
191            excluded_polygons.append( polygon )
192    else:
193        excluded_polygons = None
194
195    # Convert bounding poly to absolute values
196    # this sort of thing can be fixed with the geo_points class
197    if poly_geo_reference is not None:
198        bounding_polygon_absolute = \
199            poly_geo_reference.get_absolute(bounding_polygon)
200    else:
201        bounding_polygon_absolute = bounding_polygon
202   
203    inner_point = point_in_polygon(bounding_polygon_absolute)
204    inner = m.add_region(inner_point[0], inner_point[1])
205    inner.setMaxArea(maximum_triangle_area)
206
207    # Do interior regions
208#    if interior_regions is not None:   
209#        for polygon, res in interior_regions:
210#            m.add_region_from_polygon(polygon,
211#                                      geo_reference=poly_geo_reference)
212#            # convert bounding poly to absolute values
213#            if poly_geo_reference is not None:
214#                polygon_absolute = \
215#                    poly_geo_reference.get_absolute(polygon)
216#            else:
217#                polygon_absolute = polygon
218#            inner_point = point_in_polygon(polygon_absolute)
219#            region = m.add_region(inner_point[0], inner_point[1])
220#            region.setMaxArea(res)
221           
222           
223    if interior_regions is not None:   
224        for polygon, res in interior_regions:
225            m.add_region_from_polygon(polygon,
226                                      max_triangle_area = res,
227                                      geo_reference=poly_geo_reference)
228   
229           
230   # Do interior holes
231    if interior_holes is not None:   
232        for polygon, res in interior_holes:
233            m.add_hole_from_polygon(polygon,
234                                      geo_reference=poly_geo_reference)
235       
236           
237
238    if filename is None:
239        return m
240    else:
241        if verbose: print 'Generating mesh to file "%s"' %filename
242        m.generate_mesh(minimum_triangle_angle=minimum_triangle_angle,
243                             verbose=verbose)
244        m.export_mesh_file(filename)
245
Note: See TracBrowser for help on using the repository browser.