Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 20 additions & 28 deletions src/python/structurefinder/pyberny/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@
# limitations under the License.

import pluginplay as pp
from simde import EnergyNuclearGradientStdVectorD, TotalEnergy, MoleculeFromString
from simde import (
EnergyNuclearGradientStdVectorD,
TotalEnergyNuclearOptimization,
MoleculeFromString,
TotalEnergy,
)
from berny import Berny, geomlib
import chemist
import numpy as np
Expand All @@ -23,65 +28,52 @@ class GeomoptViaPyberny(pp.ModuleBase):

def __init__(self):
pp.ModuleBase.__init__(self)
self.satisfies_property_type(TotalEnergy())
self.satisfies_property_type(TotalEnergyNuclearOptimization())
self.description("Performs PyBerny optimization")
self.add_submodule(TotalEnergy(), "Energy")
self.add_submodule(EnergyNuclearGradientStdVectorD(), "Gradient")
self.add_submodule(MoleculeFromString(), "StringConv")

def run_(self, inputs, submods):
pt = TotalEnergy()
mol, = pt.unwrap_inputs(inputs)
molecule = mol.molecule
pt = TotalEnergyNuclearOptimization()
sys, points = pt.unwrap_inputs(inputs)
molecule = sys.molecule

# Convert Chemist Chemical System to XYZ
xyz = ""
xyz += (str(molecule.size()) + "\n\n")
xyz += str(molecule.size()) + "\n\n"
for i in range(molecule.size()):
xyz += (molecule.at(i).name + " " + str(molecule.at(i).x) + " " +
str(molecule.at(i).y) + " " + str(molecule.at(i).z) + "\n")

# Loads the geometry string into the Berny optimizer
# object.
optimizer = Berny(geomlib.loads(xyz, fmt='xyz'))
optimizer = Berny(geomlib.loads(xyz, fmt="xyz"))

for geom in optimizer:

# Converts the "Berny" geometry object to Chemical System
geom2xyz = geom.dumps('xyz')
print('Berny Geom to XYZ value: \n' + geom2xyz + '\n')
lines = geom2xyz.split('\n')
print('Lines of geom2xyz: \n' + str(lines) + '\n')
mol_string = '\n'.join(lines[2:])
print('Lines to string: \n' + mol_string + '\n')
geom2xyz = geom.dumps("xyz")
lines = geom2xyz.split("\n")
mol_string = "\n".join(lines[2:])
xyz2chem_mol = submods["StringConv"].run_as(
MoleculeFromString(), mol_string)
print('String conversion from xyz to chem sys: \n' +
str(xyz2chem_mol.nuclei) + '\n')
geom = chemist.ChemicalSystem(xyz2chem_mol)
print('Chemical system of xyz2chem_mol: \n' +
str(geom.molecule.nuclei) + '\n')
geom_nuclei = geom.molecule.nuclei.as_nuclei()
geom_points = geom_nuclei.charges.point_set
geom_points = geom_nuclei.charges.point_set.as_point_set()

# Main optimizer operation
energy = submods["Energy"].run_as(TotalEnergy(), geom)
print('Interim energy: \n' + str(energy) + '\n')
gradients = submods["Gradient"].run_as(
EnergyNuclearGradientStdVectorD(), geom,
geom_points.as_point_set())
print('Interim gradient: \n' + str(gradients) + '\n')
EnergyNuclearGradientStdVectorD(), geom, geom_points)
optimizer.send((np.array(energy).item(), gradients))

opt_geom = geom.molecule.nuclei
print(
'Resulting relaxed geometry (assigned to variable opt_geom): \n' +
str(opt_geom))
opt_geom_nuclei = geom.molecule.nuclei.as_nuclei()
opt_geom_points = opt_geom_nuclei.charges.point_set.as_point_set()
# Optimized energy is of type "float"
e = energy
print(e)
rv = self.results()
return pt.wrap_results(rv, e)
return pt.wrap_results(rv, e, opt_geom_points)


def load_pyberny_modules(mm):
Expand Down
29 changes: 17 additions & 12 deletions tests/python/unit_tests/test_optimizers/test_pybernyop.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import pluginplay as pp
import chemist
import unittest
from simde import TotalEnergy
from simde import TotalEnergyNuclearOptimization


class Test_optimize_pyberny(unittest.TestCase):
Expand All @@ -27,19 +27,24 @@ def test_optimize_pyberny(self):
mm = pp.ModuleManager()
nwchemex.load_modules(mm)
structurefinder.load_modules(mm)
mm.change_input("NWChem : SCF", "basis set", "sto-3g")
mm.change_input("NWChem : SCF Gradient", "basis set", "sto-3g")
mm.change_submod("PyBerny", "Gradient", "NWChem : SCF Gradient")
mm.change_submod("PyBerny", "Energy", "NWChem : SCF")
mm.change_submod("Pyberny", "StringConv",
"ChemicalSystem via QCElemental")
egy = mm.run_as(TotalEnergy(), "PyBerny",
chemist.ChemicalSystem(self.mol))
print("Energy = " + str(egy))
print(np.array(egy).item())
self.assertAlmostEqual(np.array(egy).item(), -1.117505879316, 10)
pyberny_mod = mm.at("PyBerny")
nwchem_scf_mod = mm.at("NWChem : SCF")
nwchem_grad_mod = mm.at("NWChem : SCF Gradient")
string_conv_mod = mm.at("ChemicalSystem via QCElemental")

nwchem_scf_mod.change_input("basis set", "sto-3g")
nwchem_grad_mod.change_input("basis set", "sto-3g")
pyberny_mod.change_submod("Energy", nwchem_scf_mod)
pyberny_mod.change_submod("Gradient", nwchem_grad_mod)
pyberny_mod.change_submod("StringConv", string_conv_mod)
egy = pyberny_mod.run_as(TotalEnergyNuclearOptimization(), self.sys,
self.point_set)
self.assertAlmostEqual(np.array(egy[0]).item(), -1.117505879316, 10)

def setUp(self):
self.mol = chemist.Molecule()
self.mol.push_back(chemist.Atom("H", 1, 1.0079, 0.0, 0.0, 0.0))
self.mol.push_back(chemist.Atom("H", 1, 1.0079, 0.0, 0.0, 1.0))
self.sys = chemist.ChemicalSystem(self.mol)
self.nuclei = self.mol.nuclei.as_nuclei()
self.point_set = self.nuclei.charges.point_set.as_point_set()