@@ -285,6 +285,117 @@ MATRIX nHamiltonian::kcrpmd_effective_force(vector<double>& auxiliary_y, const M
285285}
286286
287287
288+ vector<double > nHamiltonian::kcrpmd_effective_auxiliary_force (vector<double >& auxiliary_y, const MATRIX& q, const MATRIX& invM, double beta, double eta, double a, double b, double c, double d){
289+ /* *
290+ Compute the KC-RPMD effective auxiliary force
291+
292+ auxiliary_y - is the classical electronic coordinate as defined in KC-RPMD
293+ q - is a ndof x ntraj matrix of coordinates
294+ invM - is a ndof x 1 matrix of inverse masses of all DOFs
295+ beta - the inverse temperature Boltzmann factor in atomic units
296+ eta - geometric parameter conserving free energy of kinked pair formation ad defined in second KC-RPMD paper
297+ a - is the kinetic constraint ad-hoc parameter
298+ b - is the heavyside functional limit parameter
299+ c - is the constraint switching parameter
300+ d - is the free energy conservation switching parameter
301+ */
302+
303+ if (ham_dia_mem_status==0 ){ cout<<" Error in kcrpmd_effective_potential(): the diabatic Hamiltonian matrix is not allocated \
304+ but it is needed for the calculations\n " ; exit (0 ); }
305+
306+ if (ndia!=2 ){ cout<<" Error in kcrpmd_effective_potential(): implementation only for ndia=2\n " ; exit (0 ); }
307+
308+ int ntraj = q.n_cols ;
309+
310+ double V0;
311+ double V1;
312+ double VKP;
313+
314+ double F0;
315+ double F1;
316+ double FKP;
317+ vector<double > res;
318+
319+ if (children.size ()==0 and ntraj==1 ){
320+ // ============ Compute the pure electronic contributions =========
321+ V0 = (ham_dia->get (0 ,0 )).real ();
322+ V1 = (ham_dia->get (1 ,1 )).real ();
323+ double K = abs (ham_dia->get (0 ,1 ));
324+ double Vg = (ham_adi->get (0 ,0 )).real ();
325+ double Ve = (ham_adi->get (1 ,1 )).real ();
326+ if (beta * K > 1e-3 ){
327+ VKP = Vg - log (1 + exp (-beta * (Ve - Vg)) - exp (-beta * (V0 - Vg)) - exp (-beta * (V1 - Vg))) / beta;
328+ }
329+ else if (beta * abs (V0 - V1) > 1e-7 ){
330+ VKP = 0.5 * (V0 + V1) - log (pow (beta * K, 2 ) * sinh (0.5 * beta * (V0 - V1)) / (0.5 * beta * (V0 - V1))) / beta;
331+ }
332+ else {
333+ VKP = 0.5 * (V0 + V1) - log (pow (beta * K, 2 )) / beta;
334+ }
335+
336+ // ============ Compute the kinetic constraint =========
337+ double w = (V0 - V1) / K;
338+ double A = 0.5 * a * (1 + tanh (-c * (beta * K - 1 )));
339+ double C = 1 + 0.5 * (sqrt (A / 3.1415 ) * eta - 1 ) * (1 + tanh (-d * (beta * K - 1 )));
340+ VKP += (A * w * w - log (C)) / beta;
341+
342+ // ============ Compute the heavy side auxiliary potentials =========
343+ if (abs (auxiliary_y[0 ] + 1 ) < 0.5 ){
344+ V0 += -log (1 / (1 + exp (b * (2 * abs (auxiliary_y[0 ] + 1 ) - 1 )))) / beta;
345+ }
346+ else {
347+ V0 += (b * (2 * abs (auxiliary_y[0 ] + 1 ) - 1 ) - log (1 / (1 + exp (-b * (2 * abs (auxiliary_y[0 ] + 1 ) - 1 ))))) / beta;
348+ }
349+ if (abs (auxiliary_y[0 ] - 1 ) < 0.5 ){
350+ V1 += -log (1 / (1 + exp (b * (2 * abs (auxiliary_y[0 ] - 1 ) - 1 )))) / beta;
351+ }
352+ else {
353+ V1 += (b * (2 * abs (auxiliary_y[0 ] - 1 ) - 1 ) - log (1 / (1 + exp (-b * (2 * abs (auxiliary_y[0 ] - 1 ) - 1 ))))) / beta;
354+ }
355+ if (abs (auxiliary_y[0 ]) < 0.5 ){
356+ VKP += -log (1 / (1 + exp (b * (2 * abs (auxiliary_y[0 ]) - 1 )))) / beta;
357+ }
358+ else {
359+ VKP += (b * (2 * abs (auxiliary_y[0 ]) - 1 ) - log (1 / (1 + exp (-b * (2 * abs (auxiliary_y[0 ]) - 1 ))))) / beta;
360+ }
361+
362+ if (auxiliary_y[0 ] + 1 > 0.0 ){
363+ F0 += -b * (1 + tanh (b * (abs (auxiliary_y[0 ] + 1 ) - 0.5 ))) / beta;
364+ }
365+ else {
366+ F0 += b * (1 + tanh (b * (abs (auxiliary_y[0 ] + 1 ) - 0.5 ))) / beta;
367+ }
368+ if (auxiliary_y[0 ] > 0.0 ){
369+ FKP += -b * (1 + tanh (b * (abs (auxiliary_y[0 ]) - 0.5 ))) / beta;
370+ }
371+ else {
372+ FKP += b * (1 + tanh (b * (abs (auxiliary_y[0 ]) - 0.5 ))) / beta;
373+ }
374+ if (auxiliary_y[0 ] - 1 > 0.0 ){
375+ F1 += -b * (1 + tanh (b * (abs (auxiliary_y[0 ] - 1 ) - 0.5 ))) / beta;
376+ }
377+ else {
378+ F1 += b * (1 + tanh (b * (abs (auxiliary_y[0 ] - 1 ) - 0.5 ))) / beta;
379+ }
380+ }
381+ else if (children.size ()==ntraj){
382+ cout<<" Error in kcrpmd_effective_potential() not implemented for quantum nuclei\n " ; exit (0 );
383+ }
384+ else {
385+ cout<<" ERROR: the size of the input is different from the number of children\n " ; exit (0 );
386+ }
387+
388+ double Vshift = min ({V0, VKP, V1});
389+
390+ res = vector<double >(1 , (exp (-beta * (V0 - Vshift)) * F0 + exp (-beta * (VKP - Vshift)) * FKP + exp (-beta * (V1 - Vshift)) * F1) / (exp (-beta * (V0 - Vshift)) + exp (-beta * (VKP - Vshift)) + exp (-beta * (V1 - Vshift))));
391+
392+ return res;
393+ }
394+
395+
396+
397+
398+
288399
289400}// namespace libnhamiltonian
290401}// liblibra
0 commit comments