Esempio n. 1
0
def generate_input_rates(module_field_width_dict,
                         basis_function='gaussian',
                         spacing_factor=1.0,
                         peak_rate=1.):
    input_nodes_dict = {}
    input_groups_dict = {}
    input_rates_dict = {}

    for m in module_field_width_dict:
        nodes, groups, _ = poisson_disc_nodes(module_field_width_dict[m],
                                              (vert, smp))
        input_groups_dict[m] = groups
        input_nodes_dict[m] = nodes
        input_rates_dict[m] = {}

        for i in range(nodes.shape[0]):
            xs = [[nodes[i, 0], nodes[i, 1]]]
            x_obs = np.asarray(xs).reshape((1, -1))
            u_obs = np.asarray([[peak_rate]]).reshape((1, -1))
            if basis_function == 'constant':
                input_rate_ip = lambda xx, yy: xx, yy
            else:
                input_rate_ip = Rbf(x_obs[:, 0],
                                    x_obs[:, 1],
                                    u_obs,
                                    function=basis_function,
                                    epsilon=module_field_width_dict[m] *
                                    spacing_factor)
            input_rates_dict[m][i] = input_rate_ip

    return input_nodes_dict, input_groups_dict, input_rates_dict
def generate_input_rates(spatial_domain,
                         module_field_width_dict,
                         basis_function='gaussian',
                         spacing_factor=1.0,
                         peak_rate=1.):
    input_nodes_dict = {}
    input_groups_dict = {}
    input_rates_dict = {}

    n_modules = len(module_field_width_dict)
    if isinstance(spacing_factor, float):
        spacing_factors = [spacing_factor] * n_modules
    else:
        spacing_factors = spacing_factor
    print(f"spacing factors: {spacing_factors}")
    if isinstance(peak_rate, float):
        peak_rates = [peak_rate] * n_modules
    else:
        peak_rates = peak_rate
    print(f"peak_rates: {peak_rates}")
    vert, smp = spatial_domain
    for m in sorted(module_field_width_dict):

        nodes, groups, _ = poisson_disc_nodes(module_field_width_dict[m],
                                              (vert, smp))
        print(
            f"Generated {nodes.shape[0]} nodes for field width {module_field_width_dict[m]}"
        )
        input_groups_dict[m] = groups
        input_nodes_dict[m] = nodes
        input_rates_dict[m] = {}

        for i in range(nodes.shape[0]):
            xs = [[nodes[i, 0], nodes[i, 1]]]
            x_obs = np.asarray(xs).reshape((1, -1))
            u_obs = np.asarray([[peak_rates[m]]]).reshape((1, -1))
            if basis_function == 'constant':
                input_rate_ip = lambda xx, yy: xx, yy
            else:
                input_rate_ip = Rbf(x_obs[:, 0],
                                    x_obs[:, 1],
                                    u_obs,
                                    function=basis_function,
                                    epsilon=module_field_width_dict[m] *
                                    spacing_factors[m])
            input_rates_dict[m][i] = input_rate_ip

    return input_nodes_dict, input_groups_dict, input_rates_dict
Esempio n. 3
0
# the hyperviscosity factor
nu = 1e-6
# whether to plot the eigenvalues for the state differentiation matrix. All the
# eigenvalues must have a negative real component for the time stepping to be
# stable
plot_eigs = False
# number of nodes used for each RBF-FD stencil
stencil_size = 50
# the polynomial order for generating the RBF-FD weights
order = 4
# the RBF used for generating the RBF-FD weights
phi = 'phs5'

# generate the nodes
nodes, groups, normals = poisson_disc_nodes(
    spacing, (vert, smp),
    boundary_groups={'all': range(len(smp))},
    boundary_groups_with_ghosts=['all'])
n = nodes.shape[0]

# We will solve the wave equation by numerically integrating the state vector
# `z`. The state vector is a concatenation of `u` and `v`. `u` is a (n,) array
# consisting of:
#
#     - the displacements at the interior at `u[groups['interior']]`
#     - the displacements at the boundary at `u[groups['boundary:all']]`
#     - the free boundary conditions at `u[groups['ghosts:all']]`
#
# `v` is a (n,) array and it is the time derivative of `u`

