Я новичок ie в программировании и молекулярной динамике c симуляций. Я использую LAMMPS для моделирования процесса физического осаждения из паровой фазы (PVD) и определения взаимодействий между атомами на разных временных шагах.
После того, как я выполню молекулярно-динамическое моделирование, LAMMPS предоставляет мне выходной сигнал связей файл, который содержит записи о каждом отдельном атоме (в качестве идентификатора атома), их типах (числа, отвечающие за определенные элементы) и информацию о других атомах, связанных с этими конкретными атомами. Типичный файл bond выглядит следующим образом.
Я стремлюсь сортировать атомы в соответствии с их типами (например, группа 1: кислород-водород-водород) ) в трех группах, считая информацию об их связях из выходного файла bond и считая количество групп для каждого временного шага. Я использовал pandas и создал кадр данных для каждого временного шага.
df = pd.read_table(directory, comment="#", delim_whitespace= True, header=None, usecols=[0,1,2,3,4,5,6] )
headers= ["ID","Type","NofB","bondID_1","bondID_2","bondID_3","bondID_4"]
df.columns = headers
df.fillna(0,inplace=True)
df = df.astype(int)
timestep = int(input("Number of Timesteps: ")) #To display desired number of timesteps.
total_atom_number = 53924 #Total number of atoms in the simulation.
t= 0 #code starts from 0th timestep.
firstTime = []
while(t <= timestep):
open('file.txt', 'w').close() #In while loop = displays every timestep individually, Out of the while loop = displays results cumulatively.
i = 0
df_tablo =(df[total_atom_number*t:total_atom_number*(t+1)]) #Creates a new dataframe that inlucdes only t'th timestep.
df_tablo.reset_index(inplace=True)
print(df_tablo)
Пожалуйста, посмотрите этот пример, который иллюстрирует мой алгоритм для группировки 3 атомов . Столбцы связей отображают разные атомы (по идентификаторам атомов), которые связаны вместе с атомами в их ряду. Например, используя алгоритм, мы можем сгруппировать [1,2,5] и [1,2,6], но не [1,2,1], поскольку атом не может создать связь с самим собой. Кроме того, мы можем преобразовать эти идентификаторы атомов (первый столбец) в их типы атомов (второй столбец) после группировки, такие как [1,3,7] - [1,1,3].
, следуя связям как уже упоминалось выше, 1) Я могу успешно группировать атомы по их идентификаторам, 2) конвертировать их в их типы атомов и 3) считать сколько групп существуют на каждом временном шаге, соответственно. Первый , в то время как l oop (выше) подсчитывает группы для каждого временного шага, тогда как второй , в то время как l oop (ниже) группирует атомы из каждого ряда (что равно ID каждого атома существовал) с соответствующими атомами из разных строк в кадре данных.
while i < total_atom_number:
atom1_ID = df_tablo["ID"][i] # atom ID of i'th row was defined.
atom1_NB = df_tablo["NofB"][i] # number of bonds of the above atom ID was defined, but not used.
atom1_bond1 = df_tablo["bondID_1"][i] #bond ID1 of above atom was defined.
# bondIDs and atom types of 1,2,3 and 4 for atom1_bond1 were defined respectively.
if atom1_bond1 != 0:
atom2_index = (df_tablo.set_index('ID').index.get_loc(atom1_bond1))
atom2_ID = df_tablo["ID"][atom2_index]
atom2_bond1 = df_tablo["bondID_1"][atom2_index]
atom2_bond2 = df_tablo["bondID_2"][atom2_index]
atom2_bond3 = df_tablo["bondID_3"][atom2_index]
atom2_bond4 = df_tablo["bondID_4"][atom2_index]
type_atom1 = df_tablo["Type"][i]
type_atom2 = df_tablo["Type"][atom2_index]
#If the desired conditions are satisfied, atom types are combined as [atom at i'th row, bondID1 at'ith row, 4 bondIDs respectively at the row which is equal to bondID1's row ]
if atom1_ID != atom2_bond1 and atom2_bond1 != 0:
set = [atom1_ID, atom2_ID, atom2_bond1]
atom2_bond1_index = (df_tablo.set_index('ID').index.get_loc(atom2_bond1))
type_atom2_bond1 = df_tablo["Type"][atom2_bond1_index]
print("{}{}{}".format(type_atom1, type_atom2, type_atom2_bond1), file=open("file.txt", "a"))
# print(set)
if atom1_ID != atom2_bond2 and atom2_bond2 != 0:
set = [atom1_ID, atom2_ID, atom2_bond2]
atom2_bond2_index = (df_tablo.set_index('ID').index.get_loc(atom2_bond2))
type_atom2_bond2 = df_tablo["Type"][atom2_bond2_index]
print("{}{}{}".format(type_atom1, type_atom2, type_atom2_bond2), file=open("file.txt", "a"))
# print(set)
if atom1_ID != atom2_bond3 and atom2_bond3 != 0:
set = [atom1_ID, atom2_ID, atom2_bond3]
atom2_bond3_index = (df_tablo.set_index('ID').index.get_loc(atom2_bond3))
type_atom2_bond3 = df_tablo["Type"][atom2_bond3_index]
print("{}{}{}".format(type_atom1, type_atom2, type_atom2_bond3), file=open("file.txt", "a"))
# print(set)
if atom1_ID != atom2_bond4 and atom2_bond4 != 0:
set = [atom1_ID, atom2_ID, atom2_bond4]
atom2_bond4_index = (df_tablo.set_index('ID').index.get_loc(atom2_bond4))
type_atom2_bond4 = df_tablo["Type"][atom2_bond4_index]
print("{}{}{}".format(type_atom1, type_atom2, type_atom2_bond4), file=open("file.txt", "a"))
# print(set)
# bondIDs and atom types of 1,2,3 and 4 for atom1_bond2 were defined respectively.
atom1_bond2 = df_tablo["bondID_2"][i]
if atom1_bond2 != 0:
atom1_bond2_index = (df_tablo.set_index('ID').index.get_loc(atom1_bond2) + 6)
atom1_bond2_ID = df_tablo["ID"][atom1_bond2_index]
atom1_bond2_bond1 = df_tablo["bondID_1"][atom1_bond2_index]
atom1_bond2_bond2 = df_tablo["bondID_2"][atom1_bond2_index]
atom1_bond2_bond3 = df_tablo["bondID_3"][atom1_bond2_index]
atom1_bond2_bond4 = df_tablo["bondID_4"][atom1_bond2_index]
type_atom1_bond2 = df_tablo["Type"][atom1_bond2_index] # If the desired conditions are satisfied, atom types are combined as [atom at i'th row, bondID2 at'ith row, and 4 bondIDs respectively at the row which is equal to bondID2's row ]
if atom1_ID != atom1_bond2_bond1 and atom1_bond2_bond1 != 0:
set = [atom1_ID, atom1_bond2, atom1_bond2_bond1]
atom1_bond2_bond1_index = (df_tablo.set_index('ID').index.get_loc(atom1_bond2_bond1))
type_atom1_bond2_bond1 = df_tablo["Type"][atom1_bond2_bond1_index]
print("{}{}{}".format(type_atom1, type_atom1_bond2, type_atom1_bond2_bond1), file=open("file.txt", "a"))
# print(set)
if atom1_ID != atom1_bond2_bond2 and atom1_bond2_bond2 != 0:
set = [atom1_ID, atom1_bond2, atom1_bond2_bond2]
atom1_bond2_bond2_index = (df_tablo.set_index('ID').index.get_loc(atom1_bond2_bond2))
type_atom1_bond2_bond2 = df_tablo["Type"][atom1_bond2_bond2_index]
print("{}{}{}".format(type_atom1, type_atom1_bond2, type_atom1_bond2_bond2), file=open("file.txt", "a"))
# print(set)
if atom1_ID != atom1_bond2_bond3 and atom1_bond2_bond3 != 0:
set = [atom1_ID, atom1_bond2, atom1_bond2_bond3]
atom1_bond2_bond3_index = (df_tablo.set_index('ID').index.get_loc(atom1_bond2_bond3))
type_atom1_bond2_bond3 = df_tablo["Type"][atom1_bond2_bond3_index]
print("{}{}{}".format(type_atom1, type_atom1_bond2, type_atom1_bond2_bond3), file=open("file.txt", "a"))
# print(set)
if atom1_ID != atom1_bond2_bond4 and atom1_bond2_bond4 != 0:
set = [atom1_ID, atom1_bond2, atom1_bond2_bond4]
atom1_bond2_bond4_index = (df_tablo.set_index('ID').index.get_loc(atom1_bond2_bond4))
type_atom1_bond2_bond4 = df_tablo["Type"][atom1_bond2_bond4_index]
print("{}{}{}".format(type_atom1, type_atom1_bond2, type_atom1_bond2_bond4), file=open("file.txt", "a"))
# print(set)
# bondIDs and atom types of 1,2,3 and 4 for atom1_bond3 were defined respectively.
atom1_bond3 = df_tablo["bondID_3"][i]
if atom1_bond3 != 0:
atom1_bond3_index = (df_tablo.set_index('ID').index.get_loc(atom1_bond3))
atom1_bond3_ID = df_tablo["ID"][atom1_bond3_index]
atom1_bond3_bond1 = df_tablo["bondID_1"][atom1_bond3_index]
atom1_bond3_bond2 = df_tablo["bondID_2"][atom1_bond3_index]
atom1_bond3_bond3 = df_tablo["bondID_3"][atom1_bond3_index]
atom1_bond3_bond4 = df_tablo["bondID_4"][atom1_bond3_index]
type_atom1_bond3 = df_tablo["Type"][atom1_bond3_index]
# If the desired conditions are satisfied, atom types are combined as [atom at i'th row, bondID3 at'ith row, and 4 bondIDs respectively at the row which is equal to bondID3's row ]
if atom1_ID != atom1_bond3_bond1 and atom1_bond3_bond1 != 0:
atom1_bond3_bond1_index = (df_tablo.set_index('ID').index.get_loc(atom1_bond3_bond1))
type_atom1_bond3_bond1 = df_tablo["Type"][atom1_bond3_bond1_index]
print("{}{}{}".format(type_atom1, type_atom1_bond3, type_atom1_bond3_bond1), file=open("file.txt", "a"))
set = [atom1_ID, atom1_bond3, atom1_bond3_bond1]
# print(set)
if atom1_ID != atom1_bond3_bond2 and atom1_bond3_bond2 != 0:
set = [atom1_ID, atom1_bond3, atom1_bond3_bond2]
atom1_bond3_bond2_index = (df_tablo.set_index('ID').index.get_loc(atom1_bond3_bond2))
type_atom1_bond3_bond2 = df_tablo["Type"][atom1_bond3_bond2_index]
print("{}{}{}".format(type_atom1, type_atom1_bond3, type_atom1_bond3_bond2), file=open("file.txt", "a"))
# print(set)
if atom1_ID != atom1_bond3_bond3 and atom1_bond3_bond3 != 0:
set = [atom1_ID, atom1_bond3, atom1_bond3_bond3]
atom1_bond3_bond3_index = (df_tablo.set_index('ID').index.get_loc(atom1_bond3_bond3))
type_atom1_bond3_bond3 = df_tablo["Type"][atom1_bond3_bond3_index]
print("{}{}{}".format(type_atom1, type_atom1_bond3, type_atom1_bond3_bond3), file=open("file.txt", "a"))
# print(set)
if atom1_ID != atom1_bond3_bond4 and atom1_bond3_bond4 != 0:
set = [atom1_ID, atom1_bond3, atom1_bond3_bond4]
atom1_bond3_bond4_index = (df_tablo.set_index('ID').index.get_loc(atom1_bond3_bond4))
type_atom1_bond3_bond4 = df_tablo["Type"][atom1_bond3_bond4_index]
print("{}{}{}".format(type_atom1, type_atom1_bond3, type_atom1_bond3_bond4), file=open("file.txt", "a"))
# print(set)
atom1_bond4 = df_tablo["bondID_4"][i]
# bondIDs and atom types of 1,2,3 and 4 for atom1_bond4 were defined respectively.
if atom1_bond4 != 0:
atom1_bond4_index = (df_tablo.set_index('ID').index.get_loc(atom1_bond4))
atom1_bond4_ID = df_tablo["ID"][atom1_bond4_index]
atom1_bond4_bond1 = df_tablo["bondID_1"][atom1_bond4_index]
atom1_bond4_bond2 = df_tablo["bondID_2"][atom1_bond4_index]
atom1_bond4_bond3 = df_tablo["bondID_3"][atom1_bond4_index]
atom1_bond4_bond4 = df_tablo["bondID_4"][atom1_bond4_index]
type_atom1_bond4 = df_tablo["Type"][atom1_bond4_index]
# If the desired conditions are satisfied, atom types are combined as [atom at i'th row, bondID4 at'ith row, and 4 bondIDs respectively at the row which is equal to bondID4's row ]
if atom1_ID != atom1_bond4_bond1 and atom1_bond4_bond1 != 0:
set = [atom1_ID, atom1_bond4, atom1_bond4_bond1]
atom1_bond4_bond1_index = (df_tablo.set_index('ID').index.get_loc(atom1_bond4_bond1))
type_atom1_bond4_bond1 = df_tablo["Type"][atom1_bond4_bond1_index]
print("{}{}{}".format(type_atom1, type_atom1_bond4, type_atom1_bond4_bond1), file=open("file.txt", "a"))
# print(set)
if atom1_ID != atom1_bond4_bond2 and atom1_bond4_bond2 != 0:
set = [atom1_ID, atom1_bond4, atom1_bond4_bond2]
atom1_bond4_bond2_index = (df_tablo.set_index('ID').index.get_loc(atom1_bond4_bond2))
type_atom1_bond4_bond2 = df_tablo["Type"][atom1_bond4_bond2_index]
print("{}{}{}".format(type_atom1, type_atom1_bond4, type_atom1_bond4_bond2), file=open("file.txt", "a"))
# print(set)
if atom1_ID != atom1_bond4_bond3 and atom1_bond4_bond3 != 0:
set = [atom1_ID, atom1_bond4, atom1_bond4_bond3]
atom1_bond4_bond3_index = (df_tablo.set_index('ID').index.get_loc(atom1_bond4_bond3))
type_atom1_bond4_bond3 = df_tablo["Type"][atom1_bond4_bond3_index]
print("{}{}{}".format(type_atom1, type_atom1_bond4, type_atom1_bond4_bond3), file=open("file.txt", "a"))
# print(set)
if atom1_ID != atom1_bond4_bond4 and atom1_bond4_bond4 != 0:
set = [atom1_ID, atom1_bond4, atom1_bond4_bond4]
atom1_bond4_bond4_index = (df_tablo.set_index('ID').index.get_loc(atom1_bond4_bond4))
type_atom1_bond4_bond4 = df_tablo["Type"][atom1_bond4_bond4_index]
print("{}{}{}".format(type_atom1, type_atom1_bond4, type_atom1_bond4_bond4), file=open("file.txt", "a"))
# print(set)
print(i,".step" )
print(time.time() - start_time, "seconds")
i = i + 1
print("#timestep", t, file=open("file.txt", "a"))
print("#timestep", t)
df_veri = pd.read_table('file.txt', comment="#", header=None)
df_veri.columns = ["timestep %d" % (t)]
#Created a dictionary that corresponds to type of bonds
df_veri["timestep %d" % (t)] = df_veri["timestep %d" % (t)].astype(str).replace(
{'314': 'NCO', '312': 'NCH', '412': 'OCH', '214': 'HCO', '431': 'ONC', '414': 'OCO', '212': 'HCH',
'344': 'NOO', '343': 'NON', '441': 'OOC', '144': 'COO', '421': 'OHC', '434': 'ONO', '444': 'OOO', '121': 'CHC',
'141': 'COC'
})
# To calculate the number of 3-atom combinations
ndf = df_veri.apply(pd.Series.value_counts).fillna(0)
ndfy = pd.DataFrame(ndf)
ndfy1 = ndfy.transpose()
# To write the number of 3-atom combinations in first timestep with headers and else without headers.
if firstTime == []:
ndfy1.to_csv('filename8.csv', mode='a', header=True)
firstTime.append('Not Empty')
else:
ndfy1.to_csv('filename8.csv', mode='a', header=False)
t = t + 1
Это типичный выходной файл моего кода в формате csv
Хотя код работает, он неэффективен, так как
Он может повторять только 4 атома связи для каждого идентификатора атома (однако результаты моделирования могут достигать до 12 атомов связи, которые должны были быть подсчитаны.)
Программа работает медленно. (Я работаю с более чем 50000 атомами, что может занять до 88 минут для расчета каждого временного шага.)
Не могли бы вы порекомендовать мне более эффективный способ? Так как я новичок в ie в программировании, я не знаю, есть ли другие инструменты итерации python или пакеты, которые могли бы работать для моего случая. Я считаю, что было бы более продуктивно, если бы я мог выполнять эти операции с меньшим количеством строк кода (особенно если бы я мог избавиться от повторения , если операторов).
Спасибо за ваше время.