The Nonlinear Schrödinger Equation solved in python!

Поделиться
HTML-код
  • Опубликовано: 15 ноя 2022
  • Link to source code:
    github.com/OleKrarup123/NLSE-...
    Direct link to Python Notebook on Collaboratory:
    colab.research.google.com/dri...
    Papers on the split step method:
    hal.science/hal-00922605v3/fi...
    #python #pythontutorial #pythonprogramming #pythonprojects
  • НаукаНаука

Комментарии • 52

  • @booklab8071
    @booklab8071 4 месяца назад

    Very interesting. Thank you for such good explanation

  • @paeb80
    @paeb80 Год назад +2

    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
      @yourfavouriteta  Год назад +1

      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
      @asadmahmood3921 9 месяцев назад

      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.

  • @maxwellconniff1189
    @maxwellconniff1189 Год назад +1

    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
      @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: ruclips.net/video/nSylcJVdTSI/видео.html), 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: ruclips.net/video/Y-7hSddJZDg/видео.html). 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
      @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: ruclips.net/video/rDKjfVTWKu8/видео.html

  • @krupamaypanda8177
    @krupamaypanda8177 7 месяцев назад +1

    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
      @yourfavouriteta  7 месяцев назад

      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!

  • @user-fj5dt5bg5f
    @user-fj5dt5bg5f 3 месяца назад +1

    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?

    • @yourfavouriteta
      @yourfavouriteta  3 месяца назад +1

      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

  • @nth2tell
    @nth2tell Год назад +2

    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.

    • @yourfavouriteta
      @yourfavouriteta  Год назад

      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

    • @nth2tell
      @nth2tell Год назад

      @@yourfavouriteta Wow Thanks so much for the reply. I'll have a look at these papers.

    • @yourfavouriteta
      @yourfavouriteta  Год назад

      @@nth2tell No problem, let me know if you discover or develop something interesting!

  • @mhd-em6yt
    @mhd-em6yt 8 дней назад +1

    . Thank you

  • @Terrar-fr1bk
    @Terrar-fr1bk 7 дней назад

    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?

    • @yourfavouriteta
      @yourfavouriteta  3 дня назад

      @@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.

    • @yourfavouriteta
      @yourfavouriteta  3 дня назад

      @@Terrar-fr1bk See also this article:
      www.rp-photonics.com/group_delay_dispersion.html

  • @srikanthsugavanam8591
    @srikanthsugavanam8591 9 месяцев назад +1

    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
      @yourfavouriteta  9 месяцев назад +1

      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:
      ruclips.net/video/qUeud6DvOWI/видео.htmlsi=ylcCpGgHk3svCIfj
      Bro Code:
      ruclips.net/video/XKHEtdqhLK8/видео.htmlsi=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 RUclips. 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
      @srikanthsugavanam8591 9 месяцев назад +1

      ​@@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. :)

  • @Singh_Pankaj
    @Singh_Pankaj Год назад +1

    have you solved the same equation for cross-phase modulation?

    • @yourfavouriteta
      @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
      @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
      @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):
      ruclips.net/video/fgIjQKBTjgA/видео.html

  • @mattiaandrini9969
    @mattiaandrini9969 5 месяцев назад

    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

    • @yourfavouriteta
      @yourfavouriteta  5 месяцев назад +1

      Thank you very much! Changing the carrier frequency is possible in newer versions. Please see the source code on GitHub :-)

    • @mattiaandrini9969
      @mattiaandrini9969 5 месяцев назад +1

      @@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?

    • @yourfavouriteta
      @yourfavouriteta  5 месяцев назад +1

      @@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!

    • @mattiaandrini9969
      @mattiaandrini9969 5 месяцев назад

      @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

    • @yourfavouriteta
      @yourfavouriteta  5 месяцев назад

      @@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.

  • @soumikchatterjee956
    @soumikchatterjee956 Год назад +1

    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
      @yourfavouriteta  Год назад +1

      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
      @soumikchatterjee956 Год назад +1

      @@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
      @yourfavouriteta  Год назад +1

      @@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.

  • @Learningresource1393
    @Learningresource1393 Год назад

    How do drive non linear equation, sir please full detail explain in nonlinear equation

    • @yourfavouriteta
      @yourfavouriteta  Год назад +1

      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 RUclips), where the NLSE is derrived from scratch.

  • @nombregenerico5068
    @nombregenerico5068 10 месяцев назад +1

    This is hard drugs level.

    • @yourfavouriteta
      @yourfavouriteta  10 месяцев назад

      Just one fiber optics tutorial and I will have you hooked! ;-)

  • @user-fj5dt5bg5f
    @user-fj5dt5bg5f 5 месяцев назад +1

    Have anyone done this nlse with pinns?

    • @yourfavouriteta
      @yourfavouriteta  5 месяцев назад

      Check out this paper:
      doi.org/10.1016/j.ijleo.2023.170739

    • @user-fj5dt5bg5f
      @user-fj5dt5bg5f 5 месяцев назад

      @@yourfavouriteta Thank you sir ,but I am stuck in the code Can you help me ?

    • @yourfavouriteta
      @yourfavouriteta  5 месяцев назад

      @@user-fj5dt5bg5f I have not worked with physics informed neural networks yet, but I will let you know if I get around to it.

    • @user-fj5dt5bg5f
      @user-fj5dt5bg5f 5 месяцев назад

      ok sir @@yourfavouriteta

    • @user-fj5dt5bg5f
      @user-fj5dt5bg5f 4 месяца назад +1

      Hi sir do you have the code for the normalised NLSE?

  • @christiancortes2971
    @christiancortes2971 Год назад

    Please remove the background sound, Thanks

  • @almeidacesar3324
    @almeidacesar3324 3 месяца назад +1

    dude whats your email ? i need to contact u cause ive been trying to do that code on my own and its not working

    • @yourfavouriteta
      @yourfavouriteta  3 месяца назад

      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!