def check_forces(cgmodel): """ Given a cgmodel that contains positions and an an OpenMM System() object, this function tests the forces for cgmodel.system. More specifically, this function confirms that the model does not have any "NaN" or unphysically large forces. :param cgmodel: CGModel() class object. :param type: class :returns: - success (Logical) - Indicates if this cgmodel has unphysical forces. :Example: >>> from foldamers.cg_model.cgmodel import CGModel >>> cgmodel = CGModel() >>> pass_forces_test = check_forces(cgmodel) """ if cgmodel.topology is None: cgmodel.topology = build_topology(cgmodel) simulation = build_mm_simulation( cgmodel.topology, cgmodel.system, cgmodel.positions, simulation_time_step=5.0 * unit.femtosecond, print_frequency=1, ) forces = simulation.context.getState(getForces=True).getForces() success = True for force in forces: for component in force: if "nan" in str(component): print("Detected 'nan' force value") print("for particle " + str(forces.index(force))) success = False return success if component.__gt__(9.9e9 * component.unit): print("Detected unusually large forces") print("for particle " + str(forces.index(force))) print("The force is: " + str("{:.2e}".format(component._value)) + " " + str(component.unit)) success = False return success return success
def check_force(cgmodel, force, force_type=None): """ Given an OpenMM `Force() <https://simtk.org/api_docs/openmm/api4_1/python/classsimtk_1_1openmm_1_1openmm_1_1Force.html>`_, this function determines if there are any problems with its configuration. :param cgmodel: CGModel() class object. :type cgmodel: class :param force: An OpenMM Force() object. :type force: `Force() <https://simtk.org/api_docs/openmm/api4_1/python/classsimtk_1_1openmm_1_1openmm_1_1Force.html>`_, this function determines if there are any problems with its configuration. :param force_type: Designates the kind of 'force' provided. (Valid options include: "Nonbonded") :type force_type: str :returns: - 'success' (Logical) - a variable indicating if the force test passed. :Example: >>> from simtk.openmm.openmm import NonbondedForce >>> from foldamers.cg_model.cgmodel import CGModel >>> cgmodel = CGModel() >>> force = NonbondedForce() >>> force_type = "Nonbonded" >>> test_result = check_force(cgmodel,force,force_type="Nonbonded") """ success = True if force_type == "Nonbonded": if cgmodel.num_beads != force.getNumParticles(): print( "ERROR: The number of particles in the coarse grained model is different" ) print( "from the number of particles with nonbonded force definitions in the OpenMM NonbondedForce.\n" ) print("There are " + str(cgmodel.num_beads) + " particles in the coarse grained model") print("and " + str(force.getNumParticles()) + " particles in the OpenMM NonbondedForce.") success = False total_nonbonded_energy = 0.0 * unit.kilojoule_per_mole # print(cgmodel.nonbonded_interaction_list) for nonbonded_interaction in cgmodel.nonbonded_interaction_list: particle_1_positions = cgmodel.positions[nonbonded_interaction[0]] particle_2_positions = cgmodel.positions[nonbonded_interaction[1]] sigma = cgmodel.get_particle_sigma(nonbonded_interaction[0]) epsilon = cgmodel.get_particle_epsilon(nonbonded_interaction[0]) int_energy = lj_v(particle_1_positions, particle_2_positions, sigma, epsilon) total_nonbonded_energy = total_nonbonded_energy.__add__(int_energy) cgmodel.include_bond_forces = False cgmodel.include_bond_angle_forces = False cgmodel.include_torsion_forces = False cgmodel.topology = build_topology(cgmodel) cgmodel.simulation = build_mm_simulation( cgmodel.topology, cgmodel.system, cgmodel.positions, simulation_time_step=5.0 * unit.femtosecond, print_frequency=1, ) potential_energy = cgmodel.simulation.context.getState( getEnergy=True).getPotentialEnergy() # if potential_energy.__sub__(total_nonbonded_energy).__gt__(0.1 * unit.kilojoule_per_mole): # print("Warning: The nonbonded potential energy computed by hand does not agree") # print("with the value computed by OpenMM.") # print("The value computed by OpenMM was: "+str(potential_energy)) # print("The value computed by hand was: "+str(total_nonbonded_energy)) # print("Check the units for your model parameters. If the problem persists, there") # print("could be some other problem with the configuration of your coarse grained model.") # success = False # else: # print("The OpenMM nonbonded energy matches the energy computed by hand:") # print(str(potential_energy)) return success