PyFiberModes 0.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. PyFiberModes/.DS_Store +0 -0
  2. PyFiberModes/VERSION +1 -0
  3. PyFiberModes/__init__.py +38 -0
  4. PyFiberModes/constants.py +32 -0
  5. PyFiberModes/fiber/.DS_Store +0 -0
  6. PyFiberModes/fiber/__init__.py +0 -0
  7. PyFiberModes/fiber/factory.py +448 -0
  8. PyFiberModes/fiber/fiber.py +317 -0
  9. PyFiberModes/fiber/geometry/__init__.py +10 -0
  10. PyFiberModes/fiber/geometry/geometry.py +33 -0
  11. PyFiberModes/fiber/geometry/stepindex.py +181 -0
  12. PyFiberModes/fiber/geometry/supergaussian.py +193 -0
  13. PyFiberModes/fiber/material/__init__.py +13 -0
  14. PyFiberModes/fiber/material/air.py +20 -0
  15. PyFiberModes/fiber/material/claussiusmossotti.py +40 -0
  16. PyFiberModes/fiber/material/compmaterial.py +60 -0
  17. PyFiberModes/fiber/material/fixed.py +36 -0
  18. PyFiberModes/fiber/material/germania.py +14 -0
  19. PyFiberModes/fiber/material/material.py +107 -0
  20. PyFiberModes/fiber/material/sellmeier.py +47 -0
  21. PyFiberModes/fiber/material/sellmeiercomp.py +42 -0
  22. PyFiberModes/fiber/material/silica.py +15 -0
  23. PyFiberModes/fiber/material/sio2f.py +34 -0
  24. PyFiberModes/fiber/material/sio2geo2.py +36 -0
  25. PyFiberModes/fiber/material/sio2geo2cm.py +43 -0
  26. PyFiberModes/fiber/solver/__init__.py +12 -0
  27. PyFiberModes/fiber/solver/cuda.py +124 -0
  28. PyFiberModes/fiber/solver/cudasrc/besseldiff.c +28 -0
  29. PyFiberModes/fiber/solver/cudasrc/chareq.c +314 -0
  30. PyFiberModes/fiber/solver/cudasrc/constf.c +20 -0
  31. PyFiberModes/fiber/solver/cudasrc/hypergf.c +264 -0
  32. PyFiberModes/fiber/solver/cudasrc/ivf.c +49 -0
  33. PyFiberModes/fiber/solver/cudasrc/knf.c +166 -0
  34. PyFiberModes/fiber/solver/mlsif.py +289 -0
  35. PyFiberModes/fiber/solver/solver.py +119 -0
  36. PyFiberModes/fiber/solver/ssif.py +275 -0
  37. PyFiberModes/fiber/solver/tlsif.py +266 -0
  38. PyFiberModes/field.py +405 -0
  39. PyFiberModes/functions.py +137 -0
  40. PyFiberModes/mode.py +186 -0
  41. PyFiberModes/simulator/.DS_Store +0 -0
  42. PyFiberModes/simulator/__init__.py +15 -0
  43. PyFiberModes/simulator/psimulator.py +41 -0
  44. PyFiberModes/simulator/simulator.py +288 -0
  45. PyFiberModes/slrc.py +291 -0
  46. PyFiberModes/tools/__init__.py +0 -0
  47. PyFiberModes/tools/directories.py +41 -0
  48. PyFiberModes/wavelength.py +109 -0
  49. PyFiberModes-0.2.1.dist-info/METADATA +158 -0
  50. PyFiberModes-0.2.1.dist-info/RECORD +52 -0
  51. PyFiberModes-0.2.1.dist-info/WHEEL +5 -0
  52. PyFiberModes-0.2.1.dist-info/top_level.txt +1 -0
