Ejemplo n.º 1
0
    def topple_dissipate(self):
        """
        Forest burning and turning into ash. 
        
        :param p: probability of a new tree growh per empty cell, must be smaller than p
        :type p: float
        """

        #Displacement from a cell to its nearest neighbours

        # self.new_values[...] = self.values
        # A to T with small probability
        ash_here = self.values == _ash

        probabilities = np.random.random(size=(self.L_with_boundary,
                                               self.L_with_boundary))
        trees_grow_here = probabilities <= self.p

        self.new_values[common.clean_boundary_inplace(
            trees_grow_here & ash_here, self.BC)] = _tree
        # Trees start burning: T -> B
        self.new_values[self.values == _tree] = _tree
        burn_trees(self.new_values, self.values, self.f, self.BC)
        # B to A
        burning_here = self.values == _burning
        self.new_values[common.clean_boundary_inplace(burning_here,
                                                      self.BC)] = _ash

        self.values, self.new_values = self.new_values, self.values
        self.new_values[...] = 0
        number_burning = (self.values[self.BC:-self.BC,
                                      self.BC:-self.BC] == _burning).sum()
        return number_burning
Ejemplo n.º 2
0
    def topple_dissipate(self) -> int:
        """
        Forest burning and turning into ash. 
        """

        #Displacement from a cell to its nearest neighbours

        # self.new_values[...] = self.values
        # A to T with small probability
        ash_here = self.values == _ash

        probabilities = np.random.random(size=(self.L_with_boundary,
                                               self.L_with_boundary))
        trees_grow_here = probabilities <= self.p

        self.new_values[common.clean_boundary_inplace(
            trees_grow_here & ash_here, self.BC)] = _tree
        # Trees start burning: T -> B
        self.new_values[self.values == _tree] = _tree
        burn_trees(self.new_values, self.values, self.f, self.BC)
        # B to A
        burning_here = self.values == _burning
        self.new_values[common.clean_boundary_inplace(burning_here,
                                                      self.BC)] = _ash

        self.values, self.new_values = self.new_values, self.values
        self.new_values[...] = 0
        number_burning = (self.inside(self.values) == _burning).sum()
        return number_burning
Ejemplo n.º 3
0
def topple(values: np.ndarray, visited: np.ndarray, releases: np.ndarray,
           critical_value_current: float, critical_value: float,
           conservation_lvl: float, boundary_size: int) -> int:
    """
    Distribute material from overloaded sites to neighbors.

    Returns True/False: should we continue checking if something needs toppling?

    :param values: data array of the simulation
    :type values: np.ndarray
    :param visited: boolean array, needs to be cleaned beforehand
    :type visited: np.ndarray
    :param critical_value: nodes topple above this value
    :type critical_value: float
    # 0.25 -> full force distributed
    :param conservation_lvl: 0.25 by default - fraction of the force from a toppling site going to its neighbour
    :type conservation_lvl: float
    :param boundary_size: size of boundary for the array
    :type boundary_size: int
    :rtype: int
    """

    # find a boolean array of active (overloaded) sites

    active_sites = common.clean_boundary_inplace(
        values >= critical_value_current, boundary_size)
    number_of_iterations = 0

    while active_sites.any():

        releases += active_sites
        indices = np.vstack(np.where(active_sites)).T
        # a Nx2 array of integer indices for overloaded sites
        N = indices.shape[0]
        for i in range(N):
            x, y = index = indices[i]
            if _DEBUG:
                width, height = values.shape
                assert boundary_size <= x < width
                assert boundary_size <= y < width
            neighbors = index + np.array([[0, 1], [-1, 0], [1, 0], [0, -1]])
            # TODO crack model nie wraca do sąsiadów, którzy już releasowali energię
            for j in range(len(neighbors)):
                xn, yn = neighbors[j]
                values[xn, yn] += conservation_lvl * (
                    values[x, y] - critical_value_current + critical_value
                )  # Grassberger (1994), eqns (1)
                visited[xn, yn] = True

            values[
                x,
                y] = critical_value_current - critical_value  # Grassberger (1994), eqns (1)
            active_sites = common.clean_boundary_inplace(
                values >= critical_value_current, boundary_size)
        number_of_iterations += 1

    return number_of_iterations
Ejemplo n.º 4
0
def topple(values: np.ndarray, visited: np.ndarray, releases: np.ndarray,
           critical_value: int, boundary_size: int) -> int:
    """
    Distribute material from overloaded sites to neighbors.

    Returns True/False: should we continue checking if something needs toppling?

    :param values: data array of the simulation
    :type values: np.ndarray
    :param visited: boolean array, needs to be cleaned beforehand
    :type visited: np.ndarray
    :param releases: boolean array, used to evalute number of sandpiles activations
    :type releases: np.ndarray
    :param critical_value: nodes topple above this value
    :type critical_value: int
    :param boundary_size: size of boundary for the array
    :type boundary_size: int
    :rtype: int
    """

    # find a boolean array of active (overloaded) sites
    number_of_iterations = 0
    active_sites = common.clean_boundary_inplace(values > critical_value,
                                                 boundary_size)

    while active_sites.any():
        releases += active_sites

        indices = np.vstack(np.where(active_sites)).T
        # a Nx2 array of integer indices for overloaded sites

        N = indices.shape[0]
        for i in range(N):
            x, y = indices[i]
            values[x, y] -= critical_value + 1

            neighbors = np.array([(x - 1, y), (x, y - 1), (x + 1, y),
                                  (x, y + 1)])
            # TODO try moving update: here visited[x, y] = True

            for j in range(len(neighbors)):
                xn, yn = neighbors[j]
                values[xn, yn] += 1
                visited[xn, yn] = True

        number_of_iterations += 1

        active_sites = common.clean_boundary_inplace(values > critical_value,
                                                     boundary_size)

    return number_of_iterations
