I want to get my code to loop so that every time it performs the calculation, it adds basically does a cumulative sum for my variable delta_omega. i.e. for every calculation, it takes the previous values in the delta_omega array, adds them together and uses that value to perform the calculation again and so on. I'm really not sure how to go about this as I want to plot these results too.
import numpy as np
import matplotlib.pyplot as plt
delta_omega = np.linspace(-900*10**6, -100*10**6, m) #Hz - range of frequencies
i = 0
while i<len(delta_omega):
delta = delta_omega[i] - (k*v_cap) + (mu_eff*B)/hbar
p_ee = (s0*L/2) / (1 + s0 + (2*delta/L)**2) #population of the excited state
R = L * p_ee # scattering rate
F = hbar*k*(R) #scattering force on atoms
a = F/m_Rb #acceleration assumed constant
vf_slower = (v_cap**2 - (2*a*z0))**0.5 #velocity at the end of the slower
t_d = 1/a * (v_cap - vf_slower) #time taken during slower
# -------- After slower --------
da = 0.1 #(m) distance from end of slower to the middle of the MOT
vf_MOT = (vf_slower**2 - (2*a*da))**0.5 #(m/s) - velocity of the particles at MOT center
t_a = da/vf_MOT #(s) time taken after slower
r0 = 0.01 #MOT capture radius
vr_max = r0/(t_b+t_d+t_a) #maximum transveral velocity
vz_max = (v_cap**2 + 2*a_max*z0)**0.5 #m/s - maximum axial velocity
# -------- Flux of atoms captured --------
P = 10**(4.312-(4040/T)) #vapour pressure for liquid phase (use 4.857 for solid phase)
A = 5*10**-4 #area of the oven aperture
n = P/(k_b*T) #atomic number density
f_oven = ((n*A)/4) * (2/(np.pi)**0.5) * ((2*k_b*T)/m_Rb)**0.5
f = f_oven * (1 - np.exp(-vr_max**2/vp**2))*(1 - np.exp(-vz_max**2/vp**2))
i+=1
plt.plot(delta_omega, f)
A simple cumulative sum would be defining the variable outside the loop and adding to it
i = 0
x = 0
while i < 10:
x = x + 5 #do your work on the cumulative value here
i += 1
print("cumulative sum: {}".format(x))
so define a variable that will contain the cumulative sum, and every loop, add to it
Related
I'm trying to calculate the dimensionless pressure and plot it with dimensionless time from 0 to 1. using this equation P_dim.append((2piPP['k']*res['h']/(-Q[840]*pvt['muo']30))(3000-Pn_imp[840])). but I'm getting negative values close to -0.9 which is wrong. How can I calculate it ?
P = np.zeros((Nx,Ny))
m=len(t) # time range for pressure calculation
print(Pint)
print(np.matmul(Act,Pint) )
A_term_imp=Act + T + J # first term of pressure equation using implicit method
B_term_imp = np.matmul(Act,Pint) + Q
Pn_imp = np.linalg.solve(A_term_imp, B_term_imp)
print(np.linalg.solve(A_term_imp, B_term_imp))
p_840=[]
Pwl=[]
time=[]
P_dim=[]
for j in range(1,m+1):
A_term_imp=Act + T + J # first term of pressure equation using implicit method
B_term_imp = np.matmul(Act,Pint) + Q # second term of pressure equation using implicit method
Pn_imp = np.linalg.solve(A_term_imp, B_term_imp)
# Pwl.append(Pn_imp)
# time.append(0.01*j)
if j==1:
print(Pn_imp)
# average = Average(Pn_imp)
# print(average)
print('Pressure matrix at time step '+str(j*dt)+' days, implicit method is ',Pn_imp, ' psi', '\n')
Pint = Pn_imp
p_840.append(Pn_imp[840])
P_dim.append((2*pi*PP['k']*res['h']/(-Q[840]*pvt['muo']*30))*(3000-Pn_imp[840]) #dimenssionless pressure
for j in range(1,m):
P=Pn_imp
P = np.reshape(P, (dy.shape[0], dy.shape[0]))
I want the while loop at the end of my code to perform the calculation for each component of delta_omega, and print the result before moving on to the next number in the delta_omega array. When I run the code python outputs 'The rate of capture at a detuning of -5000000 is 3.0E+13' an infinite number of times before I manually stop it. I am unsure of why this is happening and how to fix it? I tried using break at the end of the loop, but this just performed the calculation once for the first component of the delta_omega array.
import numpy as np
from scipy.integrate import odeint
#import matplotlib.pyplot as plt
# Constants
m_Rb = 1.443*10**-25 #mass of rubidium 87
k_b = 1.38*10**-23
h = 6.63*10**-34
hbar = 1.05*10**-34
L = 38.116*10**6 #natural linewidth
epsilon_0 = 8.85418782*10**-12 #permittivity of free space
# Changable paramaters
lmbda = 780*10**-9 #wavelength of laser light
k = (2*np.pi)/lmbda #wavevector of laser light
B = 5*10**-4 #magnetic field strength
# D2 effective magetic moment
gj_gnd = 1 + (0.5*(0.5+1) + 0.5*(0.5+1) - 0*(0+1))/(2*0.5*(0.5+1))
mj_gnd = 0.5
gj_ex = 1 + (1.5*(1.5+1) + 0.5*(0.5+1) - 1*(1+1))/(2*1.5*(1.5+1))
mj_ex = 1.5
Bohr = 9.274*10**-24 #Bohr magneton value
mu_eff = Bohr*(gj_ex*mj_ex - gj_gnd*mj_gnd)
# -------- Before slower --------
T = 700 #temperature of oven
vp = ((2*k_b*T)/m_Rb)**0.5 #mean velocity of particles coming out of the oven
x_os = 0.1
a = (hbar*L*k)/(2*m_Rb) #max decelleration of atoms
vf_oven = (vp**2 + (2*a*x_os))**0.5
t_b = (2*x_os)/(vp + vf_oven) #time taken from oven to start of slower
# -------- During slower --------
length_slow = 0.5
vz_max = (vf_oven**2 + 2*a*length_slow)**0.5
Z = 0.7
#Z = np.linspace(0, length_slow, 100)
P = 10**(4.312-(4040/T)) #vapour pressure for liquid phase (use 4.857 for solid phase)
A = 5*10**-4 #area of the oven aperture
n = P/(k_b*T) #atomic number density
I = 1*10**5 #intensity
n0 = 1 #refraction constant for medium
E_0 = ((2*I)/(3*10**8*n0*epsilon_0))**0.5
Rabi = (E_0*3.5844*10**-29)/hbar
II_sat = (2*Rabi**2)/L**2
delta_omega = np.array([-5*10**6, -10*10**6, -30*10**6]) #range of frequencies
i = 0
while i<len(delta_omega):
B_p = (h/mu_eff) * (delta_omega[i] + (1/lmbda)*(vf_oven**2 - (2*a*length_slow))**0.5)
B_n = (h/mu_eff) * (delta_omega[i] - (1/lmbda)*(vf_oven**2 - (2*a*length_slow))**0.5)
delta_n = delta_omega[i] + (k*vf_oven) - (mu_eff*B_n)/hbar
delta_p = delta_omega[i] - (k*vf_oven) + (mu_eff*B_p)/hbar
F = (hbar*k*L)/2 * ((II_sat/(1+II_sat+(2*delta_n/L)**2))
- (II_sat/(1+II_sat+(2*delta_p/L)**2)))
accn = abs(F/m_Rb)
vf_slower = (vf_oven**2 - (2*accn*length_slow))**0.5
t_d = 1/accn * (vf_oven - vf_slower) #time taken during slower
# -------- After slower --------
da = 0.1 #distance from end of slower to the middle of the MOT
vf_MOT = (vf_slower**2 - (2*accn*da))**0.5
t_a = da/vf_MOT #time taken after slower
r0 = 0.01 #MOT capture radius
vr_max = r0/(t_b+t_d+t_a)
# -------- Flux of atoms captured --------
f_oven = ((n*A)/4) * (2/(np.pi)**0.5) * ((2*k_b*T)/m_Rb)**0.5
f = f_oven * (1 - np.exp(-vr_max**2/vp**2))*(1 - np.exp(-vz_max**2/vp**2))
print('The rate of capture at a detuning of', delta_omega[i], 'is', format(f, '.1E'))
It seems you forgot to increment i within the loop...
I am new here and new in programming, so excuse me if the question is not formulated clearly enough.
For a uni assignment, my labpartner and I are programming a predator-prey system.
In this predator-prey system, there is a certain load factor 'W0'.
We want to find a load factor W0, accurate to 5 significant digits, for which applies that there will never be less than 250 predators (wnum[1] in our code). We want to find this value of W0 and we need the code to carry on further calculations with this found value of W0. Here is what we've tried so far, but python does not seem to give any response:
# Import important stuff and settings
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
print ('Results of Group 4')
def W0():
W0 = 2.0
while any(wnum[1])<250:
W0 = W0-0.0001
return W0
def W(t):
if 0 <= t < 3/12:
Wt = 0
elif 3/12 <= t <= 8/12:
Wt = W0
elif 8/12 < t < 1:
Wt = 0
else:
Wt = W(t - 1)
return Wt
# Define the right-hand-side function
def rhsf(t,y):
y1 = y[0]
y2 = y[1]
f1 = (2-2*10**-3*y2)*y1-W(t)*y1
f2 = (-3.92+7*10**-3*y1)*y2
return np.array([f1,f2])
# Define one step of the RK4 method
def RK4Step(tn,wn,Dt,f):
# tn = current time
# wn = known approximation at time tn
# Dt = the time step to use
# f = the right-hand-side function to use
# wnplus1 = the new approximation at time tn+Dt
k1 = Dt*f(tn,wn)
k2 = Dt*f(tn+0.5*Dt,wn+0.5*k1)
k3 = Dt*f(tn+0.5*Dt,wn+0.5*k2)
k4 = Dt*f(tn+Dt,wn+k3)
wnplus1 = wn + 1/6*(k1 +2*k2 +2*k3 +k4)
return wnplus1
# Define the complete RK4 method
def RK4Method(t0,tend,Dt,f,y0):
# t0 = initial time of simulation
# tend = final time of simulation
# Dt = the time step to use
# f = the right-hand-side function to use
# y0 = the initial values
# calculate the number of time steps to take
N = int(np.round((tend-t0)/Dt))
# make the list of times t which we want the solution
time = np.linspace(t0,tend,num=N+1)
# make sure Dt matches with the number of time steps
Dt = (tend-t0)/N
# Allocate memory for the approximations
# row i represents all values of variable i at all times
# column j represents all values of all variables at time t_j
w = np.zeros((y0.size,N+1))
# store the (given) initial value
w[:,0] = y0
# Perform all time steps
for n,tn in enumerate(time[:-1]):
w[:,n+1] = RK4Step(tn,w[:,n],Dt,f)
return time, w
# Set all known values and settings
t0 = 0.0
tend = 10.0
y0 = np.array([600.0,1000.0])
Dt = 0.5/(2**7)
# Execute the method
tnum, wnum = RK4Method(t0,tend,Dt,rhsf,y0)
# Make a nice table
alldata = np.concatenate(([tnum],wnum),axis=0).transpose()
table = pd.DataFrame(alldata,columns=['t','y1(t)','y2(t)'])
print('\nA nice table of the simulation:\n')
print(table)
# Make a nice picture
plt.close('all')
plt.figure()
plt.plot(tnum,wnum[0,:],label='$y_1$',marker='o',linestyle='-')
plt.plot(tnum,wnum[1,:],label='$y_2$',marker='o',linestyle='-')
plt.xlabel('$t$')
plt.ylabel('$y(t)$')
plt.title('Simulation')
plt.legend()
# Do an error computation
# Execute the method again with a doubled time step
tnum2, wnum2 = RK4Method(t0,tend,2.0*Dt,rhsf,y0)
# Calculate the global truncation errors at the last simulated time
errors = (wnum[:,-1] - wnum2[:,-1])/(2**4-1)
print('\nThe errors are ',errors[0],' for y1 and ',errors[1],' for y2 at time t=',tnum[-1])
I solve the heat equation for a metal rod as one end is kept at 100 °C and the other at 0 °C as
import numpy as np
import matplotlib.pyplot as plt
dt = 0.0005
dy = 0.0005
k = 10**(-4)
y_max = 0.04
t_max = 1
T0 = 100
def FTCS(dt,dy,t_max,y_max,k,T0):
s = k*dt/dy**2
y = np.arange(0,y_max+dy,dy)
t = np.arange(0,t_max+dt,dt)
r = len(t)
c = len(y)
T = np.zeros([r,c])
T[:,0] = T0
for n in range(0,r-1):
for j in range(1,c-1):
T[n+1,j] = T[n,j] + s*(T[n,j-1] - 2*T[n,j] + T[n,j+1])
return y,T,r,s
y,T,r,s = FTCS(dt,dy,t_max,y_max,k,T0)
plot_times = np.arange(0.01,1.0,0.01)
for t in plot_times:
plt.plot(y,T[t/dt,:])
If changing the Neumann boundary condition as one end is insulated (not flux),
then, how the calculating term
T[n+1,j] = T[n,j] + s*(T[n,j-1] - 2*T[n,j] + T[n,j+1])
should be modified?
A typical approach to Neumann boundary condition is to imagine a "ghost point" one step beyond the domain, and calculate the value for it using the boundary condition; then proceed normally (using the PDE) for the points that are inside the grid, including the Neumann boundary.
The ghost point allows us to use the symmetric finite difference approximation to the derivative at the boundary, that is (T[n, j+1] - T[n, j-1]) / (2*dy) if y is the space variable. Non-symmetric approximation (T[n, j] - T[n, j-1]) / dy, which does not involve a ghost point, is much less accurate: the error it introduces is an order of magnitude worse than the error involved in the discretization of the PDE itself.
So, when j is the maximal possible index for T, the boundary condition says that "T[n, j+1]" should be understood as T[n, j-1] and this is what is done below.
for j in range(1, c-1):
T[n+1,j] = T[n,j] + s*(T[n,j-1] - 2*T[n,j] + T[n,j+1]) # as before
j = c-1
T[n+1, j] = T[n,j] + s*(T[n,j-1] - 2*T[n,j] + T[n,j-1]) # note the last term here
I am trying to analyse a wave on a string by solving the wave equation with Python. Here are my requirements for the solution.
1) I model reflective ends by using much larger masses on first and last point on the string -> Large inertia
2)No spring on edges. Then k[0] and k[-1] will be ZERO.
I have problem with indices. In my 2nd loop I get y[i,j-1], k[i-1], y[i-1,j]. In the first iteration the loop will then use y[0,-1], k[-1], y[-1,0]. These are my last points and not my first points. How can I avoid this problem?
What you need is initiating your mass array with one additional element. I mean
...
m = [mi]*N # mass array [!!!] instead of (N-1) [!!!]
...
Idem for your springs
...
k = [ki]*N
...
Consequently, you can keep k[0] equal to 10. since you model reflective ends. You may thus want to comment or drop this line
...
##k[0] = 0
...
For aesthetic considerations you may want to fill the gap at the end of the x-axis. In this case, simply do
N = 201 # Number of mass points
Your code thus becomes
from numpy import *
from matplotlib.pyplot import *
# Variables
N = 201 # Number of mass points
nT = 1200 # Number of time points
mi = 0.02 # mass in kg
m = [mi]*N # mass array
m[-1] = 100 # Large last mass reflective edges
m[0] = 100 # Large first mass reflective edges
ki = 10.#spring
k = [ki]*N
k[-1] = 0
dx = 0.2
kappa = ki*dx
my = mi/dx
c = sqrt(kappa/my) # velocity
dt = 0.04
# 3 vectors
x = arange( N )*dx # x points
t = arange( N )*dt # t points
y = zeros( [N, nT ] )# 2D array
# Loop over initial condition
for i in range(N-1):
y[i,0] = sin((7.*pi*i)/(N-1)) # Initial condition dependent on mass point
# Iterating over time and position to find next position of wave
for j in range(nT-1):
for i in range(N-1):
y[i,j+1] = 2*y[i,j] - y[i,j-1] + (dt**2/m[i])*(k[i-1]*y[i+1,j] -2*k[i-1]*y[i,j] + k[i]*y[i-1,j] )
#check values of edges
print y[:2,j+1],y[-2:,j+1]
# Creates an animation
cla()
ylabel("Amplitude")
xlabel("x")
ylim(-10,10)
plot(x,y[:,j-2])
pause(0.001)
close()
which produces
Following your comment, I think that if you want to see the wave traveling along the string before reflection, you should not initiate conditions everywhere (in space). I mean, e.g., doing
...
# Loop over initial condition
for i in range(N-1):
ci_i = sin(7.*pi*i/(N-1)) # Initial condition dependent on mass point
if np.sign(ci_i*y[i-1,0])<0:
break
else:
y[i,0] = ci_i
...
produces
New attempt after answers:
from numpy import *
from matplotlib.pyplot import *
N = 201
nT = 1200
mi = 0.02
m = [mi]*(N)
m[-1] = 1000
m[0] = 1000
ki = 10.
k = [ki]*N
dx = 0.2
kappa = ki*dx
my = mi/dx
c = sqrt(kappa/my)
dt = 0.04
x = arange( N )*dx
t = arange( N )*dt
y = zeros( [N, nT ] )
for i in range(N-1):
y[i,0] = sin((7.*pi*i)/(N-1))
for j in range(nT-1):
for i in range(N-1):
if j == 0: # if j = 0 then ... y[i,j-1]=y[i,j]
y[i,j+1] = 2*y[i,j] - y[i,j] + (dt**2/m[i])*(k[i-1]*y[i+1,j] -2*k[i-1]*y[i,j] + k[i]*y[i-1,j] )
else:
y[i,j+1] = 2*y[i,j] - y[i,j-1] + (dt**2/m[i])*( k[i-1]*y[i+1,j] -2*k[i-1]*y[i,j] + k[i]*y[i-1,j] )
cla()
ylim(-1,1)
plot(x,y[:,j-2])
pause(0.0001)
ylabel("Amplitude")
xlabel("x")
print len(x), len(t), N,nT
Here is a plot of the new attempt at solution with |amplitude| of anti node equal 1.0. Will this do anything with further solving the issue with indices?