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 import FIRE
from ase.optimize.bfgs import BFGS
from import Trajectory
from ase.constraints import UnitCellFilter, StrainFilter, ExpCellFilter
from ase.calculators.mixing import SumCalculator
from dftd3.ase import DFTD3
from import read,write
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
import tensorflow as tf

atoms = read('poscar_banco_forsterite.POSCAR')'forsterite_opt_banco_crystal.f34', format='crystal')'forsterite_opt_banco_crystal.f34')
#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)

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
51 # >>> atoms = Atoms(…)
52 # ecf = StrainFilter(atoms)
53 # qn = BFGS(ecf)
57 # qn.attach(traj)
58 #
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
# 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

# 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

# Out: -843.5337227956857