1D Simpson Integration to create a diffraction pattern plot - python

I'm trying to make a diffraction plot using Simpson integration but this just plots a straight line. I know it's just evaluating a single number but I'd like it to make a diffraction pattern with the strongest maxima in the middle.
import math
import cmath
import numpy as np
import sympy as sym
import matplotlib.pyplot as plt
from scipy.integrate import simps
from scipy import integrate
from math import sin, cos, pi
n = 100 #Number of areas to be calculated for integration approximation
λ = 1*10**-6 #Wavelength
z = 0.02 #Screen distance
k = (2*math.pi)/λ #wave number
j = complex(cmath.sqrt(-1))
n = 100
b = 2E-5
a = 0
def f(x):
return np.exp((1j*k)/(2*z)*(x)**2)
x = np.linspace(-0.005, 0.005, 100)
y = np.linspace(0, 0, 100, dtype= "complex")
def g(p, q):
h = (b - a) / n
k = 0
z = 0
for i in range(1, n // 2):
k += 2 * f(a + 2 * i * h)
for i in range(1, n // 2 + 1):
z += 4 * f(a + (2 * i - 1) * h)
return h * (z+k+f(a)+f(b)) / 3.0
for i in range(0,100,n):
if( x[i] == 0 ):
y[i] = 0
else:
q = np.linspace(0,x[i],100)
p = f(q)
y[i] = abs(np.conj(g(p, q))*(g(p, q)))*8.85E-12
plt.plot(x, np.imag(y))

Related

How could I make a line which is inverted to the original

At the moment this is my code:
import scipy
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import EventCollection
import math
from scipy import integrate
from scipy import constants
K_b = 1.380649e-23 # Boltzmanns Constant
a_n = 6.022e23 # Avogrados Number
T = 10 # Kelvin
mass = 28
a = 10e-5
def mantleEvolution(tMax, dt) :
N = int(tMax/dt) + 1
timeArray = np.zeros(N)
numberArray = np.zeros(N)
t = 0
n_m = 1 #per cubic centimeter
n_s = 0
i = 0
while i < N:
m_m = float(mass) / a_n
V_m = math.sqrt((8.0 * K_b * float(T)) / (math.pi * float(m_m)))
R = math.pi * pow(float(a), 2) * n_m * V_m
ρ_d = 3 # g/cm^3
μ_g = 2 * 1.67e-23
m_d = (4 / 3) * math.pi * pow(float(a), 3)
n_g = 10e4
d_g = 0.01 # 1% mass density of gas
n_d = (d_g * n_g * μ_g) / (m_d * float(ρ_d))
n_s = n_s + R * dt
n_m = n_m - R * n_d * dt
timeArray[i] = t
numberArray[i] = n_m
t = t + dt
i = i + 1
return [timeArray, numberArray, n_s]
timeArray, numberArray, n_s = mantleEvolution(5.0 * 10**15, 5.0 * 10**9)
fig = plt.figure(figsize=(6.4, 6.4))
ax1 = plt.subplot(111)
ax1.plot(timeArray, numberArray)
ax1.set_xlabel('time, seconds', fontsize=20)
ax1.set_ylabel('number', fontsize=20)
plt.setp(ax1.get_xticklabels(), fontsize=16)
plt.setp(ax1.get_yticklabels(), fontsize=16)
fig.subplots_adjust(left=.18)
plt.savefig('mantleEvolution.pdf')
This is the graph I recieve from graphing my code:
What I wish to find out is how I could plot a second line which behaves the exact opposite where it grows at the same rate the other declines
So for example, something that ressembles this:
If you look at the graph you'll see that the value on the y axis is for both graphs the same for two opposite x values at the x axis. That means that all you want to do is invert the x axis. That is fairly easy done using the formula:
new_x = -1 * (old_x - 2.5) + 2.5
By the way, I see some interesting comments in your code. What is it that you are trying to do here if I may ask?

Projectile motion 3d odes

I am trying to solve this set of differential equations with solve_ivp in Python. Winds are horizontal two dimensional vectors, so I need differential equation solved in y dimension.
This is the error I get:
ValueError: not enough values to unpack (expected 6, got 4)
Is there any other way of solving it? Here is my code:(just projectile motion in x-z plane, distance as function of angle). For the example of two such initial angles (with which we hit approximately the same point) I am trying to calculate the dispersion of hits in the wind according to the point hit in no wind.
Thanks for any help or pointers
from random import randrange
from statistics import stdev
from turtle import title
import numpy as np
import scipy as sp
from scipy.integrate import solve_ivp
import matplotlib.pyplot as plt
m = 30
v0 = 301
g = 9.81
ro = 1.28
A = 0.0026
c = 1
k = 0.5 * c * ro * A
B = k / m
V = v0
c_max = 10
c_windx = 0
c_windy = 0
def dSdt(t, S, B, c_windx, c_windy):
x, vx, y, vy, z, vz = S
speed = np.hypot(np.hypot((vx + c_windx),(vy + c_windy)), vz)
return [vx, -B * speed * (vx + c_windx), vy, -B * speed * (vy + c_windy), vz, -B * speed * vz - g]
def distance(angle, B, c_windx, V=v0, t=600):
v0x = V * np.cos(np.radians(angle))
v0y = 0
v0z = V * np.sin(np.radians(angle))
sol = solve_ivp(dSdt, [0, t], y0 =[0,v0x,0,v0y,0,v0z], t_eval=np.linspace(0,t,10000), args=(B, c_windx,c_windy), atol=1e-7, rtol=1e-4)
justabove = np.where(np.diff(np.sign(sol.y[2])) < 0)[0][0]
justunder = justabove + 1
xloc = (sol.y[0][justabove] + sol.y[0][justunder])/2
return xloc
angles = np.linspace(0, 90, 200)
xlocs = np.vectorize(distance)(angles, B=B, c_windx = c_windx)
plt.plot(angles, xlocs)
plt.xlabel('angles []')
plt.ylabel('distance [m]')
plt.axvline(angles[np.argmax(xlocs)], ls='--', color='r')
plt.text(angles[np.argmax(xlocs)] + 0.2 ,0, round(angles[np.argmax(xlocs)], 2), rotation=90, color='r')
plt.title('Distance(angle)')
plt.show()
alfa = 15 #its optional
def same_distance_alfa(B,c_windx, V=v0, t=600):
for a in np.arange(alfa + 5, 90, 0.1):
if abs(distance(alfa, B, c_windx, V=v0, t=600) - distance(a, B, c_windx, V=v0, t=600) < 10):
print((distance(15, B, c_windx, V=v0, t=600) - distance(a, B, c_windx, V=v0, t=600)))
return a
beta = same_distance_alfa(B)

how to add an array to a ordinary differential equation

I don't know how to add this array to an ordinary differential equation. I don't know how to select for each time the corresponding item.
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
u = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29]
def f(z,t):
dzdt = np.zeros(2,)
x = z[0]
y = z[1]
dzdt[0] = (-x + u) / 2.0
dzdt[1] = (-y + x) / 5.0
return dzdt
z0 = [0,0]
n = 30
t = np.linspace(0,15, n)
u = np.zeros(n)
u[0] = 1
x = np.zeros(n)
y = np.zeros(n)
z = odeint(f,z0,t)

Integrale value decreases when I increase range of integration using mpmath (positive function)

I am using mpmath library on python to compute this integral :
The issue is that when I increase the range of integration, my integral value slowly decreases to 0.. while the integrand is positive!! I give you some values :
integration range : [-1.17,-1.11], integral value : 1.28479400889196e-8
integration range : [-1.2,0], integral value : 2.87226592130464e-29
integration range : [-10,10], integral value : 0.0
What's going on and how to solve issue besides selecting only the range where my integrand is not 0 ?
Here is my code (fermi dirac stat and conductivity have been adapted for pmos so it's not exactly the integral i've shown)
import numpy as np
from math import pi, sqrt, exp, log
from scipy.integrate import quad
import scipy.constants as phys
import matplotlib.pyplot as plt
from decimal import Decimal, getcontext
getcontext().prec = 1000
import mpmath as mp
k = (phys.Boltzmann) # Boltzmann constant
#Parenthesis left due to previous decimal conversion
m = (9.1094e-31) #electron mass
h = (phys.Planck) #Planck constant
h_b = h/(2 * pi) #reduced
q = (1.602176634e-19)
e = (1)
dE = 3e-3 * e
pi = (pi)
m_e = m * (1.06) #electron effective mass
m_h = m * 0.59 #hole effective mass
A_2D = m_h / (pi*h_b**2)
###### INPUTS
T = (4.2)
V_d = (0.02)
chi = (4.05)*e
E_g = (1.16)*e
g = 4 #degeneracy
μ = (1e3) #mobility, cm**2/Vs
A = A_2D
W = 1.00E-05
L = 1.00E-07
#########
E_c = 0
E_v = E_c - E_g
Phi_f = (0.55)
E_f = ( E_c - E_g/2 - e*Phi_f)
Ef_d = ( E_f - e * V_d)
#######
def fd(E,E_f): #Fermi-Dirac distribution for holes
res = 1/(1 + mp.exp(((E - E_f)*q/(k*T))))
return 1-res
def sigma(E):
if E_v-E < 2 :
res = q * A * μ *1e-4 * dE*q * log( 1 + mp.exp((E_v-E)/ dE))
else:
res = - q * A * μ *1e-4 *q *(E-E_v)
return res
def integrand(E):
return sigma(E)*( fd(E,Ef_d) -fd(E,E_f))
X = np.linspace(E_v-5.05,5,1000)
FD = np.vectorize(fd)
Sigma = np.vectorize(sigma)
Integrand = np.vectorize(integrand)
#mp.quad
Int = mp.quad(integrand, [-10,10])
I_c = W/(q*L)*Int
fig, ax1 = plt.subplots()
ax1.plot(X,FD(X,Ef_d) - FD(X,E_f), color = 'g', label='fd stat');
ax2 = ax1.twinx()
ax2.semilogy() ;
ax2.plot(X,Sigma(X), label='sigma');
ax2.plot(X,Integrand(X), label='integrand');
ax1.legend()
ax2.legend(loc='lower right')
print('Int = ',Int)
Thanks

How to change Function by without Changing its Parameters

I am new to python and in learning stages. I wanted to implement Particle Swarm Optimization(PSO) algorithm which I did by taking help from on-line materials and python tutorials. In PSO, a simple calculus problem is inferred i-e 100 * ((y - (x2))2) + ((1 - (x2))2). This problem is defined in a fitness function.
def fitness(x, y):
return 100 * ((y - (x**2))**2) + ((1 - (x**2))**2)
Now, I want to replace this simple calculus problem by simple first order Ordinary Differential Equation(ODE) by without changing existing function parameters (x,y) and want to return the value of dy_dx,y0 and t for further process.
# Define a function which calculates the derivative
def dy_dx(y, x):
return x - y
t = np.linspace(0,5,100)
y0 = 1.0 # the initial condition
ys = odeint(dy_dx, y0, t)`
In python odeint function is used for ODE which requires three essential parameters i-e func/model, y0( Initial condition on y (can be a vector) and t(A sequence of time points for which to solve for y) Example of odeint parameters.
I don't want to change its parameters because it will be difficult for me to make changes in algorithm.
For simplicity I pasted the full code below and my question is open to anyone if wants to modify the code with further parameters in General Best, Personal Best and r[i].
import numpy as np
from scipy.integrate import odeint
import random as rand
from scipy.integrate import odeint
from numpy import array
import matplotlib.pyplot as plt
def main():
#Variables
n = 40
num_variables = 2
a = np.empty((num_variables, n))
v = np.empty((num_variables, n))
Pbest = np.empty((num_variables, n))
Gbest = np.empty((1, 2))
r = np.empty((n))
for i in range(0, num_variables):
for j in range(0, n):
Pbest[i][j] = rand.randint(-20, 20)
a[i][j] = Pbest[i][j]
v[i][j] = 0
for i in range(0, n):
r[i] = fitness(a[0][i], a[1][i])
#Sort elements of Pbest
Order(Pbest, r, n)
Gbest[0][0] = Pbest[0][0]
Gbest[0][1] = Pbest[1][0]
generation = 0
plt.ion()
fig = plt.figure()
ax = fig.add_subplot(111)
ax.grid(True)
while(generation < 1000):
for i in range(n):
#Get Personal Best
if(fitness(a[0][i], a[1][i]) < fitness(Pbest[0][i], Pbest[1][i])):
Pbest[0][i] = a[0][i]
Pbest[1][i] = a[1][i]
#Get General Best
if(fitness(Pbest[0][i], Pbest[1][i]) < fitness(Gbest[0][0], Gbest[0][1])):
Gbest[0][0] = Pbest[0][i]
Gbest[0][1] = Pbest[1][i]
#Calculate Velocity
Vector_Velocidad(n, a, Pbest, Gbest, v)
generation = generation + 1
print 'Generacion: ' + str(generation) + ' - - - Gbest: ' +str(Gbest)
line1 = ax.plot(a[0], a[1], 'r+')
line2 = ax.plot(Gbest[0][0], Gbest[0][1], 'g*')
ax.set_xlim(-10, 10)
ax.set_ylim(-10, 10)
fig.canvas.draw()
ax.clear()
ax.grid(True)
print 'Gbest: '
print Gbest
def Vector_Velocidad(n, a, Pbest, Gbest, v):
for i in range(n):
#Velocity in X
v[0][i] = 0.7 * v[0][i] + (Pbest[0][i] - a[0][i]) * rand.random() * 1.47 + (Gbest[0][0] - a[0][i]) * rand.random() * 1.47
a[0][i] = a[0][i] + v[0][i]
v[1][i] = 0.7 * v[1][i] + (Pbest[1][i] - a[1][i]) * rand.random() * 1.47 + (Gbest[0][1] - a[1][i]) * rand.random() * 1.47
a[1][i] = a[1][i] + v[1][i]
def fitness(x, y):
return 100 * ((y - (x**2))**2) + ((1 - (x**2))**2)
def Order(Pbest, r, n):
for i in range(1, n):
for j in range(0, n - 1):
if r[j] > r[j + 1]:
#Order the fitness
tempRes = r[j]
r[j] = r[j + 1]
r[j + 1] = tempRes
#Order las X, Y
tempX = Pbest[0][j]
Pbest[0][j] = Pbest[0][j + 1]
Pbest[0][j + 1] = tempX
tempY = Pbest[1][j]
Pbest[1][j] = Pbest[1][j + 1]
Pbest[1][j + 1] = tempY
if '__main__' == main():
main()

Categories

Resources