def __init__(self, midpoint, rot_matrix, r, k, d_eq):
		self.r = r
		self.k = k
		self.d_eq = d_eq
		
		self.L = (1/k * 8/3. * (2*r+1)**3 / ((r**2+4*r+1)*(r+1)) * 4*np.pi/3)**(1/3.) * d_eq * 0.5
		
		self.a_long = 1/(2*r+1) * self.L
		self.a_short = r * self.a_long
	
		self.H = np.sqrt(3)/2 * self.L
		self.h = (r+1)/(2*r+1) * self.H
		
		self.t = k*self.h
		
		self.circumcircle = np.sqrt((self.a_long/2.)**2 + (self.H/3.)**2 + (self.t/2.)**2)
		
		self.rot_matrix = rot_matrix
		self.rot_matrix_tr = np.ascontiguousarray(rot_matrix.transpose())
		angle, axis = GeometryTools.rotmatrix_to_axisangle(rot_matrix)
		self.rot_axis = axis
		self.rot_angle = angle
		self.euler_angles = GeometryTools.rotmatrix_to_euler(rot_matrix)
		
		self.basal_area = self.H*self.L/2. - 3*np.sqrt(3)/4 * self.a_short**2
		self.volume = self.basal_area*self.t
		
		# vertices in coordinates of the triangle
		if r > 0:
			self.vertices = np.array([[self.a_long/2, -self.H/3, -self.t/2], [self.a_long/2 + self.a_short/2, np.sqrt(3)/2*self.a_short - self.H/3, -self.t/2], [self.a_short/2, self.h - self.H/3, -self.t/2], [-self.a_short/2, self.h - self.H/3, -self.t/2], [-self.a_long/2 - self.a_short/2, np.sqrt(3)/2*self.a_short - self.H/3, -self.t/2], [-self.a_long/2, -self.H/3, -self.t/2]])
		else:
			self.vertices = np.array([[self.L/2, -self.H/3, -self.t/2], [0, 2*self.H/3, -self.t/2], [-self.L/2, -self.H/3, -self.t/2]])
		
		self.set_midpoint(midpoint)
Exemple #2
0
def prepare_triangles(vol_frac_goal, L, r_d, k_d, d_eq_d):
    """
    Prepares a list of truncated prisms from the given distributions.
    :param vol_frac_goal: Goal volume fraction.
    :param L: Size of window.
    :param r_d: Distribution (callback function) for r, truncation size.
    :param k_d: Distribution (callback function) for k, elongation factor.
    :param d_eq_d: Distribution (callback function) for d, equivalent diameter.
    :return: List of prisms which contain random locations and a random r, k, and d.
    """
    print("Prepare triangles")

    trunc_triangles = list()

    total_volume = L**3
    volume = 0.

    # Make random grains
    while volume < vol_frac_goal * total_volume:
        midpoint = L * np.random.random(3)
        r = r_d()
        k = k_d()
        d_eq = d_eq_d()

        rot_matrix = GeometryTools.random_rotation()

        trunc_triangle = tt.TruncatedTriangle(midpoint, rot_matrix, r, k, d_eq)

        trunc_triangles.append(trunc_triangle)

        volume += trunc_triangle.volume

    return trunc_triangles
def compute_all_misorientation_voxel(trunc_triangles, grain_ids, M):
    """
    Computes misorientation distribution using grain_ids to find grain boundaries.
    """
    print 'Computing voxel based misorientation'
    symOps=[]
    # Unity
    symOps.append(np.eye(3))
    # 3 fold axis around z
    symOps.append(GT.rot_matrix([0,0,1],2*math.pi/3))
    symOps.append(GT.rot_matrix([0,0,-1],2*math.pi/3))
    # 2 fold axis around (sqrt(3),-1,0)
    symOps.append(GT.rot_matrix([math.sqrt(3),-1,0],math.pi))	
    # 2 fold axis around y
    symOps.append(GT.rot_matrix([0,1,0],math.pi))
    # 2 fold axis around (sqrt(3),1,0)
    symOps.append(GT.rot_matrix([math.sqrt(3),1,0],math.pi))	

    from collections import defaultdict
    areas = defaultdict(int)
    angles = defaultdict(float)
    for ix in range(M[0]):
        nx = (ix + 1) % M[0]
        for iy in range(M[1]):
            ny = (iy + 1) % M[1]
            for iz in range(M[2]):
                nz = (iz + 1) % M[2]
                ig = grain_ids[ix + iy * M[0] + iz * (M[0] * M[1])]

                if ig == 1: continue # Skip the Co-phase

                def do_compute(ng):
                    if ig != ng and ng != 1:
                        index = (min(ig, ng), max(ig, ng))
                        areas[index] += 1
                        if index not in angles:
                            angles[index] = compute_misorientation_net(trunc_triangles[ig-2], trunc_triangles[ng-2], symOps)

                # Check all three neighbours (in the + side)
                do_compute(grain_ids[nx + iy * M[0] + iz * (M[0] * M[1])])
                do_compute(grain_ids[ix + ny * M[0] + iz * (M[0] * M[1])])
                do_compute(grain_ids[ix + iy * M[0] + nz * (M[0] * M[1])])

    return angles, areas
