-
Notifications
You must be signed in to change notification settings - Fork 0
/
contact.py
131 lines (112 loc) · 4.59 KB
/
contact.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
from shapely.geometry import Point
from shapely.geometry import LineString
import shapely
import point
import grad
import interaction
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
def circle_leads(center_theta, width_theta, radius):
"""caluclates where the a lead would fall on the ede of a circular boundary"""
a1 = np.deg2rad(center_theta + width_theta/2)
a2 = np.deg2rad(center_theta - width_theta/2)
point_max = radius * np.array([np.cos(a1), np.sin(a1)])
point_min = radius * np.array([np.cos(a2), np.sin(a2)])
return (point_max, point_min)
def sep_xy(start, end):
"""rearranges the star and end coorinates of a line into x and y speratly"""
x = [start[0], end[0]]
y = [start[1], end[1]]
return [x, y]
class Lead():
def __init__(self, coordinates):
"""attributes of a lead"""
self.coordinates = coordinates
self.start = coordinates[0]
self.end = coordinates [1]
self.line = LineString([tuple(self.start), tuple(self.end)])
self.normal = -grad.grad_line(self.start, self.end)
self.n_collisions = 0
self.length = np.sqrt((self.start[0]-self.end[0])**2+(self.start[1]-self.end[1])**2)
def calculate_line(self, particle):
line_string_coord = particle.line_coordinates()
trajectory = LineString(line_string_coord)
return trajectory
def check_intersection(self, particle, trajectory):
"""returns boolean if the the lead intersects with the path of a particle"""
intersection = self.line.intersection(trajectory)
check = isinstance(intersection, shapely.geometry.Point)
if check:
intersection = [intersection.x, intersection.y]
return [check, intersection]
def get_intersection(self, particle):
"""returns intersection between lead and path of particle"""
line_string_coord = particle.line_coordinates()
trajectory = LineString(line_string_coord)
intersection = self.line.intersection(trajectory)
return intersection
class Source(Lead):
"""Source class which had methods specific for collisions with a source boundary"""
def __init__(self, coordinates):
"""inherits from the Lead class"""
super().__init__(coordinates)
self.type = 'source'
def plot(self):
"""plot the source lead in matplotlib"""
xandy = sep_xy(self.start, self.end)
plt.plot(xandy[0], xandy[1], 'k-', lw=1, color='blue')
def response(self, particle, intersection):
"""used if check_intersection returns true.
output: new particle with position at intersection point,
direcion is unchanged because the particle will be absorbed by source"""
self.n_collisions += 1
particle.coords = intersection
def alternate_response(self, particle, f):
"""alternate response that acts like thermometer
not called in code"""
intersection = self.get_intersection(particle)
if np.random.random() < f:
interaction.diffuse_reflection(particle.specie, self.normal, intersection)
else:
interaction.specular_reflection(particle, self.normal, intersection)
class Drain(Lead):
def __init__(self, coordinates):
"""inherits from the Lead class"""
super().__init__(coordinates)
self.type = 'drain'
def plot(self):
"""plot the drain lead in matplotlib"""
xandy = sep_xy(self.start, self.end)
plt.plot(xandy[0], xandy[1], 'k-', lw=1, color='red')
def response(self, particle, intersection):
"""used if check_intersection returns true.
output: new particle with position at intersection point,
direcion is unchanged because the particle will be absorbed by drain"""
self.n_collisions += 1
particle.coords = intersection
class Thermometer(Lead):
def __init__(self, coordinates, emissivity = 0.4):
"""inherits from the Lead class"""
super().__init__(coordinates)
self.emissivity = emissivity
self.type = 'thermometer'
def plot(self):
"""plot the drain lead in matplotlib"""
xandy = sep_xy(self.start, self.end)
plt.plot(xandy[0], xandy[1], 'k-', lw=1, color='green')
def response(self, particle, initial_intersection):
"""used if collision with thermometer
output: new particle, either specularly or diffusivly scattered"""
self.n_collisions += 1
if self.emissivity >= np.random.random():
"""diffusivly scattered from a random point on the thermometer"""
particle.intermediate_point = initial_intersection
interaction.contact_emmision(self, particle)
else:
"""specularly scattered from the point of intersection"""
intersection = point.Particle(initial_intersection)
interaction.specular_reflection(particle, self.normal, intersection)
def t_norm(self, heater):
"""returns the normalised temperature averaged over the whole thermometer"""
return (self.n_collisions/self.length)/(heater.n_collisions/heater.length)