PyFiberModes/.DS_Store ADDED
Binary file
PyFiberModes/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.1
@@ -0,0 +1,38 @@
1
+ # This file is part of FiberModes.
2
+ #
3
+ # FiberModes is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # FiberModes is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with FiberModes. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ """ This package provides tools for solving modes in different kind of
17
+ optical fibers.
18
+
19
+ The following classes can be imported directly from fibermodes.
20
+ All those classes are imported if using import *
21
+
22
+ """
23
+
24
+ from .wavelength import Wavelength
25
+ from .mode import Mode, HE11, LP01, Family as ModeFamily
26
+ from .fiber.factory import FiberFactory
27
+ from .simulator.simulator import Simulator
28
+ from .simulator.psimulator import PSimulator
29
+
30
+ __all__ = ['Wavelength',
31
+ 'Mode',
32
+ 'HE11',
33
+ 'LP01',
34
+ 'ModeFamily',
35
+ 'FiberFactory',
36
+ 'Simulator',
37
+ 'PSimulator'
38
+ ]
@@ -0,0 +1,32 @@
1
+ # This file is part of FiberModes.
2
+ #
3
+ # FiberModes is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # FiberModes is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with FiberModes. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+
17
+ """Physical constants.
18
+
19
+ .. codeauthor:: Charles Brunet <charles@cbrunet.net>
20
+ """
21
+
22
+ from math import sqrt, pi
23
+
24
+ c = 299792458.0 #: Speed of light in vacuum (m/s).
25
+ h = 6.62606957e-34 #: Plank constant (m²kg/s).
26
+ mu0 = 1.2566370614359173e-06 #: Vacuum permeability (H/m).
27
+ epsilon0 = 8.854187817620389e-12 #: Vacuum permittivity (F/m).
28
+ eV = 1.602176565e-19 #: Electron charge (C).
29
+
30
+ tpi = 2 * pi #: Two times pi
31
+ eta0 = sqrt(mu0 / epsilon0) #: Impedance of free-space.
32
+ Y0 = sqrt(epsilon0 / mu0) #: Admitance of free-space.
Binary file
File without changes
@@ -0,0 +1,448 @@
1
+ # This file is part of FiberModes.
2
+ import json
3
+ import time
4
+ from distutils.version import StrictVersion as Version
5
+ from operator import mul
6
+ from functools import reduce
7
+ from itertools import product, islice
8
+ from .fiber import Fiber
9
+ from PyFiberModes.slrc import SLRC
10
+ from PyFiberModes.fiber import material as materialmod
11
+ from PyFiberModes.fiber import geometry as geometrymod
12
+ from PyFiberModes.fiber.solver.solver import FiberSolver
13
+ from PyFiberModes.fiber.material.compmaterial import CompMaterial
14
+
15
+
16
+ __version__ = "0.0.1"
17
+
18
+
19
+ class FiberFactoryValidationError(Exception):
20
+
21
+ """Exception emmited when fiber file does not validate.
22
+
23
+ """
24
+ pass
25
+
26
+
27
+ class LayerProxy(object):
28
+
29
+ def __init__(self, layer):
30
+ self._layer = layer
31
+
32
+ def __getattr__(self, name):
33
+ if name in self._layer:
34
+ return self._layer[name]
35
+ else:
36
+ raise AttributeError
37
+
38
+ def __setattr__(self, name, value):
39
+ if name == "_layer":
40
+ super().__setattr__(name, value)
41
+ elif name == "material":
42
+ self._material(value)
43
+ elif name == "type":
44
+ self._type(value)
45
+ elif name in self._layer:
46
+ self._layer[name] = value
47
+ else:
48
+ super().__setattr__(name, value)
49
+
50
+ def __getitem__(self, name):
51
+ return self._layer[name]
52
+
53
+ def __setitem__(self, name, value):
54
+ if name in self._layer:
55
+ self._layer[name] = value
56
+ else:
57
+ raise KeyError
58
+
59
+ def _material(self, value):
60
+ if value != self.material:
61
+ self._layer["material"] = value
62
+ self._layer["mparams"] = [0] * materialmod.__dict__[value].nparams
63
+
64
+ def _type(self, value):
65
+ self._layer["type"] = value
66
+ dp = geometrymod.__dict__[value].DEFAULT_PARAMS
67
+ tp = self._layer["tparams"]
68
+ for i in range(len(tp)-1, len(dp)):
69
+ tp.append(dp[i])
70
+ # print("_type", value, self._layer["tparams"])
71
+
72
+ @property
73
+ def radius(self):
74
+ return self._layer["tparams"][0]
75
+
76
+ @radius.setter
77
+ def radius(self, value):
78
+ self._layer["tparams"][0] = value
79
+
80
+
81
+ class LayersProxy(object):
82
+
83
+ def __init__(self, factory):
84
+ self.factory = factory
85
+
86
+ def __len__(self):
87
+ return len(self.factory._fibers["layers"])
88
+
89
+ def __getitem__(self, index):
90
+ return LayerProxy(self.factory._fibers["layers"][index])
91
+
92
+
93
+ class FiberFactory(object):
94
+
95
+ """FiberFactory is used to instantiate a
96
+ :py:class:`~PyFiberModes.fiber.fiber.Fiber` or a series of
97
+ Fiber objects.
98
+
99
+ It can read fiber definition from json file, and write it back.
100
+ Convenient functions are available to set fiber parameters, and to
101
+ iterate through fiber objects.
102
+
103
+ All fibers build from a given factory share the same number
104
+ of layers, the same kind of geometries, and the same
105
+ materials. However, parameters can vary.
106
+
107
+ Args:
108
+ filename: Name of fiber file to load, or None to construct
109
+ empty Fiberfactory object.
110
+
111
+ """
112
+
113
+ def __init__(self, filename=None):
114
+ self._fibers = {
115
+ "version": __version__,
116
+ "name": "",
117
+ "description": "",
118
+ "author": "",
119
+ "crdate": time.time(),
120
+ "tstamp": time.time(),
121
+ "layers": []
122
+ }
123
+ if filename:
124
+ with open(filename, 'r') as f:
125
+ self.load(f)
126
+ self._Neff = None
127
+ self._Cutoff = None
128
+
129
+ @property
130
+ def name(self):
131
+ """Name of the fiber.
132
+
133
+ The name simply is a string identifier.
134
+
135
+ """
136
+ return self._fibers["name"]
137
+
138
+ @name.setter
139
+ def name(self, value):
140
+ self._fibers["name"] = value
141
+
142
+ @property
143
+ def author(self):
144
+ """Author of the fiber definition.
145
+
146
+ Used as a reference.
147
+
148
+ """
149
+ return self._fibers["author"]
150
+
151
+ @author.setter
152
+ def author(self, value):
153
+ self._fibers["author"] = value
154
+
155
+ @property
156
+ def description(self):
157
+ """Description of the fiber build form this factory.
158
+
159
+ """
160
+ return self._fibers["description"]
161
+
162
+ @description.setter
163
+ def description(self, value):
164
+ self._fibers["description"] = value
165
+
166
+ @property
167
+ def crdate(self):
168
+ """Creation date of this factory.
169
+
170
+ """
171
+ return self._fibers["crdate"]
172
+
173
+ @property
174
+ def tstamp(self):
175
+ """Timestamp (modification date).
176
+
177
+ This is automatically updated when the fiber factory is saved.
178
+
179
+ """
180
+ return self._fibers["tstamp"]
181
+
182
+ @property
183
+ def layers(self):
184
+ """List of layers.
185
+
186
+ """
187
+ return LayersProxy(self)
188
+
189
+ def addLayer(self, pos=None, name="", radius=0,
190
+ material="Fixed", geometry="StepIndex",
191
+ **kwargs):
192
+ """Insert a new layer in the factory.
193
+
194
+ Args:
195
+ pos(int or None): Position the the inserted layer.
196
+ By default, new layer is inserted at the end.
197
+ name(string): Layer name.
198
+ radius(float): Radius of the layer (in meters).
199
+ material(string): Name of the Material (default: Fixed)
200
+ geometry(string): Name of the Geometry (default: StepIndex)
201
+ tparams(list): Parameters for the Geometry
202
+ mparams(list): Parameters for the Material
203
+ index(float): Index of the layer (for Fixed Material, otherwise
204
+ parameters are calculated to give this index)
205
+ x(float): Molar concentration for the Material
206
+ wl(float): Wavelength (in m) used for calculating parameters
207
+ (when index is given)
208
+
209
+ Please note that some parameters are specific to some
210
+ :py:mod:`~PyFiberModes.fiber.material` or
211
+ :py:mod:`~PyFiberModes.fiber.geometry`:
212
+
213
+ :py:class:`~PyFiberModes.fiber.material.fixed.Fixed` material
214
+ **index** is required. **mparams** is ignored.
215
+
216
+ :py:class:`~PyFiberModes.fiber.material.compmaterial.CompMaterial` \
217
+ (:py:class:`~PyFiberModes.fiber.material.sio2geo2.SiO2GeO2`)
218
+ You can specify either **x** or **index** and **wl**.
219
+ **mparams** is ignored.
220
+
221
+ """
222
+ if pos is None:
223
+ pos = len(self._fibers["layers"])
224
+ layer = {
225
+ "name": name,
226
+ "type": geometry,
227
+ "tparams": [radius] + kwargs.pop("tparams", []),
228
+ "material": material,
229
+ "mparams": kwargs.pop("mparams", []),
230
+ }
231
+ if material == "Fixed":
232
+ index = kwargs.pop("index", 1.444)
233
+ layer["mparams"] = [index]
234
+ else:
235
+ Mat = materialmod.__dict__[material]
236
+ if issubclass(Mat, CompMaterial):
237
+ if "x" in kwargs:
238
+ x = kwargs.pop("x")
239
+ elif "index" in kwargs and "wl" in kwargs:
240
+ x = Mat.xFromN(kwargs.pop("wl"), kwargs.pop("index"))
241
+ else:
242
+ x = 0
243
+ layer["mparams"] = [x]
244
+ assert len(kwargs) == 0, "unknown arguments {}".format(
245
+ ", ".join(kwargs.keys()))
246
+ self._fibers["layers"].insert(pos, layer)
247
+
248
+ def removeLayer(self, pos=-1):
249
+ """Remore layer at given position (default: last layer)
250
+
251
+ Args:
252
+ pos(int): Index of the layer to remove.
253
+
254
+ """
255
+ self._fibers["layers"].pop(pos)
256
+
257
+ def dump(self, fp, **kwargs):
258
+ """Dumps fiber factory to a file.
259
+
260
+ Args:
261
+ fp: File pointer.
262
+ **kwargs: See json.dumps
263
+
264
+ """
265
+ fp.write(self.dumps(**kwargs))
266
+
267
+ def dumps(self, **kwargs):
268
+ """Dumps fiber factory to a string.
269
+
270
+ Args:
271
+ **kwargs: See json.dumps.
272
+
273
+ Returns:
274
+ JSON string.
275
+
276
+ """
277
+ self._fibers["tstamp"] = time.time()
278
+ return json.dumps(self._fibers, **kwargs)
279
+
280
+ def load(self, fp, **kwargs):
281
+ """Loads fiber factory from file.
282
+
283
+ File contents is validated when loaded, and version is
284
+ upgraded is needed.
285
+
286
+ Args:
287
+ fp: File pointer.
288
+ **kwargs: See json.loads
289
+
290
+ """
291
+ self.loads(fp.read(), **kwargs)
292
+
293
+ def loads(self, s, **kwargs):
294
+ """Loads fiber factory from JSON string.
295
+
296
+ String contents is validated when loaded, and version is
297
+ upgraded is needed.
298
+
299
+ Args:
300
+ s(string): JSON string
301
+ **kwargs: See json.loads
302
+
303
+ """
304
+ fibers = json.loads(s, **kwargs)
305
+ self.validate(fibers)
306
+ self._fibers = fibers
307
+
308
+ def validate(self, obj):
309
+ """Validates that obj is a valid fiber factory.
310
+
311
+ Args:
312
+ obj(dict): Dict of fiber factory parameters.
313
+
314
+ Raises:
315
+ FiberFactoryValidationError: Object does not validate.
316
+
317
+ """
318
+ for key in ("version", "name", "description",
319
+ "author", "crdate", "tstamp", "layers"):
320
+ if key not in obj.keys():
321
+ raise FiberFactoryValidationError(
322
+ "Missing '{}' parameter".format(key))
323
+
324
+ if Version(obj["version"]) > Version(__version__):
325
+ raise FiberFactoryValidationError("Version of loaded object "
326
+ "is higher that version "
327
+ "of current library")
328
+ elif Version(obj["version"]) < Version(__version__):
329
+ self._upgrade(obj)
330
+
331
+ for layernum, layer in enumerate(obj["layers"], 1):
332
+ self._validateLayer(layer, layernum)
333
+
334
+ def _validateLayer(self, layer, layernum):
335
+ for key in ("name", "type", "tparams", "material", "mparams"):
336
+ if key not in layer.keys():
337
+ raise FiberFactoryValidationError(
338
+ "Missing '{}' parameter for layer {}".format(key,
339
+ layernum))
340
+
341
+ def _upgrade(self, obj):
342
+ obj["version"] = __version__
343
+
344
+ def __iter__(self):
345
+ self._buildFiberList()
346
+ g = product(*(range(i) for i in self._nitems))
347
+ return (self._buildFiber(i) for i in g)
348
+
349
+ def __len__(self):
350
+ if not self.layers:
351
+ return 0
352
+ self._buildFiberList()
353
+ return reduce(mul, self._nitems)
354
+
355
+ def __getitem__(self, key):
356
+ self._buildFiberList()
357
+ return self._buildFiber(self._getIndexes(key))
358
+
359
+ def _buildFiberList(self):
360
+ self._nitems = []
361
+ for layer in self._fibers["layers"]:
362
+ for key in ("tparams", "mparams"):
363
+ for tp in layer[key]:
364
+ self._nitems.append(len(SLRC(tp)))
365
+
366
+ def _getIndexes(self, index):
367
+ """Get list of indexes from a single index."""
368
+ g = product(*(range(i) for i in self._nitems))
369
+ return next(islice(g, index, None))
370
+
371
+ def setSolvers(self, Cutoff=None, Neff=None):
372
+ assert Cutoff is None or issubclass(Cutoff, FiberSolver)
373
+ assert Neff is None or issubclass(Neff, FiberSolver)
374
+ self._Cutoff = Cutoff
375
+ self._Neff = Neff
376
+
377
+ def _buildFiber(self, indexes):
378
+ """Build Fiber object from list of indexes"""
379
+
380
+ r = []
381
+ f = []
382
+ fp = []
383
+ m = []
384
+ mp = []
385
+ names = []
386
+
387
+ # Get parameters for selected fiber
388
+ ii = 0
389
+ for i, layer in enumerate(self._fibers["layers"], 1):
390
+ name = layer["name"] if layer["name"] else "layer {}".format(i+1)
391
+ names.append(name)
392
+
393
+ if i < len(self._fibers["layers"]):
394
+ rr = SLRC(layer["tparams"][0])
395
+ rr.codeParams = ["r", "fp", "mp"]
396
+ r.append(rr[indexes[ii]])
397
+ ii += 1 # we count radius of cladding, even if we don't use it
398
+
399
+ f.append(layer["type"])
400
+ fp_ = []
401
+ for p in layer["tparams"][1:]:
402
+ ff = SLRC(p)
403
+ ff.codeParams = ["r", "fp", "mp"]
404
+ fp_.append(ff[indexes[ii]])
405
+ ii += 1
406
+ fp.append(fp_)
407
+
408
+ m.append(layer["material"])
409
+ mp_ = []
410
+ for p in layer["mparams"]:
411
+ mm = SLRC(p)
412
+ mm.codeParams = ["r", "fp", "mp"]
413
+ mp_.append(mm[indexes[ii]])
414
+ ii += 1
415
+ mp.append(mp_)
416
+
417
+ # Execute code parts
418
+ for i, p in enumerate(r):
419
+ if callable(p):
420
+ r[i] = float(p(r, fp, mp))
421
+ for i, pp in enumerate(fp):
422
+ for j, p in enumerate(pp):
423
+ if callable(p):
424
+ fp[i][j] = float(p(r, fp, mp))
425
+ fp[i] = tuple(fp[i])
426
+ for i, pp in enumerate(mp):
427
+ for j, p in enumerate(pp):
428
+ if callable(p):
429
+ mp[i][j] = float(p(r, fp, mp))
430
+ mp[i] = tuple(mp[i])
431
+
432
+ # Remove unneeded layers
433
+ i = len(m)-2
434
+ while i >= 0 and len(m) > 1:
435
+ if (r[i] == 0 or
436
+ (i > 0 and r[i] <= r[i-1]) or
437
+ (f[i] == f[i+1] == 'StepIndex' and
438
+ m[i] == m[i+1] and
439
+ mp[i] == mp[i+1])):
440
+ del r[i]
441
+ del f[i]
442
+ del fp[i]
443
+ del m[i]
444
+ del mp[i]
445
+ del names[i]
446
+ i -= 1
447
+
448
+ return Fiber(r, f, fp, m, mp, names, self._Cutoff, self._Neff)