Repository files navigation

pyNLO: Nonlinear optics modeling for Python

This README is best viewed at http://pynlo.readthedocs.io/en/latest/readme_link.html

Complete documentation is available at http://pynlo.readthedocs.io/

PyNLO

Introduction

PyNLO provides an easy-to-use, object-oriented set of tools for modeling the nonlinear interaction of light with materials. It provides many functionalities for representing pulses of light, beams of light, and nonlinear materials, such as crystals and fibers. Also, it features methods for simulating both three-wave-mixing processes (such as DFG), as well as four-wave-mixing processes such as supercontinuum generation.

Features:
  • A solver for the propagation of light through a Chi-3 material, useful for simulation pulse compression and supercontinuum generation in an optical fiber. This solver is highly efficient, thanks to an adaptive-step-size implementation of the "Fourth-order Runge-Kutta in the Interaction Picture " (RK4IP) method of Hult (2007).
  • A solver for simulating Chi-2 processes such as difference frequency generation.
  • A flexible object-oriented system for treating laser pulses, beams, fibers, and crystals.
  • ...and much more!

Installation

PyNLO requires Python 2, and is tested on Python 2.7 (Python 3 compatibility is a work-in-progress). If you don't already have Python, we recommend an "all in one" Python package such as the Anaconda Python Distribution, which is available for free.

With pip

The latest "official release" can be installed from PyPi with

pip install pynlo

The up-to-the-minute latest version can be installed from GitHub with

pip install git+https://github.com/pyNLO/PyNLO.git

With setuptools

Alternatively, you can download the latest version from the PyNLO Github site (look for the "download zip" button), cd to the PyNLO directory, and use

python setup.py install

Or, if you wish to edit the PyNLO source code without re-installing each time

python setup.py develop

Documentation

The complete documentation for PyNLO is availabe at https://pynlo.readthedocs.org.

Example of use

The following example demonstrates how to use PyNLO to simulate the propagation of a 50 fs pulse through a nonlinear fiber using the split-step Fourier model (SSFM). Note that the actual propagation of the pulse takes up just a few lines of code. Most of the other code is simply plotting the results.

This example is contained in examples/simple_SSFM.py

importnumpyasnpimportmatplotlib.pyplotaspltimportpynloFWHM=0.050# pulse duration (ps)pulseWL=1550# pulse central wavelength (nm)EPP=50e-12# Energy per pulse (J)GDD=0.0# Group delay dispersion (ps^2)TOD=0.0# Third order dispersion (ps^3)Window=10.0# simulation window (ps)Steps=100# simulation stepsPoints=2**13# simulation pointsbeta2=-120# (ps^2/km)beta3=0.00# (ps^3/km)beta4=0.005# (ps^4/km)Length=20# length in mmAlpha=0.0# attentuation coefficient (dB/cm)Gamma=1000# Gamma (1/(W km)fibWL=pulseWL# Center WL of fiber (nm)Raman=True# Enable Raman effect?Steep=True# Enable self steepening?alpha=np.log((10**(Alpha*0.1))) *100# convert from dB/cm to 1/m# set up plots for the results:fig=plt.figure(figsize=(8,8))
ax0=plt.subplot2grid((3,2), (0, 0), rowspan=1)
ax1=plt.subplot2grid((3,2), (0, 1), rowspan=1)
ax2=plt.subplot2grid((3,2), (1, 0), rowspan=2, sharex=ax0)
ax3=plt.subplot2grid((3,2), (1, 1), rowspan=2, sharex=ax1)
######## This is where the PyNLO magic happens! ############################# create the pulse!pulse=pynlo.light.DerivedPulses.SechPulse(power=1, # Power will be scaled by set_eppT0_ps=FWHM/1.76,
center_wavelength_nm=pulseWL,
time_window_ps=Window,
GDD=GDD, TOD=TOD,
NPTS=Points,
frep_MHz=100,
power_is_avg=False)
# set the pulse energy!pulse.set_epp(EPP)
# create the fiber!fiber1=pynlo.media.fibers.fiber.FiberInstance()
fiber1.generate_fiber(Length*1e-3, center_wl_nm=fibWL, betas=(beta2, beta3, beta4),
gamma_W_m=Gamma*1e-3, gvd_units='ps^n/km', gain=-alpha)
# Propagationevol=pynlo.interactions.FourWaveMixing.SSFM.SSFM(local_error=0.005, USE_SIMPLE_RAMAN=True,
disable_Raman=np.logical_not(Raman),
disable_self_steepening=np.logical_not(Steep))
y, AW, AT, pulse_out=evol.propagate(pulse_in=pulse, fiber=fiber1, n_steps=Steps)
########## That's it! Physics complete. Just plotting commands from here! ################F=pulse.F_THz# Frequency grid of pulse (THz)defdB(num):
return10*np.log10(np.abs(num)**2)
zW=dB( np.transpose(AW)[:, (F>0)] )
zT=dB( np.transpose(AT) )
y_mm=y*1e3# convert distance to mmax0.plot(pulse_out.F_THz, dB(pulse_out.AW), color='r')
ax1.plot(pulse_out.T_ps, dB(pulse_out.AT), color='r')
ax0.plot(pulse.F_THz, dB(pulse.AW), color='b')
ax1.plot(pulse.T_ps, dB(pulse.AT), color='b')
extent= (np.min(F[F>0]), np.max(F[F>0]), 0, Length)
ax2.imshow(zW, extent=extent,
vmin=np.max(zW) -40.0, vmax=np.max(zW),
aspect='auto', origin='lower')
extent= (np.min(pulse.T_ps), np.max(pulse.T_ps), np.min(y_mm), Length)
ax3.imshow(zT, extent=extent,
vmin=np.max(zT) -40.0, vmax=np.max(zT),
aspect='auto', origin='lower')
ax0.set_ylabel('Intensity (dB)')
ax0.set_ylim( -80, 0)
ax1.set_ylim( -40, 40)
ax2.set_ylabel('Propagation distance (mm)')
ax2.set_xlabel('Frequency (THz)')
ax2.set_xlim(0,400)
ax3.set_xlabel('Time (ps)')
plt.show()

Here are the results:

results

Contributing

We welcome suggestions for improvement, questions, comments, etc. The best way to to open a new issue here: https://github.com/pyNLO/PyNLO/issues/.

License

PyNLO is licensed under the GPLv3 license. This means that you are free to use PyNLO for any open-source project. Of course, PyNLO is provided "as is" with absolutely no warrenty.

References

[1] Johan Hult, "A Fourth-Order Runge–Kutta in the Interaction Picture Method for Simulating Supercontinuum Generation in Optical Fibers," J. Lightwave Technol. 25, 3770-3775 (2007) https://www.osapublishing.org/jlt/abstract.cfm?uri=jlt-25-12-3770

About

