Пример #1
0
    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)
Пример #2
0
    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())
Пример #3
0
    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())
Пример #4
0
    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)