Source code for multipie.model.construct_model

"""
construct model from matrx dict.
"""
import sympy as sp
import numpy as np
from gcoreutils.nsarray import NSArray


# ==================================================
[docs] def construct_samb_matrix_k(matrix_dict, k_grid=None): """ construct SAMB matrix from matrix dict. Args: matrix_dict (dict): matrix dict from _matrix_k.py file. k_grid (NSArray, optional): k_grid points (reduced coordinate). Returns: ndarray: basis matrix, [#bases, #k, dim, dim]. """ z_samb = matrix_dict["matrix"] z_mat = {k: str(NSArray(v).evalf()) for k, v in z_samb.items()} if matrix_dict["molecule"] or k_grid is None: Nk = 1 bond = [{}] else: Nk = len(k_grid) d = {} for name, ex in matrix_dict["bond"].items(): ex = NSArray(ex, fmt="value") ex = np.broadcast_to(ex, (Nk, 3)) k_grid = np.array(k_grid) p = -2 * np.pi * np.sum(ex * np.array(k_grid), axis=1) d[name.replace("bond_", "c")] = np.cos(p) d[name.replace("bond_", "s")] = np.sin(p) bond = [{name: lst[i] for name, lst in d.items()} for i in range(len(k_grid))] def multiple_replace(s, d): s_ = s [s_ := s_.replace(name, f"({val})") for name, val in d.items()] return s_ vmultiple_replace = np.vectorize(multiple_replace) Z_list = [Zj.replace("I", "1j") for Zj in z_mat.values()] Z = np.array( [np.array([np.array(eval(m), dtype="complex64") for m in vmultiple_replace(Zj, bond)]) for Zj in Z_list] ) return Z
# ==================================================
[docs] def construct_samb_matrix(matrix_dict, k_grid=None): """ construct SAMB matrix from matrix dict. Args: matrix_dict (dict): matrix dict from _matrix.py file. k_grid (NSArray, optional): k_grid points (reduced coordinate). Returns: ndarray: basis matrix, [#bases, #k, dim, dim]. """ if k_grid is None: k_grid = np.array([[0, 0, 0]]) z_samb = matrix_dict["matrix"] ket = matrix_dict["ket"] dim = matrix_dict["dimension"] lattice = matrix_dict["group"][1].split("/")[1].replace(" ", "")[0] if lattice != "P": cell_site = {} for site, v in matrix_dict["cell_site"].items(): if "(" in site and ")" in site: if "(1)" in site: cell_site[site[:-3]] = v else: cell_site[site] = v else: cell_site = matrix_dict["cell_site"] atoms_positions = [ NSArray(cell_site[ket[a].split("@")[1]][0], style="vector", fmt="value").tolist() for a in range(len(ket)) ] Nz = len(list(z_samb.keys())) Nk = len(k_grid) Z = np.zeros((Nz, Nk, dim, dim), dtype=np.complex128) for j, Zj_dict in enumerate(z_samb.values()): for (n1, n2, n3, a, b), v in Zj_dict.items(): n_r = NSArray([n1, n2, n3], style="vector", fmt="value").numpy() ra = NSArray(atoms_positions[a], style="vector", fmt="value").numpy() rb = NSArray(atoms_positions[b], style="vector", fmt="value").numpy() v = complex(sp.sympify(v)) phase = -2 * np.pi * k_grid @ (ra - (n_r + rb)).T Z[j, :, a, b] += v * np.exp(1j * phase) return Z
# ==================================================
[docs] def convert_samb_to_matrix_set(Z, param=None): """ convert SAMB to a set of matrix. Args: Z (ndarray): samb matrix, [#bases, #k, dim, dim]. param (list, optional): parameter set(s), [z_j] for crystal or [z_j]/[[z_j]] for molecule. Returns: ndarray: matrix, [#params/#k, dim, dim]. """ if param is None: param = [1.0] * Z.shape[0] param = np.array(param) if param.ndim == 1: M = [Z.transpose(1, 2, 3, 0) @ param] else: M = [Z.transpose(1, 2, 3, 0) @ p for p in param] M = np.vstack(M) return M