Example #1
0
    def __init__(self, entries, elements=None):
        """
        Standard constructor for phase diagram.

        Args:
            entries:
                A list of PDEntry-like objects having an energy,
                energy_per_atom and composition.
            elements:
                Optional list of elements in the phase diagram. If set to None,
                the elements are determined from the the entries themselves.
        """
        if elements is None:
            elements = set()
            map(elements.update, [entry.composition.elements
                                  for entry in entries])
        elements = list(elements)
        # Qhull seems to be sensitive to choice of independent composition
        # components due to numerical issues in higher dimensions. The
        # code permutes the element sequence until one that works is found.
        dim = len(elements)
        el_refs = {}
        for el in elements:
            el_entries = filter(lambda e: e.composition.is_element and
                                e.composition.elements[0] == el, entries)
            if len(el_entries) == 0:
                raise PhaseDiagramError(
                    "There are no entries associated with terminal {}."
                    .format(el))
            el_refs[el] = min(el_entries, key=lambda e: e.energy_per_atom)

        data = []
        for entry in entries:
            comp = entry.composition
            row = map(comp.get_atomic_fraction, elements)
            row.append(entry.energy_per_atom)
            data.append(row)

        data = np.array(data)
        self.all_entries_hulldata = data[:, 1:]

        # Calculate formation energies and remove positive formation energy
        # entries
        vec = [el_refs[el].energy_per_atom for el in elements] + [-1]
        form_e = -np.dot(data, vec)
        ind = np.where(form_e <= -self.formation_energy_tol)[0].tolist()
        ind.extend(map(entries.index, el_refs.values()))
        qhull_entries = [entries[i] for i in ind]
        qhull_data = data[ind][:, 1:]

        if len(qhull_data) == dim:
            self.facets = [range(dim)]
        else:
            facets = ConvexHull(qhull_data, joggle=True).vertices
            finalfacets = []
            for facet in facets:
                is_non_element_facet = any(
                    (len(qhull_entries[i].composition) > 1 for i in facet))
                if is_non_element_facet:
                    m = qhull_data[facet]
                    m[:, -1] = 1
                    if abs(np.linalg.det(m)) > 1e-8:
                        finalfacets.append(facet)
            self.facets = finalfacets

        self.all_entries = entries
        self.qhull_data = qhull_data
        self.dim = dim
        self.el_refs = el_refs
        self.elements = elements
        self.qhull_entries = qhull_entries
def draw_dual_transform():
    xlb = 0
    xrb = 10
    ylb = 0
    yrb = 10

    A = np.array([-4, -1, -1, -0.25, 1, 0.5])
    B = np.array([1, 1, 1, 1, 1, 1])
    C = np.array([5, -5, 0, -3, -10, -10])
    CLR = np.array(["red", "yellow", "brown", "green", "blue", "grey"])
    HP = []

    X = A / B
    Y = C / B

    ch = ConvexHull(np.transpose([X, Y]))

    ax = plt.subplot(1, 2, 1)
    for a, b, c, clr in zip(A, B, C, CLR):
        HP.append(HalfPlane(a, b, c))
        HP[len(HP) - 1].draw(bclr=clr, left_b=xlb, right_b=xrb)

    ax.text(3, 2, "$\mathcal{LE}$")

    ax.axis([xlb, xrb, ylb, yrb])

    bx = plt.subplot(1, 2, 2)

    bx.text(-2, 2, "$\mathcal{UH}$")

    leftX = 500
    rightX = -500
    leftInd = 0
    rightInd = 0

    bottomHP = HalfPlane(0, -1, 0)

    P = []

    for v in ch.vertices:
        if X[v[0]] > X[v[1]]:
            P.append(HP[v[0]].intersect(HP[v[1]]))
            bx.plot(X[v], Y[v], color="black", linewidth=3)
            if X[v[0]] > rightX:
                rightX = X[v[0]]
                rightInd = v[0]
            if X[v[1]] < leftX:
                leftX = X[v[1]]
                leftInd = v[1]

    P.append(HP[leftInd].intersect(bottomHP))
    P.append(HP[rightInd].intersect(bottomHP))
    P.sort(key=lambda p: p.x)

    for i in range(len(P) - 1):
        ax.plot([P[i].x, P[i + 1].x], [P[i].y, P[i + 1].y],
                color="black",
                linewidth=3)

    for x, y, clr in zip(X, Y, CLR):
        bx.plot(x, y, color=clr, marker="o")

    plt.show()
