@@ -922,6 +922,10 @@ def read_spx_mappings(filename):
922922 2. transition_lookup: [rpa_idx] -> (ini, fin, spin)
923923 3. max_spin: 0 for unpolarized/Up-only, 1 if Down exists
924924 Indices follow Python usage and start with 0
925+
926+ --- Usage ---
927+ rpa_map, trans_lookup, max_s = read_spx_mappings("SPX.DAT")
928+ print(f"Max Spin Index: {max_s}") # 0 for Restricted, 1 for Unrestricted
925929 """
926930 temp_data = []
927931 max_orb = 0
@@ -976,11 +980,21 @@ def read_spx_mappings(filename):
976980
977981 return rpa_map , transition_lookup , actual_max_spin
978982
979- # --- Usage ---
980- # rpa_map, trans_lookup, max_s = read_spx_mappings("SPX.DAT")
981- # print(f"Max Spin Index: {max_s}") # 0 for Restricted, 1 for Unrestricted
982983
983984def parse_tagged_file (file_path ):
985+ """
986+ --- Usage ---
987+ Load the file into a data dictionary
988+ results = parse_tagged_file("autotes.tag")
989+
990+ Accessing a 0D (Scalar) value by tag name
991+ energy = results['mermin_energy'] # Returns an int or float
992+
993+ Accessing a 1D or 2D (Array) value
994+ coords = results['end_coords'] # Returns a NumPy array
995+
996+ """
997+
984998 data_dict = {}
985999
9861000 with open (file_path , 'r' ) as f :
@@ -1035,15 +1049,6 @@ def parse_tagged_file(file_path):
10351049 i += 1
10361050
10371051 return data_dict
1038- # --- Usage ---
1039- # Load the file into a data dictionary
1040- # results = parse_tagged_file("autotes.tag")
1041-
1042- # Accessing a 0D (Scalar) value by tag name
1043- # energy = results['mermin_energy'] # Returns an int or float
1044-
1045- # Accessing a 1D or 2D (Array) value
1046- # coords = results['end_coords'] # Returns a NumPy array
10471052
10481053
10491054def read_mo_matrix (filename , ndim , spin_polarized = False ):
@@ -1198,6 +1203,11 @@ def read_nacv(filename):
11981203 Parses NACV.DAT into a 4D array: [state_i, state_j, dim, atomindex]
11991204 - state_i, state_j: Use raw values from file (1-based if file is 1-based)
12001205 - dim, atomindex: 0-based
1206+
1207+ # --- Example of how to access the data ---
1208+ # data = read_nacv("NACV.DAT")
1209+ # x_comp_atom_0 = data[1, 2, 0, 0] # State 1, State 2, X-dim, 1st Atom
1210+
12011211 """
12021212 couplings_dict = {}
12031213 max_state = 0
@@ -1252,130 +1262,6 @@ def read_nacv(filename):
12521262
12531263 return nacv
12541264
1255- # --- Example of how to access the data ---
1256- # data = read_nacv("NACV.DAT")
1257- # x_comp_atom_0 = data[1, 2, 0, 0] # State 1, State 2, X-dim, 1st Atom
1258-
1259-
1260-
1261- # --- Usage Examples ---
1262- # dftb_in.hsd that creates all data files:
1263- # Geometry = GenFormat {
1264- # 2 C
1265- # N H
1266- # 1 1 0.4660890295E-01 -0.1121033973E-15 -0.1279328402E-31
1267- # 2 2 0.1104519097E+01 0.1121033973E-15 0.1279328402E-31
1268- # }
1269- # Driver = {}
1270- #
1271- # Hamiltonian = DFTB {
1272- # SCC = Yes
1273- # SCCTolerance = 1.0E-10
1274- # MaxAngularMomentum = {
1275- # N = "p"
1276- # H = "s"
1277- # }
1278- # SpinPolarisation = Colinear {
1279- # UnpairedElectrons = 2
1280- # }
1281- # SpinConstants = {
1282- # N = {-0.026} # HOMO Wpp
1283- # H = {-0.072} # HOMO Wss
1284- # }
1285- # SlaterKosterFiles = Type2FileNames {
1286- # Prefix = {/data1/niehaus/SK-SVN/mio-1-1/}
1287- # Separator = "-"
1288- # Suffix = ".skf"
1289- # }
1290- # Filling = Fermi {
1291- # Temperature [K] = 40
1292- # }
1293- #}
1294- #ExcitedState {
1295- # Casida {
1296- # NrOfExcitations = 5
1297- # StateOfInterest = 1
1298- # WriteSPTransitions = Yes
1299- # WriteXplusY = Yes
1300- # #StateCouplings = {0 2}
1301- # #WriteXplusYAscii = Yes
1302- # Diagonaliser = Stratmann{}
1303- # }
1304- #}
1305- #Options {
1306- # WriteAutotestTag = Yes
1307- # #WriteHS = Yes
1308- #}
1309- #Analysis {
1310- # WriteEigenvectors = Yes
1311- # EigenvectorsAsText = Yes
1312- # PrintForces = Yes
1313- #}
1314- ## Run this twice. Once with WriteHS = Yes uncommented.
1315-
1316- au2ev = 27.211386
1317- ## SPX
1318- rpa_map , rpa_lookup , max_spin = read_spx_mappings ("SPX.DAT" )
1319-
1320- # Case A: You know the orbitals, want the index
1321- # "What is the index for lowest -> highest MO, Spin Up?"
1322- ndim = rpa_map .shape [0 ]
1323- print ('RPA index:' , rpa_map [0 ,ndim - 1 , 0 ])
1324-
1325- # Case B: You have an index (e.g., from an xpy vector), want the orbitals
1326- # "What transition does RPA index 8 represent?"
1327- idx = 8
1328- m , n , s = rpa_lookup [idx ]
1329- print (f"Index { idx + 1 } corresponds to: Orbital { m + 1 } -> Orbital { n + 1 } (Spin { s } )" )
1330-
1331- ## X+Y
1332- # For older versions of dftb+, the binary file XplusY.BIN is not available
1333- #nmat, nexc, results = read_xplusy_ascii("XplusY.DAT")
1334- nmat , nexc , results = read_xplusy_binary ("XplusY.BIN" )
1335-
1336- # Access a specific Root (e.g., Root 2, which is index 1)
1337- ridx = 1
1338- root_data = results [ridx ]
1339- print (f"Energy for root { ridx + 1 } : { au2ev * root_data ['energy' ]} eV" )
1340- # Extract the xpy vector (the RPA eigenvector)
1341- # This is a 1D NumPy array of length 'nmat'
1342- xpy = root_data ['vector' ]
1343-
1344- # Checking norm of vector
1345- print (f'First entries X+Y eigenvector for root { ridx + 1 } : { xpy [0 :5 ]} ' )
1346- for iRoot in range (nexc ):
1347- root_data = results [iRoot ]
1348- xpy = root_data ['vector' ]
1349- # Note that (X+Y)(X-Y) = 1, this is just a rough check of normalization
1350- print (f'X+Y norm for root { iRoot + 1 } : { sum (xpy [:]** 2 )} ' )
1351-
1352- ## MO data
1353- ndim = rpa_map .shape [1 ]
1354- spin_polarized = bool (rpa_map .shape [2 ]- 1 )
1355- mo = read_mo_matrix ("eigenvec.bin" , ndim , spin_polarized = spin_polarized )
1356- # mo[spin,mu,i] corresponds to c_mu_i
1357-
1358- ## Overlap matrix
1359- S = read_overlap_matrix ('oversqr.dat' , ndim )
1360- for iSpin in range (mo .shape [0 ]):
1361- print (f"Checking MO orthornormality for spin { iSpin } " )
1362- d = np .dot (S , mo [iSpin ,:,:])
1363- mat = np .dot (mo [iSpin ,:,:].T , d )
1364- check_unity_deviation (mat )
1365-
1366- ## autotest.tag
1367- results = parse_tagged_file ("autotest.tag" )
1368- forces = results ['forces' ]
1369- # If in DFTB+ PrintForces = yes, the forces under the forces tag are for the excited state StateOfInterest
1370- # Forces are given in Hartree / Bohr
1371- print (f'x-component of force on second atom: { forces [0 ,1 ]} ' )
1372-
1373-
1374- ## NACV.DAT (not available for spin-polarized systems)
1375- # NACV are given in 1 / Bohr
1376- if os .path .exists ("NACV.DAT" ):
1377- nacv = read_nacv ("NACV.DAT" )
1378- print (f'S1 to S2 NACV, y-component of atom 3: { nacv [1 ,2 ,1 ,2 ]} ' )
13791265
13801266
13811267
0 commit comments