Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Step by Step Propagation With a Short Focal Length Lens #64

Open
IvanOstr opened this issue Sep 5, 2021 · 3 comments
Open

Step by Step Propagation With a Short Focal Length Lens #64

IvanOstr opened this issue Sep 5, 2021 · 3 comments

Comments

@IvanOstr
Copy link

IvanOstr commented Sep 5, 2021

Hey there again!
This time i'm trying to propagate a gaussian beam through a f = 15cm lens, but at small increments - ideally by 250micron.
In order to do it with Forvard (which by the way has less problems then Fresnel) without strange issues (seen in the image below) I need 10000 points in my grid and even more.
I'll give here in example:
This is how propagation looks with a N = 2000 grid as compared to N = 5000:
image

Also, I'm quite sure the strange phenomenon we see is due to grid spacing and not boundry effects.
The code for this is (1) below.

  1. I've tried the solution with the spherical coordinates - although I didn't understand the physics of it - exactly as you did in the example in the website, but i'm not sure if I did correct considering I want a propagation with steps. Could you please elaborate the trick with the f1/f2 and give me a hint if that can work with steps? Code in (2)
  2. The main problem with 10000 points is that it takes a lot of time for me to propagate 600 points from 0 to 15cm. Is there a way to use more computational power in the Lightpipes simulation?
  3. Is there a way to get rid of the smaller ocillations occuring all around the beam?

Code for (1):
from LightPipes import*
import numpy as np
import matplotlib.pyplot as plt
import LightPipes
import time

start_time = time.time()

wavelength = 800*nm
k = 2*np.pi/wavelength
size = 40*mm
N = 5000
R = 12*mm # beam radius
center = round(N/2)

F = Begin(size, wavelength, N)
F = GaussBeam(R, F)

yy, xx = F.mgrid_cartesian

########## propagation with steps ##############
f1 = 15*cm
fi = -k * (xx ** 2 + yy ** 2) / (2 * f1)
F_with_steps = LightPipes.Field.copy(F)
F_with_steps.field *= np.exp(1j * fi)

d = f1 + 2*cm
step_size = 5*cm
len = 0
while len <= d:
    len += step_size
    F_with_steps = Forvard(F_with_steps, step_size)

    I_with_steps = Intensity(F_with_steps, 0)[center, :]
    plt.figure()
    plt.title('Prop. Len: ' + str(len))
    plt.plot(I_with_steps)

time_took = time.time() - start_time

Code for (2):
from LightPipes import*
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import LightPipes
import time

start_time = time.time()

wavelength = 800*nm
k = 2*np.pi/wavelength
size = 40*mm
N = 2000
R = 12*mm # beam radius
center = round(N/2)

F = Begin(size, wavelength, N)
F = GaussBeam(R, F)

yy, xx = F.mgrid_cartesian

########## propagation with steps ##############
f1 = 10*m
f = 15*cm
f2 = f1*f/(f1-f)

len = 0
d = 5*cm
step_size = 1*cm
F_with_steps = LightPipes.Field.copy(F)
F_with_steps = Lens(F_with_steps, f1)
while len <= d:
    len += step_size

    F_with_steps = LensForvard(F_with_steps, f2, len)
    F_with_steps = Convert(F_with_steps)

    I_with_steps = Intensity(F_with_steps, 0)[center, :]
    plt.figure()
    plt.title('Prop Len' + str(len))
    plt.plot(I_with_steps)

time_took = time.time() - start_time

Thanks,
Ivan

@FredvanGoor
Copy link
Member

In general, and especially with lenses, you have to be careful not to violate the Nyquist criterium. The maximum spatial frequency of your problem (= max(derivative of the phase with respect to x and y coordinate) ) should be smaller than the maximum spatial frequency given by the grid-spacing (= N/2/size)

@FELman2011
Copy link

When you propagate from a source plane (here optical field after the thin lens) to a target plane at various distances, it is best practice to preserve the source and repeatedly propagate from source plane to new target plane. This avoids buildup of errors during the propagation. For example, when you want to propagate the optical field Field at the source plane to target planes that are in the range z_start to z_end away from the source plane, you could use:

Nz=50                                    # number of steps in range z_start to z_end
z0 = z_start
dz = (z_end -z_start)/Nz

I1=np.zeros((Nz,GridDimension))
I2=np.zeros((Nz,GridDimension))

for i in range(Nz):
   F = Forvard(Field,z0)
   I = np.array(Intensity(F))
   I1[i,:] = I[int(GridDimension/2),:]
   I2[i,:] = I[:,int(GridDimension/2)]
   z0 += dz

@IvanOstr
Copy link
Author

IvanOstr commented Oct 6, 2021

FELman2011:
Unfortunately I'm simulating an effect that has to be propagated step by step (if you are more insterested - self foucing via kerr effect), so I can't run from this problem. In a matter of fact, the errors of propagation with steps and without them are quite small so my problem is mainly the inefficient running time.

FredvanGoor:
Thanks, thats a good tip.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants