Beispiel #1
0
	def check_neighbor_edge_correlation(self):
		"""
		Ensures there is a bijection between neighbors and edges of same type
		This method can be compatible with both the types of triangle.
		"""
		spacelike_edges = set([])
		timelike_edges = set([])
		for n in self.get_sst_neighbors():
			shared_spacelike_edges = ut.set_intersection([n.spacelike_edges, self.spacelike_edges])
			shared_timelike_edges = ut.set_intersection([n.timelike_edges, self.timelike_edges])
			if len(shared_spacelike_edges) == 1 : 
				spacelike_edges.add(list(shared_spacelike_edges)[0])
			elif len(shared_timelike_edges) == 1 :
				timelike_edges.add(list(shared_timelike_edges)[0])
			else: 
				print(" Sorry, there is no shared edges of sst neigbors.")
		for n in self.get_tts_neighbors():
			shared_spacelike_edges = ut.set_intersection([n.spacelike_edges, self.spacelike_edges])
			shared_timelike_edges = ut.set_intersection([n.timelike_edges, self.timelike_edges])
			if len(shared_spacelike_edges) == 1 : 
				spacelike_edges.add(list(shared_spacelike_edges)[0])
			elif len(shared_timelike_edges) == 1 :
				timelike_edges.add(list(shared_timelike_edges)[0])
			else: 
				print(" Sorry, there is no shared edges of tts_neighbors.")
		if spacelike_edges != self.spacelike_edges and timelike_edges != self.timelike_edges:
			print("\n Erroneous Triangle!\n")
			print(self)
			raise ValueError("Each neighbor doesnot share exactly 1 edges of same type")
Beispiel #2
0
    def triangles_shared_with(self, other_instance_or_id):
        """
		Tests to see whether self is a vertex of one of the same triangles
		as other. Other can be a vertex instance or a vertex ID. If triangles
		exist, returns them. Otherwise, returns false.
		"""
        # Parse input
        other = self.parse_input(other_instance_or_id)
        # The triangles shared with self:
        shared_sst_triangles = ut.set_intersection(
            [set(self.get_sst_triangles()),
             set(other.get_sst_triangles())])
        shared_tts_triangles = ut.set_intersection(
            [set(self.get_tts_triangles()),
             set(other.get_tts_triangles())])
        return shared_sst_triangles, shared_tts_triangles
Beispiel #3
0
def move_3_to_1(cmpx):
    "Applies a 3->1 move to the input complex, cmpx."

    # Extract the complex, which contains three triangles.
    if len(cmpx.get_triangles()) == 3:
        original_triangles = [sd.triangle.instances[i] \
                                  for i in cmpx.get_triangles()]
    else:
        raise ValueError("There should be exactly 3 triangles for the " +
                         "3->1 complex.")

    # Extract the boundary vertices
    original_vertices = [set(t.get_vertices()) for t in original_triangles]
    central_vertex = list(ut.set_intersection(original_vertices))[0]
    boundary_vertices = ut.set_union(original_vertices) \
        - set([central_vertex])
    boundary_vertex_ids = [v.get_id() for v in boundary_vertices]

    # Extract the edges to be removed (there are 3)
    # Lambda functions for clarity
    get_edges = lambda i: set(sd.triangle.instances[i].get_edges())
    intersected_element = lambda L: ut.only_element(ut.set_intersection(L))
    # Nested list comprehensions: take the intersection of the set of
    # edges associated with pairs of the triangles we care
    # about. These edges are flagged for deleteion.
    shared_edges = [intersected_element([get_edges(i) for i in c]) \
                        for c in ut.k_combinations(cmpx.get_triangles())]
    # There should only be 3 shared edges. If there are more, we messed up.
    assert len(shared_edges) == 3
    
    # Make the new triangle
    new_triangle = sm.build_triangle_and_edges(boundary_vertex_ids)

    # Clean up
    for t in original_triangles: # Delete the old triangles:
        sm.remove_triangle(t)
    for e in shared_edges: # Delete the old edges.
        sm.remove_edge(e)
    sd.vertex.delete(central_vertex) # Delete the old vertex

    # Set triangles, neihgbors, and check topology
    set_neighbors_and_triangles(boundary_vertices,[new_triangle])

    return True
