File size: 6,257 Bytes
1c703f0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191


from backend.latmathcher.plots import plot_atom_list
from backend.latmathcher import atoms_to_greed
from backend.latmathcher import PipelineLatMatch
from backend.db_utils.utils import structure_ato_list
from backend.db_utils.parse_c2db import from_c2db_structure, read_c2db_json
from backend.db_utils.structure_database import DBInstance


import matplotlib.pyplot as plt
import matplotlib.patches as patches
import os
import shutil
import numpy as np
import periodictable
import ast

def get_atomic_number(element_symbol):
    # Find the element in the periodic table and return its atomic number
    element = getattr(periodictable, element_symbol)
    return element.number


def compute_supercell_a(file_material_a, file_material_b, file_source_a, file_source_b, max_angle, max_strain):


    #
    ip = "test_ip"  # get_client_ip(response)

    db_latmatcher_path = "/Users/voicutomut/Documents/GitHub/BespokeMaterials/DB/LatMatcher"
    new_directory = db_latmatcher_path + "/{}__ma{}__ms{}_on{}".format(ip, max_angle, max_strain,
                                                                       len(os.listdir(db_latmatcher_path)))
    if not os.path.exists(new_directory):
        os.makedirs(new_directory)
    path_to_move = new_directory

    file1 = process_file(file_material_a, path_to_move+"/")
    file2 = process_file(file_material_b, path_to_move+"/")


    if file_source_a == "c2db.json":
        A_structure = from_c2db_structure(read_c2db_json(file1))
        A_cell=A_structure["cell"]
    if file_source_b == "c2db.json":
        B_structure = from_c2db_structure(read_c2db_json(file2))
        B_cell=B_structure["cell"]



    if file_source_a == ".xyz":
        A_structure = extract_from_xyz(file1)
        A_cell = A_structure["cell"]
    if file_source_b == ".xyz":
        B_structure = extract_from_xyz(file2)
        B_cell=B_structure["cell"]


    if file_source_a == "bespoke.json":
        A_structure = extract_from_bespoke(file1)
        A_cell = A_structure["cell"]
    if file_source_b == "bespoke.json":
        B_structure = extract_from_bespoke(file2)
        B_cell=B_structure["cell"]


    super_xyz, min_supercel= compute_supercell(A_cell, B_cell, A_structure, B_structure )
    rez=min_supercel.rez

    # Write the new file:
    name = "solution"
    file12 = path_to_move + "/" + name + ".xyz"

    xyz_content = "{"+"'lattice_vectors':{}".format(np.array2string(min_supercel.get_new_structure()['lattice_vectors'],
                                                                  separator=', ',
                                                                   max_line_width=np.inf).replace("\n"," "))+"}\n\n"

    xyz_content += f"{len(super_xyz)}\n\n"
    xyz_content += "\n".join([f"{atom[0]} {' '.join(map(str, atom[1]))}" for atom in super_xyz])

    # Write the content to a file
    with open(file12, 'w') as file:
        file.write(xyz_content)


    plot=plot_supercel(super_xyz, min_supercel)
    return file12, str(rez[0]), str((rez[1], rez[2])),plot

def compute_supercell_b():
    pass

def compute_supercell(A_cell, B_cell,A_structure,B_structure ):

    min_supercel = PipelineLatMatch(A_cell, B_cell, Aatoms3D=structure_ato_list(A_structure),
                                    Batoms3D=structure_ato_list(B_structure), dim=(10, 10), optimize_angle=True,
                                    optimize_strain=True)

    new_structure = min_supercel.get_new_structure()
    super_xyz = structure_ato_list(new_structure)
    return super_xyz,    min_supercel




def  plot_supercel(super_xyz, min_supercel):
    fig = plt.figure()
    new_structure=min_supercel.get_new_structure()
    super_a = [super_xyz[i] for i in range(len(new_structure["host_guest"])) if
               new_structure["host_guest"][i] == "host"]
    super_b = [super_xyz[i] for i in range(len(new_structure["host_guest"])) if
               new_structure["host_guest"][i] == "guest"]

    atoms = atoms_to_greed(super_a, lat_v=min_supercel.sc_vec3, dim=(10, 10, 0))
    plot_atom_list(atoms, marker=".")
    atoms = atoms_to_greed(super_b, lat_v=min_supercel.sc_vec3, dim=(10, 10, 0))
    plot_atom_list(atoms, marker="*")

    x = [0.0, min_supercel.sc_vec3[0][0], min_supercel.sc_vec3[0][0] + min_supercel.sc_vec3[0][1],
         min_supercel.sc_vec3[0][1], 0.0]
    y = [0.0, min_supercel.sc_vec3[1][0], min_supercel.sc_vec3[1][0] + min_supercel.sc_vec3[1][1],
         min_supercel.sc_vec3[1][1], 0.0]
    plt.gca().add_patch(patches.Polygon(xy=list(zip(x, y)), fill=True, alpha=0.4, color="green"))
    plt.ylim(-15, 15)
    plt.xlim(-15, 15)
    return fig



# Utility tools for working with files
def file_json(file_path):
    file = file_path.split("/")[-1]
    ext = file.split(".")[-1]
    if ext == "json":
        return True
    else:
        return False


def get_file_name(file_path):
    file = file_path.split("/")[-1]
    file_name = file.split(".")[-2]
    return file_name


def process_file(fileobj, path_to_move):
    file_path = path_to_move + os.path.basename(fileobj.name)
    shutil.copyfile(fileobj.name, file_path)
    return file_path


def extract_from_xyz(file):

    structure={'cell':[], 'atoms':[],
               'positions':[],
               "pbc":[ True,  True, False] }

    with open(file, 'r') as xyz_file:
        lines = xyz_file.readlines()[4:]  # Skipping the first two line

    with open(file, 'r') as xyz_file:
        dict_string = xyz_file.readlines()[:1][0]
        print(dict_string)


    lattice = ast.literal_eval(dict_string)['lattice_vectors']


    structure["cell"]=np.array([[lattice[0][0], lattice[0][1], 0],
                                [lattice[1][0], lattice[1][1], 0],
                                [0,0,1]])


    atom_xyz=np.array([line.split()[1:4] for line in lines], dtype=float)

    atomic_symbols = []
    for line in lines:
        atomic_symbols.append(line.split()[0])
    structure['atoms']=[get_atomic_number(element_symbol) for element_symbol  in atomic_symbols]

    structure['positions']=atom_xyz



    return structure


def extract_from_bespoke(file):
    read_element = DBInstance().from_json_file(file)
    structure = read_element.structure
    structure["cell"]=np.array(structure["cell"])
    return structure