parent
c286d65193
commit
3624d2ff45
|
@ -213,6 +213,10 @@ class SimFieldPols(enum.StrEnum):
|
||||||
SFP.Hz: 'Hz',
|
SFP.Hz: 'Hz',
|
||||||
}[v]
|
}[v]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self) -> str:
|
||||||
|
return SimFieldPols.to_name(self)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def to_icon(_: typ.Self) -> str:
|
def to_icon(_: typ.Self) -> str:
|
||||||
"""Convert the enum value to a Blender icon.
|
"""Convert the enum value to a Blender icon.
|
||||||
|
|
|
@ -163,10 +163,19 @@ class CombineNode(base.MaxwellSimNode):
|
||||||
if not ct.FlowSignal.check(inp)
|
if not ct.FlowSignal.check(inp)
|
||||||
]
|
]
|
||||||
if func_flows:
|
if func_flows:
|
||||||
return functools.reduce(
|
return func_flows
|
||||||
lambda a, b: a | b,
|
return ct.FlowSignal.FlowPending
|
||||||
func_flows,
|
|
||||||
|
case (ct.FlowKind.Func, ct.FlowKind.Params):
|
||||||
|
params_flows = [
|
||||||
|
params_flow
|
||||||
|
for inp_sckname in self.inputs.keys() # noqa: SIM118
|
||||||
|
if not ct.FlowSignal.check(
|
||||||
|
params_flow := self._compute_input(inp_sckname, kind='params')
|
||||||
)
|
)
|
||||||
|
]
|
||||||
|
if params_flows:
|
||||||
|
return params_flows
|
||||||
return ct.FlowSignal.FlowPending
|
return ct.FlowSignal.FlowPending
|
||||||
|
|
||||||
return ct.FlowSignal.FlowPending
|
return ct.FlowSignal.FlowPending
|
||||||
|
@ -200,6 +209,18 @@ class CombineNode(base.MaxwellSimNode):
|
||||||
loose_input_sockets, props['value_or_func'], ct.FlowKind.Func
|
loose_input_sockets, props['value_or_func'], ct.FlowKind.Func
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@events.computes_output_socket(
|
||||||
|
'Sources',
|
||||||
|
kind=ct.FlowKind.Params,
|
||||||
|
all_loose_input_sockets=True,
|
||||||
|
props={'value_or_func'},
|
||||||
|
)
|
||||||
|
def compute_sources_params(self, props, loose_input_sockets) -> list[typ.Any]:
|
||||||
|
"""Compute (lazy) sources."""
|
||||||
|
return self.compute_combined(
|
||||||
|
loose_input_sockets, props['value_or_func'], ct.FlowKind.Params
|
||||||
|
)
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - Output: Structures
|
# - Output: Structures
|
||||||
####################
|
####################
|
||||||
|
@ -227,6 +248,18 @@ class CombineNode(base.MaxwellSimNode):
|
||||||
loose_input_sockets, props['value_or_func'], ct.FlowKind.Func
|
loose_input_sockets, props['value_or_func'], ct.FlowKind.Func
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@events.computes_output_socket(
|
||||||
|
'Structures',
|
||||||
|
kind=ct.FlowKind.Params,
|
||||||
|
all_loose_input_sockets=True,
|
||||||
|
props={'value_or_func'},
|
||||||
|
)
|
||||||
|
def compute_structures_params(self, props, loose_input_sockets) -> list[typ.Any]:
|
||||||
|
"""Compute (lazy) structures."""
|
||||||
|
return self.compute_combined(
|
||||||
|
loose_input_sockets, props['value_or_func'], ct.FlowKind.Params
|
||||||
|
)
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - Output: Monitors
|
# - Output: Monitors
|
||||||
####################
|
####################
|
||||||
|
@ -254,6 +287,18 @@ class CombineNode(base.MaxwellSimNode):
|
||||||
loose_input_sockets, props['value_or_func'], ct.FlowKind.Func
|
loose_input_sockets, props['value_or_func'], ct.FlowKind.Func
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@events.computes_output_socket(
|
||||||
|
'Monitors',
|
||||||
|
kind=ct.FlowKind.Params,
|
||||||
|
all_loose_input_sockets=True,
|
||||||
|
props={'value_or_func'},
|
||||||
|
)
|
||||||
|
def compute_monitors_params(self, props, loose_input_sockets) -> list[typ.Any]:
|
||||||
|
"""Compute (lazy) structures."""
|
||||||
|
return self.compute_combined(
|
||||||
|
loose_input_sockets, props['value_or_func'], ct.FlowKind.Params
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - Blender Registration
|
# - Blender Registration
|
||||||
|
|
|
@ -98,11 +98,9 @@ class GaussianBeamSourceNode(base.MaxwellSimNode):
|
||||||
####################
|
####################
|
||||||
# - Properties
|
# - Properties
|
||||||
####################
|
####################
|
||||||
injection_axis: ct.SimSpaceAxis = bl_cache.BLField(ct.SimSpaceAxis.X, prop_ui=True)
|
injection_axis: ct.SimSpaceAxis = bl_cache.BLField(ct.SimSpaceAxis.X)
|
||||||
injection_direction: ct.SimAxisDir = bl_cache.BLField(
|
injection_direction: ct.SimAxisDir = bl_cache.BLField(ct.SimAxisDir.Plus)
|
||||||
ct.SimAxisDir.Plus, prop_ui=True
|
num_freqs: int = bl_cache.BLField(1, abs_min=1, soft_max=20)
|
||||||
)
|
|
||||||
num_freqs: int = bl_cache.BLField(1, abs_min=1, soft_max=20, prop_ui=True)
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - UI
|
# - UI
|
||||||
|
|
|
@ -81,10 +81,8 @@ class PlaneWaveSourceNode(base.MaxwellSimNode):
|
||||||
####################
|
####################
|
||||||
# - Properties
|
# - Properties
|
||||||
####################
|
####################
|
||||||
injection_axis: ct.SimSpaceAxis = bl_cache.BLField(ct.SimSpaceAxis.X, prop_ui=True)
|
injection_axis: ct.SimSpaceAxis = bl_cache.BLField(ct.SimSpaceAxis.X)
|
||||||
injection_direction: ct.SimAxisDir = bl_cache.BLField(
|
injection_direction: ct.SimAxisDir = bl_cache.BLField(ct.SimAxisDir.Plus)
|
||||||
ct.SimAxisDir.Plus, prop_ui=True
|
|
||||||
)
|
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - UI
|
# - UI
|
||||||
|
@ -94,10 +92,34 @@ class PlaneWaveSourceNode(base.MaxwellSimNode):
|
||||||
layout.prop(self, self.blfields['injection_direction'], expand=True)
|
layout.prop(self, self.blfields['injection_direction'], expand=True)
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - Output Socket Computation
|
# - FlowKind.Value
|
||||||
####################
|
####################
|
||||||
@events.computes_output_socket(
|
@events.computes_output_socket(
|
||||||
'Angled Source',
|
'Angled Source',
|
||||||
|
kind=ct.FlowKind.Value,
|
||||||
|
# Loaded
|
||||||
|
output_sockets={'Angled Source'},
|
||||||
|
output_socket_kinds={'Angled Source': {ct.FlowKind.Func, ct.FlowKind.Params}},
|
||||||
|
)
|
||||||
|
def compute_value(self, output_sockets) -> ct.ParamsFlow | ct.FlowSignal:
|
||||||
|
"""Compute the particular value of the simulation domain from strictly non-symbolic inputs."""
|
||||||
|
output_func = output_sockets['Source'][ct.FlowKind.Func]
|
||||||
|
output_params = output_sockets['Source'][ct.FlowKind.Params]
|
||||||
|
|
||||||
|
has_output_func = not ct.FlowSignal.check(output_func)
|
||||||
|
has_output_params = not ct.FlowSignal.check(output_params)
|
||||||
|
|
||||||
|
if has_output_func and has_output_params and not output_params.symbols:
|
||||||
|
return output_func.realize(output_params, disallow_jax=True)
|
||||||
|
return ct.FlowSignal.FlowPending
|
||||||
|
|
||||||
|
####################
|
||||||
|
# - FlowKind.Func
|
||||||
|
####################
|
||||||
|
@events.computes_output_socket(
|
||||||
|
'Angled Source',
|
||||||
|
kind=ct.FlowKind.Func,
|
||||||
|
# Loaded
|
||||||
props={'sim_node_name', 'injection_axis', 'injection_direction'},
|
props={'sim_node_name', 'injection_axis', 'injection_direction'},
|
||||||
input_sockets={'Temporal Shape', 'Center', 'Spherical', 'Pol ∡'},
|
input_sockets={'Temporal Shape', 'Center', 'Spherical', 'Pol ∡'},
|
||||||
unit_systems={'Tidy3DUnits': ct.UNITS_TIDY3D},
|
unit_systems={'Tidy3DUnits': ct.UNITS_TIDY3D},
|
||||||
|
@ -107,24 +129,44 @@ class PlaneWaveSourceNode(base.MaxwellSimNode):
|
||||||
'Pol ∡': 'Tidy3DUnits',
|
'Pol ∡': 'Tidy3DUnits',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
def compute_source(self, props, input_sockets, unit_systems):
|
def compute_func(self, props, input_sockets) -> None:
|
||||||
|
center = input_sockets['Center']
|
||||||
|
temporal_shape = input_sockets['Temporal Shape']
|
||||||
|
spherical = input_sockets['Spherical']
|
||||||
|
pol_ang = input_sockets['Pol ∡']
|
||||||
|
|
||||||
|
has_center = not ct.FlowSignal.check(center)
|
||||||
|
has_temporal_shape = not ct.FlowSignal.check(temporal_shape)
|
||||||
|
has_spherical = not ct.FlowSignal.check(spherical)
|
||||||
|
has_pol_ang = not ct.FlowSignal.check(pol_ang)
|
||||||
|
|
||||||
|
if has_center and has_temporal_shape and has_spherical and has_pol_ang:
|
||||||
|
name = props['sim_node_name']
|
||||||
|
inj_dir = props['injection_direction'].plus_or_minus
|
||||||
size = {
|
size = {
|
||||||
ct.SimSpaceAxis.X: (0, td.inf, td.inf),
|
ct.SimSpaceAxis.X: (0, td.inf, td.inf),
|
||||||
ct.SimSpaceAxis.Y: (td.inf, 0, td.inf),
|
ct.SimSpaceAxis.Y: (td.inf, 0, td.inf),
|
||||||
ct.SimSpaceAxis.Z: (td.inf, td.inf, 0),
|
ct.SimSpaceAxis.Z: (td.inf, td.inf, 0),
|
||||||
}[props['injection_axis']]
|
}[props['injection_axis']]
|
||||||
|
|
||||||
# Display the results
|
return (
|
||||||
return td.PlaneWave(
|
center.scale_to_unit_system(ct.UNITS_TIDY3D)
|
||||||
name=props['sim_node_name'],
|
| temporal_shape
|
||||||
center=input_sockets['Center'],
|
| spherical.scale_to_unit_system(ct.UNITS_TIDY3D)
|
||||||
|
| pol_ang.scale_to_unit_system(ct.UNITS_TIDY3D)
|
||||||
|
).compose_within(
|
||||||
|
lambda els: td.PlaneWave(
|
||||||
|
name=name,
|
||||||
|
center=els[0],
|
||||||
size=size,
|
size=size,
|
||||||
source_time=input_sockets['Temporal Shape'],
|
source_time=els[1],
|
||||||
direction=props['injection_direction'].plus_or_minus,
|
direction=inj_dir,
|
||||||
angle_theta=input_sockets['Spherical'][0],
|
angle_theta=els[2][0],
|
||||||
angle_phi=input_sockets['Spherical'][1],
|
angle_phi=els[2][1],
|
||||||
pol_angle=input_sockets['Pol ∡'],
|
pol_angle=els[3],
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
return ct.FlowSignal.FlowPending
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - Preview - Changes to Input Sockets
|
# - Preview - Changes to Input Sockets
|
||||||
|
@ -134,9 +176,16 @@ class PlaneWaveSourceNode(base.MaxwellSimNode):
|
||||||
kind=ct.FlowKind.Previews,
|
kind=ct.FlowKind.Previews,
|
||||||
# Loaded
|
# Loaded
|
||||||
props={'sim_node_name'},
|
props={'sim_node_name'},
|
||||||
|
output_sockets={'Structure'},
|
||||||
|
output_socket_kinds={'Structure': ct.FlowKind.Params},
|
||||||
)
|
)
|
||||||
def compute_previews(self, props):
|
def compute_previews(self, props, output_sockets):
|
||||||
|
output_params = output_sockets['Structure']
|
||||||
|
has_output_params = not ct.FlowSignal.check(output_params)
|
||||||
|
|
||||||
|
if has_output_params and not output_params.symbols:
|
||||||
return ct.PreviewsFlow(bl_object_names={props['sim_node_name']})
|
return ct.PreviewsFlow(bl_object_names={props['sim_node_name']})
|
||||||
|
return ct.PreviewsFlow()
|
||||||
|
|
||||||
@events.on_value_changed(
|
@events.on_value_changed(
|
||||||
# Trigger
|
# Trigger
|
||||||
|
@ -147,27 +196,42 @@ class PlaneWaveSourceNode(base.MaxwellSimNode):
|
||||||
managed_objs={'modifier'},
|
managed_objs={'modifier'},
|
||||||
props={'injection_axis', 'injection_direction'},
|
props={'injection_axis', 'injection_direction'},
|
||||||
input_sockets={'Temporal Shape', 'Center', 'Spherical', 'Pol ∡'},
|
input_sockets={'Temporal Shape', 'Center', 'Spherical', 'Pol ∡'},
|
||||||
unit_systems={'BlenderUnits': ct.UNITS_BLENDER},
|
output_sockets={'Angled Source'},
|
||||||
scale_input_sockets={
|
output_socket_kinds={'Angled Source': ct.FlowKind.Params},
|
||||||
'Center': 'BlenderUnits',
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
def on_inputs_changed(self, managed_objs, props, input_sockets, unit_systems):
|
def on_inputs_changed(self, managed_objs, props, input_sockets, output_sockets):
|
||||||
|
center = input_sockets['Center']
|
||||||
|
spherical = input_sockets['Spherical']
|
||||||
|
pol_ang = input_sockets['Pol ∡']
|
||||||
|
output_params = output_sockets['Angled Source']
|
||||||
|
|
||||||
|
has_center = not ct.FlowSignal.check(center)
|
||||||
|
has_spherical = not ct.FlowSignal.check(spherical)
|
||||||
|
has_pol_ang = not ct.FlowSignal.check(pol_ang)
|
||||||
|
has_output_params = not ct.FlowSignal.check(output_params)
|
||||||
|
|
||||||
|
if (
|
||||||
|
has_center
|
||||||
|
and has_spherical
|
||||||
|
and has_pol_ang
|
||||||
|
and has_output_params
|
||||||
|
and not output_params.symbols
|
||||||
|
):
|
||||||
# Push Input Values to GeoNodes Modifier
|
# Push Input Values to GeoNodes Modifier
|
||||||
managed_objs['modifier'].bl_modifier(
|
managed_objs['modifier'].bl_modifier(
|
||||||
'NODES',
|
'NODES',
|
||||||
{
|
{
|
||||||
'node_group': import_geonodes(GeoNodes.SourcePlaneWave),
|
'node_group': import_geonodes(GeoNodes.SourcePlaneWave),
|
||||||
'unit_system': unit_systems['BlenderUnits'],
|
'unit_system': ct.UNITS_BLENDER,
|
||||||
'inputs': {
|
'inputs': {
|
||||||
'Inj Axis': props['injection_axis'].axis,
|
'Inj Axis': props['injection_axis'].axis,
|
||||||
'Direction': props['injection_direction'].true_or_false,
|
'Direction': props['injection_direction'].true_or_false,
|
||||||
'theta': input_sockets['Spherical'][0],
|
'theta': spherical[0],
|
||||||
'phi': input_sockets['Spherical'][1],
|
'phi': spherical[1],
|
||||||
'Pol Angle': input_sockets['Pol ∡'],
|
'Pol Angle': pol_ang,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
location=input_sockets['Center'],
|
location=spux.scale_to_unit_system(center, ct.UNITS_BLENDER),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ class PointDipoleSourceNode(base.MaxwellSimNode):
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
output_sockets: typ.ClassVar = {
|
output_sockets: typ.ClassVar = {
|
||||||
'Source': sockets.MaxwellSourceSocketDef(),
|
'Source': sockets.MaxwellSourceSocketDef(active_kind=ct.FlowKind.Func),
|
||||||
}
|
}
|
||||||
|
|
||||||
managed_obj_types: typ.ClassVar = {
|
managed_obj_types: typ.ClassVar = {
|
||||||
|
@ -62,59 +62,34 @@ class PointDipoleSourceNode(base.MaxwellSimNode):
|
||||||
####################
|
####################
|
||||||
# - Properties
|
# - Properties
|
||||||
####################
|
####################
|
||||||
pol_axis: ct.SimSpaceAxis = bl_cache.BLField(ct.SimSpaceAxis.X, prop_ui=True)
|
pol: ct.SimFieldPols = bl_cache.BLField(ct.SimFieldPols.Ex)
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - UI
|
# - UI
|
||||||
####################
|
####################
|
||||||
def draw_props(self, _: bpy.types.Context, layout: bpy.types.UILayout):
|
def draw_props(self, _: bpy.types.Context, layout: bpy.types.UILayout):
|
||||||
layout.prop(self, self.blfields['pol_axis'], expand=True)
|
layout.prop(self, self.blfields['pol'], expand=True)
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - FlowKind.Value
|
# - FlowKind.Value
|
||||||
####################
|
####################
|
||||||
@events.computes_output_socket(
|
@events.computes_output_socket(
|
||||||
'Source',
|
'Source',
|
||||||
|
kind=ct.FlowKind.Value,
|
||||||
# Loaded
|
# Loaded
|
||||||
props={'pol_axis'},
|
|
||||||
input_sockets={'Temporal Shape', 'Center', 'Interpolate'},
|
|
||||||
output_sockets={'Source'},
|
output_sockets={'Source'},
|
||||||
output_socket_kinds={'Source': ct.FlowKind.Params},
|
output_socket_kinds={'Source': {ct.FlowKind.Func, ct.FlowKind.Params}},
|
||||||
)
|
)
|
||||||
def compute_source_value(
|
def compute_value(self, output_sockets) -> ct.ParamsFlow | ct.FlowSignal:
|
||||||
self, input_sockets, props, output_sockets
|
"""Compute the particular value of the simulation domain from strictly non-symbolic inputs."""
|
||||||
) -> td.PointDipole | ct.FlowSignal:
|
output_func = output_sockets['Source'][ct.FlowKind.Func]
|
||||||
"""Compute the point dipole source, given that all inputs are non-symbolic."""
|
output_params = output_sockets['Source'][ct.FlowKind.Params]
|
||||||
temporal_shape = input_sockets['Temporal Shape']
|
|
||||||
center = input_sockets['Center']
|
|
||||||
interpolate = input_sockets['Interpolate']
|
|
||||||
output_params = output_sockets['Source']
|
|
||||||
|
|
||||||
has_temporal_shape = not ct.FlowSignal.check(temporal_shape)
|
has_output_func = not ct.FlowSignal.check(output_func)
|
||||||
has_center = not ct.FlowSignal.check(center)
|
|
||||||
has_interpolate = not ct.FlowSignal.check(interpolate)
|
|
||||||
has_output_params = not ct.FlowSignal.check(output_params)
|
has_output_params = not ct.FlowSignal.check(output_params)
|
||||||
|
|
||||||
if (
|
if has_output_func and has_output_params and not output_params.symbols:
|
||||||
has_temporal_shape
|
return output_func.realize(output_params, disallow_jax=True)
|
||||||
and has_center
|
|
||||||
and has_interpolate
|
|
||||||
and has_output_params
|
|
||||||
and not output_params.symbols
|
|
||||||
):
|
|
||||||
pol_axis = {
|
|
||||||
ct.SimSpaceAxis.X: 'Ex',
|
|
||||||
ct.SimSpaceAxis.Y: 'Ey',
|
|
||||||
ct.SimSpaceAxis.Z: 'Ez',
|
|
||||||
}[props['pol_axis']]
|
|
||||||
## TODO: Need Hx, Hy, Hz too?
|
|
||||||
|
|
||||||
return td.PointDipole(
|
|
||||||
center=spux.convert_to_unit_system(center, ct.UNITS_TIDY3D),
|
|
||||||
source_time=temporal_shape,
|
|
||||||
interpolate=interpolate,
|
|
||||||
polarization=pol_axis,
|
|
||||||
)
|
|
||||||
return ct.FlowSignal.FlowPending
|
return ct.FlowSignal.FlowPending
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
@ -124,42 +99,36 @@ class PointDipoleSourceNode(base.MaxwellSimNode):
|
||||||
'Source',
|
'Source',
|
||||||
kind=ct.FlowKind.Func,
|
kind=ct.FlowKind.Func,
|
||||||
# Loaded
|
# Loaded
|
||||||
props={'pol_axis'},
|
props={'pol'},
|
||||||
input_sockets={'Temporal Shape', 'Center', 'Interpolate'},
|
input_sockets={'Temporal Shape', 'Center', 'Interpolate'},
|
||||||
input_socket_kinds={
|
input_socket_kinds={
|
||||||
'Temporal Shape': ct.FlowKind.Func,
|
'Temporal Shape': ct.FlowKind.Func,
|
||||||
'Center': ct.FlowKind.Func,
|
'Center': ct.FlowKind.Func,
|
||||||
'Interpolate': ct.FlowKind.Func,
|
'Interpolate': ct.FlowKind.Func,
|
||||||
},
|
},
|
||||||
output_sockets={'Source'},
|
|
||||||
output_socket_kinds={'Source': ct.FlowKind.Params},
|
|
||||||
)
|
)
|
||||||
def compute_source_func(self, props, input_sockets, output_sockets) -> td.Box:
|
def compute_func(self, props, input_sockets) -> td.Box:
|
||||||
"""Compute a lazy function for the point dipole source."""
|
"""Compute a lazy function for the point dipole source."""
|
||||||
center = input_sockets['Center']
|
center = input_sockets['Center']
|
||||||
temporal_shape = input_sockets['Temporal Shape']
|
temporal_shape = input_sockets['Temporal Shape']
|
||||||
interpolate = input_sockets['Interpolate']
|
interpolate = input_sockets['Interpolate']
|
||||||
output_params = output_sockets['Source']
|
|
||||||
|
|
||||||
has_center = not ct.FlowSignal.check(center)
|
has_center = not ct.FlowSignal.check(center)
|
||||||
has_temporal_shape = not ct.FlowSignal.check(temporal_shape)
|
has_temporal_shape = not ct.FlowSignal.check(temporal_shape)
|
||||||
has_interpolate = not ct.FlowSignal.check(interpolate)
|
has_interpolate = not ct.FlowSignal.check(interpolate)
|
||||||
has_output_params = not ct.FlowSignal.check(output_params)
|
|
||||||
|
|
||||||
if has_temporal_shape and has_center and has_interpolate and has_output_params:
|
if has_temporal_shape and has_center and has_interpolate:
|
||||||
pol_axis = {
|
pol = props['pol']
|
||||||
ct.SimSpaceAxis.X: 'Ex',
|
return (
|
||||||
ct.SimSpaceAxis.Y: 'Ey',
|
center.scale_to_unit_system(ct.UNITS_TIDY3D)
|
||||||
ct.SimSpaceAxis.Z: 'Ez',
|
| temporal_shape
|
||||||
}[props['pol_axis']]
|
| interpolate
|
||||||
## TODO: Need Hx, Hy, Hz too?
|
).compose_within(
|
||||||
|
|
||||||
return (center | temporal_shape | interpolate).compose_within(
|
|
||||||
enclosing_func=lambda els: td.PointDipole(
|
enclosing_func=lambda els: td.PointDipole(
|
||||||
center=els[0],
|
center=els[0].flatten().tolist(),
|
||||||
source_time=els[1],
|
source_time=els[1],
|
||||||
interpolate=els[2],
|
interpolate=els[2],
|
||||||
polarization=pol_axis,
|
polarization=pol.name,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return ct.FlowSignal.FlowPending
|
return ct.FlowSignal.FlowPending
|
||||||
|
@ -183,16 +152,16 @@ class PointDipoleSourceNode(base.MaxwellSimNode):
|
||||||
input_sockets,
|
input_sockets,
|
||||||
) -> td.PointDipole | ct.FlowSignal:
|
) -> td.PointDipole | ct.FlowSignal:
|
||||||
"""Compute the point dipole source, given that all inputs are non-symbolic."""
|
"""Compute the point dipole source, given that all inputs are non-symbolic."""
|
||||||
temporal_shape = input_sockets['Temporal Shape']
|
|
||||||
center = input_sockets['Center']
|
center = input_sockets['Center']
|
||||||
|
temporal_shape = input_sockets['Temporal Shape']
|
||||||
interpolate = input_sockets['Interpolate']
|
interpolate = input_sockets['Interpolate']
|
||||||
|
|
||||||
has_temporal_shape = not ct.FlowSignal.check(temporal_shape)
|
|
||||||
has_center = not ct.FlowSignal.check(center)
|
has_center = not ct.FlowSignal.check(center)
|
||||||
|
has_temporal_shape = not ct.FlowSignal.check(temporal_shape)
|
||||||
has_interpolate = not ct.FlowSignal.check(interpolate)
|
has_interpolate = not ct.FlowSignal.check(interpolate)
|
||||||
|
|
||||||
if has_temporal_shape and has_center and has_interpolate:
|
if has_center and has_temporal_shape and has_interpolate:
|
||||||
return temporal_shape | center | interpolate
|
return center | temporal_shape | interpolate
|
||||||
return ct.FlowSignal.FlowPending
|
return ct.FlowSignal.FlowPending
|
||||||
|
|
||||||
####################
|
####################
|
||||||
|
@ -203,41 +172,58 @@ class PointDipoleSourceNode(base.MaxwellSimNode):
|
||||||
kind=ct.FlowKind.Previews,
|
kind=ct.FlowKind.Previews,
|
||||||
# Loaded
|
# Loaded
|
||||||
props={'sim_node_name'},
|
props={'sim_node_name'},
|
||||||
|
output_sockets={'Structure'},
|
||||||
|
output_socket_kinds={'Structure': ct.FlowKind.Params},
|
||||||
)
|
)
|
||||||
def compute_previews(self, props):
|
def compute_previews(self, props, output_sockets):
|
||||||
|
output_params = output_sockets['Structure']
|
||||||
|
has_output_params = not ct.FlowSignal.check(output_params)
|
||||||
|
|
||||||
|
if has_output_params and not output_params.symbols:
|
||||||
return ct.PreviewsFlow(bl_object_names={props['sim_node_name']})
|
return ct.PreviewsFlow(bl_object_names={props['sim_node_name']})
|
||||||
|
return ct.PreviewsFlow()
|
||||||
|
|
||||||
@events.on_value_changed(
|
@events.on_value_changed(
|
||||||
socket_name={'Center'},
|
socket_name={'Center'},
|
||||||
prop_name='pol_axis',
|
prop_name='pol',
|
||||||
run_on_init=True,
|
run_on_init=True,
|
||||||
# Pass Data
|
# Loaded
|
||||||
managed_objs={'modifier'},
|
managed_objs={'modifier'},
|
||||||
props={'pol_axis'},
|
props={'pol'},
|
||||||
input_sockets={'Center'},
|
input_sockets={'Center'},
|
||||||
unit_systems={'BlenderUnits': ct.UNITS_BLENDER},
|
output_sockets={'Source'},
|
||||||
scale_input_sockets={'Center': 'BlenderUnits'},
|
output_socket_kinds={'Source': ct.FlowKind.Params},
|
||||||
)
|
)
|
||||||
def on_inputs_changed(
|
def on_inputs_changed(
|
||||||
self, managed_objs, props, input_sockets, unit_systems
|
self, managed_objs, props, input_sockets, output_sockets
|
||||||
) -> None:
|
) -> None:
|
||||||
modifier = managed_objs['modifier']
|
SFP = ct.SimFieldPols
|
||||||
unit_system = unit_systems['BlenderUnits']
|
|
||||||
|
center = input_sockets['Center']
|
||||||
|
output_params = output_sockets['Source']
|
||||||
|
|
||||||
|
has_center = not ct.FlowSignal.check(center)
|
||||||
|
has_output_params = not ct.FlowSignal.check(output_params)
|
||||||
|
|
||||||
|
if has_center and has_output_params and not output_params.symbols:
|
||||||
axis = {
|
axis = {
|
||||||
ct.SimSpaceAxis.X: 0,
|
SFP.Ex: 0,
|
||||||
ct.SimSpaceAxis.Y: 1,
|
SFP.Ey: 1,
|
||||||
ct.SimSpaceAxis.Z: 2,
|
SFP.Ez: 2,
|
||||||
}[props['pol_axis']]
|
SFP.Hx: 0,
|
||||||
|
SFP.Hy: 1,
|
||||||
|
SFP.Hz: 2,
|
||||||
|
}[props['pol']]
|
||||||
|
|
||||||
# Push Loose Input Values to GeoNodes Modifier
|
# Push Loose Input Values to GeoNodes Modifier
|
||||||
modifier.bl_modifier(
|
managed_objs['modifier'].bl_modifier(
|
||||||
'NODES',
|
'NODES',
|
||||||
{
|
{
|
||||||
'node_group': import_geonodes(GeoNodes.SourcePointDipole),
|
'node_group': import_geonodes(GeoNodes.SourcePointDipole),
|
||||||
'inputs': {'Axis': axis},
|
'inputs': {'Axis': axis},
|
||||||
'unit_system': unit_system,
|
'unit_system': ct.UNITS_BLENDER,
|
||||||
},
|
},
|
||||||
location=input_sockets['Center'],
|
location=spux.scale_to_unit_system(center, ct.UNITS_BLENDER),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ class BoxStructureNode(base.MaxwellSimNode):
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
output_sockets: typ.ClassVar = {
|
output_sockets: typ.ClassVar = {
|
||||||
'Structure': sockets.MaxwellStructureSocketDef(),
|
'Structure': sockets.MaxwellStructureSocketDef(active_kind=ct.FlowKind.Func),
|
||||||
}
|
}
|
||||||
|
|
||||||
managed_obj_types: typ.ClassVar = {
|
managed_obj_types: typ.ClassVar = {
|
||||||
|
@ -228,8 +228,6 @@ class BoxStructureNode(base.MaxwellSimNode):
|
||||||
has_output_params = not ct.FlowSignal.check(output_params)
|
has_output_params = not ct.FlowSignal.check(output_params)
|
||||||
|
|
||||||
if has_center and has_size and has_output_params and not output_params.symbols:
|
if has_center and has_size and has_output_params and not output_params.symbols:
|
||||||
## TODO: There are strategies for handling examples of symbol values.
|
|
||||||
|
|
||||||
# Push Loose Input Values to GeoNodes Modifier
|
# Push Loose Input Values to GeoNodes Modifier
|
||||||
managed_objs['modifier'].bl_modifier(
|
managed_objs['modifier'].bl_modifier(
|
||||||
'NODES',
|
'NODES',
|
||||||
|
|
|
@ -58,7 +58,7 @@ class CylinderStructureNode(base.MaxwellSimNode):
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
output_sockets: typ.ClassVar = {
|
output_sockets: typ.ClassVar = {
|
||||||
'Structure': sockets.MaxwellStructureSocketDef(),
|
'Structure': sockets.MaxwellStructureSocketDef(active_kind=ct.FlowKind.Func),
|
||||||
}
|
}
|
||||||
|
|
||||||
managed_obj_types: typ.ClassVar = {
|
managed_obj_types: typ.ClassVar = {
|
||||||
|
@ -170,9 +170,16 @@ class CylinderStructureNode(base.MaxwellSimNode):
|
||||||
kind=ct.FlowKind.Previews,
|
kind=ct.FlowKind.Previews,
|
||||||
# Loaded
|
# Loaded
|
||||||
props={'sim_node_name'},
|
props={'sim_node_name'},
|
||||||
|
output_sockets={'Structure'},
|
||||||
|
output_socket_kinds={'Structure': ct.FlowKind.Params},
|
||||||
)
|
)
|
||||||
def compute_previews(self, props):
|
def compute_previews(self, props, output_sockets):
|
||||||
|
output_params = output_sockets['Structure']
|
||||||
|
has_output_params = not ct.FlowSignal.check(output_params)
|
||||||
|
|
||||||
|
if has_output_params and not output_params.symbols:
|
||||||
return ct.PreviewsFlow(bl_object_names={props['sim_node_name']})
|
return ct.PreviewsFlow(bl_object_names={props['sim_node_name']})
|
||||||
|
return ct.PreviewsFlow()
|
||||||
|
|
||||||
@events.on_value_changed(
|
@events.on_value_changed(
|
||||||
# Trigger
|
# Trigger
|
||||||
|
@ -181,32 +188,39 @@ class CylinderStructureNode(base.MaxwellSimNode):
|
||||||
# Loaded
|
# Loaded
|
||||||
input_sockets={'Center', 'Radius', 'Medium', 'Height'},
|
input_sockets={'Center', 'Radius', 'Medium', 'Height'},
|
||||||
managed_objs={'modifier'},
|
managed_objs={'modifier'},
|
||||||
unit_systems={'BlenderUnits': ct.UNITS_BLENDER},
|
output_sockets={'Structure'},
|
||||||
scale_input_sockets={
|
output_socket_kinds={'Structure': ct.FlowKind.Params},
|
||||||
'Center': 'BlenderUnits',
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
def on_inputs_changed(
|
def on_previewable_changed(self, managed_objs, input_sockets, output_sockets):
|
||||||
self,
|
center = input_sockets['Center']
|
||||||
managed_objs,
|
radius = input_sockets['Radius']
|
||||||
input_sockets,
|
height = input_sockets['Height']
|
||||||
unit_systems,
|
output_params = output_sockets['Structure']
|
||||||
):
|
|
||||||
modifier = managed_objs['modifier']
|
|
||||||
unit_system = unit_systems['BlenderUnits']
|
|
||||||
|
|
||||||
|
has_center = not ct.FlowSignal.check(center)
|
||||||
|
has_radius = not ct.FlowSignal.check(radius)
|
||||||
|
has_height = not ct.FlowSignal.check(height)
|
||||||
|
has_output_params = not ct.FlowSignal.check(output_params)
|
||||||
|
|
||||||
|
if (
|
||||||
|
has_center
|
||||||
|
and has_radius
|
||||||
|
and has_height
|
||||||
|
and has_output_params
|
||||||
|
and not output_params.symbols
|
||||||
|
):
|
||||||
# Push Loose Input Values to GeoNodes Modifier
|
# Push Loose Input Values to GeoNodes Modifier
|
||||||
modifier.bl_modifier(
|
managed_objs['modifier'].bl_modifier(
|
||||||
'NODES',
|
'NODES',
|
||||||
{
|
{
|
||||||
'node_group': import_geonodes(GeoNodes.StructurePrimitiveCylinder),
|
'node_group': import_geonodes(GeoNodes.StructurePrimitiveCylinder),
|
||||||
'inputs': {
|
'inputs': {
|
||||||
'Radius': input_sockets['Radius'],
|
'Radius': radius,
|
||||||
'Height': input_sockets['Height'],
|
'Height': height,
|
||||||
},
|
},
|
||||||
'unit_system': unit_system,
|
'unit_system': ct.UNITS_BLENDER,
|
||||||
},
|
},
|
||||||
location=input_sockets['Center'],
|
location=spux.scale_to_unit_system(center, ct.UNITS_BLENDER),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ class MaxwellBoundCondBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Properties
|
# - Properties
|
||||||
####################
|
####################
|
||||||
default: ct.BoundCondType = bl_cache.BLField(ct.BoundCondType.Pml, prop_ui=True)
|
default: ct.BoundCondType = bl_cache.BLField(ct.BoundCondType.Pml)
|
||||||
|
|
||||||
# Capabilities
|
# Capabilities
|
||||||
## Allow a boundary condition compatible with any of the following axes.
|
## Allow a boundary condition compatible with any of the following axes.
|
||||||
|
|
|
@ -46,14 +46,14 @@ class MaxwellBoundCondsBLSocket(base.MaxwellSimSocket):
|
||||||
####################
|
####################
|
||||||
# - Properties
|
# - Properties
|
||||||
####################
|
####################
|
||||||
show_definition: bool = bl_cache.BLField(False, prop_ui=True)
|
show_definition: bool = bl_cache.BLField(False)
|
||||||
|
|
||||||
x_pos: ct.BoundCondType = bl_cache.BLField(ct.BoundCondType.Pml, prop_ui=True)
|
x_pos: ct.BoundCondType = bl_cache.BLField(ct.BoundCondType.Pml)
|
||||||
x_neg: ct.BoundCondType = bl_cache.BLField(ct.BoundCondType.Pml, prop_ui=True)
|
x_neg: ct.BoundCondType = bl_cache.BLField(ct.BoundCondType.Pml)
|
||||||
y_pos: ct.BoundCondType = bl_cache.BLField(ct.BoundCondType.Pml, prop_ui=True)
|
y_pos: ct.BoundCondType = bl_cache.BLField(ct.BoundCondType.Pml)
|
||||||
y_neg: ct.BoundCondType = bl_cache.BLField(ct.BoundCondType.Pml, prop_ui=True)
|
y_neg: ct.BoundCondType = bl_cache.BLField(ct.BoundCondType.Pml)
|
||||||
z_pos: ct.BoundCondType = bl_cache.BLField(ct.BoundCondType.Pml, prop_ui=True)
|
z_pos: ct.BoundCondType = bl_cache.BLField(ct.BoundCondType.Pml)
|
||||||
z_neg: ct.BoundCondType = bl_cache.BLField(ct.BoundCondType.Pml, prop_ui=True)
|
z_neg: ct.BoundCondType = bl_cache.BLField(ct.BoundCondType.Pml)
|
||||||
|
|
||||||
####################
|
####################
|
||||||
# - UI
|
# - UI
|
||||||
|
|
|
@ -65,7 +65,6 @@ class BLField:
|
||||||
default_value: typ.Any = None,
|
default_value: typ.Any = None,
|
||||||
use_prop_update: bool = True,
|
use_prop_update: bool = True,
|
||||||
## Static
|
## Static
|
||||||
prop_ui: bool = False, ## TODO: Remove
|
|
||||||
abs_min: int | float | None = None,
|
abs_min: int | float | None = None,
|
||||||
abs_max: int | float | None = None,
|
abs_max: int | float | None = None,
|
||||||
soft_min: int | float | None = None,
|
soft_min: int | float | None = None,
|
||||||
|
|
Loading…
Reference in New Issue