Ejemplo n.º 1
0
    def box_coordinates(self, origin, diameter):
        """
        Return the 8 coordinates of the box associated with the key.

        Let the unit cube be described as follows:

        [
            [0, 0, 0],
            [1, 0, 0],
            [0, 1, 0],
            [1, 1, 0],
            [0, 0, 1],
            [1, 0, 1],
            [0, 1, 1],
            [1, 1, 1]
         ]

        The function returns the box coordinates in the same order
        as the above unit cube coordinates.

        """
        coords = np.empty(24, dtype=np.float64)
        coords_data = ffi.from_buffer("double(*)[24]", coords)

        origin = np.array(origin, dtype=np.float64)
        origin_data = ffi.from_buffer("double(*)[3]", origin)
        diameter = np.array(diameter, dtype=np.float64)
        diameter_data = ffi.from_buffer("double(*)[3]", diameter)

        lib.morton_key_box_coordinates(self.ctype, origin_data, diameter_data,
                                       coords_data)

        return coords.reshape(8, 3)
Ejemplo n.º 2
0
    def from_point(cls, point, origin, diameter):
        """Create a Morton key from a point at the deepest level."""
        point = np.array(point, dtype=np.float64)
        point_data = ffi.from_buffer("double(*)[3]", point)

        origin = np.array(origin, dtype=np.float64)
        origin_data = ffi.from_buffer("double(*)[3]", origin)

        diameter = np.array(diameter, dtype=np.float64)
        diameter_data = ffi.from_buffer("double(*)[3]", diameter)

        return cls(
            lib.morton_key_from_point(point_data, origin_data, diameter_data))
Ejemplo n.º 3
0
    def to_coordinates(self, origin, diameter):
        """Return the coordinates of the anchor."""
        coords = np.empty(3, dtype=np.float64)
        coords_data = ffi.from_buffer("double(*)[3]", coords)
        origin = np.array(origin, dtype=np.float64)
        origin_data = ffi.from_buffer("double(*)[3]", origin)
        diameter = np.array(diameter, dtype=np.float64)
        diameter_data = ffi.from_buffer("double(*)[3]", diameter)

        lib.morton_key_to_coordinates(self.ctype, origin_data, diameter_data,
                                      coords_data)

        return coords
Ejemplo n.º 4
0
    def from_global_points(cls, points, balanced, comm):
        """
        Construct a distributed tree from a set of globally distributed points.

        Params:
        ------
        points : np.array(shape=(n_points, 3), dtype=np.float64)
            Cartesian points at this processor.
        balanced : bool
            If 'True' constructs a balanced tree, if 'False' constructs an unbalanced tree.
        comm : Intracomm
           An mpi4py Intracommunicator.
        """
        points = np.array(points, dtype=np.float64, order="C", copy=False)
        npoints, _ = points.shape
        points_data = ffi.from_buffer(f"double(*)[3]", points)
        balanced_data = ffi.cast("bool", np.bool(balanced))
        npoints_data = ffi.cast("size_t", npoints)
        p_comm = MPI._addressof(comm)
        raw_comm = ffi.cast("uintptr_t*", p_comm)

        return cls(
            lib.distributed_tree_from_points(points_data, npoints_data,
                                             balanced_data, raw_comm),
            comm,
            p_comm,
            raw_comm,
        )
Ejemplo n.º 5
0
    def find_key_in_direction(self, direction):
        """
        Find a key in a given direction.

        Given an integer list `direction` containing
        3 elements, return the key obtained by moving
        from the current key `direction[j]` steps along
        dimension [j]. For example, if `direction = [2, -1, 1]`
        the method returns the key by moving two boxes in positive
        x-direction, one box in the negative y direction and one box
        in the positive z direction. Boxes are counted with respect to
        the current level.

        If there is no box in the given direction, i.e. the new coordinates
        are out of bounds, the method retunrs None.

        """

        direction = np.array(direction, dtype=np.int64)
        direction_data = ffi.from_buffer("int64_t(*)[3]", direction)

        ptr = lib.morton_key_key_in_direction(self.ctype, direction_data)

        if ptr == ffi.NULL:
            return None
        else:
            return MortonKey(ptr)
Ejemplo n.º 6
0
 def children(self):
     """Return the children."""
     ptr = np.empty(8, dtype=np.uint64)
     ptr_data = ffi.from_buffer("uintptr_t *", ptr)
     lib.morton_key_children(self.ctype, ptr_data)
     children = [
         MortonKey(ffi.cast("MortonKey *", ptr[index]))
         for index in range(8)
     ]
     return children
Ejemplo n.º 7
0
 def _clone(self, start, stop):
     """Clone a slice of the exposed Vec<T> into a Python datatype."""
     n = ffi.cast("size_t", len(self))
     nslice = stop - start
     start = ffi.cast("size_t", start)
     stop = ffi.cast("size_t", stop)
     ptr = np.empty(nslice, dtype=np.uint64)
     ptr_data = ffi.from_buffer("uintptr_t *", ptr)
     self._iterator_protocol.clone(self._head, ptr_data, n, start, stop)
     return [
         self._iterator_protocol.p_type(
             ffi.cast(f"{self._iterator_protocol.c_name} *", ptr[index])
         )
         for index in range(nslice)
     ]
Ejemplo n.º 8
0
 def from_global_points(cls, points, comm):
     points = np.array(points, dtype=np.float64, order="C")
     npoints, _ = points.shape
     points_data = ffi.from_buffer(f"double(*)[3]", points)
     n_points_data = ffi.cast("size_t", npoints)
     return cls(lib.domain_from_global_points(points_data, npoints, comm))
Ejemplo n.º 9
0
 def from_anchor(cls, anchor):
     """Create a Morton key from a given anchor."""
     anchor = np.array(anchor, dtype=np.uint64)
     data = ffi.from_buffer("uint64_t(*)[3]", anchor)
     return cls(lib.morton_key_from_anchor(data))