Ejemplo n.º 5
0
 def __init__(self, p: float = 0.05, f: float = 0, *args, **kwargs):
     super().__init__(*args, **kwargs)
     shape = (self.L_with_boundary, self.L_with_boundary)
     self.values = common.clean_boundary_inplace(
         np.random.choice([_ash, _tree, _burning], shape, p=[0.99, 0.01,
                                                             0]), self.BC)
     self.new_values = np.zeros_like(self.values)
     self.p = p
     self.f = f
Ejemplo n.º 6
0
def topple(values: np.ndarray, visited: np.ndarray, critical_value: int,
           boundary_size: int) -> bool:
    """
    Distribute material from overloaded sites to neighbors.

    Returns True/False: should we continue checking if something needs toppling?

    :param values: data array of the simulation
    :type values: np.ndarray
    :param visited: boolean array, needs to be cleaned beforehand
    :type visited: np.ndarray
    :param critical_value: nodes topple above this value
    :type critical_value: int
    :param boundary_size: size of boundary for the array
    :type boundary_size: int
    :rtype: bool
    """

    # find a boolean array of active (overloaded) sites
    active_sites = common.clean_boundary_inplace(values > critical_value,
                                                 boundary_size)

    if active_sites.any():
        indices = np.vstack(np.where(active_sites)).T
        # a Nx2 array of integer indices for overloaded sites
        N = indices.shape[0]

        for i in range(N):
            x, y = index = indices[i]

            if _DEBUG:
                width, height = values.shape
                assert boundary_size <= x < width
                assert boundary_size <= y < width
                assert values[x, y] >= 0

            values[x, y] -= 2

            # randomly and independently pick two neighbors of the current site
            neighbors = index + np.random.choice(
                np.array((-1, 1)),  # ugly but numba broke otherwise
                size=(2, 2))

            for j in range(2):
                xn, yn = neighbors[j]
                values[xn, yn] += 1
                visited[xn, yn] = True
        return True
    else:
        return False  # nothing happened, we can stop toppling
Ejemplo n.º 7
0
    def __init__(self, p=0.05, f: float = 0, *args, **kwargs):
        """
        :param f: probability of thunder setting a tree on fire; set 0 to disable lighting
        """

        super().__init__(*args, **kwargs)
        self.values = np.zeros((self.L_with_boundary, self.L_with_boundary),
                               dtype=int)
        # probabilities = np.random.random(size=(self.L, self.L))
        # trees_here = probabilities <= p
        # self.values[self.BC:self.L_with_boundary - self.BC,
        #             self.BC:self.L_with_boundary - self.BC,
        #             ][trees_here] = _tree
        self.values = common.clean_boundary_inplace(
            np.random.choice([_ash, _tree, _burning],
                             self.values.shape,
                             p=[0.99, 0.01, 0]), self.BC)
        self.new_values = np.zeros_like(self.values)
        self.p = p
        self.f = f
Ejemplo n.º 8
0
def topple_dissipate(values: np.ndarray, visited: np.ndarray,
                     critical_value: int, abelian: bool,
                     boundary_size: int) -> int:
    """
    Distribute material from overloaded sites to neighbors.

    Returns True/False: should we continue checking if something needs toppling?

    :param values: data array of the simulation
    :type values: np.ndarray
    :param visited: boolean array, needs to be cleaned beforehand
    :type visited: np.ndarray
    :param critical_value: nodes topple above this value
    :type critical_value: int
    :param abelian: True by default - abelian, False - nonabelian
    :type abelian: bool
    :param boundary_size: size of boundary for the array
    :type boundary_size: int
    :return: Number of steps it took stuff to topple
    :rtype: int
    """

    number_of_topple_iterations = 0
    # find a boolean array of active (overloaded) sites
    active_sites = common.clean_boundary_inplace(
        values > critical_value, boundary_size)  # TODO speedup?
    # odrzucam

    while active_sites.any():  # TODO speedup?
        indices = np.vstack(np.where(active_sites)).T  # TODO speedup?
        # a Nx2 array of integer indices for overloaded sites
        N = indices.shape[0]

        for i in range(N):
            x, y = index = indices[i]

            if _DEBUG:
                width, height = values.shape
                assert boundary_size <= x < width
                assert boundary_size <= y < width
                assert values[x, y] >= 0

            if abelian:
                n_to_distribute = 2  # number of particles to distribute from the active site
                values[x, y] -= n_to_distribute
            else:
                n_to_distribute = values[x, y]
                values[x, y] = 0

            # randomly and independently pick neighbors of the current site
            neighbors = index + np.random.choice(
                np.array((-1, 1)),  # ugly but numba broke otherwise
                size=(n_to_distribute, 2))  # TODO speedup?
            # to byśmy podmieniali gdybyśmy zmieniali model najbliższych sąsiadów

            for j in range(len(neighbors)):
                xn, yn = neighbors[j]
                values[xn, yn] += 1
                visited[xn, yn] = True

        number_of_topple_iterations += 1
        active_sites = common.clean_boundary_inplace(values > critical_value,
                                                     boundary_size)
    # dissipate would be here, after the while loop
    # but it's not necessary so we skip it
    return number_of_topple_iterations