Build effective harmonic model for conventional cell

Dear developer,
I am currently working on building effective harmonic models (EHMs) for La₂Zr₂O₇ using a supercell containing 4×4×4 unit cells. I have encountered two issues for which I would like to seek your assistance.

  1. When utilizing the triclinic primitive cell (containing 22 atoms) as the unit cell, I successfully constructed an EHM. However, when I employed the orthogonal conventional cell (containing 88 atoms) as the unit cell, I encountered the following errors. Does the Hiphive package necessitate the use of a primitive cell as the unit cell?

Traceback (most recent call last):
File “F:\software\Anaconda-2024.02-1\Lib\site-packages\hiphive\core\utilities.py”, line 170, in index
return self._dict[value]
~~~~~~~~~~^^^^^^^
KeyError: (1, 943)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “E:\Python\hiphive\Effective_harmonic_models\LZO-supercell\2effective_harmonic_models.py”, line 12, in
cs = ClusterSpace(structures[0], cutoffs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “F:\software\Anaconda-2024.02-1\Lib\site-packages\hiphive\cluster_space.py”, line 115, in init
build_cluster_space(self, prototype_structure)
File “F:\software\Anaconda-2024.02-1\Lib\site-packages\hiphive\core\cluster_space_builder.py”, line 62, in build_cluster_space
_create_orbits(cluster_space)
File “F:\software\Anaconda-2024.02-1\Lib\site-packages\hiphive\core\cluster_space_builder.py”, line 272, in _create_orbits
cs._orbits = get_orbits(cs._cluster_list,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “F:\software\Anaconda-2024.02-1\Lib\site-packages\hiphive\core\orbits.py”, line 65, in get_orbits
orbits = _get_orbits(permutation_map, extended_atoms, clusters, basis,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “F:\software\Anaconda-2024.02-1\Lib\site-packages\hiphive\core\orbits.py”, line 143, in _get_orbits
populate_orbit(orbit, permutations, clusters,
File “F:\software\Anaconda-2024.02-1\Lib\site-packages\hiphive\core\orbits.py”, line 189, in populate_orbit
translated_cluster_index = clusters.index(translated_cluster)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “F:\software\Anaconda-2024.02-1\Lib\site-packages\hiphive\core\utilities.py”, line 172, in index
raise ValueError(‘{} is not in list’.format(value))
ValueError: (1, 943) is not in list

  1. I aim to obtain temperature-dependent 2nd and 3rd order interatomic force constants (IFCs) from EHM for calculating thermal conductivity. Within the framework of the 2nd order term, the phonon dispersion plots indicate that the obtained 2nd order IFCs exhibit temperature dependence. However, when the 3rd order term is incorporated into the EHM training, the obtained 2nd IFCs remain identical across different temperatures. I am curious whether Hiphive can construct an EHM with 3rd order term.

I am uncertain how to address these issues and would like to ask for your help.
Thank you very much for your help.

  1. No you can use any cell as input to the ClusterSpace, but probably good practice to use the primitive cell.
    The error likely comes from the “tolerance bug” in hiphive, you can try and see if setting
atoms.set_scaled_positions(atoms.get_scaled_positions().round(6)%1)
ClusterSpace(atoms, ...)

fixes the problem with the conventional cell as input.

  1. Probably the best idea when constructing effective second and third order FCs is to fit them in sequence, meaning first fit the second order FCs, and then fit the third-order to the residual of the forces.
    See e.g. here how to do this.

Thank you so much for your guidance. When I fit the effective third-order model sequentially, I encountered the following error:

A, y = sc.get_fit_data()
^^^^

TypeError: cannot unpack non-iterable NoneType objec

Here is my script for constructing the third-order effective harmonic model, could you please check it?Thank you very much for your help.

import os
import numpy as np
from ase.io import read
from hiphive import ClusterSpace, StructureContainer, ForceConstantPotential
from trainstation import Optimizer

temperatures = [300, 500, 700]
cutoffs = [8.0, 6.0]

for T in temperatures:
structures = read(‘md_runs/snapshots_T{:}.xyz’.format(T), index=‘:’)

cs = ClusterSpace(structures[0], cutoffs)
sc = StructureContainer(cs)

# set up
inds2 = cs.get_parameter_indices(order=2)
inds3 = cs.get_parameter_indices(order=3)
assert cs.n_dofs == len(inds2) + len(inds3)
A, y = sc.get_fit_data()

# train fc2
opt = Optimizer((A[:, inds2], y), train_size=1.0)
opt.train()
print(opt)
params_2 = opt.parameters
y2 = y - np.dot(A[:, inds2], opt.parameters)

# train fc3
opt = Optimizer((A[:, inds3], y2), train_size=1.0)
opt.train()
print(opt)
params_3 = opt.parameters

# combine parameters from both fits
params = np.zeros(cs.n_dofs)
params[inds2] = params_2
params[inds3] = params_3

# make fcp
fcp = ForceConstantPotential(cs, params)

# save fcp file
output_directory = 'fcps'
if not os.path.exists(output_directory):
    os.makedirs(output_directory)

fcp.write(os.path.join(output_directory, '3rd_ehm_T{}.fcp'.format(T)))

You never add any training structures to the StructureContainer.

Thanks very much. I added training structures by

for s in structures:
sc.add_structure(s)

Now it wroks.