-
Notifications
You must be signed in to change notification settings - Fork 0
/
incoherent_seed_amplification_with_bandwidth.py
294 lines (272 loc) · 10.5 KB
/
incoherent_seed_amplification_with_bandwidth.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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
import numpy as np
import matplotlib.pyplot as plt
class AmplificationEstimation:
"""Class to estimate the amplification within a crystal"""
def __init__(
self,
power_signal: float = 1,
power_pump: float = 50.0,
absorption_signal: float = 0.25,
absorption_pump: float = 0.5,
wavelength_signal: float = 635.0,
wavelength_pump: float = 408.0,
subdivisions: int = 100,
max_length: float = 20.0,
max_step: float = 0.5,
mode_size_z: float = 0.7,
mode_size_y: float = 0.7,
power_array: list = [30, 60],
min_power: float = 0,
seed_bandwidth: float = 0.2,
):
"""
Initialization of the class instance
Parameters
----------
power_signal: float
initial signal power in mW
power_pump: float
initial pump power in mW
absorption_signal: float
absorption of signal
absorption_pump: float
absorption of pump
wavelength_signal:
wavelength of signal in nm
wavelength_pump: float
wavelength of pump in nm
subdivisions: int
number of subdivisions of crystal length
max_length: float
maximal length of the crystal in mm
max_step: float
step size of the main division
mode_size_z: float
mode size in z direction in um
mode_size_y: float
mode size in y direction in um
power_array: list
contains the input power which should compared within the plot of the power
after crystal
min_power
miminum possible pump power to stop amplification process, now works only for 0, should be adjusted
"""
self.power_signal = power_signal
self.power_pump = power_pump
self.absorption_signal = absorption_signal
self.absorption_pump = absorption_pump
self.wavelength_signal = wavelength_signal
self.wavelength_pump = wavelength_pump
self.max_length = max_length
self.max_step = max_step
self.max_length_array = np.linspace(
0, self.max_length, num=int(self.max_length / self.max_step) + 1
)
self.mode_size_z = mode_size_z
self.mode_size_y = mode_size_y
self.intensity_factor = 2.6 * 3.6 / (self.mode_size_z * self.mode_size_y)
self.gain_factor = 0.00336 * np.sqrt(self.intensity_factor)
self.power_array = power_array
self.subdivisions = subdivisions
self.min_power = min_power
self.seed_bandwidth = seed_bandwidth
def calculate_amplification(self, gain_all, length, power_overlap):
"""
Calculating the amplification within the crystal for given crystal length
Parameters
----------
gain_all: float
sum of the gain per crystal length
length: float
actual crystal length
Returns
-------
power of the signal at specific length
"""
return (
power_overlap
* np.cosh(gain_all) ** 2
* 10 ** (-self.absorption_signal * length / 100)
)
def calculate_gain(self, power_pump_j, step):
"""
Calculate the gain at each step
Parameters
----------
power_pump_j: float
pump power at specific crystal length
step:
subdivision of crystal / step size
Returns
-------
gain per step
"""
if power_pump_j < self.min_power:
return self.min_power
else:
return np.sqrt(power_pump_j) * self.gain_factor * step
def calculate_power_pump_j(
self, length, step, gain_all, gain_less, power_pump_j_before, power_overlap
):
"""
Calculate pump power at specific crystal length
Parameters
----------
length: float
current length
step: float
step size / subdivision of crystal
gain_all: float
sum of all gain
gain_less: float
sum of all gain without last value
power_pump_j_before: float
pump power before this calculation
Returns
-------
pump power after specific crystal length
"""
delta_nl = (
-(self.wavelength_signal / self.wavelength_pump)
* power_overlap
* 10 ** (-(self.absorption_signal * length - step) / 100)
* (np.sinh(gain_all) ** 2 - np.sinh(gain_less) ** 2)
)
delta_lin = 10 ** (-self.absorption_pump * step / 100) * power_pump_j_before
if power_pump_j_before <= self.min_power:
return self.min_power
else:
return delta_nl + delta_lin
def calculate_power_after_crystal(self):
"""
Calculate power of signal after crystal
Returns
-------
power after crystal
"""
pump_power = []
amplification_list = []
total_signal_power = []
for length in self.max_length_array:
if length == 0:
bandwidth = 10 * self.seed_bandwidth
else:
bandwidth = 3.8 / length
seed_overlap = min(bandwidth / self.seed_bandwidth, 1)
power_overlap = seed_overlap * self.power_signal
pump_power_sublist = []
amplification_sublist = []
gain_all_list = [0]
sub_length_array = np.linspace(0, length, num=self.subdivisions + 1)
sub_step = length / (self.subdivisions + 1)
for sub_length in sub_length_array:
if sub_length == 0:
power_pump_j = self.power_pump
gain_all_list.append(0)
amplification_sublist.append(power_overlap)
pump_power_sublist.append(power_pump_j)
else:
if power_pump_j < self.min_power:
power_pump_j = 0
elif power_pump_j > self.power_pump:
power_pump_j = self.power_pump
gain_all_list.append(
self.calculate_gain(
power_pump_j=self.calculate_power_pump_j(
length=sub_length,
step=sub_step,
gain_all=sum(gain_all_list),
gain_less=sum(gain_all_list[:-1]),
power_pump_j_before=power_pump_j,
power_overlap=power_overlap,
),
step=sub_step,
)
)
power_pump_j = self.calculate_power_pump_j(
length=sub_length,
step=sub_step,
gain_all=sum(gain_all_list),
gain_less=sum(gain_all_list[:-1]),
power_pump_j_before=power_pump_j,
power_overlap=power_overlap,
)
pump_power_sublist.append(power_pump_j)
amp = self.calculate_amplification(
gain_all=sum(gain_all_list),
length=sub_length,
power_overlap=power_overlap,
)
amplification_sublist.append(amp)
amp = amplification_sublist[-1]
pump_power.append(pump_power_sublist[-1])
amplification_list.append(amp)
total_signal_power.append(
amp
+ (1 - seed_overlap) * 10 ** (-self.absorption_signal * length / 100)
)
return amplification_list, total_signal_power, pump_power
def plot_power_signal(self):
"""
Plot power after crystal for different initial pump powers and create figure.
"""
fig, ax = plt.subplots()
for power in self.power_array:
self.power_pump = power
power_after = self.calculate_power_after_crystal()[0]
ax.set_xlabel("Length of crystal [mm]")
ax.set_ylabel("Signal power [mW]")
ax.set_xlim(0, self.max_length)
ax.plot(
self.max_length_array,
power_after,
label=f"{power} mW",
)
with open(f"signal_power_{power}.txt", "w") as f:
f.write("length [mm]\t signal_power [mW]\n")
for counter, length in enumerate(self.max_length_array):
f.write(f"{length}\t {power_after[counter]}\n")
ax.legend()
fig.savefig("Power_signal_with_bandwidth.pdf")
def plot_total(self):
fig, ax = plt.subplots()
for power in self.power_array:
self.power_pump = power
power_after = self.calculate_power_after_crystal()[1]
ax.set_xlabel("Length of crystal [mm]")
ax.set_ylabel("Total power [mW]")
ax.set_xlim(0, self.max_length)
ax.plot(
self.max_length_array,
power_after,
label=f"{power} mW",
)
with open(f"tot_power_{power}.txt", "w") as f:
f.write("length [mm]\t tot_power [mW]\n")
for counter, length in enumerate(self.max_length_array):
f.write(f"{length}\t {power_after[counter]}\n")
ax.legend()
fig.savefig("Power_total_with_bandwidth.pdf")
def plot_pump_power(self):
fig, ax = plt.subplots()
for power in self.power_array:
self.power_pump = power
power_after = self.calculate_power_after_crystal()[2]
ax.set_xlabel("Length of crystal [mm]")
ax.set_ylabel("Pump power [mW]")
ax.set_xlim(0, self.max_length)
ax.plot(
self.max_length_array,
power_after,
label=f"{power} mW",
)
with open(f"pump_power_{power}.txt", "w") as f:
f.write("length [mm]\t pump_power [mW]\n")
for counter, length in enumerate(self.max_length_array):
f.write(f"{length}\t {power_after[counter]}\n")
ax.legend()
fig.savefig("Power_pump_with_bandwidth.pdf")
get_amplification = AmplificationEstimation()
get_amplification.plot_power_signal()
get_amplification.plot_total()
get_amplification.plot_pump_power()