Example #3
0
    s = Simplex(coords)
    print('volume of simplex', s.volume())
    print(s.inertia(s.centroid()))
    # t = Polyeder(coords)
    # #print t.volume()

    # print ('volume', t.volume_by_cm())

    print('####### third example unit cube #########')

    coords.append([0, 1, 1])
    coords.append([1, 0, 1])
    coords.append([1, 1, 0])
    coords.append([1, 1, 1])

    p = ConvexHull(coords)
    # #print p.volume()

    print('volume', p.volume())
    print('volume_divergence_theorem', p.volume_divergence_theorem())
    I, v = p.inertia(p.centroid())
    print('inertia:')
    print(I)

    I_check = numpy.zeros((3, 3))
    I_check[0, 0] = (1 + 1) / 12.0
    I_check[1, 1] = (1 + 1) / 12.0
    I_check[2, 2] = (1 + 1) / 12.0
    #print('I_check',I_check)
    #print('check',I_check-I)
    print('error', numpy.linalg.norm(I_check - I) / numpy.linalg.norm(I_check))
Example #4
0
    def _make_pourbaixdiagram(self):
        """
        Calculates entries on the convex hull in the dual space.
        """
        stable_entries = set()
        self._qhull_data = self._create_conv_hull_data()
        dim = len(self._qhull_data[0])
        if len(self._qhull_data) < dim:
            raise Exception("Can only do elements with at-least 3 entries"
                            " for now")
        if len(self._qhull_data) == dim:
            self._facets = [list(range(dim))]
        else:
            facets_pyhull = np.array(ConvexHull(self._qhull_data).vertices)
            self._facets = np.sort(np.array(facets_pyhull))
            logger.debug("Final facets are\n{}".format(self._facets))

            logger.debug("Removing vertical facets...")
            vert_facets_removed = list()
            for facet in self._facets:
                facetmatrix = np.zeros((len(facet), len(facet)))
                count = 0
                for vertex in facet:
                    facetmatrix[count] = np.array(self._qhull_data[vertex])
                    facetmatrix[count, dim - 1] = 1
                    count += 1
                if abs(np.linalg.det(facetmatrix)) > 1e-8:
                    vert_facets_removed.append(facet)
                else:
                    logger.debug("Removing vertical facet : {}".format(facet))

            logger.debug("Removing UCH facets by eliminating normal.z >0 ...")

            # Find center of hull
            vertices = set()
            for facet in vert_facets_removed:
                for vertex in facet:
                    vertices.add(vertex)
            c = [0.0, 0.0, 0.0]
            c[0] = np.average(
                [self._qhull_data[vertex][0] for vertex in vertices])
            c[1] = np.average(
                [self._qhull_data[vertex][1] for vertex in vertices])
            c[2] = np.average(
                [self._qhull_data[vertex][2] for vertex in vertices])

            # Shift origin to c
            new_qhull_data = np.array(self._qhull_data)
            for vertex in vertices:
                new_qhull_data[vertex] -= c

            # For each facet, find normal n, find dot product with P, and
            # check if this is -ve
            final_facets = list()
            for facet in vert_facets_removed:
                a = new_qhull_data[facet[1]] - new_qhull_data[facet[0]]
                b = new_qhull_data[facet[2]] - new_qhull_data[facet[0]]
                n = np.cross(a, b)
                val = np.dot(n, new_qhull_data[facet[0]])
                if val < 0:
                    n = -n
                if n[2] <= 0:
                    final_facets.append(facet)
                else:
                    logger.debug("Removing UCH facet : {}".format(facet))
            final_facets = np.array(final_facets)
            self._facets = final_facets

        stable_vertices = set()
        for facet in self._facets:
            for vertex in facet:
                stable_vertices.add(vertex)
                stable_entries.add(self._qhull_entries[vertex])
        self._stable_entries = stable_entries
        self._vertices = stable_vertices
Example #5
0
 def qhull(self):
     self.convexHull = ConvexHull([[vertex.x, vertex.y]
                                   for vertex in self.Vertices])
     for segment in self.convexHull.vertices:
         self.ch_poly.append(
             Segment(self.Vertices[segment[0]], self.Vertices[segment[1]]))
Example #6
0
    def get_chempot_range_map(self, limits=[[-2, 16], [-4, 4]]):
        """
        Returns a chemical potential range map for each stable entry.

        Args:
            elements: Sequence of elements to be considered as independent
                variables. E.g., if you want to show the stability ranges of
                all Li-Co-O phases wrt to uLi and uO, you will supply
                [Element("Li"), Element("O")]

        Returns:
            Returns a dict of the form {entry: [simplices]}. The list of
            simplices are the sides of the N-1 dim polytope bounding the
            allowable chemical potential range of each entry.
        """
        tol = PourbaixAnalyzer.numerical_tol
        all_chempots = []
        facets = self._pd.facets
        for facet in facets:
            chempots = self.get_facet_chempots(facet)
            chempots["H+"] /= -0.0591
            chempots["V"] = -chempots["V"]
            chempots["1"] = chempots["1"]
            all_chempots.append([chempots[el] for el in self._keys])

        basis_vecs = []
        on_plane_points = []
        # Create basis vectors
        for entry in self._pd.stable_entries:
            ie = self._pd.qhull_entries.index(entry)
            row = self._pd._qhull_data[ie]
            on_plane_points.append([0, 0, row[2]])
            this_basis_vecs = []
            norm_vec = [-0.0591 * row[0], -1 * row[1], 1]
            if abs(norm_vec[0]) > tol:
                this_basis_vecs.append([-norm_vec[2] / norm_vec[0], 0, 1])
            if abs(norm_vec[1]) > tol:
                this_basis_vecs.append([0, -norm_vec[2] / norm_vec[1], 1])
            if len(this_basis_vecs) == 0:
                basis_vecs.append([[1, 0, 0], [0, 1, 0]])
            elif len(this_basis_vecs) == 1:
                if abs(this_basis_vecs[0][0]) < tol:
                    this_basis_vecs.append([1, 0, 0])
                else:
                    this_basis_vecs.append([0, 1, 0])
                basis_vecs.append(this_basis_vecs)
            else:
                basis_vecs.append(this_basis_vecs)

        # Find point in half-space in which optimization is desired
        ph_max_contrib = -1 * max(
            [abs(0.0591 * row[0])
             for row in self._pd._qhull_data]) * limits[0][1]
        V_max_contrib = -1 * max([abs(row[1]) for row in self._pd._qhull_data
                                  ]) * limits[1][1]
        g_max = (-1 * max([abs(pt[2]) for pt in on_plane_points]) +
                 ph_max_contrib + V_max_contrib) - 10
        point_in_region = [7, 0, g_max]

        # Append border hyperplanes along limits
        for i in range(len(limits)):
            for j in range(len(limits[i])):
                basis_vec_1 = [0.0] * 3
                basis_vec_2 = [0.0] * 3
                point = [0.0] * 3
                basis_vec_1[2] = 1.0
                basis_vec_2[2] = 0.0
                for axis in range(len(limits)):
                    if axis is not i:
                        basis_vec_1[axis] = 0.0
                        basis_vec_2[axis] = 1.0
                basis_vecs.append([basis_vec_1, basis_vec_2])
                point[i] = limits[i][j]
                on_plane_points.append(point)

        # Hyperplane enclosing the very bottom
        basis_vecs.append([[1, 0, 0], [0, 1, 0]])
        on_plane_points.append([0, 0, 2 * g_max])
        hyperplane_list = [
            Halfspace.from_hyperplane(basis_vecs[i], on_plane_points[i],
                                      point_in_region)
            for i in range(len(basis_vecs))
        ]
        hs_int = HalfspaceIntersection(hyperplane_list, point_in_region)
        int_points = hs_int.vertices
        pourbaix_domains = {}
        self.pourbaix_domain_vertices = {}

        for i in range(len(self._pd.stable_entries)):
            vertices = [[int_points[vert][0], int_points[vert][1]]
                        for vert in hs_int.facets_by_halfspace[i]]
            if len(vertices) < 1:
                continue
            pourbaix_domains[self._pd.stable_entries[i]] = ConvexHull(
                vertices).simplices

            # Need to order vertices for highcharts area plot
            cx = sum([vert[0] for vert in vertices]) / len(vertices)
            cy = sum([vert[1] for vert in vertices]) / len(vertices)
            point_comp = lambda x, y: x[0] * y[1] - x[1] * y[0]
            vert_center = [[v[0] - cx, v[1] - cy] for v in vertices]
            vert_center.sort(key=cmp_to_key(point_comp))
            self.pourbaix_domain_vertices[self._pd.stable_entries[i]] =\
             [[v[0] + cx, v[1] + cy] for v in vert_center]

        self.pourbaix_domains = pourbaix_domains
        return pourbaix_domains