def compute_misorientation_net(t1,t2,symmetry=[]):
	"""
	Computes the misorientation between two truncated triangles t1 and t2.
	"""
	R1=t1.rot_matrix
	R2=t2.rot_matrix
	R2inv = np.linalg.inv(R2)
	net_rotation=np.dot(R1,R2inv)
	if len(symmetry)==0:	
		theta,axis = GT.rotmatrix_to_axisangle(net_rotation)
		return theta*180/math.pi
	else:
		angles=[]
		for i in xrange(len(symmetry)):
			for j in xrange(len(symmetry)):	
				theta,axis = GT.rotmatrix_to_axisangle( np.dot( np.dot(symmetry[i],R1),np.dot(R2inv,symmetry[j])))
				angles.append(theta*180/math.pi)
		
		return np.min(angles)
def compute_all_misorientation_net(trunc_triangles,nbrList):
	symOps=[]
	# Unity
	symOps.append(np.eye(3))
	# 3 fold axis around z
	symOps.append(GT.rot_matrix([0,0,1],2*math.pi/3))
	symOps.append(GT.rot_matrix([0,0,-1],2*math.pi/3))
	# 2 fold axis around (sqrt(3),-1,0)
	symOps.append(GT.rot_matrix([math.sqrt(3),-1,0],math.pi))	
	# 2 fold axis around y
	symOps.append(GT.rot_matrix([0,1,0],math.pi))
	# 2 fold axis around (sqrt(3),1,0)
	symOps.append(GT.rot_matrix([math.sqrt(3),1,0],math.pi))	

	angles=[]
	for i,t in enumerate(trunc_triangles):
		for j in xrange(len(nbrList[i])):
		
			theta =  compute_misorientation_net(t,trunc_triangles[ nbrList[i][j] ],symOps)	
			angles.append(theta)
	return angles
Exemple #6
0
def compute_all_misorientation_net(trunc_triangles, nbrList):
    """
    Computes misorientation given a list of trunc_triangles and a neighborList
    Using the net rotation  M_1^-1 * M_2, with a few symmetry operations.
    This method might not be correct.
    """
    symOps = []
    # Unity
    symOps.append(np.eye(3))
    # 3 fold axis around z
    symOps.append(GT.rot_matrix([0, 0, 1], 2*math.pi/3))
    symOps.append(GT.rot_matrix([0, 0, -1], 2*math.pi/3))
    # 2 fold axis around y
    symOps.append(GT.rot_matrix([0, 1, 0], math.pi))
    
    angles = []
    print('Computing misorientation angles net')
    for i, t in enumerate(trunc_triangles):
        for j in xrange(len(nbrList[i])):
            theta = compute_misorientation_net(t, trunc_triangles[nbrList[i][j]], symOps)
            angles.append(theta)
    return angles
Exemple #7
0
def prepare_triangles(vol_frac_goal, L, r_min=0.1, r_max=0.4, k_min=0.2, k_max=0.6):
	"""	
	Prepares random truncated_triangle objects.
	
	Grains are generated until the vol_frac_goal is exceeded.
	Geometry parameters r,k,d and rotation matrix are drawn from uniform distributions.
	Returns the list of truncated triangles sorted by size.
	"""
	print "Prepare triangles"

	d_eq_min = 0.5
	d_eq_max = 2

	trunc_triangles = []

	total_volume = L**3
	volume = 0.

	# Make random grains
	while volume/total_volume < vol_frac_goal:
		midpoint = L*np.random.random(3)
		r = (r_max-r_min)*np.random.random() + r_min
		k = (k_max-k_min)*np.random.random() + k_min
		d_eq = (d_eq_max-d_eq_min)*np.random.random() + d_eq_min

		rot_matrix = GeometryTools.random_rotation()

		trunc_triangle = tt.TruncatedTriangle(midpoint, rot_matrix, r, k, d_eq)

		trunc_triangles.append(trunc_triangle)

		volume += trunc_triangle.volume

	# Sort triangles w.r.t. volume, so that large triangles are added to the box first
	trunc_triangles.sort(key=lambda m: m.volume, reverse=True)

	return trunc_triangles