Beispiel #4
0
 def triangles_shared_with(self,other_instance_or_id):
     """
     Tests to see whether self is a vertex of one of the same
     triangles as other. Other can be a vertex instance or a vertex
     ID. If triangles exist, returns them. Otherwise, returns false.
     """
     # Parse input 
     other = self.parse_input(other_instance_or_id)
     # The triangles shared with self:
     shared_triangles = ut.set_intersection([set(self.get_triangles()),
                                             set(other.get_triangles())])
     return shared_triangles
Beispiel #5
0
 def check_neighbor_edge_correlation(self):
     """
     Ensures there is a bijection between neighbors and edges.
     """
     edges = set([])
     for n in self.get_neighbors():
         shared_edges = ut.set_intersection([n.edges,self.edges])
         if len(shared_edges) == 1:
             edges.add(list(shared_edges)[0])
     if edges != self.edges:
         print "\nErroneous Triangle!\n"
         print self
         raise ValueError("Each neighbor does not share exactly 1 edge!")
Beispiel #6
0
def complex_3_to_1(simplex_id_or_simplex):
    """
    Takes a simplex or simplex id as input and calculates what, if
    any, complices are topologically acceptable to operate on.

    The 3->1 move requires a vertex that is attached to 3
    simplices. There is a slight danger that volume decreasing moves
    can make a system topologically unacceptable. If this is the case,
    then the function returns False.

    If there is more than one acceptable complex, returns one at
    random.
    """
    volume_decrease = 2
    if not check_area_decreasing_validity(volume_decrease):
        return False

    # Extract triangle
    triangle = extract_triangle(simplex_id_or_simplex)

    # Extract vertices
    vertices = triangle.get_vertices()

    # If a vertex has only three triangles, consider it
    ids = lambda x: x.get_triangle_ids() # For convenience
    possibilities = [ids(v) for v in vertices if len(ids(v)) == 3]
    
    # Each boundary point on a possible complex must be attached to at
    # least 4 triangles
    # Function to extract vertex class objects from a triangle id
    obj = lambda i: sd.triangle.instances[i].get_vertices()
    # function to extract the boundary points of a complex possibility
    boundaries = lambda c: ut.set_union([set(obj(t)) for t in c]) \
        - ut.set_intersection([set(obj(t)) for t in c])
    # Function that tells us if every boundary vertex of a possibility
    # is connected to greater than 3 simplex
    acceptable = lambda p: len([b for b in boundaries(p) if len(b) > 3]) == 3

    # Only accept a possibility if each boundary vertex has 4 or more
    # triangles.
    complices = [complex(p) for p in possibilities if acceptable(p)]

    if len(complices) == 1:
        return complices[0]
    elif len(complices) > 1:
        return random.choice(complices)
    else:
        return False
Beispiel #7
0
def try_3_to_1(simplex_id_or_simplex):
    """
    Tries a 3->1 move and returns the move data that the metropolis
    algorithm will use to decide whether or not to accept the move. If
    the move is simply not topologically acceptable, returns false.
    """
    # The complex
    cmpx = complex_3_to_1(simplex_id_or_simplex)
    
    # If there are no topologically acceptable complices, stop right
    # now and return False. Otherwise, extract the triangles.
    if cmpx:
        triangles = cmpx.get_triangles()
    else:
        return False

    # Now that we have the triangle, extract the list of points of
    # each triangle.
    old_vertices = [sd.triangle.instances[t].get_vertices() \
                        for t in triangles]
    # The central vertex is the intersection of all the vertices in
    # the old triangles
    central_vertex = ut.set_intersection([set(t) for t in old_vertices])
    # The boundary vertices are the union of the vertices of the old
    # triangles minus the intersection:
    boundary_vertices = ut.set_union([set(t) for t in old_vertices]) \
        - central_vertex

    # We're removing the central vertex, but each boundary vertex will
    # be attached to 1 fewer triangle.
    
    # "Replace" the 3 original vertices
    removed_vertices = [st.imaginary_vertex(len(v),False) \
                            for v in boundary_vertices]
    added_vertices = [st.imaginary_vertex(len(v)-1,True) \
                          for v in boundary_vertices]
    # "Remove" the center vertex
    removed_vertices.append(st.imaginary_vertex(3,False))

    return st.move_data(removed_vertices + added_vertices,cmpx,
                        move_3_to_1,-2)