Example #7
0
File: paths.py Project: zbanks/axi
def convex_hull(points):
    hull = ConvexHull(points)
    vertices = set(i for v in hull.vertices for i in v)
    return [hull.points[i] for i in vertices]
Example #8
0
    s = Simplex(coords)
    print('volume of simplex',s.volume())
    print(s.inertia(s.centroid()))
    # t = Polyeder(coords)
    # #print t.volume()

    # print ('volume', t.volume_by_cm())

    print('####### third example unit cube #########')

    coords.append([0,1,1])
    coords.append([1,0,1])
    coords.append([1,1,0])
    coords.append([1,1,1])

    p = ConvexHull(coords)
    # #print p.volume()

    print ('volume', p.volume())
    print ('volume_divergence_theorem', p.volume_divergence_theorem())
    I,v=p.inertia(p.centroid())
    print('inertia:')
    print(I)

    I_check= numpy.zeros((3,3))
    I_check[0,0] = (1+1)/12.0
    I_check[1,1] = (1+1)/12.0
    I_check[2,2] = (1+1)/12.0
    #print('I_check',I_check)
    #print('check',I_check-I)
    print('error',numpy.linalg.norm(I_check-I)/numpy.linalg.norm(I_check))
Example #9
0
def convex_hull(points):
    vertices = ConvexHull(points).vertices
    return [
        points[idx]
        for idx in set([point for pair in vertices for point in pair])
    ]
