问题
How to correct this program, please? There is an error: ValueError: One of the requested xi is out of bounds in dimension 0. There is a function for defining the magnetic field according to equations in cylindric coordinates. Then, it should compute steamline using yt module and compute a trajectory of charges particle.
Without the last two lines, it works. However, I am not sure wheater it works correct but there is no error.
import numpy as np
import matplotlib.pyplot as plt
from numpy import array
from scipy.interpolate import RegularGridInterpolator,interpn
from scipy.integrate import solve_ivp # Runge-Kutta method
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D # 3d graph
from mpl_toolkits.mplot3d import proj3d # 3d graph
from matplotlib.patches import FancyArrowPatch
import matplotlib.patches as mpatches
import math
from matplotlib import patches
import code
import yt
from yt import YTArray # arrays in yt module
from yt.visualization.api import Streamlines # force lines
import matplotlib.pylab as pl
# Configuration file
from configparser import ConfigParser
cfg = ConfigParser()
cfg.read('setting.cfg')
# Font setting
import font
# Constants
q =-1.6e-19 # electron charge
m = 9.1e-31 # electron mass
v_par = 2000 # parallel volocity
v_per = 2000 # perpendicular velocity
NUM = 150 # grid resolution
x0=np.zeros(6) # vector - 6 dim, give zeros into it (3 components - positions, 3 components - velocity)
def get_b(grid):
B_theta = np.zeros((150, 150, 150), dtype=np.float)
if grid[2].any() < 0:
B_z = grid[0]
B_R = 0
elif grid[2].any() < np.pi:
B_z = 0.25 * grid[0] * np.cos(grid[2]) + 0.75 * grid[0]
B_R = (0.25/3) * grid[0] * grid[0] * np.sin(grid[2])
else:
B_z = 0.5 * grid[0]
B_R = 0
return (B_R, B_theta, B_z)
import numpy as np
# Grid limits
RMIN = 0.000001
RMAX = 1
THETA_MIN = 0
THETA_MAX = 2*np.pi
ZMIN =0
ZMAX = 2
# Definition of space
R = np.linspace(RMIN, RMAX, num = NUM)
THETA = np.linspace(THETA_MIN, THETA_MAX, num = NUM)
Z = np.linspace(ZMIN, ZMAX, num = NUM)
B_R, B_theta, B_z = get_b(grid=np.meshgrid(R, THETA, Z))
print(B_R)
print(type(B_R))
print(B_R.shape)
# Choose point in field where force line will be integrated
R_point = 0.025
THETA_point = 0.05*np.pi
Z_point = 0
# Dictionary of numpy arrays - magnetic field data
data = dict(B1=B_R, B2=B_theta, B3=B_z)
B_R = data["B1"]
B_theta = data["B1"]
B_Z = data["B1"]
print(data)
# 3d array of dipole magnetic field
bbox = np.array([[-0.15, 0.15], [0, 0.2], [-0.1, 0.1]]) # border
ds = yt.load_uniform_grid(data, B_R.shape, length_unit="Mpc", bbox=bbox, nprocs=100) # data, dimenze
# Define c: the center of the box, chosen point
c = ds.arr([R_point, THETA_point, Z_point], 'code_length')
c1 = ds.domain_center
# N is number of streamlines
N = 1
# Scale is the spatial scale of the streamlines relative to the boxsize
scale = ds.domain_width[0]
pos = c
# Create streamlines and integration
streamlines = Streamlines(ds, pos, 'B1', 'B2', 'B3', length=None)
streamlines.integrate_through_volume()
# Initial conditions are copied from result below
def fields(t = 0, x=[2.56662842e-02, 4.60688953e-02, 1.50116387e-18]):
n = len(B_R)
# Interpolate
B1 = my_3d_interp(R,THETA,Z, B_R, x[0], x[1], x[2])
B2 = my_3d_interp(R,THETA,Z, B_theta, x[0], x[1], x[2])
B3 = my_3d_interp(R,THETA,Z, B_Z, x[0], x[1], x[2])
# Results to matrices
B = np.array([B1, B2, B3]);
return B
def my_3d_interp(x, y, z, V, xi, yi, zi):
import numpy as np
from scipy.interpolate import RegularGridInterpolator as rgi
interpolating_function = rgi((x, y, z), V)
return interpolating_function(np.array([xi, yi, zi]).T)
B = fields(t=0, x=[2.56662842e-02, 4.60688953e-02, 1.50116387e-18])
# Formulae
w_c = abs(q*np.sqrt(sum(np.power(B,2)))/m)/2 # cyclotron frequency, addition of seconds powers of the vector B
dt = (1/w_c)/100 # step is 1/100 of characteristic frequency
t0 = 0
tmax = (1/w_c)*15
t = np.arange(t0,tmax,dt)
rL = abs(v_per/w_c) # Larmor radius
# Definition of function for prependicular vector in cases when the multiplication by the vector [1,0,0] fails due to the parallel vector with the basis
def perpendicular_vector(v):
if v[1] == 0 and v[2] == 0:
if v[0] == 0:
raise ValueError('zero vector')
else:
return np.cross(v, [0, 1, 0])
return np.cross(v, [1, 0, 0])
for stream in streamlines.streamlines:
stream = stream[np.all(stream != 0.0, axis=1)]
# Data of force line
x_streamline = stream[:,0]
y_streamline = stream[:,1]
z_streamline = stream[:,2]
xd = np.array([x_streamline[2]-x_streamline[0], y_streamline[2]-y_streamline[0], z_streamline[2]-z_streamline[0]]) # tangent at the curve's start point
xd_norm=xd/np.linalg.norm(xd) # unit parallel vector
x_par=v_par*xd_norm
perp = perpendicular_vector(xd_norm) # random perpendicular vector
perp_norm = perp / np.linalg.norm(perp) # normalized perpendicular vector
x_per = v_per * perp_norm # perpendicular velocity
xv = x_par+x_per # total velocity
temp_norm=np.cross(xd_norm,perp_norm)
# Spatial coordinates of x0 should be near the initial point of force line
norm_vector=np.cross(xd_norm,perp_norm)/np.linalg.norm(np.cross(xd_norm,perp_norm))
# It is necessary to divide by two
dx_rL = rL * norm_vector/2 # difference to the distance of rL, perpendicular to curve starting point
# Convert dx_rL to yt array
dx_rL_yt = ds.arr(dx_rL, 'code_length')
# Initial position
x0[0] = x_streamline[1]+dx_rL_yt[0]
print('aaaaaaaaaa',x0[0])
x0[1] = y_streamline[1]+dx_rL_yt[1]
x0[2] = z_streamline[1]+dx_rL_yt[2]
# These values were copied to functions above
x_start=[x0[0],x0[1],x0[2]]
# Initial velocities
x0[3]=xv[0]
x0[4]=xv[1]
x0[5]=-xv[2]
print('xxxxxxxxxxxxxxx',x0)
# B magnetic field in the place of particle
def deriv (t, x0):
q=-1.6e-19 # electron charge
m=9.1e-31 # electron mass
B = fields(t,x0)
v=[x0[3], x0[4], x0[5]]
xdot=[v[0],
v[1],
v[2],
q/m*((v[1]*B[2]-v[2]*B[1])),
q/m*((v[2]*B[0]-v[0]*B[2])),
q/m*((v[0]*B[1]-v[1]*B[0]))]
return xdot
# Solution of differential equations
xdot = deriv(t, x0)
solution = solve_ivp(deriv, [t0, tmax], x0, method = "RK45", t_eval = np.arange(t0,tmax,dt))
来源:https://stackoverflow.com/questions/61855941/how-to-correct-one-of-the-requested-variable-is-out-of-bounds-in-dimension-0-err