/
source.py
150 lines (115 loc) · 4.8 KB
/
source.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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
from __future__ import division
import meep as mp
from meep.geom import Vector3, check_nonnegative
def check_positive(prop, val):
if val > 0:
return val
else:
raise ValueError("{} must be positive. Got {}".format(prop, val))
class Source(object):
def __init__(self, src, component, center, size=Vector3(), amplitude=1.0, amp_func=None):
self.src = src
self.component = component
self.center = center
self.size = size
self.amplitude = complex(amplitude)
self.amp_func = amp_func
class SourceTime(object):
def __init__(self, is_integrated=False):
self.is_integrated = is_integrated
class ContinuousSource(SourceTime):
def __init__(self, frequency=None, start_time=0, end_time=1.0e20, width=0,
fwidth=float('inf'), cutoff=3.0, wavelength=None):
if frequency is None and wavelength is None:
raise ValueError("Must set either frequency or wavelength in {}.".format(self.__class__.__name__))
super(ContinuousSource, self).__init__()
self.frequency = 1 / wavelength if wavelength else float(frequency)
self.start_time = start_time
self.end_time = end_time
self.width = max(width, 1 / fwidth)
self.cutoff = cutoff
self.swigobj = mp.continuous_src_time(self.frequency, self.width, self.start_time,
self.end_time, self.cutoff)
self.swigobj.is_integrated = self.is_integrated
class GaussianSource(SourceTime):
def __init__(self, frequency=None, width=0, fwidth=float('inf'), start_time=0, cutoff=5.0, wavelength=None):
if frequency is None and wavelength is None:
raise ValueError("Must set either frequency or wavelength in {}.".format(self.__class__.__name__))
super(GaussianSource, self).__init__()
self.frequency = 1 / wavelength if wavelength else float(frequency)
self.width = max(width, 1 / fwidth)
self.start_time = start_time
self.cutoff = cutoff
self.swigobj = mp.gaussian_src_time(self.frequency, self.width, self.start_time,
self.start_time + 2 * self.width * self.cutoff)
self.swigobj.is_integrated = self.is_integrated
class CustomSource(SourceTime):
def __init__(self, src_func, start_time=-1.0e20, end_time=1.0e20):
super(CustomSource, self).__init__()
self.src_func = src_func
self.start_time = start_time
self.end_time = end_time
self.swigobj = mp.custom_src_time(src_func, start_time, end_time)
self.swigobj.is_integrated = self.is_integrated
class EigenModeSource(Source):
def __init__(self,
src,
center,
eig_lattice_size=None,
eig_lattice_center=None,
component=mp.ALL_COMPONENTS,
direction=mp.AUTOMATIC,
eig_band=1,
eig_kpoint=Vector3(),
eig_match_freq=True,
eig_parity=mp.NO_PARITY,
eig_resolution=0,
eig_tolerance=1e-7,
**kwargs):
super(EigenModeSource, self).__init__(src, component, center, **kwargs)
self.eig_lattice_size = eig_lattice_size
self.eig_lattice_center = eig_lattice_center
self.component = component
self.direction = direction
self.eig_band = eig_band
self.eig_kpoint = eig_kpoint
self.eig_match_freq = eig_match_freq
self.eig_parity = eig_parity
self.eig_resolution = eig_resolution
self.eig_tolerance = eig_tolerance
@property
def eig_lattice_size(self):
return self._eig_lattice_size
@eig_lattice_size.setter
def eig_lattice_size(self, val):
if val is None:
self._eig_lattice_size = self.size
else:
self._eig_lattice_size = val
@property
def eig_lattice_center(self):
return self._eig_lattice_center
@eig_lattice_center.setter
def eig_lattice_center(self, val):
if val is None:
self._eig_lattice_center = self.center
else:
self._eig_lattice_center = val
@property
def eig_band(self):
return self._eig_band
@eig_band.setter
def eig_band(self, val):
self._eig_band = check_positive('EigenModeSource.eig_band', val)
@property
def eig_resolution(self):
return self._eig_resolution
@eig_resolution.setter
def eig_resolution(self, val):
self._eig_resolution = check_nonnegative('EigenModeSource.eig_resolution', val)
@property
def eig_tolerance(self):
return self._eig_tolerance
@eig_tolerance.setter
def eig_tolerance(self, val):
self._eig_tolerance = check_positive('EigenModeSource.eig_tolerance', val)