Example #10
0
    def detect_contact(self):
        """
        This function is responsible for detecting the contact forces between the robot's fingers and the object, in every simulation loop.
        It also calculates the score of the grasp based on the prefered method (inner product/ convex hull) and checks for finger collisions
        """
        global sim
        counter = 0
        contact_force = [0]*len(self.finger_geom)
        contact_list = []
        contact_frame = 0
        finger_collision = 0
        for index in range(13):
            contact = sim.data.contact[index]

            """Check if this contact involves any of the robot's fingers and the object"""
            if contact.geom1 in self.finger_geom and contact.geom2 in self.object_geom:

                idx = self.finger_geom.index(contact.geom1)

                """
                Check if this contact still exists. In mujoco, a contact remains in the contacts table, until it gets replaced. This means that we have to check if the contact is still relevant,
                by checking the contact.dist parameter. When a contact is present across multiple simulation steps, this parameter oscillates a bit, due to simulation imperfections. So if a contact is inactive,
                the parameter will have the same value between two successive steps. We use this property to identify active contacts
                """

                if contact.dist != self.last_contact[idx]:
                    self.contact_points[idx] = contact.dist
                    counter +=1
                    contact_force_vector = np.array([0, 0, 0, 0, 0, 0], dtype=np.float64)
                    functions.mj_contactForce(model, sim.data, index, contact_force_vector)
                    contact_force[idx] = contact_force_vector[0]
                    contact_list.append(self.Contact_point(force = contact_force_vector[0], frame = contact.frame, geom = contact.geom1, index = idx, coordinates = contact.pos, obj_geom = contact.geom2))
                    sim.data.contact[index].geom1 = 99

            """Check for finger collision """
            if contact.geom1 in self.finger_geom and contact.geom2 in self.finger_geom:
                finger_collision = 1
                break

        for i in range(len(self.finger_geom)):
            self.last_contact[i] = self.contact_points[i]

        score = 0
        hull = 0


        """Calculate Inner Product/ Convex Hull score"""
        if self.convex_option == 0:
            for i in range(len(contact_list) -1):
                for j in range(i+1, len(contact_list)):
                    a = contact_list[i].frame*contact_list[i].force
                    b = contact_list[j].frame*contact_list[j].force
                    prod = np.inner(a,b)
                    score += -prod

            score =  1 - np.exp(-2*score/160000)
            score =  max(score, 0)

        elif self.convex_option == 1:
            pts = []
            for contact in contact_list:
                pts.append([contact.wrench[0][0], contact.wrench[0][1], contact.wrench[0][2]])
                pts.append([contact.wrench[1][0], contact.wrench[1][1], contact.wrench[1][2]])
                pts.append([contact.wrench[2][0], contact.wrench[2][1], contact.wrench[2][2]])

            if len(pts)>5 and pts:
                try:
                    hull = ConvexHull(pts)
                except AttributeError:
                    pass

        return counter, contact_force, score, finger_collision, hull
Example #11
0
    "Please input the number of random 3D points you want to generate(random range from x, y:-10000 to 10000):"
)
points = []
for i in range(int(n)):
    temp = [random.uniform(-10, 10),
            random.randint(-10, 10)]  # random number generator
    temp.append(temp[0]**2 + temp[1]**2)
    points.append(temp)

for pt in points:
    ax1.plot([pt[0]], [pt[1]], [0], 'ro')
    ax2.plot(pt[0], pt[1], 'ro')

    ax1.plot([pt[0]], [pt[1]], [pt[2]], 'ro')

d = ConvexHull(points)

central_point = [0, 0, 0]
for simplex in d.simplices:
    for index in range(3):
        central_point[index] += (simplex.coords[0][index] +
                                 simplex.coords[1][index] +
                                 simplex.coords[2][index]) / 3
for index in range(3):
    central_point[index] /= len(d.simplices)

lines = set()

for simplex in d.simplices:

    if not downward(central_point, simplex.coords):
Example #12
0
#!/usr/bin/python

import sys
import numpy as np
import irtk

from pyhull.convex_hull import ConvexHull
from irtk.vtk2irtk import voxellise

seg = irtk.imread(sys.argv[1])
output = sys.argv[2]

ZYX = np.transpose(np.nonzero(seg))
pts = seg.ImageToWorld(ZYX[:, ::-1])
hull = ConvexHull(pts)

img = voxellise(hull.points, hull.vertices, header=seg.get_header())

irtk.imwrite(output, img)
Example #13
0
def get_vertices(data):
    return ConvexHull(data).vertices