Error while trying optimizing with SumCalculator function freeing the cell with ExpCellFilter

Dear Ase Users,

I’m trying to relax some periodic structures using a combination of machine learning potential (m3gnet) with DFTd3 dispersion due to the fact that the dataset of m3gnet is without dispersion effects.

This is the following script that I’m using:

import os
#import ase
#import m3gnet
from m3gnet.models import  *
from ase.optimize.fire import FIRE
from ase.optimize.bfgs import BFGS
from ase.io.trajectory import Trajectory
from ase.constraints import UnitCellFilter, StrainFilter, ExpCellFilter
from ase.calculators.mixing import SumCalculator
from dftd3.ase import DFTD3
from ase.io import read,write
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
warnings.filterwarnings("ignore")
import tensorflow as tf
tf.get_logger().setLevel('ERROR')


atoms = read('poscar_banco_forsterite.POSCAR')
#atoms=ase.io.read('forsterite_opt_banco_crystal.f34', format='crystal')
#ase.io.crystal.read_crystal('forsterite_opt_banco_crystal.f34')
#atoms.set_calculator(M3GNetCalculator(potential=Potential(M3GNet.load())))
#with Grimme dispersion

atoms.calc = SumCalculator([DFTD3(method="PBE", damping="d3bj"), M3GNetCalculator(potential=Potential(M3GNet.load()),compute_stress = True, stress_weight = 1.0)])

energy = atoms.get_potential_energy()
a,b,c,bc,ac,ab = atoms.get_cell_lengths_and_angles()
#forces = atoms.get_forces()

print("Single point energy --> %.8f eV" % (energy))
print("Cell parameter --> a: %.5f , b: %.5f, c: %.5f " % (a,b,c))
print("                   BC: %.4f , AC: %.4f , AB: %.4f" % (bc,ac,ab))

atoms = ExpCellFilter(atoms)
opt=BFGS(atoms)
opt.run(fmax=0.001)

energy_opt = atoms.get_potential_energy()
a,b,c,bc,ac,ab = atoms.get_cell_lengths_and_angles()


print("Optimized energy --> %.8f eV" % (energy_opt))
print("Optimized cell parameter --> a: %.5f , b: %.5f, c: %.5f " % (a,b,c))
print("                   BC: %.4f , AC: %.4f , AB: %.4f" % (bc,ac,ab))

when I run this code it exits with this error message:


ValueError Traceback (most recent call last)
Cell In[1], line 47
43 atoms = ExpCellFilter(atoms)
46 opt=BFGS(atoms)
—> 47 opt.run(fmax=0.1)
51 # >>> atoms = Atoms(…)
52 # ecf = StrainFilter(atoms)
53 # qn = BFGS(ecf)
(…)
57 # qn.attach(traj)
58 # qn.run(fmax=0.05)
62 energy_opt = atoms.get_potential_energy()



57 self.results[k] = w * calc.results[k]
58 else:
—> 59 self.results[k] += w * calc.results[k]

ValueError: operands could not be broadcast together with shapes (6,) (3,3) (6,)

However, when I remove the SumCalcuator function, thus I’m removing the dispersion effects from my calculator, the calculation run smoothly.

Do you have any clue about this?

Thank you

I wonder if there is an inconsistency in the way these calculators represent the strain tensor: this could be 6 unique components or a 3x3 matrix, in which case adding them together would give the error message shown.

What does the stress tensor look like when calling get_stress() with each calculator without adding/mixing them?

Reviving this because I’m having the same issue. @ajjackson

I have some periodic atoms object from a CIF file that I’m assessing here:

import matgl
from matgl.ext.ase import M3GNetCalculator
from dftd4.ase import DFTD4
from ase.calculators.mixing import SumCalculator
potential = matgl.load_model("M3GNet-MP-2021.2.8-PES")
calculator = SumCalculator([DFTD4(method="PBE"), M3GNetCalculator(potential=potential)])
atoms.calc = calculator
atoms.get_stress() # gives same error as above

calculator = M3GNetCalculator(potential=potential)
atoms.calc = calculator
atoms.get_stress()
# Out: array([-4.01619339e+00, -4.01619530e+00, -3.35417414e+00, -2.47374101e-06, -5.90982552e-07,  4.39243770e-08])

dispcalc = DFTD4(method='pbe')
atoms.calc = dispcalc
atoms.get_stress()

# Out[5]: array([ 2.91348683e-03,  2.91348685e-03,  3.06167218e-03,  4.54646934e-13, -7.51897674e-13,  2.23088170e-11])

It seems like the stress arrays are the right shapes, but there’s a bug in the SumCalculator. I’ll add that I have no issues running simple tests like get_potential_energy() with the SumCalculator:

calculator = SumCalculator([DFTD4(method="PBE"), M3GNetCalculator(potential=potential)])
atoms.calc = calculator
atoms.get_potential_energy()

# Out: -843.5337227956857

Ok, I think I found the issue in the SumCalculator, and I’ve made the changes and put in a merge request here. I hope this change can resolve similar future problems!