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

Last change on this file since 3715 was 3715, checked in by ole, 18 years ago

Enabled caching in create_mesh_from_regions as requested in ticket:80 and
added a unittest for it.

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