diff --git a/src/relentless/optimize/objective.py b/src/relentless/optimize/objective.py index d2f1fe0b..e6ffea1a 100644 --- a/src/relentless/optimize/objective.py +++ b/src/relentless/optimize/objective.py @@ -585,21 +585,22 @@ def _calc_ensemble_average_dvar_gradient(self, trajectory, variables): filter_j_gt_i = neighbors[:, 1] > neighbors[:, 0] neighbors.filter(filter_j_gt_i) # pair contributions to the gradient - for i in self.potentials.pair.types: - for j in self.potentials.pair.types: - filter_ij = numpy.logical_and( - type_masks[i][neighbors[:, 0]], - type_masks[j][neighbors[:, 1]], - ) - for var in variables: - gradient[var] += numpy.sum( - self.potentials.pair.derivative( - (i, j), var, x=neighbors.distances[filter_ij] - ) + if self.potentials.pair is not None: + for i in self.potentials.pair.types: + for j in self.potentials.pair.types: + filter_ij = numpy.logical_and( + type_masks[i][neighbors[:, 0]], + type_masks[j][neighbors[:, 1]], ) + for var in variables: + gradient[var] += numpy.sum( + self.potentials.pair.derivative( + (i, j), var, x=neighbors.distances[filter_ij] + ) + ) # bond contributions to the gradient - if snap.bonds.N != 0: + if self.potentials.bond is not None and snap.bonds.N != 0: bond_type_map = { type: i for i, type in enumerate(self.potentials.bond.types) } @@ -624,7 +625,7 @@ def _calc_ensemble_average_dvar_gradient(self, trajectory, variables): ) # angle contributions to the gradient - if snap.angles.N != 0: + if self.potentials.angle is not None and snap.angles.N != 0: angle_type_map = { type: i for i, type in enumerate(self.potentials.angle.types) } @@ -657,7 +658,7 @@ def _calc_ensemble_average_dvar_gradient(self, trajectory, variables): ) # dihedral contributions to the gradient - if snap.dihedrals.N != 0: + if self.potentials.dihedral is not None and snap.dihedrals.N != 0: dihedral_type_map = { type: i for i, type in enumerate(self.potentials.dihedral.types) } diff --git a/tests/optimize/test_objective.py b/tests/optimize/test_objective.py index 42e49177..261bc25e 100644 --- a/tests/optimize/test_objective.py +++ b/tests/optimize/test_objective.py @@ -882,6 +882,42 @@ def test_compute_all_exclusions(self): # test B-B pair contributions self.assertAlmostEqual(res[self.sigma_BB], 0.0, delta=1e-3) + def test_compute_no_bonded_potentials(self): + self.potentials.bond = None + self.potentials.angle = None + self.potentials.dihedral = None + + self.target = self.create_gsd_mers_tgt() + + # add 1-2, 1-3, and 1-4 exclusions to the pair potential + self.potentials.pair.exclusions = ["1-2", "1-3", "1-4"] + + relent = relentless.optimize.RelativeEntropy( + self.target, + self.simulation, + self.potentials, + self.thermo, + T=1.0, + extensive=True, + ) + sim_traj = self.create_gsd_two_4mers_sim() + + vars = ( + self.sigma_AA, + self.sigma_AB, + self.sigma_BB, + ) + res = relent._compute_gradient_direct_average(sim_traj, vars) + + # test A-A pair contributions + self.assertAlmostEqual(res[self.sigma_AA], 0.0, delta=1e-3) + + # test A-B pair contributions + self.assertAlmostEqual(res[self.sigma_AB], 0.0, delta=1e-3) + + # test B-B pair contributions + self.assertAlmostEqual(res[self.sigma_BB], 0.0, delta=1e-3) + def test_intensive(self): """Test compute and compute_gradient methods""" self.target = self.create_gsd_mers_tgt()