source: trunk/anuga_core/anuga/pmesh/mesh_quadtree.py @ 9679

Last change on this file since 9679 was 8697, checked in by steve, 12 years ago

Changes to get Padarn's new code working for windows. Do need to setup netcdf dll and netcdf.h in fit_interpolate directory

File size: 3.9 KB
Line 
1"""
2    Quadtree representation of 2D mesh geometry.
3
4   Ole Nielsen, Stephen Roberts, Duncan Gray
5   Geoscience Australia, 2006.
6
7
8   PADARN NOTE 06/12/12: This quad tree has been
9   replaced by a C quad tree. Save the old code
10   somewhere?
11
12   PADARN NOTE: Most of the functionality of the
13   old quad tree has been emulated. However, some
14   methods inherrited from cell have not been. This
15   causes a few of the unit tests to fail, and thus
16   can easily be identified if it is felt the are
17   needed.
18
19"""
20
21from anuga.config import max_float
22
23from anuga.geometry.quad import Cell
24from anuga.geometry.aabb import AABB
25
26import numpy as num
27from anuga.utilities.numerical_tools import ensure_numeric
28import anuga.fit_interpolate.fitsmooth as fitsmooth
29
30
31# PADARN NOTE: I don't think much from Cell is used anymore, if
32# anything, this dependency could be removed.
33class MeshQuadtree(Cell):
34    """ A quadtree constructed from the given mesh.
35        This class is the root node of a quadtree,
36        and derives from a Cell.
37        It contains optimisations and search patterns specific to meshes.
38    """
39
40    def __init__(self, mesh, verbose=False):
41        """Build quad tree for mesh.
42
43        All vertex indices in the mesh are stored in a quadtree.
44        """
45        self.mesh = mesh
46
47        self.set_extents()
48        self.add_quad_tree()
49
50        Cell.__init__(self, self.extents, None)  # root has no parent
51
52
53    def __getstate__(self):
54        dic = self.__dict__
55        if (dic.has_key('root')):
56            dic.pop('root')
57        return dic
58
59    def set_extents(self):
60        extents = AABB(*self.mesh.get_extent(absolute=True))
61        extents.grow(1.001)  # To avoid round off error
62        numextents = [extents.xmin, extents.xmax, extents.ymin, extents.ymax]
63        self.extents = num.array(numextents, num.float)
64        #print self.extents
65
66    def add_quad_tree(self):
67
68        V = self.mesh.get_vertex_coordinates(absolute=True)
69       
70        self.set_extents()
71        #print self.extents
72        self.root = fitsmooth.build_quad_tree(self.mesh.triangles, V, self.extents)
73
74
75    # PADARN NOTE: This function does not properly emulate the old functionality -
76    # it seems uneeded though. Check this.
77    def search(self, point):
78        return self.search_fast(point)
79
80    # PADARN NOTE: Although this function emulates the functionality of the old
81    # quad tree, it cannot be called on the sub-trees anymore.
82    def count(self):
83        if not hasattr(self, 'root'):
84            self.add_quad_tree()
85        return fitsmooth.items_in_tree(self.root)
86
87    def search_fast(self, point):
88        """
89        Find the triangle (element) that the point x is in.
90
91        Does a coherent quadtree traversal to return a single triangle that the
92        point falls within. The traversal begins at the last triangle found.
93        If this fails, it checks the triangles beneath it in the tree, and then
94        begins traversing up through the tree until it reaches the root.
95
96        This results in performance which varies between constant time and O(n),
97        depending on the geometry.
98
99        Inputs:
100            point:    The point to test
101
102        Return:
103            element_found, sigma0, sigma1, sigma2, k
104
105            where
106            element_found: True if a triangle containing x was found
107            sigma0, sigma1, sigma2: The interpolated values
108            k: Index of triangle (if found)
109
110        """
111
112        # PADARN NOTE: Adding checks on the input point to make sure it is a float.
113
114        if not hasattr(self, 'root'):
115            self.add_quad_tree()
116
117        point = ensure_numeric(point, num.float)
118
119        [found, sigma, index] = fitsmooth.individual_tree_search(self.root, point)
120
121        if found == 1:
122            element_found = True
123        else:
124            element_found = False
125
126        return element_found, sigma[0], sigma[1], sigma[2], index
127
128    # PADARN NOTE: Only here to pass unit tests - does nothing.
129    def set_last_triangle(self):
130        pass
Note: See TracBrowser for help on using the repository browser.