def write(self, extracted_global_state: Sequence[Node]) -> None: """ Extract the bond lengths and bond angles of all water molecules and write them to the temporary files. Parameters ---------- extracted_global_state : Sequence[base.node.Node] The extracted global state. Raises ------ AssertionError If not each root node contains three children. """ super().write(extracted_global_state) for root_cnode in extracted_global_state: assert len(root_cnode.children) == 3 hydrogen_one_position = root_cnode.children[0].value.position oxygen_position = root_cnode.children[1].value.position hydrogen_two_position = root_cnode.children[2].value.position vector_oh_one = setting.periodic_boundaries.separation_vector(oxygen_position, hydrogen_one_position) vector_oh_two = setting.periodic_boundaries.separation_vector(oxygen_position, hydrogen_two_position) print(vectors.norm(vector_oh_one), file=self._file_bond_lengths) print(vectors.norm(vector_oh_two), file=self._file_bond_lengths) print(vectors.angle_between_two_vectors(vector_oh_one, vector_oh_two), file=self._file_bond_angles)
def standard_velocity_derivative( self, direction: int, separation_one: Sequence[float], separation_two: Sequence[float]) -> Tuple[float, float, float]: """ Return the space derivative with respect to i, j, and k of the potential along a positive direction parallel to one of the cartesian axes for the given separations . Parameters ---------- direction : int The direction of the derivative. separation_one : Sequence[float] The separation vector r_i - r_j. separation_two : Sequence[float] The separation vector r_k - r_j. Returns ------- (float, float, float) The space derivatives with respect to i, j, and k. """ separation_norm_one = vectors.norm(separation_one) separation_norm_two = vectors.norm(separation_two) cosine_of_angle = (sum(separation_one[i] * separation_two[i] for i in range(setting.dimension)) / separation_norm_one / separation_norm_two) angle = math.acos(cosine_of_angle) d_potential_by_d_angle = self._prefactor * (angle - self._equilibrium_angle) d_angle_by_d_cosine_of_angle = -1.0 / math.sin(angle) d_cosine_by_d_separation_one = ( separation_two[direction] / separation_norm_one / separation_norm_two - cosine_of_angle * separation_one[direction] / separation_norm_one**2) d_cosine_by_d_separation_two = ( separation_one[direction] / separation_norm_one / separation_norm_two - cosine_of_angle * separation_two[direction] / separation_norm_two**2) d_potential_by_d_separation_one = (d_potential_by_d_angle * d_angle_by_d_cosine_of_angle * d_cosine_by_d_separation_one) d_potential_by_d_separation_two = (d_potential_by_d_angle * d_angle_by_d_cosine_of_angle * d_cosine_by_d_separation_two) return (d_potential_by_d_separation_one, -d_potential_by_d_separation_one - d_potential_by_d_separation_two, d_potential_by_d_separation_two)
def write(self, extracted_global_state: Sequence[Node]) -> None: """ Extract the shortest separations between all leaf unit pairs in different composite objects and write them to the temporary files. Parameters ---------- extracted_global_state : Sequence[base.node.Node] The extracted global state. """ super().write(extracted_global_state) for first_root_cnode_index, first_root_cnode in enumerate( extracted_global_state): for second_root_cnode_index in range(first_root_cnode_index + 1, len(extracted_global_state)): second_root_cnode = extracted_global_state[ second_root_cnode_index] for first_leaf_node in yield_leaf_nodes(first_root_cnode): for second_leaf_node in yield_leaf_nodes( second_root_cnode): first_leaf_identifier = first_leaf_node.value.identifier[ -1] second_leaf_identifier = second_leaf_node.value.identifier[ -1] identifier_distance = ( abs(first_leaf_identifier - second_leaf_identifier) if setting.number_of_node_levels > 1 else 0) separation = setting.periodic_boundaries.separation_vector( first_leaf_node.value.position, second_leaf_node.value.position) print(vectors.norm(separation), file=self._files[identifier_distance])
def standard_velocity_displacement(self, direction: int, separation: MutableSequence[float], potential_change: float) -> float: """ Return the required displacement in space of the active unit along the positive direction of motion parallel to one of the cartesian axes where the cumulative event rate of the potential equals the given potential change. This method determines whether the active unit is behind or in front of the target unit, and whether the the absolute value of the separation is larger than r_0 ('outside sphere') or smaller ('inside sphere'). This is used to call one of the four corresponding methods. Parameters ---------- direction : int The direction of motion of the active unit i. separation : MutableSequence[float] The separation vector r_ij. potential_change : float The sampled potential change. Returns ------- float The required displacement in space of the active unit along its direction of motion where the cumulative event rate equals the sampled potential change. """ norm_of_separation = vectors.norm(separation) # Active unit is outside of the minimum potential shell if norm_of_separation >= self._equilibrium_separation: # Active unit is in front of target unit if separation[direction] <= 0.0: current_potential = self._potential(separation) displacement = self._displacement_front_outside_sphere( direction, current_potential, potential_change, separation) # Active unit is behind of target unit else: displacement = self._displacement_behind_outside_sphere( direction, potential_change, separation) # Active unit is inside of the minimum potential shell else: # Active unit is in front of target unit if separation[direction] <= 0.0: displacement = self._displacement_front_inside_sphere( direction, potential_change, separation) # Active unit is behind of target unit else: current_potential = self._potential(separation) displacement = self._displacement_behind_inside_sphere( direction, current_potential, potential_change, separation) return displacement
def _potential(self, separation: Sequence[float]) -> float: """ Return the potential for the given separation. Parameters ---------- separation : Sequence[float] The separation vector r_ij. Returns ------- float The potential. """ distance_from_minimum = vectors.norm(separation) - self._equilibrium_separation return self._prefactor * distance_from_minimum ** self._power
def standard_velocity_derivative(self, direction: int, separation: Sequence[float]) -> float: """ Return the space derivative of the potential along a positive direction parallel to one of the cartesian axes for the given separation. Parameters ---------- direction : int The direction of the derivative. separation : Sequence[float] The separation vector r_ij. Returns ------- float The space derivative. """ norm_of_separation = vectors.norm(separation) return (- self._power * self._prefactor * (norm_of_separation - self._equilibrium_separation) ** (self._power - 1) * separation[direction] / norm_of_separation)
def standard_velocity_derivative(self, direction: int, separation: Sequence[float], charge_one: float, charge_two: float) -> float: """ Return the space derivative of the potential along a positive direction parallel to one of the cartesian axes for the given separation and charges. Parameters ---------- direction : int The direction of the derivative. separation : Sequence[float] The separation vector r_ij. charge_one : float The charge c_i. charge_two : float The charge c_j. Returns ------- float The space derivative. """ return (self._power * separation[direction] / vectors.norm(separation) ** self._power_plus_two * self._prefactor * charge_one * charge_two)
def test_norm(self): self.assertAlmostEqual(vectors.norm([0.1, 0.2, 0.3]), 0.3741657386773941, places=13) self.assertAlmostEqual(vectors.norm([0.1, 0.0, 0.0]), 0.1, places=13) self.assertAlmostEqual(vectors.norm([0.0, 0.2, 0.0]), 0.2, places=13) self.assertAlmostEqual(vectors.norm([0.0, 0.0, -0.3]), 0.3, places=13) self.assertAlmostEqual(vectors.norm([0.4, 1.5, 2.3]), 2.774887385102321, places=12) self.assertAlmostEqual(vectors.norm([0.4, 1.5, -2.3]), 2.774887385102321, places=12) self.assertAlmostEqual(vectors.norm([0.4, -1.5, 2.3]), 2.774887385102321, places=12) self.assertAlmostEqual(vectors.norm([0.4, -1.5, -2.3]), 2.774887385102321, places=12) self.assertAlmostEqual(vectors.norm([-0.4, 1.5, -2.3]), 2.774887385102321, places=12) self.assertAlmostEqual(vectors.norm([-0.4, 1.5, 2.3]), 2.774887385102321, places=12) self.assertAlmostEqual(vectors.norm([-0.4, -1.5, -2.3]), 2.774887385102321, places=12) self.assertAlmostEqual(vectors.norm([-0.4, -1.5, 2.3]), 2.774887385102321, places=12) self.assertAlmostEqual(vectors.norm([0.1, 0.0]), 0.1, places=13) self.assertAlmostEqual(vectors.norm([0.0, 0.0, 0.0, 0.2]), 0.2, places=13)