def poptraj(T1): dyn = initdyn() geo = initgeom() ph = physconst() pec, der = abinitio.inp_out(0, 0, geo, T1) # First ab-initio run T1.setpotential_traj(pec) # taking V(R) from ab-initio T1.setderivs_traj( der ) # derivatives matrix mass-weighted (possibly change that), diagonals are forces and off-d are nacmes T1.setmass_traj( geo.masses ) # mass of every atom in a.u (the dimmension is natoms/nparts) T1.setmassall_traj( geo.massrk ) # mass in every degree of freedom (careful to use it, it can triple the division/multiplication easily) amps = np.zeros(T1.nstates, dtype=np.complex128) amps[ dyn.inipes - 1] = 1.00 # Amplitudes of Ehrenfest trajectories, they should be defined as a=d *exp(im*S) T1.setamplitudes_traj(amps) phases = np.zeros( T1.nstates) # Phase of the wfn, would be S in the previous equation T1.setphases_traj(phases) T1.setwidth_traj(dyn.gamma) return T1
def overlap_trajs(T1, T2): geo = g.initgeom() w1 = T1.getwidth_traj() w2 = T2.getwidth_traj() ph1 = T1.getphase_traj() ph2 = T2.getphase_traj() ndim = T1.ndim S = np.exp(1j * (-ph1 + ph2), dtype=np.complex128) * np.complex128(1.000 + 0j) i = 0 for n in range(geo.natoms): for j in range(3): a1 = w1[n] a2 = w2[n] x1 = T1.getposition_traj()[i] x2 = T2.getposition_traj()[i] p1 = T1.getmomentum_traj()[i] p2 = T2.getmomentum_traj()[i] S = S * overlap_CG(x1, x2, p1, p2, a1, a2) i = i + 1 return S
def overlap_dp_traj(T1, T2): geo = g.initgeom() x1 = T1.getposition_traj() x2 = T2.getposition_traj() p1 = T1.getmomentum_traj() p2 = T2.getmomentum_traj() a1 = T1.getwidth_traj() a2 = T2.getwidth_traj() dx = x1 - x2 dp = p1 - p2 ndim = T1.ndim pref = np.zeros(ndim, dtype=np.complex128) i = 0 for n in range(geo.natoms): for j in range(3): pref[i] = 0.5 * (dp[i] + 2j * a1[n] * dx[i]) / (a1[n] + a2[n]) pref[i] *= overlap_CG(x1[i], x2[i], p1[i], p2[i], a1[n], a2[n]) i += 1 dpSij = pref return dpSij
def inittraj(): dyn = initdyn() geo = initgeom() ph = physconst() '''First initialize and populate one trajectory''' T1 = initialize_traj.trajectory(geo.natoms, 3, dyn.nstates) # qin, pin = Wigner_dist.WignerSampling() q = np.zeros(geo.ndf) p = np.zeros_like(q) with open('initialqp.dat', 'r') as f: f.readline() for i in range(geo.ndf): N, M = f.readline().strip().split() q[i] = np.double(float(N.replace('D', 'E'))) / np.sqrt( geo.massrk[i]) p[i] = np.double(float(M.replace('D', 'E'))) * np.sqrt( geo.massrk[i]) T1.setposition_traj(q + geo.rkinit) T1.setmomentum_traj(p) pec, der = abinitio.inp_out(0, 0, geo, T1) # First ab-initio run print(pec) T1.setpotential_traj(pec) # taking V(R) from ab-initio T1.setderivs_traj( der ) # derivatives matrix mass-weighted (possibly change that), diagonals are forces and off-d are nacmes T1.setmass_traj( geo.masses ) # mass of every atom in a.u (the dimmension is natoms/nparts) T1.setmassall_traj( geo.massrk ) # mass in every degree of freedom (careful to use it, it can triple the division/multiplication easily) amps = np.zeros(T1.nstates, dtype=np.complex128) amps[ dyn.inipes - 1] = 1.00 # Amplitudes of Ehrenfest trajectories, they should be defined as a=d *exp(im*S) T1.setamplitudes_traj(amps) phases = np.zeros( T1.nstates) # Phase of the wfn, would be S in the previous equation T1.setphases_traj(phases) T1.setwidth_traj(dyn._gamma) return T1
def calc_ekin_tr(T, ekin_tr): X = T.getposition_traj() X_old = T.getoldpos_traj() P = T.getmomentum_traj() P_old = T.getoldpos_traj() geo = geometry.initgeom() dyn = dyn_params.initdyn() dr_com = np.zeros(3) v_com = np.zeros_like(dr_com) k = 0 totmass = np.sum(geo.masses) dt = dyn.dt vel = np.zeros_like(P) for i in range(geo.natoms): for j in range(3): dr_com[j] += geo.masses[i] * (X[k] - X_old[k]) vel[k] = P[k] / geo.masses[i] k += 1 k = 0 for i in range(geo.natoms): for j in range(3): v_com[j] += vel[k] * geo.masses[i] / totmass k += 1 idf = 0 q_corr = np.zeros_like(X) p_corr = np.zeros_like(X) for i in range(geo.natoms): for j in range(3): # q_corr[idf] = X[idf] - dr_com[j] vel[idf] = vel[idf] - v_com[j] p_corr[idf] = vel[idf] * geo.masses[i] idf += 1 for i in range(3): ekin_tr = ekin_tr + 0.5 * (np.sqrt(totmass) * v_com[i])**2.0 T.setmomentum_traj(p_corr) # T.setposition_traj(q_corr) return T, ekin_tr
def overlap_dx_traj(T1, T2): geo = g.initgeom() sij = overlap_trajs(T1, T2) ndim = T1.ndim x1 = T1.getposition_traj() x2 = T2.getposition_traj() p1 = T1.getmomentum_traj() p2 = T2.getmomentum_traj() a1 = T1.getwidth_traj() a2 = T2.getwidth_traj() dxsij = np.zeros(ndim, dtype=np.complex128) i = 0 for n in range(geo.natoms): for j in range(3): dxsij[i] = overlap_dx_cg(x1[i], x2[i], p1[i], p2[i], a1[n], a2[n]) i += 1 #dxsij = dxsij * sij return dxsij
def overlap_ke_traj(T1, T2): geo = g.initgeom() ke = np.complex(0.0 + 0j) sij = overlap_trajs(T1, T2) ndim = T1.ndim x1 = T1.getposition_traj() x2 = T2.getposition_traj() p1 = T1.getmomentum_traj() p2 = T2.getmomentum_traj() a1 = T1.getwidth_traj() a2 = T2.getwidth_traj() i = 0 for n in range(geo.natoms): for j in range(3): ke -= overlap_d2x_cg(x1[i], x2[i], p1[i], p2[i], a1[n], a2[n]) / (2.0 * T1.allmass[i]) i = i + 1 ke = ke * sij ke = ke * np.dot(T1.getamplitude_traj(), T2.getamplitude_traj()) return ke
def velocityverlet(T, timestep, NN): geo = initgeom() ii = complex(0, 1.00) magnus_slice = 20 nst = T.nstates M = T.getmassall_traj() print(M) R0 = T.getposition_traj() P0 = T.getmomentum_traj() V0 = T.getvelocity_traj() FO = T.get_traj_force() E0 = T.getpotential_traj() A0 = T.getamplitude_traj() HE_0 = np.zeros((nst, nst), dtype=np.complex128) for n1 in range(nst): HE_0[n1, n1] = T.getpotential_traj_i(n1) for n2 in range(n1 + 1, nst): HE_0[n1, n2] = -ii * coupdotvel(T, n1, n2) HE_0[n2, n1] = -HE_0[n1, n2] nslice = magnus_slice Ab = A0 F0 = 0.0 for i in range(1, nslice + 1): dt = timestep / nslice A1 = np.matmul(magnus_2(-ii * HE_0, -ii * HE_0, dt), Ab) Ab = A1 F0 += T.get_traj_force() / nslice T.stateAmpE = A0 es0 = np.zeros(nst) fs0 = np.zeros((T.ndim, nst)) cs0 = np.zeros((T.ndim, nst, nst)) for i in range(nst): es0[i] = T.getpotential_traj_i(i) fs0[:, i] = T.getforce_traj(i) for j in range(nst): cs0[:, i, j] = T.getcoupling_traj(i, j) T.phase += timestep / 2.0 * T.phasedot() R1 = R0 + timestep * V0 + timestep**2 / 2.0 * F0 / M T.setposition_traj(R1) pes, der = ab.inp_out(NN, 0, geo, T) print('coupling before: ', T.getcoupling_traj(0, 1)) T.setderivs_traj(der) print('coupling after: ', T.getcoupling_traj(0, 1)) F1 = T.get_traj_force() T.setpotential_traj(pes) es1 = np.zeros(nst) fs1 = np.zeros((T.ndim, nst)) cs1 = np.zeros((T.ndim, nst, nst)) for i in range(nst): es1[i] = T.getpotential_traj_i(i) fs1[:, i] = T.getforce_traj(i) for j in range(nst): cs1[:, i, j] = T.getcoupling_traj(i, j) HE_1 = np.zeros_like(HE_0, dtype=np.complex128) for n1 in range(nst): HE_1[n1, n1] = T.getpotential_traj_i(n1) for n2 in range(n1 + 1, nst): HE_1[n1, n2] = -ii * coupdotvel(T, n1, n2) HE_1[n2, n1] = -HE_1[n1, n2] nslice = magnus_slice Ab = A0 F1 = 0.0 for n in range(1, nslice + 1): dt = timestep / nslice f_b = (n - 0.5) / np.double(float(nslice)) HE_b = (1.0 - f_b) * HE_0 + f_b * HE_1 esb = (1.0 - f_b) * es0 + f_b * es1 fsb = (1.0 - f_b) * fs0 + f_b * fs1 csb = (1.0 - f_b) * cs0 + f_b * cs1 A1 = np.matmul(magnus_2(-ii * HE_b, -ii * HE_b, dt), Ab) Ab = A1 T.stateAmpE = Ab T.HE = HE_1 fb = ip.compforce(T, A1, fsb, esb, csb) F1 += fb * 1.00 / nslice P1 = P0 + timestep * F1 T.setamplitudes_traj(Ab) T.setmomentum_traj(P1) T.phase += timestep / 2.0 * T.phasedot() T.setphases_traj(T.phase) T.setoldpos_traj(R0) T.setoldmom_traj(P0) return T
def readpun(): '''This routine reads a punch molpro file, it outputs as matrices the potential energies, gradients and non-adiabatic coupling matrices''' dyn = initdyn() geo = initgeom() v_c = np.zeros(dyn.nstates) grad = np.zeros((3, geo.natoms, dyn.nstates)) nacmes = np.zeros((3, geo.natoms, dyn.nstates, dyn.nstates)) pos = np.zeros((3, geo.natoms)) cis = np.zeros((40, 3)) CIV = True j = 0 configs = [] with open('molpro.pun', 'r') as f: cV = 0 cPes = 0 cNacs1 = 0 cNacs2 = cNacs1 + 1 readV = True for lines in f: if lines.startswith('ATOM'): string = lines.strip().split() atom = int(string[1]) - 1 pos[0, atom] = np.double(float(string[4])) pos[1, atom] = np.double(float(string[5])) pos[2, atom] = np.double(float(string[6])) if 'MCSCF STATE ' in lines and readV: string = lines.strip().split() if string[3] == 'Energy': v_c[cV] = np.double(float(string[4])) cV += 1 if cV == dyn.nstates: readV = False if 'SA-MC GRADIENT' in lines: string = lines.strip().split() atom = int(string[3].replace(':', '')) - 1 grad[0, atom, cPes] = np.double(float(string[4])) grad[1, atom, cPes] = np.double(float(string[5])) grad[2, atom, cPes] = np.double(float(string[6])) if atom == geo.natoms - 1: cPes += 1 if 'SA-MC NACME' in lines: string = lines.strip().split() atom = int(string[3].replace(':', '')) - 1 nacmes[0, atom, cNacs1, cNacs2] = np.double(float(string[4])) nacmes[1, atom, cNacs1, cNacs2] = np.double(float(string[5])) nacmes[2, atom, cNacs1, cNacs2] = np.double(float(string[6])) if atom == geo.natoms - 1: if cNacs2 == dyn.nstates - 1: cNacs1 += 1 else: cNacs2 += 1 if lines.startswith(' ') and CIV: ff = lines.strip().split() for i in range(3): cis[j, i] = float(ff[i + 1]) configs.append(ff[0]) j = j + 1 print(configs) total = len(configs) print('total CIS ',total) oneciv = int(total / 3) cis = cis[0:oneciv, :] configs = configs[0:oneciv] # for i in range(2): # for j in range(geo.natoms): # print(grad[0, j, i], grad[1, j, i], grad[2, j, i]) return v_c, grad, nacmes, cis, configs
def createswarm(ntraj, npart, ndim, numstates): geo = geometry.initgeom() trajs = [] Tinit = inittraj() Tinit.settrajid_traj(0) # trajs.append(Tinit) print(Tinit.PotEn) X = Tinit.getposition_traj() print(X) P = Tinit.getmomentum_traj() sigma = 0.1 p_norm = np.sqrt(np.sum(P**2)) for i in range(ntraj): T = initialize_traj.trajectory(npart=npart, ndim=ndim, numstates=numstates) n1 = np.random.rand() dx = sigma * (2 * n1 - 1.0) n2 = np.random.rand() dp = sigma / p_norm * (2 * n2 - 1) T.setposition_traj(X + dx) T.setmomentum_traj(P + dp) T.setamplitudes_traj(Tinit.getamplitude_traj()) T.setphases_traj(Tinit.getphase_traj()) T.setwidth_traj(Tinit.getwidth_traj()) print('widths:', T.getwidth_traj()) T.settrajid_traj(i) pec, der = abinitio.inp_out(0, 0, geo, T) # First ab-initio run T.setpotential_traj(pec) # taking V(R) from ab-initio T.setderivs_traj( der ) # derivatives matrix mass-weighted (possibly change that), diagonals are forces and off-d are nacmes T.setmass_traj( geo.masses ) # mass of every atom in a.u (the dimmension is natoms/nparts) T.setmassall_traj( geo.massrk ) # mass in every degree of freedom (careful to use it, it can triple the division/multiplication easily) trajs.append(T) B = bundle.bundle(ntraj, npart, ndim, numstates) B.setTraj_bundle(trajs) norm = B.get_calc_set_norm() for i in range(ntraj): B.Traj[i].amp = B.Traj[i].amp / cmath.sqrt(norm) B.setamps_bundle(B.getamps_bundle() / cmath.sqrt(norm)) print('Amplitudes before normalizing: ', B.getamps_bundle()) B = buildhs.buildsandh(B) Sif = np.zeros(ntraj, dtype=np.complex128) for i in range(ntraj): Sif[i] = ov.overlap_trajs(Tinit, B.Traj[i]) print('Overlaps: ', Sif) print('Sinv :', B.Sinv) Sif_2 = np.matmul(np.conj(B.Sinv), Sif) print('Overlaps*Sinv: ', Sif_2) B.setamps_bundle(Sif_2) norm = B.get_calc_set_norm() print('norm: ', norm) B.setamps_bundle(B.getamps_bundle() / np.sqrt(norm)) print('Final bundle amplitudes: ', B.getamps_bundle()) print('Norm Final bundle: ', np.linalg.norm(B.getamps_bundle())) print('Norm Final bundle branch: ', B.get_calc_set_norm()) return B
def velocityverlet(T, timestep, NN, calc1, phasewf): ab2 = ab_par() geo = initgeom() geo2 = singlepart() ii = np.complex128(0 + 1.00j) magnus_slice = 20 nst = T.nstates M = T.getmassall_traj() R0 = T.getposition_traj() P0 = T.getmomentum_traj() V0 = T.getvelocity_traj() A0 = T.getamplitude_traj() phase = T.getphase_traj() HE_0 = np.zeros((nst, nst), dtype=np.complex128) for n1 in range(nst): HE_0[n1, n1] = T.getpotential_traj_i(n1) for n2 in range(n1 + 1, nst): HE_0[n1, n2] = np.complex128(-ii * coupdotvel(T, n1, n2)) HE_0[n2, n1] = -HE_0[n1, n2] nslice = magnus_slice Ab = A0 F0 = 0.0 for i in range(0, nslice): dt = timestep / np.double(nslice) if T.nstates > 1: A1 = np.matmul(magnus_2(-ii * HE_0, -ii * HE_0, dt), Ab, dtype=np.complex128) else: A1 = magnus_2(-ii * HE_0, -ii * HE_0, dt) * Ab Ab = A1 T.setamplitudes_traj(A1) F0 += T.get_traj_force() / nslice T.setamplitudes_traj(A0) es0 = np.zeros(nst) fs0 = np.zeros((T.ndim, nst)) cs0 = np.zeros((T.ndim, nst, nst)) for i in range(nst): es0[i] = T.getpotential_traj_i(i) fs0[:, i] = T.getforce_traj(i) for j in range(nst): cs0[:, i, j] = T.getcoupling_traj(i, j) phase += timestep / 2.0 * T.phasedot() R1 = R0 + timestep * V0 + timestep**2.0 / 2.00 * F0 / M P1 = P0 + timestep * F0 oldcis = T.getcivecs() T.setoldpos_traj(R0) T.setoldmom_traj(P0) T_try = copy(T) T.setposition_traj(R1) T.setmomentum_traj(P1) if not calc1: pes, der, cis, configs = ab.inp_out(NN, 0, geo, T) else: pes = np.sum(0.5 * geo2.K * T.getposition_traj()**2) der = np.zeros(3) cis = 0 configs = 0 for i in range(3): der[i] = -geo2.K * T.getposition_traj()[i] T.setderivs_traj(der) T.setpotential_traj(pes) T.setcivecs(cis) T.setconfigs(configs) phasewf = T.getphasewf() ovs = np.zeros((T.nstates, T.nstates)) ov1, ov2 = ovwf(T_try, T) print('wfoverlaps', ov1, ov2) for n1 in range(T.nstates): for n2 in range(T.nstates): ovs[n1, n2] = (np.dot(T.getcivecs()[:, n1], oldcis[:, n2])) print(ovs[0, 0]) print(ovs[1, 1]) print(abs(ovs[0, 0]) + abs(ovs[1, 1]), abs(ovs[0, 1]) + abs(ovs[1, 0])) # if abs(ovs[0, 0]) + abs(ovs[1, 1]) < abs(ovs[0, 1]) + abs(ovs[1, 0]): # print('Trying to reduce timestep') # T.setposition_traj(T.getoldpos_traj()) # T.setmomentum_traj(T.getoldmom_traj()) # os.system('cp /home/AndresMoreno/wfu/002.molpro.wfu /home/AndresMoreno/wfu/003.molpro.wfu') # os.system('cp 002.molpro.wfu 003.molpro.wfu') # pes, der, cis = ab.inp_out(NN, 0, geo, T) # T.setderivs_traj(der) # T.setpotential_traj(pes) # T.setcivecs(cis) # print('momentum stored: ', T.getmomentum_traj()[0]) # print(T.getkineticlass() + T.getpotential_traj()) # # timestep = timestep / 2.00 # for ts in range(2): # T = velocityverlet(T, timestep, 120+ts, calc1, phasewf) # print('returning to the main routine') # return T print(T.getcivecs()[:, 1]) print(oldcis[:, 1]) for i in range(T.nstates): ovs = np.dot(T.getcivecs()[:, i], oldcis[:, i]) print(ovs) if abs(ovs) > 0.9: phasewf = phasewf * np.dot( T.getcivecs()[:, i], oldcis[:, i]) / np.abs( np.dot(T.getcivecs()[:, i], oldcis[:, i])) else: print('STEP TO CHECK; CI OVERLAP IS WRONG') changingindex = np.ones(np.size(T_try.configs)).astype(int) megamatrix1, M1, syms1 = readingmolden(T_try.getfilecalc()) megamatrix2, M2, syms2 = readingmolden(T.getfilecalc()) syms1 = (syms1[ab2.closed_orb:] - ab2.closed_orb).astype(int) syms2 = (syms2[ab2.closed_orb:] - ab2.closed_orb).astype(int) for nc in range(np.size(T_try.configs)): cfg = T.configs[nc] newcfg = '' for nstring in range(len(cfg)): newcfg += cfg[syms2[nstring]] index1 = T_try.configs.index(newcfg) changingindex[nc] = int(index1) print(index1) newCIs = T.getcivecs()[changingindex, :] print(oldcis[:, i]) print(newCIs[:, i]) print('changed CIvectors') ovs_2 = np.dot(newCIs[:, i], oldcis[:, i]) print('newoverlap: ', ovs_2) print('up to here') derivs = np.zeros((T.ndim, T.nstates, T.nstates)) for n1 in range(T.nstates): for n2 in range(T.nstates): if n1 != n2: derivs[:, n1, n2] = phasewf * T.getcoupling_traj(n1, n2) else: derivs[:, n1, n1] = T.getforce_traj(n1) T.setphasewf(phasewf) T.setderivs_traj(derivs) es1 = np.zeros(nst) fs1 = np.zeros((T.ndim, nst)) cs1 = np.zeros((T.ndim, nst, nst)) for i in range(nst): es1[i] = T.getpotential_traj_i(i) fs1[:, i] = T.getforce_traj(i) for j in range(nst): cs1[:, i, j] = T.getcoupling_traj(i, j) HE_1 = np.zeros_like(HE_0, dtype=np.complex128) for n1 in range(nst): HE_1[n1, n1] = T.getpotential_traj_i(n1) for n2 in range(n1 + 1, nst): HE_1[n1, n2] = np.complex128(-ii * coupdotvel(T, n1, n2)) HE_1[n2, n1] = -HE_1[n1, n2] nslice = magnus_slice Ab = A0 F1 = 0.0 for n in range(1, nslice + 1): dt = timestep / np.double(float(nslice)) f_b = (n - 0.5) / np.double(float(nslice)) HE_b = (1.0 - f_b) * HE_0 + f_b * HE_1 esb = (1.0 - f_b) * es0 + f_b * es1 fsb = (1.0 - f_b) * fs0 + f_b * fs1 csb = (1.0 - f_b) * cs0 + f_b * cs1 if T.nstates > 1: A1 = np.matmul(magnus_2(-ii * HE_b, -ii * HE_b, dt), Ab, dtype=np.complex128) else: A1 = magnus_2(-ii * HE_b, -ii * HE_b, dt) * Ab Ab = A1 T.setamplitudes_traj(A1) T.HE = HE_1 fb = T.compforce(A1, fsb, esb, csb) F1 += fb / np.double(float(nslice)) P1 = P0 + timestep * F1 T.setmomentum_traj(P1) phase += timestep / 2.0 * T.phasedot() ICycle = np.floor(phase / (2.0000 * np.pi)) phase = phase - 2.000 * np.pi * ICycle T.setphase_traj(phase) T.setoldpos_traj(R0) T.setoldmom_traj(P0) return T
def rkf45(T, dt, time, nstep): geo = initgeom() d = T.getd_traj() q = T.getposition_traj() p = T.getmomentum_traj() s = T.getphases_traj() A0 = T.getamplitude_traj() ii = np.complex128(0 + 1j) nstates = T.nstates masses = T.getmassall_traj() time = np.linspace(0, dt, 10) # Coefficients used to compute the independent variable argument of f a2 = 2.500000000000000e-01 # 1/4 a3 = 3.750000000000000e-01 # 3/8 a4 = 9.230769230769231e-01 # 12/13 a5 = 1.000000000000000e+00 # 1 a6 = 5.000000000000000e-01 # 1/2 # Coefficients used to compute the dependent variable argument of f b21 = 2.500000000000000e-01 # 1/4 b31 = 9.375000000000000e-02 # 3/32 b32 = 2.812500000000000e-01 # 9/32 b41 = 8.793809740555303e-01 # 1932/2197 b42 = -3.277196176604461e+00 # -7200/2197 b43 = 3.320892125625853e+00 # 7296/2197 b51 = 2.032407407407407e+00 # 439/216 b52 = -8.000000000000000e+00 # -8 b53 = 7.173489278752436e+00 # 3680/513 b54 = -2.058966861598441e-01 # -845/4104 b61 = -2.962962962962963e-01 # -8/27 b62 = 2.000000000000000e+00 # 2 b63 = -1.381676413255361e+00 # -3544/2565 b64 = 4.529727095516569e-01 # 1859/4104 b65 = -2.750000000000000e-01 # -11/40 # Coefficients used to compute local truncation error estimate. These # come from subtracting a 4th order RK estimate from a 5th order RK # estimate. r1 = 2.777777777777778e-03 # 1/360 r3 = -2.994152046783626e-02 # -128/4275 r4 = -2.919989367357789e-02 # -2197/75240 r5 = 2.000000000000000e-02 # 1/50 r6 = 3.636363636363636e-02 # 2/55 # Coefficients used to compute 4th order RK estimate c1 = 1.157407407407407e-01 # 25/216 c3 = 5.489278752436647e-01 # 1408/2565 c4 = 5.353313840155945e-01 # 2197/4104 c5 = -2.000000000000000e-01 # -1/5 n = len(time) a = 0.0 b = 2.5 t = a hmax = 1.25 h = hmax hmin = 0.01 tol = 1e-7 tol2 = 0.000001 T2 = T while t < b: T2 = T energy0 = T.getkineticlass() + T.getpotential_traj() print(h, energy0) if t + h > b: h = b - t qk1 = h * qdot(T) pk1 = h * pdot(T) dk1 = h * ddot(T) sk1 = h * sdot(T) T2.setposition_traj(q + qk1) T2.setmomentum_traj(p + pk1) T2.setd_traj(d + dk1) T2.setphases_traj(s + sk1) T2.setamplitudes_traj( T2.getd_traj() * np.exp(T2.getphases_traj() * 1j, dtype=np.complex128)) epot, derivs = ab.inp_out(nstep, 0, geo, T2) T.setderivs_traj(derivs) T.setpotential_traj(epot) qk2 = h * (qdot(T) + b21 * qk1) pk2 = h * (pdot(T) + b21 * pk1) dk2 = h * (ddot(T) + b21 * dk1) sk2 = h * (sdot(T) + b21 * sk1) T2.setposition_traj(q + qk2) T2.setmomentum_traj(p + pk2) T2.setd_traj(d + dk2) T2.setphases_traj(s + sk2) T2.setamplitudes_traj( T2.getd_traj() * np.exp(T2.getphases_traj() * 1j, dtype=np.complex128)) epot, derivs = ab.inp_out(nstep, 0, geo, T2) T.setderivs_traj(derivs) T.setpotential_traj(epot) qk3 = h * (qdot(T) + b31 * qk1 + b32 * qk2) pk3 = h * (pdot(T) + b31 * pk1 + b32 * pk2) dk3 = h * (ddot(T) + b31 * dk1 + b32 * dk2) sk3 = h * (sdot(T) + b31 * sk1 + b32 * sk2) T2.setposition_traj(q + qk3) T2.setmomentum_traj(p + pk3) T2.setd_traj(d + dk3) T2.setphases_traj(s + sk3) T2.setamplitudes_traj( T2.getd_traj() * np.exp(T2.getphases_traj() * 1j, dtype=np.complex128)) epot, derivs = ab.inp_out(nstep, 0, geo, T2) T.setderivs_traj(derivs) T.setpotential_traj(epot) qk4 = h * (qdot(T) + b41 * qk1 + b42 * qk2 + b43 * qk3) pk4 = h * (pdot(T) + b41 * pk1 + b42 * pk2 + b43 * pk3) dk4 = h * (ddot(T) + b41 * dk1 + b42 * dk2 + b43 * dk3) sk4 = h * (sdot(T) + b41 * sk1 + b42 * sk2 + b43 * sk3) T2.setposition_traj(q + qk4) T2.setmomentum_traj(p + pk4) T2.setd_traj(d + dk4) T2.setphases_traj(s + sk4) T2.setamplitudes_traj( T2.getd_traj() * np.exp(T2.getphases_traj() * 1j, dtype=np.complex128)) epot, derivs = ab.inp_out(nstep, 0, geo, T2) T.setderivs_traj(derivs) T.setpotential_traj(epot) qk5 = h * (qdot(T) + b51 * qk1 + b52 * qk2 + b53 * qk3 + b54 * qk4) pk5 = h * (pdot(T) + b51 * pk1 + b52 * pk2 + b53 * pk3 + b54 * pk4) dk5 = h * (ddot(T) + b51 * dk1 + b52 * dk2 + b53 * dk3 + b54 * dk4) sk5 = h * (sdot(T) + b51 * sk1 + b52 * sk2 + b53 * sk3 + b54 * sk4) T2.setposition_traj(q + qk5) T2.setmomentum_traj(p + pk5) T2.setd_traj(d + dk5) T2.setphases_traj(s + sk5) T2.setamplitudes_traj( T2.getd_traj() * np.exp(T2.getphases_traj() * 1j, dtype=np.complex128)) epot, derivs = ab.inp_out(nstep, 0, geo, T2) T.setderivs_traj(derivs) T.setpotential_traj(epot) qk6 = h * (qdot(T) + b61 * qk1 + b62 * qk2 + b63 * qk3 + b64 * qk4 + b65 * qk5) pk6 = h * (pdot(T) + b61 * pk1 + b62 * pk2 + b63 * pk3 + b64 * pk4 + b65 * pk5) dk6 = h * (ddot(T) + b61 * dk1 + b62 * dk2 + b63 * dk3 + b64 * dk4 + b65 * dk5) sk6 = h * (sdot(T) + b61 * sk1 + b62 * sk2 + b63 * sk3 + b64 * sk4 + b65 * sk5) T2.setposition_traj(q + qk6) T2.setmomentum_traj(p + pk6) T2.setd_traj(d + dk6) T2.setphases_traj(s + sk6) T2.setamplitudes_traj( T2.getd_traj() * np.exp(T2.getphases_traj() * 1j, dtype=np.complex128)) epot, derivs = ab.inp_out(nstep, 0, geo, T2) T.setderivs_traj(derivs) T.setpotential_traj(epot) rq = abs(r1 * qk1 + r3 * qk3 + r4 * qk4 + r5 * qk5 + r6 * qk6) / h rp = abs(r1 * qk1 + r3 * qk3 + r4 * qk4 + r5 * qk5 + r6 * qk6) / h energy2 = T2.getkineticlass() + T2.getpotential_traj() if len(np.shape(rq)) > 0: rq = max(rq) rp = max(rp) if abs(rp) <= tol2: t = t + h q = q + c1 * qk1 + c3 * qk3 + c4 * qk4 + c5 * qk5 p = p + c1 * pk1 + c3 * pk3 + c4 * pk4 + c5 * pk5 d = d + c1 * dk1 + c3 * dk3 + c4 * dk4 + c5 * dk5 s = s + c1 * sk1 + c3 * sk3 + c4 * sk4 + c5 * sk5 T.setposition_traj(q) T.setmomentum_traj(p) T.setamplitudes_traj(d * np.exp(s * 1j, dtype=np.complex128)) h = h * min(max(0.84 * (tol2 / rp)**0.25, 0.1), 4.0) if h > hmax: h = hmax elif h < hmin: print("Error: stepsize should be smaller than %e." % hmin) break print(h, q[0]) return T
def rk_method_4(T, dt, time, nstep): geo = initgeom() d = T.getd_traj() q = T.getposition_traj() p = T.getmomentum_traj() s = T.getphases_traj() a = T.getamplitude_traj() ii = np.complex128(0 + 1j) nslice = 20 nstates = T.nstates epot = T.PotEn ndf = T.ndim grad = np.zeros((nstates, ndf)) nacs = np.zeros((nstates, nstates, ndf)) masses = T.getmassall_traj() for i in range(nstates): grad[i, :] = T.getforce_traj(i) for j in range(nstates): nacs[i, j, :] = T.getcoupling_traj(i, j) '''first define the total energy and the d norm''' dnorm = 0.00 for i in range(nstates): dnorm = dnorm + np.abs(np.conj(d[i]) * d[i]) epot_av = 0.000 for i in range(nstates): epot_av += np.abs(np.conj(d[i]) * d[i]) * epot[i] ekin = np.sum(0.5 * p**2 / masses) tot_en = ekin + epot_av print('Total Energy:', tot_en) qk1 = dt * p / masses pk1 = dt * T.get_traj_force() d_dot = np.zeros(nstates, dtype=np.complex128) for i in range(nstates): for j in range(nstates): if i != j: nac1d = 0.0 for n in range(ndf): nac1d += p[n] / masses[n] * T.getcoupling_traj(j, i)[n] d_dot[i] = d_dot[i] - np.complex128(nac1d) * d[j] * np.exp( 1.0j * (s[j] - s[i]), dtype=np.complex128) dk1 = dt * d_dot s_dot = np.zeros(nstates, dtype=np.complex128) # Derivative of S (action) tmp = 0.0 for i in range(ndf): tmp += 0.5 * (p[i] / masses[i] * p[i] - q[i] * T.get_traj_force()[i]) for j in range(nstates): s_dot[j] = tmp - (0.5 * np.dot(p, p / masses) + epot[j]) sk1 = dt * s_dot T.setposition_traj(q + 0.5 * qk1) T.setmomentum_traj(p + 0.5 * pk1) T.setd_traj(d + 0.5 * dk1) T.setphases_traj(s + 0.5 * sk1) amps = T.getd_traj() * np.exp(1j * T.getphases_traj(), dtype=np.complex128) T.setamplitudes_traj(amps) epot, derivs = ab.inp_out(nstep, 0, geo, T) T.setderivs_traj(derivs) T.setpotential_traj(epot) p2 = T.getmomentum_traj() q2 = T.getposition_traj() # a2 = T.getamplitude_traj() d2 = T.getd_traj() s2 = T.getphases_traj() qk2 = dt * p2 / masses pk2 = dt * T.get_traj_force() d_dot = np.zeros(nstates, dtype=np.complex128) for i in range(nstates): for j in range(nstates): if i != j: nac1d = 0.0 for n in range(ndf): nac1d += p2[n] / masses[n] * T.getcoupling_traj(j, i)[n] d_dot[i] = d_dot[i] - np.complex128(nac1d) * d2[j] * np.exp( 1.0j * (s2[j] - s2[i]), dtype=np.complex128) dk2 = dt * d_dot s_dot = np.zeros(nstates, dtype=np.complex128) # Derivative of S (action) tmp = 0.0 for i in range(ndf): tmp += 0.5 * (p2[i] / masses[i] * p2[i] - q2[i] * T.get_traj_force()[i]) for j in range(nstates): s_dot[j] = tmp - (0.5 * np.dot(p2, p2 / masses) + epot[j]) sk2 = dt * s_dot T.setposition_traj(q + 0.5 * qk2) T.setmomentum_traj(p + 0.5 * pk2) T.setd_traj(d + 0.5 * dk2) T.setphases_traj(s + 0.5 * sk2) amps = T.getd_traj() * np.exp(1j * T.getphases_traj(), dtype=np.complex128) T.setamplitudes_traj(amps) epot, derivs = ab.inp_out(nstep, 0, geo, T) T.setderivs_traj(derivs) T.setpotential_traj(epot) p3 = T.getmomentum_traj() q3 = T.getposition_traj() d3 = T.getd_traj() s3 = T.getphases_traj() qk3 = dt * p3 / masses pk3 = dt * T.get_traj_force() d_dot = np.zeros(nstates, dtype=np.complex128) for i in range(nstates): for j in range(nstates): if i != j: nac1d = 0.0 for n in range(ndf): nac1d += p3[n] / masses[n] * T.getcoupling_traj(j, i)[n] d_dot[i] = d_dot[i] - np.complex128(nac1d) * d3[j] * np.exp( 1.0j * (s3[j] - s3[i]), dtype=np.complex128) dk3 = dt * d_dot s_dot = np.zeros(nstates, dtype=np.complex128) # Derivative of S (action) tmp = 0.0 for i in range(ndf): tmp += 0.5 * (p3[i] / masses[i] * p3[i] - q3[i] * T.get_traj_force()[i]) for j in range(nstates): s_dot[j] = tmp - (0.5 * np.dot(p3, p3 / masses) + epot[j]) sk3 = dt * s_dot T.setposition_traj(q + qk3) T.setmomentum_traj(p + pk3) T.setd_traj(d + dk3) T.setphases_traj(s + sk3) amps = T.getd_traj() * np.exp(1j * T.getphases_traj(), dtype=np.complex128) T.setamplitudes_traj(amps) epot, derivs = ab.inp_out(nstep, 0, geo, T) T.setderivs_traj(derivs) T.setpotential_traj(epot) p4 = T.getmomentum_traj() q4 = T.getposition_traj() d4 = T.getd_traj() s4 = T.getphases_traj() qk4 = dt * p4 / masses pk4 = dt * T.get_traj_force() d_dot = np.zeros(nstates, dtype=np.complex128) for i in range(nstates): for j in range(nstates): if i != j: nac1d = 0.0 for n in range(ndf): nac1d += p4[n] / masses[n] * T.getcoupling_traj(j, i)[n] d_dot[i] = d_dot[i] - np.complex128(nac1d) * d4[j] * np.exp( 1.0j * (s4[j] - s4[i]), dtype=np.complex128) dk4 = dt * d_dot s_dot = np.zeros(nstates, dtype=np.complex128) # Derivative of S (action) tmp = 0.0 for i in range(ndf): tmp += 0.5 * (p4[i] / masses[i] * p4[i] - q4[i] * T.get_traj_force()[i]) for j in range(nstates): s_dot[j] = tmp - (0.5 * np.dot(p4, p4 / masses) + epot[j]) sk4 = dt * s_dot T.setposition_traj(q + (qk1 + 2.000 * qk2 + 2.00 * qk3 + qk4) / 6.00) T.setmomentum_traj(p + (pk1 + 2.000 * pk2 + 2.00 * pk3 + pk4) / 6.00) T.setd_traj(d + (dk1 + 2.000 * dk2 + 2.00 * dk3 + dk4) / 6.00) T.setphases_traj(s + (sk1 + 2.000 * sk2 + 2.00 * sk3 + sk4) / 6.00) amps = T.getd_traj() * np.exp(1j * T.getphases_traj(), dtype=np.complex128) T.setamplitudes_traj(amps) return T
from src import buildhs import src.ekincorrection as ek print("Number of processors: ", mp.cpu_count()) '''AIMCE propagation''' ''' First, common variables are initialized using the class Traj, based on the dynamics and geometry inputs''' '''q,p initial values, taken from the wigner dist and d,s,a''' '''Remove previous files if needed''' os.system('rm molpro.pun') os.system('rm molpro_traj*') os.system('rm *.wfu') os.system('rm /home/AndresMoreno/wfu/*') ''' call initial geometry and dynamic parameters along with pyhisical constants''' dyn = initdyn() geo = initgeom() ph = physconst() '''First initialize and populate one trajectory''' T1 = initialize_traj.trajectory(geo.natoms, 3, dyn.nstates) # qin, pin = Wigner_dist.WignerSampling() q = np.zeros(geo.ndf) p = np.zeros_like(q) with open('initialqp_2.dat', 'r') as f: f.readline() for i in range(geo.ndf): N, M = f.readline().strip().split() q[i] = np.double(float(N.replace('D', 'E'))) p[i] = np.double(float(M.replace('D', 'E'))) T1.setposition_traj(q)