# -*- coding: utf-8 -*- """ Computing Energy and Force Using Builtin Models =============================================== TorchANI has a model ensemble trained by NeuroChem on the `ANI-1x dataset`_. These models are shipped with TorchANI and can be used directly. .. _ANI-1x dataset: https://aip.scitation.org/doi/abs/10.1063/1.5023802 """ ############################################################################### # To begin with, let's first import the modules we will use: import torch import torchani ############################################################################### # Let's now manually specify the device we want TorchANI to run: device = torch.device('cpu') ############################################################################### # Let's now load the built-in models and create a pipeline of AEV computer, # neural networks, and energy shifter. This pipeline will first compute AEV, # then use all models in the ensemble to compute molecular energies, and take # the average of these energies to obtain a final output. The reason we need an # energy shifter in the end is that the output of these networks is not the # total energy but the total energy subtracted by a self energy for each atom. builtin = torchani.neurochem.Builtins() model = torch.nn.Sequential( builtin.aev_computer, builtin.models, builtin.energy_shifter ) ############################################################################### # Now let's define the coordinate and species. If you just want to compute the # energy and force for a single structure like in this example, you need to # make the coordinate tensor has shape ``(1, Na, 3)`` and species has shape # ``(1, Na)``, where ``Na`` is the number of atoms in the molecule, the # preceding ``1`` in the shape is here to support batch processing like in # training. If you have ``N`` different structures to compute, then make it # ``N``. coordinates = torch.tensor([[[0.03192167, 0.00638559, 0.01301679], [-0.83140486, 0.39370209, -0.26395324], [-0.66518241, -0.84461308, 0.20759389], [0.45554739, 0.54289633, 0.81170881], [0.66091919, -0.16799635, -0.91037834]]], requires_grad=True, device=device) species = builtin.consts.species_to_tensor('CHHHH').to(device).unsqueeze(0) ############################################################################### # Now let's compute energy and force: _, energy = model((species, coordinates)) derivative = torch.autograd.grad(energy.sum(), coordinates)[0] force = -derivative ############################################################################### # And print to see the result: print('Energy:', energy.item()) print('Force:', force.squeeze())