def get_transformation(self, coordinates): """Construct a transformation object""" atom1, atom2 = self.hinge_atoms center = coordinates[atom1] axis = coordinates[atom1] - coordinates[atom2] axis /= np.linalg.norm(axis) angle = np.random.uniform(-self.max_amplitude, self.max_amplitude) return Complete.about_axis(center, angle, axis)
def get_transformation(self, coordinates): """Construct a transformation object""" atom1, atom2 = self.hinge_atoms center = coordinates[atom1] axis = coordinates[atom1] - coordinates[atom2] axis /= numpy.linalg.norm(axis) angle = numpy.random.uniform(-self.max_amplitude, self.max_amplitude) return Complete.about_axis(center, angle, axis)
def get_transformation(self, coordinates): """Construct a transformation object""" atom1, atom2, atom3 = self.hinge_atoms center = coordinates[atom2] a = coordinates[atom1] - coordinates[atom2] b = coordinates[atom3] - coordinates[atom2] axis = np.cross(a, b) norm = np.linalg.norm(axis) if norm < 1e-5: # We suppose that atom3 is part of the affected atoms axis = random_orthonormal(a) else: axis /= np.linalg.norm(axis) angle = np.random.uniform(-self.max_amplitude, self.max_amplitude) return Complete.about_axis(center, angle, axis)
def get_transformation(self, coordinates): """Construct a transformation object""" atom1, atom2, atom3 = self.hinge_atoms center = coordinates[atom2] a = coordinates[atom1] - coordinates[atom2] b = coordinates[atom3] - coordinates[atom2] axis = numpy.cross(a, b) norm = numpy.linalg.norm(axis) if norm < 1e-5: # We suppose that atom3 is part of the affected atoms axis = random_orthonormal(a) else: axis /= numpy.linalg.norm(axis) angle = numpy.random.uniform(-self.max_amplitude, self.max_amplitude) return Complete.about_axis(center, angle, axis)
def random_dimer(molecule0, molecule1, thresholds, shoot_max): """Create a random dimer. molecule0 and molecule1 are placed in one reference frame at random relative positions. Interatomic distances are above the thresholds. Initially a dimer is created where one interatomic distance approximates the threshold value. Then the molecules are given an additional separation in the range [0, shoot_max]. thresholds has the following format: {frozenset([atom_number1, atom_number2]): distance} """ # apply a random rotation to molecule1 center = np.zeros(3, float) angle = np.random.uniform(0, 2 * np.pi) axis = random_unit() rotation = Complete.about_axis(center, angle, axis) cor1 = np.dot(molecule1.coordinates, rotation.r) # select a random atom in each molecule atom0 = np.random.randint(len(molecule0.numbers)) atom1 = np.random.randint(len(molecule1.numbers)) # define a translation of molecule1 that brings both atoms in overlap delta = molecule0.coordinates[atom0] - cor1[atom1] cor1 += delta # define a random direction direction = random_unit() cor1 += 1 * direction # move molecule1 along this direction until all intermolecular atomic # distances are above the threshold values threshold_mat = np.zeros((len(molecule0.numbers), len(molecule1.numbers)), float) distance_mat = np.zeros((len(molecule0.numbers), len(molecule1.numbers)), float) for i1, n1 in enumerate(molecule0.numbers): for i2, n2 in enumerate(molecule1.numbers): threshold = thresholds.get(frozenset([n1, n2])) threshold_mat[i1, i2] = threshold**2 while True: cor1 += 0.1 * direction distance_mat[:] = 0 for i in 0, 1, 2: distance_mat += np.subtract.outer(molecule0.coordinates[:, i], cor1[:, i])**2 if (distance_mat > threshold_mat).all(): break # translate over a random distance [0, shoot] along the same direction # (if necessary repeat until no overlap is found) while True: cor1 += direction * np.random.uniform(0, shoot_max) distance_mat[:] = 0 for i in 0, 1, 2: distance_mat += np.subtract.outer(molecule0.coordinates[:, i], cor1[:, i])**2 if (distance_mat > threshold_mat).all(): break # done dimer = Molecule(np.concatenate([molecule0.numbers, molecule1.numbers]), np.concatenate([molecule0.coordinates, cor1])) dimer.direction = direction dimer.atom0 = atom0 dimer.atom1 = atom1 return dimer
def random_dimer(molecule0, molecule1, thresholds, shoot_max): """Create a random dimer. molecule0 and molecule1 are placed in one reference frame at random relative positions. Interatomic distances are above the thresholds. Initially a dimer is created where one interatomic distance approximates the threshold value. Then the molecules are given an additional separation in the range [0, shoot_max]. thresholds has the following format: {frozenset([atom_number1, atom_number2]): distance} """ # apply a random rotation to molecule1 center = numpy.zeros(3, float) angle = numpy.random.uniform(0, 2*numpy.pi) axis = random_unit() rotation = Complete.about_axis(center, angle, axis) cor1 = numpy.dot(molecule1.coordinates, rotation.r) # select a random atom in each molecule atom0 = numpy.random.randint(len(molecule0.numbers)) atom1 = numpy.random.randint(len(molecule1.numbers)) # define a translation of molecule1 that brings both atoms in overlap delta = molecule0.coordinates[atom0] - cor1[atom1] cor1 += delta # define a random direction direction = random_unit() cor1 += 1*direction # move molecule1 along this direction until all intermolecular atomic # distances are above the threshold values threshold_mat = numpy.zeros((len(molecule0.numbers), len(molecule1.numbers)), float) distance_mat = numpy.zeros((len(molecule0.numbers), len(molecule1.numbers)), float) for i1, n1 in enumerate(molecule0.numbers): for i2, n2 in enumerate(molecule1.numbers): threshold = thresholds.get(frozenset([n1, n2])) threshold_mat[i1, i2] = threshold**2 while True: cor1 += 0.1*direction distance_mat[:] = 0 for i in 0, 1, 2: distance_mat += numpy.subtract.outer(molecule0.coordinates[:, i], cor1[:, i])**2 if (distance_mat > threshold_mat).all(): break # translate over a random distance [0, shoot] along the same direction # (if necessary repeat until no overlap is found) while True: cor1 += direction*numpy.random.uniform(0, shoot_max) distance_mat[:] = 0 for i in 0, 1, 2: distance_mat += numpy.subtract.outer(molecule0.coordinates[:, i], cor1[:, i])**2 if (distance_mat > threshold_mat).all(): break # done dimer = Molecule( numpy.concatenate([molecule0.numbers, molecule1.numbers]), numpy.concatenate([molecule0.coordinates, cor1]) ) dimer.direction = direction dimer.atom0 = atom0 dimer.atom1 = atom1 return dimer