from pathlib import Path
import pandas as pd
from dotmap import DotMap
from ttnopt.src import Hamiltonian
[docs]def hamiltonian(config: DotMap):
"""_summary_
Args:e
config Dict: the configuration of the system
"""
if isinstance(config.spin_size, DotMap) and isinstance(
config.spin_size.file, DotMap
):
print("=" * 50)
print("⚠️ Error: Please input spin value in spin_size as S or Si_file")
print("=" * 50)
exit()
spin_sizes = None
if isinstance(config.spin_size, str):
if Path(config.spin_size).suffix == ".dat":
spin_csv = pd.read_csv(config.spin_size, delimiter=",", header=None)
spin_csv_sorted = spin_csv.sort_values(by=0)
spin_size = spin_csv_sorted.iloc[:, 1].values
spin_sizes = [f"S={s}" for s in spin_size]
else:
spin_sizes = ["S=" + str(config.spin_size)] * config.N
else:
print("=" * 50)
print(
"⚠️ Error : spin_size is not specified correctly either number or .dat file"
)
print("=" * 50)
exit()
interaction_indices = None
interaction_coefs = None
if Path(config.model.file).suffix == ".dat":
interaction_csv = pd.read_csv(config.model.file, delimiter=",", header=None)
interaction_indices = interaction_csv.iloc[:, :2].values
interaction_coefs = interaction_csv.iloc[:, 2:].values
else:
print("=" * 50)
print("⚠️ Error : model.file is not specified correctly")
print("=" * 50)
exit()
if interaction_indices.max() >= config.N:
print("=" * 50)
print(
f"⚠️ Error: XXY, XYZ interaction indices exceed the allowed range. All indices must be less than N-1 (N={config.system.N})."
)
print("=" * 50)
exit()
# magnetic_field_X
magnetic_field_X_indices = None
magnetic_field_X = None
if not isinstance(config.MF_X, DotMap):
if Path(str(config.MF_X)).suffix == ".dat":
magnetic_field_X_csv = pd.read_csv(config.MF_X, delimiter=",", header=None)
magnetic_field_X_indices = magnetic_field_X_csv.iloc[:, 0].values
magnetic_field_X = magnetic_field_X_csv.iloc[:, 1].values
else:
if isinstance(float(config.MF_X), float):
magnetic_field_X_indices = [i for i in range(config.N)]
magnetic_field_X = [config.MF_X] * config.N
else:
print("=" * 50)
print("⚠️ Error: MF_X should be .dat file or float.")
print("=" * 50)
exit()
# magnetic_field_Y
magnetic_field_Y_indices = None
magnetic_field_Y = None
if not isinstance(config.MF_Y, DotMap):
if Path(str(config.MF_Y)).suffix == ".dat":
magnetic_field_Y_csv = pd.read_csv(config.MF_Y, delimiter=",", header=None)
magnetic_field_Y_indices = magnetic_field_Y_csv.iloc[:, 0].values
magnetic_field_Y = magnetic_field_Y_csv.iloc[:, 1].values
else:
if isinstance(float(config.MF_Y), float):
magnetic_field_Y_indices = [i for i in range(config.N)]
magnetic_field_Y = [config.MF_Y] * config.N
else:
print("=" * 50)
print("⚠️ Error: MF_Y should be .dat file or float.")
print("=" * 50)
exit()
# magnetic_field_Z
magnetic_field_Z_indices = None
magnetic_field_Z = None
if not isinstance(config.MF_Z, DotMap):
if Path(str(config.MF_Z)).suffix == ".dat":
magnetic_field_Z_csv = pd.read_csv(config.MF_Z, delimiter=",", header=None)
magnetic_field_Z_indices = magnetic_field_Z_csv.iloc[:, 0].values
magnetic_field_Z = magnetic_field_Z_csv.iloc[:, 1].values
else:
if isinstance(float(config.MF_Z), float):
magnetic_field_Z_indices = [i for i in range(config.N)]
magnetic_field_Z = [config.MF_Z] * config.N
else:
print("=" * 50)
print("⚠️ Error: MF_Z should be .dat file or float.")
print("=" * 50)
exit()
ion_anisotropy_indices = None
ion_anisotropy = None
if not isinstance(config.SIA, DotMap):
if Path(str(config.SIA)).suffix == ".dat":
ion_anisotropy_csv = pd.read_csv(config.SIA, delimiter=",", header=None)
ion_anisotropy_indices = ion_anisotropy_csv.iloc[:, 0].values
ion_anisotropy = ion_anisotropy_csv.iloc[:, 1].values
else:
if isinstance(float(config.SIA), float):
ion_anisotropy_indices = [i for i in range(config.N)]
ion_anisotropy = [config.SIA] * config.N
else:
print("=" * 50)
print("⚠️ Error: SIA should be .dat file or float.")
print("=" * 50)
exit()
# dzyaloshinskii_moriya_X
dzyaloshinskii_moriya_X_indices = None
dzyaloshinskii_moriya_X = None
if not isinstance(config.DM_X, DotMap):
if Path(config.DM_X).suffix == ".dat":
dzyaloshinskii_moriya_X_csv = pd.read_csv(
config.DM_X, delimiter=",", header=None
)
dzyaloshinskii_moriya_X_indices = dzyaloshinskii_moriya_X_csv.iloc[
:, :2
].values
dzyaloshinskii_moriya_X = dzyaloshinskii_moriya_X_csv.iloc[:, 2:].values
if dzyaloshinskii_moriya_X_indices.max() >= config.N:
print("=" * 50)
print(
f"⚠️ Error: DM_X interaction indices exceed the allowed range. All indices must be less than N-1 (N={config.system.N})."
)
print("=" * 50)
exit()
else:
print("=" * 50)
print("⚠️ Error: DM_X should be .dat file.")
print("=" * 50)
exit()
# dzyaloshinskii_moriya_Y
dzyaloshinskii_moriya_Y_indices = None
dzyaloshinskii_moriya_Y = None
if not isinstance(config.DM_Y, DotMap):
if Path(config.DM_Y).suffix == ".dat":
dzyaloshinskii_moriya_Y_csv = pd.read_csv(
config.DM_Y, delimiter=",", header=None
)
dzyaloshinskii_moriya_Y_indices = dzyaloshinskii_moriya_Y_csv.iloc[
:, :2
].values
dzyaloshinskii_moriya_Y = dzyaloshinskii_moriya_Y_csv.iloc[:, 2:].values
if dzyaloshinskii_moriya_Y_indices.max() >= config.N:
print("=" * 50)
print(
f"⚠️ Error: DM_Y interaction indices exceed the allowed range. All indices must be less than N-1 (N={config.system.N})."
)
print("=" * 50)
exit()
else:
print("=" * 50)
print("⚠️ Error: DM_Y should be .dat file.")
print("=" * 50)
exit()
# dzyaloshinskii_moriya_Z
dzyaloshinskii_moriya_Z_indices = None
dzyaloshinskii_moriya_Z = None
if not isinstance(config.DM_Z, DotMap):
if Path(config.DM_Z).suffix == ".dat":
dzyaloshinskii_moriya_Z_csv = pd.read_csv(
config.DM_Z, delimiter=",", header=None
)
dzyaloshinskii_moriya_Z_indices = dzyaloshinskii_moriya_Z_csv.iloc[
:, :2
].values
dzyaloshinskii_moriya_Z = dzyaloshinskii_moriya_Z_csv.iloc[:, 2:].values
if dzyaloshinskii_moriya_Z_indices.max() >= config.N:
print("=" * 50)
print(
f"⚠️ Error: DM_Z interaction indices exceed the allowed range. All indices must be less than N-1 (N={config.system.N})."
)
print("=" * 50)
exit()
else:
print("=" * 50)
print("⚠️ Error: DM_Y should be .dat file.")
print("=" * 50)
exit()
# sod_x
sod_X_indices = None
sod_X = None
if not isinstance(config.SOD_X, DotMap):
if Path(config.SOD_X).suffix == ".dat":
sod_x_csv = pd.read_csv(config.SOD_X, delimiter=",", header=None)
sod_X_indices = sod_x_csv.iloc[:, :2].values
sod_X = sod_x_csv.iloc[:, 2:].values
if sod_X_indices.max() >= config.N:
print("=" * 50)
print(
f"⚠️ Error: SOD_X interaction indices exceed the allowed range. All indices must be less than N-1 (N={config.system.N})."
)
print("=" * 50)
exit()
# sod_y
sod_Y_indices = None
sod_Y = None
if not isinstance(config.SOD_Y, DotMap):
if Path(config.SOD_Y).suffix == ".dat":
sod_y_csv = pd.read_csv(config.SOD_Y, delimiter=",", header=None)
sod_Y_indices = sod_y_csv.iloc[:, :2].values
sod_Y = sod_y_csv.iloc[:, 2:].values
if sod_Y_indices.max() >= config.N:
print("=" * 50)
print(
f"⚠️ Error: SOD_Y interaction indices exceed the allowed range. All indices must be less than N-1 (N={config.system.N})."
)
print("=" * 50)
exit()
# sod_Z
sod_Z_indices = None
sod_Z = None
if not isinstance(config.SOD_Z, DotMap):
if Path(config.SOD_Z).suffix == ".dat":
sod_z_csv = pd.read_csv(config.SOD_Z, delimiter=",", header=None)
sod_Z_indices = sod_z_csv.iloc[:, :2].values
sod_Z = sod_z_csv.iloc[:, 2:].values
if sod_Z_indices.max() >= config.N:
print("=" * 50)
print(
f"⚠️ Error: SOD_Z interaction indices exceed the allowed range. All indices must be less than N-1 (N={config.system.N})."
)
print("=" * 50)
exit()
if config.model.type == "XXZ":
if interaction_coefs.shape[1] == 2:
hamiltonian = Hamiltonian(
config.N,
spin_sizes,
config.model.type,
interaction_indices,
interaction_coefs,
magnetic_field_X_indices=magnetic_field_X_indices,
magnetic_field_X=magnetic_field_X,
magnetic_field_Y_indices=magnetic_field_Y_indices,
magnetic_field_Y=magnetic_field_Y,
magnetic_field_Z_indices=magnetic_field_Z_indices,
magnetic_field_Z=magnetic_field_Z,
ion_anisotropy_indices=ion_anisotropy_indices,
ion_anisotropy=ion_anisotropy,
dzyaloshinskii_moriya_X_indices=dzyaloshinskii_moriya_X_indices,
dzyaloshinskii_moriya_X=dzyaloshinskii_moriya_X,
dzyaloshinskii_moriya_Y_indices=dzyaloshinskii_moriya_Y_indices,
dzyaloshinskii_moriya_Y=dzyaloshinskii_moriya_Y,
dzyaloshinskii_moriya_Z_indices=dzyaloshinskii_moriya_Z_indices,
dzyaloshinskii_moriya_Z=dzyaloshinskii_moriya_Z,
sod_X_indices=sod_X_indices,
sod_X=sod_X,
sod_Y_indices=sod_Y_indices,
sod_Y=sod_Y,
sod_Z_indices=sod_Z_indices,
sod_Z=sod_Z,
)
else:
print("=" * 50)
print("⚠️ Error: Please input two columns in model.file for XXZ model")
print("=" * 50)
exit()
elif config.model.type == "XYZ":
if interaction_coefs.shape[1] == 3:
hamiltonian = Hamiltonian(
config.N,
spin_sizes,
config.model.type,
interaction_indices,
interaction_coefs,
magnetic_field_X_indices=magnetic_field_X_indices,
magnetic_field_X=magnetic_field_X,
magnetic_field_Y_indices=magnetic_field_Y_indices,
magnetic_field_Y=magnetic_field_Y,
magnetic_field_Z_indices=magnetic_field_Z_indices,
magnetic_field_Z=magnetic_field_Z,
ion_anisotropy_indices=ion_anisotropy_indices,
ion_anisotropy=ion_anisotropy,
dzyaloshinskii_moriya_X_indices=dzyaloshinskii_moriya_X_indices,
dzyaloshinskii_moriya_X=dzyaloshinskii_moriya_X,
dzyaloshinskii_moriya_Y_indices=dzyaloshinskii_moriya_Y_indices,
dzyaloshinskii_moriya_Y=dzyaloshinskii_moriya_Y,
dzyaloshinskii_moriya_Z_indices=dzyaloshinskii_moriya_Z_indices,
dzyaloshinskii_moriya_Z=dzyaloshinskii_moriya_Z,
sod_X_indices=sod_X_indices,
sod_X=sod_X,
sod_Y_indices=sod_Y_indices,
sod_Y=sod_Y,
sod_Z_indices=sod_Z_indices,
sod_Z=sod_Z,
)
else:
print("=" * 50)
print("⚠️ Error: Please input three columns in model.file for XYZ model")
print("=" * 50)
exit()
else:
print("=" * 50)
print("⚠️ Error: Please input the correct model type (XXZ or XYZ)")
print("=" * 50)
exit()
return hamiltonian