working direct dispersion
This commit is contained in:
44
README.md
44
README.md
@@ -4,24 +4,40 @@ It is recommended to import scgenerator in the following manner :
|
|||||||
# How to run a set of simulations
|
# How to run a set of simulations
|
||||||
create a config file
|
create a config file
|
||||||
|
|
||||||
run `sc.parallel_simulations(config_file)` or `sc.simulate(config_file)`
|
run `sc.run_simulation(config_file)`
|
||||||
|
|
||||||
# How to analyse a simulation
|
# How to analyse a simulation
|
||||||
|
|
||||||
load data with the load_sim_data method
|
Load completed simulations with the SimulationSeries class. The path argument should be that of the last fiber in the series (of the form `xx fiber A...` where `xx` is an integer)
|
||||||
spectra, params = load_sim_data("varyTechNoise100kW_sim_data")
|
|
||||||
to plot
|
The SimulationSeries class has basic plotting functions available. See the class documentation for more info
|
||||||
plot_results_2D(spectra[0], (600, 1450, nm), params)
|
|
||||||
|
```
|
||||||
|
series = sc.SimulationSeries(path_to_data_folder)
|
||||||
|
fig, ax = plt.subplots()
|
||||||
|
series.plot_2D(800, 1600, "nm", ax)
|
||||||
|
plt.show()
|
||||||
|
```
|
||||||
|
|
||||||
# Environment variables
|
# Environment variables
|
||||||
|
|
||||||
SCGENERATOR_PBAR_POLICY : "none", "file", "print", "both", optional
|
`SCGENERATOR_PBAR_POLICY` : "none", "file", "print", "both", optional
|
||||||
whether progress should be printed to a file ("file"), to the standard output ("print") or both, default : print
|
whether progress should be printed to a file ("file"), to the standard output ("print") or both, default : print
|
||||||
|
|
||||||
|
`SCGENERATOR_LOG_FILE_LEVEL` : "debug", "info", "warning", "error", "critical", optional
|
||||||
|
level of logging printed in $PWD/scgenerator.log
|
||||||
|
|
||||||
|
`SCGENERATOR_LOG_PRINT_LEVEL` : "debug", "info", "warning", "error", "critical", optional
|
||||||
|
level of logging printed in the cli.
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
|
|
||||||
You can load parameters by simply passing the path to a toml file to the appropriate simulation function. Each possible key of this dictionary is described below. Every value must be given in standard SI units (m, s, W, J, ...)
|
You can load parameters by simply passing the path to a toml file to the appropriate simulation function. Each possible key of this dictionary is described below. Every value must be given in standard SI units (m, s, W, J, ...)
|
||||||
the root of the file has information concerning the whole simulation : name, grid information, input pulse, ...
|
the root of the file has information concerning the whole simulation : name, grid information, input pulse, ...
|
||||||
|
Then, there must be a `[[Fiber]]` array with at least one fiber with fiber-specific parameters.
|
||||||
|
|
||||||
|
Parameters can be variable (either in the root or in one fiber). if at most one single `[variable]` dict is specified by section, all the possible combinations of those variable parameters are considered. Another possibility is to specify a `[[variable]]` array where the length of each set of parameter is the same so they're coupled to each other.
|
||||||
|
|
||||||
Examples :
|
Examples :
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -38,11 +54,14 @@ n2 = 2.2e-20
|
|||||||
[variable]
|
[variable]
|
||||||
n2 = [2.1e-20, 2.4e-20, 2.6e-20]
|
n2 = [2.1e-20, 2.4e-20, 2.6e-20]
|
||||||
```
|
```
|
||||||
NOT ALLOWED
|
NOT ALLOWED. You cannot specified the same parameter twice.
|
||||||
|
|
||||||
Here is an example of a configuration file
|
Here is an example of a configuration file
|
||||||
|
|
||||||
```
|
```
|
||||||
|
# these be applied to the whole simulation fiber PM1550_1 only
|
||||||
|
# fiber parameters specified here would apply to the whole simulation as well
|
||||||
|
# unless overridden in one of the individual fiber
|
||||||
name = "Test/Compound 1"
|
name = "Test/Compound 1"
|
||||||
|
|
||||||
field_file = "Toptica/init_field.npz"
|
field_file = "Toptica/init_field.npz"
|
||||||
@@ -57,11 +76,9 @@ z_num = 32
|
|||||||
mean_power = 200e-3
|
mean_power = 200e-3
|
||||||
repeat = 3
|
repeat = 3
|
||||||
|
|
||||||
# will be applied to the whole simulation fiber PM1550_1 only
|
|
||||||
# fiber parameters specified here would apply to the whole simulation as well
|
[[variable]]
|
||||||
# unless overridden in one of the individual fiber
|
spm = [true, false]
|
||||||
[variable]
|
|
||||||
behaviors = [["spm", "ss", "raman"], ["spm", "ss"]]
|
|
||||||
raman_type = ["agrawal", "stolen"]
|
raman_type = ["agrawal", "stolen"]
|
||||||
|
|
||||||
[[Fiber]]
|
[[Fiber]]
|
||||||
@@ -82,8 +99,7 @@ dispersion_file = "PM2000D/Dispersion/PM2000D_1 extrapolated 0 4.npz"
|
|||||||
input_transmission = [0.9, 0.95]
|
input_transmission = [0.9, 0.95]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
this means that only `(spm=true, raman_type="agrawal")` and `(spm=false, raman_type="stolen")` are considered and not `(spm=false, raman_type="agrawal")` for example. In the end, 12 simulations are ran with this configuration.
|
||||||
note : internally, another structure with a flattened dictionary is used
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
37
make_new_dispersion.py
Normal file
37
make_new_dispersion.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import numpy as np
|
||||||
|
import scgenerator as sc
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
params = sc.Configuration(
|
||||||
|
"/Users/benoitsierro/tests/test_sc/Travers2019 Fig2 dev/initial_config.toml"
|
||||||
|
).first
|
||||||
|
evalu = sc.Evaluator.default()
|
||||||
|
evalu.set(**params.prepare_for_dump())
|
||||||
|
n_eff = evalu.compute("n_eff")
|
||||||
|
wl = evalu.compute("wl_for_disp")
|
||||||
|
w = evalu.compute("w_for_disp")
|
||||||
|
print(w.max(), w.min())
|
||||||
|
disp_inf = evalu.compute("dispersion_ind")
|
||||||
|
# quit()
|
||||||
|
|
||||||
|
params.interpolation_degree = 6
|
||||||
|
params.compute()
|
||||||
|
current_disp = params.linear_operator.dispersion_op
|
||||||
|
beta = n_eff * w / 3e8
|
||||||
|
beta1 = np.gradient(beta, w)
|
||||||
|
ind = sc.argclosest(w, params.w0)
|
||||||
|
disp = -1j * (beta - beta1[ind] * (w - params.w0) - beta[ind])
|
||||||
|
disp2 = sc.fiber.fast_direct_dispersion(w, params.w0, n_eff, ind)
|
||||||
|
|
||||||
|
plt.plot(params.l * 1e9, current_disp(None).imag)
|
||||||
|
plt.plot(wl * 1e9, disp.imag)
|
||||||
|
plt.plot(wl * 1e9, disp2.imag)
|
||||||
|
plt.xlim(100, 3000)
|
||||||
|
plt.ylim(-1000, 4000)
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -19,3 +19,4 @@ from .plotting import (
|
|||||||
from .spectra import SimulationSeries, Spectrum
|
from .spectra import SimulationSeries, Spectrum
|
||||||
from .utils import Paths, _open_config, open_single_config
|
from .utils import Paths, _open_config, open_single_config
|
||||||
from .variationer import DescriptorDict, VariationDescriptor, Variationer, VariationSpecsError
|
from .variationer import DescriptorDict, VariationDescriptor, Variationer, VariationSpecsError
|
||||||
|
from .evaluator import Evaluator
|
||||||
|
|||||||
@@ -131,9 +131,24 @@ class Evaluator:
|
|||||||
self.rules[t].append(r)
|
self.rules[t].append(r)
|
||||||
self.rules[t].sort(key=lambda el: el.targets[t], reverse=True)
|
self.rules[t].sort(key=lambda el: el.targets[t], reverse=True)
|
||||||
|
|
||||||
def set(self, **params: Any):
|
def set(self, dico: dict[str, Any] = None, **params: Any):
|
||||||
self.params.update(params)
|
"""sets the internal set of parameters
|
||||||
for k in params:
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
dico : dict, optional
|
||||||
|
if given, replace current dict of parameters with this one
|
||||||
|
(not a copy of it), by default None
|
||||||
|
params : Any
|
||||||
|
if dico is None, update the internal dict of parameters with params
|
||||||
|
"""
|
||||||
|
if dico is None:
|
||||||
|
dico = params
|
||||||
|
self.params.update(dico)
|
||||||
|
else:
|
||||||
|
self.reset()
|
||||||
|
self.params = dico
|
||||||
|
for k in dico:
|
||||||
self.eval_stats[k].priority = np.inf
|
self.eval_stats[k].priority = np.inf
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
@@ -175,7 +190,9 @@ class Evaluator:
|
|||||||
self.__curent_lookup.append(target)
|
self.__curent_lookup.append(target)
|
||||||
|
|
||||||
if len(self.rules[target]) == 0:
|
if len(self.rules[target]) == 0:
|
||||||
error = EvaluatorError(f"no rule for {target}")
|
error = EvaluatorError(
|
||||||
|
f"no rule for {target}, trying to evaluate {self.__curent_lookup!r}"
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
error = None
|
error = None
|
||||||
|
|
||||||
@@ -312,13 +329,9 @@ default_rules: list[Rule] = [
|
|||||||
Rule("L_NL", pulse.L_NL),
|
Rule("L_NL", pulse.L_NL),
|
||||||
Rule("L_sol", pulse.L_sol),
|
Rule("L_sol", pulse.L_sol),
|
||||||
# Fiber Dispersion
|
# Fiber Dispersion
|
||||||
Rule("wl_for_disp", fiber.lambda_for_dispersion),
|
Rule(["wl_for_disp", "dispersion_ind"], fiber.lambda_for_dispersion),
|
||||||
Rule("w_for_disp", units.m, ["wl_for_disp"]),
|
Rule("w_for_disp", units.m, ["wl_for_disp"]),
|
||||||
Rule(
|
Rule("beta2_coefficients", fiber.dispersion_coefficients),
|
||||||
"beta2_coefficients",
|
|
||||||
fiber.dispersion_coefficients,
|
|
||||||
["wl_for_disp", "beta2_arr", "w0", "interpolation_range", "interpolation_degree"],
|
|
||||||
),
|
|
||||||
Rule("beta2_arr", fiber.beta2),
|
Rule("beta2_arr", fiber.beta2),
|
||||||
Rule("beta2_arr", fiber.dispersion_from_coefficients),
|
Rule("beta2_arr", fiber.dispersion_from_coefficients),
|
||||||
Rule("beta2", lambda beta2_coefficients: beta2_coefficients[0]),
|
Rule("beta2", lambda beta2_coefficients: beta2_coefficients[0]),
|
||||||
|
|||||||
@@ -75,8 +75,8 @@ class Operator(ABC):
|
|||||||
|
|
||||||
|
|
||||||
class NoOp:
|
class NoOp:
|
||||||
def __init__(self, w: np.ndarray):
|
def __init__(self, t_num: int):
|
||||||
self.arr_const = np.zeros_like(w)
|
self.arr_const = np.zeros(t_num)
|
||||||
|
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
@@ -112,23 +112,45 @@ class ConstantPolyDispersion(AbstractDispersion):
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
wl_for_disp: np.ndarray,
|
w_for_disp: np.ndarray,
|
||||||
beta2_arr: np.ndarray,
|
beta2_arr: np.ndarray,
|
||||||
w0: float,
|
w0: float,
|
||||||
w_c: np.ndarray,
|
w_c: np.ndarray,
|
||||||
interpolation_range: tuple[float, float],
|
|
||||||
interpolation_degree: int,
|
interpolation_degree: int,
|
||||||
):
|
):
|
||||||
self.coefs = fiber.dispersion_coefficients(
|
self.coefs = fiber.dispersion_coefficients(w_for_disp, beta2_arr, w0, interpolation_degree)
|
||||||
wl_for_disp, beta2_arr, w0, interpolation_range, interpolation_degree
|
|
||||||
)
|
|
||||||
self.w_c = w_c
|
self.w_c = w_c
|
||||||
self.w_power_fact = np.array(
|
self.w_power_fact = np.array(
|
||||||
[math.power_fact(w_c, k) for k in range(2, interpolation_degree + 3)]
|
[math.power_fact(w_c, k) for k in range(2, interpolation_degree + 3)]
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, state: CurrentState) -> np.ndarray:
|
def __call__(self, state: CurrentState = None) -> np.ndarray:
|
||||||
return fiber.fast_dispersion_op(self.w_c, self.coefs, self.w_power_fact)
|
return fiber.fast_poly_dispersion_op(self.w_c, self.coefs, self.w_power_fact)
|
||||||
|
|
||||||
|
|
||||||
|
class ConstantDirectDispersion(AbstractDispersion):
|
||||||
|
"""
|
||||||
|
Direct dispersion for when the refractive index is known
|
||||||
|
"""
|
||||||
|
|
||||||
|
disp_arr_const: np.ndarray
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
w_for_disp: np.ndarray,
|
||||||
|
w0: np.ndarray,
|
||||||
|
t_num: int,
|
||||||
|
n_eff: np.ndarray,
|
||||||
|
dispersion_ind: np.ndarray,
|
||||||
|
):
|
||||||
|
self.disp_arr_const = np.zeros(t_num)
|
||||||
|
w0_ind = math.argclosest(w_for_disp, w0)
|
||||||
|
self.disp_arr_const[dispersion_ind] = fiber.fast_direct_dispersion(
|
||||||
|
w_for_disp, w0, n_eff, w0_ind
|
||||||
|
)[2:-2]
|
||||||
|
|
||||||
|
def __call__(self, state: CurrentState = None):
|
||||||
|
return self.disp_arr_const
|
||||||
|
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
@@ -286,8 +308,8 @@ class AbstractGamma(Operator):
|
|||||||
|
|
||||||
|
|
||||||
class ConstantScalarGamma(AbstractGamma):
|
class ConstantScalarGamma(AbstractGamma):
|
||||||
def __init__(self, gamma: np.ndarray, w: np.ndarray):
|
def __init__(self, gamma: np.ndarray, t_num: int):
|
||||||
self.arr_const = gamma * np.ones_like(w)
|
self.arr_const = gamma * np.ones(t_num)
|
||||||
|
|
||||||
def __call__(self, state: CurrentState) -> np.ndarray:
|
def __call__(self, state: CurrentState) -> np.ndarray:
|
||||||
return self.arr_const
|
return self.arr_const
|
||||||
@@ -373,8 +395,8 @@ class AbstractLoss(Operator):
|
|||||||
class ConstantLoss(AbstractLoss):
|
class ConstantLoss(AbstractLoss):
|
||||||
arr_const: np.ndarray
|
arr_const: np.ndarray
|
||||||
|
|
||||||
def __init__(self, alpha: float, w: np.ndarray):
|
def __init__(self, alpha: float, t_num: int):
|
||||||
self.arr_const = alpha * np.ones_like(w)
|
self.arr_const = alpha * np.ones(t_num)
|
||||||
|
|
||||||
def __call__(self, state: CurrentState = None) -> np.ndarray:
|
def __call__(self, state: CurrentState = None) -> np.ndarray:
|
||||||
return self.arr_const
|
return self.arr_const
|
||||||
@@ -388,15 +410,15 @@ class NoLoss(ConstantLoss):
|
|||||||
class CapillaryLoss(ConstantLoss):
|
class CapillaryLoss(ConstantLoss):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
l: np.ndarray,
|
wl_for_disp: np.ndarray,
|
||||||
|
dispersion_ind: np.ndarray,
|
||||||
|
t_num: int,
|
||||||
core_radius: float,
|
core_radius: float,
|
||||||
interpolation_range: tuple[float, float],
|
|
||||||
he_mode: tuple[int, int],
|
he_mode: tuple[int, int],
|
||||||
):
|
):
|
||||||
mask = (l < interpolation_range[1]) & (l > interpolation_range[0])
|
alpha = fiber.capillary_loss(wl_for_disp, he_mode, core_radius)
|
||||||
alpha = fiber.capillary_loss(l[mask], he_mode, core_radius)
|
self.arr = np.zeros(t_num)
|
||||||
self.arr = np.zeros_like(l)
|
self.arr[dispersion_ind] = alpha[2:-2]
|
||||||
self.arr[mask] = alpha
|
|
||||||
|
|
||||||
def __call__(self, state: CurrentState) -> np.ndarray:
|
def __call__(self, state: CurrentState) -> np.ndarray:
|
||||||
return self.arr
|
return self.arr
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ from numpy import e
|
|||||||
from numpy.fft import fft
|
from numpy.fft import fft
|
||||||
from numpy.polynomial.chebyshev import Chebyshev, cheb2poly
|
from numpy.polynomial.chebyshev import Chebyshev, cheb2poly
|
||||||
from scipy.interpolate import interp1d
|
from scipy.interpolate import interp1d
|
||||||
|
from sympy import re
|
||||||
|
|
||||||
from .. import utils
|
from .. import utils
|
||||||
from ..cache import np_cache
|
from ..cache import np_cache
|
||||||
from ..logger import get_logger
|
from ..math import argclosest, u_nm
|
||||||
from ..math import argclosest, power_fact, u_nm
|
|
||||||
from . import materials as mat
|
from . import materials as mat
|
||||||
from . import units
|
from . import units
|
||||||
from .units import c, pi
|
from .units import c, pi
|
||||||
@@ -18,14 +18,28 @@ pipi = 2 * pi
|
|||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
|
||||||
|
|
||||||
def lambda_for_dispersion(interpolation_range: tuple[float, float]) -> np.ndarray:
|
def lambda_for_dispersion(
|
||||||
|
l: np.ndarray, interpolation_range: tuple[float, float]
|
||||||
|
) -> tuple[np.ndarray, np.ndarray]:
|
||||||
"""Returns a wl vector for dispersion calculation
|
"""Returns a wl vector for dispersion calculation
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
array of wl values
|
np.ndarray
|
||||||
|
subset of l in the interpolation range with two extra values on each side
|
||||||
|
to accomodate for taking gradients
|
||||||
|
np.ndarray
|
||||||
|
indices of the original l where the values are valid (i.e. without the two extra on each side)
|
||||||
"""
|
"""
|
||||||
return np.arange(interpolation_range[0] - 2e-9, interpolation_range[1] + 3e-9, 1e-9)
|
su = np.where((l >= interpolation_range[0]) & (l <= interpolation_range[1]))[0]
|
||||||
|
ind_above_cond = su >= len(l) // 2
|
||||||
|
ind_above = su[ind_above_cond]
|
||||||
|
ind_below = su[~ind_above_cond]
|
||||||
|
fu = np.concatenate((ind_below, (ind_below + 2)[-2:], (ind_above - 2)[:2], ind_above))
|
||||||
|
fs = fu[np.argsort(l[fu])[::-1]]
|
||||||
|
l_out = l[fs]
|
||||||
|
ind_out = fs[2:-2]
|
||||||
|
return l_out, ind_out
|
||||||
|
|
||||||
|
|
||||||
def is_dynamic_dispersion(pressure=None):
|
def is_dynamic_dispersion(pressure=None):
|
||||||
@@ -107,9 +121,8 @@ def plasma_dispersion(wl_for_disp, number_density, simple=False):
|
|||||||
w_pl = number_density * e2_me_e0
|
w_pl = number_density * e2_me_e0
|
||||||
return -(w_pl ** 2) / (c * w ** 2)
|
return -(w_pl ** 2) / (c * w ** 2)
|
||||||
|
|
||||||
beta = w / c * np.sqrt(1 - number_density * e2_me_e0 / w ** 2)
|
beta2_arr = beta2(w, np.sqrt(1 - number_density * e2_me_e0 / w ** 2))
|
||||||
beta2 = np.gradient(np.gradient(beta, w), w)
|
return beta2_arr
|
||||||
return beta2
|
|
||||||
|
|
||||||
|
|
||||||
def n_eff_marcatili(wl_for_disp, n_gas_2, core_radius, he_mode=(1, 1)):
|
def n_eff_marcatili(wl_for_disp, n_gas_2, core_radius, he_mode=(1, 1)):
|
||||||
@@ -561,6 +574,14 @@ def HCPF_ZDW(
|
|||||||
return l[zdw_ind]
|
return l[zdw_ind]
|
||||||
|
|
||||||
|
|
||||||
|
def beta(w_for_disp: np.ndarray, n_eff: np.ndarray) -> np.ndarray:
|
||||||
|
return n_eff * w_for_disp / c
|
||||||
|
|
||||||
|
|
||||||
|
def beta1(w_for_disp: np.ndarray, n_eff: np.ndarray) -> np.ndarray:
|
||||||
|
return np.gradient(beta(w_for_disp, n_eff), w_for_disp)
|
||||||
|
|
||||||
|
|
||||||
def beta2(w_for_disp: np.ndarray, n_eff: np.ndarray) -> np.ndarray:
|
def beta2(w_for_disp: np.ndarray, n_eff: np.ndarray) -> np.ndarray:
|
||||||
"""computes the dispersion parameter beta2 according to the effective refractive index of the fiber and the frequency range
|
"""computes the dispersion parameter beta2 according to the effective refractive index of the fiber and the frequency range
|
||||||
|
|
||||||
@@ -575,7 +596,7 @@ def beta2(w_for_disp: np.ndarray, n_eff: np.ndarray) -> np.ndarray:
|
|||||||
-------
|
-------
|
||||||
beta2 : ndarray, shape (n, )
|
beta2 : ndarray, shape (n, )
|
||||||
"""
|
"""
|
||||||
return np.gradient(np.gradient(n_eff * w_for_disp / c, w_for_disp), w_for_disp)
|
return np.gradient(np.gradient(beta(w_for_disp, n_eff), w_for_disp), w_for_disp)
|
||||||
|
|
||||||
|
|
||||||
def HCPCF_dispersion(
|
def HCPCF_dispersion(
|
||||||
@@ -849,11 +870,10 @@ def load_custom_loss(l: np.ndarray, loss_file: str) -> np.ndarray:
|
|||||||
|
|
||||||
@np_cache
|
@np_cache
|
||||||
def dispersion_coefficients(
|
def dispersion_coefficients(
|
||||||
wl_for_disp: np.ndarray,
|
w_for_disp: np.ndarray,
|
||||||
beta2_arr: np.ndarray,
|
beta2_arr: np.ndarray,
|
||||||
w0: float,
|
w0: float,
|
||||||
interpolation_range=None,
|
interpolation_degree: int,
|
||||||
interpolation_degree=8,
|
|
||||||
):
|
):
|
||||||
"""Computes the taylor expansion of beta2 to be used in dispersion_op
|
"""Computes the taylor expansion of beta2 to be used in dispersion_op
|
||||||
|
|
||||||
@@ -865,8 +885,6 @@ def dispersion_coefficients(
|
|||||||
beta2 as function of wl_for_disp
|
beta2 as function of wl_for_disp
|
||||||
w0 : float
|
w0 : float
|
||||||
pump angular frequency
|
pump angular frequency
|
||||||
interpolation_range : slice-like
|
|
||||||
index-style specifying wl range over which to fit to get beta2 coefficients
|
|
||||||
interpolation_degree : int
|
interpolation_degree : int
|
||||||
degree of polynomial fit. Will return deg+1 coefficients
|
degree of polynomial fit. Will return deg+1 coefficients
|
||||||
|
|
||||||
@@ -875,29 +893,13 @@ def dispersion_coefficients(
|
|||||||
beta2_coef : 1D array
|
beta2_coef : 1D array
|
||||||
Taylor coefficients in decreasing order
|
Taylor coefficients in decreasing order
|
||||||
"""
|
"""
|
||||||
logger = get_logger()
|
|
||||||
if interpolation_range is None:
|
|
||||||
r = slice(2, -2)
|
|
||||||
else:
|
|
||||||
# 2 discrete gradients are computed before getting to
|
|
||||||
# beta2, so we need to make sure coefficients are not affected
|
|
||||||
# by edge effects
|
|
||||||
r = (wl_for_disp >= interpolation_range[0]) & (wl_for_disp <= interpolation_range[1])
|
|
||||||
logger.debug(
|
|
||||||
f"interpolating dispersion between {wl_for_disp[r].min()*1e9:.1f}nm and {wl_for_disp[r].max()*1e9:.1f}nm"
|
|
||||||
)
|
|
||||||
|
|
||||||
# we get the beta2 Taylor coeffiecients by making a fit around w0
|
# we get the beta2 Taylor coeffiecients by making a fit around w0
|
||||||
w_c = units.m(wl_for_disp) - w0
|
w_c = w_for_disp - w0
|
||||||
interp = interp1d(w_c[r], beta2_arr[r])
|
|
||||||
w_c = np.linspace(w_c[r].min(), w_c[r].max(), len(w_c[r]))
|
|
||||||
|
|
||||||
# import matplotlib.pyplot as plt
|
w_c = w_c[2:-2]
|
||||||
|
beta2_arr = beta2_arr[2:-2]
|
||||||
# ax = plt.gca()
|
fit = Chebyshev.fit(w_c, beta2_arr, interpolation_degree)
|
||||||
# ax.plot(w_c, interp(w_c) * 1e28)
|
|
||||||
|
|
||||||
fit = Chebyshev.fit(w_c, interp(w_c), interpolation_degree)
|
|
||||||
poly_coef = cheb2poly(fit.convert().coef)
|
poly_coef = cheb2poly(fit.convert().coef)
|
||||||
beta2_coef = poly_coef * np.cumprod([1] + list(range(1, interpolation_degree + 1)))
|
beta2_coef = poly_coef * np.cumprod([1] + list(range(1, interpolation_degree + 1)))
|
||||||
|
|
||||||
@@ -981,7 +983,7 @@ def delayed_raman_w(t: np.ndarray, raman_type: str) -> np.ndarray:
|
|||||||
return fft(delayed_raman_t(t, raman_type)) * (t[1] - t[0])
|
return fft(delayed_raman_t(t, raman_type)) * (t[1] - t[0])
|
||||||
|
|
||||||
|
|
||||||
def fast_dispersion_op(w_c, beta_arr, power_fact_arr, where=slice(None)):
|
def fast_poly_dispersion_op(w_c, beta_arr, power_fact_arr, where=slice(None)):
|
||||||
"""
|
"""
|
||||||
dispersive operator
|
dispersive operator
|
||||||
|
|
||||||
@@ -1015,39 +1017,32 @@ def _fast_disp_loop(dispersion: np.ndarray, beta_arr, power_fact_arr):
|
|||||||
return dispersion
|
return dispersion
|
||||||
|
|
||||||
|
|
||||||
def dispersion_op(w_c, beta2_coefficients, where=None):
|
def direct_dispersion(w: np.ndarray, w0: float, n_eff: np.ndarray) -> np.ndarray:
|
||||||
"""
|
"""returns the dispersive operator in direct form (without polynomial interpolation)
|
||||||
dispersive operator
|
i.e. -1j * (beta(w) - beta1 * (w - w0) - beta0)
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
w_c : 1d array
|
w : np.ndarray
|
||||||
angular frequencies centered around 0
|
angular frequency array
|
||||||
beta2_coefficients : 1d array
|
w0 : float
|
||||||
beta coefficients returned by scgenerator.physics.fiber.dispersion_coefficients
|
center frequency
|
||||||
where : indices over which to apply the operatory, otherwise 0
|
n_eff : np.ndarray
|
||||||
|
effectiv refractive index
|
||||||
|
|
||||||
Returns
|
Returns
|
||||||
-------
|
-------
|
||||||
disp_arr : dispersive component as an array of len = len(w_c)
|
np.ndarray
|
||||||
|
dispersive operator
|
||||||
"""
|
"""
|
||||||
|
w0_ind = argclosest(w, w0)
|
||||||
dispersion = np.zeros_like(w_c)
|
return fast_direct_dispersion(w, w0, n_eff, w0_ind)
|
||||||
|
|
||||||
for k, beta in reversed(list(enumerate(beta2_coefficients))):
|
|
||||||
dispersion = dispersion + beta * power_fact(w_c, k + 2)
|
|
||||||
|
|
||||||
out = np.zeros_like(dispersion)
|
|
||||||
out[where] = dispersion[where]
|
|
||||||
|
|
||||||
return -1j * out
|
|
||||||
|
|
||||||
|
|
||||||
def _get_radius(radius_param, wl_for_disp=None):
|
def fast_direct_dispersion(w: np.ndarray, w0: float, n_eff: np.ndarray, w0_ind: int) -> np.ndarray:
|
||||||
if isinstance(radius_param, tuple) and wl_for_disp is not None:
|
beta_arr = beta(w, n_eff)
|
||||||
return effective_core_radius(wl_for_disp, *radius_param)
|
beta1_arr = np.gradient(beta_arr, w)
|
||||||
else:
|
return -1j * (beta_arr - beta1_arr[w0_ind] * (w - w0) - beta_arr[w0_ind])
|
||||||
return radius_param
|
|
||||||
|
|
||||||
|
|
||||||
def effective_core_radius(wl_for_disp, core_radius, s=0.08, h=200e-9):
|
def effective_core_radius(wl_for_disp, core_radius, s=0.08, h=200e-9):
|
||||||
|
|||||||
9173
test_ind.txt
Normal file
9173
test_ind.txt
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user