Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added example notebooks for FDTD, one how to use on its own, and one … #78

Merged
merged 11 commits into from
Apr 22, 2022
Merged
18 changes: 15 additions & 3 deletions nidn/fdtd/sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def __init__(
pulse: bool = False,
cycle: int = 5,
hanning_dt: float = 10.0,
signal_type: str = "continuous",
):
"""Create a LineSource with a gaussian profile

Expand All @@ -59,6 +60,8 @@ def __init__(
self.cycle = cycle
self.frequency = 1.0 / period
self.hanning_dt = hanning_dt if hanning_dt is not None else 0.5 / self.frequency
self.wavelength = SPEED_OF_LIGHT / self.frequency
self.signal_type = signal_type

def _register_grid(self, grid: Grid, x: Number, y: Number, z: Number):
"""Register a grid for the source.
Expand Down Expand Up @@ -90,12 +93,13 @@ def _register_grid(self, grid: Grid, x: Number, y: Number, z: Number):
raise ValueError("a point source should be placed on a single grid cell.")
self.x, self.y, self.z = grid._handle_tuple((x, y, z))
self.period = grid._handle_time(self.period)
self.courant = self.grid.courant_number
self.grid_points_per_wavelength = self.wavelength / self.grid.grid_spacing

def update_E(self):
"""Add the source to the electric field"""
q = self.grid.time_steps_passed
# if pulse
if self.pulse:
if self.signal_type == "hanning":
t1 = int(2 * pi / (self.frequency * self.hanning_dt / self.cycle))
if q < t1:
src = self.amplitude * hanning(
Expand All @@ -104,7 +108,15 @@ def update_E(self):
else:
# src = - self.grid.E[self.x, self.y, self.z, 2]
src = 0
# if not pulse
elif self.signal_type == "ricker":
# By experimental value, the ricker wavelet signal converges to zero after 6 times the grid points per wavelength, so just set the source-signal to zero after this
t1 = self.grid_points_per_wavelength * 6
if q < t1:
vsrcect = self.amplitude * _ricker(
q, self.grid_points_per_wavelength, 1, self.courant
)
else:
src = self.amplitude * 0
else:
src = self.amplitude * sin(2 * pi * q / self.period + self.phase_shift)
self.grid.E[self.x, self.y, self.z, 2] += src
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,6 @@ def _check_for_all_zero_signal(signals):
raise ValueError(
"The free-space signal is all zero. Increase the number of FDTD_niter to ensure that the signal reaches the detector."
)
if _mean_square(signals[1]) <= 1e-15:
gomezzz marked this conversation as resolved.
Show resolved Hide resolved
logger.warning(
"WARNING:The signal through the material layer(s) never reaches the detector. Increase FDTD_niter to ensure that the signal reaches the detector. The signal usually travels slower in a material than in free space."
)


# From : https://stackoverflow.com/questions/54498775/pytorch-argrelmax-function-or-c
def _torch_find_peaks(signal):
Expand Down
2 changes: 2 additions & 0 deletions nidn/fdtd_integration/init_fdtd.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ def init_fdtd(cfg: DotMap, include_object, wavelength, permittivity):
fdtd:Grid: Grid with all the added object, ready to be run
"""
set_backend("torch")
if (len(cfg.PER_LAYER_THICKNESS) == 1) and (cfg.N_layers > 1):
cfg.PER_LAYER_THICKNESS = [cfg.PER_LAYER_THICKNESS] * cfg.N_layers
# The scaling is the number of grid points per unit magnitude. This is the maximum of the reation between the unit magnitude and 1/10th of the smallest wavelength,
# and a constant which is defaulted to 10. If this scaling becomes too low, i.e. below 2, there might be some errors in creating the grid,
# as there is too feew grid points for ceartian elements to be placed correctly.
Expand Down
5 changes: 0 additions & 5 deletions nidn/training/utils/validate_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,11 +224,6 @@ def _validate_config(cfg: DotMap):
):
raise ValueError(f"PER_LAYER_THICKNESS must have length 1 or N_layers")

if cfg.solver == "FDTD" and (not len(cfg.PER_LAYER_THICKNESS) == cfg.N_layers):
raise ValueError(
f"PER_LAYER_THICKNESS must have length N_layers when using FDTD"
)

if not (cfg.freq_distribution == "linear" or cfg.freq_distribution == "log"):
raise ValueError(f"freq_distribution must be either 'linear' or 'log'")

Expand Down
Loading