C++QEDElements  2.100.2 (v2 Milestone 10 Development branch)
a framework for simulating open quantum dynamics – generic elements
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Modules Pages
Mode_.h
Go to the documentation of this file.
1 // Copyright András Vukics 2006–2014. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.txt)
3 // -*- C++ -*-
4 #ifndef CPPQEDELEMENTS_FREES_MODE__H_INCLUDED
5 #define CPPQEDELEMENTS_FREES_MODE__H_INCLUDED
6 
7 #include "Mode_Fwd.h"
8 
9 #include "ParsMode.h" // for the user interface
10 
11 #include "QM_PictureFwd.h"
12 #include "StateVectorFwd.h"
13 
14 #include "ElementLiouvillean.h"
15 #include "ElementAveraged.h"
16 #include "Free.h"
17 #include "FreeExact.h"
18 #include "TridiagonalHamiltonian.h"
19 
20 #include <boost/shared_ptr.hpp>
21 
23 namespace mode {
24 
25 const std::string keyTitle="Mode";
26 
27 
28 using namespace structure::freesystem; using structure::NoTime;
29 
30 typedef boost::shared_ptr<const ModeBase> Ptr;
31 
32 const Tridiagonal aop(Ptr);
33 const Tridiagonal nop(Ptr);
34 
35 inline const Tridiagonal xop(Ptr mode) {return tridiagPlusHC(aop(mode))/sqrt(2.);}
36 // inline const Tridiagonal yop(mode::Ptr) {return ...}
37 
39 
41 
46 const StateVector coherent(const dcomp& alpha,
47  size_t cutoff
48  );
49 
50 const StateVector fock(size_t n, size_t dim, double phase=0);
51 
53 const StateVector init(const Pars&);
54 
55 
56 template<typename AveragingType, typename... AveragingConstructorParameters>
57 const Ptr make(const Pars &, QM_Picture, AveragingConstructorParameters&&... );
58 
59 template<typename AveragingType, typename... AveragingConstructorParameters>
60 const Ptr make(const ParsLossy &, QM_Picture, AveragingConstructorParameters&&... );
61 
62 template<typename AveragingType, typename... AveragingConstructorParameters>
63 const Ptr make(const ParsPumped &, QM_Picture, AveragingConstructorParameters&&... );
64 
65 template<typename AveragingType, typename... AveragingConstructorParameters>
66 const Ptr make(const ParsPumpedLossy&, QM_Picture, AveragingConstructorParameters&&... );
67 
68 
69 const Ptr make(const Pars &, QM_Picture);
70 const Ptr make(const ParsLossy &, QM_Picture);
71 const Ptr make(const ParsPumped &, QM_Picture);
72 const Ptr make(const ParsPumpedLossy&, QM_Picture);
73 
74 
75 double photonNumber(const StateVectorLow&);
76 // This can be implemented in an extremely elegant way using tensor notation from blitz++, but it is not enough, the one below is needed.
77 double photonNumber(const LazyDensityOperator&);
78 
79 
80 inline std::ostream& isFiniteTempStream(std::ostream& os, double , boost::mpl::false_)
81 {return os <<std::endl;}
82 inline std::ostream& isFiniteTempStream(std::ostream& os, double nTh, boost::mpl:: true_)
83 {return os<<" Finite temperature.\n# nTh="<<nTh<<std::endl;}
84 
85 
86 inline double finiteTemperatureHamiltonianDecay(const ParsLossy& p, boost::mpl::false_) {return p.kappa ;}
87 inline double finiteTemperatureHamiltonianDecay(const ParsLossy& p, boost::mpl:: true_) {return p.kappa*(2.*p.nTh+1);}
88 
89 
90 const Tridiagonal::Diagonal mainDiagonal(const dcomp& z, size_t dim);
91 
92 const Tridiagonal pumping(const dcomp& eta, size_t dim);
93 
94 
95 
96 class Exact : public structure::FreeExact<false>
97 {
98 public:
99  Exact(const dcomp& zI, size_t);
100 
101  const dcomp& get_zI() const {return zI_;}
102 
103 private:
104  void updateU(Time) const;
105 
106  bool applicableInMaster_v() const {return !bool(real(zI_));}
107 
108  const dcomp zI_;
109 
110 };
111 
112 
113 namespace details { struct EmptyBase {}; }
114 
115 template<bool IS_TIME_DEPENDENT>
117  : public quantumoperator::TridiagonalHamiltonian<1,IS_TIME_DEPENDENT>,
118  public mpl::if_c<IS_TIME_DEPENDENT,Exact,details::EmptyBase>::type
119 {
120 public:
122 
123  Hamiltonian(const dcomp& zSch, const dcomp& zI, const dcomp& eta, size_t, mpl::bool_<IS_TIME_DEPENDENT> =mpl:: true_()); // works for IS_TIME_DEPENDENT=true
124  Hamiltonian(const dcomp& zSch, const dcomp& eta, size_t, mpl::bool_<IS_TIME_DEPENDENT> =mpl::false_()); // works for IS_TIME_DEPENDENT=false
125  // The trailing dummy argument is there to cause a _compile_time_
126  // (and not merely linking time) error in case of misuse
127 
128 protected:
129  const dcomp& get_zSch() const {return zSch_;}
130  const dcomp& get_zI () const {return Exact::get_zI();}
131 
132  const dcomp& get_eta() const {return eta_;}
133 
134 private:
135  const dcomp zSch_,
136  // z_=kappa_-I*delta_ --- zSch_ is the part appearing in the
137  // tridiagonal hamiltonian, zI_ is appearing in the frequencies.
138  eta_;
139  const size_t dim_;
140 
141 };
142 
143 
144 
145 template<bool TEMPERATURE, bool IS_ALTERNATIVE=false> class Liouvillean;
146 
147 
148 namespace details {
149 
150 void aJump (StateVectorLow&, double);
151 void aDagJump(StateVectorLow&, double);
152 
153 } // details
154 
155 
156 template<bool IS_ALTERNATIVE>
157 class Liouvillean<false,IS_ALTERNATIVE>
158  : protected boost::mpl::false_, // Tagging for the isFiniteTemp... functions
160 {
161 protected:
162  Liouvillean(double kappa, double=0, const std::string& kT=keyTitle) : structure::ElementLiouvillean<1,1>(kT,"excitation loss"), kappa_(kappa) {}
163  // the second dummy argument is there only to have the same form for the ctor as in the TEMPERATURE=true case
164 
165 private:
166  void doActWithJ (NoTime, StateVectorLow& psi ) const {details::aJump(psi,kappa_);}
167  double rate (NoTime, const LazyDensityOperator&) const;
168 
169  const double kappa_;
170 
171 };
172 
173 
174 namespace details {
175 
176 class LiouvilleanFiniteTemperatureBase
177 {
178 protected:
179  LiouvilleanFiniteTemperatureBase(double kappa, double nTh) : kappa_(kappa), nTh_(nTh) {}
180 
181  double rate0(const LazyDensityOperator&, boost::mpl::false_) const;
182  double rate1(const LazyDensityOperator&, boost::mpl::false_) const;
183  double rate0(const LazyDensityOperator&, boost::mpl:: true_) const {return -1.;}
184  double rate1(const LazyDensityOperator&, boost::mpl:: true_) const {return -1.;}
185 
186  const double kappa_, nTh_;
187 
188 };
189 
190 } // details
191 
192 
193 template<bool IS_ALTERNATIVE>
194 class Liouvillean<true ,IS_ALTERNATIVE>
195  : private details::LiouvilleanFiniteTemperatureBase,
196  protected boost::mpl::true_,
198 {
199 protected:
201 
202  Liouvillean(double kappa, double nTh, const std::string& kT=keyTitle)
203  : details::LiouvilleanFiniteTemperatureBase(kappa,nTh), Base(kT,{"excitation loss","excitation absorption"}) {}
204 
205 private:
206  void doActWithJ(NoTime, StateVectorLow& psi, LindbladNo<0>) const {details:: aJump(psi,kappa_*(nTh_+1));}
207  void doActWithJ(NoTime, StateVectorLow& psi, LindbladNo<1>) const {details::aDagJump(psi,kappa_* nTh_ );}
208 
209  double rate(NoTime, const LazyDensityOperator& matrix, LindbladNo<0>) const {return rate0(matrix,boost::mpl::bool_<IS_ALTERNATIVE>());}
210  double rate(NoTime, const LazyDensityOperator& matrix, LindbladNo<1>) const {return rate1(matrix,boost::mpl::bool_<IS_ALTERNATIVE>());}
211 
212 };
213 
214 
215 
216 // A basic, extensible Averaging class
218 {
219 public:
221 
222  Averaged(const KeyLabels& follow=KeyLabels(), const KeyLabels& precede=KeyLabels());
223 
224 protected:
225  const Averages average_v(NoTime, const LazyDensityOperator&) const;
226  void process_v( Averages&) const;
227 
228 private:
229  const ClonedPtr do_clone() const {return new Averaged(*this);}
230 
231 };
232 
233 
235 {
236 public:
237  AveragedQuadratures(const KeyLabels& follow=KeyLabels(), const KeyLabels& precede=KeyLabels());
238 
239 protected:
240  const Averages average_v(NoTime, const LazyDensityOperator&) const;
241  void process_v( Averages&) const;
242 
243 private:
244  const ClonedPtr do_clone() const {return new AveragedQuadratures(*this);}
245 
246 };
247 
248 
249 template<typename Base>
250 class AveragedMonitorCutoff : public Base
251 {
252 public:
253  typedef typename Base::Averages Averages;
254  typedef typename Base::KeyLabels KeyLabels;
255 
257 
258 private:
259  const Averages average_v(NoTime, const LazyDensityOperator&) const;
260  void process_v( Averages&) const;
261 
262 };
263 
264 
265 } // mode
266 
267 
268 
270 //
271 // Highest level
272 //
274 
275 
276 class ModeBase
277  : public structure::Free
278 {
279 public:
280  ModeBase(size_t dim,
281  const RealFreqs& realFreqs=emptyRF, const ComplexFreqs& complexFreqs=emptyCF,
282  const std::string& keyTitle=mode::keyTitle);
283 
284  ModeBase(size_t dim, const ComplexFreqs& complexFreqs, const std::string& keyTitle=mode::keyTitle) : ModeBase(dim,emptyRF,complexFreqs,keyTitle) {}
285  ModeBase(size_t dim, RealFreqsInitializer rf, ComplexFreqsInitializer cf={}, const std::string& keyTitle=mode::keyTitle)
286  : ModeBase(dim,RealFreqs(rf),ComplexFreqs(cf),keyTitle) {}
287  ModeBase(size_t dim, ComplexFreqsInitializer cf, const std::string& keyTitle=mode::keyTitle) : ModeBase(dim,RealFreqsInitializer(),cf,keyTitle) {}
288  ModeBase(size_t dim, RF rf, CF cf=CF(), const std::string& keyTitle=mode::keyTitle)
289  : ModeBase(dim,RealFreqsInitializer{rf}, cf==CF() ? ComplexFreqsInitializer{} : ComplexFreqsInitializer{cf},keyTitle) {}
290  ModeBase(size_t dim, CF cf, const std::string& keyTitle=mode::keyTitle) : ModeBase(dim,ComplexFreqsInitializer{cf},keyTitle) {}
291  ModeBase(size_t dim, RealFreqsInitializer rf, CF cf, const std::string& keyTitle=mode::keyTitle) : ModeBase(dim,rf,{cf},keyTitle) {}
292  ModeBase(size_t dim, RF rf, ComplexFreqsInitializer cf, const std::string& keyTitle=mode::keyTitle) : ModeBase(dim,{rf},cf,keyTitle) {}
293 
294  virtual ~ModeBase() {}
295 
296 };
297 
298 
300 // 1
302 
304 template<typename AveragingType>
305 class Mode
306  : public mode::Exact, public ModeBase, public AveragingType
307 {
308 public:
309  template<typename... AveragingConstructorParameters>
310  Mode(const mode::Pars&, AveragingConstructorParameters&&... );
311 };
312 
313 
316 template<typename AveragingType>
318 struct ModeUIP : Mode<AveragingType>
319 {
320  template<typename... AveragingConstructorParameters>
321  ModeUIP(const mode::Pars& p, AveragingConstructorParameters&&... a) : Mode<AveragingType>(p,a...) {}
322 };
323 
326 // 2
329 
331 template<typename AveragingType>
332 class ModeSch
333  : public mode::Hamiltonian<false>, public ModeBase, public AveragingType
334 {
335 public:
336  template<typename... AveragingConstructorParameters>
337  ModeSch(const mode::Pars&, AveragingConstructorParameters&&... );
338 };
339 
340 
342 // 3
344 
346 template<typename AveragingType>
348  : public mode::Hamiltonian<true>, public ModeBase, public AveragingType
349 {
350 public:
351  template<typename... AveragingConstructorParameters>
352  PumpedMode(const mode::ParsPumped&, AveragingConstructorParameters&&... );
353 };
354 
355 
358 template<typename AveragingType>
359 struct PumpedModeUIP : PumpedMode<AveragingType>
360 {
361  template<typename... AveragingConstructorParameters>
362  PumpedModeUIP(const mode::ParsPumped& p, AveragingConstructorParameters&&... a) : PumpedMode<AveragingType>(p,a...) {}
363 };
364 
367 // 4
370 
372 template<typename AveragingType>
374  : public mode::Hamiltonian<false>, public ModeBase, public AveragingType
375 {
376 public:
377  template<typename... AveragingConstructorParameters>
378  PumpedModeSch(const mode::ParsPumped&, AveragingConstructorParameters&&... );
379 };
380 
381 
383 // 5
385 
387 
388 template<bool TEMPERATURE, typename AveragingType>
389 class LossyMode
390  : public mode::Liouvillean<TEMPERATURE>, public mode::Exact, public ModeBase, public AveragingType
391 {
392 public:
393  template<typename... AveragingConstructorParameters>
394  LossyMode(const mode::ParsLossy&, AveragingConstructorParameters&&... );
395 
396 };
397 
399 // 6
401 
403 template<bool TEMPERATURE, typename AveragingType>
405  : public mode::Liouvillean<TEMPERATURE>, public mode::Hamiltonian<true>, public ModeBase, public AveragingType
406 {
407 public:
408  template<typename... AveragingConstructorParameters>
409  LossyModeUIP(const mode::ParsLossy&, AveragingConstructorParameters&&... );
410 
411 };
412 
414 // 7
416 
418 template<bool TEMPERATURE, typename AveragingType>
420  : public mode::Liouvillean<TEMPERATURE>, public mode::Hamiltonian<false>, public ModeBase, public AveragingType
421 {
422 public:
423  template<typename... AveragingConstructorParameters>
424  LossyModeSch(const mode::ParsLossy&, AveragingConstructorParameters&&... );
425 
426 };
427 
428 
430 // 8
432 
434 template<bool TEMPERATURE, typename AveragingType>
436  : public mode::Liouvillean<TEMPERATURE>, public mode::Hamiltonian<true>, public ModeBase, public AveragingType
437 {
438 public:
439  template<typename... AveragingConstructorParameters>
440  PumpedLossyMode(const mode::ParsPumpedLossy&, AveragingConstructorParameters&&... );
441 };
442 
444 // 9
446 
448 template<bool TEMPERATURE, typename AveragingType>
450  : public mode::Liouvillean<TEMPERATURE>, public mode::Hamiltonian<true>, public ModeBase, public AveragingType
451 {
452 public:
453  template<typename... AveragingConstructorParameters>
454  PumpedLossyModeUIP(const mode::ParsPumpedLossy&, AveragingConstructorParameters&&... );
455 };
456 
458 // 10
460 
462 template<bool TEMPERATURE, typename AveragingType>
464  : public mode::Liouvillean<TEMPERATURE>, public mode::Hamiltonian<false>, public ModeBase, public AveragingType
465 {
466 public:
467  template<typename... AveragingConstructorParameters>
468  PumpedLossyModeSch(const mode::ParsPumpedLossy&, AveragingConstructorParameters&&... );
469 };
470 
471 
473 // One more to help testing the alternative jumping in MCWF_Trajectory
475 
476 template<bool TEMPERATURE, typename AveragingType=mode::Averaged>
478  : public mode::Liouvillean<TEMPERATURE,true>, public mode::Hamiltonian<true>, public ModeBase, public AveragingType
479 {
480 public:
481  template<typename... AveragingConstructorParameters>
482  PumpedLossyModeAlternative(const mode::ParsPumpedLossy&, AveragingConstructorParameters&&... );
483 };
484 
485 
487 // One more to test time-dependent jump and averages
489 
491  : public ModeBase,
493  public structure::ElementLiouvillean<1,1,true>,
494  public structure::ElementAveraged<1,true>
495 {
496 public:
497  PumpedLossyModeIP_NoExact(const mode::ParsPumpedLossy&);
498 
499 private:
500  typedef structure::OneTime OneTime;
503 
504  void doActWithJ (OneTime, StateVectorLow& ) const;
505  double rate (OneTime, const LazyDensityOperator&) const;
506 
507  const Averages average_v(OneTime, const LazyDensityOperator&) const;
508 
509  const dcomp z_;
510 
511 };
512 
513 #endif // CPPQEDELEMENTS_FREES_MODE__H_INCLUDED
Combines LossyModeUIP and PumpedMode.
Definition: Mode_.h:449
std::tuple< std::string, dcomp, double > CF
quantumdata::Types< 1 >::StateVectorLow StateVectorLow
Implements a free mode, that is, in a fully exact way, that is .
Definition: Mode_.h:305
const StateVector coherent(const dcomp &alpha, size_t cutoff)
Coherent state.
std::list< CF > ComplexFreqs
Contains helpers for the Mode bundle.
Definition: Mode_.h:23
const StateVector init(const Pars &)
Dispatcher for initial condition.
Definition: Qbit_.h:84
Implements a mode damped with rate , that is , in a fully exact way, that is , and ...
Definition: Mode_.h:389
Same as Mode, but without exact propagation.
Definition: Mode_.h:332
std::list< RF > RealFreqs
Implements a pumped mode, that is in interaction picture defined by the first term.
Definition: Mode_.h:347
Diagonals::T_numtype Diagonal
Same as LossyMode, but in Schrödinger picture.
Definition: Mode_.h:419
Combines LossyMode with pumping in full (non-unitary) interaction picture.
Definition: Mode_.h:435
Same as LossyMode, but in unitary interaction picture, defined only by the part of the Hamiltonian...
Definition: Mode_.h:404
std::tuple< std::string, double, double > RF
std::complex< double > dcomp
Same as PumpedMode, without exact propagation.
Definition: Mode_.h:373
const Ptr make(const IA &ia)
Combines LossyModeSch and PumpedModeSch.
Definition: Mode_.h:463
LiouvilleanAveragedCommon::DArray1D Averages