def do(self): cache = context.application.cache parent = cache.node unit_cell = None if isinstance(parent, UnitCell): unit_cell = parent Atom = context.application.plugins.get_node("Atom") def yield_positioned_atoms(): for child in parent.children: if isinstance(child, Atom): yield PositionedObject(child, child.transformation.t) binned_atoms = SparseBinnedObjects(yield_positioned_atoms(), periodic.max_radius*0.4) def overlap(positioned1, positioned2): number = positioned1.id.number if number != positioned2.id.number: return delta = parent.shortest_vector(positioned2.coordinate - positioned1.coordinate) distance = math.sqrt(numpy.dot(delta, delta)) if distance < periodic[number].vdw_radius*0.4: return True cf = ClusterFactory() for (positioned1, positioned2), foo in IntraAnalyseNeighboringObjects(binned_atoms, overlap)(unit_cell): cf.add_members([positioned1.id, positioned2.id]) clusters = cf.get_clusters() del cf # define the new singles singles = [] for cluster in clusters: number = cluster.members[0].number single = Atom(name="Single " + periodic[number].symbol) single.set_number(number) singles.append((single, cluster.members)) # calculate their positions for single, overlappers in singles: # in the following algorithm, we suppose that the cluster of # atoms is small compared to the parent's periodic sizes # (if the parent is a periodic system) first_pos = overlappers[0].transformation.t delta_to_mean = numpy.zeros(3, float) for atom in overlappers[1:]: delta_to_mean += parent.shortest_vector(atom.transformation.t - first_pos) delta_to_mean /= float(len(overlappers)) single.transformation.t = first_pos + delta_to_mean # modify the model for single, overlappers in singles: lowest_index = min([atom.get_index() for atom in overlappers]) primitive.Add(single, parent, index=lowest_index) for atom in overlappers: while len(atom.references) > 0: primitive.SetTarget(atom.references[0], single) primitive.Delete(atom)
def test_blind(self): cf = ClusterFactory() for counter in xrange(1000): a = random.randint(0, 100) b = random.randint(0, 100) if (a+b)%2 == 0: cf.add_members([a, b]) for cluster in cf.get_clusters(): #print cluster.members tmp = numpy.array(cluster.members) % 2 #print tmp self.assert_((tmp == 0).all() or (tmp == 1).all())
def test_blind(self): cf = ClusterFactory() for counter in xrange(1000): a = random.randint(0, 100) b = random.randint(0, 100) if (a + b) % 2 == 0: cf.add_members([a, b]) for cluster in cf.get_clusters(): #print cluster.members tmp = numpy.array(cluster.members) % 2 #print tmp self.assert_((tmp == 0).all() or (tmp == 1).all())
def connect_state_variables(self): # before we connect the state variables, we must assign indices to # the variables. This is regulated by the constraints that apply. # first cluster the variables into groups. They are grouped by the constraints. # for example: constraint A(1, 2) and B(2, 3) will make variables 1, 2, 3 related # trhough the constraintderivatives matrix. All nonrelated variables will be put together # at the end of the state vector. cf = ClusterFactory(RuleCluster) for constraint in self.constraints: cf.add_related(RuleCluster(constraint.input_variables, [constraint])) self.constraint_clusters = cf.get_clusters() del cf # assign state indices to the variables state_index = 0 excess_index = 0 self.unconstrained_variables = set(self.state_variables) for cluster in self.constraint_clusters: cluster.state_index = state_index for variable in cluster.items: self.unconstrained_variables.remove(variable) variable.state_index = state_index state_index += variable.dimension cluster.input_dimension = sum([variable.dimension for variable in cluster.items]) cluster.output_dimension = sum([constraint.output_dimension for constraint in cluster.rules]) cluster.inputs = self.state[cluster.state_index: cluster.state_index + cluster.input_dimension] cluster.state_derivatives = self.derivatives[cluster.state_index: cluster.state_index + cluster.input_dimension] cluster.outputs = numpy.zeros(cluster.output_dimension, float) cluster.constraint_derivatives = numpy.zeros((cluster.output_dimension, cluster.input_dimension), float) output_index = 0 for constraint in cluster.rules: constraint.sanity_check() constraint.connect_outputs(output_index, cluster.outputs) constraint.connect_derivatives([ cluster.constraint_derivatives[ output_index: output_index + constraint.output_dimension, variable.state_index - cluster.state_index: variable.state_index - cluster.state_index + variable.dimension ] for variable in constraint.input_variables ]) output_index += constraint.output_dimension for variable in self.unconstrained_variables: variable.state_index = state_index state_index += variable.dimension for variable in self.state_variables: variable.connect(self.state, self.derivatives, self.mass)