Skip to content

Commit 69b2cc1

Browse files
committed
Added the new experimental decoherence scheme
1 parent decf594 commit 69b2cc1

File tree

6 files changed

+132
-12
lines changed

6 files changed

+132
-12
lines changed

src/dyn/Dynamics.cpp

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,63 @@ void propagate_electronic(dyn_variables& dyn_var, nHamiltonian* Ham, nHamiltonia
11201120

11211121
}
11221122

1123+
void renormalize_hopping_probabilities(vector< vector<double> >& g, vector< vector<vector<double> > >& coherence_factors, vector<int>& act_states){
1124+
/**
1125+
Scale the hopping probabilities by the factors and ensure the sum of all
1126+
hopping probabilities is still 1
1127+
1128+
g[itraj][i] - hopping probability from the current active state for the trajectory itraj to the state i
1129+
1130+
act_states[itraj] - the active state for the trajectory itraj
1131+
1132+
coherence_factors[itraj][i][j] - the scaling of the hopping probability from state i to state j for the trajectory itraj
1133+
1134+
1135+
Result: the g vector is modified
1136+
*/
1137+
int ntraj = g.size();
1138+
int nstates = coherence_factors[0].size();
1139+
1140+
for(int itraj=0; itraj<ntraj; itraj++){
1141+
int a = act_states[itraj];
1142+
double sum = 0.0;
1143+
for(int j=0;j<nstates; j++){
1144+
if(j!=a){
1145+
double val = g[itraj][j] * coherence_factors[itraj][a][j];
1146+
sum += val;
1147+
g[itraj][j] = val;
1148+
}
1149+
}// for j
1150+
// The self-element:
1151+
g[itraj][a] = 1.0 - sum;
1152+
if(g[itraj][a]<0){ g[itraj][a] = 0.0; }
1153+
1154+
}// for itraj
1155+
1156+
}
1157+
1158+
void reset_coherence_factors(vector< vector<vector<double> > >& coherence_factors, vector<int>& act_states, vector<int>& old_states){
1159+
1160+
int ntraj = coherence_factors.size();
1161+
int nstates = coherence_factors[0].size();
1162+
1163+
for(int itraj=0; itraj<ntraj; itraj++){
1164+
if( act_states[itraj] != old_states[itraj]){
1165+
// If the hop has happened for this trajectory, we start
1166+
// new evolution of the wavepackets on all the surfaces
1167+
// so we have to reset all the coherence factors to 1.0
1168+
for(int i=0; i<nstates; i++){
1169+
for(int j=0; j<nstates; j++){
1170+
coherence_factors[itraj][i][j] = 1.0;
1171+
}// for j
1172+
}// for i
1173+
1174+
}// if
1175+
}// for itraj
1176+
1177+
}
1178+
1179+
11231180
void compute_dynamics(dyn_variables& dyn_var, bp::dict dyn_params,
11241181
nHamiltonian& ham, nHamiltonian& ham_aux, bp::object py_funct, bp::dict params, Random& rnd,
11251182
vector<Thermostat>& therm){
@@ -1151,7 +1208,7 @@ void compute_dynamics(dyn_variables& dyn_var, bp::dict dyn_params,
11511208

11521209
// cout<<"In compute_dynamics\n";
11531210
//======== General variables =======================
1154-
int i, cdof, traj, dof, idof, ntraj1;
1211+
int i, j, cdof, traj, dof, idof, ntraj1;
11551212

11561213
//========= Control parameters variables ===========
11571214
dyn_control_params prms;
@@ -1378,7 +1435,7 @@ void compute_dynamics(dyn_variables& dyn_var, bp::dict dyn_params,
13781435
}
13791436

13801437
else if(prms.decoherence_times_type==5){
1381-
decoherence_rates = Gu_Franco(prms, *dyn_var.ampl_adi);
1438+
decoherence_rates = Gu_Franco(prms, *dyn_var.ampl_adi);
13821439
}
13831440

13841441
///== Optionally, apply the dephasing-informed correction ==
@@ -1435,7 +1492,19 @@ void compute_dynamics(dyn_variables& dyn_var, bp::dict dyn_params,
14351492
}
14361493

14371494
// DISH, rev2023
1438-
if(prms.decoherence_algo==7){ dish_rev2023(dyn_var, ham, decoherence_rates, prms, rnd); }
1495+
else if(prms.decoherence_algo==7){ dish_rev2023(dyn_var, ham, decoherence_rates, prms, rnd); }
1496+
1497+
// Simple decoherence
1498+
else if(prms.decoherence_algo==9){
1499+
for(traj=0; traj<ntraj; traj++){
1500+
for(i=0; i<nadi; i++){
1501+
for(j=0; j<nadi; j++){
1502+
double argg = decoherence_rates[traj].get(i,j) * prms.dt;
1503+
dyn_var.coherence_factors[traj][i][j] *= exp( - argg * argg );
1504+
}// for j
1505+
}// for i
1506+
}// for traj
1507+
}// simple decoherence
14391508

14401509

14411510
// Update amplitudes and density matrices in response to decoherence corrections
@@ -1467,6 +1536,11 @@ void compute_dynamics(dyn_variables& dyn_var, bp::dict dyn_params,
14671536
vector< vector<double> > g;
14681537
g = hop_proposal_probabilities(prms, dyn_var, ham, ham_aux);
14691538

1539+
// simple decoherence correction
1540+
if(prms.decoherence_algo==9){ // intended only for adiabatic states for now
1541+
renormalize_hopping_probabilities(g, dyn_var.coherence_factors, dyn_var.act_states);
1542+
}
1543+
14701544
// Propose new discrete states for all trajectories
14711545
vector<int> prop_states(ntraj, 0);
14721546
if(prms.rep_sh==1){
@@ -1511,7 +1585,11 @@ void compute_dynamics(dyn_variables& dyn_var, bp::dict dyn_params,
15111585
prms.instantaneous_decoherence_variant, prms.collapse_option);
15121586
}
15131587
else{ cout<<"ERROR: Instantaneous Decoherence requires rep_tdse = 1\nExiting now...\n"; exit(0); }
1514-
}// algo == 6
1588+
}// algo == 8
1589+
1590+
else if(prms.decoherence_algo==9){ // simple decoherence method
1591+
reset_coherence_factors(dyn_var.coherence_factors, act_states, old_states);
1592+
}// algo == 9
15151593

15161594
}
15171595
// DISH - the old one
@@ -1522,6 +1600,7 @@ void compute_dynamics(dyn_variables& dyn_var, bp::dict dyn_params,
15221600
}// DISH
15231601

