I am trying to generate BER-SNR curve in Rayleigh channel using BPSK modulation. Can anyone help me to find what is wrong with the python code? The theoretical BER differs from the simulated BER. The red dotted line is theoretical and the blue one is simulated.
import math as mt
import numpy as np
import matplotlib.pyplot as plt
import numpy.random as nr
from scipy.linalg import toeplitz
# ------------Simulation parameters------------------------
N = 500 #No.of symbols
H_n = 10 #No.of channel elements
h_ray = np.zeros((H_n, 1), dtype = complex)
# ---------------------------------------------------------
EbN0dB = np.array(range(0, 11))
itr = len(EbN0dB)
ber = [None] * itr
theoreticalBER = [None] * itr
# -----------------------------Transmitter----------------------------
s = 2 * (nr.rand(N, 1) >= 0.5) - 1 # BPSK
# ------------------------------Channel-------------------------------
h_ray = (1/mt.sqrt(2)) * (nr.randn(H_n, 1) + 1j * nr.randn(H_n, 1))
# Rayleigh fading channel
z = np.zeros((N-1,1))
c = np.concatenate((h_ray, z), axis=0)
r = np.concatenate(([h_ray[0]], np.zeros((1, N-1))), axis=1)
h_ray_y=toeplitz(c, r) # Toeplitz matrix instead of convolution
y_ray = np.dot(h_ray_y, s)
for n in range(itr):
EbN0dB_n = EbN0dB[n]
EbN0 = 10.0 ** (-EbN0dB_n/ 20.0)
noise = 1/mt.sqrt(2) * (nr.randn(N+H_n-1) + 1j * nr.randn(N+H_n-1))
r_ray = y_ray + EbN0 * noise
# --------------------------Receiver------------------------------
r_t = np.dot(np.dot(np.linalg.pinv(np.dot(h_ray_y.T, h_ray_y)), h_ray_y.T), r_ray) # (H.T * H)^(-1)*H.T*received
r_d = 2 * (np.real(r_t) >= 0) - 1
errors = (s != r_d).sum()
ber[n] = 1.0 * errors / N
EbN0_th = 10.0 ** (EbN0dB_n / 10.0)
theoreticalBER[n] = 0.5 *(1 - mt.sqrt(EbN0_th/ (1 + EbN0_th)))
ber=np.asanyarray(ber)
#-------------------------------------------------------------------------
plt.plot(EbN0dB, np.log10(ber), '--bo')
plt.plot(EbN0dB, np.log10(theoreticalBER), 'ro')
plt.xlabel('EbN0(dB)')
plt.ylabel('BER')
plt.grid(True)
plt.title('BPSK - Rayleigh')
plt.show()
Related
im trying to run an SIR model in python. I want to plot changing beta values against the maximum of I for each beta value. I have the beta's figured out but i dont know how i would plot the I against it?.
here's my code so far:
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
import math
def SIR(y, t):
S, I, R = y
mu = 0.1
N = S + I + R
Sdot = -beta * S * I
Idot = beta * S * I - mu * I
Rdot = mu * I
return Sdot, Idot, Rdot
tf = 100
Nsteps = 1000
t = np.linspace(0, tf, Nsteps+1)
S0 = 10**4 - 3
I0 = 3
R0 = 0
y0 = np.array([S0, I0, R0])
y_sol = odeint(SIR, y0, t)
S = y_sol[:,0]
I = y_sol[:,1]
R = y_sol[:,2]
Imax = max(I)
tmax = t[I.argmax()]
Smax = S[I.argmax()]
beta_vals = np.linspace(0.2, 0.6, 5)
max_I =[]
for beta in beta_vals:
max_I.append(max(I))
plt.plot(beta_vals, max_I)
plt.xlabel('beta')
plt.ylabel('Maximum value of I')
plt.title('Effect of beta on the maximum value of I')
plt.show()
I thought that using append would give me the corresponding values but i end up with a straight line
You are almost there.
Try this updated code :
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
import math
def SIR(y, t, beta):
S, I, R = y
mu = 0.1
N = S + I + R
Sdot = -beta * S * I
Idot = beta * S * I - mu * I
Rdot = mu * I
return Sdot, Idot, Rdot
tf = 100
Nsteps = 1000
t = np.linspace(0, tf, Nsteps+1)
S0 = 10**4 - 3
I0 = 3
R0 = 0
y0 = np.array([S0, I0, R0])
beta_vals = np.linspace(0.2, 0.6, 5)
max_I = []
for beta in beta_vals:
y_sol = odeint(SIR, y0, t, args=(beta,))
S = y_sol[:,0]
I = y_sol[:,1]
max_I.append(max(I))
plt.plot(beta_vals, max_I)
plt.xlabel('beta')
plt.ylabel('Maximum value of I')
plt.title('Effect of beta on the maximum value of I')
plt.show()
I am trying to apply a low pass filter to a signal in the frequency domain, with gaussian weighting/roll off curve.
I got the first version of the for loop from my collegues and I admit that I do not understand it. Why is the sigma definition the way it is with the logarythm? I would just put it the Gauss function as I read it in wikipedia (second version).
Why is the resulting filter characteristic a little offset (by approx. 0.2?) for both versions and why is the result 0 for the second?
the code:
import numpy as np
import matplotlib.pyplot as plt
from scipy.fftpack import fft
from scipy.fftpack import ifft
data = np.loadtxt("profil.txt")
t = data[:,0]
x = data[:,1]
amplitudes = fft(x)
c = np.abs(amplitudes)
c_norm = 2 * c/len(t)
c[0] /= 2
c_half = c[0:len(amplitudes)//2]
f = np.fft.fftfreq(len(t), d = t[len(t)-1]/(len(t)-1))
p_t = np.zeros(len(amplitudes))
sigma = np.sqrt(np.log(0.5)/(-2.))/np.pi/10 #FIRST VERSION
s = 0.7 #SECOND VERSION
for i in range(len(c)):
e = np.exp(-2*np.pi**2*sigma**2*f[i]**2) #FIRST VERSION
#e = np.e**(-f[i]**2/2/s**2)/s/np.sqrt(2*np.pi) #SECOND VERSION
if e > 0.1:
#FIRST VERSION
p_t[i] = np.exp(-2*np.pi**2*sigma**2*f[i]**2)
p_t[-i] = np.exp(-2 * np.pi ** 2 * sigma ** 2 * f[i] ** 2)
#SECOND VERSION:
#p_t[i] = np.e**(-f[i]**2/2/s**2)/s/np.sqrt(2*np.pi)
#p_t[-i] = np.e ** (-f[i] ** 2 / 2 / s ** 2)/s/np.sqrt(2*np.pi)
else:
pass
x_filtered = ifft(amplitudes * p_t)
fig = plt.figure(constrained_layout = True)
gs = fig.add_gridspec(2, 1)
a00 = fig.add_subplot(gs[0, 0])
a00.plot(t, x,color='blue', label="original")
a00.plot(t,x_filtered, color='red', label="filtered")
a00.legend(bbox_to_anchor=(0,1,1,0), loc="lower left", ncol = 1)
a01 = fig.add_subplot(gs[1, 0])
a01.plot(f,c, label="amplitudes")
a01.set_ylim([0,1000])
a01.legend()
a03 = a01.twinx()
a03.plot(f, p_t, color='red', label='filter characteristic')
plt.show()
thanks in advance for any idea or explanation. The resulting plot (first version):
second version:
I have the following code. I know it's long and complex, however it takes 1.5 mins on my laptop to run. I would greatly appreciate any help towards finding the problem causing the error at the end - the plotting part.I didn't find anything on Google related to this error message:
TypeError: unsupported operand type(s) for : 'QuadMesh' and 'float'
from scipy import interpolate
from scipy.fft import fft, ifft
from scipy.constants import c, epsilon_0
import numpy as np, math
from matplotlib import pyplot as plt
lambda_0 = 800 * 10**(-9)
omega_0 = 2*np.pi*c / lambda_0
delta_lambda = 50.0 * 10**(-9)
delta_Tau = (1.47 * 10**(-3) * (lambda_0*10**9)**2 / (delta_lambda*10**9)) * 10**(-15) #
delta_omega_PFT = (4*np.log(2) / delta_Tau) # equivalent (equal) to: ((4*ln(2)) / (2*pi)) * (2*pi/delta_Tau) = 0.441 * (2*pi/delta_Tau)
F = 2.0 # focal length in meters, as from Liu 2017
def G(omegas):
# return ( np.sqrt(np.pi/(2*np.log(2))) * tau * np.exp( -(tau**2/(8*np.log(2))) * (omegas-omega_0)**2 ) ) # why is this here?
return np.exp( -(delta_Tau**2/(8*np.log(2))) * (omegas-omega_0)**2 )
xsi = 0.1 * (1.0 * 10**(-15)) / (1.0 * 10**(-3))
def phase_c(xs, omegas):
return ( xsi * np.reshape(xs, (xs.shape[0], 1)) * np.reshape((omegas-omega_0), (1, omegas.shape[0])) )
E0 = np.sqrt( (0.2*10**4 * 8 * np.sqrt(np.log(2))) / (delta_Tau*np.sqrt(np.pi)*c*epsilon_0/2.0) ) * np.sqrt(2*np.pi*np.log(2)) / delta_omega_PFT
def f(xi, omega): # the prefactors from Eq. (5) of Li et al. (2017) (the ones pre-multiplying the Fraunhoffer integral)
first = omega * np.exp(1j * (omega/c) * F) / (1j * 2*np.pi*c*F) # only function of omega. first is shape (omega.shape[0], )
omega = np.reshape(omega, (1, omega.shape[0]))
xi = np.reshape(xi, (xi.shape[0], 1))
second = np.exp(1j * (omega/c) * xi**2 / (2*F)) # second is shape (xi.shape[0], omega.shape[0]).
return (first * second) # returned is shape (xi.shape[0], omega.shape[0])
x0 = 0.0
delta_x = 196.0 # obtained from N=10, N_x=8*10^3, xi_max=10um, F=2m
xmin_PFT = x0 - delta_x #
xmax_PFT = x0 + delta_x #
num_xs_PFT = 8 * 10**3
xs_PFT = np.linspace(xmin_PFT, xmax_PFT, num_xs_PFT)
sampling_spacing_xs_PFT = np.true_divide( (xmax_PFT-xmin_PFT), num_xs_PFT)
num_omegas_focus = 5 * 10**2
maximum_time = 100.0 * 10**(-15)
N = math.ceil( (np.pi*num_omegas_focus)/(2*delta_omega_PFT*maximum_time) ) - 1
omega_max_focus = omega_0 + N*delta_omega_PFT
omega_min_focus = omega_0 - N*delta_omega_PFT
omegas_focus = np.linspace(omega_min_focus, omega_max_focus, num_omegas_focus) # shape (num_omegas_focus, )
sampling_spacing_omegas_focus = np.true_divide((omega_max_focus-omega_min_focus) , num_omegas_focus)
Es_x_omega = np.multiply( (E0 * G(omegas_focus)) ,
(np.exp(1j*phase_c(xs_PFT, omegas_focus))) # phase_c uses xsi, the PFT coefficient
)
# Es_x_omega holds across columns (vertically downwards) the x-dependence and across rows (horizontally) the omega-dependence
# Es_x_omega is shape (num_xs_PFT, num_omegas_focus)
Bprime_data_real = np.empty((Es_x_omega.shape[0], Es_x_omega.shape[1])) # this can be rewritten in a more Pythonic way
Bprime_data_imag = np.empty((Es_x_omega.shape[0], Es_x_omega.shape[1]))
for i in range(Es_x_omega.shape[1]): # for all the columns (all omegas)
# Perform FFT wrt x (so go from x to Kappa (a scaled spatial frequency))
intermediate = fft(Es_x_omega[:, i])
Bprime_data_real[:, i] = np.real(intermediate) * sampling_spacing_xs_PFT # multiplication by \Delta, see my docu above
Bprime_data_imag[:, i] = np.imag(intermediate) * sampling_spacing_xs_PFT # multiplication by \Delta, see my docu above
if i % 10000 == 0:
print("We have done fft number {}".format(i) + " out of {}".format(Es_x_omega.shape[1]) + "ffts")
# Bprime is function of (Kappa, omega): across rows the omega dependence, across columns the Kappa dependence.
# Get the Kappas:
returned_freqs = np.fft.fftfreq(num_xs_PFT, sampling_spacing_xs_PFT) # shape (num_xs_PFT, )
Kappas_ugly = 2*np.pi * returned_freqs # shape (num_xs_PFT, ), but unordered in terms of the magnitude of the values! see https://numpy.org/doc/stable/reference/generated/numpy.fft.fftfreq.html
Kappas_pretty = 2*np.pi * np.fft.fftshift(returned_freqs)
indices = (Kappas_ugly == Kappas_pretty[:, None]).argmax(1) # shape (num_xs_PFT, )
indices = indices.reshape((indices.shape[0], 1)) # needed for adapting Dani Mesejo's answer: he reordered based on 1D slices laid horizontally, here I reorder based on 1D slices laid vertically.
# see my notebook for visuals, 22-23 Nov 2021
hold_real = Bprime_data_real.shape[1]
hold_imag = Bprime_data_imag.shape[1]
Bprime_data_real_pretty = np.take_along_axis(Bprime_data_real, np.tile(indices, (1, hold_real)), axis=0) # adapted from Dani Mesejo's answer
Bprime_data_imag_pretty = np.take_along_axis(Bprime_data_imag, np.tile(indices, (1, hold_imag)), axis=0) # adapted from Dani Mesejo's answer
print(Bprime_data_real_pretty.shape) # shape (num_xs_PFT, num_omegas_focus), similarly for Bprime_data_imag_pretty
Bprime_real = interpolate.RectBivariateSpline(Kappas_pretty, omegas_focus, Bprime_data_real_pretty) # this CTOR creates an object faster (which can also be queried faster)
Bprime_imag = interpolate.RectBivariateSpline(Kappas_pretty, omegas_focus, Bprime_data_imag_pretty) # than interpolate.interp2d() does.
print("We have the interpolators!")
# Prepare for the aim: plot E versus time (horizontal axis) and xi (vertical axis).
xi_min = -5.0 * 10**(-6) # um
xi_max = 5.0 * 10**(-6) # um
num_xis = 5000
xis = np.linspace(xi_min, xi_max, num_xis)
print("We are preparing now!")
Es_Kappa_omega_without_prefactor = np.empty((xis.shape[0], omegas_focus.shape[0]), dtype=complex)
for j in range(Es_Kappa_omega_without_prefactor.shape[0]): # for each row
for i in range(Es_Kappa_omega_without_prefactor.shape[1]): # for each column
Es_Kappa_omega_without_prefactor[j, i] = Bprime_real(omegas_focus[i]*xis[j] /(c*F), omegas_focus[i]) + 1j*Bprime_imag(omegas_focus[i]*xis[j] /(c*F), omegas_focus[i])
if ((i + j*Es_Kappa_omega_without_prefactor.shape[1]) % 30000 == 0):
print("We have done iter number {}".format(i + j*Es_Kappa_omega_without_prefactor.shape[1])
+ " out of {}".format(Es_Kappa_omega_without_prefactor.shape[0] * Es_Kappa_omega_without_prefactor.shape[1]) + " iterations in querying the interpolators")
Es_Kappa_omega = np.multiply( f(xis, omegas_focus), # f(xis, omegas_focus) is shape (xis.shape[0], omegas_focus.shape[0])
Es_Kappa_omega_without_prefactor # Es_Kappa_omega_without_prefactor is shape (xis.shape[0], omegas_focus.shape[0])
) # the obtained variable is shape (xis.shape[0], omegas_focus.shape[0])
# Do IFT of Es_Kappa_omega w.r.t. omega to go from FD (omega) to TD (time t).
Es_Kappa_time = np.empty_like(Es_Kappa_omega, dtype=complex) # shape (xis.shape[0], omegas_focus.shape[0])
# Along columns (so vertically) the xi dependence, along rows (horizontally), the omega dependence
for i in range(Es_Kappa_omega.shape[0]): # for each row (for each xi)
Es_Kappa_time[i, :] = ifft(Es_Kappa_omega[i, :]) * (sampling_spacing_omegas_focus/(2*np.pi)) * num_omegas_focus # 1st multiplication is by Delta, 2nd multiplication is by N
if i % 10000 == 0:
print("We have done ifft number {}".format(i) + " out of a total of {}".format(Es_Kappa_omega.shape[0]) + " iffts")
returned_times_ugly = np.fft.fftfreq(num_omegas_focus, d=(sampling_spacing_omegas_focus/(2*np.pi))) # shape (num_omegas_focus, )
returned_times_pretty = np.fft.fftshift(returned_times_ugly) # order the returned "frequencies" (here "frequencies" = times because it's IFT (so from FD to TD))
indices = (returned_times_ugly == returned_times_pretty[:, None]).argmax(1)
Es_Kappa_time = np.take_along_axis(Es_Kappa_time, np.tile(indices, (Es_Kappa_time.shape[0], 1)), axis=1) # this is purely Dani Mesejo's answer
returned_times_pretty_mesh, xis_mesh = np.meshgrid(returned_times_pretty, xis)
fig, ax = plt.subplots()
c = ax.pcolormesh(returned_times_pretty_mesh, xis_mesh, np.real(Es_Kappa_time), cmap='viridis')
fig.colorbar(c, ax=ax, label=r'$[V/m]$')
ax.set_xlabel("t [s]")
ax.set_ylabel("xi [m]")
plt.show()
fig, ax = plt.subplots()
ax.imshow(np.multiply(np.square(np.real(Es_Kappa_time)), (c*epsilon_0)), cmap='viridis')
ax.set_xlabel("t [s]")
ax.set_ylabel("xi [m]")
plt.show()
I have tried many forms to be introduced in the plotting part. It fails with:
c = ax.pcolormesh(returned_times_pretty_mesh, xis_mesh, (c*epsilon_0)*np.real(Es_Kappa_time)**2, cmap='viridis')
fig.colorbar(c, ax=ax, label=r'$[V/m]$')
Fails with:
160 fig, ax = plt.subplots()
--> 161 ax.imshow(np.multiply(np.real(Es_Kappa_time)**2, (c*epsilon_0)), cmap='viridis')
I ran out of ideas of what I might introduce there.
Thank you!
It looks like you're reassigning c to the return value from ax.pcolormesh(...) after you import c from scipy.constants.
Code:
from scipy.integrate import odeint
import numpy as np
import matplotlib.pyplot as plt
# parameters
S = 0.0001
M = 30.03
K = 113.6561
Vr = 58
R = 8.3145
T = 298.15
Q = 0.000133
Vp = 0.000022
Mr = 36
Pvap = 1400
wf = 0.001
tr = 1200
mass = 40000
# define t
time = 14400
t = np.arange(0, time + 1, 1)
# define initial state
Cv0 = (mass / Vp) * wf # Cv(0)
Cr0 = (mass / Vp) * (1 - wf)
Cair0 = 0 # Cair(0)
# define function and solve ode
def model(x, t):
C = x[0] # C is Cair(t)
c = x[1] # c is Cv(t)
a = Q + (K * S / Vr)
b = (K * S * M) / (Vr * R * T)
s = (K * S * M) / (Vp * R * T)
w = (1 - wf) * 1000
Peq = (c * Pvap) / (c + w * c * M / Mr)
Pair = (C * R * T) / M
dcdt = -s * (Peq - Pair)
if t <= tr:
dCdt = -a * C + b * Peq
else:
dCdt = -a * C
return [dCdt, dcdt]
x = odeint(model, [Cair0, Cv0], t)
C = x[:, 0]
c = x[:, 1]
Now, I want to figure out wf value when I know C(0)(when t is 0) and C(tr)(when t is tr)(Therefore I know two kind of t and C(t)).
I found some links(Curve Fit Parameters in Multiple ODE Function, Solving ODE with Python reversely, https://medium.com/analytics-vidhya/coronavirus-in-italy-ode-model-an-parameter-optimization-forecast-with-python-c1769cf7a511, https://kitchingroup.cheme.cmu.edu/blog/2013/02/18/Fitting-a-numerical-ODE-solution-to-data/) related to this, although I cannot get the hang of subject.
Can I fine parameter wf with two data((0, C(0)), (tr, C(tr)) and ode?
First, ODE solvers assume smooth right-hand-side functions. So the if t <= tr:... statement in your code isn't going to work. Two separate integrations must be done to deal with the discontinuity. Integrate to tf, then use the solution at tf as initial conditions to integrate beyond tf for the new ODE function.
But it seems like your main problem (solving for wf) only involves integrating to tf (not beyond), so we can ignore that issue when solving for wf
Now, I want to figure out wf value when I know C(0)(when t is 0) and C(tr)(when t is tr)(Therefore I know two kind of t and C(t)).
You can do a non-linear solve for wf:
from scipy.integrate import odeint
import numpy as np
import matplotlib.pyplot as plt
# parameters
S = 0.0001
M = 30.03
K = 113.6561
Vr = 58
R = 8.3145
T = 298.15
Q = 0.000133
Vp = 0.000022
Mr = 36
Pvap = 1400
mass = 40000
# initial condition for wf
wf_initial = 0.02
# define t
tr = 1200
t_eval = np.array([0, tr], np.float)
# define initial state. This is C(t = 0)
Cv0 = (mass / Vp) * wf_initial # Cv(0)
Cair0 = 0 # Cair(0)
init_cond = np.array([Cair0, Cv0],np.float)
# Definte the final state. This is C(t = tr)
final_state = 3.94926615e-03
# define function and solve ode
def model(x, t, wf):
C = x[0] # C is Cair(t)
c = x[1] # c is Cv(t)
a = Q + (K * S / Vr)
b = (K * S * M) / (Vr * R * T)
s = (K * S * M) / (Vp * R * T)
w = (1 - wf) * 1000
Peq = (c * Pvap) / (c + w * c * M / Mr)
Pair = (C * R * T) / M
dcdt = -s * (Peq - Pair)
dCdt = -a * C + b * Peq
return [dCdt, dcdt]
# define non-linear system to solve
def function(x):
wf = x[0]
x = odeint(model, init_cond, t_eval, args = (wf,), rtol = 1e-10, atol = 1e-10)
return x[-1,0] - final_state
from scipy.optimize import root
sol = root(function, np.array([wf_initial]), method='lm')
print(sol.success)
wf_solution = sol.x[0]
x = odeint(model, init_cond, t_eval, args = (wf_solution,), rtol = 1e-10, atol = 1e-10)
print(wf_solution)
print(x[-1])
print(final_state)
I have an iterative model in Python which generates at signal using a function which contains a derivative. As the model iterates the signal becomes noisy - I suspect it may be an issue with computing the numerical derivative. I've tried to smooth this by applying a low-pass filter, convolving the noisy signal with a Gaussian kernel. I use the code snippet:
nw = 256
std = 40
window = gaussian(nw, std, sym=True)
filtered = convolve(current, window, mode='same') / np.sum(window)
where current is my signal, and gaussian and convolve have been imported from scipy. This seems to give a slight improvement, and the first 2 or 3 iterations appear very smooth. However, after that the signal becomes extremely noisy again, despite the fact that the low-pass filter is positioned inside the iterative loop.
Can anyone suggest where I might be going wrong or how I could better tackle this problem? Thanks.
EDIT: As suggested I've included the code I'm using below. At 5 iterations the noise on the signal is clearly apparent.
import numpy as np
from scipy import special
import matplotlib.pyplot as plt
from scipy.integrate import odeint
from scipy.signal import convolve
from scipy.signal import gaussian
# Constants
B = 426400E-9 # tesla
R = 71723E3
Rkm = R / 1000.
Omega = 1.75e-4 #8.913E-4 # rads/s
period = (2. * np.pi / Omega) / 3600. # Gets period in hours
Bj = 2.0 * B
mdot = 1000.
sigmapstar = 0.05
# Create rhoe array
rho0 = 5.* R
rho1 = 100. * R
rhoe = np.linspace(rho0, rho1, 2.E5)
# Define flux function and z component of equatorial field strength
Fe = B * R**3 / rhoe
Bze = B * (R/rhoe)**3
def derivs(u, rhoe, p):
"""Computes the derivative"""
wOmegaJ = u
Bj, sigmapstar, mdot, B, R = p
# Compute the derivative of w/omegaJ wrt rhoe (**Fe and Bjz have been subbed)
dwOmegaJ = (((8.0*np.pi*sigmapstar*B**2 * (R**6)) / (mdot * rhoe**5)) \
*(1.0-wOmegaJ) - (2.*wOmegaJ/rhoe))
res = dwOmegaJ
return res
its = 5 # number of iterations to perform
i = 0
# Loop to iterate
while i < its:
# Define the initial condition of rigid corotation
wOmegaJ_0 = 1
params = [Bj, sigmapstar, mdot, B, R]
init = wOmegaJ_0
# Compute numerical solution to Hill eqn
u = odeint(derivs, init, rhoe, args=(params,))
wOmega = u[:,0]
# Calculate I_rho
i_rho = 8. * np.pi * sigmapstar * Omega * Fe * ( 1. - wOmega)
dx = rhoe[1] - rhoe[0]
differential = np.gradient(i_rho, dx)
jpara = 1. * differential / (4 * np.pi * rhoe * Bze )
jpari = 2. * B * para
# Remove infinity and NaN values)
jpari[~np.isfinite(jpari)] = 0.0
# Convolve to smooth curve
nw = 256
std = 40
window = gaussian(nw, std, sym=True)
filtered = convolve(jpari, window, mode='same') /np.sum(window)
jpari = filtered
# Pedersen conductivity as function of jpari
sigmapstar0 = 0.05
jstar = 0.01e-6
jstarstar = 0.25e-6
s1 = 0.1e6#0.1e6 # (Am^-2)^-1
s2 = 9.9e6 # (Am^-2)^-1
n = 8.
# Calculate news sigmapstar. Realistic conductivity
sigmapstarNew = sigmapstar0 + 0.5 * (s1 + s2/(1 + (jpari/jstarstar)**n)**(1./n)) * (np.sqrt(jpari**2 + jstar**2) + jpari)
sigmapstarNew = sigmapstarNew
diff = np.abs(sigmapstar - sigmapstarNew) / sigmapstar * 100
diff = max(diff)
sigmapstar = 0.5* sigmapstar + 0.5* sigmapstarNew # Weighted averaging
i += 1
print diff
# Plot jpari
ax = plt.subplot(111)
ax.plot(rhoe/R, jpari * 1e6)
ax.axhline(0, ls=':')
ax.set_xlabel(r'$\rho_e / R_{UCD}$')
ax.set_ylabel(r'$j_{\parallel i} $ / $ \mu$ A m$^{-2}$')
ax.set_xlim([0,80])
ax.set_ylim(-0.01,0.01)
plt.locator_params(nbins=5)
plt.draw()
plt.show()