# Path: phon/mesh_objects/element.py
# class Element:
# 
#     """ Represents a finite element. """
# 
#     def __init__(self, elem_type, vertices):
#         """
#         :param elem_type: The type of the element in Abaqus format.
#         :type elem_type: str
#         :param vertices: The vertices of the element given as node identifiers.
#         :type vertices: list of ints
# 
#         """
#         self.elem_type = elem_type
#         self.vertices = vertices
# 
#     def __str__(self):
#         """
#         Returns a string representation of the element.
# 
#         :return: The string representation
#         :rtype: string
# 
#         """
#         return ("Element of type {0} containing the vertices with "
#                 "id {1}.".format(self.elem_type, self.vertices))
# 
# Path: phon/mesh_objects/element_set.py
# class ElementSet:
# 
#     """ Represents a set of elements """
# 
#     def __init__(self, name, dimension, ids=None):
#         """
#         :param name: Name of the element set.
#         :type name: str
#         :param dimension: The dimension of the elements in the set
#         :type dimension: int
#         :param ids: Identifiers of the elements in the set.
#         :type ids: list of ints
# 
#         """
#         self.name = name
#         self.dimension = dimension
# 
#         if ids is None:
#             ids = []
#         self.ids = ids
# 
#         # Specific properties assigned to the set, e.g. material properties.
#         self.set_properties = {}
# 
#     def get_dimension(self):
#         """
#         Get the dimension of the element set.
# 
#         :return: The dimension.
#         :rtype: int
# 
#         """
#         return self.dimension
# 
#     def __str__(self):
#         """
#         Returns a string representation of the element set.
# 
#         :return: The string representation
#         :rtype: str
# 
#         """
#         return ("Element set with name {0} containing elements with the "
#                 "following ids {1}".format(self.name, self.ids))
# 
#     def get_all_node_ids(self, mesh):
#         """
#         Gets all the nodes identifiers for the elements in the element set.
# 
#         :param mesh: The mesh
#             :type mesh: :class:`phon.mesh_objects.mesh.Mesh()`
#         :return: The node identifiers
#         :rtype: list of ints
# 
#         """
#         all_node_ids = []
# 
#         for element_id in self.ids:
#             all_node_ids += mesh.elements[element_id].vertices
# 
#         return list(set(all_node_ids))
# 
# Path: phon/mesh_objects/node.py
# class Node:
# 
#     """ Represents a node."""
# 
#     def __init__(self, c):
#         """
#         :param c: The coordinates of the node
#         :type c: ndarray
# 
#         """
#         self.c = c
# 
#     def __str__(self):
#         """
#         Returns a string representation of the node.
# 
#         :return: The string representation.
#         :rtype: str
# 
#         """
#         return "Node located at (%f, %f, %f)." % (
#             self.c[0], self.c[1], self.c[2])


from collections import defaultdict
from phon.mesh_objects.element import Element
from phon.mesh_objects.element_set import ElementSet
from phon.mesh_objects.node import Node
import numpy as np

        grain_id_1 = grains_connected_to_face[0]
        grain_id_2 = grains_connected_to_face[1]

        cohesive_set_name = ("cohes" + str(grain_id_1) + "_" +
                             str(grain_id_2))
        cohesive_set = ElementSet(cohesive_set_name, dimension=mesh_dimension)
        mesh.element_sets[cohesive_set_name] = cohesive_set

        # Create two new element sets that will represent the triangles
        # in the new faces. This is not strictly needed but is useful
        # information to have.
        face_set_coh_name_1 = "coh_face_" + \
                              str(grain_id_1) + "_" + str(grain_id_2) + "_1"
        face_set_coh_name_2 = "coh_face_" + \
                              str(grain_id_1) + "_" + str(grain_id_2) + "_2"

        face_set_coh_1 = ElementSet(
            face_set_coh_name_1, dimension=mesh_dimension - 1)
        face_set_coh_2 = ElementSet(
            face_set_coh_name_2, dimension=mesh_dimension - 1)

        mesh.element_sets[face_set_coh_name_1] = face_set_coh_1
        mesh.element_sets[face_set_coh_name_2] = face_set_coh_2

        # For each node in face make two new at the same place
        for node_id in face_set.get_all_node_ids(mesh):
            original_node = mesh.nodes[node_id]
            new_node_id_1 = node_id + n_nodes * grain_id_1
            new_node_id_2 = node_id + n_nodes * grain_id_2

