2024-03-10 11:56:37 +01:00
|
|
|
import typing as typ
|
|
|
|
|
2024-02-19 18:36:16 +01:00
|
|
|
import tidy3d as td
|
2024-03-10 11:56:37 +01:00
|
|
|
import numpy as np
|
2024-02-19 18:36:16 +01:00
|
|
|
import sympy as sp
|
|
|
|
import sympy.physics.units as spu
|
|
|
|
|
2024-03-10 11:56:37 +01:00
|
|
|
import bpy
|
|
|
|
|
|
|
|
from ......utils import extra_sympy_units as spuex
|
|
|
|
from .... import contracts as ct
|
2024-02-19 18:36:16 +01:00
|
|
|
from .... import sockets
|
2024-03-10 11:56:37 +01:00
|
|
|
from .... import managed_objs
|
2024-02-19 18:36:16 +01:00
|
|
|
from ... import base
|
|
|
|
|
2024-03-10 11:56:37 +01:00
|
|
|
class GaussianPulseTemporalShapeNode(base.MaxwellSimNode):
|
|
|
|
node_type = ct.NodeType.GaussianPulseTemporalShape
|
2024-02-19 18:36:16 +01:00
|
|
|
|
|
|
|
bl_label = "Gaussian Pulse Temporal Shape"
|
|
|
|
#bl_icon = ...
|
|
|
|
|
|
|
|
####################
|
|
|
|
# - Sockets
|
|
|
|
####################
|
|
|
|
input_sockets = {
|
|
|
|
#"amplitude": sockets.RealNumberSocketDef(
|
|
|
|
# label="Temporal Shape",
|
|
|
|
#), ## Should have a unit of some kind...
|
2024-03-10 11:56:37 +01:00
|
|
|
"Freq Center": sockets.PhysicalFreqSocketDef(
|
|
|
|
default_value=500 * spuex.terahertz,
|
2024-02-19 18:36:16 +01:00
|
|
|
),
|
2024-03-10 11:56:37 +01:00
|
|
|
"Freq Std.": sockets.PhysicalFreqSocketDef(
|
|
|
|
default_value=200 * spuex.terahertz,
|
2024-02-19 18:36:16 +01:00
|
|
|
),
|
2024-03-10 11:56:37 +01:00
|
|
|
"Phase": sockets.PhysicalAngleSocketDef(),
|
|
|
|
"Delay rel. AngFreq": sockets.RealNumberSocketDef(
|
2024-02-26 16:16:06 +01:00
|
|
|
default_value=5.0,
|
2024-02-19 18:36:16 +01:00
|
|
|
),
|
2024-03-10 11:56:37 +01:00
|
|
|
"Remove DC": sockets.BoolSocketDef(
|
2024-02-19 18:36:16 +01:00
|
|
|
default_value=True,
|
|
|
|
),
|
|
|
|
}
|
|
|
|
output_sockets = {
|
2024-03-10 11:56:37 +01:00
|
|
|
"Temporal Shape": sockets.MaxwellTemporalShapeSocketDef(),
|
|
|
|
}
|
|
|
|
|
|
|
|
managed_obj_defs = {
|
|
|
|
"amp_time": ct.schemas.ManagedObjDef(
|
|
|
|
mk=lambda name: managed_objs.ManagedBLImage(name),
|
|
|
|
name_prefix="amp_time_",
|
|
|
|
)
|
2024-02-19 18:36:16 +01:00
|
|
|
}
|
|
|
|
|
2024-03-10 11:56:37 +01:00
|
|
|
####################
|
|
|
|
# - Properties
|
|
|
|
####################
|
|
|
|
plot_time_start: bpy.props.FloatProperty(
|
|
|
|
name="Plot Time Start (ps)",
|
|
|
|
description="The instance ID of a particular MaxwellSimNode instance, used to index caches",
|
|
|
|
default=0.0,
|
|
|
|
update=(lambda self, context: self.sync_prop("plot_time_start", context)),
|
|
|
|
)
|
|
|
|
plot_time_end: bpy.props.FloatProperty(
|
|
|
|
name="Plot Time End (ps)",
|
|
|
|
description="The instance ID of a particular MaxwellSimNode instance, used to index caches",
|
|
|
|
default=5,
|
|
|
|
update=(lambda self, context: self.sync_prop("plot_time_start", context)),
|
|
|
|
)
|
|
|
|
|
|
|
|
####################
|
|
|
|
# - UI
|
|
|
|
####################
|
|
|
|
def draw_props(self, context, layout):
|
|
|
|
layout.label(text="Plot Settings")
|
|
|
|
split = layout.split(factor=0.6)
|
|
|
|
|
|
|
|
col = split.column()
|
|
|
|
col.label(text="t-Range (ps)")
|
|
|
|
|
|
|
|
col = split.column()
|
|
|
|
col.prop(self, "plot_time_start", text="")
|
|
|
|
col.prop(self, "plot_time_end", text="")
|
|
|
|
|
2024-02-19 18:36:16 +01:00
|
|
|
####################
|
|
|
|
# - Output Socket Computation
|
|
|
|
####################
|
2024-03-10 11:56:37 +01:00
|
|
|
@base.computes_output_socket(
|
|
|
|
"Temporal Shape",
|
|
|
|
input_sockets={
|
|
|
|
"Freq Center", "Freq Std.", "Phase", "Delay rel. AngFreq",
|
|
|
|
"Remove DC",
|
|
|
|
}
|
|
|
|
)
|
|
|
|
def compute_source(self, input_sockets: dict) -> td.GaussianPulse:
|
|
|
|
if (
|
|
|
|
(_freq_center := input_sockets["Freq Center"]) is None
|
|
|
|
or (_freq_std := input_sockets["Freq Std."]) is None
|
|
|
|
or (_phase := input_sockets["Phase"]) is None
|
|
|
|
or (time_delay_rel_ang_freq := input_sockets["Delay rel. AngFreq"]) is None
|
|
|
|
or (remove_dc_component := input_sockets["Remove DC"]) is None
|
|
|
|
):
|
|
|
|
raise ValueError("Inputs not defined")
|
2024-02-19 18:36:16 +01:00
|
|
|
|
|
|
|
cheating_amplitude = 1.0
|
|
|
|
freq_center = spu.convert_to(_freq_center, spu.hertz) / spu.hertz
|
|
|
|
freq_std = spu.convert_to(_freq_std, spu.hertz) / spu.hertz
|
2024-03-10 11:56:37 +01:00
|
|
|
phase = spu.convert_to(_phase, spu.radian) / spu.radian
|
2024-02-19 18:36:16 +01:00
|
|
|
|
|
|
|
return td.GaussianPulse(
|
|
|
|
amplitude=cheating_amplitude,
|
|
|
|
phase=phase,
|
|
|
|
freq0=freq_center,
|
|
|
|
fwidth=freq_std,
|
|
|
|
offset=time_delay_rel_ang_freq,
|
|
|
|
remove_dc_component=remove_dc_component,
|
|
|
|
)
|
2024-03-10 11:56:37 +01:00
|
|
|
|
|
|
|
@base.on_show_plot(
|
|
|
|
managed_objs={"amp_time"},
|
|
|
|
props={"plot_time_start", "plot_time_end"},
|
|
|
|
output_sockets={"Temporal Shape"},
|
|
|
|
stop_propagation=True,
|
|
|
|
)
|
|
|
|
def on_show_plot(
|
|
|
|
self,
|
|
|
|
managed_objs: dict[str, ct.schemas.ManagedObj],
|
|
|
|
output_sockets: dict[str, typ.Any],
|
|
|
|
props: dict[str, typ.Any],
|
|
|
|
):
|
|
|
|
temporal_shape = output_sockets["Temporal Shape"]
|
|
|
|
plot_time_start = props["plot_time_start"] * 1e-15
|
|
|
|
plot_time_end = props["plot_time_end"] * 1e-15
|
|
|
|
|
|
|
|
times = np.linspace(plot_time_start, plot_time_end)
|
|
|
|
|
|
|
|
managed_objs["amp_time"].mpl_plot_to_image(
|
|
|
|
lambda ax: temporal_shape.plot_spectrum(times, ax=ax),
|
|
|
|
bl_select=True,
|
|
|
|
)
|
2024-02-19 18:36:16 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
2024-02-19 14:28:35 +01:00
|
|
|
####################
|
|
|
|
# - Blender Registration
|
|
|
|
####################
|
2024-02-19 18:36:16 +01:00
|
|
|
BL_REGISTER = [
|
|
|
|
GaussianPulseTemporalShapeNode,
|
|
|
|
]
|
|
|
|
BL_NODES = {
|
2024-03-10 11:56:37 +01:00
|
|
|
ct.NodeType.GaussianPulseTemporalShape: (
|
|
|
|
ct.NodeCategory.MAXWELLSIM_SOURCES_TEMPORALSHAPES
|
2024-02-19 18:36:16 +01:00
|
|
|
)
|
|
|
|
}
|