Open stefangri opened 3 years ago
It is possible to define circular polarization of some of the pulses. There is currently no "elegant" way of doing this. You have to directly modify the attribute "polarization_sequence". If, for example, you initialize with dm = ufss.UF2.DensityMatrices(file_path) (or similar for RKE or closed systems counterparts)
you can then set the polarization to left or right-handed by doing this: dm.polarization_sequence = [np.array([1,1j,0]),np.array([1,-1j,0]),...]
as an example. This is the way you set any generic polarization. Note that the method "set_polarization_sequence" currently only works to set 'x', 'y' or 'z' linearly polarized light. I will make a note to update this method to allow 'r' and 'l' as valid entries. I'll let you know when I have done that.
I have done only some very basic testing on circular polarizations. Please let me know if you encounter any problems, and I will be happy to help sort them out!
In addition I should note that I have currently only implemented isotropic averaging to work for light that is linearly polarized in the 'x', 'y' and/or 'z' directions. Please let me know if you would like to be able to use isotropic averaging with circularly polarized light.
I have just pushed changes to the repository to address this issue. I have updated the set_polarization_sequence method to allow setting right and left circularly polarized light using set_polarization_sequence(['r','r','l','l']) (you can use any combination of 'x', 'y', 'z', 'r' and 'l' now).
MORE IMPORTANTLY I found and fixed a bug that relates to the complex polarization vectors (this bug did not impact linear polarization in any way!). Please use the most recent version of ufss straight from github for circular polarization calculations (do not use old github versions or pip install ufss; I have not yet updated the pypi release). The old version of ufss did not take the complex conjugate of the polarization vector when working with the counter-rotating terms.
Please let me know if this update works for you. I will just reiterate that I haven't done in-depth testing of UFSS with complex polarization vectors. I believe that I have implemented this correctly, and have done some surface-level testing. However, if you have a simple reference calculation to compare against using UFSS with circularly polarized light, I would definitely recommend running a comparison. Let me know if you need help with the comparison (for example inputting a simple Hamiltonian to match your test-case). And if you do a comparison, please post the results (positive or negative).
Thanks for the quick answer and expansion for circular polarizations! I have a simple example that I would like to use your software for. I couldn’t figure out yet how to put everything in correctly and would be happy if you could help me. This example could be a good test for the software since I can compare the result to my simulations that assume delta-like pulses.
I would like to simulate the temporal behaviour of the photon echo arising from an inhomogenously broadened ensemble of V-type excitons as shown schematically in the figure below (I don’t know how to define dipole selection rules for the two excitation branches). There is also a figure of the typical pulse sequence of a photon-echo experiment. I would like to set arbitrary polarizations for the first and second pulse, for example ‘r’ for the first and ‘x’ for the second. The final signal should be given by the cross-correlation between the photon-echo and an arbitrary polarized reference pulse. All pulses have Gaussian shape with same duration.
As a result of the simulation, I would like to receive a two-dimensional data-set of the detected signal as a function of two parameters: 1. the temporal delay between the first pulse and the second pulse and 2. the first pulse and the reference pulse.
When you get a chance, take a look at CircularlyPolarizedLight.ipynb, which I have just added to the repository. It doesn't quite produce the signal that you want, but I hope that it is a good step in the right direction. I believe that I have constructed the V-type Hamiltonian and the dipole operator with appropriate selection rules. I have produced the rephasing 2DPE signal (which is not quite what you are asking for) as a quick test case. With linear x-polarized light, both states are excited. However, as you can see, right-circularly polarized light excites only one state, while left-circularly polarized light excites only the other state. So far this has been done for a closed system, so I have just added a gaussian line-shape.
Does this look like it is moving in the right direction to you? If so, then I think the next step would be to get the correct spectroscopic signal. Let me know what you think of this so far!
Note that the gaussian line-shape I have added does not correctly show the inhomogeneous linewidth only along the diagonal of the spectra, but also includes the inhomogeneous linewidth along the anti-diagonal of the 2DPE plot. We can address this problem later, assuming the other aspects are working
Yes, this really looks like a step in the right direction! If I understand correctly, the signal I am interested in should be contained in the array full_sig_tau_T_t. I am not sure about the definitions of the three different times t, T, and tau in your example. In order to include inhomogenity somehow, I took the average over a random Gaussian distribution of energies (see file below, I am sure there is an easier and faster way to do this within the ufss package). The result already looks close to what I would expect. Just the time axes seem not to correspond to the delays I described in my last post.
So glad this is looking like it's going in a good direction! As for inhomogeneous broadening, that is probably the simplest (and perhaps best) way to include it in UFSS, but we can discuss other options going forward (what we do will probably depend upon wether or not you want to include open-systems effects like dephasing and relaxation).
In regards to the time-axes, I am actually a little confused as to what you want to simulate (I have only ever done transient absorption, transient grating, rephasing/non-rephasing 2DPE, and higher-order signals of this type). Are you requesting a 2-pulse photon echo? Is the green curve the local oscillator? Is the local oscillator always locked to be 2*tau? Does tau correspond to a coherence between ground and excited states, or is it a population time? Could you send me the phase-matching or phase-cycling conditions that describe this? And/or could you send me an example double-sided Feynman diagram (maybe for the stimulated emission), showing which pulse causes excitation of the ket and bra sides? Or instead of all of that, just a link to any paper describing this type of experiment. Nonlinear optical spectroscopies are a zoo, and I don't know about them all! :)
Yes, for the beginning, I am interested in two-pulse photon echo. The green curve shows the photon-echo signal with time-resolution. Below you can see a Feynman diagram of the process. In chapter II of the paper below, the experimental details are described compactly. In figure 1 the times I mentioned above are defined. I would like to simulate the signal as a function of tau_12 and tau_ref. Would be great if also dephasing and relaxation could be included!
Are the delays in your example defined as here:
?
Great, thanks! I think I understand now. So the key thing is that you want to do is change the phase-matching condition from [(0,1),(1,0),(1,0)] to [(0,1),(2,0)]. You would only put in 3 pulses (2 pulses that interact with the system, the third being a local oscillator). You would also just remove the "T" delay time altogether. I've updated the jupyter notebook (please pull the latest version of the code; I made a couple of very minor improvements to the interface, which don't break anything older, but which are necessary for the new version of the notebook to run) to do all of this, and hopefully explain things quite a bit more. Your diagram of delay times for rephasing 2DPE is exactly right! Your signal is probably roughly the same as the 2DPE with T = 0, but I'm not sure if they will be equivalent or not.
Are you ultimately interested only in the diagonal of the 2D plot where what I'm calling t = tau? If so we can speed up the calculation to avoid calculating unnecessary time points.
For adding relaxation and dephasing, I'll send you an update when I get a chance of how to include them in the Lindblad formalism. There's a Lindblad constructor in UFSS, but it probably isn't clear at all how to access it/use it, so I'll send an explanation of that. In the meantime let me know if the current version of
...the jupyter notebook is continuing to move in the direction you're aiming for!
Thank you! The updated version helps a lot for understanding. I agree, setting T = 0 with three pulses gave the same result. It would be useful to have the option to calculate only the diagonal line t = tau, there are cases when this is enough. Do you think there could be a faster/more elegant way to include inhomogenity without looping over a big number of eigenenergies?
No problem! Okay, I've added the ability to calculate only the diagonal line t = tau. It is faster/more elegant, though I haven't had a chance to really explain what's going on yet, sorry... It strikes me that this is the best place to focus for now, because this line is not affected by inhomogeneous broadening (at least qualitatively) if I understand correctly. Do you agree? I will be including homogenous lineshapes within the next day or so (almost done).
Regarding inhomogeneous broadening, I do believe that we can do much better at including this effect, but it is not something that I have actually done before, so this will take a little bit longer.
By the way, please pull the newest version of ufss before looking at the updated jupyter notebook
I agree, inhomogenity doesn't affect the line t = tau. Great to have the option to calculate it exclusively!
I've just added a jupyter notebook, CircularlyPolarizedLight-OpenSystems.ipynb, which shows how to include both relaxation (and incoherent excitation at non-zero temperature) effects, as well as pure dephasing terms. UFSS works with open systems using either Lindblad or Redfield theory. Because your system has no off-diagonal terms in the Hamiltonian, I believe these theories are actually equivalent (which of course is in general not the case!).
I've also added two .py scripts to the repo, "CircularlyPolarizedLight_inhomogeneous_trapezoidal.py" and "CircularlyPolarizedLight_inhomogeneous_random_sampling.py", the latter of which is a slightly tweaked version of what you shared in this issue. If you run them both (the second takes a few minutes) you can see that using the trapezoidal rule to compute the convolution integral required for inhomogeneous broadening is much more efficient than using the random sampling method. The trapezoidal rule requires 17 separate runs to converge to within 1% of the correct answer, whereas random sampling requires over 900 separate runs to achieve 1% convergence. The key thing to note is that the trapezoidal rule will create artifacts if your mesh spacing for energy gaps is too large. So if you look at line 30 of _trapezoidal.py, you'll see I am using a de value of 0.05. This de needs to be about the same size as 2pi/tau_max. You can try running the script with a de of 0.1 and 0.2, to see what happens. Essentially we are taking advantage of the fact that we only need to resolve the 2 pulse echo signal on a grid, we don't need to sample the full, continuous signal.
I'm afraid I haven't explained/commented nearly as much as I would like, so please ask lots of questions!!!
Great update! The software seems to be capable to simulate almost everything I need. I have indeed a few questions:
Thank you!
Glad to hear it!
I just discovered that I forgot to commit one of the changes I made to manual_L_input.py. This may have caused some problems with the open systems calculations in CircularlyPolarizedLight-OpenSystems.ipynb. I am sorry, I hope that this hasn't caused problems for you. I am also wondering if you have further questions/issues so far? Were you able to compare successfully to your own impulsive calculations?
In addition, I wanted to mention that although the trapezoidal rule is much more efficient for inhomogeneous broadening over a single parameter, it can be much less efficient for broadening over many different parameters. Apparently the cross-over is usually around 4 dimensions. So if you want to do inhomogeneous broadening over 3 or fewer parameters, trapezoidal rule is great. If you want to broaden over 4 or more, Monte Carlo sampling is generally expected to be better.
Thanks for the answers to my questions! Sorry for late reply, I finally found the time to have a look on the latest updates. Everything works fine for me, also ufss reproduces the results I obtained from my own calculations. I have a further question concerning non-diagonal Hamiltonians. In this case, can I just calculate eigenvectors/values while the rest of the procedure is the same?
No problem, glad to hear everything looks good! As for non-diagonal Hamiltonians, let's start with closed systems. In this case, most of the procedure remains the same. After calculating eigenvectors/values, you need to use the eigenvectors to transform mu so that mu is represented in the eigenbasis. I have updated CircularrlyPolarizedLight.ipynb to demonstrate this.
For open systems, the answer depends upon how you want to define the Liouvillian. As it currently stands, you could add off-diagonal elements to the Hamiltonian definition in CircularrlyPolarizedLight-OpenSystems.ipynb, and not change anything (you would NOT transform mu into the eigenbasis of the Hamiltonian in this case). You may notice that, although I found the eigenvalues of H in that notebook, I never used them (never saved them or anything else). The problem with this approach is that the Lindblad relaxation and dephasing rates will be defined on the diabatic states. UFSS will run, and you can get somewhat reasonable results. However, defining relaxation rates on diabatic states results in "incorrect" long-time behaviour: the relaxation process will not bring the system to a Boltzmann distribution of eigenstates, and therefore will violate detailed balance. If you would instead like to define Lindblad relaxation and dephasing rates on the eigenstates of the Hamiltonian, I will need to make several changes. Please let me know which approach you want to take!
The problems I would like to solve are formulated in terms of equation (3) of your paper "Efficient numerical method for predicting nonlinear optical spectroscopies of open systems". In general, I have H_0, which could be non-diagonal, and the matrix D. D has only time-independent entries. Is it currently possible to solve this problem using ufss?
Definitely! My long answer about open systems was based around the idea that you would be using UFSS to construct D. However, if you have already constructed D, things should be fairly straight-forward. What basis do you use to construct D? If rho is an NxN matrix, do you represent D as an NxNxNxN tensor, or as a N^2 x N^2 matrix?
Perfect! I am definitely not too much into the details of relaxation/dephasing. I would write D also as a NxN matrix. See for example this paper and supplement (D is called Gamma there): https://www.nature.com/articles/nphoton.2014.219.
Sounds good, I'll take a look and get back to you over the weekend
I took a look at the supplemental info for that paper, and am looking in particular at equation (9) that defines Gamma. Gamma is not a matrix, but rather an expression of the equations of motion that result by taking the tensor product D*rho. If you look at the upper left-hand entry, it reads (-rho_11 + rho_22)/2Tz + rho33/tau. People often describe D as being a 4-index object, because it acts on a density matrix, and produces a new density matrix. So drho{i,j}/dt = Sum{k,l} D{i,j,k,l} rho_{k,l}. UFSS works by flattening rho into a column vector, so as an example using a 2 level system, [[rho_11,rho_12],[rho_21,rho_22]] -> [rho_11,rho_12,rho_21,rho_22]. For the two-level system, D must similarly be flattened from a 2x2x2x2 tensor into a 4x4 matrix. Looking at your reference, you need to take eq. (9) and reconstruct the D that would create the equations of motion represented by Gamma. As a first step, the first row of D must be [-1/2Tz,0,0,0,0,1/2Tz,0,0,0,0,1/taur,0,0,0,0,0], since the dot product of this row with [rho_11,rho_12,rho_13,rho_14,rho_21,rho_22,rho_23,rho_24,rho_31,rho_32,rho_33,rho_34,rho_41,rho_42,rho_43,rho_44] gives the desired Gamma_11 entry. This is obviously tedious. They say they are using the Lindblad formalism. If you can find out what Lindblad operators they are using (perhaps the pauli matrices?) to construct Gamma, you can use UFSS to build D in a very straightforward fashion. If you can find a paper that shows the construction of D or Gamma using Lindblad formalism, I'll be able to show you how to use UFSS to make D easily (and that should open up the door to making much more general D's, for larger systems. Unpacking 4x4 equations of motion into a 16x16 D is totally doable, if annoying, but doing this for larger systems gets really frustrating!).
If you want to proceed by just making the D operator manually, upload a python script here that makes your Haniltonian and your D, and I'll reply showing you how to feed those two objects into UFSS.
Maybe as an example we can just take the Hamiltonian from the paper. I attached a python script where I typed in H and Gamma as 4x4 matrix. Then I wrote some code that constructs D as 4x4x4x4 matrix. I would be happy if you could show me how two move on with those objects. hamiltonian_lindblad_example.txt
Sorry for the delay! I have added a few import statements at the top, and some code at the bottom of the file you sent me. You should be able to run this script, and then run ufss using ufss.DensityMatrices(os.path.join(folder,'open/uf2')), just as we do in the jupyter notebooks we have worked on in the past, with folder = 'trion' (or whatever you choose to name it). In fact you should be able to use any of your previous scripts and notebooks that worked for the old 3LS and simply redirect them to the new folder location for the 4LS. Please let me know if this doesn't work extremely smoothly. Also please let me know if you have questions. It is my goal to create a class that will simply accept a Hamiltonian, a 4d tensor for D, and a dipole operator, and do all of this under the hood. I'll let you know when that happens. hamiltonian_lindblad_example_edited_prose.txt
Thanks, everything works fine for me! My previous scripts are completely compatible with this addition.
Is it yet possible to define polarizations of the light pulses. For example, in a system with linear eigenpolarizations, can I also define circular polarization of some of the pulses. Or some arbitrary linear polarization?