Plotting, Beam Coupling, Propagation
Plotting modes
Plotting all the modes is useful both for visualisation, as well as performing
numerical integration required for coupling in beams or determining the
power in the core. Plotting is easiest to perform using the Solution
class, although low-level functions can also be used directly.
Assuming we already have a list of modes stored in modes, obtained from
lpmodes.find_modes(), we then need to define the size of the square grid,
in pixels, and also in physical units:
grid_size = 150 # pixels
max_plot_radius = 15 # microns
The max_plot_radius is half of the width or height of the plot. For
a core radius of 10 microns, a max_plot_radius of 15 microns will ensure all
the core plus a reasonable extent of the cladding is plotted.
We then create an instance of the Solution class. Creating this instance
plots all the modes, and so this line may take several
seconds to execute, depending on the number of modes and grid size chosen:
solution = lpmodes.Solution(modes, grid_size, max_plot_radius)
If we do not specifiy the max_plot_radius, it will automatically chosen to be
1.5 times the core_radius that the modes in modes were calculated for.
The mode plots are now available as 3D numpy arrays. For example, plots of the
amplitude of the cosine orientations are stored in solution.mode_cos. The
3D array is organised as (mode number, x co-ord, y co-ord). To extract the
3rd mode plot, for example, you can use:
mode_3 = solution.mode_cos[2]
which will return a 2D numpy array containing a plot of the 3rd mode. The
sine orientations are stored in mode_sin, and intensity plots are stored
in mode_sin_intensity and mode_cos_intensity.
The mode details are now stored in solution.modes. If the index of a mode
with specific l and m values is required, use the find_mode_idx() function, e.g.
to obtain the plot of the l = 1, m = 2 mode:
mode_12 = solution.mode_cos[lpmodes.find_mode_idx(solution.modes, 1, 2)]
Coupling Into Modes
To simulate couling a beam into the simulated fibre, we require a representation of the electric field as 2D complex numpy array. The array must have the same dimension and physical pixel size as the mode plots were created for.
Functions are provided to generate plane waves (with a tilt) or Gaussian
shaped beams, which are two common use cases. Assume we have created a
Solution with a grid_size of 100 and a max_plot_radius of 15 microns.
We can generated a Gaussian beam with a sigma of 5 microns, centred on the fibre,
using:
field_size = max_plot_radius * 2
sigma = 5
position = (0,0)
g_field = lpmodes.gaussian_field(grid_size, field_size, position, sigma)
We have set field_size to twice max_plot_radius because the mode plots
run from -max_plot_radius to +max_plot_radius. To produce an offset
beam, set position to a tuple of (x pos, y pos). The position is in microns
relative to the centre of the field, and can can be positive or negative.
The field can now be coupled in to the fibre using the couple_field method
of the Solution class. Assuming we have created a solution stored in solution:
solution.couple_field(g_field)
The complex amplitude in each mode is now stored in solution.cos_amp and
solution.sin_amp, for the sine and cosine orientations of the modes. Each
of these is a 1D complex numpy array. The amplitudes can be obtained using
np.abs(solution.sin_amp).
The power in each mode (combined sine and cosine
orientations) is stored in solution.mode_power. The total power coupled
is stored in solution.power_coupled. If the input field is normalised to
have a total power of 1, as the fields generated by gaussian_field() and
tilted_field() are, this will be the coupling efficiency.
Plotting the Coupled Field
A plot of the coupled field, as a 2D complex numpy array, is obtained using:
field = solution.get_in_field()
or the coupled intensity distribution using:
intensity = solution.get_in_intensity()
The grid size and pixel size are as defined when the modes and field to couple were plotted.
Propagating the Coupled Field
The field coupled into the fibre is propagated along a length of the fibre by:
distance = 2000 # microns
solution.propagate(distance)
The complex amplitudes for each mode are then stored in the 1D arrays in
solution.prop_cos_amp and solution.prop_sin_amp. The amplitudes do not
change, only the phases. The total field after
propgation is stored in solution.prop_field as a 2D complex numpy array, and
the intensity distribution is in solution.prop_intensity, as a 2D
real numpy array.
To allow random rotations of the modes during propagation,
pass the keyword argument rotations = True.