def molpro_mcscf(filename, select_run=0, threshold=0.0, **kwargs): '''Reads MOLPRO MCSCF output. **Parameters:** filename : str Specifies the filename for the input file. select_run : (list of) int Specifies the MCSCF calculation (1PROGRAM * MULTI) to be read. For the selected MCSCF calculation, all electronic states will be read. threshold : float, optional Specifies a read threshold for the CI coefficients. **Returns:** ci : list of CIinfo class instances See :ref:`Central Variables` for details. ..ATTENTION: Changed return value to list of CI classes ''' display('\nReading data of MCSCF calculation from MOLPRO...') method = 'mcscf' available = {'mcscf': 'MULTI'} single_run_selected = isinstance(select_run, int) count = 0 numci = [] # Go through the file line by line with open(filename) as fileobject: for line in fileobject: if '1PROGRAM * %s' % available[method] in line: count += 1 numci.append(0) if '!%s state' % method in line.lower() and 'energy' in line.lower( ): numci[-1] += 1 if count == 0: display( 'The input file %s does not contain any DETCI calculations!\n' % (filename) + 'It does not contain the keyword:\n\t1PROGRAM * MULTI') raise IOError('Not a valid input file') else: string = ', '.join(map(str, numci)).rsplit(', ', 1) string = ' and '.join(string) if len( string[0].split(',')) < 2 else ', and '.join(string) display('The input file %s contains' % (filename)) display('%d MCSCF calculation(s) with %s root(s)%s.' % (count, string, ', respectively' if len(numci) > 1 else '')) if select_run is None: select_run = numpy.arange(count) if isinstance(select_run, int) and 0 <= select_run < count: select_run = [select_run] ci = [[]] elif isinstance(select_run, (list, numpy.ndarray)): ci = [] for i in select_run: ci.append([]) if not isinstance(i, int): raise IOError( str(i) + ' is not a valid selection for select_run') else: raise IOError( str(select_run) + ' is a not valid selection for select_run') select_run = numpy.array(select_run) display('\tYour selection (counting from zero): %s' % ', '.join(map(str, select_run))) general_information = {'fileinfo': filename, 'read_threshold': threshold} ci_skip = 0 count = 0 count_runs = 0 min_c = 1 start_reading = False sec_flag = False info_flag = False info_sep = False info_split = False occ_types = ['core', 'closed', 'active', 'external'] with open(filename) as fileobject: for line in fileobject: thisline = line.split() # The current line split into segments if '1PROGRAM *' in line: start_reading = False #--- Number of IRREPs if 'Point group' in line or '_PGROUP' in line: nIRREP = point_groups()[thisline[-1].lower()] rhf_occ = numpy.zeros(nIRREP, dtype=numpy.intc) #--- RHF occupation elif 'Final occupancy:' in line: c_occ = line.split()[2:] for ii in range(len(c_occ)): rhf_occ[ii] = int(c_occ[ii]) #--- A MCSCF Calculation starts --- elif '1PROGRAM * %s' % available[method] in line: occ_info = {} for i in occ_types: occ_info[i] = numpy.zeros(nIRREP, dtype=numpy.intc) state_info = [] i = numpy.argwhere(select_run == count_runs) if len(i) > 0: index_run = int(i) start_reading = True count = 0 old = 0 count_runs += 1 elif start_reading: #--- Active space --- if 'Number of ' in line and 'orbitals:' in line: line = line.replace('(', '').replace(')', '').replace('-shell', '') c_occ = numpy.array(line.split()[-nIRREP:], dtype=numpy.intc) occ_info[line.split()[2]] += c_occ elif 'State symmetry' in line: fileobject.next() thisline = fileobject.next() if 'State symmetry' in thisline: fileobject.next() thisline = fileobject.next() thisline = thisline.replace('=', ' ').split() data = { 'nel': thisline[3], 'spin': thisline[6], 'sym': thisline[9] } thisline = fileobject.next().split() state_info.extend([data for i in range(int(thisline[-1]))]) elif '!%s state' % method in line.lower( ) and 'energy' in line.lower(): ci[index_run].append(CIinfo(method=method)) info = state_info[count] thisline = line.lower().replace('state', 'state ').split() ci[index_run][count].info = copy(general_information) ci[index_run][count].info['fileinfo'] += '@%d' % index_run ci[index_run][count].info['state'] = thisline[2] ci[index_run][count].info['energy'] = float(thisline[4]) ci[index_run][count].info['spin'] = info['spin'] ci[index_run][count].info['nel'] = info['nel'] ci[index_run][count].info['occ_info'] = occ_info count += 1 elif 'CI vector' in line: sec_flag = 'mcscf' info_split = ' ' ci_skip = 3 info = thisline[-1] count = old first = True if not ci_skip: if line == '\n' or '/EOF' in line: sec_flag = False elif sec_flag != False: split_line = filter(None, line.split(info_split)) if len(split_line) > 1: occupation = numpy.zeros( (numpy.sum(occ_info['active']), 2), dtype=numpy.intc) for i, j in enumerate(split_line[0].replace( ' ', '')): if j == '2': occupation[i, :] = 1 elif j == 'a': occupation[i, 0] = 1 elif j == 'b': occupation[i, 1] = 1 c0 = 0 coeffs = split_line[-1].split() for i, j in enumerate(coeffs): if first: old += 1 min_c = min(min_c, abs(float(j))) if abs(float(j)) > threshold: ci[index_run][count + c0 + i].coeffs.append( float(j)) ci[index_run][count + c0 + i].occ.append(occupation) c0 += len(coeffs) first = False else: ci_skip -= 1 #--- Calculating norm of CI states display('\nIn total, %d states have been read.' % sum([len(i) for i in ci])) display('Norm of the states:') for i in range(len(ci)): for j in range(len(ci[i])): ci[i][j].coeffs = numpy.array(ci[i][j].coeffs) ci[i][j].occ = numpy.array(ci[i][j].occ, dtype=numpy.intc) norm = sum(ci[i][j].coeffs**2) # Write Norm to log-file display('\tState %s (%s):\tNorm = %0.8f (%d Coefficients)' % (ci[i][j].info['state'], ci[i][j].info['spin'], norm, len(ci[i][j].coeffs))) display('') if min_c > threshold: display( '\nInfo:' + '\n\tSmallest coefficient (|c|=%f) larger than the read threshold (%f).' % (min_c, threshold) + '\n\tUse `gthresh, printci=0.0` in the MOLPRO input file to print ' + 'all CI coefficients.\n') #if single_run_selected and len(ci) == 1: #ci = ci[0] ci_new = [] for i in ci: ci_new.extend(i) return ci_new
def gaussian_tddft(fname,select_state=None,threshold=0.0,**kwargs): '''Reads Gaussian16 TDDFT output. **Parameters:** fname: str, file descriptor Specifies the filename for the input file. fname can also be used with a file descriptor instad of a filename. select_state : None or list of int, optional If not None, specifies the states to be read (0 corresponds to the ground state), else read all electronic states. threshold : float, optional Specifies a read threshold for the CI coefficients. **Returns:** ci : list of CIinfo class instances See :ref:`Central Variables` for details. ''' display('\nReading data of TDDFT calculation from Gaussian...') # Initialize variables ci = [] ci_flag = False prttol = False init_state = False rhfspin = 0 spin = 'Unknown' nel = 0 deex = [] if isinstance(select_state,int): select_state = [select_state] if isinstance(fname, str): filename = fname fname = descriptor_from_file(filename, index=0, ci_descriptor=True) else: filename = fname.name for line in fname: thisline = line.split() # The current line split into segments #--- Check the file for keywords --- # Initialize Hartree-Fock ground state if ' SCF Done: E(' in line: ci.append(CIinfo(method='tddft')) ci[-1].info = [] ci[-1].coeffs = [] ci[-1].occ = [] ci[-1].occ.append([0,0]) ci[-1].coeffs.append(1.0) ci[-1].info = {'state': '0', 'energy': float(thisline[4]), 'energy_nm': 0.0, 'fileinfo': filename, 'read_threshold': threshold, 'spin': spin, 'f_0i': 0.0} # Initialize new excited state elif ' Excited State' in line and 'eV' in line and 'nm' in line: if select_state is None or int(thisline[2].replace(':',' ')) in select_state: init_state = True tddft_skip = 1 ci.append(CIinfo(method='tddft')) ci[-1].info = [] ci[-1].coeffs = [] ci[-1].occ = [] ci[-1].info = {'state': thisline[2][:-1], 'energy': float(thisline[-6])*ev_to_ha + ci[0].info['energy'], 'energy_nm': float(thisline[-4]), 'fileinfo': filename, 'read_threshold': threshold, 'spin': thisline[3].split('-')[0], 'f_0i': float(thisline[8].replace('=',' ').split()[-1])} deex.append([]) if init_state == True: if not tddft_skip: if thisline == [] or '->' not in line and '<-' not in line: init_state = False else: if '->' in line: thisline = line.replace('->','-> ').split() if abs(float(thisline[-1])) > threshold: tmp_occ = [thisline[0],thisline[2]] ci[-1].occ.append(tmp_occ) ci[-1].coeffs.append(float(thisline[-1])*numpy.sqrt(2)) elif '<-' in line: deex[-1].append(float(thisline[-1])*numpy.sqrt(2)) elif tddft_skip: tddft_skip -= 1 fname.close() deex = numpy.array(deex) #--- Calculating norm of CI states display('\nIn total, %d states have been read.' % len(ci)) display('Norm of the states:') for i in range(len(ci)): j = numpy.array(ci[i].coeffs,dtype=float) norm = numpy.sum(j**2) ci[i].coeffs = j # Write Norm to log-file display('\tState %s:\tNorm = %0.8f (%d Coefficients)' % (ci[i].info['state'],norm, len(ci[i].coeffs))) # Transform to numpy arrays ci[i].occ = numpy.array([s for s in ci[i].occ],dtype=numpy.intc)-1 return ci
def gamess_cis(filename, select_state=None, threshold=0.0, **kwargs): '''Reads GAMESS-US CIS output. **Parameters:** filename : str Specifies the filename for the input file. select_state : None or list of int, optional If not None, specifies the states to be read (0 corresponds to the ground state), else read all electronic states. threshold : float, optional Specifies a read threshold for the CI coefficients. **Returns:** ci : list of CIinfo class instances See :ref:`Central Variables` for details. ''' display('\nReading data of CIS calculation from GAMESS-US...') # Initialize variables ci = [] ci_flag = False prttol = False init_state = False rhfspin = 0 min_c = -1 if isinstance(select_state, int): select_state = [select_state] with open(filename) as fileobject: for line in fileobject: thisline = line.split() # The current line split into segments #--- Check the file for keywords --- # Initialize Hartree-Fock ground state if 'NUMBER OF ELECTRONS' in line and "=" in line: nel = int(thisline[-1]) elif 'SPIN MULTIPLICITY' in line: rhfspin = int(thisline[-1]) elif ' FINAL RHF ENERGY IS' in line and (select_state is None or 0 in select_state): ci.append(CIinfo(method='cis')) ci[-1].info = [] ci[-1].coeffs = [] ci[-1].occ = [] ci[-1].occ.append([0, 0]) ci[-1].coeffs.append(1.0) ci[-1].info = { 'state': '0', 'energy': float(thisline[4]), 'fileinfo': filename, 'read_threshold': threshold, 'spin': multiplicity()[rhfspin], 'nel': nel } # Printing parameter elif ' PRINTING CIS COEFFICIENTS LARGER THAN' in line: min_c = float(thisline[-1]) # Initialize new excited state elif ' EXCITED STATE ' in line and 'ENERGY=' and 'SPACE SYM' in line: if select_state is None or int(thisline[2]) in select_state: init_state = True cis_skip = 6 ci.append(CIinfo(method='cis')) ci[-1].info = [] ci[-1].coeffs = [] ci[-1].occ = [] ci[-1].info = { 'state': thisline[2], 'energy': float(thisline[4]), 'fileinfo': filename, 'read_threshold': threshold, 'spin': multiplicity()[int(2 * float(thisline[7]) + 1)], 'nel': nel } if init_state == True: if not cis_skip: if '----------------------------------------------' in line: init_state = False else: if abs(float(thisline[2])) > threshold: ci[-1].occ.append(thisline[:2]) ci[-1].coeffs.append(thisline[2]) elif cis_skip: cis_skip -= 1 #--- Calculating norm of CI states display('\nIn total, %d states have been read.' % len(ci)) display('Norm of the states:') for i in range(len(ci)): j = numpy.array(ci[i].coeffs, dtype=float) norm = numpy.sum(j**2) ci[i].coeffs = j # Write Norm to log-file display('\tState %s:\tNorm = %0.8f (%d Coefficients)' % (ci[i].info['state'], norm, len(ci[i].coeffs))) # Transform to numpy arrays ci[i].occ = numpy.array([s for s in ci[i].occ], dtype=numpy.intc) - 1 display('') if min_c > threshold: display( '\nInfo:' + '\n\tSmallest coefficient (|c|=%f) is larger than the read threshold (%f).' % (min_c, threshold) + '\n\tUse `PRTTOL=0.0` in the `$CIS` input card to print ' + 'all CI coefficients.\n') return ci
def gamess_tddft(fname, select_state=None, threshold=0.0, **kwargs): '''Reads GAMESS-US TDDFT output. **Parameters:** fname: str, file descriptor Specifies the filename for the input file. fname can also be used with a file descriptor instad of a filename. select_state : None or list of int, optional If not None, specifies the states to be read (0 corresponds to the ground state), else read all electronic states. threshold : float, optional Specifies a read threshold for the CI coefficients. **Returns:** ci : list of CIinfo class instances See :ref:`Central Variables` for details. ''' display('\nReading data of TDDFT calculation from GAMESS-US...') # Initialize variables ci = [] ci_flag = False prttol = False init_state = False rhfspin = 0 spin = 'Unknown' if isinstance(select_state, int): select_state = [select_state] if isinstance(fname, str): filename = fname fname = descriptor_from_file(filename, index=0, ci_descriptor=True) else: filename = fname.name for line in fname: thisline = line.split() # The current line split into segments #--- Check the file for keywords --- # Initialize Hartree-Fock ground state if 'NUMBER OF ELECTRONS' in line: nel = int(thisline[-1]) elif 'SPIN MULTIPLICITY' in line: rhfspin = int(thisline[-1]) elif 'SINGLET EXCITATIONS' in line: spin = 'Singlet' #elif ' FINAL RHF ENERGY IS' in line and (select_state is None or 0 in select_state): elif ' FINAL' in line and ' ENERGY IS' in line and ( select_state is None or 0 in select_state): ci.append(CIinfo(method='tddft')) ci[-1].info = [] ci[-1].coeffs = [] ci[-1].occ = [] ci[-1].occ.append([0, 0]) ci[-1].coeffs.append(1.0) ci[-1].info = { 'state': '0', 'energy': float(thisline[4]), 'fileinfo': filename, 'read_threshold': threshold, 'spin': spin, 'nel': nel } # Initialize new excited state elif 'STATE #' in line and 'ENERGY =' in line: if select_state is None or int(thisline[2]) in select_state: init_state = True tddft_skip = 8 ci.append(CIinfo(method='cis')) ci[-1].info = [] ci[-1].coeffs = [] ci[-1].occ = [] ci[-1].info = { 'state': thisline[2], 'energy': float(thisline[-2]) * ev_to_ha + ci[0].info['energy'], 'fileinfo': filename, 'read_threshold': threshold, 'spin': 'Unknown', 'nel': nel } if init_state == True and line != '\n' and 'WARNING:' not in line: if not tddft_skip: if 'NON-ABELIAN' in line or 'SUMMARY' in line or 'SYMMETRY' in line or 'STATE #' in line: init_state = False else: if abs(float(thisline[2])) > threshold: ci[-1].occ.append(thisline[:2]) ci[-1].coeffs.append(thisline[2]) elif tddft_skip: tddft_skip -= 1 fname.close() #--- Calculating norm of CI states display('\nIn total, %d states have been read.' % len(ci)) display('Norm of the states:') for i in range(len(ci)): j = numpy.array(ci[i].coeffs, dtype=float) norm = numpy.sum(j**2) ci[i].coeffs = j # Write Norm to log-file display('\tState %s:\tNorm = %0.8f (%d Coefficients)' % (ci[i].info['state'], norm, len(ci[i].coeffs))) # Transform to numpy arrays ci[i].occ = numpy.array([s for s in ci[i].occ], dtype=numpy.intc) - 1 return ci
def psi4_detci(filename,select_run=None,threshold=0.0,**kwargs): '''Reads PSI4 DETCI output. **Parameters:** filename : str Specifies the filename for the input file. select_run : (list of) int Specifies the DETCI calculation (D E T C I) to be read. For the selected DETCI calculation, all electronic states will be read. threshold : float, optional Specifies a read threshold for the CI coefficients. **Returns:** ci : list of CIinfo class instances See :ref:`Central Variables` for details. ..#ATTENTION: Changed return value to list of CI classes ''' display('\nReading data of DETCI calculation from PSI4...') count = 0 numci = [] # Go through the file line by line with open(filename) as fileobject: for line in fileobject: if 'D E T C I' in line: count += 1 numci.append(0) if '* ROOT' in line: numci[-1] += 1 if count == 0: display('The input file %s does not contain any DETCI calculations!\n' % (filename) + 'It does not contain the keyword:\n\tD E T C I') raise IOError('Not a valid input file') else: string = ', '.join(map(str,numci)).rsplit(', ',1) string = ' and '.join(string) if len(string[0].split(',')) < 2 else ', and '.join(string) display('The input file %s contains' % (filename)) display('%d DETCI calculation(s) with %s root(s)%s.'%(count, string, ', respectively' if len(numci)>1 else '')) if select_run is None: select_run = numpy.arange(count) if isinstance(select_run,int) and 0 <= select_run < count: select_run = [select_run] ci = [[]] elif isinstance(select_run,(list,numpy.ndarray)): ci = [] for i in select_run: ci.append([]) if not isinstance(i,int): raise IOError(str(i) + ' is not a valid selection for select_run') else: raise IOError(str(select_run) + ' is a not valid selection for select_run') select_run = numpy.array(select_run) display('\n\tYour selection (counting from zero): %s' % ', '.join(map(str,select_run))) general_information = {'fileinfo': filename, 'read_threshold': threshold} ci_skip = 0 count = 0 count_runs = 0 min_c = 1 orbs_in_ci = 0 start_reading = False occ_types = ['core','closed','active','external'] synonyms = {'frozen docc': 'core', 'restricted docc': 'closed', 'ras ': 'active', 'active': 'active', 'restricted uocc': 'external', 'frozen uocc': 'external'} irreps = [] fist_active_mo = [] index_active_mo = [] occ_symbols = {'A': numpy.array([1,0]), 'B': numpy.array([0,1]), 'X': numpy.array([1,1])} with open(filename) as fileobject: for line in fileobject: thisline = line.split() # The current line split into segments if 'Running in ' in line and 'symmetry.' in line: nIRREP = point_groups()[thisline[2].lower()] rhf_occ = numpy.zeros(nIRREP,dtype=numpy.intc) #--- RHF occupation elif 'Final Occupation by Irrep:' in line: irreps = fileobject.next().split() line = fileobject.next() c_occ = line.replace(',','').split()[2:-1] for ii in range(len(c_occ)): rhf_occ[ii] = int(c_occ[ii]) #--- A DETCI Calculation starts --- elif 'D E T C I' in line: occ_info = {} for i in occ_types: occ_info[i] = numpy.zeros(nIRREP,dtype=numpy.intc) info = {} num_roots = 0 method = 'detci' i = numpy.argwhere(select_run == count_runs) if len(i) > 0: index_run = int(i) start_reading = True count_runs += 1 elif start_reading: if 'NUM ROOTS =' in line: num_roots = int(thisline[3]) elif 'FCI =' in line and line.endswith('yes'): method = 'fci' elif 'REF SYM =' in line: info['sym'] = thisline[3] if info['sym'] != 'auto': info['sym'] = irreps[int(info['sym'])] elif 'S =' in line: info['spin'] = multiplicity()[int(2*float(thisline[2])+1)] elif 'NUM ALP =' in line: info['nel'] = int(thisline[3]) + int(thisline[-1]) elif 'ORBS IN CI =' in line: orbs_in_ci = int(thisline[-1]) elif '=' in line and any([i in line.lower() for i in synonyms.keys()]): for i in synonyms.keys(): if i in line.lower(): occ_info[synonyms[i]] += numpy.array(thisline[-nIRREP:], dtype=numpy.intc) elif '* ROOT' in line and 'CI total energy' in line: ci[index_run].append(CIinfo(method=method)) ci[index_run][-1].info = copy(general_information) ci[index_run][-1].info['fileinfo'] += '@%d' % index_run ci[index_run][-1].info['irreps'] = irreps ci[index_run][-1].info['state'] = '%s.%s'%(thisline[2],info['sym']) ci[index_run][-1].info['energy'] = float(thisline[7]) ci[index_run][-1].info['spin'] = info['spin'] ci[index_run][-1].info['nel'] = info['nel'] ci[index_run][-1].info['occ_info'] = occ_info closed = [] active = {} c = 0 for i in range(nIRREP): a = occ_info['core'][i] + occ_info['closed'][i] for b in range(occ_info['active'][i]): active['%d%s' % (a+b+1,irreps[i])] = c c += 1 elif 'most important determinants' in line: num_det = int(thisline[1]) ci[index_run][-1].coeffs = [] # numpy.zeros(num_det) ci[index_run][-1].occ = [] # numpy.zeros((numpy.sum(occ_info['active']),2), #dtype=numpy.intc) fileobject.next() def rm(s,w='*(,)'): for i in w: s = s.replace(i,' ') return s for i in range(num_det): thisline = rm(fileobject.next()).split() if thisline == []: break min_c = min(min_c,abs(float(thisline[1]))) if abs(float(thisline[1])) > threshold: ci[index_run][-1].coeffs.append(float(thisline[1])) ci[index_run][-1].occ.append(numpy.zeros((numpy.sum(occ_info['active']),2), dtype=numpy.intc)) for j in thisline[4:]: ci[index_run][-1].occ[-1][active[j[:-1]]] = occ_symbols[j[-1]] ci[index_run][-1].coeffs = numpy.array(ci[index_run][-1].coeffs) ci[index_run][-1].occ = numpy.array(ci[index_run][-1].occ,dtype=numpy.intc) elif 'A good bug is a dead bug' in line: start_reading = False #--- Calculating norm of CI states display('\nIn total, %d states have been read.' % sum([len(i) for i in ci])) display('Norm of the states:') for i in range(len(ci)): for j in range(len(ci[i])): norm = sum(ci[i][j].coeffs**2) display('\tState %s (%s):\tNorm = %0.8f (%d Coefficients)' % (ci[i][j].info['state'],ci[i][j].info['spin'], norm,len(ci[i][j].coeffs))) display('') if threshold and min_c > threshold: display('\nInfo:'+ '\n\tSmallest coefficient (|c|=%f) larger than the read threshold (%f).' %(min_c,threshold) + '\n\tUse `set num_dets_print -1` in the PSI4 input file to print ' + 'all CI coefficients.\n') ci_new = [] for i in ci: ci_new.extend(i) return ci_new
def fermions_tdscf(fname, td_typ='rpa', st_typ='singlet', select_state=None, threshold=0.0, **kwargs): '''Reads FermiONs++ TDDFT output. **Parameters:** fname: str, file descriptor Specifies the filename for the input file. fname can also be used with a file descriptor instad of a filename. select_state : None or list of int, optional If not None, specifies the states to be read (0 corresponds to the ground state), else read all electronic states. threshold : float, optional Specifies a read threshold for the CI coefficients. **Returns:** ci : list of CIinfo class instances See :ref:`Central Variables` for details. ''' display('\nReading data of TDDFT calculation from FermiONs++...') # # future user-input... # sst = 'Singlets' fspin = 1.0 if st_typ == 'triplet': fspin = 3.0 sst = 'Triplets' ss0 = '' if td_typ == 'tda': ss0 = 'Tamm-Dancoff Excitation Energies [%s]' % sst elif td_typ == 'rpa': ss0 = 'RPA Excitation Energies [%s]' % sst elif td_typ == 'stda': ss0 = 'Simplified Tamm-Dancoff Excitation Energies [%s]' % sst elif td_typ == 'srpa': ss0 = 'Simplified RPA Excitation Energies [%s]' % sst nocca = -1 noccb = -1 # Initialize variables ci = [] ci_flag = False prttol = False init_state = False rhfspin = 0 spin = 'Unknown' nel = 0 deex = [] if isinstance(select_state, int): select_state = [select_state] if isinstance(fname, str): filename = fname fname = descriptor_from_file(filename, index=0, ci_descriptor=True) else: filename = fname.name st = 0 for line in fname: thisline = line.split() # The current line split into segments #--- Check the file for keywords --- # Initialize Hartree-Fock ground state if 'No. of alpha-electrons:' in line: nocca = int(line.split()[3]) elif 'No. of beta-electrons:' in line: noccb = int(line.split()[3]) elif 'Final SCF energy:' in line: ci.append(CIinfo(method='tddft')) ci[-1].info = [] ci[-1].coeffs = [] ci[-1].occ = [] ci[-1].occ.append([0, 0]) ci[-1].coeffs.append(1.0) ci[-1].info = { 'state': '0', 'energy': float(thisline[3]), 'energy_nm': 0.0, 'fileinfo': filename, 'read_threshold': threshold, 'spin': spin, 'f_0i': 0.0 } # Initialize new excited state if st == 0: # look for RPA if ss0 in line: st = 1 elif st == 1: if 'Converged' in line and '==' in line: st = 2 elif st == 2: if 'Excited State' in line: # and 'eV' in line and 'nm' in line: if select_state is None or int(thisline[2]) in select_state: init_state = True tddft_skip = 1 ci.append(CIinfo(method='tddft')) ci[-1].info = [] ci[-1].coeffs = [] ci[-1].occ = [] ci[-1].info = { 'state': thisline[2], 'energy': 0.0, #float(thisline[-6])*ev_to_ha + ci[0].info['energy'], 'energy_nm': 0.0, #float(thisline[-4]), 'fileinfo': filename, 'read_threshold': threshold, 'spin': fspin, #thisline[3].split('-')[0], 'f_0i': 0.0 } #float(thisline[8].replace('=',' ').split()[-1])} deex.append([]) if init_state == True: if not tddft_skip: if 'Excitation Energy:' in line: ci[-1].info['energy'] = float( thisline[2]) * ev_to_ha + ci[0].info['energy'] elif ' nm' in line: ci[-1].info['energy_nm'] = float(thisline[0]) # 'spin': thisline[3].split('-')[0], elif len( line.strip() ) == 0: #thisline == [] or '->' not in line and '<-' not in line: init_state = False else: if '<-->' in line: if abs(float(thisline[-2])) > threshold: ex = thisline[-2] dex = thisline[-2] thisline = line.split( '<-->') #replace('->','-> ').split() s0 = thisline[0].split('(')[1].split( ')')[0].strip() nocc = nocca if 'beta' in line: nocc = noccb s1 = int(thisline[1].split('(')[1].split(')') [0].strip()) + nocc tmp_occ = [s0, '%i' % s1] ci[-1].occ.append(tmp_occ) ci[-1].coeffs.append(float(ex) * numpy.sqrt(2)) deex[-1].append(float(dex) * numpy.sqrt(2)) elif tddft_skip: tddft_skip -= 1 if '-------------------' in line or 'Excite Total:' in line: st = 3 fname.close() deex = numpy.array(deex) #--- Calculating norm of CI states display('\nIn total, %d states have been read.' % len(ci)) display('Norm of the states:') for i in range(len(ci)): j = numpy.array(ci[i].coeffs, dtype=float) norm = numpy.sum(j**2) ci[i].coeffs = j # Write Norm to log-file display('\tState %s:\tNorm = %0.8f (%d Coefficients)' % (ci[i].info['state'], norm, len(ci[i].coeffs))) # Transform to numpy arrays ci[i].occ = numpy.array([s for s in ci[i].occ], dtype=numpy.intc) - 1 return ci
def tmol_tddft(fname, nmoocc=None, nforbs=0, select_state=None, threshold=0.0, bortho=False, **kwargs): '''Reads Turbomole TD-DFT output (``sing_a`` file). Hint: Only implemented for singlet TD-DFT computations in C_1 symmetry, the output data file of which is usually called ``sing_a``. **Parameters:** fname: str, file descriptor Specifies the filename for the input file. fname can also be used with a file descriptor instad of a filename. nmoocc : int Specifies the number of non-frozen occupied orbitals. nforbs : int,optional Specifies the number of frozen orbitals. select_state : None or list of int, optional If not None, specifies the states to be read (0 corresponds to the ground state), else read all electronic states. threshold : float, optional Specifies a read threshold for the TD-DFT coefficients. bortho : bool If True, an orthonormalization of the TD-DFT coefficients is perfomed with Gram-Schmidt. **Returns:** ci : list of CIinfo class instances See :ref:`Central Variables` for details. ''' display('\nReading data of TD-DFT calculation from Turbomole...') nel = (nmoocc + nforbs) * 2 lumo = (nmoocc + nforbs) states = [] if isinstance(select_state, int): select_state = [select_state] if isinstance(fname, str): filename = fname fname = descriptor_from_file(filename, index=0, ci_descriptor=True) else: filename = fname.name start = False for i, line in enumerate(fname): if '$tensor space dimension' in line: tspace = int(line.split()[-1]) if 'eigenvalue' in line: start = True l = line.split() states.append({ 'eigenvalue': float(l[-1].replace('D', 'E')), 'coeffs': [] }) elif start: for i in range((len(line) - 1) // 20): states[-1]['coeffs'].append( float(line[i * 20:(i + 1) * 20].replace('D', 'E'))) for i in range(len(states)): if len(states[i]['coeffs']) == tspace * 2: states[i]['coeffs'] = numpy.array(states[i]['coeffs']).reshape( (2, nmoocc, -1)) states[i]['xia'] = states[i]['coeffs'][0] elif len(states[i]['coeffs']) == tspace: states[i]['xia'] = numpy.array(states[i]['coeffs']).reshape( (nmoocc, -1)) else: raise IOError( 'Shape of coefficient matrix does not match with tensor space.' ) del states[i]['coeffs'] coeffs = numpy.zeros( (len(states) + 1, numpy.prod(states[1]['xia'].shape) + 1)) for i in range(len(states)): coeffs[i + 1][1:] = states[i]['xia'].reshape((-1, )) coeffs[0, 0] = 1.0 # Set up configurations ci = [] for i in range(len(states) + 1): if select_state is None or i in select_state: ci.append(CIinfo(method='tddft')) ci[-1].coeffs = coeffs[i] ci[-1].occ = [] ci[-1].info = { 'state': str(i), 'energy': 0.0 if i == 0 else numpy.abs(states[i - 1]['eigenvalue']), 'fileinfo': filename, 'read_threshold': threshold, 'spin': 'Unknown', 'nel': nel } if not i: ci[-1].occ.append([-1, -1]) else: ci[-1].occ.append([0, 0]) for jj in range(states[i - 1]['xia'].shape[0]): for kk in range(states[i - 1]['xia'].shape[1]): ci[-1].occ.append([jj + nforbs, kk + lumo]) ci[-1].occ = numpy.array(ci[-1].occ, dtype=numpy.intc) # Gram-Schmidt display('Orthonormalizing the TD-DFT coefficients with Gram-Schmidt...\n') ci = orthonorm(ci, reorth=False) if bortho: for c in ci: c.apply_threshold(threshold, keep_length=True) ci = orthonorm(ci, reorth=True) else: for c in ci: c.apply_threshold(threshold, keep_length=False) for c in ci: c.apply_threshold(0.0, keep_length=False) #--- Calculating norm of CI states display('\nIn total, %d states have been read.' % len(ci)) display('Norm of the states:') for i in ci: display(str(i)) return ci