def update_vars(v_c, grad, nacmes, geo): dyn = initdyn() '''Update the variables and store them using vectorization''' pes = np.zeros(dyn.nstates) grads = np.zeros((geo.ndf, dyn.nstates)) nacs = np.zeros((geo.ndf, dyn.nstates, dyn.nstates)) for i in range( dyn.nstates): # Updates pes energy with the reference value (value corresponding to the initial geometry GS) pes[i] = v_c[i] - dyn.e_ref for n in range(dyn.nstates): idf = 0 for i in range(geo.natoms): for j in range(3): grads[idf, n] = (grad[j, i, n]) idf += 1 for n in range(dyn.nstates): for k in range(n + 1, dyn.nstates): idf = 0 for i in range(geo.natoms): for j in range(3): nacs[idf, n, k] = nacmes[j, i, n, k] # / np.sqrt(geo.masses[i]) nacs[idf, k, n] = -nacmes[j, i, n, k] # /np.sqrt(geo.masses[i]) idf += 1 '''Gradients are negative as we use them as forces''' return pes, -grads, nacs
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 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 create_input(trajN, istep, q, geo): ab = ab_par() ph = physconst() dyn = initdyn() if trajN == 0 and istep == 0: first = True else: first = False # Molpro input, it must be changed for other codes '''routine to create molpro input, valid for molpro2012''' file = 'molpro_traj_' + str(trajN) + '_' + str(istep) + '.inp' file2 = 'molpro_traj_' + str(trajN) + '_' + str(istep) + '.mld' # if first: r = transform_q_to_r(q, geo, first) # if istep==0 and trajN==0: # r=np.transpose(np.asarray([[7.0544201503E-01,-8.8768894715E-03,-6.6808940143E-03],[-6.8165975936E-01,1.7948934206E-02,4.0230273972E-03],[ 1.2640943417E+00,9.0767471618E-01,-3.0960211126E-02],[-1.4483835697E+00 ,8.7539956319E-01 ,4.6789959947E-02],[1.0430033100E+00,-9.0677165411E-01 ,8.1418967247E-02],[-1.1419988770E+00,-9.8436525752E-01,-6.5589218426E-02]])) with open(file, 'w') as f: f.write( '***,' + ab.molecule + ' ' + 'calculation of ' + str(istep) + ' step in trejectory ' + str(trajN) + '\n') line_wr_2 = 'file,2,' + str(trajN) + '.check.wfu,new\n' # f.write(line_wr_2) if first: line_wr = 'file,3,003.molpro.wfu,new\n' else: line_wr = 'file,3,003.molpro.wfu\n' f.write(line_wr) f.write('memory,100,m\n') f.write('''gprint,orbitals,civector,angles=-1,distance=-1 gthresh,twoint=1.0d-13 gthresh,energy=1.0d-7,gradient=1.0d-2 gthresh,thrpun=0.001\n''') f.write('punch,molpro.pun,new\n') f.write('basis=6-31g**\n') # f.write('basis={\n') # f.write(''' ! # ! HYDROGEN (4s,1p) -> [2s,1p] # s, H , 13.0100000, 1.9620000, 0.4446000 # c, 1.3, 0.0196850, 0.1379770, 0.4781480 # s, H , 0.1220000 # c, 1.1, 1.0000000 # p, H , 0.7270000 # c, 1.1, 1.0000000 # ! # ! # ! CARBON (9s,4p,1d) -> [3s,2p,1d] # s, C , 6665.0000000, 1000.0000000, 228.0000000, 64.7100000, 21.0600000, 7.4950000, 2.7970000, 0.5215000 # c, 1.8, 0.0006920, 0.0053290, 0.0270770, 0.1017180, 0.2747400, 0.4485640, 0.2850740, 0.0152040 # s, C , 6665.0000000, 1000.0000000, 228.0000000, 64.7100000, 21.0600000, 7.4950000, 2.7970000, 0.5215000 # c, 1.8, -0.0001460, -0.0011540, -0.0057250, -0.0233120, -0.0639550, -0.1499810, -0.1272620, 0.5445290 # s, C , 0.1596000 # c, 1.1, 1.0000000 # p, C , 9.4390000, 2.0020000, 0.5456000 # c, 1.3, 0.0381090, 0.2094800, 0.5085570 # p, C , 0.1517000 # c, 1.1, 1.0000000 # d, C , 0.5500000 # c, 1.1, 1.0000000 # } # ''') f.write('''symmetry,nosym; orient,noorient; angstrom; geomtype=xyz; geom={ ''') f.write(str(geo.natoms) + '\n') f.write('\n') for i in range(geo.natoms): line_wr = geo.atnames[i] + ' ' + str(r[0, i]) + ' ' + str(r[1, i]) + ' ' + str(r[2, i]) + '\n' # print(file) # print(line_wr) f.write(line_wr) f.write('}\n') f.write('''{multi,failsafe; maxiter,40; ''') line_wr = 'occ,' + str(ab.act_orb) + ';\n' line_wr2 = 'closed,' + str(ab.closed_orb) + ';\n' line_wr3 = 'wf,' + str(ab.n_el) + ',1,0;' line_wr4 = 'state,' + str(3) + ';\n' f.write(line_wr) f.write(line_wr2) f.write(line_wr3) f.write(line_wr4) f.write('''pspace,10.0 orbital,2140.3; ORBITAL,IGNORE_ERROR; ciguess,2501.2 save,ci=2501.2} ''') f.write('''data,copy,2140.3,3000.2 ''') f.write('''{multi,failsafe; maxiter,40; ''') line_wr = 'occ,' + str(ab.act_orb) + ';\n' line_wr2 = 'closed,' + str(ab.closed_orb) + ';\n' line_wr3 = 'wf,' + str(ab.n_el) + ',1,0;' line_wr4 = 'state,' + str(3) + ';\n' f.write(line_wr) f.write(line_wr2) f.write(line_wr3) f.write(line_wr4) f.write('''pspace,10.0 orbital,2140.3; dm,2140.3 save,ci=2501.2 diab,3000.2,save=2140.3} ''') f.write('''{multi,failsafe; maxiter,40; ''') line_wr = 'occ,' + str(ab.act_orb) + ';\n' line_wr2 = 'closed,' + str(ab.closed_orb) + ';\n' line_wr3 = 'wf,' + str(ab.n_el) + ',1,0;' line_wr4 = 'state,' + str(3) + ';\n' f.write(line_wr) f.write(line_wr2) f.write(line_wr3) f.write(line_wr4) f.write('''pspace,10.0 orbital,2140.3; dm,2140.3 save,ci=2501.2 diab,3000.2,save=2140.3 ''') record = 5100.1 for i in range(dyn.nstates): for j in range(i, dyn.nstates): if i == j: f.write('CPMCSCF,GRAD,' + str(i + 1) + '.1,record=' + str(record) + ';\n') record += 1 else: f.write('CPMCSCF,NACM,' + str(i + 1) + '.1,' + str(j + 1) + '.1,' + 'record=' + str(record) + ';\n') record += 1 f.write('}\n') record = 5100.1 for i in range(dyn.nstates): for j in range(i, dyn.nstates): if i == j: f.write('{FORCES;SAMC,' + str(record) + '};\n') record += 1 else: f.write('{FORCES;SAMC,' + str(record) + '};\n') record += 1 f.write('put,molden, ' + file2 + '\n') f.write('''---''') return file2
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
from src import swarm from src import branching as br 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*') ''' call initial geometry and dynamic parameters along with pyhisical constants''' dyn = initdyn() geo = singlepart() ph = physconst() T1 = initialize_traj.trajectory(1, 3, 1) q = np.zeros(3) q[0] = 4.00 p = np.zeros_like(q) T1.setposition_traj(q) T1.setmomentum_traj(p) T1.setpotential_traj(np.sum(geo.K * q**2 / 2)) T1.setderivs_traj(geo.K * (T1.getposition_traj()))