66from mesohops .dynamics .hops_eom import HopsEOM
77from mesohops .dynamics .hops_hierarchy import HopsHierarchy
88from mesohops .dynamics .hops_system import HopsSystem
9- from mesohops .dynamics .prepare_functions import prepare_noise
9+ from mesohops .dynamics .prepare_functions import prepare_hops_noise
1010from mesohops .dynamics .hops_storage import HopsStorage
11+ from mesohops .util .dynamic_dict import Dict_wDefaults
1112from mesohops .util .exceptions import UnsupportedRequest , LockedException , TrajectoryError
1213from mesohops .util .physical_constants import precision # Constant
1314
1415__title__ = "HOPS"
15- __author__ = "D. I. G. Bennett, L. Varvelo"
16+ __author__ = "D. I. G. Bennett, L. Varvelo, Z. W. Freeman "
1617__version__ = "1.4"
1718
19+ INTEGRATION_DICT_DEFAULT = {
20+ "INTEGRATOR" : "RUNGE_KUTTA" ,
21+ "EARLY_ADAPTIVE_INTEGRATOR" : "INCH_WORM" ,
22+ "EARLY_INTEGRATOR_STEPS" : 5 ,
23+ "INCHWORM_CAP" : 5 ,
24+ "STATIC_BASIS" : None ,
25+ "EFFECTIVE_NOISE_INTEGRATION" : False ,
26+ }
27+
28+ INTEGRATION_DICT_TYPES = {
29+ "INTEGRATOR" : [str ],
30+ "EARLY_ADAPTIVE_INTEGRATOR" : [str ],
31+ "EARLY_INTEGRATOR_STEPS" : [int ],
32+ "INCHWORM_CAP" : [int ],
33+ "STATIC_BASIS" : [type (None ), list , np .ndarray ],
34+ "EFFECTIVE_NOISE_INTEGRATION" : [bool ],
35+ }
36+
1837
1938class HopsTrajectory :
2039 """
@@ -28,10 +47,7 @@ def __init__(
2847 noise_param = {},
2948 hierarchy_param = {},
3049 storage_param = {},
31- integration_param = dict (
32- INTEGRATOR = "RUNGE_KUTTA" , EARLY_ADAPTIVE_INTEGRATOR = 'INCH_WORM' ,EARLY_INTEGRATOR_STEPS = 5 , INCHWORM_CAP = 5 ,
33- STATIC_BASIS = None , EFFECTIVE_NOISE_INTEGRATION = False ,
34- ),
50+ integration_param = {},
3551 ):
3652 """
3753 This class manages four classes:
@@ -104,32 +120,30 @@ def __init__(
104120 self .noise_param = noise_param
105121 self .basis = HopsBasis (system , hierarchy , eom )
106122 self .storage = HopsStorage (self .basis .eom .param ['ADAPTIVE' ],storage_param )
107- self .noise1 = prepare_noise (noise_param , self .basis .system .param )
123+ self .noise1 = prepare_hops_noise (noise_param , self .basis .system .param )
108124 if "L_NOISE2" in system .param .keys ():
109125 noise_param2 = copy .copy (noise_param )
110126 rand = np .random .RandomState (seed = noise_param ['SEED' ])
111127 noise_param2 ['SEED' ] = int (rand .randint (0 , 2 ** 20 , 1 )[0 ])
112- self .noise2 = prepare_noise (noise_param2 , self .basis .system .param , flag = 2 )
128+ self .noise2 = prepare_hops_noise (noise_param2 , self .basis .system .param , flag = 2 )
113129 else :
114130 noise_param2 = {
115131 "TLEN" : noise_param ["TLEN" ],
116132 "TAU" : noise_param ["TAU" ],
117133 "MODEL" : "ZERO" ,
118134 }
119- self .noise2 = prepare_noise (noise_param2 , self .basis .system .param , flag = 1 )
135+ self .noise2 = prepare_hops_noise (noise_param2 , self .basis .system .param , flag = 1 )
120136
121137 # Defines integration method
122138 # -------------------------
123- self ._early_integrator = integration_param ['EARLY_ADAPTIVE_INTEGRATOR' ]
124- self ._static_basis = integration_param ["STATIC_BASIS" ]
125- self ._early_steps = integration_param ["EARLY_INTEGRATOR_STEPS" ]
139+ self .integration_param = Dict_wDefaults ._initialize_dictionary (
140+ integration_param ,
141+ INTEGRATION_DICT_DEFAULT ,
142+ INTEGRATION_DICT_TYPES ,
143+ "integration_param in the HopsTrajectory initialization" ,
144+ )
126145 self ._early_step_counter = 0
127- if integration_param ['EARLY_ADAPTIVE_INTEGRATOR' ] == 'INCH_WORM' or \
128- integration_param ['EARLY_ADAPTIVE_INTEGRATOR' ] == 'STATIC_STATE_INCHWORM_HIERARCHY' :
129- self ._inchworm_cap = integration_param ["INCHWORM_CAP" ]
130- if "EFFECTIVE_NOISE_INTEGRATION" not in integration_param .keys ():
131- integration_param ["EFFECTIVE_NOISE_INTEGRATION" ] = False
132- if integration_param ["INTEGRATOR" ] == "RUNGE_KUTTA" :
146+ if self .integrator == "RUNGE_KUTTA" :
133147 from mesohops .dynamics .integrator_rk import (
134148 runge_kutta_step ,
135149 runge_kutta_variables ,
@@ -138,11 +152,9 @@ def __init__(
138152 self .step = runge_kutta_step
139153 self .integration_var = runge_kutta_variables
140154 self .integrator_step = 0.5
141- self .effective_noise_integration = integration_param [
142- "EFFECTIVE_NOISE_INTEGRATION" ]
143155 else :
144156 raise UnsupportedRequest (
145- ("Integrator of type " + str (integration_param [ "INTEGRATOR" ] )),
157+ ("Integrator of type " + str (self . integrator )),
146158 type (self ).__name__ ,
147159 )
148160
@@ -184,7 +196,7 @@ def initialize(self, psi_0):
184196 phi_tmp [: self .n_state ] = np .array (psi_0 )[self .state_list ]
185197 self .z_mem = np .zeros (len (self .basis .system .param ["L_NOISE1" ]))
186198 if self .basis .adaptive :
187- if self ._static_basis is None :
199+ if self .static_basis is None :
188200 # Update Basis
189201 z_step = self ._prepare_zstep (self .z_mem )
190202 (state_update , aux_update ) = self .basis .define_basis (phi_tmp , 1 ,
@@ -197,13 +209,13 @@ def initialize(self, psi_0):
197209 # Construct initial basis
198210 list_stable_state = self .state_list
199211 list_state_new = list (
200- set (self .state_list ).union (set (self ._static_basis [0 ])))
212+ set (self .state_list ).union (set (self .static_basis [0 ])))
201213 list_add_state = set (list_state_new ) - set (list_stable_state )
202214 state_update = (list_state_new , list_stable_state , list_add_state )
203215
204216 list_stable_aux = self .auxiliary_list
205217 list_aux_new = list (
206- set (self .auxiliary_list ).union (set (self ._static_basis [1 ])))
218+ set (self .auxiliary_list ).union (set (self .static_basis [1 ])))
207219 list_add_aux = set (list_aux_new ) - set (list_stable_aux )
208220 aux_update = (list_aux_new , list_stable_aux , list_add_aux )
209221
@@ -337,17 +349,17 @@ def propagate(self, t_advance, tau):
337349 # Checks for Early Time Integration
338350 # ================================
339351 if self .use_early_integrator :
340- print (f'Early Integration: Using { self ._early_integrator } ' )
352+ print (f'Early Integration: Using { self .early_integrator } ' )
341353 # Early Integrator: Inch Worm
342354 # ---------------------------
343- if self ._early_integrator == 'INCH_WORM' or \
344- self ._early_integrator == 'STATIC_STATE_INCHWORM_HIERARCHY' :
355+ if self .early_integrator == 'INCH_WORM' or \
356+ self .early_integrator == 'STATIC_STATE_INCHWORM_HIERARCHY' :
345357 # Define New Basis
346358 z_step = self ._prepare_zstep (z_mem )
347359 (state_update , aux_update ) = self .basis .define_basis (phi , tau ,
348360 z_step )
349- if self ._early_integrator == 'STATIC_STATE_INCHWORM_HIERARCHY' :
350- state_update = self ._static_basis [0 ]
361+ if self .early_integrator == 'STATIC_STATE_INCHWORM_HIERARCHY' :
362+ state_update = self .static_basis [0 ]
351363
352364 # Update basis for new step
353365 step_num = 0
@@ -356,10 +368,10 @@ def propagate(self, t_advance, tau):
356368 state_update , aux_update , phi = self .inchworm_integrate (
357369 state_update , aux_update , tau
358370 )
359- if self ._early_integrator == 'STATIC_STATE_INCHWORM_HIERARCHY' :
360- state_update = self ._static_basis [0 ]
371+ if self .early_integrator == 'STATIC_STATE_INCHWORM_HIERARCHY' :
372+ state_update = self .static_basis [0 ]
361373 step_num += 1
362- if step_num >= self ._inchworm_cap :
374+ if step_num >= self .inchworm_cap :
363375 break
364376
365377 # Update basis
@@ -369,11 +381,11 @@ def propagate(self, t_advance, tau):
369381
370382 # Early Integrator: Static Basis
371383 # ------------------------------
372- elif self ._early_integrator == 'STATIC' :
384+ elif self .early_integrator == 'STATIC' :
373385 pass
374386
375387 else :
376- raise UnsupportedRequest (self ._early_integrator ,
388+ raise UnsupportedRequest (self .early_integrator ,
377389 "early time integrator "
378390 "clause of the propagate" )
379391
@@ -579,13 +591,13 @@ def construct_noise_correlation_function(self, n_l2, n_traj):
579591 list_ct1 = np .zeros (len (t_axis ), dtype = np .complex128 )
580592 list_ct2 = np .zeros (len (t_axis ), dtype = np .complex128 )
581593 for _ in np .arange (n_traj ):
582- noise1 = prepare_noise (self .noise_param , self .basis .system .param )
594+ noise1 = prepare_hops_noise (self .noise_param , self .basis .system .param )
583595 noise1 .prepare_noise ()
584596 result = np .correlate (noise1 .get_noise (t_axis )[n_l2 , :],
585597 noise1 .get_noise (t_axis )[n_l2 , :], mode = 'full' )
586598 list_ct1 += result [result .size // 2 :]
587599 if "L_NOISE2" in self .basis .system .param .keys ():
588- noise2 = prepare_noise (self .noise_param , self .basis .system .param ,
600+ noise2 = prepare_hops_noise (self .noise_param , self .basis .system .param ,
589601 flag = 2 )
590602 noise2 .prepare_noise ()
591603 result = np .correlate (noise2 .get_noise (t_axis )[n_l2 , :],
@@ -596,11 +608,31 @@ def construct_noise_correlation_function(self, n_l2, n_traj):
596608 def reset_early_time_integrator (self ):
597609 """
598610 Sets self._early_integrator_time to the current time so that the next use of
599- propagate will make the first self._early_steps early time integrator
611+ propagate will make the first self.early_steps early time integrator
600612 propagation steps.
601613 """
602614 self ._early_step_counter = 0
603615
616+ @property
617+ def early_integrator (self ):
618+ return self .integration_param ["EARLY_ADAPTIVE_INTEGRATOR" ]
619+
620+ @property
621+ def integrator (self ):
622+ return self .integration_param ["INTEGRATOR" ]
623+
624+ @property
625+ def inchworm_cap (self ):
626+ return self .integration_param ["INCHWORM_CAP" ]
627+
628+ @property
629+ def effective_noise_integration (self ):
630+ return self .integration_param ["EFFECTIVE_NOISE_INTEGRATION" ]
631+
632+ @property
633+ def static_basis (self ):
634+ return self .integration_param ["STATIC_BASIS" ]
635+
604636 @property
605637 def psi (self ):
606638 return self .phi [: self .n_state ]
@@ -645,9 +677,13 @@ def z_mem(self, z_mem):
645677 def t (self ):
646678 return self ._t
647679
680+ @property
681+ def early_steps (self ):
682+ return self .integration_param ["EARLY_INTEGRATOR_STEPS" ]
683+
648684 @property
649685 def use_early_integrator (self ):
650- return self ._early_step_counter < self ._early_steps
686+ return self ._early_step_counter < self .early_steps
651687
652688 @t .setter
653689 def t (self , t ):
0 commit comments