TheLartians / PyPropagate

A paraxial wave propagation framework for python
GNU General Public License v3.0
5 stars 7 forks source link

How to create a custom source? #44

Closed Ganyme-d closed 6 years ago

Ganyme-d commented 6 years ago

I am trying to simulate a thin film on top of a substrate layer interacting with an x-ray plane wave source at a shallow angle (<2°) but none of the examples explain how to customize the source in anyway outside of the energy. I tried to figure it out myself by looking through the source code but that part is not really commented and as far as I can tell the few examples are the complete documentation so I have to ask some stupid questions.

Thanks in advance

TheLartians commented 6 years ago

The idea is to define the initial field u0 as the appropriate scalar field from your source. To define a beam traveling at an small angle alpha in the xz plane, you would multiply a phase factor exp(-ikx sin(alpha)) to the beam's initial profile.

For example, the following script defines, propagates and plots a gaussian beam traveling downwards at an angle of 0.1 degrees in a perfectly reflective box.

from pypropagate import *

settings = presets.settings.create_paraxial_wave_equation_settings() # stores simulation parameters s = settings.symbols # shortcut to relevant parameters
s = settings.symbols # shortcut to relevant parameters

# define the initial condition as a 1D gaussian profile propagating at a small angle
angle = -0.1*units.degrees
phase_shift = pc.exp(-1j*s.k*pc.sin(angle)*s.x) # phase shift resulting from the rotation
gaussian_profile = pc.exp(-s.x**2/(2*(10*units.nm)**2))
s.u0 = gaussian_profile * phase_shift 

s.n = 1 # free-space propagation
s.u_boundary = 0 # reflective boundary condition
settings.simulation_box.set((100*units.nm,100*units.nm,0.1*units.mm),(1024,1024,2000)) # set simulation boxphysical and voxel size
settings.wave_equation.set_energy(100*units.keV) # set photon energy

propagator = propagators.FiniteDifferences2D(settings) # initialize propagation algorithm
field = propagator.run_slice()[:,:] # propagate and store the resulting 2D field

plot(field) # plot result

As for documentation, I've finally uploaded the complete thesis covering the mathematical theory behind PyPropagate and also many more examples.

Free to ask if you need any more support.