def test_position_output(): """ Test that the hybrid returns the correct positions for the new and old systems after construction """ from perses.annihilation.relative import HybridTopologyFactory import numpy as np #generate topology proposal topology_proposal, old_positions, new_positions = utils.generate_solvated_hybrid_test_topology( ) factory = HybridTopologyFactory(topology_proposal, old_positions, new_positions) old_positions_factory = factory.old_positions(factory.hybrid_positions) new_positions_factory = factory.new_positions(factory.hybrid_positions) assert np.all( np.isclose(old_positions.in_units_of(unit.nanometers), old_positions_factory.in_units_of(unit.nanometers))) assert np.all( np.isclose(new_positions.in_units_of(unit.nanometers), new_positions_factory.in_units_of(unit.nanometers)))
def compute_nonalchemical_perturbation( alchemical_thermodynamic_state: states.ThermodynamicState, growth_thermodynamic_state: states.ThermodynamicState, hybrid_sampler_state: states.SamplerState, hybrid_factory: HybridTopologyFactory, nonalchemical_thermodynamic_state: states.ThermodynamicState, lambda_state: int) -> tuple: """ Compute the perturbation of transforming the given hybrid equilibrium result into the system for the given nonalchemical_thermodynamic_state Parameters ---------- alchemical_thermodynamic_state: states.ThermodynamicState alchemical thermostate growth_thermodynamic_state : states.ThermodynamicState hybrid_sampler_state: states.SamplerState sampler state for the alchemical thermodynamic_state hybrid_factory : HybridTopologyFactory Hybrid factory necessary for getting the positions of the nonalchemical system nonalchemical_thermodynamic_state : states.ThermodynamicState ThermodynamicState of the nonalchemical system lambda_state : int Whether this is lambda 0 or 1 Returns ------- valence_energy: float reduced potential energy of the valence contribution of the alternate endstate nonalchemical_reduced_potential : float reduced potential energy of the nonalchemical endstate hybrid_reduced_potential: float reduced potential energy of the alchemical endstate """ #get the objects we need to begin hybrid_reduced_potential = compute_reduced_potential( alchemical_thermodynamic_state, hybrid_sampler_state) hybrid_positions = hybrid_sampler_state.positions #get the positions for the nonalchemical system if lambda_state == 0: nonalchemical_positions = hybrid_factory.old_positions( hybrid_positions) nonalchemical_alternate_positions = hybrid_factory.new_positions( hybrid_positions) elif lambda_state == 1: nonalchemical_positions = hybrid_factory.new_positions( hybrid_positions) nonalchemical_alternate_positions = hybrid_factory.old_positions( hybrid_positions) else: raise ValueError("lambda_state must be 0 or 1") nonalchemical_sampler_state = states.SamplerState( nonalchemical_positions, box_vectors=hybrid_sampler_state.box_vectors) nonalchemical_alternate_sampler_state = states.SamplerState( nonalchemical_alternate_positions, box_vectors=hybrid_sampler_state.box_vectors) nonalchemical_reduced_potential = compute_reduced_potential( nonalchemical_thermodynamic_state, nonalchemical_sampler_state) #now for the growth system (set at lambda 0 or 1) so we can get the valence energy if growth_thermodynamic_state: valence_energy = compute_reduced_potential( growth_thermodynamic_state, nonalchemical_alternate_sampler_state) else: valence_energy = 0.0 #now, the corrected energy of the system (for dispersion correction) is the nonalchemical_reduced_potential + valence_energy return (valence_energy, nonalchemical_reduced_potential, hybrid_reduced_potential)