-
Notifications
You must be signed in to change notification settings - Fork 33
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
Improvements on RF waveguide design tutorial #164
Comments
The numerical mismatch is indeed a worry. There must be something different between the two versions? |
The difference comes from the dependencies versions. I have created a new environment with a fresh install of femwell and I also get something similar to the above (not exactly the same though). I suspect that if the packages are installed the mismatch will go away. The difference in versions are below (package_name femwell_repo_version local_venv_version): annotated-types 0.7.0 Do any of these seem like a red flag? The results are now:
However, the results when considering the symmetry plane are great:
Maybe it's a meshing issue? |
Sounds great!
Sounds good!
I'm totally fine with defining them with quantities, that's a great approach to avoid problems! I just guess if we use the scipy values and define the constants based on them, it simplifies the code further :)
Yay! Generalizing this and understanding multi conductor transmission lines sounds amazing! 🥳
Sounds easy to fix :)
Hmm, feel free to just adjust it that the numbers are right, I went quick quickly over it, but I can give it another look. The
We should for sure be worried! My first guess would be that the integrals depend somehow on the phase of the mode. As the modes are normalized to have a power of 1, the phase of the modes can still be arbitrary. While it often shows the same modes on the same machine, these different absolute phases can lead to different numbers in calculations. Usually, physical quantities which we calculate from such modes should not depend on the phase. Might that explain the differences? |
Maybe try first the older gmsh version
We had to pin it for now as the newest version created some trouble. If that doesn't fix it we can look into the other dependencies. |
I tried downgrading gmsh but the results are the same
A change in phase should not alter the result. It's the absolute value of that has changed. For the PI model to have changed the value so much, it means the current EDIT: @HelgeGehring I have made the following successive downgrades/upgrades:
Something seems to be happening with scikit-fem latest version. |
Turns out the |
I think hte main problem is that the pictures are just not there :D Nice catch about the versions! Just as a sanity check: If you use all the newest versions except scikit-fem, do you also get the mismatch? Is it only the latest version? I.e. 9.0.0 gives different results compared to 9.0.1? Or is 9.0.0 also having the problem? |
ah... that explains it XD
Yes, the tests were with all the versions up to date (as in the list above, left column) and then I did the downgrades/upgrades. I just tried 9.0.0, but it throws an error with meshio:
|
Strange, meshio is still a dependency of scikit-fem |
you can just install meshio additionally for now :) Do you have a reference simulation which we could compare to see if the new version is correct or the old one? |
I just tried this, and the version
Not perfect ones... For the current example, the three approaches should be close together since the modes are very close to TEM modes. I have tried another example which has an analytical solution and the same numerical difference appears. The example is a shielded microstrip line surrounded by air. We can use a conformal mapping formula to get the characteristic impedance which is valid for infinitely thin metal strip and perfect conductors. You can find the .py file for it here: With this example,
And when downgrading to
I also had to install and uninstall meshio for some reason. This was the cmd prompt:
I'm not sure if one version is more correct over the other, but there certainly is a difference. You can also check the theory in this book (chapter 3.14): Collin, Robert E. 2001. Foundations for Microwave Engineering. 2. ed., [Nachdr.]. IEEE Press Series on Electromagnetic Wave Theory. New York, NY: IEEE Press. |
ok, thanks, were narrowing it down! i think the update of meshio was due to an update of numpy which required some changes. I/d guess you use the same numpy version for both? It's somehow interesting that before the update the values were almost the same while afterwards they got different. Is there a meshio version which works with both skfem versions? It also seems that there was a change in the interface to meshio (which would make me doubt that there's a version working with both)... , see kinnala/scikit-fem@9.0.1...9.1.1 I'd guess best would be if we could make a simplified short version of the example (i.e. only a mode solve on a simple geometry and then the integral which is different between the two), that way we can easier iterate and test. We should then compare the exact values of the E / H fields, I'd suspect that the result of the calculation of the H-field might have changed. (easiest would be to just dump the array via numpy.save and load it with the newer version and compare) |
The other thing I'm wondering: Is one of the line integrals you calculate along an interface at which the epsilon changes discontinuously? (I.e. the surface of the conductor?) |
Yes, I have checked and both versions use
I have also checked that, and it successfully install
I think the current example of the microstrip is good because it is the simplest geometry: just a square on a simulation region.
Indeed! I have narrowed it down as you say to the integral calculation. The first thing I checked was to see if the modes calculated are the same: they are. Next I check the integral calculation and there is where the difference is. Here's what I did: I have the following snippet of code placed after the geometry definition, mesh generation, epsilon definition and mode calculation: from femwell.maxwell.waveguide import Mode
mode_9_0_1 = Mode(modes[0].frequency,
modes[0].k,
modes[0].basis_epsilon_r,
modes[0].epsilon_r,
modes[0].basis,
np.loadtxt('E_9_0_1.txt', dtype = complex),
np.loadtxt('H_9_0_1.txt', dtype = complex))
mode_9_1_1 = Mode(modes[0].frequency,
modes[0].k,
modes[0].basis_epsilon_r,
modes[0].epsilon_r,
modes[0].basis,
np.loadtxt('E_9_1_1.txt', dtype = complex),
np.loadtxt('H_9_1_1.txt', dtype = complex))
print('np.all(np.isclose(mode_9_0_1.H, mode_9_1_1.H)):', np.all(np.isclose(mode_9_0_1.H, mode_9_1_1.H)))
print('np.all(np.isclose(mode_9_0_1.E, mode_9_1_1.E)):', np.all(np.isclose(mode_9_0_1.E, mode_9_1_1.E)))
@Functional(dtype=np.complex64)
def current_form(w):
"""
What this does is it takes the normal vector to the boundary and rotates it 90deg
Then takes the inner product with the magnetic field in it's complex form
"""
return inner(np.array([w.n[1], -w.n[0]]), w.H)
@Functional(dtype=np.complex64)
def voltage_form(w):
"""
What this does is it takes the normal vector to the boundary and rotates it 90deg
Then takes the inner product with the electric field in it's complex form
"""
return -inner(np.array([w.n[1], -w.n[0]]), w.E)
conductor = "metal_sig_interface"
line = "path_integral"
for mode in [mode_9_0_1, mode_9_1_1]:
p0 = calculate_scalar_product(
mode.basis, np.conjugate(mode.E), mode.basis, np.conjugate(mode.H)
) # The conjugate is due to femwell internal definition as conj(E) x H
(ht, ht_basis), (hz, hz_basis) = mode.basis.split(mode.H)
facet_basis = ht_basis.boundary(facets=mesh.boundaries[conductor])
i0 = current_form.assemble(facet_basis, H=facet_basis.interpolate(ht))
(et, et_basis), (ez, ez_basis) = mode.basis.split(mode.E)
facet_basis = et_basis.boundary(facets=mesh.boundaries[line])
v0 = voltage_form.assemble(facet_basis, E=facet_basis.interpolate(et))
print('Power:', p0)
print('v0:', v0)
print('i0:', i0) This is put into a file called
With this, I end up with:
Notice how every value stays the same except the i0 calculation.
The v0 line integral goes from the middle of the conductor to the edge of the simulation region where the boundary condition is set to metal. The i0 line integral is along a line that starts at the left boundary not set to metal and loops around the conductor up to the boundary again. However, the line integral which is calculated where epsilon changes discontinuously (the v0) remains the same in both versions. It's actually the i0 which is all defined in the air that is giving an issue |
The error reported above stems from an optimization done from version 9.0.1 to 9.1.1 in skfem on
|
@HelgeGehring
Follow up from #159 (comment) .
Indeed, it can be made more compact. I will work on it and organize the code in a class
CPW
. I used that approach in another project and it made things more compact and readable.I need to double check. There's a good chance they're not. The use of pint came as a follow up from another project and I ended up pasting things at the top hoping I'd use them and be safe.
We don't need the numeric and we can use the ones from scipy. but if pint is actively used in the notebook it's best to redefine the constants as
pint.Quantity
to take care of unit tracking. It needs to be double checked.This one I would not do. At least without deeper study of multi conductor transmission line (MTL) theory and application in multimode waveguides (coupled waveguides). When I started I picked the tutorial on the repo for the CPW and the theory you follow is from MTL. However, when reading up on it, I found the math to quickly become more involved, with mathematical artifacts coming up when analyzing a waveguide as a circuit. A big issue is on the normalization of the fields, which depending on which formalism you choose, you may either conserve power and not reciprocity, not conserve power and have reciprocity or a mix of both,. The point being: I feel like it all comes down the your choice when analysing, that's why I put some effort illustrating the choices I've made to calculate i0 and v0, since those are values that made intuitive sense, and I think we should be aware of those assumptions. As for the calculation for RLGC parameters, I believe those are obtained with the assumption of single mode operation. I don't know how to scale it to multimode scenarios. One of the papers on the tutorial has a complete theory on MTL, which could help. Bottom line: I would be weary of generalizing this analysis due to the ambiguity present.
That one is my fault. When removing whitespaces I forgot to correct the filenames on the notebook's markdown cells.
Are these numbers correct? Because [4] I know it is used and [3] is to link to delft's software, which now that you mention it I'm not sure it's the correct reference or if it is linked to somewhere in the text. But if not, it should definitely be included. It's a nice software that they have.
Also, one thing I noticed @HelgeGehring : online, the tutorial has:
While in my laptop I get:
Unclear if it's something to be concerned about...
The text was updated successfully, but these errors were encountered: