-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmydocs.pd
More file actions
1204 lines (875 loc) · 53.7 KB
/
mydocs.pd
File metadata and controls
1204 lines (875 loc) · 53.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# About
## What Is IOpy?
IOpy is a python-based package for solving the equations of motion of coupled oscillators which are in contact with thermal baths. These equations which are in the form of Langevin equations (or quantum Langevin equations in quantum limit) appear in many research areas in physics. Specifically, in optomechanics, which is the study of interaction of light with mechanical oscillators, this problem forms the essence of the theory. Finding the solutions of Langevin equations in different optomechanical systems can help with discovering and understanding novel phenomena. However, the procedure of finding these solutions is similar in many cases ([input-output formalism](http://127.0.0.1:8000/theory/#input-output-formalism), which is where the name IOpy is coming from) and the essential difference between them is the difference between the physical setups. Moreover, in complex setups the calculations necessary to find the solutions can be hard and tedious to do by hand (for example inverting matrices with large dimensions).
On the other hand, in many problems in optomechanics there are a lot of physical phenomena which are involved in the dynamics. For newcomers to the field, like students who want to learn optomechanics, it can be confusing to distinguish between the different effects involved in the dynamics. Looking for a solution to resolve the two mentioned issues was the motivation to write this code.
With IOpy, you can define your physical setup very fast and without the need for going through the details. Further more you can visualize the results in a way which can help people to test their theoretical results and also help newcomers to grasp the elements of the optomechanics. For example to see the emission spectrum of a hot optical resonator you can define your optical mode in a single line:
```python
a = Mode(name = 'a', omega = 5e9 *2*np.pi)
```
And then defining the thermal bath and the driving field can be done each in a single line:
```python
a_inex = Input(name = 'ex', a, kappa = 0.2e6 *2*np.pi,
kind = 'drive', omega_drive = 5e9 *2*np.pi,
bath_temp = 2e-5)
a_in0 = Input('0', a, kappa = 0.3e6 *2*np.pi, kind = 'bath',
bath_temp = 10e-3)
```
And finally defining the system, the output port and the spectrum:
```python
sys_cav = System([a], [a_in0, a_inex], [])
a_outex = Output(sys_cav, a_inex)
spec = me.spectrum(omegas, me.PowerMeasurement(a_outex),
components = False, plot = True)
```
And the result would be:
{width=460 .center}
\begin{figure}[!h]
\caption{Simple cavity output spectrum}
\end{figure}
<!--
<p align="center">
<img width="460" src="\Simple Cavity\simple_cavity_spectrum.png">
</p>
-->
A more detailed explanation of this example as well as more examples with respect to optomechanics are available on the [Examples](http://127.0.0.1:8000/Examples/) page.
## Structure of IOpy
IOpy consists out of four scripts which each serving a special purpose:
`elements`: For defining different components of the physical system (modes, couplings, input-output fields and the system)
`DCnonlinearities`: For calculation of DC shifts in the system variables due to nonlinear effects.
`measurement`: For calculating linear responses and power spectral densities.
`plots`: For visualizing the measurements' results in graphs.
## Installation
To install IOpy you have to clone the IOpy repository on your local computer. The packages you need for using IOpy are `numpy`, `scipy` and `matplotlib`.
<!--
### Comments of Nick
In general I would try to make a story around these two usecases.
IOpy aims for:
* testing and visulizing of theorectical models
* being an educational tool to learn about the classical effects in optomechanics
As an eyecatcher, it maybe makes sense to show a very short example of IOpy on the about page. (You can use the simple cavity example. But don't add a lot of explanation. This you will do in the examples section)
Usually people (including me =) ) that want to use the software for the first time, just look at the first page to start.
Also try to make a short comment about the structure of IOpy. What are the important files? And link to the section that gives a more detailed description.
At the end you should have some links to installation and further examples.
Installation:
git pull
and also name all the packages that have to installed to use iopy:
numpy, scipy, matplotlib (These are all the classics)
-->
# Theory
## Input-Output Formalism
On this Page, the theory behind the IOpy calculations is introduced.
There are different approaches to model open quantum systems. But the two most commonly used ones are the density matrix approach using master equations and the Langevin equations, which is also known as input-output theory. Input-output theory allows us to directly model the quantum fluctuations injected from any port into the system. Quantum Langevin equations are formulated on the level of the Heisenberg equations of motion describing the time evolution of any operator of the system. Moreover, in case of optical cavities any coherent laser drive that may be present can be taken into account. For more details see [Gardiner and Zoller (2004)](https://www.springer.com/de/book/9783540223016) and [Clerk et al. (2010)](http://dx.doi.org/10.1103/RevModPhys.82.1155).
<br />For example, for an optical cavity which is driven by a coherent laser field with the detuning $\Delta$ from the cavity resonance frequency, via a coupling of $\kappa_{ex}$ and is also coupled to the environment through the dissipation rate of $\kappa_0$, the equations of motion can be written as
$$\dot a = -\frac{\kappa}{2}a + i\Delta a + \sqrt{\kappa_{\text{ex}}}a_{\text{in},\text{ex}} + \sqrt{\kappa_{0}}a_{\text{in},0},$$
where $\kappa = \kappa_0 + \kappa_{\text{ex}}$ is the total dissipation rate. $a_{\text{in},\text{ex}}$ and $a_{\text{in},0}$ are input operators of the driving field and the stochastic thermal field respectively. This equation can also be written in terms of quadrature operators
$$\dot X = \Delta Y -\frac{\kappa}{2} X + \sqrt{\kappa_{\text{ex}}}\, X_{\text{in},\text{ex}} + \sqrt{\kappa_{0}}\, X_{\text{in},0}$$
$$\dot Y = -\Delta X -\frac{\kappa}{2} Y + \sqrt{\kappa_{\text{ex}}}\, Y_{\text{in},\text{ex}} + \sqrt{\kappa_{0}}\, Y_{\text{in},0},$$
where the quadrature operators are defined as
$$X = \frac{a^\dagger + a}{\sqrt{2}},$$
$$Y = i\frac{a^\dagger - a}{\sqrt{2}}.$$
According to the input-output theory of open quantum systems, the output field (which in case of optical cavity can be the reflected or transmitted light through the cavity) is given by
$$a_{\text{out}} = a_{\text{in}} - \sqrt{\kappa_{\text{ex}}}a.$$
It can also be written in terms of quadratures
$$X_{\text{out},\text{ex}} = X_{\text{in},\text{ex}} - \sqrt{\kappa_{\text{ex}}}\, X,$$
$$Y_{\text{out},\text{ex}} = Y_{\text{in},\text{ex}} - \sqrt{\kappa_{\text{ex}}}\, Y.$$
Any set of Langevin equations, linearized around a stationary solution, can in principle be written in the form
$$\dot Z = \textbf{M}Z + \textbf{L}Z_{\text{in}} \tag{1},$$
with the input-output relations
$$Z_{\text{out}} = Z_{\text{in}} - \textbf{L}^TZ,$$
where $Z$ is a vector containing the quadrature operators of different oscillators involved in the dynamics. $Z_{\text{in}}$ and $Z_{\text{out}}$ are vectors containing the quadrature operators of the input and output fields. For the optical cavity of the example above we have
$$Z = \begin{pmatrix} X \\ Y \end{pmatrix},\quad Z_{\text{in}} = \begin{pmatrix} X_{\text{in},\text{ex}} \\ Y_{\text{in},\text{ex}} \\ X_{\text{in},0} \\ Y_{\text{in},0}\end{pmatrix},\quad Z_{\text{out}} = \begin{pmatrix} X_{\text{out},\text{ex}} \\ Y_{\text{out},\text{ex}} \\ X_{\text{out},0} \\ Y_{\text{out},0}\end{pmatrix}$$
and
$$\textbf{M} = \begin{pmatrix} -\frac{\kappa}{2} &\Delta
\\-\Delta &-\frac{\kappa}{2} \end{pmatrix}, \quad
\textbf{L}= \begin{pmatrix} \sqrt{\kappa_{\text{ex}}} &0 &\sqrt{\kappa_{0}} &0
\\0 &\sqrt{\kappa_{\text{ex}}} &0 &\sqrt{\kappa_{0}}\end{pmatrix}.$$
Due to the linearity of the equations one can take the Fourier transform of the equations and define a scattering matrix which relates the output fields to the input fields
$$Z_{\text{out}}(\omega) = \textbf{S}(\omega)Z_{\text{in}}(\omega) \tag{2},$$
where
$$\textbf{S} = 1 + \textbf{L}^T(i\omega+\textbf{M})^{-1}\textbf{L} \tag{3}.$$
## Measurements
IOpy implements two different methods to characterize a linear system. They mimic closely the different types of measurements performed in the laboratory. First is the linear response of the system, which is similar to output of a vector network analyser (VNA). And, second is the spectrum of the output field, which is the same as the output of the spectrum analyser.
### Linear Response
According to the [Equation (2)](http://127.0.0.1:8000/theory/#input-output-formalism), a quadrature pair of any output port $i$ can be related to the quadrature pair of any input port $j$ using a submatrix of the scattering matrix
$$\begin{pmatrix}X_{\text{out},i} \\ Y_{\text{out},i}\end{pmatrix} = \textbf{S}^{(ij)} \begin{pmatrix}X_{\text{in},j} \\ Y_{\text{in},j}\end{pmatrix}.$$
Then the output field operator can be written as
$$a_{\text{out},i} = \frac{X_{\text{out},i} + iY_{\text{out},i}}{\sqrt2} = (\textbf{S}^{(ij)}_{11} + i\textbf{S}^{(ij)}_{21})\frac{X_{\text{in},j}}{\sqrt2} +
(\textbf{S}^{(ij)}_{22} - i\textbf{S}^{(ij)}_{12})\frac{iY_{\text{in},j}}{\sqrt2}.$$
In many cases the input field is a coherent drive with constant amplitude and $X_{\text{in},j}$ and $Y_{\text{in},j}$ are cosine part and sine part of it. Therefore, choosing any arbitrary values for the quadratures, as long as they satisfy the identity $X_{\text{in},j}^2+Y_{\text{in},j}^2=1$, will only impose a total phase shift to the response. By choosing $Y_{\text{in},j}$ to be zero, we consider this phase shift to be zero and $a_{\text{in},j}=X_{\text{in},j}/\sqrt2$. as a result, any phase response in the output is being calculated with respect to the input field.
$$a_{\text{out},i} = (\textbf{S}^{(ij)}_{11} + i\textbf{S}^{(ij)}_{21})a_{\text{in},j}$$
or in a more familiar notation
$$\chi^{(ij)}(\omega) = \textbf{S}^{(ij)}_{11} + i\textbf{S}^{(ij)}_{21} \tag{4}.$$
### Spectra
In general for analyzing the spectrum of some measured signals, we can define a correlator using a measurement matrix $Q_{ij}$
$$Q(\tau) = \langle Q_{ij}Z_{\text{out},i}(0)Z_{\text{out},j}(\tau)\rangle,$$
where we have used the Einstein notation for the summations. The Fourier transform of this correlator would be the spectral density or spectrum
$$S_{QQ}[\omega] = \int_{-\infty}^{\infty} Q(\tau) e^{i\omega\tau}d\tau.$$
Due to the linearity of the expectation value and the integral, the spectrum can be rewritten in the following way
$$ S_{QQ}[\omega] = \frac{1}{2\pi} Q_{ij}\int_{-\infty}^{\infty} \langle Z_{\text{out},i}(\omega_1)Z_{\text{out},j}(\omega) \rangle d\omega_1.$$
According to [Equation (2)](http://127.0.0.1:8000/theory/#input-output-formalism), we can write the output signals in terms of input signals
$$Z_{\text{out},i}(\omega) = S_{ik}(\omega)Z_{\text{in},k}(\omega),$$
$$S_{QQ}[\omega] = \frac{1}{2\pi} Q_{ij}\int_{-\infty}^{\infty}S_{ik}(\omega_1)S_{jl}(\omega) \langle Z_{\text{in},k}(\omega_1)Z_{\text{in},l}(\omega) \rangle d\omega_1 \tag{5}.$$
In general, the input signals can be correlated with each other and have complicated statistical behaviors. In many situations (such as thermal input noises) it's a good approximation to consider different sources to be uncorrelated. More precisely
$$\langle Z_{\text{in},k}(\omega_1)Z_{\text{in},l}(\omega) \rangle = 2\pi\delta_{kl}\mathcal{S}_k^{\text{in}}(\omega)\delta(\omega_1+\omega),$$
where $\mathcal{S}_k^{\text{in}}(\omega)$ is the spectral density of the $k^\text{th}$ input signal. Now, we can simplify Equation (5) to
$$S_{QQ}[\omega] = Q_{ij}S_{ik}(-\omega)S_{jk}(\omega)\mathcal{S}_k^{\text{in}}(\omega). $$
This final result is used in the calculations of IOpy. Here we make a remark on the summations by rearranging the terms in the following way
$$S_{QQ}[\omega] = \sum_k \mathcal{S}_k^{\text{in}}(\omega) (\sum_{i,j} Q_{ij}S_{ik}(-\omega)S_{jk}(\omega)) = \sum_k c_k(\omega)\mathcal{S}_k^{\text{in}}(\omega).$$
This illustrates that the spectrum can be expressed as a sum of the different input noise contributions.
# Library
In this section the different classes and functions of IOpy are introduced. IOpy consists of 4 main scripts `elements`, `measurement`, `DCnonlinearaity` and `plots`.
## elements
Objects and functions in this script are used to define the oscillating modes, input-output ports, couplings between different modes and finally the whole system of coupled oscillators.
##### Class `Mode`
This class represents the harmonic oscillators modes.
```python
'''
Attributes:
name: name of the mode.
omega: resonance frequency of the mode in rad/sec.
kappa: mode total dissipation rate in rad/sec.
omega_rot: frequency at which the mode frame is
rotating in rad/sec.
driven: flag indicates whether the mode is driven or not.
Properties:
omega_d():
returns the frequency of the field which is driving
the mode in rad/sec.
'''
```
##### Class `Input`
This class represents the input field coupled to a `Mode`. Inputs can be coherent drives (pumps) or thermal baths where the only difference between them is the rotating frame.
```python
'''
Attributes:
name: name of the input field.
mode: the mode which the input is coupled to.
kind: flag which indicates the input is a pump or a thermal
bath. 'drive' for a pump and 'bath' for a thermal bath.
kappa: coupling rate to the mode in rad/sec.
omega_drive: frequency of the pump fields in rad/sec.
bath_temp: temperature of the bath or the pump in Kelvins.
nbar: average number of thermal photons in the input field.
'''
```
`nbar` is calculated using the formula
$$\bar n =\frac{1}{e^{\frac{\hbar\omega}{kT}}-1}.$$
Methods:
```python
'''
spectrum(self, omegas):
spectrum of the input field. Here we approximately take
the thermal spectrum to be constant near the mode frequency.
Args:
omegas: the frequencies vector at which we want to
calculate the spectrum.
Returns:
spectrum of the input field in units of number
of photons.
'''
```
Currently for the input noise spectrum we consider the simplest case that it is a thermal spectrum. In future a feature will be added that allows for user defined spectra. This would make it possible to account for the classical noises of the lasers (phase noise and amplitude noise).
##### Class `Coupling`
This class represents the couplings between two `Mode`s using the coupling vector. The coupling vector $V_g$ is a 4-dimensional vector which is defined in a way that the interaction Hamiltonian for two coupled modes would be
$$H_{\text{int}} = 2\hbar(V_{g,1}X_1X_2 + V_{g,1}X_1Y_2 + V_{g,1}Y_1X_2 + V_{g,1}Y_1Y_2).$$
For optomechanics the couling vector is
$$V_g = (g, 0, 0, 0).$$
```python
'''
Attributes:
mode1: first mode.
mode2: second mode.
vg: coupling vector. a 4-d real vector.
'''
```
Methods:
```python
'''
contains_mode(self, mode):
indicates if the mode is involved in this coupling or not.
Args:
mode: the mode we want to look for.
Returns:
'True' if the mode is involved and 'False' for otherwise.
'''
```
##### Class `System`
Defines the complex system made of coupled `Mode`s and `Input`s. Its most important purpose is to calculate the scattering matrix.
```python
'''
Attributes:
modes: an array of modes in the system.
inputs: an array of inputs of the system.
couplings: couplings between the modes of the system.
M: the M matrix in the relation dZ/dt = M*Z + L*Z_in.
L: the L matrix in the relation dZ/dt = M*Z + L*Z_in.
'''
```
Refer to [Equation (1)](http://127.0.0.1:8000/theory/#input-output-formalism) on the Theory page for more information on $M$ and $L$ matrices.
Methods:
```python
'''
add_mode(self, mode):
Adding a mode to the system.
Args:
mode: the mode we want to add.
'''
```
```python
'''
add_input(self, inp):
Adding an input to the system.
Args:
inp: the input we want to add.
'''
```
```python
'''
add_coupling(self, coup):
Adding a coupling to the system.
Args:
coup: the coupling we want to add.
'''
```
```python
'''
make_ML(self):
Constructing M and L matrices of the system.
'''
```
```python
'''
SMatrix(self, omegas):
Constructs the scattering matrix of the system for a
frequency range.
Args:
omegas: frequencies vector in rad/sec.
Returns:
Ss: the scattering matrix.
'''
```
Refer to [Equation (3)](http://127.0.0.1:8000/theory/#input-output-formalism) on Theory page for more information about scattering matrix.
##### Class `Output`
This class represents the output field of the system with respect to an input field (in terms of input-output formalism).
```python
'''
Attributes:
system: the complex system of coupled modes and inputs.
input: the input field which we want to define its
output field (in terms of input-output formalism).
mode: the mode which these input and output fields are coupled.
'''
```
## measurement
Objects and functions in this script are used to perfom measurements on the output fields. The possible measurement schemes are linear response and spectrum. For more information on the definitions see Paragraph [measurements](http://127.0.0.1:8000/theory/#measurements) on the theory Page.
##### Class `MeasurementOperator`
This class represents a general measurement with a measurement matrix for defining a correlator
$$Q(\tau) = \langle Q_{ij}Z_{\text{out},i}(0)Z_{\text{out},j}(\tau)\rangle,$$
where $Q_{ij}$ is the $ij^{th}$ element of the measurement matrix.
Refer to the Paragraph [spectra](http://127.0.0.1:8000/theory/#spectra) of the theory Page for more information on the measurement matrix.
```python
'''
Attributes:
Q: the measurement matrix.
system: the system which the output field is coming from.
omega_d: the driving frequency of the mode which the
output field is coming from.
'''
```
##### Class `PowerMeasurement`
This class represents a power measurement scheme object. The correlator function and measurement matrix in this scheme are
$$ Q(\tau) = \langle X(0)X(\tau) + iX(0)Y(\tau) - iY(0)X(\tau) + Y(0)Y(\tau) \rangle ,$$
$$ [Q] = \begin{pmatrix} 1 &i \\ -i &1 \end{pmatrix}. $$
```python
'''
Attributes:
system: the system which the output field is coming from.
omega_d: the driving frequency of the mode which the
output field is coming from.
Q: the measurement matrix.
'''
```
##### Class `HomodynMeasurement`
This class represents a Homodyn measurement scheme object with a homodyning angle.
The correlator function and measurement matrix in this scheme are
$$
Q(\tau) = \langle \cos^2(\theta) X(0)X(\tau) + \sin(\theta)\cos(\theta) X(0)Y(\tau)
$$$$\quad\quad\quad + \sin(\theta)\cos(\theta) Y(0)X(\tau) + \sin^2(\theta) Y(0)Y(\tau) \rangle,
$$
$$ [Q] = \begin{pmatrix} \cos^2(\theta) &\sin(\theta)\cos(\theta) \\ \sin(\theta)\cos(\theta) &\sin^2(\theta) \end{pmatrix}. $$
```python
'''
Attributes:
system: the system which the output field is coming from.
omega_d: the driving frequency of the mode which the
output field is coming from.
Q: the measurement matrix.
'''
```
##### Function `linear_response`
This function calculates linear response (susceptibility) of the system from one specific input port to an output port in frequency domain
$$ a_{\text{out}} = \chi a_{\text{in}} .$$
Refer to [Equation (4)](http://127.0.0.1:8000/theory/#measurements) of linear response Paragraph on the theory Page for more information on linear response.
```python
'''
Args:
Omegas: the frequencies vector we want to calculate
the linear response for them, in frame of the
input field (not a rotating frame)
system: the system which we want to measure its response.
output: the output port.
Input: the input port.
plot: flag, indicates to plot the susceptibilities or not.
Returns:
omegas_out: the frequencies vector we want to calculate
the linear response for them, in frame of the
output field (not a rotating frame)
chi: the susceptibility we want to measure.
'''
```
##### Function `spectrum`
The spectrum of an output field. Refer to [spectra](http://127.0.0.1:8000/theory/#spectra) Paragraph on the theory Page for more information on the spectra.
```python
'''
Args:
omegas: the frequencies vector we want to calculate the
spectrum for them, in frame of the output field
(not a rotating frame)
measurement: the measurement scheme, of kinds PowerMeasurement
or HomodynMeasurement or another general measurement.
components: flag, indicates to calcuate different contributions
of noise sources or just calculate the whole spectrum.
plot: flag, indicates to plot the spectra or not.
Returns:
spec: the spectrum of the output field in case of components = False.
A list of spectra from different contributions in case of
components = True. The nth element of the list contains the
comulative sum of first n contributions.
'''
```
## DCnonlinearities
Functions in this script are used to calculate the DC shifts resulting from nonlinear effects.
##### Function `Kerr_effect_nbar`
This function finds the steady state average photon number in an optical cavity with kerr type nonlinearity. It findes the smallest root of a third order polynomial equation:
$$ [\frac{- \kappa_{\text{ex}}P_{\text{in}}}{\hbar\omega_{\text{drive}}}]\bar n^3 +
(\Delta^2 + (\frac{\kappa}{2})^2)\bar n^2 +
(2K\Delta) \bar n +
(K^2) = 0$$
```python
'''
Args:
P_in: input power in Watts.
kappa_0: cavity intrinsic dissipation rate in rad/sec.
kappa_ex: input coupling rate in rad/sec.
omega_c: cavity resonance frequency in rad/sec.
omega_drive: frequency of the input field in rad/sec.
K: nonlinearity coefficient in rad/sec.
returns:
smallest real root of the third order polynomial equation.
'''
```
##### Function `optomechanics`
This function finds the steady state average photon number in an optomechanical cavity and also finds the DC shift cavity
resonance frequency. It uses the `Kerr_effect_nbar()` function to solve the third order equation
$$\bar n [ \frac{\kappa^2}{4} + (\Delta - (\frac{2g_0^2}{\Omega_m})\bar n)^2 ] = \kappa_{\text{ext}} \frac{P_{\text{in}}}{\hbar\omega_{\text{drive}}}.$$
```python
'''
Args:
P_in: input power in Watts.
kappa_0: cavity intrinsic dissipation rate in rad/sec.
kappa_ex: input coupling rate in rad/sec.
omega_c: cavity resonance frequency in rad/sec.
omega_drive: frequency of the input field in rad/sec.
omega_m: resonance frequency of the mechanical oscillator in rad/sec.
g_0: vacuum optomechanical coupling rate in rad/sec.
returns:
omega_c: modified cavity resonance frequency in rad/sec.
g: optomechanical coupling rate in rad/sec.
'''
```
## plots
Functions in this script can be used for plotting the linear responses and spectra.
##### Function `plot_linear_response`
This function is used for plotting the linear response functions. It plots the absolute value and phase of the linear response as well as the linear response as a trajectory in the complex plane.
```python
'''
Args:
omegas: the vector containing the frequencies
in rad/sec (not in a rotating frame).
chi: the linear response function.
system: the system which the linear response is from.
output: the output field we that the linear response
is calculated for.
input: the input field we that the linear response
is calculated for.
'''
```
##### Function `plot_spectrum`
This function is used for plotting the spectra.
```python
'''
Args:
omegas: the vector containing the frequencies
in rad/sec (not in a rotating frame).
spec: the spectrum.
componenets: flag, indicates to plot different contributions
of noise sources in the spectrum or just
plot the whole spectrum.
system: the system which the spectrum is from.
'''
```
# Examples
In this section a set of famous phenomena in optomechanics is presented. These calculations serve first as examples of using IOpy in simulating Langevin equations, and second are benchmarks of IOpy by comparing it to known theoretical models.
## Simple Cavity
{width=260 .center}
<!--
<p align="center">
<img width="260" src="\LC.png">
<p align = "center">
Inverted-colour optical micrograph of the circuit consisting of two coupled LC resonators, one having a mechanically com- pliant capacitor (Toth et. al. 2017).
</p>
</p>
-->
in the first example we illustrate how to simulate a hot microwave resonator. Here the temperature of the bath is higher than the temperature of the drive and therefore we expect to see an emission shaped like a Lorentzian. <!--To see the fool written example, go to [Simple cavity example](http://localhost:8888/notebooks/IOpy/iopy/examples/Simple%20Cavity.ipynb).-->
Let's start by defining the cavity mode
```python
omega_c = 5e9*np.pi*2
a = Mode('a', omega_c)
```
Then we have to define input fields. In this example the cavity is driven by a coherent drive and it is coupled to a thermal bath.
```python
kappa_ex = 0.2e6*np.pi*2
kappa_0 = 0.3e6*np.pi*2
kappa = kappa_ex + kappa_0
T_drive = 2e-5
T_bath = 10e-3
a_inex = Input('ex', a, kappa_ex, kind = 'drive',
omega_drive = omega_c, bath_temp=T_drive)
a_in0 = Input('0', a, kappa_0, kind = 'bath', bath_temp=T_bath)
```
And finally we define the system object and the output field.
```python
sys_cav = System([a], [a_in0, a_inex], [])
```
```python
a_outex = Output(sys_cav, a_inex)
```
Now for measuring the spectrum of the output field, we have to use the `spectrum` function.
```python
omegas = np.linspace(omega_c - 15*kappa, omega_c + 15*kappa, 1001)
spec = me.spectrum(omegas, me.PowerMeasurement(a_outex),
components = False, plot = True)
```
{width=460 .center}
\begin{figure}[!h]
\caption{Simple cavity output spectrum}
\end{figure}
<!--
<p align="center">
<img width="460" src="\Simple Cavity\simple_cavity_spectrum.png">
<p align = "center">
Simple cavity output spectrum
</p>
</p>
-->
As we expect, we can see a Lorentzian in the spectrum. If the temperature of the driving field was higher than the thermal bath, we would see a deep instead of a peak.
The linear response of the system to driving can also be measured with the `linear_response` function
```python
omegas_newex, S_ex = me.linear_response(omegas, sys_cav, a_outex,
a_inex, plot = 1)
```
{width=460 .center}
\begin{figure}[!h]
\caption{Cavity linear response in complex space}
\end{figure}
{width=460 .center}
\begin{figure}[!h]
\caption{Cavity linear response amplitude}
\end{figure}
{width=460 .center}
\begin{figure}[!h]
\caption{Cavity linear response phase}
\end{figure}
<!--
<p align="center">
<img width="460" src="\Simple Cavity\linear_response_comp.png">
<p align = "center">
Cavity linear response in complex space
</p>
</p>
<p align="center">
<img width="460" src="\Simple Cavity\linear_response_amp.png">
<p align = "center">
Cavity linear response amplitude
</p>
</p>
<p align="center">
<img width="460" src="\Simple Cavity\linear_response_phase.png">
<p align = "center">
Cavity linear response phase
</p>
</p>
-->
The results can also be compared to the theory. For example in this case the linear response of the system to the drive field is
$$ S_{aa} = 1 - \frac{\kappa_{ex}}{\frac{\kappa}{2} - i(\omega-\omega_c)}.$$
The graphs below show the comparison between this equation and IOpy results.
{width=460 .center}
\begin{figure}[!h]
\caption{Cvity linear response amplitude calculated by theory (dashed) and IOpy (blue)}
\end{figure}
{width=460 .center}
\begin{figure}[!h]
\caption{Cvity linear response phase calculated by theory (dashed) and IOpy (blue)}
\end{figure}
<!--
<p align="center">
<img width="460" src="\Simple Cavity\comparison_amp.png">
<p align = "center">
Cavity linear response amplitude
</p>
</p>
<p align="center">
<img width="460" src="\Simple Cavity\comparison_phase.png">
<p align = "center">
Cavity linear response phase
</p>
</p>
-->
## Basic Optomechanics and Cooling
{width=260 .center}
<!--
<p align="center">
<img width="260" src="\ExamplesImg\drum.png">
<p align = "center">
False-colour scanning electron micrograph of the mechanically compliant drum capacitor (Toth et. al. 2017).
</p>
</p>
-->
In this example we simulate an optomechanical system with a weak drive. Here we want to see the optomechanical cooling due to the increase in optomechanical damping rate. <!--To see the fool written example, go to [Basic optomechanics](http://localhost:8888/notebooks/IOpy/iopy/examples/Basic%20Optomechanics.ipynb).-->
In the basic optomechanical interaction, the cavity resonance frequency shifts by a constant value due to the DC nonlinearity. Therefore, before defining the modes we have to calculate this DC shift.
```python
omega_c = 5e9*np.pi*2 # cavity resonance frequency
kappa_0 = 0.3e6*np.pi*2
kappa_ex = 0.4e6*np.pi*2
kappa = kappa_0 + kappa_ex
omega_m = 5e6*np.pi*2 # mechanical resonance frequency
gamma_m = 100*np.pi*2
P_in = 5e-12
g_0 = 200*np.pi*2
omega_drive = omega_c - 1* omega_m
from DCnonlinearities import optomechanics
omdir = optomechanics(P_in, kappa_0, kappa_ex, omega_c,
omega_drive, omega_m, g_0)
g= omdir['g'] # optomechanical coupling rate = sqrt(nbar)*g_0
omega_c = omdir['omega_c'] # new cavity resonance frequency
```
Now we can define the modes, as well as input fields including thermal baths coupled to optics and mechanics and the optical driving field.
```python
a = Mode('a', omega_c)
b = Mode('b', omega_m)
a_inex = Input('ex', a, kappa_ex, kind = 'drive',
omega_drive = omega_drive, bath_temp=10e-3)
a_in0 = Input('0', a, kappa_0, kind = 'bath', bath_temp=10e-3)
b_in0 = Input('0', b, gamma_m, kind = 'bath', bath_temp=10e-3)
```
Then we should define the coupling between the optical and mechanical modes:
```python
g_ab = Coupling(a, b, g * np.array([1,0,0,0]))
```
And finally we define the whole optomechanical system:
```python
sys_om = System([a, b], [a_in0,b_in0 , a_inex], [g_ab])
```
Now just like the previous example we can measure the spectrum of the output field.
{width=460 .center}
\begin{figure}[!h]
\caption{Optomechanical cavity output spectrum}
\end{figure}
<!--
<p align="center">
<img width="460" src="\Basic OM\spec.png">
<p align = "center">
Optomechanical cavity output spectrum
</p>
</p>
-->
The peak that can be seen is because of low sampling rate of the calculations. To have a better precision we zoom on the neighborhood of the cavity resonance frequency.
{width=460 .center}
\begin{figure}[!h]
\caption{Optomechanical cavity output spectrum}
\end{figure}
<!--
<p align="center">
<img width="460" src="\Basic OM\spec_zoom.png">
<p align = "center">
Optomechanical cavity output spectrum
</p>
</p>
-->
Here we can clearly see different contributions to the spectrum. In addition the width of the spectrum is equal to the theory value $\Gamma_{\text{eff}} = \Gamma_m (1 + C)$ (with $C$ as the cooperativity equal to $\frac{4g^2}{\kappa\Gamma_m}$) which results in cooling.
## Strong Coupling Regime
{width=260 .center}
<!--
<p align="center">
<img width="260" src="\ExamplesImg\Strong.png">
<p align = "center">
Mechanical frequency spectrum (frequency on vertical axis) as a function of laser detuning, for a strongly coupled optomechanical system. (Aspelmeyer, Kippenberg, Marquardt 2014)
</p>
</p>
-->
In this example we show the effect of increasing of the laser input power ($P_{\text{in}}$). For the details on the theory see [(Aspelmeyer, Kippenberg, Marquardt (2014))](https://journals.aps.org/rmp/abstract/10.1103/RevModPhys.86.1391), Section VII.C. By increasing the input power, at the beginning we can observe an improvement in the cooling, but as we continue increasing the power, the optical and mechanical modes hybridize to form two new modes with the eigenfrequencies
$$ \omega_{\pm} = \frac{\Omega_m-\Delta}{2} \pm \sqrt{g^2 + (\frac{\Omega_m+\Delta}{2})^2}.$$
When the driving laser is exactly detuned on the red sideband ($\Delta=-\Omega_m$) the splitting of these two modes is equal to $2g$. In this example we want to show this splitting on the spectrum.
To simulate this phenomenon, the code is exactly the same as the previous example but with a different input power.<!-- To see the full code go to [Strong coupling regime](http://localhost:8888/notebooks/IOpy/iopy/examples/Strong%20Coupling%20Regime.ipynb). -->
```python
P_in = 5e-9
```
By measuring the output filed spectrum we can clearly see this mode splitting.
{width=460 .center}
\begin{figure}[!h]
\caption{Optomechanical cavity output spectrum. One can see both red and blue sidebands of the pump.}
\end{figure}
<!--
<p align="center">
<img width="460" src="\Strong coupling\spec0.png">
<p align = "center">
Optomechanical cavity output spectrum. One can see both red and blue sidebands of the pump.
</p>
</p>
-->
To see better the splitting we change the measurement frequencies.
{width=460 .center}
\begin{figure}[!h]
\caption{Optomechanical cavity output spectrum}
\end{figure}
<!--
<p align="center">
<img width="460" src="\Strong coupling\spec.png">
<p align = "center">
Optomechanical cavity output spectrum
</p>
</p>
-->
## Optomechanically Induced Transparency
{width=260 .center}
<!--
<p align="center">
<img width="260" src="\ExamplesImg\omit.png">
<p align = "center">
Transmission of the probe laser power through the optomechanical system in the case of a critically coupled cavity k0 = kex as a function of normalized probe laser frequency offset, when the control field is off (blue lines) and on (green lines) (Weis et al., 2010).
</p>
</p>
-->
This example is about the optomechanically induced transparency effect also known as OMIT. This effect was observed in atoms (electromagnetically induced transparency [Fleischhauer, Imamoglu, and Marangos, 2005](https://journals.aps.org/rmp/abstract/10.1103/RevModPhys.77.633)) as the cancellation of absorption in the presence of an auxiliary laser field. OMIT was predicted theoretically by Schliesser, 2009 and [Agarwal and Huang 2010](https://journals.aps.org/pra/abstract/10.1103/PhysRevA.81.041803). When the optical cavity is pumped on the red sideband and we inject a weak probe field into the cavity, the optomechanical interaction causes the cavity to be seen transparent by this weak field.
To simulate this phenomenan in IOpy, the setup is again similar to the basic optomechanics example. The difference here is that we set the driving field (control field, in this context) to be a high temperature source. In this way, the noise around this control field play the role of the weak probe field for us, so we can see the OMIT effect in the spectrum, as well as the linear response. <!--To see the full code go to [OMIT](http://localhost:8888/notebooks/IOpy/iopy/examples/OMIT.ipynb) example.-->
```python
T_cont = 1
T_bath = 10e-3
a_cont = Input('ex', a, kappa_ex, kind = 'drive',
omega_drive = omega_cont, bath_temp = T_cont)
a_in0 = Input('0', a, kappa_0, kind = 'bath', bath_temp = T_bath)
b_in0 = Input('0', b, gamma_m, kind = 'bath', bath_temp = T_bath)
```
And now we measure the spectrum and the linear response.
{width=460 .center}
\begin{figure}[!h]
\caption{Optomechanical cavity output spectrum}
\end{figure}
{width=460 .center}
\begin{figure}[!h]
\caption{Optomechanical cavity linear response amplitude}
\end{figure}
{width=460 .center}
\begin{figure}[!h]
\caption{Optomechanical cavity linear response phase}
\end{figure}
<!--
<p align="center">
<img width="460" src="\omit\spec.png">
<p align = "center">
Optomechanical cavity output spectrum
</p>
</p>
<p align="center">
<img width="460" src="\omit\LR_amp.png">
<p align = "center">
Optomechanical cavity linear response amplitude
</p>
</p>
<p align="center">
<img width="460" src="\omit\LR_phase.png">
<p align = "center">
Optomechanical cavity linear response phase
</p>
</p>
-->
These results can also be compared to theory. To see the details go to [OMIT Test](http://localhost:8888/notebooks/IOpy/iopy/Tests/OMIT%20Test.ipynb) notebook. We can show for the transmission window
$$T = 1 - \kappa_{\text{ext}}\frac{\chi_{\text{opt}}(\Omega)}{1 + g^2\chi_{\text{mech}}(\Omega)\chi_{\text{opt}}(\Omega)},$$
where
$$
\chi_{\text{opt}}(\Omega) = [-i(\Omega+\Delta)+\kappa/2]^{-1},\\
\chi_{\text{mech}}(\Omega) = [-i(\Omega-\Omega_m)+\Gamma_m/2]^{-1},
$$
with
$$\Delta = \omega_{\text{cont}} - \omega_{\text{cav}},\quad \Omega = \omega_p - \omega_{\text{cont}}.$$
And the linear response from IOpy can be compared with this results as shown in figures bellow.
{width=460 .center}
\begin{figure}[!h]
\caption{Optomechanical cavity linear response amplitude}
\end{figure}
{width=460 .center}
\begin{figure}[!h]
\caption{Optomechanical cavity linear response phase}
\end{figure}
<!--
<p align="center">
<img width="460" src="\omit\test_amp.png">
<p align = "center">
Optomechanical cavity linear response amplitude
</p>
</p>
<p align="center">
<img width="460" src="\omit\test_phase.png">
<p align = "center">
Optomechanical cavity linear response phase
</p>
</p>
-->
## Frequency Conversion Using OMIT
{width=260 .center}