15241602

1603+
15251604
//====================== Momenta adjustment after successful/frustrated hops ===================
15261605
// Velocity rescaling: however here we may be changing velocities
15271606
if(prms.rep_sh==1){

src/dyn/dyn_control_params.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -292,15 +292,15 @@ class dyn_control_params{
292292
int convergence;
293293

294294
/**
295-
The maximum number of hops that an be attempted before either choosing the identity or exiting in stochastic reordering algorithm 3.
295+
The maximum number of hops that an be attempted before either choosing the identity or exiting in stochastic reordering algorithm 3.
296296
*/
297297
int max_number_attempts;
298298

299299
/**
300-
The probability threshold for stochastic state reordering algorithm.
301-
If a probability for a multi-state stransition is below this value, it will be disregarded and set to 0
302-
The rest of the probabilities will be renormalized
303-
Default: 0.0
300+
The probability threshold for stochastic state reordering algorithm.
301+
If a probability for a multi-state stransition is below this value, it will be disregarded and set to 0
302+
The rest of the probabilities will be renormalized
303+
Default: 0.0
304304
*/
305305
double min_probability_reordering;
306306

@@ -513,6 +513,7 @@ class dyn_control_params{
513513
- 6: MQCXF
514514
- 7: DISH, rev2023
515515
- 8: diabatic IDA, experimental
516+
- 9: simple decoherence, experimental
516517
517518
*/
518519
double decoherence_algo;

src/dyn/dyn_variables.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ dyn_variables::dyn_variables(int _ndia, int _nadi, int _ndof, int _ntraj){
119119
///================= KC-RPMD ====================
120120
kcrpmd_vars_status = 0;
121121

122+
///================= simple decoherence ====================
123+
simple_decoherence_vars_status = 0;
124+
122125
}
123126

124127

@@ -313,6 +316,18 @@ void dyn_variables::allocate_kcrpmd(){
313316
}// allocate_kcrpmd
314317

315318

319+
void dyn_variables::allocate_simple_decoherence(){
320+
321+
if(simple_decoherence_vars_status==0){
322+
323+
coherence_factors = std::vector< std::vector< std::vector<double> > >(ntraj, std::vector< std::vector<double> >(nadi, std::vector<double>(nadi, 1.0) ) );
324+
simple_decoherence_vars_status = 1;
325+
}
326+
327+
}
328+
329+
330+
316331
dyn_variables::dyn_variables(const dyn_variables& x){
317332
//cout<<"dyn_variables copy constructor\n";
318333
int itraj, idof;
@@ -470,6 +485,10 @@ dyn_variables::dyn_variables(const dyn_variables& x){
470485

471486
}// if KCRPMD vars
472487

488+
if(x.simple_decoherence_vars_status == 1 ){
489+
coherence_factors = x.coherence_factors;
490+
}
491+
473492
}// dyn_variables cctor
474493

475494

@@ -629,6 +648,12 @@ dyn_variables::~dyn_variables(){
629648
kcrpmd_vars_status = 0;
630649
}
631650

651+
if(simple_decoherence_vars_status==1){
652+
coherence_factors.clear();
653+
654+
simple_decoherence_vars_status = 0;
655+
}
656+
632657
}
633658

634659

src/dyn/dyn_variables.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -552,12 +552,20 @@ class dyn_variables{
552552
int timestep;
553553

554554

555-
///=============== For new decoherence method ==============
555+
///=============== For new decoherence method (let's call it simple_decoherence ) ==============
556+
/**
557+
Status of the new decoherence method vars
558+
559+
0 - not allocated;
560+
1 - allocated
561+
*/
562+
int simple_decoherence_vars_status;
563+
556564
/**
557565
Integrated exp( -(dt/tau(t))**2 ) over many timesteps
558-
Reset to 1 at every accepted hop
566+
Reset to 1 at every accepted hop, separate for each trajectory
559567
*/
560-
vector< vector<double> > coherence_factors;
568+
vector< vector< vector<double> > > coherence_factors;
561569

562570

563571
///====================== In dyn_variables.cpp =====================
@@ -573,6 +581,8 @@ class dyn_variables{
573581
void allocate_mqcxf();
574582
void allocate_qtsh();
575583
void allocate_kcrpmd();
584+
void allocate_simple_decoherence();
585+
576586

577587
dyn_variables(int _ndia, int _nadi, int _ndof, int _ntraj);
578588
dyn_variables(const dyn_variables& x);

src/dyn/libdyn.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ void export_dyn_variables_objects(){
248248
.def_readwrite("tcnbra_ekin", &dyn_variables::tcnbra_ekin)
249249
.def_readwrite("qtsh_vars_status", &dyn_variables::qtsh_vars_status)
250250
.def_readwrite("kcrpmd_vars_status", &dyn_variables::kcrpmd_vars_status)
251+
.def_readwrite("simple_decoherence_vars_status", &dyn_variables::simple_decoherence_vars_status)
251252

252253
.def("set_parameters", expt_set_parameters_v1)
253254

@@ -262,6 +263,7 @@ void export_dyn_variables_objects(){
262263
.def("allocate_mqcxf", &dyn_variables::allocate_mqcxf)
263264
.def("allocate_qtsh", &dyn_variables::allocate_qtsh)
264265
.def("allocate_kcrpmd", &dyn_variables::allocate_kcrpmd)
266+
.def("allocate_simple_decoherence", &dyn_variables::allocate_simple_decoherence)
265267

266268
.def("set_q", &dyn_variables::set_q)
267269
.def("set_p", &dyn_variables::set_p)

src/libra_py/dynamics/tsh/compute.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,9 @@ def run_dynamics(dyn_var, _dyn_params, ham, compute_model, _model_params, rnd):
988988
dyn_var.allocate_shxf()
989989
elif decoherence_algo == 6: # MQCXF
990990
dyn_var.allocate_mqcxf()
991+
elif decoherence_algo == 9: # simple decoherence
992+
dyn_var.allocate_simple_decoherence()
993+
991994
if tsh_method == 5 or decoherence_algo == 7: # DISH or DISH_rev2023
992995
dyn_var.allocate_dish()
993996
if tsh_method == 7 or tsh_method == 8 or tsh_method == 9: # FSSH2 or FSSH3 or original GFSH

0 commit comments

Comments
 (0)