示例#1
0
  out2 : (N,2) float array
    Array of normalized vectors that are orthogonal to the 
    corresponding vectors in *n* and in *out1*
    
  '''
  out1 = np.empty_like(n,dtype=float)
  out1[:,0] = -np.sum(n,axis=1) + n[:,0]
  out1[:,1:] = n[:,[0]] 
  out1 /= np.linalg.norm(out1,axis=1)[:,None] # normalize length
  out2 = np.cross(n,out1) # find vectors that are orthogonal to *n* and *out1*
  out2 /= np.linalg.norm(out2,axis=1)[:,None] # normalize length
  return out1,out2

# generate nodes. Note that this may take a while
nodes,smpid = menodes(N,vert,smp,rho=density_func,itr=50)
# find which nodes are attached to each simplex
int_idx = np.nonzero(smpid == -1)[0].tolist()
roller_idx = np.nonzero((smpid >= 0) & (smpid <= 9))[0].tolist()
free_idx = np.nonzero(smpid > 9)[0].tolist()
# find normal vectors to each free surface node
simplex_normals = simplex_outward_normals(vert,smp)
free_normals = simplex_normals[smpid[free_idx]]
# find the normal vectors to each roller node
roller_normals = simplex_normals[smpid[roller_idx]]
# find two orthogonal vectors that are parallel to the surface at each 
# roller node. This is used to determine the directions along which 
# traction forces will be constrained. Note that any two orthogonal 
# vectors that are parallel to the surface would do.
roller_parallels1,roller_parallels2 = find_orthogonals(roller_normals)
# add ghost nodes next to free and roller nodes
示例#2
0
文件: laplacian.py 项目: xtoof/RBF
# symbolic definition of the solution
x, y = sympy.symbols('x,y')
r = sympy.sqrt(x**2 + y**2)
true_soln_sym = (1 - r) * sympy.sin(x) * sympy.cos(y)
# numerical solution
true_soln = sympy.lambdify((x, y), true_soln_sym, 'numpy')

# symbolic forcing term
forcing_sym = true_soln_sym.diff(x, x) + true_soln_sym.diff(y, y)
# numerical forcing term
forcing = sympy.lambdify((x, y), forcing_sym, 'numpy')

# define a circular domain
vert, smp = rbf.domain.circle()

nodes, smpid = menodes(N, vert, smp)
# smpid describes which boundary simplex, if any, the nodes are
# attached to. If it is -1, then the node is in the interior
boundary, = (smpid >= 0).nonzero()
interior, = (smpid == -1).nonzero()

# create the left-hand-side matrix which is the Laplacian of the basis
# function for interior nodes and the undifferentiated basis functions
# for the boundary nodes. The third argument to weight_matrix
# describes the derivates order for each spatial dimension
A = scipy.sparse.lil_matrix((N, N))
A[interior, :] = weight_matrix(nodes[interior], nodes, [[2, 0], [0, 2]])
A[boundary, :] = weight_matrix(nodes[boundary], nodes, [0, 0])
# convert A to a csr matrix for efficient solving
A = A.tocsr()
示例#3
0
from rbf.nodes import menodes
import matplotlib.pyplot as plt

# define the problem domain
vert = np.array([[0.762,0.057],[0.492,0.247],[0.225,0.06 ],[0.206,0.056],
                 [0.204,0.075],[0.292,0.398],[0.043,0.609],[0.036,0.624],
                 [0.052,0.629],[0.373,0.63 ],[0.479,0.953],[0.49 ,0.966],
                 [0.503,0.952],[0.611,0.629],[0.934,0.628],[0.95 ,0.622],
                 [0.941,0.607],[0.692,0.397],[0.781,0.072],[0.779,0.055]])

smp = np.array([[0,1],[1,2],[2,3],[3,4],[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,0]])

N = 500 # total number of nodes
nodes,smpid = menodes(N,vert,smp) # generate nodes
boundary, = (smpid>=0).nonzero() # identify boundary nodes
interior, = (smpid==-1).nonzero() # identify interior nodes

# create left-hand-side matrix and right-hand-side vector
A = np.empty((N,N))
A[interior]  = phs3(nodes[interior],nodes,diff=[2,0])
A[interior] += phs3(nodes[interior],nodes,diff=[0,2])
A[boundary,:] = phs3(nodes[boundary],nodes)
d = np.empty(N)
d[interior] = -100.0
d[boundary] = 0.0

# Solve the PDE
coeff = np.linalg.solve(A,d) # solve for the RBF coefficients
itp = menodes(10000,vert,smp)[0] # interpolation points
示例#4
0
import numpy as np
from rbf.fd import weight_matrix
from rbf.nodes import menodes, neighbors
from rbf.geometry import contains, simplex_outward_normals
import matplotlib.pyplot as plt
from scipy.integrate import ode
from scipy.interpolate import griddata
from scipy.sparse.linalg import spsolve

# define the problem domain
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]])
times = np.linspace(0.0, 2.0, 5)  # output times
N = 50000  # total number of nodes
nodes, smpid = menodes(N, vert, smp)  # generate nodes
interior = np.nonzero(smpid == -1)[0].tolist()  # identify boundary nodes
boundary = np.nonzero(smpid >= 0)[0].tolist()  # identify boundary nodes
# calculate surface normal vector for each boundary node
normals = simplex_outward_normals(vert, smp)[smpid[boundary]]
# dx is the shortest distance between any two nodes
dx = np.min(neighbors(nodes, 2)[1][:, 1])
# add ghost nodes to greatly improve accuracy at the free surface
nodes = np.vstack((nodes, nodes[boundary] + 0.5 * dx * normals))
ghost = range(N, N + len(boundary))  # ghost node indices
# create differentiation matrices for the interior and boundary nodes
D = weight_matrix(nodes[interior + boundary], nodes, [(2, 0), (0, 2)], n=30)
dD = weight_matrix(nodes[boundary],
                   nodes, [(1, 0), (0, 1)],
                   coeffs=normals.T,
                   n=30)
示例#5
0
# symbolic definition of the solution
x,y = sympy.symbols('x,y')
r = sympy.sqrt(x**2 + y**2)
true_soln_sym = (1-r)*sympy.sin(x)*sympy.cos(y)
# numerical solution
true_soln = sympy.lambdify((x,y),true_soln_sym,'numpy')

# symbolic forcing term
forcing_sym = true_soln_sym.diff(x,x) + true_soln_sym.diff(y,y)
# numerical forcing term
forcing = sympy.lambdify((x,y),forcing_sym,'numpy')

# define a circular domain
vert,smp = rbf.domain.circle()

nodes,smpid = menodes(N,vert,smp)
# smpid describes which boundary simplex, if any, the nodes are 
# attached to. If it is -1, then the node is in the interior
boundary, = (smpid>=0).nonzero()
interior, = (smpid==-1).nonzero()

# create the left-hand-side matrix which is the Laplacian of the basis 
# function for interior nodes and the undifferentiated basis functions 
# for the boundary nodes. The third argument to weight_matrix 
# describes the derivates order for each spatial dimension
A = scipy.sparse.lil_matrix((N,N))
A[interior,:]  = weight_matrix(nodes[interior],nodes,[[2,0],[0,2]])
A[boundary,:]  = weight_matrix(nodes[boundary],nodes,[0,0])
# convert A to a csr matrix for efficient solving
A = A.tocsr()
示例#6
0
文件: ghosts.py 项目: treverhines/RBF
# number of nodes
N = 200

# define the vertices and simplices for cut annulus
t = np.linspace(gap,2*np.pi,100)
vert_outer = np.array([2*np.cos(t),2*np.sin(t)]).T
vert_inner = np.array([np.cos(t[::-1]),np.sin(t[::-1])]).T
vert = np.vstack((vert_outer,vert_inner))
smp = np.array([np.arange(200),np.roll(np.arange(200),-1)]).T



# setting bound_force=True ensures that the edges where the annulus is 
# cut will have an appropriate number of boundary nodes. This also 
# makes the function considerably slower
nodes,smpid = menodes(N,vert,smp,bound_force=True)

# identify nodes associated with the different boundary types
slit_top, = (smpid==199).nonzero()
slit_bot, = (smpid==99).nonzero()
# edges of the annulus minus the cut
boundary, = ((smpid>=0) & (smpid!=199) & (smpid!=99)).nonzero()
interior, = (smpid==-1).nonzero()

# add ghost nodes
ghost_nodes = make_ghost_nodes(nodes,smpid,boundary,vert,smp)
nodes = np.vstack((nodes,ghost_nodes))
# ghost node indices
ghost = N + np.arange(len(boundary))

# do not build stencils which cross this line
示例#7
0
# symbolic definition of the solution
x, y = sympy.symbols('x,y')
r = sympy.sqrt(x**2 + y**2)
true_soln_sym = (1 - r) * sympy.sin(x) * sympy.cos(y)
# numerical solution
true_soln = sympy.lambdify((x, y), true_soln_sym, 'numpy')

# symbolic forcing term
forcing_sym = true_soln_sym.diff(x, x) + true_soln_sym.diff(y, y)
# numerical forcing term
forcing = sympy.lambdify((x, y), forcing_sym, 'numpy')

# define a circular domain
vert, smp = rbf.domain.circle()

nodes, smpid = menodes(N, vert, smp)
# smpid describes which boundary simplex, if any, the nodes are
# attached to. If it is -1, then the node is in the interior
boundary, = (smpid >= 0).nonzero()
interior, = (smpid == -1).nonzero()

# create the left-hand-side matrix which is the Laplacian of the basis
# function for interior nodes and the undifferentiated basis functions
# for the boundary nodes
A = np.zeros((N, N))
A[interior] = basis(nodes[interior], nodes, diff=[2, 0])
A[interior] += basis(nodes[interior], nodes, diff=[0, 2])
A[boundary, :] = basis(nodes[boundary], nodes)

# create the right-hand-side vector, consisting of the forcing term
# for the interior nodes and zeros for the boundary nodes
示例#8
0

# number of nodes
N = 200

# define the vertices and simplices for cut annulus
t = np.linspace(gap, 2 * np.pi, 100)
vert_outer = np.array([2 * np.cos(t), 2 * np.sin(t)]).T
vert_inner = np.array([np.cos(t[::-1]), np.sin(t[::-1])]).T
vert = np.vstack((vert_outer, vert_inner))
smp = np.array([np.arange(200), np.roll(np.arange(200), -1)]).T

# setting bound_force=True ensures that the edges where the annulus is
# cut will have an appropriate number of boundary nodes. This also
# makes the function considerably slower
nodes, smpid = menodes(N, vert, smp, bound_force=True)

# identify nodes associated with the different boundary types
slit_top, = (smpid == 199).nonzero()
slit_bot, = (smpid == 99).nonzero()
# edges of the annulus minus the cut
boundary, = ((smpid >= 0) & (smpid != 199) & (smpid != 99)).nonzero()
interior, = (smpid == -1).nonzero()

# do not build stencils which cross this line
bnd_vert = np.array([[0.0, 0.0],
                     [10 * np.cos(gap / 2.0), 10 * np.sin(gap / 2.0)]])
bnd_smp = np.array([[0, 1]])
weight_kwargs = {'vert': bnd_vert, 'smp': bnd_smp, 'n': 20}
# build lhs
# enforce laplacian on interior nodes
示例#9
0
文件: laplacian.py 项目: xtoof/RBF
# symbolic definition of the solution
x,y,z = sympy.symbols('x,y,z')
r = sympy.sqrt(x**2 + y**2 + z**2)
true_soln_sym = (1-r)*sympy.sin(x)*sympy.cos(y)*sympy.cos(z)
# numerical solution
true_soln = sympy.lambdify((x,y,z),true_soln_sym,'numpy')

# symbolic forcing term
forcing_sym = true_soln_sym.diff(x,x) + true_soln_sym.diff(y,y) + true_soln_sym.diff(z,z)
# numerical forcing term
forcing = sympy.lambdify((x,y,z),forcing_sym,'numpy')

# smpid describes which boundary simplex, if any, the nodes are 
# attached to. If it is -1, then the node is in the interior
vert,smp = rbf.domain.sphere()
nodes,smpid = menodes(N,vert,smp,itr=10)
interior, = np.nonzero(smpid==-1)
boundary, = np.nonzero(smpid>=0)

# create the left-hand-side matrix which is the Laplacian of the basis 
# function for interior nodes and the undifferentiated basis functions 
# for the boundary nodes. The third argument to weight_matrix 
# describes the derivates order for each spatial dimension
A = scipy.sparse.lil_matrix((N,N))
A[interior,:]  = weight_matrix(nodes[interior],nodes,[[2,0,0],[0,2,0],[0,0,2]])
A[boundary,:]  = weight_matrix(nodes[boundary],nodes,[0,0,0])
# convert A to a csr matrix for efficient solving
A = A.tocsr()

# create the right-hand-side vector, consisting of the forcing term 
# for the interior nodes and zeros for the boundary nodes
示例#10
0
from rbf.nodes import menodes
import matplotlib.pyplot as plt

# define the problem domain
vert = np.array([[0.762,0.057],[0.492,0.247],[0.225,0.06 ],[0.206,0.056],
                 [0.204,0.075],[0.292,0.398],[0.043,0.609],[0.036,0.624],
                 [0.052,0.629],[0.373,0.63 ],[0.479,0.953],[0.49 ,0.966],
                 [0.503,0.952],[0.611,0.629],[0.934,0.628],[0.95 ,0.622],
                 [0.941,0.607],[0.692,0.397],[0.781,0.072],[0.779,0.055]])

smp = np.array([[0,1],[1,2],[2,3],[3,4],[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,0]])

N = 500 # total number of nodes
nodes,smpid = menodes(N,vert,smp) # generate nodes
boundary, = (smpid>=0).nonzero() # identify boundary nodes
interior, = (smpid==-1).nonzero() # identify interior nodes

# create left-hand-side matrix and right-hand-side vector
A = np.empty((N,N))
A[interior]  = phs3(nodes[interior],nodes,diff=[2,0]) 
A[interior] += phs3(nodes[interior],nodes,diff=[0,2]) 
A[boundary,:] = phs3(nodes[boundary],nodes)
d = np.empty(N)
d[interior] = -100.0
d[boundary] = 0.0

# Solve the PDE
coeff = np.linalg.solve(A,d) # solve for the RBF coefficients
itp = menodes(10000,vert,smp)[0] # interpolation points
示例#11
0
from rbf.nodes import menodes

# 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]])

# define a node density function. It takes an (N,D) array of positions
# and returns an (N,) array of normalized densities between 0 and 1
def rho(x):
  r = np.sqrt((x[:,0] - 1.0)**2 + (x[:,1] - 1.0)**2)
  return 0.1 + 0.9/((r/0.25)**4 + 1.0)

N = 1000 # total number of nodes

nodes,smpid = menodes(N,vert,smp,rho=rho)
# identify boundary and interior nodes
interior = smpid == -1
boundary = smpid >  -1

fig,ax = plt.subplots(figsize=(6,6))
# plot the domain
for s in smp: ax.plot(vert[s,0],vert[s,1],'k-')
ax.plot(nodes[interior,0],nodes[interior,1],'k.')
ax.plot(nodes[boundary,0],nodes[boundary,1],'b.')
ax.set_aspect('equal')
fig.tight_layout()
plt.savefig('../figures/nodes.a.png')
plt.show()

示例#12
0
# symbolic definition of the solution
x,y = sympy.symbols('x,y')
r = sympy.sqrt(x**2 + y**2)
true_soln_sym = (1-r)*sympy.sin(x)*sympy.cos(y)
# numerical solution
true_soln = sympy.lambdify((x,y),true_soln_sym,'numpy')

# symbolic forcing term
forcing_sym = true_soln_sym.diff(x,x) + true_soln_sym.diff(y,y)
# numerical forcing term
forcing = sympy.lambdify((x,y),forcing_sym,'numpy')

# define a circular domain
vert,smp = rbf.domain.circle()

nodes,smpid = menodes(N,vert,smp)
# smpid describes which boundary simplex, if any, the nodes are 
# attached to. If it is -1, then the node is in the interior
boundary, = (smpid>=0).nonzero()
interior, = (smpid==-1).nonzero()

# create the left-hand-side matrix which is the Laplacian of the basis 
# function for interior nodes and the undifferentiated basis functions 
# for the boundary nodes
A = np.zeros((N,N))
A[interior]  = basis(nodes[interior],nodes,diff=[2,0]) 
A[interior] += basis(nodes[interior],nodes,diff=[0,2]) 
A[boundary,:] = basis(nodes[boundary],nodes)

# create the right-hand-side vector, consisting of the forcing term 
# for the interior nodes and zeros for the boundary nodes
示例#13
0
文件: fd.a.py 项目: treverhines/RBF
from rbf.fd import weight_matrix
from rbf.nodes import menodes
import matplotlib.pyplot as plt

# define the problem domain
vert = np.array([[0.762,0.057],[0.492,0.247],[0.225,0.06 ],[0.206,0.056],
                 [0.204,0.075],[0.292,0.398],[0.043,0.609],[0.036,0.624],
                 [0.052,0.629],[0.373,0.63 ],[0.479,0.953],[0.49 ,0.966],
                 [0.503,0.952],[0.611,0.629],[0.934,0.628],[0.95 ,0.622],
                 [0.941,0.607],[0.692,0.397],[0.781,0.072],[0.779,0.055]])
smp = np.array([[0,1],[1,2],[2,3],[3,4],[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,0]])
dt = 0.000025 # time step size
N = 100000 # total number of nodes
nodes,smpid = menodes(N,vert,smp) # generate nodes
boundary, = (smpid>=0).nonzero() # identify boundary nodes
interior, = (smpid==-1).nonzero() # identify interior nodes
D = weight_matrix(nodes[interior],nodes,[[2,0],[0,2]],n=30)
r = np.linalg.norm(nodes-np.array([0.49,0.46]),axis=1)
u_prev = 1.0/(1 + (r/0.01)**4) # create initial conditions
u_curr = 1.0/(1 + (r/0.01)**4)
fig,axs = plt.subplots(2,2,figsize=(7,7))
axs = [axs[0][0],axs[0][1],axs[1][0],axs[1][1]]
for i in range(15001):
  u_next = dt**2*D.dot(u_curr) + 2*u_curr[interior] - u_prev[interior]
  u_prev[:] = u_curr
  u_curr[interior] = u_next
  if i in [0,5000,10000,15000]:  
    ax = axs[[0,5000,10000,15000].index(i)]
    p = ax.scatter(nodes[:,0],nodes[:,1],s=3,c=np.array(u_curr,copy=True),
示例#14
0
    
  Returns
  -------
  out : (N,2) float array
    Array of normalized vectors that are orthogonal to the 
    corresponding vector in *n*.
    
  '''
  out = np.empty_like(n,dtype=float)
  out[:,0] = -np.sum(n,axis=1) + n[:,0]
  out[:,1:] = n[:,[0]]
  out /= np.linalg.norm(out,axis=1)[:,None]
  return out