Python package for nonlinear optics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

pyNLO: Nonlinear optics modeling for Python

This README is best viewed at http://pynlo.readthedocs.io/en/latest/readme_link.html

Complete documentation is available at http://pynlo.readthedocs.io/

PyNLO

Introduction

PyNLO provides an easy-to-use, object-oriented set of tools for modeling the nonlinear interaction of light with materials. It provides many functionalities for representing pulses of light, beams of light, and nonlinear materials, such as crystals and fibers. Also, it features methods for simulating both three-wave-mixing processes (such as DFG), as well as four-wave-mixing processes such as supercontinuum generation.

Features:
  • A solver for the propagation of light through a Chi-3 material, useful for simulation pulse compression and supercontinuum generation in an optical fiber. This solver is highly efficient, thanks to an adaptive-step-size implementation of the "Fourth-order Runge-Kutta in the Interaction Picture " (RK4IP) method of Hult (2007).
  • A solver for simulating Chi-2 processes such as difference frequency generation.
  • A flexible object-oriented system for treating laser pulses, beams, fibers, and crystals.
  • ...and much more!

Installation

PyNLO requires Python 2, and is tested on Python 2.7 (Python 3 compatibility is a work-in-progress). If you don't already have Python, we recommend an "all in one" Python package such as the Anaconda Python Distribution, which is available for free.

With pip

The latest "official release" can be installed from PyPi with

pip install pynlo

The up-to-the-minute latest version can be installed from GitHub with

pip install git+https://github.com/pyNLO/PyNLO.git

With setuptools

Alternatively, you can download the latest version from the PyNLO Github site (look for the "download zip" button), cd to the PyNLO directory, and use

python setup.py install

Or, if you wish to edit the PyNLO source code without re-installing each time

python setup.py develop

Documentation

The complete documentation for PyNLO is availabe at https://pynlo.readthedocs.org.

Example of use

The following example demonstrates how to use PyNLO to simulate the propagation of a 50 fs pulse through a nonlinear fiber using the split-step Fourier model (SSFM). Note that the actual propagation of the pulse takes up just a few lines of code. Most of the other code is simply plotting the results.

This example is contained in examples/simple_SSFM.py

importnumpyasnpimportmatplotlib.pyplotaspltimportpynloFWHM=0.050# pulse duration (ps)pulseWL=1550# pulse central wavelength (nm)EPP=50e-12# Energy per pulse (J)GDD=0.0# Group delay dispersion (ps^2)TOD=0.0# Third order dispersion (ps^3)Window=10.0# simulation window (ps)Steps=100# simulation stepsPoints=2**13# simulation pointsbeta2=-120# (ps^2/km)beta3=0.00# (ps^3/km)beta4=0.005# (ps^4/km)Length=20# length in mmAlpha=0.0# attentuation coefficient (dB/cm)Gamma=1000# Gamma (1/(W km)fibWL=pulseWL# Center WL of fiber (nm)Raman=True# Enable Raman effect?Steep=True# Enable self steepening?alpha=np.log((10**(Alpha*0.1))) *100# convert from dB/cm to 1/m# set up plots for the results:fig=plt.figure(figsize=(8,8))
ax0=plt.subplot2grid((3,2), (0, 0), rowspan=1)
ax1=plt.subplot2grid((3,2), (0, 1), rowspan=1)
ax2=plt.subplot2grid((3,2), (1, 0), rowspan=2, sharex=ax0)
ax3=plt.subplot2grid((3,2), (1, 1), rowspan=2, sharex=ax1)
######## This is where the PyNLO magic happens! ############################# create the pulse!pulse=pynlo.light.DerivedPulses.SechPulse(power=1, # Power will be scaled by set_eppT0_ps=FWHM/1.76,
center_wavelength_nm=pulseWL,
time_window_ps=Window,
GDD=GDD, TOD=TOD,
NPTS=Points,
frep_MHz=100,
power_is_avg=False)
# set the pulse energy!pulse.set_epp(EPP)
# create the fiber!fiber1=pynlo.media.fibers.fiber.FiberInstance()
fiber1.generate_fiber(Length*1e-3, center_wl_nm=fibWL, betas=(beta2, beta3, beta4),
gamma_W_m=Gamma*1e-3, gvd_units='ps^n/km', gain=-alpha)
# Propagationevol=pynlo.interactions.FourWaveMixing.SSFM.SSFM(local_error=0.005, USE_SIMPLE_RAMAN=True,
disable_Raman=np.logical_not(Raman),
disable_self_steepening=np.logical_not(Steep))
y, AW, AT, pulse_out=evol.propagate(pulse_in=pulse, fiber=fiber1, n_steps=Steps)
########## That's it! Physics complete. Just plotting commands from here! ################F=pulse.F_THz# Frequency grid of pulse (THz)defdB(num):
return10*np.log10(np.abs(num)**2)
zW=dB( np.transpose(AW)[:, (F>0)] )
zT=dB( np.transpose(AT) )
y_mm=y*1e3# convert distance to mmax0.plot(pulse_out.F_THz, dB(pulse_out.AW), color='r')
ax1.plot(pulse_out.T_ps, dB(pulse_out.AT), color='r')
ax0.plot(pulse.F_THz, dB(pulse.AW), color='b')
ax1.plot(pulse.T_ps, dB(pulse.AT), color='b')
extent= (np.min(F[F>0]), np.max(F[F>0]), 0, Length)
ax2.imshow(zW, extent=extent,
vmin=np.max(zW) -40.0, vmax=np.max(zW),
aspect='auto', origin='lower')
extent= (np.min(pulse.T_ps), np.max(pulse.T_ps), np.min(y_mm), Length)
ax3.imshow(zT, extent=extent,
vmin=np.max(zT) -40.0, vmax=np.max(zT),
aspect='auto', origin='lower')
ax0.set_ylabel('Intensity (dB)')
ax0.set_ylim( -80, 0)
ax1.set_ylim( -40, 40)
ax2.set_ylabel('Propagation distance (mm)')
ax2.set_xlabel('Frequency (THz)')
ax2.set_xlim(0,400)
ax3.set_xlabel('Time (ps)')
plt.show()

Here are the results:

results

Contributing

We welcome suggestions for improvement, questions, comments, etc. The best way to to open a new issue here: https://github.com/pyNLO/PyNLO/issues/.

License

PyNLO is licensed under the GPLv3 license. This means that you are free to use PyNLO for any open-source project. Of course, PyNLO is provided "as is" with absolutely no warrenty.

References

[1] Johan Hult, "A Fourth-Order Runge–Kutta in the Interaction Picture Method for Simulating Supercontinuum Generation in Optical Fibers," J. Lightwave Technol. 25, 3770-3775 (2007) https://www.osapublishing.org/jlt/abstract.cfm?uri=jlt-25-12-3770

About

Python package for nonlinear optics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

pyNLO: Nonlinear optics modeling for Python

This README is best viewed at http://pynlo.readthedocs.io/en/latest/readme_link.html

Complete documentation is available at http://pynlo.readthedocs.io/

PyNLO

Introduction

PyNLO provides an easy-to-use, object-oriented set of tools for modeling the nonlinear interaction of light with materials. It provides many functionalities for representing pulses of light, beams of light, and nonlinear materials, such as crystals and fibers. Also, it features methods for simulating both three-wave-mixing processes (such as DFG), as well as four-wave-mixing processes such as supercontinuum generation.

Features:
  • A solver for the propagation of light through a Chi-3 material, useful for simulation pulse compression and supercontinuum generation in an optical fiber. This solver is highly efficient, thanks to an adaptive-step-size implementation of the "Fourth-order Runge-Kutta in the Interaction Picture " (RK4IP) method of Hult (2007).
  • A solver for simulating Chi-2 processes such as difference frequency generation.
  • A flexible object-oriented system for treating laser pulses, beams, fibers, and crystals.
  • ...and much more!

Installation

PyNLO requires Python 2, and is tested on Python 2.7 (Python 3 compatibility is a work-in-progress). If you don't already have Python, we recommend an "all in one" Python package such as the Anaconda Python Distribution, which is available for free.

With pip

The latest "official release" can be installed from PyPi with

pip install pynlo

The up-to-the-minute latest version can be installed from GitHub with

pip install git+https://github.com/pyNLO/PyNLO.git

With setuptools

Alternatively, you can download the latest version from the PyNLO Github site (look for the "download zip" button), cd to the PyNLO directory, and use

python setup.py install

Or, if you wish to edit the PyNLO source code without re-installing each time

python setup.py develop

Documentation

The complete documentation for PyNLO is availabe at https://pynlo.readthedocs.org.

Example of use

The following example demonstrates how to use PyNLO to simulate the propagation of a 50 fs pulse through a nonlinear fiber using the split-step Fourier model (SSFM). Note that the actual propagation of the pulse takes up just a few lines of code. Most of the other code is simply plotting the results.

This example is contained in examples/simple_SSFM.py

importnumpyasnpimportmatplotlib.pyplotaspltimportpynloFWHM=0.050# pulse duration (ps)pulseWL=1550# pulse central wavelength (nm)EPP=50e-12# Energy per pulse (J)GDD=0.0# Group delay dispersion (ps^2)TOD=0.0# Third order dispersion (ps^3)Window=10.0# simulation window (ps)Steps=100# simulation stepsPoints=2**13# simulation pointsbeta2=-120# (ps^2/km)beta3=0.00# (ps^3/km)beta4=0.005# (ps^4/km)Length=20# length in mmAlpha=0.0# attentuation coefficient (dB/cm)Gamma=1000# Gamma (1/(W km)fibWL=pulseWL# Center WL of fiber (nm)Raman=True# Enable Raman effect?Steep=True# Enable self steepening?alpha=np.log((10**(Alpha*0.1))) *100# convert from dB/cm to 1/m# set up plots for the results:fig=plt.figure(figsize=(8,8))
ax0=plt.subplot2grid((3,2), (0, 0), rowspan=1)
ax1=plt.subplot2grid((3,2), (0, 1), rowspan=1)
ax2=plt.subplot2grid((3,2), (1, 0), rowspan=2, sharex=ax0)
ax3=plt.subplot2grid((3,2), (1, 1), rowspan=2, sharex=ax1)
######## This is where the PyNLO magic happens! ############################# create the pulse!pulse=pynlo.light.DerivedPulses.SechPulse(power=1, # Power will be scaled by set_eppT0_ps=FWHM/1.76,
center_wavelength_nm=pulseWL,
time_window_ps=Window,
GDD=GDD, TOD=TOD,
NPTS=Points,
frep_MHz=100,
power_is_avg=False)
# set the pulse energy!pulse.set_epp(EPP)
# create the fiber!fiber1=pynlo.media.fibers.fiber.FiberInstance()
fiber1.generate_fiber(Length*1e-3, center_wl_nm=fibWL, betas=(beta2, beta3, beta4),
gamma_W_m=Gamma*1e-3, gvd_units='ps^n/km', gain=-alpha)
# Propagationevol=pynlo.interactions.FourWaveMixing.SSFM.SSFM(local_error=0.005, USE_SIMPLE_RAMAN=True,
disable_Raman=np.logical_not(Raman),
disable_self_steepening=np.logical_not(Steep))
y, AW, AT, pulse_out=evol.propagate(pulse_in=pulse, fiber=fiber1, n_steps=Steps)
########## That's it! Physics complete. Just plotting commands from here! ################F=pulse.F_THz# Frequency grid of pulse (THz)defdB(num):
return10*np.log10(np.abs(num)**2)
zW=dB( np.transpose(AW)[:, (F>0)] )
zT=dB( np.transpose(AT) )
y_mm=y*1e3# convert distance to mmax0.plot(pulse_out.F_THz, dB(pulse_out.AW), color='r')
ax1.plot(pulse_out.T_ps, dB(pulse_out.AT), color='r')
ax0.plot(pulse.F_THz, dB(pulse.AW), color='b')
ax1.plot(pulse.T_ps, dB(pulse.AT), color='b')
extent= (np.min(F[F>0]), np.max(F[F>0]), 0, Length)
ax2.imshow(zW, extent=extent,
vmin=np.max(zW) -40.0, vmax=np.max(zW),
aspect='auto', origin='lower')
extent= (np.min(pulse.T_ps), np.max(pulse.T_ps), np.min(y_mm), Length)
ax3.imshow(zT, extent=extent,
vmin=np.max(zT) -40.0, vmax=np.max(zT),
aspect='auto', origin='lower')
ax0.set_ylabel('Intensity (dB)')
ax0.set_ylim( -80, 0)
ax1.set_ylim( -40, 40)
ax2.set_ylabel('Propagation distance (mm)')
ax2.set_xlabel('Frequency (THz)')
ax2.set_xlim(0,400)
ax3.set_xlabel('Time (ps)')
plt.show()

Here are the results:

results

Contributing

We welcome suggestions for improvement, questions, comments, etc. The best way to to open a new issue here: https://github.com/pyNLO/PyNLO/issues/.

License

PyNLO is licensed under the GPLv3 license. This means that you are free to use PyNLO for any open-source project. Of course, PyNLO is provided "as is" with absolutely no warrenty.

References

[1] Johan Hult, "A Fourth-Order Runge–Kutta in the Interaction Picture Method for Simulating Supercontinuum Generation in Optical Fibers," J. Lightwave Technol. 25, 3770-3775 (2007) https://www.osapublishing.org/jlt/abstract.cfm?uri=jlt-25-12-3770

About

Python package for nonlinear optics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

pyNLO: Nonlinear optics modeling for Python

This README is best viewed at http://pynlo.readthedocs.io/en/latest/readme_link.html

Complete documentation is available at http://pynlo.readthedocs.io/

PyNLO

Introduction

PyNLO provides an easy-to-use, object-oriented set of tools for modeling the nonlinear interaction of light with materials. It provides many functionalities for representing pulses of light, beams of light, and nonlinear materials, such as crystals and fibers. Also, it features methods for simulating both three-wave-mixing processes (such as DFG), as well as four-wave-mixing processes such as supercontinuum generation.

Features:
  • A solver for the propagation of light through a Chi-3 material, useful for simulation pulse compression and supercontinuum generation in an optical fiber. This solver is highly efficient, thanks to an adaptive-step-size implementation of the "Fourth-order Runge-Kutta in the Interaction Picture " (RK4IP) method of Hult (2007).
  • A solver for simulating Chi-2 processes such as difference frequency generation.
  • A flexible object-oriented system for treating laser pulses, beams, fibers, and crystals.
  • ...and much more!

Installation

PyNLO requires Python 2, and is tested on Python 2.7 (Python 3 compatibility is a work-in-progress). If you don't already have Python, we recommend an "all in one" Python package such as the Anaconda Python Distribution, which is available for free.

With pip

The latest "official release" can be installed from PyPi with

pip install pynlo

The up-to-the-minute latest version can be installed from GitHub with

pip install git+https://github.com/pyNLO/PyNLO.git

With setuptools

Alternatively, you can download the latest version from the PyNLO Github site (look for the "download zip" button), cd to the PyNLO directory, and use

python setup.py install

Or, if you wish to edit the PyNLO source code without re-installing each time

python setup.py develop

Documentation

The complete documentation for PyNLO is availabe at https://pynlo.readthedocs.org.

Example of use

The following example demonstrates how to use PyNLO to simulate the propagation of a 50 fs pulse through a nonlinear fiber using the split-step Fourier model (SSFM). Note that the actual propagation of the pulse takes up just a few lines of code. Most of the other code is simply plotting the results.

This example is contained in examples/simple_SSFM.py

importnumpyasnpimportmatplotlib.pyplotaspltimportpynloFWHM=0.050# pulse duration (ps)pulseWL=1550# pulse central wavelength (nm)EPP=50e-12# Energy per pulse (J)GDD=0.0# Group delay dispersion (ps^2)TOD=0.0# Third order dispersion (ps^3)Window=10.0# simulation window (ps)Steps=100# simulation stepsPoints=2**13# simulation pointsbeta2=-120# (ps^2/km)beta3=0.00# (ps^3/km)beta4=0.005# (ps^4/km)Length=20# length in mmAlpha=0.0# attentuation coefficient (dB/cm)Gamma=1000# Gamma (1/(W km)fibWL=pulseWL# Center WL of fiber (nm)Raman=True# Enable Raman effect?Steep=True# Enable self steepening?alpha=np.log((10**(Alpha*0.1))) *100# convert from dB/cm to 1/m# set up plots for the results:fig=plt.figure(figsize=(8,8))
ax0=plt.subplot2grid((3,2), (0, 0), rowspan=1)
ax1=plt.subplot2grid((3,2), (0, 1), rowspan=1)
ax2=plt.subplot2grid((3,2), (1, 0), rowspan=2, sharex=ax0)
ax3=plt.subplot2grid((3,2), (1, 1), rowspan=2, sharex=ax1)
######## This is where the PyNLO magic happens! ############################# create the pulse!pulse=pynlo.light.DerivedPulses.SechPulse(power=1, # Power will be scaled by set_eppT0_ps=FWHM/1.76,
center_wavelength_nm=pulseWL,
time_window_ps=Window,
GDD=GDD, TOD=TOD,
NPTS=Points,
frep_MHz=100,
power_is_avg=False)
# set the pulse energy!pulse.set_epp(EPP)
# create the fiber!fiber1=pynlo.media.fibers.fiber.FiberInstance()
fiber1.generate_fiber(Length*1e-3, center_wl_nm=fibWL, betas=(beta2, beta3, beta4),
gamma_W_m=Gamma*1e-3, gvd_units='ps^n/km', gain=-alpha)
# Propagationevol=pynlo.interactions.FourWaveMixing.SSFM.SSFM(local_error=0.005, USE_SIMPLE_RAMAN=True,
disable_Raman=np.logical_not(Raman),
disable_self_steepening=np.logical_not(Steep))
y, AW, AT, pulse_out=evol.propagate(pulse_in=pulse, fiber=fiber1, n_steps=Steps)
########## That's it! Physics complete. Just plotting commands from here! ################F=pulse.F_THz# Frequency grid of pulse (THz)defdB(num):
return10*np.log10(np.abs(num)**2)
zW=dB( np.transpose(AW)[:, (F>0)] )
zT=dB( np.transpose(AT) )
y_mm=y*1e3# convert distance to mmax0.plot(pulse_out.F_THz, dB(pulse_out.AW), color='r')
ax1.plot(pulse_out.T_ps, dB(pulse_out.AT), color='r')
ax0.plot(pulse.F_THz, dB(pulse.AW), color='b')
ax1.plot(pulse.T_ps, dB(pulse.AT), color='b')
extent= (np.min(F[F>0]), np.max(F[F>0]), 0, Length)
ax2.imshow(zW, extent=extent,
vmin=np.max(zW) -40.0, vmax=np.max(zW),
aspect='auto', origin='lower')
extent= (np.min(pulse.T_ps), np.max(pulse.T_ps), np.min(y_mm), Length)
ax3.imshow(zT, extent=extent,
vmin=np.max(zT) -40.0, vmax=np.max(zT),
aspect='auto', origin='lower')
ax0.set_ylabel('Intensity (dB)')
ax0.set_ylim( -80, 0)
ax1.set_ylim( -40, 40)
ax2.set_ylabel('Propagation distance (mm)')
ax2.set_xlabel('Frequency (THz)')
ax2.set_xlim(0,400)
ax3.set_xlabel('Time (ps)')
plt.show()

Here are the results:

results

Contributing

We welcome suggestions for improvement, questions, comments, etc. The best way to to open a new issue here: https://github.com/pyNLO/PyNLO/issues/.

License

PyNLO is licensed under the GPLv3 license. This means that you are free to use PyNLO for any open-source project. Of course, PyNLO is provided "as is" with absolutely no warrenty.

References

[1] Johan Hult, "A Fourth-Order Runge–Kutta in the Interaction Picture Method for Simulating Supercontinuum Generation in Optical Fibers," J. Lightwave Technol. 25, 3770-3775 (2007) https://www.osapublishing.org/jlt/abstract.cfm?uri=jlt-25-12-3770

About

Python package for nonlinear optics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

pyNLO: Nonlinear optics modeling for Python

This README is best viewed at http://pynlo.readthedocs.io/en/latest/readme_link.html

Complete documentation is available at http://pynlo.readthedocs.io/

PyNLO

Introduction

PyNLO provides an easy-to-use, object-oriented set of tools for modeling the nonlinear interaction of light with materials. It provides many functionalities for representing pulses of light, beams of light, and nonlinear materials, such as crystals and fibers. Also, it features methods for simulating both three-wave-mixing processes (such as DFG), as well as four-wave-mixing processes such as supercontinuum generation.

Features:
  • A solver for the propagation of light through a Chi-3 material, useful for simulation pulse compression and supercontinuum generation in an optical fiber. This solver is highly efficient, thanks to an adaptive-step-size implementation of the "Fourth-order Runge-Kutta in the Interaction Picture " (RK4IP) method of Hult (2007).
  • A solver for simulating Chi-2 processes such as difference frequency generation.
  • A flexible object-oriented system for treating laser pulses, beams, fibers, and crystals.
  • ...and much more!

Installation

PyNLO requires Python 2, and is tested on Python 2.7 (Python 3 compatibility is a work-in-progress). If you don't already have Python, we recommend an "all in one" Python package such as the Anaconda Python Distribution, which is available for free.

With pip

The latest "official release" can be installed from PyPi with

pip install pynlo

The up-to-the-minute latest version can be installed from GitHub with

pip install git+https://github.com/pyNLO/PyNLO.git

With setuptools

Alternatively, you can download the latest version from the PyNLO Github site (look for the "download zip" button), cd to the PyNLO directory, and use

python setup.py install

Or, if you wish to edit the PyNLO source code without re-installing each time

python setup.py develop

Documentation

The complete documentation for PyNLO is availabe at https://pynlo.readthedocs.org.

Example of use

The following example demonstrates how to use PyNLO to simulate the propagation of a 50 fs pulse through a nonlinear fiber using the split-step Fourier model (SSFM). Note that the actual propagation of the pulse takes up just a few lines of code. Most of the other code is simply plotting the results.

This example is contained in examples/simple_SSFM.py

importnumpyasnpimportmatplotlib.pyplotaspltimportpynloFWHM=0.050# pulse duration (ps)pulseWL=1550# pulse central wavelength (nm)EPP=50e-12# Energy per pulse (J)GDD=0.0# Group delay dispersion (ps^2)TOD=0.0# Third order dispersion (ps^3)Window=10.0# simulation window (ps)Steps=100# simulation stepsPoints=2**13# simulation pointsbeta2=-120# (ps^2/km)beta3=0.00# (ps^3/km)beta4=0.005# (ps^4/km)Length=20# length in mmAlpha=0.0# attentuation coefficient (dB/cm)Gamma=1000# Gamma (1/(W km)fibWL=pulseWL# Center WL of fiber (nm)Raman=True# Enable Raman effect?Steep=True# Enable self steepening?alpha=np.log((10**(Alpha*0.1))) *100# convert from dB/cm to 1/m# set up plots for the results:fig=plt.figure(figsize=(8,8))
ax0=plt.subplot2grid((3,2), (0, 0), rowspan=1)
ax1=plt.subplot2grid((3,2), (0, 1), rowspan=1)
ax2=plt.subplot2grid((3,2), (1, 0), rowspan=2, sharex=ax0)
ax3=plt.subplot2grid((3,2), (1, 1), rowspan=2, sharex=ax1)
######## This is where the PyNLO magic happens! ############################# create the pulse!pulse=pynlo.light.DerivedPulses.SechPulse(power=1, # Power will be scaled by set_eppT0_ps=FWHM/1.76,
center_wavelength_nm=pulseWL,
time_window_ps=Window,
GDD=GDD, TOD=TOD,
NPTS=Points,
frep_MHz=100,
power_is_avg=False)
# set the pulse energy!pulse.set_epp(EPP)
# create the fiber!fiber1=pynlo.media.fibers.fiber.FiberInstance()
fiber1.generate_fiber(Length*1e-3, center_wl_nm=fibWL, betas=(beta2, beta3, beta4),
gamma_W_m=Gamma*1e-3, gvd_units='ps^n/km', gain=-alpha)
# Propagationevol=pynlo.interactions.FourWaveMixing.SSFM.SSFM(local_error=0.005, USE_SIMPLE_RAMAN=True,
disable_Raman=np.logical_not(Raman),
disable_self_steepening=np.logical_not(Steep))
y, AW, AT, pulse_out=evol.propagate(pulse_in=pulse, fiber=fiber1, n_steps=Steps)
########## That's it! Physics complete. Just plotting commands from here! ################F=pulse.F_THz# Frequency grid of pulse (THz)defdB(num):
return10*np.log10(np.abs(num)**2)
zW=dB( np.transpose(AW)[:, (F>0)] )
zT=dB( np.transpose(AT) )
y_mm=y*1e3# convert distance to mmax0.plot(pulse_out.F_THz, dB(pulse_out.AW), color='r')
ax1.plot(pulse_out.T_ps, dB(pulse_out.AT), color='r')
ax0.plot(pulse.F_THz, dB(pulse.AW), color='b')
ax1.plot(pulse.T_ps, dB(pulse.AT), color='b')
extent= (np.min(F[F>0]), np.max(F[F>0]), 0, Length)
ax2.imshow(zW, extent=extent,
vmin=np.max(zW) -40.0, vmax=np.max(zW),
aspect='auto', origin='lower')
extent= (np.min(pulse.T_ps), np.max(pulse.T_ps), np.min(y_mm), Length)
ax3.imshow(zT, extent=extent,
vmin=np.max(zT) -40.0, vmax=np.max(zT),
aspect='auto', origin='lower')
ax0.set_ylabel('Intensity (dB)')
ax0.set_ylim( -80, 0)
ax1.set_ylim( -40, 40)
ax2.set_ylabel('Propagation distance (mm)')
ax2.set_xlabel('Frequency (THz)')
ax2.set_xlim(0,400)
ax3.set_xlabel('Time (ps)')
plt.show()

Here are the results:

results

Contributing

We welcome suggestions for improvement, questions, comments, etc. The best way to to open a new issue here: https://github.com/pyNLO/PyNLO/issues/.

License

PyNLO is licensed under the GPLv3 license. This means that you are free to use PyNLO for any open-source project. Of course, PyNLO is provided "as is" with absolutely no warrenty.

References

[1] Johan Hult, "A Fourth-Order Runge–Kutta in the Interaction Picture Method for Simulating Supercontinuum Generation in Optical Fibers," J. Lightwave Technol. 25, 3770-3775 (2007) https://www.osapublishing.org/jlt/abstract.cfm?uri=jlt-25-12-3770

About

Python package for nonlinear optics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

pyNLO: Nonlinear optics modeling for Python

This README is best viewed at http://pynlo.readthedocs.io/en/latest/readme_link.html

Complete documentation is available at http://pynlo.readthedocs.io/

PyNLO

Introduction

PyNLO provides an easy-to-use, object-oriented set of tools for modeling the nonlinear interaction of light with materials. It provides many functionalities for representing pulses of light, beams of light, and nonlinear materials, such as crystals and fibers. Also, it features methods for simulating both three-wave-mixing processes (such as DFG), as well as four-wave-mixing processes such as supercontinuum generation.

Features:
  • A solver for the propagation of light through a Chi-3 material, useful for simulation pulse compression and supercontinuum generation in an optical fiber. This solver is highly efficient, thanks to an adaptive-step-size implementation of the "Fourth-order Runge-Kutta in the Interaction Picture " (RK4IP) method of Hult (2007).
  • A solver for simulating Chi-2 processes such as difference frequency generation.
  • A flexible object-oriented system for treating laser pulses, beams, fibers, and crystals.
  • ...and much more!

Installation

PyNLO requires Python 2, and is tested on Python 2.7 (Python 3 compatibility is a work-in-progress). If you don't already have Python, we recommend an "all in one" Python package such as the Anaconda Python Distribution, which is available for free.

With pip

The latest "official release" can be installed from PyPi with

pip install pynlo

The up-to-the-minute latest version can be installed from GitHub with

pip install git+https://github.com/pyNLO/PyNLO.git

With setuptools

Alternatively, you can download the latest version from the PyNLO Github site (look for the "download zip" button), cd to the PyNLO directory, and use

python setup.py install

Or, if you wish to edit the PyNLO source code without re-installing each time

python setup.py develop

Documentation

The complete documentation for PyNLO is availabe at https://pynlo.readthedocs.org.

Example of use

The following example demonstrates how to use PyNLO to simulate the propagation of a 50 fs pulse through a nonlinear fiber using the split-step Fourier model (SSFM). Note that the actual propagation of the pulse takes up just a few lines of code. Most of the other code is simply plotting the results.

This example is contained in examples/simple_SSFM.py

importnumpyasnpimportmatplotlib.pyplotaspltimportpynloFWHM=0.050# pulse duration (ps)pulseWL=1550# pulse central wavelength (nm)EPP=50e-12# Energy per pulse (J)GDD=0.0# Group delay dispersion (ps^2)TOD=0.0# Third order dispersion (ps^3)Window=10.0# simulation window (ps)Steps=100# simulation stepsPoints=2**13# simulation pointsbeta2=-120# (ps^2/km)beta3=0.00# (ps^3/km)beta4=0.005# (ps^4/km)Length=20# length in mmAlpha=0.0# attentuation coefficient (dB/cm)Gamma=1000# Gamma (1/(W km)fibWL=pulseWL# Center WL of fiber (nm)Raman=True# Enable Raman effect?Steep=True# Enable self steepening?alpha=np.log((10**(Alpha*0.1))) *100# convert from dB/cm to 1/m# set up plots for the results:fig=plt.figure(figsize=(8,8))
ax0=plt.subplot2grid((3,2), (0, 0), rowspan=1)
ax1=plt.subplot2grid((3,2), (0, 1), rowspan=1)
ax2=plt.subplot2grid((3,2), (1, 0), rowspan=2, sharex=ax0)
ax3=plt.subplot2grid((3,2), (1, 1), rowspan=2, sharex=ax1)
######## This is where the PyNLO magic happens! ############################# create the pulse!pulse=pynlo.light.DerivedPulses.SechPulse(power=1, # Power will be scaled by set_eppT0_ps=FWHM/1.76,
center_wavelength_nm=pulseWL,
time_window_ps=Window,
GDD=GDD, TOD=TOD,
NPTS=Points,
frep_MHz=100,
power_is_avg=False)
# set the pulse energy!pulse.set_epp(EPP)
# create the fiber!fiber1=pynlo.media.fibers.fiber.FiberInstance()
fiber1.generate_fiber(Length*1e-3, center_wl_nm=fibWL, betas=(beta2, beta3, beta4),
gamma_W_m=Gamma*1e-3, gvd_units='ps^n/km', gain=-alpha)
# Propagationevol=pynlo.interactions.FourWaveMixing.SSFM.SSFM(local_error=0.005, USE_SIMPLE_RAMAN=True,
disable_Raman=np.logical_not(Raman),
disable_self_steepening=np.logical_not(Steep))
y, AW, AT, pulse_out=evol.propagate(pulse_in=pulse, fiber=fiber1, n_steps=Steps)
########## That's it! Physics complete. Just plotting commands from here! ################F=pulse.F_THz# Frequency grid of pulse (THz)defdB(num):
return10*np.log10(np.abs(num)**2)
zW=dB( np.transpose(AW)[:, (F>0)] )
zT=dB( np.transpose(AT) )
y_mm=y*1e3# convert distance to mmax0.plot(pulse_out.F_THz, dB(pulse_out.AW), color='r')
ax1.plot(pulse_out.T_ps, dB(pulse_out.AT), color='r')
ax0.plot(pulse.F_THz, dB(pulse.AW), color='b')
ax1.plot(pulse.T_ps, dB(pulse.AT), color='b')
extent= (np.min(F[F>0]), np.max(F[F>0]), 0, Length)
ax2.imshow(zW, extent=extent,
vmin=np.max(zW) -40.0, vmax=np.max(zW),
aspect='auto', origin='lower')
extent= (np.min(pulse.T_ps), np.max(pulse.T_ps), np.min(y_mm), Length)
ax3.imshow(zT, extent=extent,
vmin=np.max(zT) -40.0, vmax=np.max(zT),
aspect='auto', origin='lower')
ax0.set_ylabel('Intensity (dB)')
ax0.set_ylim( -80, 0)
ax1.set_ylim( -40, 40)
ax2.set_ylabel('Propagation distance (mm)')
ax2.set_xlabel('Frequency (THz)')
ax2.set_xlim(0,400)
ax3.set_xlabel('Time (ps)')
plt.show()

Here are the results:

results

Contributing

We welcome suggestions for improvement, questions, comments, etc. The best way to to open a new issue here: https://github.com/pyNLO/PyNLO/issues/.

License

PyNLO is licensed under the GPLv3 license. This means that you are free to use PyNLO for any open-source project. Of course, PyNLO is provided "as is" with absolutely no warrenty.

References

[1] Johan Hult, "A Fourth-Order Runge–Kutta in the Interaction Picture Method for Simulating Supercontinuum Generation in Optical Fibers," J. Lightwave Technol. 25, 3770-3775 (2007) https://www.osapublishing.org/jlt/abstract.cfm?uri=jlt-25-12-3770

About

Python package for nonlinear optics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

pyNLO: Nonlinear optics modeling for Python

This README is best viewed at http://pynlo.readthedocs.io/en/latest/readme_link.html

Complete documentation is available at http://pynlo.readthedocs.io/

PyNLO

Introduction

PyNLO provides an easy-to-use, object-oriented set of tools for modeling the nonlinear interaction of light with materials. It provides many functionalities for representing pulses of light, beams of light, and nonlinear materials, such as crystals and fibers. Also, it features methods for simulating both three-wave-mixing processes (such as DFG), as well as four-wave-mixing processes such as supercontinuum generation.

Features:
  • A solver for the propagation of light through a Chi-3 material, useful for simulation pulse compression and supercontinuum generation in an optical fiber. This solver is highly efficient, thanks to an adaptive-step-size implementation of the "Fourth-order Runge-Kutta in the Interaction Picture " (RK4IP) method of Hult (2007).
  • A solver for simulating Chi-2 processes such as difference frequency generation.
  • A flexible object-oriented system for treating laser pulses, beams, fibers, and crystals.
  • ...and much more!

Installation

PyNLO requires Python 2, and is tested on Python 2.7 (Python 3 compatibility is a work-in-progress). If you don't already have Python, we recommend an "all in one" Python package such as the Anaconda Python Distribution, which is available for free.

With pip

The latest "official release" can be installed from PyPi with

pip install pynlo

The up-to-the-minute latest version can be installed from GitHub with

pip install git+https://github.com/pyNLO/PyNLO.git

With setuptools

Alternatively, you can download the latest version from the PyNLO Github site (look for the "download zip" button), cd to the PyNLO directory, and use

python setup.py install

Or, if you wish to edit the PyNLO source code without re-installing each time

python setup.py develop

Documentation

The complete documentation for PyNLO is availabe at https://pynlo.readthedocs.org.

Example of use

The following example demonstrates how to use PyNLO to simulate the propagation of a 50 fs pulse through a nonlinear fiber using the split-step Fourier model (SSFM). Note that the actual propagation of the pulse takes up just a few lines of code. Most of the other code is simply plotting the results.

This example is contained in examples/simple_SSFM.py

importnumpyasnpimportmatplotlib.pyplotaspltimportpynloFWHM=0.050# pulse duration (ps)pulseWL=1550# pulse central wavelength (nm)EPP=50e-12# Energy per pulse (J)GDD=0.0# Group delay dispersion (ps^2)TOD=0.0# Third order dispersion (ps^3)Window=10.0# simulation window (ps)Steps=100# simulation stepsPoints=2**13# simulation pointsbeta2=-120# (ps^2/km)beta3=0.00# (ps^3/km)beta4=0.005# (ps^4/km)Length=20# length in mmAlpha=0.0# attentuation coefficient (dB/cm)Gamma=1000# Gamma (1/(W km)fibWL=pulseWL# Center WL of fiber (nm)Raman=True# Enable Raman effect?Steep=True# Enable self steepening?alpha=np.log((10**(Alpha*0.1))) *100# convert from dB/cm to 1/m# set up plots for the results:fig=plt.figure(figsize=(8,8))
ax0=plt.subplot2grid((3,2), (0, 0), rowspan=1)
ax1=plt.subplot2grid((3,2), (0, 1), rowspan=1)
ax2=plt.subplot2grid((3,2), (1, 0), rowspan=2, sharex=ax0)
ax3=plt.subplot2grid((3,2), (1, 1), rowspan=2, sharex=ax1)
######## This is where the PyNLO magic happens! ############################# create the pulse!pulse=pynlo.light.DerivedPulses.SechPulse(power=1, # Power will be scaled by set_eppT0_ps=FWHM/1.76,
center_wavelength_nm=pulseWL,
time_window_ps=Window,
GDD=GDD, TOD=TOD,
NPTS=Points,
frep_MHz=100,
power_is_avg=False)
# set the pulse energy!pulse.set_epp(EPP)
# create the fiber!fiber1=pynlo.media.fibers.fiber.FiberInstance()
fiber1.generate_fiber(Length*1e-3, center_wl_nm=fibWL, betas=(beta2, beta3, beta4),
gamma_W_m=Gamma*1e-3, gvd_units='ps^n/km', gain=-alpha)
# Propagationevol=pynlo.interactions.FourWaveMixing.SSFM.SSFM(local_error=0.005, USE_SIMPLE_RAMAN=True,
disable_Raman=np.logical_not(Raman),
disable_self_steepening=np.logical_not(Steep))
y, AW, AT, pulse_out=evol.propagate(pulse_in=pulse, fiber=fiber1, n_steps=Steps)
########## That's it! Physics complete. Just plotting commands from here! ################F=pulse.F_THz# Frequency grid of pulse (THz)defdB(num):
return10*np.log10(np.abs(num)**2)
zW=dB( np.transpose(AW)[:, (F>0)] )
zT=dB( np.transpose(AT) )
y_mm=y*1e3# convert distance to mmax0.plot(pulse_out.F_THz, dB(pulse_out.AW), color='r')
ax1.plot(pulse_out.T_ps, dB(pulse_out.AT), color='r')
ax0.plot(pulse.F_THz, dB(pulse.AW), color='b')
ax1.plot(pulse.T_ps, dB(pulse.AT), color='b')
extent= (np.min(F[F>0]), np.max(F[F>0]), 0, Length)
ax2.imshow(zW, extent=extent,
vmin=np.max(zW) -40.0, vmax=np.max(zW),
aspect='auto', origin='lower')
extent= (np.min(pulse.T_ps), np.max(pulse.T_ps), np.min(y_mm), Length)
ax3.imshow(zT, extent=extent,
vmin=np.max(zT) -40.0, vmax=np.max(zT),
aspect='auto', origin='lower')
ax0.set_ylabel('Intensity (dB)')
ax0.set_ylim( -80, 0)
ax1.set_ylim( -40, 40)
ax2.set_ylabel('Propagation distance (mm)')
ax2.set_xlabel('Frequency (THz)')
ax2.set_xlim(0,400)
ax3.set_xlabel('Time (ps)')
plt.show()

Here are the results:

results

Contributing

We welcome suggestions for improvement, questions, comments, etc. The best way to to open a new issue here: https://github.com/pyNLO/PyNLO/issues/.

License

PyNLO is licensed under the GPLv3 license. This means that you are free to use PyNLO for any open-source project. Of course, PyNLO is provided "as is" with absolutely no warrenty.

References

[1] Johan Hult, "A Fourth-Order Runge–Kutta in the Interaction Picture Method for Simulating Supercontinuum Generation in Optical Fibers," J. Lightwave Technol. 25, 3770-3775 (2007) https://www.osapublishing.org/jlt/abstract.cfm?uri=jlt-25-12-3770

About

Python package for nonlinear optics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

pyNLO: Nonlinear optics modeling for Python

This README is best viewed at http://pynlo.readthedocs.io/en/latest/readme_link.html

Complete documentation is available at http://pynlo.readthedocs.io/

PyNLO

Introduction

PyNLO provides an easy-to-use, object-oriented set of tools for modeling the nonlinear interaction of light with materials. It provides many functionalities for representing pulses of light, beams of light, and nonlinear materials, such as crystals and fibers. Also, it features methods for simulating both three-wave-mixing processes (such as DFG), as well as four-wave-mixing processes such as supercontinuum generation.

Features:
  • A solver for the propagation of light through a Chi-3 material, useful for simulation pulse compression and supercontinuum generation in an optical fiber. This solver is highly efficient, thanks to an adaptive-step-size implementation of the "Fourth-order Runge-Kutta in the Interaction Picture " (RK4IP) method of Hult (2007).
  • A solver for simulating Chi-2 processes such as difference frequency generation.
  • A flexible object-oriented system for treating laser pulses, beams, fibers, and crystals.
  • ...and much more!

Installation

PyNLO requires Python 2, and is tested on Python 2.7 (Python 3 compatibility is a work-in-progress). If you don't already have Python, we recommend an "all in one" Python package such as the Anaconda Python Distribution, which is available for free.

With pip

The latest "official release" can be installed from PyPi with

pip install pynlo

The up-to-the-minute latest version can be installed from GitHub with

pip install git+https://github.com/pyNLO/PyNLO.git

With setuptools

Alternatively, you can download the latest version from the PyNLO Github site (look for the "download zip" button), cd to the PyNLO directory, and use

python setup.py install

Or, if you wish to edit the PyNLO source code without re-installing each time

python setup.py develop

Documentation

The complete documentation for PyNLO is availabe at https://pynlo.readthedocs.org.

Example of use

The following example demonstrates how to use PyNLO to simulate the propagation of a 50 fs pulse through a nonlinear fiber using the split-step Fourier model (SSFM). Note that the actual propagation of the pulse takes up just a few lines of code. Most of the other code is simply plotting the results.

This example is contained in examples/simple_SSFM.py

importnumpyasnpimportmatplotlib.pyplotaspltimportpynloFWHM=0.050# pulse duration (ps)pulseWL=1550# pulse central wavelength (nm)EPP=50e-12# Energy per pulse (J)GDD=0.0# Group delay dispersion (ps^2)TOD=0.0# Third order dispersion (ps^3)Window=10.0# simulation window (ps)Steps=100# simulation stepsPoints=2**13# simulation pointsbeta2=-120# (ps^2/km)beta3=0.00# (ps^3/km)beta4=0.005# (ps^4/km)Length=20# length in mmAlpha=0.0# attentuation coefficient (dB/cm)Gamma=1000# Gamma (1/(W km)fibWL=pulseWL# Center WL of fiber (nm)Raman=True# Enable Raman effect?Steep=True# Enable self steepening?alpha=np.log((10**(Alpha*0.1))) *100# convert from dB/cm to 1/m# set up plots for the results:fig=plt.figure(figsize=(8,8))
ax0=plt.subplot2grid((3,2), (0, 0), rowspan=1)
ax1=plt.subplot2grid((3,2), (0, 1), rowspan=1)
ax2=plt.subplot2grid((3,2), (1, 0), rowspan=2, sharex=ax0)
ax3=plt.subplot2grid((3,2), (1, 1), rowspan=2, sharex=ax1)
######## This is where the PyNLO magic happens! ############################# create the pulse!pulse=pynlo.light.DerivedPulses.SechPulse(power=1, # Power will be scaled by set_eppT0_ps=FWHM/1.76,
center_wavelength_nm=pulseWL,
time_window_ps=Window,
GDD=GDD, TOD=TOD,
NPTS=Points,
frep_MHz=100,
power_is_avg=False)
# set the pulse energy!pulse.set_epp(EPP)
# create the fiber!fiber1=pynlo.media.fibers.fiber.FiberInstance()
fiber1.generate_fiber(Length*1e-3, center_wl_nm=fibWL, betas=(beta2, beta3, beta4),
gamma_W_m=Gamma*1e-3, gvd_units='ps^n/km', gain=-alpha)
# Propagationevol=pynlo.interactions.FourWaveMixing.SSFM.SSFM(local_error=0.005, USE_SIMPLE_RAMAN=True,
disable_Raman=np.logical_not(Raman),
disable_self_steepening=np.logical_not(Steep))
y, AW, AT, pulse_out=evol.propagate(pulse_in=pulse, fiber=fiber1, n_steps=Steps)
########## That's it! Physics complete. Just plotting commands from here! ################F=pulse.F_THz# Frequency grid of pulse (THz)defdB(num):
return10*np.log10(np.abs(num)**2)
zW=dB( np.transpose(AW)[:, (F>0)] )
zT=dB( np.transpose(AT) )
y_mm=y*1e3# convert distance to mmax0.plot(pulse_out.F_THz, dB(pulse_out.AW), color='r')
ax1.plot(pulse_out.T_ps, dB(pulse_out.AT), color='r')
ax0.plot(pulse.F_THz, dB(pulse.AW), color='b')
ax1.plot(pulse.T_ps, dB(pulse.AT), color='b')
extent= (np.min(F[F>0]), np.max(F[F>0]), 0, Length)
ax2.imshow(zW, extent=extent,
vmin=np.max(zW) -40.0, vmax=np.max(zW),
aspect='auto', origin='lower')
extent= (np.min(pulse.T_ps), np.max(pulse.T_ps), np.min(y_mm), Length)
ax3.imshow(zT, extent=extent,
vmin=np.max(zT) -40.0, vmax=np.max(zT),
aspect='auto', origin='lower')
ax0.set_ylabel('Intensity (dB)')
ax0.set_ylim( -80, 0)
ax1.set_ylim( -40, 40)
ax2.set_ylabel('Propagation distance (mm)')
ax2.set_xlabel('Frequency (THz)')
ax2.set_xlim(0,400)
ax3.set_xlabel('Time (ps)')
plt.show()

Here are the results:

results

Contributing

We welcome suggestions for improvement, questions, comments, etc. The best way to to open a new issue here: https://github.com/pyNLO/PyNLO/issues/.

License

PyNLO is licensed under the GPLv3 license. This means that you are free to use PyNLO for any open-source project. Of course, PyNLO is provided "as is" with absolutely no warrenty.

References

[1] Johan Hult, "A Fourth-Order Runge–Kutta in the Interaction Picture Method for Simulating Supercontinuum Generation in Optical Fibers," J. Lightwave Technol. 25, 3770-3775 (2007) https://www.osapublishing.org/jlt/abstract.cfm?uri=jlt-25-12-3770

About

Python package for nonlinear optics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages