from aiida import orm, load_profile, engine
_ = load_profile()
import numpy as np
import matplotlib.pyplot as plt
from aiida_kkr.tools import find_parent_structure, plot_kkr, kkrparams
from aiida_kkr.workflows import combine_imps_wc
from masci_tools.io.common_functions import get_alat_from_bravais
from aiida_kkr.calculations import VoronoiCalculation, KkrCalculation
import pandas as pd
import seaborn as sns
from tqdm import tqdm
from matplotlib.gridspec import GridSpec
Version of workflow: 0.7.2
def load_or_create_group(label):
try:
group = orm.load_group(label)
except:
group = orm.Group(label)
group.store()
return group
def get_builder_double_imp(impname1, impname2, add_pos):
# set offset
alat0 = get_alat_from_bravais(np.array(struc.cell))
offset_imp2 = orm.Dict({'index': 50, 'r_offset': add_pos[1]/alat0})
# imp 1 is always in layer 3
single_imp_calc1 = [node for node in group_single_imps_3.nodes if impname1 in node.label][0]
# imp2 in layer 3 or 4
if add_pos[2]==3:
single_imp_calc2 = [node for node in group_single_imps_3.nodes if impname2 in node.label][0]
else:
single_imp_calc2 = [node for node in group_single_imps_4.nodes if impname2 in node.label][0]
group_label = f'new_calcs/Bi2Te3/il_3_{add_pos[2]}_Off_{add_pos[3]}'
calc_label = f'{impname1}:{impname2}:' + group_label.split('/')[-1]
from aiida_kkr.workflows import combine_imps_wc
# set combine_imps inputs
builder = combine_imps_wc.get_builder()
builder.metadata.label = calc_label
return calc_label, group_label, builder
def relabel_kpts(bs):
"""
Relabel high-symmetry points to use convention from https://www.sciencedirect.com/science/article/pii/S0927025610002697?via%3Dihub
"""
k = bs.called[2].inputs.kpoints
klbls = []
k_rename = {
'GAMMA': r'$\Gamma$',
'T': 'Z',
'H_2': 'B',
'H_0': 'B1',
'L': 'L',
'S_0': 'P2',
'S_2': 'Q',
'F': 'F',
}
for i, (ik, klbl) in enumerate(k.labels):
if klbl in k_rename:
klbl = k_rename[klbl]
# print(i, ik, (k.labels[i+1][0]-ik)==1)
if (i==len(k.labels)-1 or i==0) or (abs(ik-k.labels[i+1][0])>1 and abs(ik-k.labels[i-1][0])>1):
klbls.append([ik, klbl])
elif k.labels[i+1][0]-ik==1:
klbl2 = k.labels[i+1][1]
if klbl2 in k_rename:
klbl2 = k_rename[klbl2]
klbl += '|'+klbl2
klbls.append([ik+0.5, klbl])
plt.xticks([i[0] for i in klbls], [i[1] for i in klbls])
def get_add_positions(struc):
"""Get all connecting vectors and distances for impurity dimer configurations"""
done_first = False
struc_aux = orm.StructureData(cell=struc.cell)
for site in struc.sites:
symbol = site.kind_name
if symbol in ['Te', 'Bi']:
if symbol=='Bi' and not done_first:
symbol = 'Sb'
done_first = True
struc_aux.append_atom(position=site.position, symbols=symbol)
ps = struc_aux.get_pymatgen()
dists = ([np.linalg.norm(i.coords - ps.sites[4].coords) for i in ps.get_all_neighbors(15)[4] if 'Bi' in i.species_string or 'Sb' in i.species_string])
dists_34 = ([np.linalg.norm(i.coords - ps.sites[4].coords) for i in ps.get_all_neighbors(15)[4] if 'Sb' in i.species_string])
dists_33 = ([np.linalg.norm(i.coords - ps.sites[4].coords) for i in ps.get_all_neighbors(15)[4] if 'Bi' in i.species_string])
pos_34 = -np.array([i.coords - ps.sites[4].coords for i in ps.get_all_neighbors(15)[4] if 'Sb' in i.species_string])
pos_33 = np.array([i.coords - ps.sites[4].coords for i in ps.get_all_neighbors(15)[4] if 'Bi' in i.species_string])
num_3, num_4 = 0, -1 # counters to keep track of offset index (for consistent labeling later on)
dists_unique = np.unique(np.round(dists, 3))
def get_r(idist, num_3, num_4):
try:
pp = pos_33[abs(np.linalg.norm(pos_33, axis=1) - dists_unique[idist]) < 1e-3]
if len(pp)==0:
msg = f'Error in getting pos_33: {idist}, {dists_unique[idist]}, {abs(np.linalg.norm(pos_34, axis=1) - dists_unique[idist]).min()}'
raise ValueError(msg)
R = pp[0]
num_3 += 1
return num_3, num_4, [np.linalg.norm(R), R, 3, num_3]
except:
pp = pos_34[abs(np.linalg.norm(pos_34, axis=1) - dists_unique[idist]) < 1e-3]
if len(pp)==0:
msg = f'Error in getting pos_34: {idist}, {dists_unique[idist]}, {abs(np.linalg.norm(pos_34, axis=1) - dists_unique[idist]).min()}'
raise ValueError(msg)
R = pp[0]
num_4 += 1
return num_3, num_4, [np.round(np.linalg.norm(R),3), R, 4, num_4]
add_positions = {}
for i in range(17):
num_3, num_4, add_positions[i] = get_r(i, num_3, num_4)
return add_positions
def get_imp_outputs(group, plot=False):
"""Extract output of single impurity calculation and plot data"""
print('label spin mom orb. mom rms of calc charge neutrality of imp.')
print(75*'-')
out, names = [], []
for impname in impname_all_3d4d:
nodes = [node for node in group.nodes if impname in node.label]
if len(nodes)==0:
print(impname, 'not found in group')
else:
node = nodes[0]
if node.is_finished_ok:
o = node.outputs.last_calc_output_parameters.get_dict()
o = node.outputs.last_calc_output_parameters.get_dict()
rms =o['convergence_group']['rms']
ms = o['magnetism_group']['spin_moment_per_atom'][0][2]
mo = o['magnetism_group']['orbital_moment_per_atom'][0][2]
if ms<0:
# flip spin and orbital moment to point in +z if necessary
mo *= -1
ms *= -1
charge_neutr = o['total_charge_per_atom'][0] - node.inputs.impurity_info['Zimp']
print(f'{node.label:15} {np.round(ms,3):7} {np.round(mo,3):7} {rms:15} {charge_neutr}')
out.append([ms, mo])
else:
print(node.label, 'not done yet. pk:', node.pk)
out.append([np.NaN, np.NaN])
names.append(impname)
if plot and len(out)>0:
plt.figure(figsize=(8,4))
plt.subplot(1,2,1)
out = np.array(out)
plt.axhline(0, ls=':', color='C0')
plt.plot(out[:,0], 'o--')
m = np.where(abs(np.nan_to_num(out)[:,0])<1e-3)
plt.plot(np.arange(len(out))[m], out[m][:,0], 'o', color='w', ms=3)
plt.ylabel(r'spin moment ($\mu_B$)', color='C0')
plt.xticks(np.arange(len(out)), [ '\n'*(i%2) + n for i, n in enumerate(names)])
plt.axvline(9.5, color='grey', ls=':')
plt.subplot(1,2,2)
plt.axhline(0, ls=':', color='C1')
plt.plot(out[:,1], 'o--', color='C1')
plt.plot(np.arange(len(out))[m], out[m][:,0], 'o', color='w', ms=3)
plt.ylabel(r'orbital moment ($\mu_B$)', color='C1')
plt.xticks(np.arange(len(out)), [ '\n'*(i%2) + n for i, n in enumerate(names)])
plt.axvline(9.5, color='grey', ls=':')
plt.tight_layout()
# save figures to files?
savefigs = False
# mappings of Zimp to element names
Zimp_all_3d4d = list(range(21, 31)) + list(range(39, 49))
impname_all_3d4d = 'Sc Ti V Cr Mn Fe Co Ni Cu Zn Y Zr Nb Mo Tc Ru Rh Pd Ag Cd'.split()
impname_from_Zimp = {Z: impname_all_3d4d[i] for i, Z in enumerate(Zimp_all_3d4d)}
%%capture --no-stdout --no-display
# load data
dos = orm.load_node('5da28b6c-563d-4256-993b-c6374d187dfe')
bs = orm.load_node('2be554d9-31af-4398-9b81-8b41a13e15be')
# create figure
fig = plt.figure(figsize=(9,6))
gs = GridSpec(1, 3, figure=fig)
ax1 = fig.add_subplot(gs[0, :2])
plot_kkr(bs, silent=True, cmap='binary', clim=(0, None), nofig=True, show_cbar=False, noshow=True)
plt.title('')
plt.ylim(-5,3)
plt.ylabel(r'$E-E_\mathrm{F}$ (eV)')
relabel_kpts(bs)
ax2 = fig.add_subplot(gs[0, 2])
plot_kkr(dos, silent=True, sum_spins=True, switch_xy=True, noshow=True, nofig=True, l_channels=False, lw=2)
plt.axhline(0, color='r', ls=':', lw=2)
plt.ylim(-5,3)
plt.title('')
plt.ylabel('')
plt.xlabel('DOS (1/eV)')
ax2.yaxis.tick_right()
plt.tight_layout()
plt.subplots_adjust(wspace=0.02)
if savefigs:
plt.savefig('Bi2Te3_DOS_bs.svg')
plt.show()
# load host structure
struc = orm.load_node('c1626804-5b71-450c-91c4-aa7197d85279')
# create duplicate structure for cif file without the empty sites used by the KKR formalism
cell_new = np.array(struc.cell)
struc_aux = orm.StructureData(cell=cell_new)
for isite, site in enumerate(struc.sites[:5]):
pos = site.position
if isite!=0:
pos -= 2*cell_new[2]
struc_aux.append_atom(position=pos, symbols=site.kind_name)
ps = struc_aux.get_pymatgen()
ps.get_primitive_structure()
# with open('Bi2Te3.cif', 'w') as _f:
# _f.writelines(struc_aux.get_cif().get_content())
# plot_kkr(struc_aux, silent=True, static=True)
Structure Summary Lattice abc : 10.472657559692419 10.472657559692419 10.472657559692438 angles : 24.157680577616187 24.157680577616187 24.157680577615878 volume : 169.06740315520517 A : 2.1914815820078 1.2652524812963 10.162337378619 B : -2.1914815820078 1.2652524812963 10.162337378619 C : -8.1101110346236e-17 -2.5305049625927 10.162337378619 pbc : True True True PeriodicSite: Te (0.0, 0.0, 0.0) [0.0, 0.0, 0.0] PeriodicSite: Te (-4.903e-16, 7.592, 6.463) [1.212, 1.212, -1.788] PeriodicSite: Te (-1.825e-16, 5.061, 3.699) [0.788, 0.788, -1.212] PeriodicSite: Bi (2.191, 6.326, 2.032) [1.4, 0.4, -1.6] PeriodicSite: Bi (2.191, 6.326, 8.13) [1.6, 0.6, -1.4]
# get impurity configurations (distance, connecting vectors etc.)
add_positions = get_add_positions(struc)
# load groups for single imp. calculations
group_single_imps_3 = load_or_create_group('single_imps:Bi2Te3_il_3')
group_single_imps_4 = load_or_create_group('single_imps:Bi2Te3_il_4')
%%capture --no-stdout --no-display
from aiida_kkr.workflows import kkr_imp_sub_wc
for iadd in range(17):
calc_label, group_label, builder = get_builder_double_imp('Mn', 'Mn', add_positions[iadd])
group_double_imps = load_or_create_group(group_label)
calc = [n for n in group_double_imps.nodes if n.label==calc_label][0]
calc = calc.get_outgoing(node_class=kkr_imp_sub_wc).first().node
if savefigs:
plot_kkr(calc, strucplot=True, silent=True, static=True)
# plot single impurity spin and orbital moments
get_imp_outputs(group_single_imps_3, plot=True)
if savefigs:
plt.savefig('Bi2Te3_single_imps_mag.svg')
label spin mom orb. mom rms of calc charge neutrality of imp. --------------------------------------------------------------------------- Sc:Bi2Te3_il_3 0.0 -0.0 9.5432e-08 -1.2717980000000004 Ti:Bi2Te3_il_3 0.838 0.051 7.6547e-08 -1.1305189999999996 V:Bi2Te3_il_3 2.655 0.035 8.0752e-08 -0.9281010000000016 Cr:Bi2Te3_il_3 3.822 -0.055 7.9519e-08 -0.8107809999999986 Mn:Bi2Te3_il_3 4.412 -0.054 6.4814e-08 -0.8007449999999992 Fe:Bi2Te3_il_3 3.375 -0.267 4.7912e-08 -0.6753490000000006 Co:Bi2Te3_il_3 2.104 -0.344 8.4998e-08 -0.5109250000000003 Ni:Bi2Te3_il_3 0.92 -0.128 5.1966e-08 -0.388539999999999 Cu:Bi2Te3_il_3 0.0 0.0 6.9722e-08 -0.3594790000000003 Zn:Bi2Te3_il_3 0.0 0.0 9.0272e-08 -0.5750600000000006 Y:Bi2Te3_il_3 0.0 0.0 9.96e-08 -1.658811 Zr:Bi2Te3_il_3 0.0 0.0 9.4709e-08 -1.713476 Nb:Bi2Te3_il_3 1.219 0.102 9.383e-08 -1.4920609999999996 Mo:Bi2Te3_il_3 2.575 -0.029 5.3193e-08 -1.2540729999999982 Tc:Bi2Te3_il_3 2.237 -0.228 4.8877e-09 -1.0623369999999994 Ru:Bi2Te3_il_3 0.225 -0.08 3.8292e-08 -0.8079919999999987 Rh:Bi2Te3_il_3 0.0 -0.0 6.2622e-08 -0.6396269999999973 Pd:Bi2Te3_il_3 0.0 -0.0 5.5765e-08 -0.5337600000000009 Ag:Bi2Te3_il_3 0.0 -0.0 5.5227e-08 -0.5989879999999985 Cd:Bi2Te3_il_3 0.0 0.0 8.6775e-08 -0.8821349999999981
# extract single impurity moments, used later again
impnames = [n.label.split(':')[0] for n in group_single_imps_3.nodes]
moments = [n.outputs.last_calc_output_parameters['magnetism_group']['spin_moment_per_atom'][0][2] for n in group_single_imps_3.nodes]
single_imp_moments = {l: abs(moments[i]) for i,l in enumerate(impnames)}
group_DOS = load_or_create_group('Bi2Te3/single_imps_DOS')
i = 0
Delta_xc = []
plt.figure(figsize=(8, 10))
for impname in impname_all_3d4d:
node = [n for n in group_DOS.nodes if impname in n.label][0]
if node.is_finished_ok:
if i<10:
plt.subplot(3,1,1)
else:
plt.subplot(3,1,2)
_, x, _ = node.outputs.dos_data_interpol.get_x()
x = x[0]
_, y, _ = node.outputs.dos_data_interpol.get_y()[0] # total
plt.plot(x, y[0], color=f'C{i}', label=node.label.split(':')[0], lw=3)
plt.plot(x, -y[1], color=f'C{i}', lw=3)
Delta_xc += [abs(x[y[0]==y[0].max()] - x[y[1]==y[1].max()])]
i+=1
Delta_xc = np.array(Delta_xc)[:,0]
for i in range(2):
plt.subplot(3,1,1+i)
plt.xlim(-3.5, 2)
plt.axvline(0, color='k', ls='--')
if i==0:
plt.yticks([-25, -20, -15, -10, -5, 0, 5, 10, 15], fontsize=12)
plt.ylim(-25)
else:
plt.yticks([-12.5, -10, -7.5, -5, -2.5, 0, 2.5, 5, 7.5], fontsize=12)
plt.xlabel(r'$E-E_\mathrm{F}$ (eV)', fontsize=14)
plt.ylim(-14)
plt.ylabel('DOS (1/eV)', fontsize=14)
plt.xticks([-3, -2, -1, 0, 1, 2], fontsize=12)
plt.legend(ncol=5, loc=3, fontsize=12)
plt.subplot(3,1,3)
x = np.array(Zimp_all_3d4d, dtype=float)
x[10:] -= 7.5
plt.axhline(0, color='grey', ls=':')
plt.plot(x[:10], Delta_xc[:10], 'o--', lw=3, ms=10, color='C0', label=r'$3d$ impurities')
plt.plot(x[10:], Delta_xc[10:], 'o--', lw=3, ms=10, color='C1', label=r'$4d$ impurities')
plt.plot(x[Delta_xc==0], Delta_xc[Delta_xc==0], 'o', ms=5, color='w')
plt.xticks(x, impname_all_3d4d, fontsize=14)
plt.yticks([0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5], fontsize=14)
plt.ylabel(r'$\Delta_{xc}$ (eV)', fontsize=14)
plt.legend(fontsize=12)
plt.tight_layout()
plt.annotate(xy=(0.01, 0.97), text='(a)', xycoords='figure fraction', fontsize=19)
plt.annotate(xy=(0.01, 0.64), text='(b)', xycoords='figure fraction', fontsize=19)
plt.annotate(xy=(0.01, 0.30), text='(b)', xycoords='figure fraction', fontsize=19)
if savefigs:
plt.savefig('imp_DOS.pdf')
plt.show()
# !verdi archive create -G 'Bi2Te3/single_imps_DOS' --compress 9 -f 'export_DOS.aiida'
# !du -sch export_DOS.aiida
def get_dat_from_node(node, reload=False):
"""Get data from node (neighbor index, radius, Zimp, ..., Jij)"""
if 'Jij_data' in node.extras and not reload:
# load from extra
dat = node.extras['Jij_data']
else:
# load from node if not found as extra already
imp1, imp2, off = node.label.split(':')
# data.append([add_positions[iadd][0], imp1, imp2])
Zimp1, Zimp2 = node.outputs.workflow_info['imps_info_in_exact_cluster']['Zimps']
m1, m2 = np.array(node.outputs.workflow_info['magmoms'])[[0,20]]
J = node.outputs.JijData.get_array('JijData')[0,3]
m01 = single_imp_moments[impname_from_Zimp[Zimp1]]
m02 = single_imp_moments[impname_from_Zimp[Zimp2]]
uuid_JijData = node.outputs.JijData.uuid
r = add_positions[iadd][1]
dat = [iadd, add_positions[iadd][0], r[0], r[1], r[2], add_positions[iadd][2], Zimp1, Zimp2, num_neighbors, m1, m2, m01, m02, J, uuid_JijData]
node.set_extra('Jij_data', dat)
return dat
def get_R_num_neighbor(iadd):
"""Extract shell Radius, ilayer index and number of neighbors per shell"""
R, _, il, _ = add_positions[iadd]
num_neighbors = len([i for i in ps.get_neighbors_in_shell(origin=ps.sites[3].coords, r=R, dr=0.02) if i.species_string in ['Bi', 'Sb']])
return R, il, num_neighbors
def get_all_equivalent_R(iadd):
"""Extract all equivalent positions for a shell"""
R, _, il, _ = add_positions[iadd]
all_neighbors =np.array( [i.coords for i in ps.get_neighbors_in_shell(origin=ps.sites[3].coords, r=R, dr=0.02) if i.species_string in ['Bi', 'Sb']])
return all_neighbors
from pandas import DataFrame, read_csv
try:
df = read_csv('Jij_table.csv', usecols=range(1,16))
data_all = df.to_numpy()
print('loaded data from csv file')
except:
# load from aiida DB
reload = False
data_all = []
for iadd in range(17):
data = []
_, group_label, _ = get_builder_double_imp('Mn', 'Mn', add_positions[iadd])
group_double_imps = load_or_create_group(group_label)
R, il, num_neighbors = get_R_num_neighbor(iadd)
for node in tqdm(group_double_imps.nodes):
if node.is_finished_ok:
dat = get_dat_from_node(node, reload=reload)
data.append(dat)
if len(data)>0:
data_all += data
data_all = np.array(data_all)
# convert to pandas dataframe
df = DataFrame(data_all, columns='i_shell R Rx Ry Rz ilayer2 Zimp1 Zimp2 num_neighbors m1 m2 m01 m02 J J_data_uuid'.split())
# write to file
df.to_csv('Jij_table.csv')
df
loaded data from csv file
i_shell | R | Rx | Ry | Rz | ilayer2 | Zimp1 | Zimp2 | num_neighbors | m1 | m2 | m01 | m02 | J | J_data_uuid | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 4.382963 | -4.382963 | 4.440892e-16 | 3.552714e-15 | 3 | 25 | 25 | 6 | 4.407155e+00 | 4.406440e+00 | 4.412136e+00 | 4.412136e+00 | -2.390368e+00 | c5aebb74-fe53-4deb-87b5-2fc404c5515d |
1 | 0 | 4.382963 | -4.382963 | 4.440892e-16 | 3.552714e-15 | 3 | 21 | 21 | 6 | -2.790808e-08 | -3.555508e-08 | 8.954006e-10 | 8.954006e-10 | -1.403952e-14 | 8d601f7d-3208-4985-9618-aedfd6b1794a |
2 | 0 | 4.382963 | -4.382963 | 4.440892e-16 | 3.552714e-15 | 3 | 21 | 22 | 6 | 5.448661e-05 | 8.249654e-01 | 8.954006e-10 | 8.376878e-01 | 1.268217e-02 | 4e51812f-67c0-4aed-ad98-ca12f4bfcd94 |
3 | 0 | 4.382963 | -4.382963 | 4.440892e-16 | 3.552714e-15 | 3 | 21 | 23 | 6 | 3.450025e-03 | 2.645953e+00 | 8.954006e-10 | 2.654750e+00 | 5.595529e-02 | 7450d4f3-fa82-46f4-8f3a-2e83beb7447d |
4 | 0 | 4.382963 | -4.382963 | 4.440892e-16 | 3.552714e-15 | 3 | 21 | 24 | 6 | 4.139466e-03 | 3.815054e+00 | 8.954006e-10 | 3.821704e+00 | 3.846999e-02 | 22c432f3-a0c4-4535-8a6e-276af0ee698e |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2072 | 16 | 12.169523 | -4.382963 | -5.061010e+00 | -1.016234e+01 | 3 | 41 | 43 | 12 | 1.219888e+00 | 5.017296e-03 | 1.218793e+00 | 2.236967e+00 | 9.496666e-02 | 8564141b-e7e2-46cb-b640-5cd52b933522 |
2073 | 16 | 12.169523 | -4.382963 | -5.061010e+00 | -1.016234e+01 | 3 | 42 | 42 | 12 | 2.575095e+00 | 1.162002e-02 | 2.575066e+00 | 2.575066e+00 | 9.700414e-02 | ea8c30f4-d92e-4444-a350-8457f4230681 |
2074 | 16 | 12.169523 | -4.382963 | -5.061010e+00 | -1.016234e+01 | 3 | 42 | 43 | 12 | 2.575201e+00 | 1.163527e-02 | 2.575066e+00 | 2.236967e+00 | 1.052456e-01 | 32c8c923-8a5d-426e-a1c9-c12ac0793310 |
2075 | 16 | 12.169523 | -4.382963 | -5.061010e+00 | -1.016234e+01 | 3 | 43 | 43 | 12 | 2.237093e+00 | 9.554635e-03 | 2.236967e+00 | 2.236967e+00 | 3.642698e-02 | 074d238a-8092-4f2a-ad6f-374877c2076f |
2076 | 16 | 12.169523 | -4.382963 | -5.061010e+00 | -1.016234e+01 | 3 | 43 | 44 | 12 | 2.238531e+00 | 9.572239e-03 | 2.236967e+00 | 2.252663e-01 | 5.479927e-03 | d5fc4340-81bb-443e-9ad3-cbb2dcd50fe8 |
2077 rows × 15 columns
# count number of magnetic combinations
dd = data_all[data_all[:,-5]>1e-3]
dd = dd[dd[:,-3]>1e-3]
# total pairs, magnetic pairs
len(data_all), len(dd), np.round(len(dd)/len(data_all),2)
(2077, 876, 0.42)
def get_d_part(Zimp):
dd = data_all[data_all[:,6]==Zimp]
return dd
def get_m_change(Zimp, plot=True):
dd = get_d_part(Zimp)
m0 = dd[0,-4]
if plot:
plt.scatter(x=dd[:,1], y=dd[:,-6], c=dd[:,7], cmap='Spectral', )
plt.axhline(m0)
plt.twinx()
plt.scatter(x=dd[:,1], y=100*(dd[:,-6]-m0)/m0, c=dd[:,9], cmap='Spectral', )
return m0, dd
def get_data_delta_m1(iadd = 0):
arr = np.zeros((20, 20))
# arr[:,:] = np.NaN
arr2 = arr.copy()
for i, Zimp in enumerate(Zimp_all_3d4d):
m0, dat = get_m_change(Zimp, plot=False)
dd = dat[dat[:,1]==add_positions[iadd][0]]
for j, Zimp2 in enumerate(Zimp_all_3d4d):
ddd = dd[dd[:,7]==Zimp2]
if len(ddd)>0:
arr[i, j] = ddd[0, -6] - ddd[0, -4]
arr2[i, j] = ddd[0, -5] - ddd[0, -3]
# arr[i, j] = abs(ddd[0, -6]) - abs(ddd[0, -4])
# arr2[i, j] = abs(ddd[0, -5]) - abs(ddd[0, -3])
arr22 = arr2.copy()
for i in range(len(arr)):
arr22[i,i] = 0
dat = np.nan_to_num(arr) + np.nan_to_num(arr22).transpose()
return dat, arr, arr2
def plot_delta_m1(iadd=0, figsize=(16,6), **kwargs):
dat, arr, arr2 = get_data_delta_m1(iadd)
moms = np.zeros((20,20))
for i, Zimp in enumerate(Zimp_all_3d4d):
m0, _ = get_m_change(Zimp, plot=False)
moms[i,:] = m0
plt.figure(figsize=figsize)
plt.subplot(1,2,1)
g = sns.heatmap(dat, cmap='seismic', center=0, square=True, vmin=-0.5, vmax=0.3, **kwargs)
plt.xlabel('impurity 2', fontsize='large')
plt.ylabel('impurity 1', fontsize='large')
print(np.max(abs(dat), axis=1))
plt.xticks(np.arange(len(Zimp_all_3d4d))+0.5, impname_all_3d4d)
plt.yticks(np.arange(len(Zimp_all_3d4d))+0.5, impname_all_3d4d)
# g.set_facecolor('lightgrey')
plt.title(r'$\Delta_{m_1}$ ($\mu_B$)', fontsize='large')
[f(i, color='grey') for f in [plt.axhline] for i in [1,8, 12, 16]]
plt.annotate(xy=(0.39, 0.91), text=r'$\iota$', xycoords='figure fraction' )
plt.annotate(xy=(0.39, 0.76), text=r'$\mu$', xycoords='figure fraction' )
plt.annotate(xy=(0.39, 0.51), text=r'$\iota$', xycoords='figure fraction' )
plt.annotate(xy=(0.39, 0.36), text=r'$\mu$', xycoords='figure fraction' )
plt.annotate(xy=(0.39, 0.18), text=r'$\iota$', xycoords='figure fraction' )
plt.subplot(1,2,2)
arr22 = arr2.copy()
for i in range(len(arr)):
arr22[i,i] = 0
dat = np.nan_to_num(arr) + np.nan_to_num(arr22).transpose()
dat = dat / moms * 100
dat[abs(moms)<1e-1] = np.NaN
print('rel')
print(np.max(np.nan_to_num(abs(dat)), axis=1))
g = sns.heatmap(dat, cmap='seismic', center=0, vmin=-50, vmax=20, square=True, **kwargs)
plt.xlabel('impurity 2', fontsize='large')
plt.ylabel('impurity 1', fontsize='large')
plt.xticks(np.arange(len(Zimp_all_3d4d))+0.5, impname_all_3d4d)
plt.yticks(np.arange(len(Zimp_all_3d4d))+0.5, impname_all_3d4d)
g.set_facecolor('lightgrey')
plt.title(r'$\Delta_{m_1}/m_1$ (%)', fontsize='x-large')
plt.tight_layout()
plt.subplots_adjust(wspace=0.1)
plt.annotate(xy=(0.02, 0.95), text="(a)", xycoords='figure fraction', fontsize=18)
plt.annotate(xy=(0.52, 0.95), text="(b)", xycoords='figure fraction', fontsize=18)
plot_delta_m1(iadd=0, annot=False)
if savefigs:
plt.savefig('change_m1.svg')
plt.show()
[0.01413579 0.24851188 0.06016112 0.0382715 0.02018017 0.02779272 0.04246742 0.06919043 0.02168747 0.01470566 0.00672862 0.03485266 0.27980025 0.06404894 0.13006274 0.48361186 0.09944406 0.08621498 0.01264877 0.01003735] rel [ 0. 29.66640936 2.26616873 1.00142508 0.45737869 0.82354688 2.01826779 7.51878274 0. 0. 0. 0. 22.95716305 2.48727369 5.81424528 214.68455519 0. 0. 0. 0. ]
def reshape_data_to_arr(data, plot_J=True):
data = np.array(data)
Zimp_all_3d4d = list(range(21, 31)) + list(range(39, 49))
impname_all_3d4d = 'Sc Ti V Cr Mn Fe Co Ni Cu Zn Y Zr Nb Mo Tc Ru Rh Pd Ag Cd'.split()
arr = np.zeros((len(Zimp_all_3d4d), len(Zimp_all_3d4d)))
arr[:,:] = np.NaN
for i1, Z1 in enumerate(Zimp_all_3d4d):
for i2, Z2 in enumerate(Zimp_all_3d4d):
d = data[data[:,6]==Z1]
# print(len(d))
if len(d)>0:
dd = d[d[:,7]==Z2]
if len(dd)>0:
if plot_J:
arr[i1, i2] = dd[0][-2]
else:
arr[i1, i2] = dd[0][-4] + dd[0][-3]
if i1 != i2:
arr[i2, i1] = arr[i1, i2]
return arr
def get_and_plot_data(iadd = 0, plot_J=True, reload=False, vlim=None, hide_threshold=None, **kwargs):
data = data_all[data_all[:,0]==iadd]
if len(data)>0:
arr = reshape_data_to_arr(data)
if hide_threshold is not None:
arr[abs(arr)<hide_threshold] = 0 #np.NaN
import seaborn as sns
# plt.figure(figsize=(18,14))
ivm = 1
cmap='seismic'
if vlim is None:
vlim = abs(np.nan_to_num(arr)).max()
if not plot_J:
ivm = 0
cmap='viridis'
p = sns.heatmap(arr, cmap=cmap, vmin=ivm * -vlim, vmax=vlim, **kwargs)
R, _, il1, ioff = add_positions[iadd]
plt.title(f'3-{il1}:{ioff} (R={R:.3f} Ang.)'.replace('3-3', '1-1').replace('3-4', '1-2'))
plt.xticks(np.arange(len(Zimp_all_3d4d))+0.5, impname_all_3d4d)
plt.yticks(np.arange(len(Zimp_all_3d4d))+0.5, impname_all_3d4d)
plt.figure(figsize=(20,12))
for iadd in range(5):
plt.subplot(2,3,1+iadd)
get_and_plot_data(iadd, reload=False, hide_threshold=0.1, vlim=20, cbar=True, square=True, center=0, annot=True, annot_kws={"fontsize": 7}, fmt=".1g")
plt.tight_layout()
if savefigs:
plt.savefig('Jij_maps_all.pdf')
plt.show()
plt.figure(figsize=(20,15))
for i, iadd in enumerate(range(5, 17)):
plt.subplot(3,4,1+i)
get_and_plot_data(iadd, reload=False, cbar=True, square=True, center=0, annot=False, annot_kws={"fontsize": 8}, fmt=".1f")
plt.tight_layout()
if savefigs:
plt.savefig('Jij_maps_all.svg')
plt.show()
# get only magnetic atoms
dd = np.array(data_all[data_all[:,11]>1e-1][:, :-1], dtype=float)
dd = dd[dd[:,12]>1e-1]
plt.figure()
plt.axhline(0, ls=':', color='grey')
for i, Zimp in enumerate(Zimp_all_3d4d[:]):
ddd = dd[dd[:,6]==Zimp]
if len(ddd)>0:
marker = 'o v ^ < > s P * X D'.split()[i%10]
size = 16
if Zimp>=30:
size=13
c = ddd[:,7]
c[c>30] -= 7
plt.scatter(ddd[:, 1], ddd[:, -1], c=ddd[:,7], alpha=0.5, cmap='Spectral',
marker=marker, s=size, label=impname_from_Zimp[Zimp],
vmin=21, vmax=48-7, lw=1)
plt.legend(ncol=3)
cb = plt.colorbar()
cl = np.array(Zimp_all_3d4d)
cl[cl>30] -= 7
cb.set_ticks(cl, labels=impname_all_3d4d)
plt.xlabel(r'$R_{ij}$ ($\AA$)')
plt.ylabel(r'$J_{ij}$ (meV)')
# inset
axin1 = plt.gca().inset_axes([0.46, 0.08, 0.5, 0.4])
x0 = np.unique(np.round(dd[:,1],3))
y0 = [np.max(abs(dd[np.round(dd[:,1],3)==i][:,-1])) for i in x0]
# select datapoints without the outlier at ~6.5 Ang for fitting
x1 = np.array([x0[i] for i in range(len(x0)) if i !=3])
y1 = np.array([y0[i] for i in range(len(y0)) if i !=3])
axin1.plot(x0, y0, '--', color='C7', lw=1)
ddd_z, ddd_xy, i_z, i_xy = [], [], [], []
for i, iadd in enumerate(dd[:,0]):
z = dd[i, 4]
if abs(z)>5:
ddd_z.append(dd[i])
i_z.append(iadd)
else:
ddd_xy.append(dd[i])
i_xy.append(iadd)
ddd_z, ddd_xy, i_z, i_xy = np.array(ddd_z), np.array(ddd_xy), np.array(i_z, dtype=int), np.array(i_xy, dtype=int)
i_z, i_xy = np.unique(i_z), np.unique(i_xy)
for il, ddd in enumerate([ddd_xy, ddd_z]):
x = np.unique(np.round(ddd[:,1],3))
y = [np.max(abs(ddd[np.round(ddd[:,1],3)==i][:,-1])) for i in x]
axin1.plot(x, y, {0: 'o', 1:'s', 3: 'o', 4: 's'}[il], color={0:'C0', 1:'C1', 3: 'C0', 4: 'C1'}[il],
ms=5, label={0:'intra-QL', 1:'inter-QL', 3: '1-1', 4: '1-2'}[il])
axin1.axhline(0, color='grey', ls=':')
# fitting of exponential decay
from scipy.optimize import curve_fit
def fitfunc(x, a, b):
return a*np.exp(-x/b)
popt, pcov = curve_fit(fitfunc, x1, y1)
xx = np.linspace(4, 12.5, 1000)
axin1.plot(xx, fitfunc(xx, *popt), ls='--', color='C3', label=r'$\exp{(-R/\lambda)}$')
axin1.legend(loc=0)
axin1.set_xlim(4, 12.5)
plt.xlim(4, 12.5)
plt.tight_layout()
if savefigs:
plt.savefig('Jij_radial.pdf')
plt.show()
print('# of Jij calculations:', len(dd))
print('Fit parameter:', popt)
# of Jij calculations: 1070 Fit parameter: [215.21628609 1.79254668]
plt.figure(figsize=(16,6))
plt.subplot(1,3,1)
plt.plot(x0, y0, '--', color='grey', lw=2)
for il, ddd in enumerate([ddd_xy, ddd_z]):
x = np.unique(np.round(ddd[:,1],3))
y = [np.max(abs(ddd[np.round(ddd[:,1],3)==i][:,-1])) for i in x]
plt.plot(x, y, {0: 'o', 1:'s', 3: 'o', 4: 's'}[il], color={0:'C0', 1:'C1', 3: 'C0', 4: 'C1'}[il],
ms=8, label={0:'intra-QL', 1:'inter-QL', 3: '1-1', 4: '1-2'}[il])
plt.axhline(0, color='grey', ls=':')
plt.ylabel(r'$\max_{R_{ij}}(|J_{ij}|)$ (meV)', color='k', fontsize='large')
plt.xlim(4, 12.5)
plt.xlabel(r'$R_{ij}$ ($\AA$)', fontsize='large')
plt.subplot(1,3,2)
z = np.array([[i[0], i[1][2]] for i in add_positions.values()])
z0 = np.unique(np.round(z, 2))
plt.plot(z[:,0], z[:,1], ':', color='grey', lw=2)
plt.plot(z[[i_xy]][0,:,0], z[[i_xy]][0,:,1], 'o', color='C0', ms=8)
plt.plot(z[[i_z]][0,:,0], z[[i_z]][0,:,1], 's', color='C1', ms=8)
plt.axhline(0, ls='--', color='k')
plt.axhline(z0[1], ls='--', color='k')
plt.axhline(0+z0[0], ls='--', color='k')
plt.axhline(0-z0[0], ls='--', color='k')
plt.axhline(z0[1]-z0[0], ls='--', color='k')
xx =np.linspace(3, 13, 2)
plt.fill_between(xx, xx*0+z0[1]/2-z0[0]/2, xx*0+z0[1]/2+z0[0]/2, alpha=0.2, color='C1')
plt.ylabel(r'$R_z$ ($\AA$)', color='k', fontsize='large')
plt.xlim(4, 12.5)
plt.xlabel(r'$R_{ij}$ ($\AA$)', fontsize='large')
plt.subplot(1,3,3)
for il, ddd in enumerate([ddd_xy, ddd_z]):
x, isort = np.unique(np.round(ddd[:,1],3), return_index=True)
y = [np.max(abs(ddd[np.round(ddd[:,1],3)==i][:,8])) for i in x]
plt.plot(x, y, {0: 'o', 1:'s', 3: 'o', 4: 's'}[il], color={0:'C0', 1:'C1', 3: 'C0', 4: 'C1'}[il],
ms=8, label={0:'intra-QL', 1:'inter-QL', 3: '1-1', 4: '1-2'}[il])
plt.ylabel('# of neighbors in shell', fontsize='large')
plt.ylim(0)
plt.xlim(4, 12.5)
plt.xlabel(r'$R_{ij}$ ($\AA$)', fontsize='large')
plt.tight_layout()
plt.annotate(xy=(0.005, 0.95), text='(a)', xycoords='figure fraction', fontsize='18')
plt.annotate(xy=(0.335, 0.95), text='(b)', xycoords='figure fraction', fontsize='18')
plt.annotate(xy=(0.675, 0.95), text='(c)', xycoords='figure fraction', fontsize='18')
if savefigs:
plt.savefig('Jij_geometry_inter-intra.pdf')
plt.show()
kB = 8.6173324e-5 # eV / K
# prefac = 1e-3 * 2/3 / kB
prefac = 1e-3 * 1/3 / kB # 1/3 instead of 2/3 due to definition of Heisenberg Hamiltonian
def get_Tc(imp1, imp2, plot=False, mark_dists=False):
d = data_all[data_all[:,6]==imp1]
dd = d[d[:,7]==imp2]
if plot:
plt.plot(dd[:,1], dd[:,-1], '--', color='C0')
ddd = dd[dd[:,5]==3]
plt.plot(ddd[:,1], ddd[:,-1], 'o', color='C0', label='1-1')
ddd = dd[dd[:,5]==4]
plt.plot(ddd[:,1], ddd[:,-1], 's', color='C0', label='1-2')
plt.legend(loc=5)
plt.ylabel(r'$N\cdot J_{ij}$ (meV)', color='C0')
plt.axhline(0, ls=':', color='C0')
plt.xlabel(r'$R_{ij}$ ($\AA$)')
plt.twinx()
Tcs = np.array([np.sum(dd[:1+i,-2]*dd[:1+i,5]) * prefac for i in range(len(dd))])
plt.plot(dd[:,1], Tcs, '-', color='C1')
plt.plot(dd[:,1][dd[:,5]==3], Tcs[dd[:,5]==3], 'o', color='C1')
plt.plot(dd[:,1][dd[:,5]==4], Tcs[dd[:,5]==4], 's', color='C1')
plt.ylabel('$T_c$ (K/c)', color='C1')
# plt.axhline(0, ls=':', color='C1')
plt.xlim(4, 12.5)
plt.tight_layout()
if mark_dists:
plt.axvline(np.min(np.round(dists_33, 3)), ls=':', color='r', label='33')
[plt.axvline(i, ls=':', color='r') for i in np.unique(np.round(dists_33, 3))[1:]]
plt.axvline(np.min(np.round(dists_34, 3)), ls=':', color='m', label='34')
[plt.axvline(i, ls=':', color='m') for i in np.unique(np.round(dists_34, 3))[1:]]
Tc = np.sum(dd[:,-2]*dd[:,8]) * prefac
Tc1 = np.sum(dd[1:,-2]*dd[1:,8]) * prefac
ddd_z, ddd_xy = [], []
for i, iadd in enumerate(dd[:,0]):
z = add_positions[iadd][1][2]
if abs(z)>5:
ddd_z.append(dd[i])
else:
ddd_xy.append(dd[i])
ddd_z, ddd_xy = np.array(ddd_z), np.array(ddd_xy)
Tc_xy = np.sum(ddd_xy[:,-2]*ddd_xy[:,8]) * prefac
Tc_z = np.sum(ddd_z[:,-2]*ddd_z[:,8]) * prefac
return Tc, Tc1, Tc_xy, Tc_z
Zimp_all_3d4d = list(range(21, 31)) + list(range(39, 49))
impname_all_3d4d = 'Sc Ti V Cr Mn Fe Co Ni Cu Zn Y Zr Nb Mo Tc Ru Rh Pd Ag Cd'.split()
Tcs = np.zeros((len(impname_all_3d4d), len(impname_all_3d4d)))
Tcs[:,:] = np.NaN
Tcs1 = Tcs.copy()
Tcs_xy = Tcs.copy()
Tcs_z = Tcs.copy()
for imp1 in range(len(impname_all_3d4d)):
for imp2 in range(imp1, len(impname_all_3d4d)):
Tcs[imp1, imp2], Tcs1[imp1, imp2], Tcs_xy[imp1, imp2], Tcs_z[imp1, imp2] = get_Tc(Zimp_all_3d4d[imp1], Zimp_all_3d4d[imp2])
for imp1 in range(len(impname_all_3d4d)):
for imp2 in range(imp1, len(impname_all_3d4d)):
if imp1 != imp2:
Tcs[imp1, imp2] = (Tcs[imp1, imp2] + Tcs[imp1, imp1] + Tcs[imp2, imp2])/3
Tcs[imp2, imp1] = Tcs[imp1, imp2]
# same for Tc without the first neighbor
Tcs1[imp1, imp2] = (Tcs1[imp1, imp2] + Tcs1[imp1, imp1] + Tcs1[imp2, imp2])/3
Tcs1[imp2, imp1] = Tcs1[imp1, imp2]
Tcs_xy[imp1, imp2] = (Tcs_xy[imp1, imp2] + Tcs_xy[imp1, imp1] + Tcs_xy[imp2, imp2])/3
Tcs_xy[imp2, imp1] = Tcs_xy[imp1, imp2]
Tcs_z[imp1, imp2] = (Tcs_z[imp1, imp2] + Tcs_z[imp1, imp1] + Tcs_z[imp2, imp2])/3
Tcs_z[imp2, imp1] = Tcs_z[imp1, imp2]
m = np.array(list(single_imp_moments.values()))<1e-3
Tcs[m, :] = np.NaN
Tcs[:, m] = np.NaN
Tcs1[m, :] = np.NaN
Tcs1[:, m] = np.NaN
Tcs_xy[m, :] = np.NaN
Tcs_xy[:, m] = np.NaN
Tcs_z[m, :] = np.NaN
Tcs_z[:, m] = np.NaN
cbar = False
plt.figure(figsize=(8, 4))
plt.subplot(1,2,1)
for i, (imp1, imp2) in enumerate([[23, 23], [23, 24], [24, 24]]):
d = data_all[data_all[:,6]==imp1]
dd = d[d[:,7]==imp2]
impnames = {23:'V', 24:'Cr'}
label = impnames[imp1]+':'+impnames[imp2]
plt.plot(dd[:,1], dd[:,8]*dd[:,-2], 'o--', color=f'C{i}', label=label)
if i==0:
Tc = np.zeros(len(dd))
Tc += np.array([np.sum(dd[:1+i,-2]*dd[:1+i,8]) * prefac for i in range(len(dd))])
Tc /= 3. # average for V/Cr
plt.ylabel(r'$N\cdot J_{ij}$ (meV)')
plt.axhline(0, ls=':', color='grey')
plt.xlabel(r'$R_{ij}$ ($\AA$)')
plt.legend(loc=5)
plt.twinx()
plt.plot(dd[:,1], Tc, 's-', color='C3')
plt.ylabel(r'$T_c$ ($\mathrm{K}/c$)', color='C3')
plt.subplot(1,2,2)
g = sns.heatmap(Tcs, cmap='seismic', center=0, square=True, annot=False, cbar=cbar, vmin=-1000, vmax=1000)
g.set_facecolor('lightgrey')
[f(i, color='k') for f in [plt.axvline, plt.axhline] for i in [0, 20]]
plt.xticks(np.arange(len(Zimp_all_3d4d))+0.5, impname_all_3d4d)
plt.yticks(np.arange(len(Zimp_all_3d4d))+0.5, impname_all_3d4d)
plt.tight_layout()
plt.annotate(text='(a)', fontsize=16, xy=(0.02, 0.92), xycoords='figure fraction')
plt.annotate(text='(b)', fontsize=16, xy=(0.535, 0.92), xycoords='figure fraction')
if savefigs:
if not cbar:
plt.savefig('stiffness.svg')
else:
plt.savefig('stiffness_cbar.svg')
plt.show()
Tc
array([327.32945372, 437.53509909, 438.82298848, 573.48419692, 581.24855478, 602.94391742, 644.72187137, 673.49340551, 669.91712314, 746.77926964, 749.95917466, 748.53713672, 748.74173371, 757.71515475, 763.05946028, 779.79281319, 784.50670405])
cbar=False
plt.figure(figsize=(16,6))
plt.subplot(1,3,1)
g = sns.heatmap(Tcs, cmap='seismic', center=0, square=True, annot=False, cbar=cbar, vmin=-1000, vmax=1000)
g.set_facecolor('lightgrey')
plt.title(r'$T_c$', fontsize=16)
plt.subplot(1,3,2)
g = sns.heatmap(Tcs_xy, cmap='seismic', center=0, square=True, annot=False, cbar=cbar, vmin=-1000, vmax=1000)
g.set_facecolor('lightgrey')
plt.title(r'$T_c^\mathrm{intra}$', fontsize=16)
plt.subplot(1,3,3)
g = sns.heatmap(Tcs_z*5, cmap='seismic', center=0, square=True, annot=False, cbar=cbar, vmin=-1000, vmax=1000)
g.set_facecolor('lightgrey')
plt.title(r'$T_c^\mathrm{inter}$', fontsize=16)
# plt.colorbar(g)
for i in range(3):
plt.subplot(1,3,1+i)
[f(i, color='k') for f in [plt.axvline, plt.axhline] for i in [0, 20]]
plt.xticks(np.arange(len(Zimp_all_3d4d))+0.5, impname_all_3d4d)
plt.yticks(np.arange(len(Zimp_all_3d4d))+0.5, impname_all_3d4d)
plt.tight_layout()
plt.annotate(xy=(0.00+0.01, 0.94), text='(a)', xycoords='figure fraction', fontsize=18)
plt.annotate(xy=(0.33+0.01, 0.94), text='(b)', xycoords='figure fraction', fontsize=18)
plt.annotate(xy=(0.66+0.01, 0.94), text='(c)', xycoords='figure fraction', fontsize=18)
if savefigs:
plt.savefig('Tc_intra_inter.svg')
plt.show()
# take only Tc1
Tc_Mn = get_Tc(25, 25, False, False)[0]
Tc_VNb = get_Tc(23, 41, False, False)[0]
Tc_VMo = get_Tc(23, 42, False, False)[0]
Tc_CrNb = get_Tc(24, 41, False, False)[0]
Tc_CrMo = get_Tc(24, 42, False, False)[0]
Tc_NbNb = get_Tc(41, 41, False, False)[0]
Tc_NbMo = get_Tc(41, 42, False, False)[0]
Tc_MoMo = get_Tc(42, 42, False, False)[0]
Tc_V = get_Tc(23, 23, False, False)[0]
Tc_Cr = get_Tc(24, 24, False, False)[0]
Tc_VCr = get_Tc(23, 24, False, False)[0]
print('imps c Tc\n'+'-'*18)
for T, name in [[Tc_Mn, ' Mn-Mn'], [Tc_V, ' V-V'], [Tc_VCr, ' V-Cr'], [Tc_Cr, 'Cr-Cr'], ]:
for c in [0.1, 0.2]: #0.02, 0.11/2, 0.12, 0.22]:
print(f'{name:5} {c:5} {np.round(T*c, 1):5.1f}')
print()
imps c Tc ------------------ Mn-Mn 0.1 -19.6 Mn-Mn 0.2 -39.3 V-V 0.1 50.7 V-V 0.2 101.4 V-Cr 0.1 84.9 V-Cr 0.2 169.8 Cr-Cr 0.1 99.7 Cr-Cr 0.2 199.4
Literature values:
print(' Tc^MFA Tc^MFA[no J_1] Tc^intra Tc^inter\n'+'='*40)
cimp = 0.12
print(f'V (cimp={cimp})\n'+'='*20)
print(np.array(get_Tc(23, 23, False, False)[:]) * cimp)
print('relative to reference:')
print(np.array(get_Tc(23, 23, False, False)[:]) * cimp / 30)
cimp = 0.22
print(f'Cr (cimp={cimp})\n'+'='*20)
print(np.array(get_Tc(24, 24, False, False)[:]) * cimp)
print('relative to reference:')
print(np.array(get_Tc(24, 24, False, False)[:]) * cimp / 40)
cimp = 0.09
print(f'Mn (cimp={cimp})\n'+'='*20)
print(np.array(get_Tc(25, 25, False, False)[:]) * cimp)
print('relative to reference:')
print(np.array(get_Tc(25, 25, False, False)[:]) * cimp / 10)
Tc^MFA Tc^MFA[no J_1] Tc^intra Tc^inter ======================================== V (cimp=0.12) ==================== [60.86138518 27.65166951 69.28895074 -8.42756555] relative to reference: [ 2.02871284 0.92172232 2.30963169 -0.28091885] Cr (cimp=0.22) ==================== [219.39298072 157.46386424 196.88970554 22.50327518] relative to reference: [5.48482452 3.93659661 4.92224264 0.56258188] Mn (cimp=0.09) ==================== [-17.67871373 -12.68568153 -18.72492715 1.04621342] relative to reference: [-1.76787137 -1.26856815 -1.87249272 0.10462134]
for imp2 in [24, 26]:
imp1 = imp2
d = data_all[data_all[:,6]==imp1]
dd = d[d[:,7]==imp2]
impnames = {23:'V', 24:'Cr', 26: 'Fe'}
label = impnames[imp1]+':'+impnames[imp2]
data_expanded = []
for ddd in dd:
iadd = ddd[0]
r = get_all_equivalent_R(iadd)
for rr in r:
data_expanded.append([rr[0], rr[1], ddd[-2]])
data_expanded = np.array(data_expanded)
plt.scatter(data_expanded[:,0], data_expanded[:,1], s=10*abs(data_expanded[:,-1]), c=data_expanded[:,-1], cmap='seismic', lw=0, vmin=-abs(data_expanded[:,-1]).max(), vmax=abs(data_expanded[:,-1]).max())
plt.xlabel(r'$R_{ij,x}$ ($\mathrm{\AA}$)'); plt.ylabel(r'$R_{ij,y}$ ($\mathrm{\AA}$)')
plt.axis('equal')
plt.colorbar()
plt.show()
%%capture --no-stdout --no-display
from tqdm import tqdm
iadd = 9
_, group_label, _ = get_builder_double_imp('Mn', 'Mn', add_positions[iadd])
# change label for group
group_double_imps100 = load_or_create_group(group_label)
group_label += '/k120'
group_double_imps120 = load_or_create_group(group_label) # group label only depends on info in
reload = False
node_labels = [i.label for i in group_double_imps120.nodes] # if i.label in [n.label for n in group_double_imps100.nodes]]
node_labels2 = []
for n in tqdm(group_double_imps100.nodes):
if n.label in node_labels:
n120 = [i for i in group_double_imps120.nodes if i.label==n.label][0]
if n.is_finished_ok and n120.is_finished_ok:
node_labels2.append(n.label)
node_labels = node_labels2
data_all = []
for iadd in [9]: #range(17):
data = []
_, group_label, _ = get_builder_double_imp('Mn', 'Mn', add_positions[iadd])
group_double_imps = load_or_create_group(group_label)
R, il, num_neighbors = get_R_num_neighbor(iadd)
for node in tqdm(group_double_imps.nodes):
if node.is_finished_ok and node.label in node_labels:
dat = get_dat_from_node(node, reload=reload)
data.append(dat)
if len(data)>0:
data_all += data
data_all = np.array(data_all)
# convert to pandas dataframe
# dat = [iadd, add_positions[iadd][0], r[0], r[1], r[2], add_positions[iadd][2], Zimp1, Zimp2, num_neighbors, m1, m2, m01, m02, J, uuid_JijData]
df100 = DataFrame(data_all, columns='i_shell R Rx Ry Rz ilayer2 Zimp1 Zimp2 num_neighbors m1 m2 m01 m02 J J_data_uuid'.split())
data_all = []
for iadd in [9]: #range(17):
data = []
_, group_label, _ = get_builder_double_imp('Mn', 'Mn', add_positions[iadd])
group_label += '/k120'
group_double_imps = load_or_create_group(group_label)
R, il, num_neighbors = get_R_num_neighbor(iadd)
for node in tqdm(group_double_imps.nodes):
if node.is_finished_ok and node.label in node_labels:
dat = get_dat_from_node(node, reload=reload)
data.append(dat)
if len(data)>0:
data_all += data
data_all = np.array(data_all)
# convert to pandas dataframe
df120 = DataFrame(data_all, columns='i_shell R Rx Ry Rz ilayer2 Zimp1 Zimp2 num_neighbors m1 m2 m01 m02 J J_data_uuid'.split())
fig, ax = plt.subplots()
plt.scatter(np.array(df100['J'], dtype=float), np.array(df120['J'], dtype=float), label=r'$J_{ij}(R=10\mathrm{\AA})$')
plt.plot([-4,6], [-4,6], ls='--', color='k', label='ideal')
plt.legend(loc=2)
plt.xlim(-4,10)
plt.ylim(-4,6)
plt.xlabel(r'$J_{ij}$ [$100^3$ $k$-points] (meV)')
plt.ylabel(r'$J_{ij}$ [$120^3$ $k$-points] (meV)')
axin1 = ax.inset_axes([0.5, 0.15, 0.45, 0.46])
diffs = (np.array(df100['J'], dtype=float) - np.array(df120['J'], dtype=float))*1e6
axin1.hist(abs(diffs), bins=21, label='absolute error')
axin1.axvline(abs(diffs).mean(), ls='--', color='C1', label='MAE')
axin1.legend()
axin1.set_ylabel('count')
axin1.set_xlabel(r'absolute error ($\mu$eV)')
plt.savefig('convergence_Jijs.pdf')
plt.show()
print('MAE=', np.round(abs(diffs).mean(), 2), 'micro-eV')
MAE= 2.16 micro-eV
reldiff = (np.array(df100['J'], dtype=float) - np.array(df120['J'], dtype=float)) / np.array(df120['J'], dtype=float) * 1e3
plt.hist(abs(reldiff), bins=21, label='relative error')
plt.axvline(abs(reldiff).mean(), color='C1', ls='--')
plt.xlabel(r'relative error ($\perthousand$)')
abs(reldiff).mean(), abs(reldiff).mean() * 1e-3
(0.023289332826489595, 2.3289332826489595e-05)