# generate nodes. Note that this may take a while
nodes,smpid = menodes(N,vert,smp,rho=node_density)
# roller nodes are on the bottom and sides of the domain
roller_idx = np.nonzero((smpid == 0) |
                        (smpid == 1) |
                        (smpid == 299))[0].tolist()
# free nodes are on the top of the domain
free_idx = np.nonzero(~((smpid == -1) |
                        (smpid == 0)  |
                        (smpid == 1)  |
                        (smpid == 299)))[0].tolist()
# interior nodes
int_idx = np.nonzero(smpid == -1)[0].tolist()
# find normal vectors for each simplex
simplex_normals = simplex_outward_normals(vert,smp)
# find normal vectors for each boundary node
roller_normals = simplex_normals[smpid[roller_idx]]
示例#15
0
文件: lenna.py 项目: treverhines/RBF
# make gray scale image
img = Image.open('Lenna.png')
imga = np.array(img,dtype=float)/256.0
gray = np.linalg.norm(imga,axis=-1)
# normalize so that the max value is 1
gray = gray/gray.max()

# define the node density function
def rho(p):
  # x and y are mapped to integers between 0 and 512
  p = p*512
  p = np.array(p,dtype=int)
  return 1.0001 - gray[511-p[:,1],p[:,0]]


nodes,smpid = menodes(N,vert,smp,rho=rho)
interior, = np.nonzero(smpid==-1)
boundary, = np.nonzero(smpid>=0)

### plot results
#####################################################################
fig,ax = plt.subplots()
# plot interior nodes
ax.plot(nodes[interior,0],nodes[interior,1],'k.',markersize=2)
# plot boundary nodes
ax.plot(nodes[boundary,0],nodes[boundary,1],'b.',markersize=2)
ax.set_aspect('equal')
fig.tight_layout()
plt.savefig('figures/lenna.png')
plt.show()