# create a new node group for convenience
groups['interior+boundary:all'] = np.hstack(
Esempio n. 4
0
def generate_random_trajectory(arena,
                               max_distance=None,
                               spacing=10.0,
                               temporal_resolution=1.,
                               velocity=30.,
                               equilibration_duration=None,
                               local_random=None,
                               n_trials=1):
    """
    Construct coordinate arrays for a spatial trajectory, considering run velocity to interpolate at the specified
    temporal resolution. Optionally, the trajectory can be prepended with extra distance traveled for a specified
    network equilibration time, with the intention that the user discards spikes generated during this period before
    analysis.

    :param trajectory: namedtuple
    :param temporal_resolution: float (s)
    :param equilibration_duration: float (s)
    :return: tuple of array
    """

    if local_random is None:
        local_random = np.random.RandomState(0)

    vert, smp = arena

    # generate the nodes. `nodes` is a (N, 2) float array, `groups` is a dict
    # identifying which group each node is in.
    nodes, groups, _ = poisson_disc_nodes(spacing, (vert, smp))
    N = nodes.shape[0]

    tri = Delaunay(nodes)
    G = nx.Graph()
    for path in tri.simplices:
        nx.add_path(G, path)

    # Choose a starting point
    path_distance = 0.
    path_nodes = []
    p = None
    s = local_random.choice(N)
    visited = deque(maxlen=5)
    while ((max_distance is None) or (path_distance < max_distance)):

        neighbors = list(G.neighbors(s))
        visited.append(s)
        path_nodes.append(s)
        if p is not None:
            path_distance = path_distance + euclidean_distance(
                nodes[s], nodes[p])
        p = s
        print(path_distance)

        candidates = [n for n in neighbors if n not in visited]
        if len(candidates) == 0:
            break
        else:
            selected = local_random.choice(len(candidates))
            s = candidates[selected]

    input_trajectory = nodes[path_nodes]

    trajectory_lst = []
    for i_trial in range(n_trials):
        trajectory_lst.append(input_trajectory)

    trajectory = np.concatenate(trajectory_lst)

    velocity = velocity  # (cm / s)
    spatial_resolution = velocity * temporal_resolution
    x = trajectory[:, 0]
    y = trajectory[:, 1]

    if equilibration_duration is not None:
        equilibration_distance = velocity / equilibration_duration
        x = np.insert(x, 0, x[0] - equilibration_distance)
        y = np.insert(y, 0, y[0])
    else:
        equilibration_duration = 0.
        equilibration_distance = 0.

    segment_lengths = np.sqrt((np.diff(x)**2. + np.diff(y)**2.))
    distance = np.insert(np.cumsum(segment_lengths), 0, 0.)

    interp_distance = np.arange(distance.min(),
                                distance.max() + spatial_resolution / 2.,
                                spatial_resolution)
    interp_x = np.interp(interp_distance, distance, x)
    interp_y = np.interp(interp_distance, distance, y)
    t = interp_distance / velocity  # s

    t = np.subtract(t, equilibration_duration)
    interp_distance -= equilibration_distance

    return t, interp_x, interp_y, interp_distance
Esempio n. 5
0
# size of RBF-FD stencils
n = 30
# lame parameters
lamb = 1.0
mu = 1.0
# z component of body for
body_force = 1.0

## Build and solve for displacements and strain
#####################################################################
# generate nodes. The nodes are assigned groups based on which simplex
# they lay on
boundary_groups = {'fixed':[0],
                   'free':[1, 2, 3]}
nodes, groups, normals = poisson_disc_nodes(
  dx, (vert, smp),
  boundary_groups=boundary_groups,
  boundary_groups_with_ghosts=['free'])
# `nodes` : (N, 2) float array
# `groups` : dictionary containing index sets. It has the keys
#            "interior", "boundary:free", "boundary:fixed",
#            "ghosts:free".
# `normals : (N, 2) float array

## Create the sparse submatrices for the system matrix 
N = nodes.shape[0]
G_xx = sp.coo_matrix((N, N))
G_xy = sp.coo_matrix((N, N))
G_yx = sp.coo_matrix((N, N))
G_yy = sp.coo_matrix((N, N))

## Enforce the PDE on interior nodes AND the free surface nodes 
Esempio n. 6
0
from rbf.pde.geometry import contains
from rbf.pde.nodes import poisson_disc_nodes
import matplotlib.pyplot as plt

# Define the problem domain with line segments.
vert = np.array([[0.0, 0.0], [2.0, 0.0], [2.0, 1.0], [1.0, 1.0], [1.0, 2.0],
                 [0.0, 2.0]])
smp = np.array([[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 0]])

spacing = 0.07  # approximate spacing between nodes

eps = 0.3 / spacing  # shape parameter

# generate the nodes. `nodes` is a (N, 2) float array, `groups` is a dict
# identifying which group each node is in
nodes, groups, _ = poisson_disc_nodes(spacing, (vert, smp))
N = nodes.shape[0]

# create "left hand side" matrix
A = np.empty((N, N))
A[groups['interior']] = mq(nodes[groups['interior']],
                           nodes,
                           eps=eps,
                           diff=[2, 0])
A[groups['interior']] += mq(nodes[groups['interior']],
                            nodes,
                            eps=eps,
                            diff=[0, 2])
A[groups['boundary:all']] = mq(nodes[groups['boundary:all']], nodes, eps=eps)

# create "right hand side" vector
Esempio n. 7
0
File: fd.m.py Progetto: NelisW/RBF
simplices = np.array([[0, 1], [1, 2], [2, 3], [3, 0], [4, 5], [5, 6], [6, 7],
                      [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13],
                      [13, 14], [14, 15], [15, 16], [16, 17], [17, 18],
                      [18, 19], [19, 4]])

boundary_groups = {
    'box': [0, 1, 2, 3],
    'circle': [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
}

# Generate the nodes. `groups` identifies which group each node belongs to.
# `normals` contains the normal vectors corresponding to each node (nan if the
# node is not on a boundary). We are giving the circle boundary nodes ghost
# nodes to improve the accuracy of the free boundary constraint.
nodes, groups, normals = poisson_disc_nodes(
    node_spacing, (vertices, simplices),
    boundary_groups=boundary_groups,
    boundary_groups_with_ghosts=['circle'])

# Create the LHS and RHS enforcing that the Lapacian is -5 at the interior
# nodes
A_interior = weight_matrix(nodes[groups['interior']],
                           nodes,
                           stencil_size, [[2, 0], [0, 2]],
                           phi=radial_basis_function,
                           order=polynomial_order)

b_interior = np.full(len(groups['interior']), -5.0)

# Enforce that the solution is x at the box boundary nodes.
A_boundary_box = weight_matrix(nodes[groups['boundary:box']],
                               nodes,