lbolla / empy Goto Github PK
View Code? Open in Web Editor NEWElectromagnetic Python
License: MIT License
Electromagnetic Python
License: MIT License
Please help why i can't import EMpy
still display
import EMpy
Traceback (most recent call last):
File "", line 1, in
ImportError: No module named 'EMpy
Hi!
windows python 3.11
pip install ElectromagneticPython
fails due to mismatch in version metadata
had to do :
pip install --upgrade --no-cache-dir --use-depreciated=legacy-resolver ElectromagneticPython
to force it to install.
i will git clone the repo (mainly to get the examples for thin film and grating scattering) and see if its an easy fix....
Thanks for making this open source so i can independently verify the commercially provided spectra fitting programs from kla, noca, n&k etc.
cheers
Dan
Does this package have a more detailed user manual or program manual?
Hi there! I just started using EMPy - it looks really cool. I am interested in calculating waveguide modes, so I have been playing around with the VFDModesolver. It looks pretty similar to the matlab code "wgmodes", but I noticed that there in this version, there was no place to enter the "guess" for the refractive index as there is in wgmodes, which has the parameter "guess", described as:
% guess - scalar shift to apply when calculating the eigenvalues.
% This routine will return the eigenpairs which have an
% effective index closest to this guess
Additionally, I was wondering if there were other significant ways that VFDModesolver performs differently from wgmodes. As I learn more about the VFDModesolver, I may add some docstrings and comments - would that be something that you would be receptive to?
Thanks!
Dan
I've found the EMpy solutions break down when changing the wave angle. I've attached my binary grating test below.
The following example outputs a solution which is the same as the Gsolver solution for the same binary grating. The Gsolver parameters are as follows: Theta: 0 Phi: 0 Alpha: 90 Beta: 0
import numpy
import pylab
import EMpy
from EMpy.materials import IsotropicMaterial, RefractiveIndex
alpha = EMpy.utils.deg2rad(0.) #Angle of incidence
delta = EMpy.utils.deg2rad(0.)
psi = EMpy.utils.deg2rad(0.) # TE
phi = EMpy.utils.deg2rad(90.) #azimuth
LAMBDA = 900e-9
ns = 1 # orders of diffraction
Top = IsotropicMaterial('Top', n0=RefractiveIndex(n0_const=1.0))
Bottom = IsotropicMaterial('Bottom', n0=RefractiveIndex(n0_const=1.45032))
solutions = []
wls = numpy.linspace(.909e-6, 1.500e-6, 30)
multilayer = EMpy.utils.Multilayer([
EMpy.utils.Layer(Top, numpy.inf),
#EMpy.utils.SymmetricDoubleGrating(Top,Top,Bottom,.25,.25, LAMBDA, 1200e-9),
EMpy.utils.BinaryGrating(Top,Bottom, .5, LAMBDA, 1200e-9),
EMpy.utils.Layer(Bottom, numpy.inf),
])
solution = EMpy.RCWA.AnisotropicRCWA(
multilayer, alpha, delta, psi, phi, ns).solve(wls)
#Ns +1 == Gsolver -1?
#Ns == Gsolver 0
#Ns -1 == Gsolver +1?
n=0
pylab.plot(wls*1e9, solution.DEE1[ns+n, :], 'ko-',
wls*1e9, solution.DEE3[ns+n, :], 'ro-',
wls*1e9, solution.DEO1[ns+n, :], 'ko-',
wls*1e9, solution.DEO3[ns+n, :], 'ro-',
#wls*1e9, solution.DEE1[2, :], 'kx-',
#wls*1e9, solution.DEE3[2, :], 'rx-',
#wls*1e9, solution.DE1[ns + 1, 0], 'k.-',
#wls*1e9, solution.DE3[ns + 1, 0], 'r.-',
)
pylab.xlabel('wavelength /m')
pylab.ylabel('diffraction efficiency')
pylab.legend(('DE1:0', 'DE3:0', 'DE1:1', 'DE3:1', 'DE1:+2', 'DE3:+2'))
pylab.axis('tight')
pylab.ylim([0, 1])
pylab.show()
If we change our phi and Gsolvers Alpha to 0 degrees our solutions no longer follow.
We update the above code to have..
alpha = EMpy.utils.deg2rad(0.) #Angle of incidence
delta = EMpy.utils.deg2rad(0.)
psi = EMpy.utils.deg2rad(0.) # TE
phi = EMpy.utils.deg2rad(0.) #azimuth
Gsolver parameters as follows: Theta: 0 Phi: 0 Alpha: 0 Beta: 0
What are your thoughts, Is my code incorrect?
Thanks for the excellent work.
I am a new on metasurface. I wanna define a meta-atom consists of a cylinder with a glass substrate, which is a periodic unit of a 2D binary grating, and I wanna get the transmittance of the plane wave with different frequencies. Here is the model I made in Lumerical FDTD solutions.
Is there any example that is similar to this task that I can refer to?
Hi there,
I have tried several times and ways to install the EMpy but still cannot make it.
I have searched the meaning of the error code and followed the ways how others solved their issue.
Error: "python setup.py egg_info" failed with error code 1
Many people met this problem because of the out-of-date setuptools in Python, and they solved their problem by updating the setuptools in their Python.
However, I still cannot install EMpy after updating the setuptools.
Does anyone recently install the EMpy successfully or know how to solve this problem?
Thanks in advance.
I would like to use an anisotropic refractive index with the FD modesolver. This seems to basically be implemented, but I can't figure out a practical way to make my "epsfunc" return a 2D array of length-5 tuples. To me, it seems more practical to have the function return a NxMx5 numpy array, but this is not quite compatible with the current code (seems easy to modify).
Before I start hacking the VFDModeSolver function, I thought that I would ask: do you already have an example of how to work with an anisotropic refractive index?
First of all, good work on this!!! It's almost like a dream come true!
Anyway, I'm really new to Python, so maybe I was doing something very wrong. I'm on Manjaro Linux (Arch-based), using Python 3.6. I tried installing the module from pip, but it always failed when installing the "distribute" package. Searching about it, I found that it is now simply a compatibility layer that installs SetupTools, which was already installed.
So, using "--no-deps" with pip enabled me to install EMpy, and it's working beautifully! So maybe it's an unecessary dependency?
@lbolla : I found a bug in RefractiveIndex.__from_function()
, in which the function erroneously passed an array of ones [1,1,1...]
via the numpy.ones_like(...)
value, instead of the actual wavelength values [1.55e-6,1.54e-6...]
, to the RIX function supplied by the user.
In my recent fork (to add laser monitor example), I've updated this to return n0_func(wls) * numpy.ones_like(wls)
similar to your other functions.
See https://github.com/demisjohn/EMpy/commit/7813056e58b0d4872e176b3593c503f5b4ac9ce2
However, I'm wondering why you multiply the wavelengths wls
by numpy.ones_like()
in the first place. What is the purpose of this? Should I omit that entirely?
Currently, installing EMpy downgrades my matplotlib 2.0 to 1.5.x. Is there a reason that EMpy is not compatible with matplotlib 2.0?
In general, it seems weird that setup.py specifies maximum version numbers for the required packages. Typically, minimum version numbers are specified. (I.e., should the <
signs be >
?)
install_requires=[
'distribute>=0.6.28',
'future<1.0dev',
'numpy<2.0dev',
'scipy<1.0dev',
'matplotlib<2.0dev',
],
Since underlying structure is List, assignments are by reference. The Multilayer.copy()
method is needed to prevent alteration of assigned objects.
Eg.:
>>> iso_layers = EMpy.utils.Multilayer()
< append layers to iso_layers >
>>> print(iso_layers)
Multilayer
----------
0: lyr 0, isotropic, thickness: 1.10352e-07
1: lyr 1, isotropic, thickness: 1.30269e-07
2: lyr 2, isotropic, thickness: 1.10352e-07
>>> test =iso_layers
>>> print(test)
Multilayer
----------
0: lyr 0, isotropic, thickness: 1.10352e-07
1: lyr 1, isotropic, thickness: 1.30269e-07
2: lyr 2, isotropic, thickness: 1.10352e-07
test
& iso_layers
are the same.
>>> iso_layers.pop(0) # remove 1st layer
<EMpy.utils.Layer object at 0x1176d0da0>
>>> print(iso_layers)
Multilayer
----------
0: lyr 1, isotropic, thickness: 1.30269e-07
1: lyr 2, isotropic, thickness: 1.10352e-07
>>> print(test)
Multilayer
----------
0: lyr 1, isotropic, thickness: 1.30269e-07
1: lyr 2, isotropic, thickness: 1.10352e-07
test
was also updated. Would usually use test =iso_layers.copy()
to prevent this, but the method doesn't exist.
Hi, I installed EMpy using
pip install ElectromagneticPython
and checked that it is installed:
pip show ElectromagneticPython
Name: ElectroMagneticPython
Version: 2.0.0
Summary: EMpy - ElectroMagnetic Python
Home-page: http://lbolla.github.io/EMpy/
Author: Lorenzo Bolla
Author-email: [email protected]
License: BSD
However, according to the master, the file FD.py contains the correct line 1369:
nlayers *= numpy.ones(4,dtype=int)
but in the installed version, the line is:
nlayers *= numpy.ones(4)
How can that be?
Thank you,
Tom
First of all, Thank for the excellent work!
I downloaded the tar.gz and the zip file from Homepage,
and install EMpy in both way.
(Installing tar.gz by pip, and adding sys.path to directory of decompressed zip file.)
I try to do some RCWA calculation.
For Layer both method came to the same result.
However, when it came to BinaryGrating and AsymmetricDoubleGrating,
the tar.gz one and zip one have different DE1 and DE3 result.
Comparing to my reference data, it seems the tar.gz's result is correct.
I'd like to know if anyone encountered the same problem?
And I'm try to found out the bug in github, however, haven't gotten an idea.
Do anyone have any idea?
Thinks for taking your time.
I'm trying to use your modesolver example #2 with the "CrossSection" & "Slices" method that I like very much (ex_modesolver_2.py
).
Your example only plots the mode versus grid/mesh points - the spatial dimension is missing.
If I insert the variables X
& Y
into the contourf
function, the solver.modes[0].Ex
array then doesn't match the X
& Y
arrays, I have to use numpy.rot90()
to get it to plot, indicating that the X & Y axes are flipped for some reason (and the mode shows up sideways).
(Also I have to strip one point off from each X/Y array, as CrossSection.grid()
is one value larger in each direction than the solver.modes[0].Ex
array.)
I am thus unable to figure out which way is the expected "up/down/left/right" in this example, it doesn't seem to match the passed X & Y arrays.
Is VFDModeSolver.solve()
returning the modes sideways, and missing one point in each dimension? Is it also solving them sideways?
I'm working on a paper where I present some results calculated using EMPy. Is there a preferred way that EMPy should be cited?
Hi
Is there a way to solve a waveguide mode (just like in your example ex_modesolver.py), but only in 1D (and not 2D like in the example)?
Thanks
Giovanni
It looks like the author copied and pasted this from wgmodes.m
The author should have copied and pasted from svmodes.m
The boundary conditions are not described properly in the docstring.
In SVFDModeSolver, the boundary string describes the conditions on the field being solved for (Ex, Ey, or scalar) not the Hx and Hx fields.
Hi all,
Just wondering whether the EMpy is capable of SRR simulaiton? I saw the example for ring resonators but I am unclear about how to model a gap ring in EMpy.
Thanks,
Shinong
Hey, I plan to use EMpy in order to calculate the fields for different waveguides. So far, I have been using a commercial software (Lumerical) but EMpy would be much more convenient since I could integrate it into other python scripts. However, after comparing the fields from the EMpy example (http://lbolla.github.io/EMpy/#example_modesolver) for the 2nd mode to the solution of the commercial software, I found them to be quiet different:
In order to check the E to H field relation I calculated the magnetic field from the Electric field using:
For the commercial software the resulting field is of the same order of magnitude as the field magnetic field calculated by the solver. For EMpy this is not the case.
Do I need to adapt anything in the example code? Thank you for your help.
Hello.
Sellmeier coefficient is defined by
(in form of)
n^2 = constant + B1 wl ^2 /(wl^2-C1) + B2 wl ^2 /(wl^2-C2) +B3 wl ^2 /(wl^2-C3)
as written in Wiki
But in materials.py, Sellmeier equation is written by
Set the rix dispersion function to the 6-parameter Sellmeier
function as so:
n(wls) = 1. +
B1 * wls ** 2 / (wls ** 2 - C1) +
B2 * wls ** 2 / (wls ** 2 - C2) +
B3 * wls ** 2 / (wls ** 2 - C3)
Sellmeier is about to "the square of refractive index" but the comments in the Method describe it as "the refractive index" itself.
I checked
def __from_sellmeier(n0_smcoeffs, wls)
I can see the script is right but the only description is wrong.
So the description should be updated correctly.
Thanks
I've been using EMpy every now and then, but am now running into an import error and am wondering if there've been changes to the numpy.testing library that conflict with EMpy. Please see the error below. Does anyone know what might be going on?
ImportError: cannot import name 'Tester' from 'numpy.testing' (C:\Users\username\AppData\Local\miniforge3\lib\site-packages\numpy\testing_init_.py)
Thanks,
Carsten
class SymmetricDoubleGrating(object): in utils.py
Initial assumptions:
if..
Top = IsotropicMaterial('Top', n0=RefractiveIndex(n0_const=1.0))
Bottom = IsotropicMaterial('Bottom', n0=RefractiveIndex(n0_const=1.5))
..
EMpy.utils.SymmetricDoubleGrating(Top,Top,Bottom,.25,.25,580e-9,d*nanometers)
..
Should effectively act as a 50% DC binary grating. I tested this theory in G solver and in it this holds true.
EMpy's
EMpy.utils.AsymmetricDoubleGrating(Top,Top,Bottom,.25,.25,.0,580e-9,d*nanometers),
..
EMpy.utils.AsymmetricDoubleGrating(Top,Top,Bottom,.25,.25,1,580e-9,d*nanometers),
Both act effectively as a 50% DC binary solution
However, the EMpy solution does not follow this case, Results below with results of proposed fix...
Plot 1 is the results of the Binary grating. Under it, labeled figure 3, are the results from the Asymmetrical grating class, which are in agreement with our binary test. The Symmetrical grating class initial results are shown in figure two, and the results from the Symmetrical class fix are shown in the final plot labeled figure 4.
Hot fix is as follows:
Find utils.py --> class
def getEPSFourierCoeffs(self, wl, n, anisotropic=True):
"""Return the Fourier coefficients of eps and eps**-1, orders [-n,n]."""
nood = 2 * n + 1
hmax = nood - 1
if not anisotropic:
# isotropic
rix1 = self.mat1.n(wl)
rix2 = self.mat2.n(wl)
rix3 = self.mat3.n(wl)
f1 = self.dc1
f2 = self.dc2
h = numpy.arange(-hmax, hmax + 1)
N = len(h)
A = -N / 4
B = N / 4
print(A,B)
EPS = (
rix3 ** 2 * (h == 0) + (rix1 ** 2 - rix3 ** 2) * f1 *
numpy.sinc(h * f1) * numpy.exp(2j * numpy.pi * h / N * A) +
(rix2 ** 2 - rix3 ** 2) * f2 * numpy.sinc(h * f2) *
numpy.exp(2j * numpy.pi * h / N * B)
)
EPS1 = (
rix3 ** -2 * (h == 0) + (rix1 ** -2 - rix3 ** -2) * f1 *
numpy.sinc(h * f1) * numpy.exp(2j * numpy.pi * h / N * A) +
(rix2 ** -2 - rix3 ** -2) * f2 * numpy.sinc(h * f2) *
numpy.exp(2j * numpy.pi * h / N * B)
)
return EPS, EPS1
else:
# anisotropic
EPS = numpy.zeros((3, 3, 2 * hmax + 1), dtype=complex)
EPS1 = numpy.zeros_like(EPS)
eps1 = numpy.squeeze(
self.mat1.epsilonTensor(wl)) / EMpy.constants.eps0
eps2 = numpy.squeeze(
self.mat2.epsilonTensor(wl)) / EMpy.constants.eps0
eps3 = numpy.squeeze(
self.mat3.epsilonTensor(wl)) / EMpy.constants.eps0
f1 = self.dc1
f2 = self.dc2
h = numpy.arange(-hmax, hmax + 1)
N = len(h)
A = -N / 4.
B = N / 4.
for ih, hh in enumerate(h):
EPS[:, :, ih] = (
(eps1 - eps3) * f1 * numpy.sinc(hh * f1) *
numpy.exp(2j * numpy.pi * hh / N * A) +
(eps2 - eps3) * f2 * numpy.sinc(hh * f2) *
numpy.exp(2j * numpy.pi * hh / N * B) +
eps3 * (hh == 0)
)
EPS1[:, :, ih] = (
(scipy.linalg.inv(eps1) - scipy.linalg.inv(eps3)) * f1 *
numpy.sinc(hh * f1) *
numpy.exp(2j * numpy.pi * hh / N * A) +
(scipy.linalg.inv(eps2) - scipy.linalg.inv(eps3)) * f2 *
numpy.sinc(hh * f2) *
numpy.exp(2j * numpy.pi * hh / N * B) +
scipy.linalg.inv(eps3) * (hh == 0)
)
return EPS, EPS1
Referencing the Asymmetric class I changed assignment statement of A,B vars to the following..
def getEPSFourierCoeffs(self, wl, n, anisotropic=True):
"""Return the Fourier coefficients of eps and eps**-1, orders [-n,n]."""
nood = 2 * n + 1
hmax = nood - 1
if not anisotropic:
# isotropic
rix1 = self.mat1.n(wl)
rix2 = self.mat2.n(wl)
rix3 = self.mat3.n(wl)
f1 = self.dc1
f2 = self.dc2
h = numpy.arange(-hmax, hmax + 1)
N = len(h)
A = -N*f1 / 2
B = N*f2 / 2
EPS = (
rix3 ** 2 * (h == 0) + (rix1 ** 2 - rix3 ** 2) * f1 *
numpy.sinc(h * f1) * numpy.exp(2j * numpy.pi * h / N * A) +
(rix2 ** 2 - rix3 ** 2) * f2 * numpy.sinc(h * f2) *
numpy.exp(2j * numpy.pi * h / N * B)
)
EPS1 = (
rix3 ** -2 * (h == 0) + (rix1 ** -2 - rix3 ** -2) * f1 *
numpy.sinc(h * f1) * numpy.exp(2j * numpy.pi * h / N * A) +
(rix2 ** -2 - rix3 ** -2) * f2 * numpy.sinc(h * f2) *
numpy.exp(2j * numpy.pi * h / N * B)
)
return EPS, EPS1
else:
# anisotropic
EPS = numpy.zeros((3, 3, 2 * hmax + 1), dtype=complex)
EPS1 = numpy.zeros_like(EPS)
eps1 = numpy.squeeze(
self.mat1.epsilonTensor(wl)) / EMpy.constants.eps0
eps2 = numpy.squeeze(
self.mat2.epsilonTensor(wl)) / EMpy.constants.eps0
eps3 = numpy.squeeze(
self.mat3.epsilonTensor(wl)) / EMpy.constants.eps0
f1 = self.dc1
f2 = self.dc2
h = numpy.arange(-hmax, hmax + 1)
N = len(h)
A = -N / 4.
B = N / 4.
for ih, hh in enumerate(h):
EPS[:, :, ih] = (
(eps1 - eps3) * f1 * numpy.sinc(hh * f1) *
numpy.exp(2j * numpy.pi * hh / N * A) +
(eps2 - eps3) * f2 * numpy.sinc(hh * f2) *
numpy.exp(2j * numpy.pi * hh / N * B) +
eps3 * (hh == 0)
)
EPS1[:, :, ih] = (
(scipy.linalg.inv(eps1) - scipy.linalg.inv(eps3)) * f1 *
numpy.sinc(hh * f1) *
numpy.exp(2j * numpy.pi * hh / N * A) +
(scipy.linalg.inv(eps2) - scipy.linalg.inv(eps3)) * f2 *
numpy.sinc(hh * f2) *
numpy.exp(2j * numpy.pi * hh / N * B) +
scipy.linalg.inv(eps3) * (hh == 0)
)
return EPS, EPS1
I have not tested Anisotropic just yet, but am working on getting it up shortly. By chance can you reference any literature on getting the Fourier coefficients? I read the following work and see the similarities, but I'm at a loss of how the multiple indices come together with relation to duty cycle.
https://www.osapublishing.org/josaa/abstract.cfm?uri=josaa-12-5-1068
What does empy.propagators.FDTD.py do?
There are some hard-coded usernames in the fetch_data
and put_data
functions that seem like they perhaps don't belong in the main EmPy package.
Hello,
i encountered the problem, that IsotropicTransferMatrix.solve() returns integer arrays (which is not useful) if one provides wavelengths as an integer like array. This could be circumvented by specifying the datatype float in the declaration of Rs, Ts, Rp, and Ts.
i was wondering if EMpy solves modes on a yee grid?
if so is there a way to get the X and Y components of that yee grid?
I noticed a function in the Class FDMode called get_fields_for_FDTD so is this the function i would need to get the mode on the yee grid?
I ask this because i wish to use these calculated mode profiles to initialize the boundary of a yee mesh to perform FDTD and was wondering what would be a good way of doing this?
In FD.py the documentation for the epsfunc states the following:
"epsfunc : function
This is a function that provides the relative permittivity (square of the refractive index)
as a function of the x and y position. The function must be of the form:
myRelativePermittivity(x,y)
The function can either return a single float, corresponding the an isotropic refractive index,
or, ir may a length-5 tuple. In the tuple case, the relative permittivity is given in the form
(epsxx, epsxy, epsyx, epsyy, epszz)."
but I found this to not be true in fact epsfunc should take a numpy.arrays x and y and output an epsilon matrix of shape ( x.length() , y.length() ).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.