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
MultiLevel_.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_MULTILEVEL__H_INCLUDED
5 #define CPPQEDELEMENTS_FREES_MULTILEVEL__H_INCLUDED
6 
7 #include "MultiLevel_Fwd.h"
8 
9 #include "ParsMultiLevel.h"
10 
11 #include "AveragingUtils.tcc"
12 
13 #include "ElementAveraged.h"
14 #include "ElementLiouvillean.h"
15 #include "Free.h"
16 #include "FreeExact.h"
17 #include "Hamiltonian.h"
18 
19 #include <boost/fusion/mpl/size.hpp>
20 
21 #include <boost/shared_ptr.hpp>
22 
23 
25 namespace multilevel {
26 
27 
28 const std::string keyTitle="MultiLevel";
29 
30 
31 using namespace structure::freesystem;
32 
34 template<int NL> using Levels = blitz::TinyVector<dcomp,NL>;
35 
37 template<int NL> using RealLevels = blitz::TinyVector<double,NL>;
38 
39 
40 
42 //
43 // Exact
44 //
46 
48 
50 template<int NL>
51 class Exact : public structure::FreeExact<false>
52 {
53 public:
54  typedef Levels<NL> L;
55 
56  Exact(const L& zIs) : FreeExact<false>(NL), zIs_(zIs) {}
57 
58  const L& get_zIs() const {return zIs_;}
59 
60 private:
61  void updateU(double) const;
62 
63  bool applicableInMaster_v() const;
64 
65  const L zIs_;
66 
67 };
68 
69 
70 
72 //
73 // Hamiltonian
74 //
76 
77 
78 template<typename T>
79 class Storage
80 {
81 public:
82  Storage(const T& value) : value_(value) {} //< Deliberately not explicit
83  Storage() : value_() {}
84 
85  const T& get() const {return value_;}
86  void set(const T& value) {value_=value;}
87 
88 private:
89  T value_;
90 
91 };
92 
93 
94 template<>
95 class Storage<double>
96 {
97 public:
98  Storage(double value) : value_(value) {} //< Deliberately not explicit
99  Storage() : value_() {}
100 
101  double get() const {return value_;}
102  void set(double value) {value_=value;}
103 
104 private:
105  double value_;
106 
107 };
108 
109 
110 
111 template<typename T>
112 inline
113 std::ostream& operator<<(std::ostream& os, const Storage<T>& s)
114 {
115  return os<<s.get();
116 }
117 
118 
119 template<typename T>
120 inline
121 std::istream& operator>>(std::istream& is, Storage<T>& s)
122 {
123  T temp; is>>temp;
124  s.set(temp);
125  return is;
126 }
127 
128 
130 template<int I, int J>
131 class Pump : public Storage<dcomp>, public tmptools::pair_c<I,J>
132 {
133 public:
135 
136 };
137 
138 
139 template<int NL, typename VP>
141  : public structure::Hamiltonian<1>,
142  public Exact<NL>
143 {
144 public:
145  static const int NPT=mpl::size<VP>::value; // number of pumped transitions
146 
147  typedef typename Exact<NL>::L L;
148 
149  HamiltonianIP(const L& zSchs, const L& zIs, const VP& etas)
150  : Exact<NL>(zIs), zSchs_(zSchs), etas_(etas) {}
151 
152 private:
153  void addContribution_v(double, const StateVectorLow&, StateVectorLow&, double) const;
154 
155 
156  const L zSchs_;
157 
158  const VP etas_;
159 
160 };
161 
162 
163 template<int NL, typename VP>
165  : public structure::HamiltonianTimeDependenceDispatched<1,structure::NO_TIME>
166 {
167 public:
168  static const int NPT=mpl::size<VP>::value; // number of pumped transitions
169 
170  typedef Levels<NL> L;
171 
172  HamiltonianSch(const L& zSchs, const VP& etas) : zSchs_(zSchs), etas_(etas) {}
173 
174  const L& get_zSchs() const {return zSchs_;}
175 
176 private:
177  void addContribution_v(structure::NoTime, const StateVectorLow&, StateVectorLow&) const;
178 
179 
180  const L zSchs_;
181 
182  const VP etas_;
183 
184 };
185 
186 
188 //
189 // Liouvillean
190 //
192 
193 
195 template<int I, int J>
196 class Decay : public Storage<double>, public tmptools::pair_c<I,J>
197 {
198 public:
200 
201 };
202 
203 
204 template<int NL, typename VL>
205 class Liouvillean : public structure::ElementLiouvilleanStrategies<1,mpl::size<VL>::value+NL>
206 // Note that, at some point, the Fusion sequence VL needs to be converted into a runtime sequence (JumpStrategies & JumpRateStrategies)
207 {
208 public:
209  static const int NLT=mpl::size<VL>::value; // number of lossy transitions
210 
212 
213  typedef typename Base::JumpStrategies JumpStrategies ;
214  typedef typename Base::JumpRateStrategies JumpRateStrategies;
215 
216  static_assert( blitzplusplus::TinyVectorLengthTraits<JumpRateStrategies>::value==NLT+NL , "Jump number inconsistent." );
217 
218  typedef typename Base::KeyLabels KeyLabels;
219 
220  Liouvillean(const VL& gammas, double gamma_parallel) : Base(Liouvillean::fillJS(),Liouvillean::fillJRS(),keyTitle,fillKeyLabels()), gammas_(gammas), gamma_parallel_(gamma_parallel) {}
221 
222  const JumpStrategies fillJS () const;
223  const JumpRateStrategies fillJRS() const;
224 
225  static const KeyLabels fillKeyLabels();
226 
227 private:
228  template<int>
229  void jumpStrategy(StateVectorLow&) const;
230 
231  template<int>
232  double jumpRateStrategy(const LazyDensityOperator&) const;
233 
234  // NEED_TO_UNDERSTAND can member TEMPLATES be passed as template parameters? This would be needed to fuse fillJS and fillJRS into a template together with the helper classes below
235 
236  void flipStrategy(StateVectorLow& psi, size_t i) const {psi*=sqrt(2.*gamma_parallel_); psi(i)*=-1.;}
237  double flipRateStrategy(const LazyDensityOperator&) const {return 2*gamma_parallel_;} // Being a member is somewhat superfluous here
238 
239  class JS_helper;
240  class JRS_helper;
241 
242  class KeyHelper;
243 
244  const VL gammas_;
245 
246  const double gamma_parallel_;
247 
248 };
249 
250 
251 } // multilevel
252 
253 
255 //
256 // Highest level
257 //
259 
260 
261 template<int NL>
263  : public structure::Free
264 {
265 public:
266  typedef boost::shared_ptr<const MultiLevelBase> Ptr;
267 
269 
270  MultiLevelBase(const RealFreqs& realFreqs=RealFreqs(), const ComplexFreqs& complexFreqs=ComplexFreqs())
271  : structure::Free(NL,realFreqs,complexFreqs)
272  {
273  getParsStream()<<"# "<<multilevel::keyTitle<<std::endl;
274  }
275 
276  virtual ~MultiLevelBase() {}
277 
278 };
279 
280 
282 
289 template<int NL, typename VP, typename VL, typename AveragingType>
291  : public multilevel::HamiltonianSch<NL,VP>,
292  public multilevel::Liouvillean<NL,VL>,
293  public MultiLevelBase<NL>,
294  public AveragingType
295  // The ordering becomes important here
296 {
297 public:
300 
303  typedef MultiLevelBase<NL> Base;
304 
305  typedef typename Base::Ptr Ptr;
306 
307  template<typename... AveragingConstructorParameters>
308  PumpedLossyMultiLevelSch(const RealLevels&, const VP&, const VL&, double gamma_parallel, AveragingConstructorParameters&&...);
309 
310 };
311 
312 
313 
314 namespace multilevel {
315 
316 #define RETURN_type typename MultiLevelBase<NL>::Ptr
317 
319 template<typename AveragingType, int NL, typename VP, typename VL, typename... AveragingConstructorParameters>
320 inline
321 RETURN_type
323  const VP& etas, const VL& gammas, double gamma_parallel,
324  AveragingConstructorParameters&&... a)
325 {
326  return boost::make_shared<PumpedLossyMultiLevelSch<NL,VP,VL,AveragingType> >(deltas,etas,gammas,gamma_parallel,a...);
327 }
328 
330 template<typename AveragingType, int NL, typename VP, typename VL, typename... AveragingConstructorParameters>
331 inline
332 RETURN_type
333 makePumpedLossySch(const multilevel::ParsPumpedLossy<NL,VP,VL>& p, AveragingConstructorParameters&&... a)
334 {
335  return makePumpedLossySch<AveragingType>(p.deltas,p.etas,p.gammas,p.gamma_parallel,a...);
336 }
337 
339 template<int NL, typename VP, typename VL>
340 inline
341 RETURN_type
342 makePumpedLossySch(const RealLevels<NL>& deltas, const VP& etas, const VL& gammas, double gamma_parallel, const std::string& keyTitle="PumpedLossyMultiLevelSch", bool offDiagonals=false)
343 {
344  return makePumpedLossySch<ReducedDensityOperator<1> >(deltas,etas,gammas,gamma_parallel,keyTitle,NL,offDiagonals);
345 }
346 
348 template<int NL, typename VP, typename VL>
349 inline
350 RETURN_type
351 makePumpedLossySch(const multilevel::ParsPumpedLossy<NL,VP,VL>& p, const std::string& keyTitle="PumpedLossyMultiLevelSch", bool offDiagonals=false)
352 {
353  return makePumpedLossySch<ReducedDensityOperator<1> >(p,keyTitle,NL,offDiagonals);
354 }
355 
356 
357 #undef RETURN_type
358 
359 } // multilevel
360 
361 
362 #endif // CPPQEDELEMENTS_FREES_MULTILEVEL__H_INCLUDED
Contains helpers for the MultiLevel bundle.
Definition: MultiLevel_.h:25
boost::shared_ptr< const QuantumSystem > Ptr
quantumdata::Types< 1 >::StateVectorLow StateVectorLow
std::list< CF > ComplexFreqs
blitz::TinyVector< JumpStrategy, NLINDBLADS > JumpStrategies
blitz::TinyVector< JumpRateStrategy, NLINDBLADS > JumpRateStrategies
std::istream & operator>>(std::istream &, Method &)
blitz::TinyVector< double, NL > RealLevels
Type for storing level energies (the s here)
Definition: MultiLevel_.h:37
std::list< RF > RealFreqs
Class representing an elementary pump term (an here) with a compile-time pair and a runtime complex...
Definition: MultiLevel_.h:131
Implements a free multi-level system with driving and loss.
Definition: MultiLevel_.h:290
Class representing an elementary decay term (a here) with a compile-time pair and a runtime real va...
Definition: MultiLevel_.h:196
std::ostringstream & getParsStream()
RETURN_type makePumpedLossySch(const RealLevels< NL > &deltas, const VP &etas, const VL &gammas, double gamma_parallel, AveragingConstructorParameters &&...a)
Maker function for PumpedLossyMultiLevelSch.
Definition: MultiLevel_.h:322
blitz::TinyVector< dcomp, NL > Levels
Type for storing complex level energies (the s here)
Definition: MultiLevel_.h:34