def water_orientation_is_valid(self, water_orientation, water_orient, molecule_no): """ go through all neighbors and check that there are no breakage of ice rules if there is: return False else return True """ nn = self.nearest_neighbors_nos[0][molecule_no] nps = self.nearest_neighbors_nos[1][molecule_no] bvv = get_bond_variable_values_from_water_orientation(water_orientation) assert not self.periodic or len(nn)==4 for l, nearest_neighbor_no in enumerate(nn): periodic = nps[l] periodicity_axis = self.nearest_neighbors_nos[2][molecule_no][l] neighbor_set = True neighbor_bv_value = 0 opposite = get_opposite_periodicity_axis_number(periodicity_axis) # get corresponding water_orientation_value of neighbor and store it to neighbor_bv_value # -first check that the neighbor has a value # - if not then no breakage happens if water_orient[nearest_neighbor_no] != -1: # current neighbors bond variable values nbbv = get_bond_variable_values_from_water_orientation(water_orient[nearest_neighbor_no]) for x, n in enumerate(self.nearest_neighbors_nos[0][nearest_neighbor_no]): # find the neighbor that corresponds to the molecule currently handled (i) [and has the same periodicity and the periodicity axis correspond] if n == molecule_no and self.nearest_neighbors_nos[1][nearest_neighbor_no][x] == periodic and self.nearest_neighbors_nos[2][nearest_neighbor_no][x] == opposite: neighbor_bv_value = nbbv[x] break else: neighbor_set = False if water_orientation > 9 and nearest_neighbor_no == molecule_no and bvv[l] != -1: return False # if both bond variables have the same value, then we have not succeeded if neighbor_set and bvv[l] == neighbor_bv_value: return False return True
def get_single_molecule_hydrogen_coordinates(self, site, water_orientation, i, oxygen_positions, nearest_neighbors_nos, nn_periodicity, periodicity_axis, cell): bvv = get_bond_variable_values_from_water_orientation(water_orientation) result = np.zeros((0,3)) index = 0 for n, x in enumerate(nearest_neighbors_nos): if bvv[n] == 1: if i != x or nn_periodicity[n]: if nn_periodicity[n]: distance, real_position = get_periodic_distance(oxygen_positions[i], oxygen_positions[x], cell, periodicity_axis[n]) else: distance = get_distance(oxygen_positions[i], oxygen_positions[x], False, None) real_position = oxygen_positions[x] result = np.vstack((result, oxygen_positions[i] - (( self.O_H_distance * (oxygen_positions[i]-real_position)) / distance))) index += 1 elif i == x and not nn_periodicity[n]: vector = np.array([0, 0, 1]) if i % 8 in [0, 1, 4, 5]: result = np.vstack((result, oxygen_positions[i] - (self.O_H_distance * vector))) else: result = np.vstack((result, oxygen_positions[i] + (self.O_H_distance * vector))) else: site = np.mod(i, 8) if site == 2 or site == 6: add = np.array(oxygen_positions[i]) add[2] += self.O_H_distance result = np.vstack((result, add)) elif site == 0 or site == 4: add = np.array(oxygen_positions[i]) add[2] -= self.O_H_distance result = np.vstack((result, add)) index += 1 return result
def get_single_molecule_hydrogen_coordinates(self, site, water_orientation, i, oxygen_positions, nearest_neighbors_nos, nn_periodicity, nn_periodicity_axis, cell): bvv = get_bond_variable_values_from_water_orientation(water_orientation) if water_orientation > 9: result = np.zeros((3,3)) else: result = np.zeros((2,3)) index = 0 #print nearest_neighbors_nos for n, x in enumerate(nearest_neighbors_nos): if bvv[n] == 1: # i == x means that this is a dangling bond if i == x: com = oxygen_positions[3] vector = oxygen_positions[i] - com # normalize the vector vector_length = scipy.linalg.norm(vector) vector /= vector_length # the dangling hydrogen is along this vector result[index] = np.array(oxygen_positions[i] + self.O_H_distance * vector) else: result[index] = np.array(oxygen_positions[i] - (( self.O_H_distance * (oxygen_positions[i]-oxygen_positions[x])) / get_distance(oxygen_positions[i], oxygen_positions[x], False, None))) index += 1 #print result return result
def get_water_molecule_type(self, molecule_no, water_orientations, nearest_neighbors_nos): """ Return if the molecule is an acceptor or donor -1 : not set 0 : AADD 1 : AAD 2 : ADD 3 : DDD """ # FIXME: When doing at middle of execution, returns false numbers # Find the indeces of dangling bonds if water_orientations[molecule_no] == -1: return -1; else: bvv = get_bond_variable_values_from_water_orientation(water_orientations[molecule_no]) index = numpy.where(nearest_neighbors_nos[0][molecule_no]==molecule_no)[0] if len(index) == 0: return 0 if water_orientations[molecule_no] > 9: return 3 else: if bvv[index] == -1: return 2 else: return 1
def get_bond_variables_2(water_orientations, nearest_neighbors_nos): result = {} for i, nn in enumerate(nearest_neighbors_nos[0]): result[i] = {} water_orientation = water_orientations[i] bvv = get_bond_variable_values_from_water_orientation(water_orientation) for j, neighbor_no in enumerate(nn): if neighbor_no not in result[i]: result[i][neighbor_no] = {} periodic_axis = nearest_neighbors_nos[2][i][j] assert periodic_axis not in result[i][neighbor_no] result[i][neighbor_no][periodic_axis] = bvv[j] return result
def get_bond_variables(water_orientations, nearest_neighbors_nos): bond_variables = np.zeros((2, len(nearest_neighbors_nos[0]), len(nearest_neighbors_nos[0])), dtype='int8') for i, nn in enumerate(nearest_neighbors_nos[0]): water_orientation = water_orientations[i] bvv = get_bond_variable_values_from_water_orientation(water_orientation) for l, neighbor_no in enumerate(nn): periodic = nearest_neighbors_nos[1][i][l] if neighbor_no > i: bond_variables[periodic][i][neighbor_no][0] = bvv[l] bond_variables[periodic][i][neighbor_no][1] = nearest_neighbors_nos[2][i][l] bond_variables[periodic][neighbor_no][i][0] = -bvv[l] bond_variables[periodic][neighbor_no][i][1] = get_opposite_periodicity_axis_number(nearest_neighbors_nos[2][i][l]) elif neighbor_no == i: bond_variables[periodic][i][neighbor_no][0] = bvv[l] bond_variables[periodic][i][neighbor_no][1] = nearest_neighbors_nos[2][i][l] return bond_variables
def get_bond_types(self, water_orientations): try: return get_bond_types(water_orientations, self.nearest_neighbors_nos) except: """ Bond types: 0: AADD - AADD or a dangling bond 1: AADD - AAD 2: AADD - ADD 3: 1 - 0 : AAD - AADD 4: 1 - 1 : AAD - AAD 5: 1 - 2 : AAD - ADD 6: 2 - 0 : ADD - AADD 7: 2 - 1 : ADD - AAD 8: 2 - 2 : ADD - ADD 9: Dangling bond 10: 3 - 0 : DDD - AADD 11: 3 - 1 : DDD - AAD 12: 3 - 2 : DDD - ADD 13: 3 - 3 : DDD - DDD 14 - 16 : DDD:s other way around """ bond_type_matrix = [[0, 1, 2, 14], [3, 4, 5, 15], [6, 7, 8, 16], [10, 11, 12, 13]] water_molecule_types = self.get_water_molecule_types(water_orientations) result = numpy.zeros((len(water_orientations), len(self.nearest_neighbors_nos[0]), 2), dtype=int) # counts contains the number of bond types # 1:st slot contains the number of donor types ie AAD*-AAD where the one marked with star is doning # the hydrogen bond # 2:nd slot contains the number of acceptor types ie AAD-AAD* counts = numpy.zeros((17, 2), dtype=int) for molecule_no in range(len(water_orientations)): type_a = water_molecule_types[molecule_no] if type_a != -1 : bvv = get_bond_variable_values_from_water_orientation(water_orientations[molecule_no]) for i, nn in enumerate(self.nearest_neighbors_nos[0][molecule_no]): # IF a dangling bond if nn == molecule_no: result[molecule_no][i][0] = 9 if bvv[i] == 1: counts[9][1] += 1 else: counts[9][0] += 1 else: type_b = water_molecule_types[nn] if type_b != -1: bt = bond_type_matrix[type_a][type_b] result[molecule_no][i][0] = bt if bvv[i] == 1: counts[bt][0] += 1 result[molecule_no][i][1] = 0 elif bvv[i] == -1: counts[bt][1] += 1 result[molecule_no][i][1] = 1 return result, counts