# Path: phon/mesh_objects/element.py
# class Element:
# 
#     """ Represents a finite element. """
# 
#     def __init__(self, elem_type, vertices):
#         """
#         :param elem_type: The type of the element in Abaqus format.
#         :type elem_type: str
#         :param vertices: The vertices of the element given as node identifiers.
#         :type vertices: list of ints
# 
#         """
#         self.elem_type = elem_type
#         self.vertices = vertices
# 
#     def __str__(self):
#         """
#         Returns a string representation of the element.
# 
#         :return: The string representation
#         :rtype: string
# 
#         """
#         return ("Element of type {0} containing the vertices with "
#                 "id {1}.".format(self.elem_type, self.vertices))
# 
# Path: phon/mesh_objects/element_set.py
# class ElementSet:
# 
#     """ Represents a set of elements """
# 
#     def __init__(self, name, dimension, ids=None):
#         """
#         :param name: Name of the element set.
#         :type name: str
#         :param dimension: The dimension of the elements in the set
#         :type dimension: int
#         :param ids: Identifiers of the elements in the set.
#         :type ids: list of ints
# 
#         """
#         self.name = name
#         self.dimension = dimension
# 
#         if ids is None:
#             ids = []
#         self.ids = ids
# 
#         # Specific properties assigned to the set, e.g. material properties.
#         self.set_properties = {}
# 
#     def get_dimension(self):
#         """
#         Get the dimension of the element set.
# 
#         :return: The dimension.
#         :rtype: int
# 
#         """
#         return self.dimension
# 
#     def __str__(self):
#         """
#         Returns a string representation of the element set.
# 
#         :return: The string representation
#         :rtype: str
# 
#         """
#         return ("Element set with name {0} containing elements with the "
#                 "following ids {1}".format(self.name, self.ids))
# 
#     def get_all_node_ids(self, mesh):
#         """
#         Gets all the nodes identifiers for the elements in the element set.
# 
#         :param mesh: The mesh
#             :type mesh: :class:`phon.mesh_objects.mesh.Mesh()`
#         :return: The node identifiers
#         :rtype: list of ints
# 
#         """
#         all_node_ids = []
# 
#         for element_id in self.ids:
#             all_node_ids += mesh.elements[element_id].vertices
# 
#         return list(set(all_node_ids))
# 
# Path: phon/mesh_objects/node.py
# class Node:
# 
#     """ Represents a node."""
# 
#     def __init__(self, c):
#         """
#         :param c: The coordinates of the node
#         :type c: ndarray
# 
#         """
#         self.c = c
# 
#     def __str__(self):
#         """
#         Returns a string representation of the node.
# 
#         :return: The string representation.
#         :rtype: str
# 
#         """
#         return "Node located at (%f, %f, %f)." % (
#             self.c[0], self.c[1], self.c[2])


# Path: phon/mesh_tools/create_cohesive_elements.py
from collections import defaultdict
from phon.mesh_objects.element import Element
from phon.mesh_objects.element_set import ElementSet
from phon.mesh_objects.node import Node
import numpy as np


        grain_id_1 = grains_connected_to_face[0]
        grain_id_2 = grains_connected_to_face[1]

        cohesive_set_name = ("cohes" + str(grain_id_1) + "_" +
                             str(grain_id_2))
        cohesive_set = ElementSet(cohesive_set_name, dimension=mesh_dimension)
        mesh.element_sets[cohesive_set_name] = cohesive_set

        # Create two new element sets that will represent the triangles
        # in the new faces. This is not strictly needed but is useful
        # information to have.
        face_set_coh_name_1 = "coh_face_" + \
                              str(grain_id_1) + "_" + str(grain_id_2) + "_1"
        face_set_coh_name_2 = "coh_face_" + \
                              str(grain_id_1) + "_" + str(grain_id_2) + "_2"

        face_set_coh_1 = ElementSet(
            face_set_coh_name_1, dimension=mesh_dimension - 1)
        face_set_coh_2 = ElementSet(
            face_set_coh_name_2, dimension=mesh_dimension - 1)

        mesh.element_sets[face_set_coh_name_1] = face_set_coh_1
        mesh.element_sets[face_set_coh_name_2] = face_set_coh_2

        # For each node in face make two new at the same place
        for node_id in face_set.get_all_node_ids(mesh):
            original_node = mesh.nodes[node_id]
            new_node_id_1 = node_id + n_nodes * grain_id_1
            new_node_id_2 = node_id + n_nodes * grain_id_2

            mesh.nodes[new_node_id_1] = Node(np.copy(original_node.c))