Hi, many thanks for this tutorial. I have a question though, could you clarify, why do you multiply the terms by 'dt' in 'getSpectrumFromPulse' function (also for the 'getPulseFromSpectrum' but division by 'dt')? I think you explained it in the video, but I am still not getting it. Also it would be really great if you could recommend some tutorials on how to deal with the math of Fourier Analysis in 'scipy' or python in general. Thanks again.
@yourfavouriteta Жыл бұрын
You're welcome! In short, the multiplication or division by dt is done to keep the units consistent. A simple way to realize this is to remember that the Fourier transform of a time domain signal involves integrating w.r.t. dt, so the units of the results should be the units of whatever you are integrating multiplied by time. This is taken care of "automatically" when doing the Fourier transform analytically, but numerical integration always happens in discrete steps of a certain size, so we have to multiply by this step-size to keep everything consistent. Another way to think about this is that in my code, pulse amplitude is measured in sqrt(W)=sqrt(J/s). This ensures that when the energy is computed by integrating the absolute square of the amplitude w.r.t. time the result will have units of J: sqrt(J/s)**2*s = J. When integrating the absolute square of the spectral amplitude w.r.t. frequency, the result should likewise be in units of J (since the energy of the signal is the same whether we analyze it in the temporal or spectral domains). Thus, sqrt( "units of spectral amplitude" )**2*Hz = J. Thus, we can see that the appropriate units of the spectral amplitude are sqrt(J/Hz) = sqrt(J*s). We can go from sqrt(J/s) to sqrt(J*s) by simply multiplying the former by s. Using the FFT in scipy is very confusing at first. Here is what I recommend: Start by taking the numerical FFT of a well-known function that you are faimilar with, and whose analytical Fourier transform is known; for example the Gaussian (could also be cos, sin, box, etc.). Plot both the numerically computed FFT of the function and its analytical result, which you know to be correct, in the same graph and compare them. If the numerical result looks "cut in half", you most likely need to use fftshift as shown in my video. If one result looks much smaller or much bigger than the other, you may need to scale by the dt step size as explained above. Next, you can check if the energy of the signal is preserved when going from the time domain to the frequency domain as well. The overall idea is to learn scipy's implementation of the FFT by doing systematic "sanity checks" compared to known analytical results and thereby "nail down" different functionalities (shift, scaling, energy conservation etc.) one at the time. Hope this helps and thank you for watching!
@booklab80719 ай бұрын
Very interesting. Thank you for such good explanation
@yourfavouriteta9 ай бұрын
You're welcome!
@paeb80 Жыл бұрын
Thanks for sharing your work. This is really interesting and one of the rare instances where this kind of simulations was done in python. I was wondering if you have similar simulations for propagating ultrashort pulse through transparent materials where a filament is formed due to balance between self-focusing and plasma defocusing. It is solved by NLSE with additional terms including multi-photon ionization and self-focusing
@yourfavouriteta Жыл бұрын
I am happy you found the video interesting. Please feel free to watch and share my other ones on nonlinear phenomena in fibers. The version of the NLSE presented here is "one dimensional" because it's assumed that the refractive index change due to the power of the pulse is much smaller than the inherent difference in refractive index between the core and cladding of the fiber. Essentially, this means that the transverse field distribution remains constant throughout the length of the fiber; neither converging or diverging. A more general version of the NLSE can be used in bulk materials, where the inherent refractive index is spatially uniform. As you mention, a high power pulse can cause such a large change in the refractive index along its center, that the pulse "self-focuses". My code is not sophisticated enough to model this at the moment and there are some more basic effects I would like to implement and explain before I try that out.
@asadmahmood3921 Жыл бұрын
Thanks. I found your reply really helpful because I'm exactly looking for writing a code not only for temporal part but also for the transverse part. I am trying to propagate a pulse in a medium where I can study simultaneously many effects, linear (diffraction, pulse broadening) and non linear (self focusing and SPM). Could you suggest me how I can incorporate the transverse part information? I am intending to do it for free infinite medium of same refractive index, unlike fibre optics.
@mhd-em6yt3 ай бұрын
can be solved in the same way when adding the ''k'' coupling coefficient to the nonlinear Schrödinger equation (( Manakov equation)) ? linear part stay the same but Nonlinear part !! tnx
@nth2tell2 жыл бұрын
Hi, I just found the channel by chance. Great job explaining the nlse. Could you guide me how to solve this equation for a continuous wave? I am studying the effect of SRS in the fiber laser.
@yourfavouriteta2 жыл бұрын
Hey, thanks a lot. I am glad you found it helpful! To model a CW signal numerically using the SSFM, you can often get away with using a square pulse with a duration longer than whatever effect you are studying. For example, if you are studying an effect that takes place on the scale of nanoseconds, you can use a resolution on the scale of 10 picoseconds and a pulse duration of 100 nanoseconds. This paper contains a general version of the NLSE and also shows how a variable step size can be implemented: hal.archives-ouvertes.fr/hal-00922605v3/file/balac_fernandez_1013.pdf Note that Raman effects are modelled as a convolution between the pulse power and the Raman response function. This function essentially describes how the molecular bonds in the silica lattice of the fiber oscillate over time when suddenly perturbed. Here is a paper that explains the details: www.researchgate.net/publication/235429509_Multiple-vibrational-mode_model_for_fiber-optic_Raman_gain_spectrum_and_response_function
@nth2tell2 жыл бұрын
@@yourfavouriteta Wow Thanks so much for the reply. I'll have a look at these papers.
@yourfavouriteta2 жыл бұрын
@@nth2tell No problem, let me know if you discover or develop something interesting!
@maxwellconniff1189 Жыл бұрын
Such good material, have followed along thus far. A little off topic, but is there an equivalent to a waveplate in fiber optics? (ie λ/4 waveplate or λ/2 waveplate etc) If so, what is it called? And if not, what is the most similar fiber module? Also if you cover mode-locking, you'll go from "maybe my favourite TA" to definitively earning your namesake.
@yourfavouriteta Жыл бұрын
Thank you very much! In free-space laser optics, waveplates consist of special crystals where the speed of light is different for different polarizations of light (birefringence). If these plates are carefully designed and aligned with the beam path, the polarization components of the light will experience different relative phase delays, which alter the state of polarization. For example, a λ/2 waveplate can effectively "rotate" linearly polarized light, converting it from being x-polarized to y-polarized, while a λ/4 can convert linearly polarized light into circularly polarized light. In fiber optics, the light always propagates inside a silica strand, where the birefringence changes randomly and continuously throughout its entire length. It is almost as if the light propagates through a large number of randomly oriented waveplates. The SOP at the output will be constant over time if the fiber remains unperturbed, but environmental disturbances (changes in temperature or applied strain) can alter it dramatically. For example, gently touching a fiber with your finger is enough to induce a change in the birefringence, which significantly alters the SOP at the output. Fortunately, there are ways to manage this effect. In experiments where controlling polarization is crucial, simply using scotch tape to fix fibers to the optical table is an excellent way to keep them steady. Furthermore, as I show in my video on polarization in fiber optics (BFO 9: kzbin.info/www/bejne/pITcnZaAi8mHias), we can also use a polarization controller (either manual or digitally controlled). The device shown in the video consists of a fiber wrapped into three coils. The first one has 3 turns while the second one has 5 or 6 and the final one has 3. By adjusting the coils, controlled strain is applied to the fiber allowing the SOP to be adjusted at will. Note that this structure is analogous to a "quarter-half-quarter" arrangement of waveplates in free-space typically used for adjusting the SOP of a beam. Another approach is to use polarization maintaining fiber, where the birefringence is deliberately increased. This ensures that light launched into either the slow or fast axes will remain in the slow or fast axis as explained in a previous video (BFO 17: kzbin.info/www/bejne/j16amYaama-Nesk). Essentially, it is equivalent to a very long λ/2 waveplate. Equivalent PM fibers with circular birefringence can be designed as well, though they are more tricky to manufacture. I may cover mode locking in future videos, so please stay tuned!
@yourfavouriteta Жыл бұрын
I decided to take you up on the offer and record a video on mode-locking. Please let me know what you think about it: BFO 31: kzbin.info/www/bejne/qHWum5mMibx-q5o
@GauravGangwar-r2v7 ай бұрын
I have a question about NLSE. If we consider both linear and non-linear effects, when β2 is positive, influenced by dispersion and non-linearity (which leads to SPM), both effects broaden the pulse. Conversely, when β2 is negative, SPM (resulting from non-linearity) SPM will try to broaden the pulse but as β2 Is negative it will not broaden and we will get the fundamental soliton?
@yourfavouriteta7 ай бұрын
Yes, you are overall correct in both cases. When β2 is positive and nonlinearity is present, "Optical Wave Breaking" can occur. Essentially, SPM makes the leading edge of the pulse "more red" and β2>0 implies that red light moves faster than blue light. Similarly, the trailing edge will become "more blue". In total, this causes the pulse to spread out quickly. Check out my video on this phenomenon! If, additionally, the loss coefficient, α, is positive (i.e. the pulse experienced gain!) we can form "Similaritons", with parabolic shapes and linear chirps. I also have a video on this. With regards to the β2
@Singh_Pankaj Жыл бұрын
have you solved the same equation for cross-phase modulation?
@yourfavouriteta Жыл бұрын
I believe this version of the NLSE already accounts for XPM. If I define the initial field, A(0,T), to have two different frequencies, the nonlinearity will cause them to change each other's phases. Will have to go through the derivation from first principles to double-check.
@Singh_Pankaj Жыл бұрын
I am solving this for Directional coupler. Same equation can be written in decouple form for Directional coupler. For considering effect of XPM pumping two input signal in with phase shifted. How can I solve same equation? Is there any idea could you help me
@yourfavouriteta Жыл бұрын
@@Singh_Pankaj To clarify, are you specifically studying nonlinear effects in directional couplers or do you just need an equation for modelling wave propagation in a directional coupler? In the latter case, I can recommend the following video (and the entire lecture series): kzbin.info/www/bejne/nJism4SBd7mdnaM
@soumikchatterjee956 Жыл бұрын
Hi, I randomly stumbled upon your video and your channel and I would say amazing video. I love the way how you explained every term of the NLSE with an illustration. Really great and simple explanation. However, I have a small question i.e. how do you estimate/calculate the each cycle duration inside the carrier envelope in an Ultrashort pulse ? I mean not experimentally but on paper using calculations.
@yourfavouriteta Жыл бұрын
Hey, thanks a lot! If I understand your question correctly, I think you can see the answer at 0:44. If an EM wave has a (proper) frequency f, then the duration of a single oscillation is simply 1/f. If the angular frequency, ω, is used, the duration of a single cycle will simply be 2pi/ω. For example a 200THz optical wave will have a cycle duration of 1/200THz = 1/200 ps = 0.005 ps = 5fs. In deriving the NLSE from Maxwell's equations, one assumes that the cycle duration is much shorter than the overall duration of the pulse. For extremely short pulses, it may be necessary to model the propagation "from scratch" using MWE instead of the simplified case of the NLSE. Make sure to check out my other videos on the NLSE where I explore interesting phenomena such as Optical Wave Breaking, Modulation Instability and Solitons!
@soumikchatterjee956 Жыл бұрын
@@yourfavouriteta Thanks for your reply, makes sense now. So when we talk about ultrashort pulses, like for example a 10 fs pulse, is it the cycle duration inside the envelope or the overall pulse duration ?
@yourfavouriteta Жыл бұрын
@@soumikchatterjee956 The overall pulse duration determines if we refer to a pulse as being "ultrashort". For example, consider light with a carrier frequency of 200THz emitted by a laser source. Whether we switch on the laser source for only 100fs or for a very long time, like five minutes, the cycle duration of the light will be the same. What changes is the overall pulse duration.
@Terrar-fr1bk4 ай бұрын
What about Group Delay Dispersion (GDD)? I see that in almost all SSF simulations they omit it. My gut feeling is that it breaks the slowly varying envelope approximation required for the Split Step Fourier Method but what's your take on the matter?
@yourfavouriteta4 ай бұрын
@@Terrar-fr1bk In the video, I do show how Group Delay Dispersion (i.e. Group Velocity Dispersion*distance=β2*dz) causes the pulse to broaden in the time domain, so I assume that you are referring to the impact of β1. You can watch my video on dispersion for an deeper explanation, but basically, β1 determines the arrival time at a distance, z, inside the medium of a pulse with a carrier frequency of ω0. Thus, we can replace the "actual" time, t, by T = t - β1z, which causes the term in the NLSE containing β1 to cancel out. Using T instead of t does not change the actual evolution of the pulse in either the temporal or spectral domains; only the arrival time.
@yourfavouriteta4 ай бұрын
@@Terrar-fr1bk See also this article: www.rp-photonics.com/group_delay_dispersion.html
@Terrar-fr1bk4 ай бұрын
@@yourfavouriteta Thank you for your answer! I might be confusing two different things, but I always interpreted the GDD as the first Taylor series expansion term of the propagation factor β around a center frequency ω0. It is essentially the inverse of the group velocity v_g. (Small derivation: beta(ω0 + Δω) = β0 + dβ/dω + d^2β/dω^2 + ...). With β1 = dβ/dω = 1/v_g, and β2 = d^2β/dω^2 = d/dω[1/v_g]. Here my understanding is that the GDD is the β1 term, and GVD is the β2 term. If we assume no GVD or higher order dispersion, that is β2 = 0, then we can still have β1 = 1/v_g, but v_g will be independent of the frequency ω. It will be some constant velocity. However, the phase velocity v_p and group velocity v_g don't necessarily have to be equal, so we can still get the optical packet propagating with group velocity v_g and the carrier wave inside it propagating with v_p. If we look at the spectrum of the pulse, it shouldn't matter how the carrier wave moves inside the packet, as long as the packet doesn't deform, so this is actually my understanding as to why they omit β1 in the equation, but I think you explained the same thing using the concept of 'retarded time' that everyone seems to mention in papers and yet nobody really explains it.
@yourfavouriteta4 ай бұрын
@@Terrar-fr1bk You're getting closer, but your picture is still not quite accurate. The "group delay" (or as I like to call it for maximum clarity: The "pulse delay") is related to β1 by T_g = d(β(ω)*L)/dω|_ω0=L*β1. It is essentially the time delay experienced by any pulse with a certain carrier frequency propagating through a *particular* fiber. Note that it is measured in units of [time]. The value v_g = 1/β1 is also called the "group velocity" (though I think that "pulse velocity" would be a better phrase). "Group delay dispersion" is related to the derivative of β1 by D_2 = dT_g/dω|_ω0 = L*dβ1/dω|_ω0 = L*β2. It is essentially a measure of how much the frequencies surrounding the carrier frequency, ω0, get delayed relative to each other and thus how much the pulse *broadens* in the time domain when propagating through a *particular* fiber. Note that it is measured in units of [time^2]. The value, β2, is called the "group velocity dispersion" and essentially tells you "how much more the pulse broadens for every additional meter we extend the medium". Thus, the difference between GDD and GVD (as the terms are commonly used) is like the difference between "mass" and "density". We can talk about the mass (GDD) of a *particular object* and the density (GVD) of a *type of material*. Just as the density tells us how much more mass we will get if we add additional volume to the object, GVD tells us how much more GDD we will get if we add additional length to our fiber. Please do let me know if you have further questions!
@mattiaandrini996910 ай бұрын
Hello, very good video and explanation. I have one question: is it possible to change the carrier frequency to simulate a propagating pulse of selected wavelength? Thanks
@yourfavouriteta10 ай бұрын
Thank you very much! Changing the carrier frequency is possible in newer versions. Please see the source code on GitHub :-)
@mattiaandrini996910 ай бұрын
@@yourfavouriteta Thanks for the answer. Unfortunately, I still see this functionality listed as "TODO". Does that mean I should put it manually? If so, do you have any quick suggestion?
@yourfavouriteta10 ай бұрын
@@mattiaandrini9969 Here is the most recent version of the code: github.com/OleKrarup123/NLSE-vector-solver/blob/main/ssfm_functions.py In an attempt to make the code modular, the split step method takes a FiberLink class and an InputSignal class as arguments. To create the InputSignal, you need to supply it with a TimeFreq class and a bunch of signal parameters (pulse duration, amplitude etc.). The TimeFreq class only requires you to specify the number of points on the time axis, N, the time resolution, dt, in s and the desired carrier frequency in Hz. To create signals that are offset from the carrier frequency, you can change the "frequency offset" parameter supplied to the InputSignal class. In some sense, the carrier frequency in my code is mostly "cosmetic" (apart from certain cases involving EDFA's) and used for plotting. In reality, the carrier will determine the dispersion, but in my code all dispersion order terms are specified by the user independently of the carrier for maximum flexibility. Hope this helps!
@mattiaandrini996910 ай бұрын
@vouriteta Oh, I didn't consider that part of the code because I was using the SSFM notebook you explained in this video. That python code is hella crazy, I made it to work and now I'm trying to figure out exatly where to put the parameters because any change seems not to change anything in the output lol. Thanks for the explanations! PS what environment and py version are you using? I'm having trouble with list-command
@yourfavouriteta10 ай бұрын
@@mattiaandrini9969 As you can probably see, this project is my first venture into software development. My real expertise is in physics, so I am still learning how to set up code in a way that is accessible to others. To write and run the code, I have simply been using Anaconda without touching any of its defaults, Spyder as the IDE and python 3.9. Hopefully that makes things more clear. My main goal of this code is to give users a flexible, reproducible and user-friendly way to simulate nonlinear optics (at the cost higher runtime, which is typically less crucial for research projects). If you would like help getting it to work, feel free to reach out to me on LinkedIn [linkedin.com/in/olekrarup] and we can set up a video call; I think it would be interesting to get some direct feedback from an actual user.
@Learningresource13932 жыл бұрын
How do drive non linear equation, sir please full detail explain in nonlinear equation
@yourfavouriteta2 жыл бұрын
Derriving the NLSE starting from Maxwell's equations is a bit tricky, but check out video 0 in my Basic Fiber Optics playlist. It mentions a video series on nonlinear optics by IIT Karagphur (available on KZbin), where the NLSE is derrived from scratch.
@srikanthsugavanam8591 Жыл бұрын
Hi Ole - great video as always. I am going through your code, and I see some very interesting programming tricks being used - especially the use of **kwargs. Essentially, we researchers get a basic understanding of the code syntax, learn the essential math and plotting packages, and get to task. But your code shows how a deeper understanding of the capabilities of Python can really ease programming workflow. Along these lines, can you recommend some good Python resources for scientists and researchers?
@yourfavouriteta Жыл бұрын
Hey, I am glad you found it interesting! I found the following two channels and specifically the linked videos very useful for learning the intricacies of Python: mCoding: kzbin.info/www/bejne/p4bIppdseduCjassi=ylcCpGgHk3svCIfj Bro Code: kzbin.info/www/bejne/jnyrdqeaps1_gZosi=cfZHIWI_uDBuvr4e Some additional "guidelines" that I suggest pursuing for using Python for scientific activities: 1) Get comfortable with "object oriented programming". This buzzword refers to the fact that python allows you to create arbitrary data structures with a variety of properties. For example, we can define a fiber "class" with properties that can be accessed using fiber.length, fiber.dispCoeffs.beta2 etc. If we want to simulate 10 different fiber types, where each of them has a length, a dispersion coefficient, an attenuation coefficient and a nonlinear coefficient, this saves us from defining and tracking 40 different variables. We only have to name the fiber "objects" and then access their properties. For scientific computing projcts, which often have a lot of moving parts, it is quite handy to "compartmentalize" variables in this way. 2) Take the time to properly document your code. I know it's tempting to focus on optimizing the numerical performance of your code and other things that feel more "sciency" than typing out an instruction manual. However, it is very likely that future students/colleagues/reviewers etc. will be interested in your code, so having it be an opaque mess of poorly labelled variables and absent comments is not beneficial; either they will get no value out of it or they will constantly pester you with requests for explanations. Furthermore, if you pause a project for a few weeks and return to it, you will have an easier time picking it back up! I recommend spending maybe 20 mins at the end of each work session (when you are getting tired anyways) writing documentation. Little by little, this will add up to a lot! 3) Do unit tests! As shown in the video, I compare my numerical code to certain special cases that can be solved analytically. This approach of testing individual behaviors separately allows you to "sanity check" your code and ensure that bugs are caught early. It is even possible to automate the process, so all unit tests are run automatically when your main code is executed; very useful when adding new features that risk breaking old ones! 4) Learn how to use Git for version control. Basically, it's a tool that allows you to log the history of changes to your project and recover old versions if need be. Typically, you connect a folder on your PC to a remote server (GitHub, Bitbucket) and use either a Git terminal or a GUI to do the following: i) Add changed files or new files to a "box" using git add file.py ii) Once you have added all the files you want, for example ones that support a new functionality, use git commit -m "added split step support" to "seal" the box and add a message describing it. iii) When you have added a number of small functionalities (boxes) and tested that they work as intended, you can use git push origin to upload the "committed" boxes to the server. This updates your project on there while retaining older versions; this last point can be particularly important for research code as reviewers may want the particular version you used for simulating results in your paper! Git is notoriously unintuitive to set up and learn in the beginning, but decent tutorials are available on KZbin. Learning Git is also crucial for students who want to pursue a job in industry as it's the standard method for handling large software projects with multiple contributors.
@srikanthsugavanam8591 Жыл бұрын
@@yourfavouritetaGreat stuff, thanks a tonne! Git is something I have been using in quite a roundabout way. Will have to make it part of my workflow. Also, very useful pointers (pun intended) on object oriented programming. Will get to the task. :)
@GauravGangwar-r2v10 ай бұрын
Have anyone done this nlse with pinns?
@yourfavouriteta10 ай бұрын
Check out this paper: doi.org/10.1016/j.ijleo.2023.170739
@GauravGangwar-r2v10 ай бұрын
@@yourfavouriteta Thank you sir ,but I am stuck in the code Can you help me ?
@yourfavouriteta10 ай бұрын
@@GauravGangwar-r2v I have not worked with physics informed neural networks yet, but I will let you know if I get around to it.
@GauravGangwar-r2v10 ай бұрын
ok sir @@yourfavouriteta
@GauravGangwar-r2v8 ай бұрын
Hi sir do you have the code for the normalised NLSE?
@mhd-em6yt4 ай бұрын
. Thank you
@yourfavouriteta4 ай бұрын
@@mhd-em6yt You're welcome!
@nombregenerico5068 Жыл бұрын
This is hard drugs level.
@yourfavouriteta Жыл бұрын
Just one fiber optics tutorial and I will have you hooked! ;-)
@christiancortes2971 Жыл бұрын
Please remove the background sound, Thanks
@almeidacesar33247 ай бұрын
dude whats your email ? i need to contact u cause ive been trying to do that code on my own and its not working
@yourfavouriteta7 ай бұрын
Hey, my email is: yourfavouriteta@gmail.com You can also find an up-to-date version of the code here: github.com/OleKrarup123/NLSE-vector-solver/blob/main/ssfm_functions.py The main function at the end of the code should work as is. Feel free to experiment with it and email me if you need help!