refactor: Renamed LazyArrayRange to Range

main
Sofus Albert Høgsbro Rose 2024-05-21 09:00:23 +02:00
parent f5d19abecd
commit 84825c2642
Signed by: so-rose
GPG Key ID: AD901CB0F3701434
19 changed files with 110 additions and 116 deletions

View File

@ -47,7 +47,7 @@ from .flow_kinds import (
CapabilitiesFlow, CapabilitiesFlow,
FlowKind, FlowKind,
InfoFlow, InfoFlow,
LazyArrayRangeFlow, RangeFlow,
LazyValueFuncFlow, LazyValueFuncFlow,
ParamsFlow, ParamsFlow,
ScalingMode, ScalingMode,
@ -118,7 +118,7 @@ __all__ = [
'CapabilitiesFlow', 'CapabilitiesFlow',
'FlowKind', 'FlowKind',
'InfoFlow', 'InfoFlow',
'LazyArrayRangeFlow', 'RangeFlow',
'LazyValueFuncFlow', 'LazyValueFuncFlow',
'ParamsFlow', 'ParamsFlow',
'ScalingMode', 'ScalingMode',

View File

@ -18,7 +18,7 @@ from .array import ArrayFlow
from .capabilities import CapabilitiesFlow from .capabilities import CapabilitiesFlow
from .flow_kinds import FlowKind from .flow_kinds import FlowKind
from .info import InfoFlow from .info import InfoFlow
from .lazy_array_range import LazyArrayRangeFlow, ScalingMode from .lazy_range import RangeFlow, ScalingMode
from .lazy_value_func import LazyValueFuncFlow from .lazy_value_func import LazyValueFuncFlow
from .params import ParamsFlow from .params import ParamsFlow
from .value import ValueFlow from .value import ValueFlow
@ -28,7 +28,7 @@ __all__ = [
'CapabilitiesFlow', 'CapabilitiesFlow',
'FlowKind', 'FlowKind',
'InfoFlow', 'InfoFlow',
'LazyArrayRangeFlow', 'RangeFlow',
'ScalingMode', 'ScalingMode',
'LazyValueFuncFlow', 'LazyValueFuncFlow',
'ParamsFlow', 'ParamsFlow',

View File

@ -42,7 +42,7 @@ class FlowKind(enum.StrEnum):
However, for any other array-like variants (or sockets that only represent array-like objects), `Array` should be defined manually. However, for any other array-like variants (or sockets that only represent array-like objects), `Array` should be defined manually.
LazyValueFunc: A composable function. LazyValueFunc: A composable function.
Can be used to represent computations for which all data is not yet known, or for which just-in-time compilation can drastically increase performance. Can be used to represent computations for which all data is not yet known, or for which just-in-time compilation can drastically increase performance.
LazyArrayRange: An object that generates an `Array` from range information (start/stop/step/spacing). Range: An object that generates an `Array` from range information (start/stop/step/spacing).
This should be used instead of `Array` whenever possible. This should be used instead of `Array` whenever possible.
Param: A dictionary providing particular parameters for a lazy value. Param: A dictionary providing particular parameters for a lazy value.
Info: An dictionary providing extra context about any aspect of flow. Info: An dictionary providing extra context about any aspect of flow.
@ -56,7 +56,7 @@ class FlowKind(enum.StrEnum):
# Lazy # Lazy
LazyValueFunc = enum.auto() LazyValueFunc = enum.auto()
LazyArrayRange = enum.auto() Range = enum.auto()
# Auxiliary # Auxiliary
Params = enum.auto() Params = enum.auto()
@ -79,7 +79,7 @@ class FlowKind(enum.StrEnum):
flow_obj, flow_obj,
unit_system, unit_system,
) )
if kind == FlowKind.LazyArrayRange: if kind == FlowKind.Range:
return flow_obj.rescale_to_unit_system(unit_system) return flow_obj.rescale_to_unit_system(unit_system)
if kind == FlowKind.Params: if kind == FlowKind.Params:
@ -97,7 +97,7 @@ class FlowKind(enum.StrEnum):
FlowKind.Value: FlowKind.Value, FlowKind.Value: FlowKind.Value,
FlowKind.Array: FlowKind.Array, FlowKind.Array: FlowKind.Array,
FlowKind.LazyValueFunc: FlowKind.LazyValueFunc, FlowKind.LazyValueFunc: FlowKind.LazyValueFunc,
FlowKind.LazyArrayRange: FlowKind.LazyArrayRange, FlowKind.Range: FlowKind.Range,
}[self] }[self]
@property @property
@ -105,7 +105,7 @@ class FlowKind(enum.StrEnum):
return { return {
FlowKind.Value: 'CIRCLE', FlowKind.Value: 'CIRCLE',
FlowKind.Array: 'SQUARE', FlowKind.Array: 'SQUARE',
FlowKind.LazyArrayRange: 'SQUARE', FlowKind.Range: 'SQUARE',
FlowKind.LazyValueFunc: 'DIAMOND', FlowKind.LazyValueFunc: 'DIAMOND',
}[self] }[self]
@ -118,7 +118,7 @@ class FlowKind(enum.StrEnum):
FlowKind.Capabilities: 'Capabilities', FlowKind.Capabilities: 'Capabilities',
FlowKind.Value: 'Value', FlowKind.Value: 'Value',
FlowKind.Array: 'Array', FlowKind.Array: 'Array',
FlowKind.LazyArrayRange: 'Range', FlowKind.Range: 'Range',
FlowKind.LazyValueFunc: 'Func', FlowKind.LazyValueFunc: 'Func',
FlowKind.Params: 'Parameters', FlowKind.Params: 'Parameters',
FlowKind.Info: 'Information', FlowKind.Info: 'Information',

View File

@ -24,7 +24,7 @@ from blender_maxwell.utils import extra_sympy_units as spux
from blender_maxwell.utils import logger from blender_maxwell.utils import logger
from .array import ArrayFlow from .array import ArrayFlow
from .lazy_array_range import LazyArrayRangeFlow from .lazy_range import RangeFlow
log = logger.get(__name__) log = logger.get(__name__)
@ -35,7 +35,7 @@ class InfoFlow:
# - Covariant Input # - Covariant Input
#################### ####################
dim_names: list[str] = dataclasses.field(default_factory=list) dim_names: list[str] = dataclasses.field(default_factory=list)
dim_idx: dict[str, ArrayFlow | LazyArrayRangeFlow] = dataclasses.field( dim_idx: dict[str, ArrayFlow | RangeFlow] = dataclasses.field(
default_factory=dict default_factory=dict
) ## TODO: Rename to dim_idxs ) ## TODO: Rename to dim_idxs
@ -43,7 +43,7 @@ class InfoFlow:
def dim_has_coords(self) -> dict[str, int]: def dim_has_coords(self) -> dict[str, int]:
return { return {
dim_name: not ( dim_name: not (
isinstance(dim_idx, LazyArrayRangeFlow) isinstance(dim_idx, RangeFlow)
and (dim_idx.start.is_infinite or dim_idx.stop.is_infinite) and (dim_idx.start.is_infinite or dim_idx.stop.is_infinite)
) )
for dim_name, dim_idx in self.dim_idx.items() for dim_name, dim_idx in self.dim_idx.items()
@ -74,7 +74,7 @@ class InfoFlow:
def dim_idx_arrays(self) -> list[jax.Array]: def dim_idx_arrays(self) -> list[jax.Array]:
return [ return [
dim_idx.realize().values dim_idx.realize().values
if isinstance(dim_idx, LazyArrayRangeFlow) if isinstance(dim_idx, RangeFlow)
else dim_idx.values else dim_idx.values
for dim_idx in self.dim_idx.values() for dim_idx in self.dim_idx.values()
] ]
@ -129,7 +129,7 @@ class InfoFlow:
) )
def replace_dim( def replace_dim(
self, old_dim_name: str, new_dim_idx: tuple[str, ArrayFlow | LazyArrayRangeFlow] self, old_dim_name: str, new_dim_idx: tuple[str, ArrayFlow | RangeFlow]
) -> typ.Self: ) -> typ.Self:
"""Replace a dimension (and its indexing) with a new name and index array/range.""" """Replace a dimension (and its indexing) with a new name and index array/range."""
return InfoFlow( return InfoFlow(
@ -151,7 +151,7 @@ class InfoFlow:
output_unit=self.output_unit, output_unit=self.output_unit,
) )
def rescale_dim_idxs(self, new_dim_idxs: dict[str, LazyArrayRangeFlow]) -> typ.Self: def rescale_dim_idxs(self, new_dim_idxs: dict[str, RangeFlow]) -> typ.Self:
"""Replace several dimensional indices with new index arrays/ranges.""" """Replace several dimensional indices with new index arrays/ranges."""
return InfoFlow( return InfoFlow(
# Dimensions # Dimensions

View File

@ -54,7 +54,7 @@ class ScalingMode(enum.StrEnum):
@dataclasses.dataclass(frozen=True, kw_only=True) @dataclasses.dataclass(frozen=True, kw_only=True)
class LazyArrayRangeFlow: class RangeFlow:
r"""Represents a linearly/logarithmically spaced array using symbolic boundary expressions, with support for units and lazy evaluation. r"""Represents a linearly/logarithmically spaced array using symbolic boundary expressions, with support for units and lazy evaluation.
# Advantages # Advantages
@ -62,7 +62,7 @@ class LazyArrayRangeFlow:
## Memory ## Memory
`ArrayFlow` generally has a memory scaling of $O(n)$. `ArrayFlow` generally has a memory scaling of $O(n)$.
Naturally, `LazyArrayRangeFlow` is always constant, since only the boundaries and steps are stored. Naturally, `RangeFlow` is always constant, since only the boundaries and steps are stored.
## Symbolic ## Symbolic
Both boundary points are symbolic expressions, within which pre-defined `sp.Symbol`s can participate in a constrained manner (ex. an integer symbol). Both boundary points are symbolic expressions, within which pre-defined `sp.Symbol`s can participate in a constrained manner (ex. an integer symbol).
@ -71,7 +71,7 @@ class LazyArrayRangeFlow:
## Performant Unit-Aware Operations ## Performant Unit-Aware Operations
While `ArrayFlow`s are also unit-aware, the time-cost of _any_ unit-scaling operation scales with $O(n)$. While `ArrayFlow`s are also unit-aware, the time-cost of _any_ unit-scaling operation scales with $O(n)$.
`LazyArrayRangeFlow`, by contrast, scales as $O(1)$. `RangeFlow`, by contrast, scales as $O(1)$.
As a result, more complicated operations (like symbolic or unit-based) that might be difficult to perform interactively in real-time on an `ArrayFlow` will work perfectly with this object, even with added complexity As a result, more complicated operations (like symbolic or unit-based) that might be difficult to perform interactively in real-time on an `ArrayFlow` will work perfectly with this object, even with added complexity
@ -82,7 +82,7 @@ class LazyArrayRangeFlow:
- **Gradient**: The gradient of the output array, with respect to any symbols used to define the input bounds, can easily be found using `jax.grad` over `self.as_func`. - **Gradient**: The gradient of the output array, with respect to any symbols used to define the input bounds, can easily be found using `jax.grad` over `self.as_func`.
- **JIT**: When `self.as_func` is composed with other `jax` functions, and `jax.jit` is run to optimize the entire thing, the "cost of array generation" _will often be optimized away significantly or entirely_. - **JIT**: When `self.as_func` is composed with other `jax` functions, and `jax.jit` is run to optimize the entire thing, the "cost of array generation" _will often be optimized away significantly or entirely_.
Thus, as part of larger computations, the performance properties of `LazyArrayRangeFlow` is extremely favorable. Thus, as part of larger computations, the performance properties of `RangeFlow` is extremely favorable.
## Numerical Properties ## Numerical Properties
Since the bounds support exact (ex. rational) calculations and symbolic manipulations (_by virtue of being symbolic expressions_), the opportunities for certain kinds of numerical instability are mitigated. Since the bounds support exact (ex. rational) calculations and symbolic manipulations (_by virtue of being symbolic expressions_), the opportunities for certain kinds of numerical instability are mitigated.
@ -174,7 +174,7 @@ class LazyArrayRangeFlow:
corrected_unit: The unit to replace the current unit with. corrected_unit: The unit to replace the current unit with.
Returns: Returns:
A new `LazyArrayRangeFlow` with replaced unit. A new `RangeFlow` with replaced unit.
Raises: Raises:
ValueError: If the existing unit is `None`, indicating that there is no unit to correct. ValueError: If the existing unit is `None`, indicating that there is no unit to correct.
@ -185,7 +185,7 @@ class LazyArrayRangeFlow:
self, self,
corrected_unit, corrected_unit,
) )
return LazyArrayRangeFlow( return RangeFlow(
start=self.start, start=self.start,
stop=self.stop, stop=self.stop,
steps=self.steps, steps=self.steps,
@ -204,7 +204,7 @@ class LazyArrayRangeFlow:
unit: The unit to convert the bounds to. unit: The unit to convert the bounds to.
Returns: Returns:
A new `LazyArrayRangeFlow` with replaced unit. A new `RangeFlow` with replaced unit.
Raises: Raises:
ValueError: If the existing unit is `None`, indicating that there is no unit to correct. ValueError: If the existing unit is `None`, indicating that there is no unit to correct.
@ -215,7 +215,7 @@ class LazyArrayRangeFlow:
self, self,
unit, unit,
) )
return LazyArrayRangeFlow( return RangeFlow(
start=spux.scale_to_unit(self.start * self.unit, unit), start=spux.scale_to_unit(self.start * self.unit, unit),
stop=spux.scale_to_unit(self.stop * self.unit, unit), stop=spux.scale_to_unit(self.stop * self.unit, unit),
steps=self.steps, steps=self.steps,
@ -234,7 +234,7 @@ class LazyArrayRangeFlow:
unit: The unit to convert the bounds to. unit: The unit to convert the bounds to.
Returns: Returns:
A new `LazyArrayRangeFlow` with replaced unit. A new `RangeFlow` with replaced unit.
Raises: Raises:
ValueError: If the existing unit is `None`, indicating that there is no unit to correct. ValueError: If the existing unit is `None`, indicating that there is no unit to correct.
@ -245,7 +245,7 @@ class LazyArrayRangeFlow:
self, self,
unit_system[spux.PhysicalType.from_unit(self.unit)], unit_system[spux.PhysicalType.from_unit(self.unit)],
) )
return LazyArrayRangeFlow( return RangeFlow(
start=spux.strip_unit_system( start=spux.strip_unit_system(
spux.convert_to_unit_system(self.start * self.unit, unit_system), spux.convert_to_unit_system(self.start * self.unit, unit_system),
unit_system, unit_system,
@ -277,7 +277,7 @@ class LazyArrayRangeFlow:
new_start = rescale_func(new_pre_start * self.unit) new_start = rescale_func(new_pre_start * self.unit)
new_stop = rescale_func(new_pre_stop * self.unit) new_stop = rescale_func(new_pre_stop * self.unit)
return LazyArrayRangeFlow( return RangeFlow(
start=( start=(
spux.scale_to_unit(new_start, new_unit) spux.scale_to_unit(new_start, new_unit)
if new_unit is not None if new_unit is not None
@ -314,9 +314,9 @@ class LazyArrayRangeFlow:
reverse: Whether to reverse the bounds after running the `scaler`. reverse: Whether to reverse the bounds after running the `scaler`.
Returns: Returns:
A rescaled `LazyArrayRangeFlow`. A rescaled `RangeFlow`.
""" """
return LazyArrayRangeFlow( return RangeFlow(
start=rescale_func(self.start if not reverse else self.stop), start=rescale_func(self.start if not reverse else self.stop),
stop=rescale_func(self.stop if not reverse else self.start), stop=rescale_func(self.stop if not reverse else self.start),
steps=self.steps, steps=self.steps,
@ -442,7 +442,7 @@ class LazyArrayRangeFlow:
reverse: Whether to reverse the bounds after running the `scaler`. reverse: Whether to reverse the bounds after running the `scaler`.
Returns: Returns:
A rescaled `LazyArrayRangeFlow`. A rescaled `RangeFlow`.
""" """
if not set(self.symbols).issubset(set(symbol_values.keys())): if not set(self.symbols).issubset(set(symbol_values.keys())):
msg = f'Provided symbols ({set(symbol_values.keys())}) do not provide values for all expression symbols ({self.symbols}) that may be found in the boundary expressions (start={self.start}, end={self.end})' msg = f'Provided symbols ({set(symbol_values.keys())}) do not provide values for all expression symbols ({self.symbols}) that may be found in the boundary expressions (start={self.start}, end={self.end})'
@ -482,7 +482,7 @@ class LazyArrayRangeFlow:
new_start = step_size * start new_start = step_size * start
new_stop = new_start + step_size * slice_steps new_stop = new_start + step_size * slice_steps
return LazyArrayRangeFlow( return RangeFlow(
start=sp.S(new_start), start=sp.S(new_start),
stop=sp.S(new_stop), stop=sp.S(new_stop),
steps=slice_steps, steps=slice_steps,

View File

@ -39,7 +39,7 @@ class ExprInfo(typ.TypedDict):
# Value # Value
default_value: spux.SympyExpr default_value: spux.SympyExpr
# LazyArrayRange # Range
default_min: spux.SympyExpr default_min: spux.SympyExpr
default_max: spux.SympyExpr default_max: spux.SympyExpr
default_steps: int default_steps: int
@ -184,7 +184,7 @@ class ParamsFlow:
# TODO: Default Values # TODO: Default Values
# FlowKind.Value: Default Value # FlowKind.Value: Default Value
#'default_value': #'default_value':
# FlowKind.LazyArrayRange: Default Min/Max/Steps # FlowKind.Range: Default Min/Max/Steps
#'default_min': #'default_min':
#'default_max': #'default_max':
#'default_steps': #'default_steps':

View File

@ -227,7 +227,7 @@ class FilterOperation(enum.StrEnum):
dim_0: str, dim_0: str,
dim_1: str, dim_1: str,
slice_tuple: tuple[int, int, int] | None = None, slice_tuple: tuple[int, int, int] | None = None,
corrected_dim: tuple[str, tuple[str, ct.ArrayFlow | ct.LazyArrayRangeFlow]] corrected_dim: tuple[str, tuple[str, ct.ArrayFlow | ct.RangeFlow]]
| None = None, | None = None,
): ):
FO = FilterOperation FO = FilterOperation

View File

@ -225,16 +225,14 @@ class TransformOperation(enum.StrEnum):
info.dim_names[-1], info.dim_names[-1],
[ [
'f', 'f',
ct.LazyArrayRangeFlow(start=0, stop=sp.oo, steps=0, unit=spu.hertz), ct.RangeFlow(start=0, stop=sp.oo, steps=0, unit=spu.hertz),
], ],
), ),
TO.InvFFT1D: info.replace_dim( TO.InvFFT1D: info.replace_dim(
info.dim_names[-1], info.dim_names[-1],
[ [
't', 't',
ct.LazyArrayRangeFlow( ct.RangeFlow(start=0, stop=sp.oo, steps=0, unit=spu.second),
start=0, stop=sp.oo, steps=0, unit=spu.second
),
], ],
), ),
}.get(self, lambda: info)() }.get(self, lambda: info)()

View File

@ -337,7 +337,7 @@ class VizNode(base.MaxwellSimNode):
}: }:
self.loose_input_sockets = { self.loose_input_sockets = {
sym.name: sockets.ExprSocketDef( sym.name: sockets.ExprSocketDef(
active_kind=ct.FlowKind.LazyArrayRange, active_kind=ct.FlowKind.Range,
size=spux.NumberSize1D.Scalar, size=spux.NumberSize1D.Scalar,
mathtype=info.dim_mathtypes[sym.name], mathtype=info.dim_mathtypes[sym.name],
physical_type=info.dim_physical_types[sym.name], physical_type=info.dim_physical_types[sym.name],
@ -409,7 +409,7 @@ class VizNode(base.MaxwellSimNode):
): ):
return return
# Compute LazyArrayRanges for Symbols from Loose Sockets # Compute Ranges for Symbols from Loose Sockets
## -> These are the concrete values of the symbol for plotting. ## -> These are the concrete values of the symbol for plotting.
## -> In a quite nice turn of events, all this is cached lookups. ## -> In a quite nice turn of events, all this is cached lookups.
## -> ...Unless something changed, in which case, well. It changed. ## -> ...Unless something changed, in which case, well. It changed.

View File

@ -204,7 +204,7 @@ class DataFileImporterNode(base.MaxwellSimNode):
return ct.InfoFlow( return ct.InfoFlow(
dim_names=dim_names, ## TODO: User dim_names=dim_names, ## TODO: User
dim_idx={ dim_idx={
dim_name: ct.LazyArrayRangeFlow( dim_name: ct.RangeFlow(
start=sp.S(0), ## TODO: User start=sp.S(0), ## TODO: User
stop=sp.S(shape[i] - 1), ## TODO: User stop=sp.S(shape[i] - 1), ## TODO: User
steps=shape[dim_names.index(dim_name)], steps=shape[dim_names.index(dim_name)],

View File

@ -74,11 +74,11 @@ class SceneNode(base.MaxwellSimNode):
return bpy.context.scene.frame_current return bpy.context.scene.frame_current
@property @property
def scene_frame_range(self) -> ct.LazyArrayRangeFlow: def scene_frame_range(self) -> ct.RangeFlow:
"""Retrieve the current start/end frame of the scene, with `steps` corresponding to single-frame steps.""" """Retrieve the current start/end frame of the scene, with `steps` corresponding to single-frame steps."""
frame_start = bpy.context.scene.frame_start frame_start = bpy.context.scene.frame_start
frame_stop = bpy.context.scene.frame_end frame_stop = bpy.context.scene.frame_end
return ct.LazyArrayRangeFlow( return ct.RangeFlow(
start=frame_start, start=frame_start,
stop=frame_stop, stop=frame_stop,
steps=frame_stop - frame_start + 1, steps=frame_stop - frame_start + 1,

View File

@ -100,30 +100,26 @@ class WaveConstantNode(base.MaxwellSimNode):
run_on_init=True, run_on_init=True,
) )
def on_use_range_changed(self, props: dict) -> None: def on_use_range_changed(self, props: dict) -> None:
"""Synchronize the `active_kind` of input/output sockets, to either produce a `ct.FlowKind.Value` or a `ct.FlowKind.LazyArrayRange`.""" """Synchronize the `active_kind` of input/output sockets, to either produce a `ct.FlowKind.Value` or a `ct.FlowKind.Range`."""
if self.inputs.get('WL') is not None: if self.inputs.get('WL') is not None:
active_input = self.inputs['WL'] active_input = self.inputs['WL']
else: else:
active_input = self.inputs['Freq'] active_input = self.inputs['Freq']
# Modify Active Kind(s) # Modify Active Kind(s)
## Input active_kind -> Value/LazyArrayRange ## Input active_kind -> Value/Range
active_input_uses_range = active_input.active_kind == ct.FlowKind.LazyArrayRange active_input_uses_range = active_input.active_kind == ct.FlowKind.Range
if active_input_uses_range != props['use_range']: if active_input_uses_range != props['use_range']:
active_input.active_kind = ( active_input.active_kind = (
ct.FlowKind.LazyArrayRange if props['use_range'] else ct.FlowKind.Value ct.FlowKind.Range if props['use_range'] else ct.FlowKind.Value
) )
## Output active_kind -> Value/LazyArrayRange ## Output active_kind -> Value/Range
for active_output in self.outputs.values(): for active_output in self.outputs.values():
active_output_uses_range = ( active_output_uses_range = active_output.active_kind == ct.FlowKind.Range
active_output.active_kind == ct.FlowKind.LazyArrayRange
)
if active_output_uses_range != props['use_range']: if active_output_uses_range != props['use_range']:
active_output.active_kind = ( active_output.active_kind = (
ct.FlowKind.LazyArrayRange ct.FlowKind.Range if props['use_range'] else ct.FlowKind.Value
if props['use_range']
else ct.FlowKind.Value
) )
#################### ####################
@ -161,11 +157,11 @@ class WaveConstantNode(base.MaxwellSimNode):
@events.computes_output_socket( @events.computes_output_socket(
'WL', 'WL',
kind=ct.FlowKind.LazyArrayRange, kind=ct.FlowKind.Range,
input_sockets={'WL', 'Freq'}, input_sockets={'WL', 'Freq'},
input_socket_kinds={ input_socket_kinds={
'WL': ct.FlowKind.LazyArrayRange, 'WL': ct.FlowKind.Range,
'Freq': ct.FlowKind.LazyArrayRange, 'Freq': ct.FlowKind.Range,
}, },
input_sockets_optional={'WL': True, 'Freq': True}, input_sockets_optional={'WL': True, 'Freq': True},
) )
@ -176,7 +172,7 @@ class WaveConstantNode(base.MaxwellSimNode):
return input_sockets['WL'] return input_sockets['WL']
freq = input_sockets['Freq'] freq = input_sockets['Freq']
return ct.LazyArrayRangeFlow( return ct.RangeFlow(
start=spux.scale_to_unit( start=spux.scale_to_unit(
sci_constants.vac_speed_of_light / (freq.stop * freq.unit), spu.um sci_constants.vac_speed_of_light / (freq.stop * freq.unit), spu.um
), ),
@ -190,11 +186,11 @@ class WaveConstantNode(base.MaxwellSimNode):
@events.computes_output_socket( @events.computes_output_socket(
'Freq', 'Freq',
kind=ct.FlowKind.LazyArrayRange, kind=ct.FlowKind.Range,
input_sockets={'WL', 'Freq'}, input_sockets={'WL', 'Freq'},
input_socket_kinds={ input_socket_kinds={
'WL': ct.FlowKind.LazyArrayRange, 'WL': ct.FlowKind.Range,
'Freq': ct.FlowKind.LazyArrayRange, 'Freq': ct.FlowKind.Range,
}, },
input_sockets_optional={'WL': True, 'Freq': True}, input_sockets_optional={'WL': True, 'Freq': True},
) )
@ -205,7 +201,7 @@ class WaveConstantNode(base.MaxwellSimNode):
return input_sockets['Freq'] return input_sockets['Freq']
wl = input_sockets['WL'] wl = input_sockets['WL']
return ct.LazyArrayRangeFlow( return ct.RangeFlow(
start=spux.scale_to_unit( start=spux.scale_to_unit(
sci_constants.vac_speed_of_light / (wl.stop * wl.unit), spux.THz sci_constants.vac_speed_of_light / (wl.stop * wl.unit), spux.THz
), ),

View File

@ -115,11 +115,11 @@ class LibraryMediumNode(base.MaxwellSimNode):
output_sockets: typ.ClassVar = { output_sockets: typ.ClassVar = {
'Medium': sockets.MaxwellMediumSocketDef(), 'Medium': sockets.MaxwellMediumSocketDef(),
'Valid Freqs': sockets.ExprSocketDef( 'Valid Freqs': sockets.ExprSocketDef(
active_kind=ct.FlowKind.LazyArrayRange, active_kind=ct.FlowKind.Range,
physical_type=spux.PhysicalType.Freq, physical_type=spux.PhysicalType.Freq,
), ),
'Valid WLs': sockets.ExprSocketDef( 'Valid WLs': sockets.ExprSocketDef(
active_kind=ct.FlowKind.LazyArrayRange, active_kind=ct.FlowKind.Range,
physical_type=spux.PhysicalType.Length, physical_type=spux.PhysicalType.Length,
), ),
} }
@ -254,11 +254,11 @@ class LibraryMediumNode(base.MaxwellSimNode):
@events.computes_output_socket( @events.computes_output_socket(
'Valid Freqs', 'Valid Freqs',
kind=ct.FlowKind.LazyArrayRange, kind=ct.FlowKind.Range,
props={'freq_range'}, props={'freq_range'},
) )
def compute_valid_freqs_lazy(self, props) -> sp.Expr: def compute_valid_freqs_lazy(self, props) -> sp.Expr:
return ct.LazyArrayRangeFlow( return ct.RangeFlow(
start=props['freq_range'][0] / spux.THz, start=props['freq_range'][0] / spux.THz,
stop=props['freq_range'][1] / spux.THz, stop=props['freq_range'][1] / spux.THz,
steps=0, steps=0,
@ -268,11 +268,11 @@ class LibraryMediumNode(base.MaxwellSimNode):
@events.computes_output_socket( @events.computes_output_socket(
'Valid WLs', 'Valid WLs',
kind=ct.FlowKind.LazyArrayRange, kind=ct.FlowKind.Range,
props={'wl_range'}, props={'wl_range'},
) )
def compute_valid_wls_lazy(self, props) -> sp.Expr: def compute_valid_wls_lazy(self, props) -> sp.Expr:
return ct.LazyArrayRangeFlow( return ct.RangeFlow(
start=props['wl_range'][0] / spu.nm, start=props['wl_range'][0] / spu.nm,
stop=props['wl_range'][0] / spu.nm, stop=props['wl_range'][0] / spu.nm,
steps=0, steps=0,

View File

@ -63,7 +63,7 @@ class EHFieldMonitorNode(base.MaxwellSimNode):
input_socket_sets: typ.ClassVar = { input_socket_sets: typ.ClassVar = {
'Freq Domain': { 'Freq Domain': {
'Freqs': sockets.ExprSocketDef( 'Freqs': sockets.ExprSocketDef(
active_kind=ct.FlowKind.LazyArrayRange, active_kind=ct.FlowKind.Range,
physical_type=spux.PhysicalType.Freq, physical_type=spux.PhysicalType.Freq,
default_unit=spux.THz, default_unit=spux.THz,
default_min=374.7406, ## 800nm default_min=374.7406, ## 800nm
@ -73,7 +73,7 @@ class EHFieldMonitorNode(base.MaxwellSimNode):
}, },
'Time Domain': { 'Time Domain': {
't Range': sockets.ExprSocketDef( 't Range': sockets.ExprSocketDef(
active_kind=ct.FlowKind.LazyArrayRange, active_kind=ct.FlowKind.Range,
physical_type=spux.PhysicalType.Time, physical_type=spux.PhysicalType.Time,
default_unit=spu.picosecond, default_unit=spu.picosecond,
default_min=0, default_min=0,
@ -119,7 +119,7 @@ class EHFieldMonitorNode(base.MaxwellSimNode):
'Freqs', 'Freqs',
}, },
input_socket_kinds={ input_socket_kinds={
'Freqs': ct.FlowKind.LazyArrayRange, 'Freqs': ct.FlowKind.Range,
}, },
unit_systems={'Tidy3DUnits': ct.UNITS_TIDY3D}, unit_systems={'Tidy3DUnits': ct.UNITS_TIDY3D},
scale_input_sockets={ scale_input_sockets={
@ -160,7 +160,7 @@ class EHFieldMonitorNode(base.MaxwellSimNode):
't Stride', 't Stride',
}, },
input_socket_kinds={ input_socket_kinds={
't Range': ct.FlowKind.LazyArrayRange, 't Range': ct.FlowKind.Range,
}, },
unit_systems={'Tidy3DUnits': ct.UNITS_TIDY3D}, unit_systems={'Tidy3DUnits': ct.UNITS_TIDY3D},
scale_input_sockets={ scale_input_sockets={

View File

@ -63,7 +63,7 @@ class PowerFluxMonitorNode(base.MaxwellSimNode):
input_socket_sets: typ.ClassVar = { input_socket_sets: typ.ClassVar = {
'Freq Domain': { 'Freq Domain': {
'Freqs': sockets.ExprSocketDef( 'Freqs': sockets.ExprSocketDef(
active_kind=ct.FlowKind.LazyArrayRange, active_kind=ct.FlowKind.Range,
physical_type=spux.PhysicalType.Freq, physical_type=spux.PhysicalType.Freq,
default_unit=spux.THz, default_unit=spux.THz,
default_min=374.7406, ## 800nm default_min=374.7406, ## 800nm
@ -73,7 +73,7 @@ class PowerFluxMonitorNode(base.MaxwellSimNode):
}, },
'Time Domain': { 'Time Domain': {
't Range': sockets.ExprSocketDef( 't Range': sockets.ExprSocketDef(
active_kind=ct.FlowKind.LazyArrayRange, active_kind=ct.FlowKind.Range,
physical_type=spux.PhysicalType.Time, physical_type=spux.PhysicalType.Time,
default_unit=spu.picosecond, default_unit=spu.picosecond,
default_min=0, default_min=0,
@ -137,7 +137,7 @@ class PowerFluxMonitorNode(base.MaxwellSimNode):
'Freqs', 'Freqs',
}, },
input_socket_kinds={ input_socket_kinds={
'Freqs': ct.FlowKind.LazyArrayRange, 'Freqs': ct.FlowKind.Range,
}, },
unit_systems={'Tidy3DUnits': ct.UNITS_TIDY3D}, unit_systems={'Tidy3DUnits': ct.UNITS_TIDY3D},
scale_input_sockets={ scale_input_sockets={

View File

@ -58,7 +58,7 @@ class PermittivityMonitorNode(base.MaxwellSimNode):
abs_min=0, abs_min=0,
), ),
'Freqs': sockets.ExprSocketDef( 'Freqs': sockets.ExprSocketDef(
active_kind=ct.FlowKind.LazyArrayRange, active_kind=ct.FlowKind.Range,
physical_type=spux.PhysicalType.Freq, physical_type=spux.PhysicalType.Freq,
default_unit=spux.THz, default_unit=spux.THz,
default_min=374.7406, ## 800nm default_min=374.7406, ## 800nm
@ -87,7 +87,7 @@ class PermittivityMonitorNode(base.MaxwellSimNode):
'Freqs', 'Freqs',
}, },
input_socket_kinds={ input_socket_kinds={
'Freqs': ct.FlowKind.LazyArrayRange, 'Freqs': ct.FlowKind.Range,
}, },
unit_systems={'Tidy3DUnits': ct.UNITS_TIDY3D}, unit_systems={'Tidy3DUnits': ct.UNITS_TIDY3D},
scale_input_sockets={ scale_input_sockets={

View File

@ -74,7 +74,7 @@ class TemporalShapeNode(base.MaxwellSimNode):
}, },
'Symbolic': { 'Symbolic': {
't Range': sockets.ExprSocketDef( 't Range': sockets.ExprSocketDef(
active_kind=ct.FlowKind.LazyArrayRange, active_kind=ct.FlowKind.Range,
physical_type=spux.PhysicalType.Time, physical_type=spux.PhysicalType.Time,
default_unit=spu.picosecond, default_unit=spu.picosecond,
default_min=0, default_min=0,
@ -132,7 +132,7 @@ class TemporalShapeNode(base.MaxwellSimNode):
'Envelope', 'Envelope',
}, },
input_socket_kinds={ input_socket_kinds={
't Range': ct.FlowKind.LazyArrayRange, 't Range': ct.FlowKind.Range,
'Envelope': ct.FlowKind.LazyValueFunc, 'Envelope': ct.FlowKind.LazyValueFunc,
}, },
input_sockets_optional={ input_sockets_optional={

View File

@ -551,9 +551,9 @@ class MaxwellSimSocket(bpy.types.NodeSocket, bl_instance.BLInstance):
msg = f'Socket {self.bl_label} {self.socket_type}): Tried to set "ct.FlowKind.LazyValueFunc", but socket does not define it' msg = f'Socket {self.bl_label} {self.socket_type}): Tried to set "ct.FlowKind.LazyValueFunc", but socket does not define it'
raise NotImplementedError(msg) raise NotImplementedError(msg)
# LazyArrayRange # Range
@property @property
def lazy_array_range(self) -> ct.LazyArrayRangeFlow: def lazy_range(self) -> ct.RangeFlow:
"""Throws a descriptive error. """Throws a descriptive error.
Notes: Notes:
@ -564,8 +564,8 @@ class MaxwellSimSocket(bpy.types.NodeSocket, bl_instance.BLInstance):
""" """
return ct.FlowSignal.NoFlow return ct.FlowSignal.NoFlow
@lazy_array_range.setter @lazy_range.setter
def lazy_array_range(self, value: ct.LazyArrayRangeFlow) -> None: def lazy_range(self, value: ct.RangeFlow) -> None:
"""Throws a descriptive error. """Throws a descriptive error.
Notes: Notes:
@ -574,7 +574,7 @@ class MaxwellSimSocket(bpy.types.NodeSocket, bl_instance.BLInstance):
Raises: Raises:
NotImplementedError: When used without being overridden. NotImplementedError: When used without being overridden.
""" """
msg = f'Socket {self.bl_label} {self.socket_type}): Tried to set "ct.FlowKind.LazyArrayRange", but socket does not define it' msg = f'Socket {self.bl_label} {self.socket_type}): Tried to set "ct.FlowKind.Range", but socket does not define it'
raise NotImplementedError(msg) raise NotImplementedError(msg)
#################### ####################
@ -596,7 +596,7 @@ class MaxwellSimSocket(bpy.types.NodeSocket, bl_instance.BLInstance):
ct.FlowKind.Value: lambda: self.value, ct.FlowKind.Value: lambda: self.value,
ct.FlowKind.Array: lambda: self.array, ct.FlowKind.Array: lambda: self.array,
ct.FlowKind.LazyValueFunc: lambda: self.lazy_value_func, ct.FlowKind.LazyValueFunc: lambda: self.lazy_value_func,
ct.FlowKind.LazyArrayRange: lambda: self.lazy_array_range, ct.FlowKind.Range: lambda: self.lazy_range,
ct.FlowKind.Params: lambda: self.params, ct.FlowKind.Params: lambda: self.params,
ct.FlowKind.Info: lambda: self.info, ct.FlowKind.Info: lambda: self.info,
} }
@ -783,7 +783,7 @@ class MaxwellSimSocket(bpy.types.NodeSocket, bl_instance.BLInstance):
{ {
ct.FlowKind.Value: self.draw_value, ct.FlowKind.Value: self.draw_value,
ct.FlowKind.Array: self.draw_array, ct.FlowKind.Array: self.draw_array,
ct.FlowKind.LazyArrayRange: self.draw_lazy_array_range, ct.FlowKind.Range: self.draw_lazy_range,
ct.FlowKind.LazyValueFunc: self.draw_lazy_value_func, ct.FlowKind.LazyValueFunc: self.draw_lazy_value_func,
}[self.active_kind](col) }[self.active_kind](col)
@ -894,11 +894,11 @@ class MaxwellSimSocket(bpy.types.NodeSocket, bl_instance.BLInstance):
col: Target for defining UI elements. col: Target for defining UI elements.
""" """
def draw_lazy_array_range(self, col: bpy.types.UILayout) -> None: def draw_lazy_range(self, col: bpy.types.UILayout) -> None:
"""Draws the socket lazy array range on its own line. """Draws the socket lazy array range on its own line.
Notes: Notes:
Should be overriden by individual socket classes, if they have an editable `FlowKind.LazyArrayRange`. Should be overriden by individual socket classes, if they have an editable `FlowKind.Range`.
Parameters: Parameters:
col: Target for defining UI elements. col: Target for defining UI elements.

View File

@ -169,7 +169,7 @@ class ExprBLSocket(base.MaxwellSimSocket):
((0.0, 0.0), (0.0, 0.0), (0.0, 0.0)), float_prec=4 ((0.0, 0.0), (0.0, 0.0), (0.0, 0.0)), float_prec=4
) )
# UI: LazyArrayRange # UI: Range
steps: int = bl_cache.BLField(2, soft_min=2, abs_min=0) steps: int = bl_cache.BLField(2, soft_min=2, abs_min=0)
scaling: ct.ScalingMode = bl_cache.BLField(ct.ScalingMode.Lin) scaling: ct.ScalingMode = bl_cache.BLField(ct.ScalingMode.Lin)
## Expression ## Expression
@ -248,7 +248,7 @@ class ExprBLSocket(base.MaxwellSimSocket):
and not self.symbols and not self.symbols
): ):
self.value = self.value.subs({self.unit: prev_unit}) self.value = self.value.subs({self.unit: prev_unit})
self.lazy_array_range = self.lazy_array_range.correct_unit(prev_unit) self.lazy_range = self.lazy_range.correct_unit(prev_unit)
self.prev_unit = self.active_unit self.prev_unit = self.active_unit
@ -454,20 +454,20 @@ class ExprBLSocket(base.MaxwellSimSocket):
) )
#################### ####################
# - FlowKind: LazyArrayRange # - FlowKind: Range
#################### ####################
@property @property
def lazy_array_range(self) -> ct.LazyArrayRangeFlow: def lazy_range(self) -> ct.RangeFlow:
"""Return the not-yet-computed uniform array defined by the socket. """Return the not-yet-computed uniform array defined by the socket.
Notes: Notes:
Called to compute the internal `FlowKind.LazyArrayRange` of this socket. Called to compute the internal `FlowKind.Range` of this socket.
Return: Return:
The range of lengths, which uses no symbols. The range of lengths, which uses no symbols.
""" """
if self.symbols: if self.symbols:
return ct.LazyArrayRangeFlow( return ct.RangeFlow(
start=self.raw_min_sp, start=self.raw_min_sp,
stop=self.raw_max_sp, stop=self.raw_max_sp,
steps=self.steps, steps=self.steps,
@ -493,7 +493,7 @@ class ExprBLSocket(base.MaxwellSimSocket):
], ],
}[self.mathtype]() }[self.mathtype]()
return ct.LazyArrayRangeFlow( return ct.RangeFlow(
start=min_bound, start=min_bound,
stop=max_bound, stop=max_bound,
steps=self.steps, steps=self.steps,
@ -501,12 +501,12 @@ class ExprBLSocket(base.MaxwellSimSocket):
unit=self.unit, unit=self.unit,
) )
@lazy_array_range.setter @lazy_range.setter
def lazy_array_range(self, value: ct.LazyArrayRangeFlow) -> None: def lazy_range(self, value: ct.RangeFlow) -> None:
"""Set the not-yet-computed uniform array defined by the socket. """Set the not-yet-computed uniform array defined by the socket.
Notes: Notes:
Called to compute the internal `FlowKind.LazyArrayRange` of this socket. Called to compute the internal `FlowKind.Range` of this socket.
""" """
self.steps = value.steps self.steps = value.steps
self.scaling = value.scaling self.scaling = value.scaling
@ -609,7 +609,7 @@ class ExprBLSocket(base.MaxwellSimSocket):
The output name/size/mathtype/unit corresponds directly the `ExprSocket`. The output name/size/mathtype/unit corresponds directly the `ExprSocket`.
If `self.symbols` has entries, then these will propagate as dimensions with unresolvable `LazyArrayRangeFlow` index descriptions. If `self.symbols` has entries, then these will propagate as dimensions with unresolvable `RangeFlow` index descriptions.
The index range will be $(-\infty,\infty)$, with $0$ steps and no unit. The index range will be $(-\infty,\infty)$, with $0$ steps and no unit.
The order/naming matches `self.params` and `self.lazy_value_func`. The order/naming matches `self.params` and `self.lazy_value_func`.
@ -619,7 +619,7 @@ class ExprBLSocket(base.MaxwellSimSocket):
return ct.InfoFlow( return ct.InfoFlow(
dim_names=[sym.name for sym in self.sorted_symbols], dim_names=[sym.name for sym in self.sorted_symbols],
dim_idx={ dim_idx={
sym.name: ct.LazyArrayRangeFlow( sym.name: ct.RangeFlow(
start=-sp.oo if _check_sym_oo(sym) else -sp.zoo, start=-sp.oo if _check_sym_oo(sym) else -sp.zoo,
stop=sp.oo if _check_sym_oo(sym) else sp.zoo, stop=sp.oo if _check_sym_oo(sym) else sp.zoo,
steps=0, steps=0,
@ -805,13 +805,13 @@ class ExprBLSocket(base.MaxwellSimSocket):
for sym in self.symbols: for sym in self.symbols:
col.label(text=spux.pretty_symbol(sym)) col.label(text=spux.pretty_symbol(sym))
def draw_lazy_array_range(self, col: bpy.types.UILayout) -> None: def draw_lazy_range(self, col: bpy.types.UILayout) -> None:
"""Draw the socket body for a simple, uniform range of values between two values/expressions. """Draw the socket body for a simple, uniform range of values between two values/expressions.
Drawn when `self.active_kind == FlowKind.LazyArrayRange`. Drawn when `self.active_kind == FlowKind.Range`.
Notes: Notes:
If `self.steps == 0`, then the `LazyArrayRange` is considered to have a to-be-determined number of steps. If `self.steps == 0`, then the `Range` is considered to have a to-be-determined number of steps.
As such, `self.steps` won't be exposed in the UI. As such, `self.steps` won't be exposed in the UI.
""" """
if self.symbols: if self.symbols:
@ -925,7 +925,7 @@ class ExprSocketDef(base.SocketDef):
socket_type: ct.SocketType = ct.SocketType.Expr socket_type: ct.SocketType = ct.SocketType.Expr
active_kind: typ.Literal[ active_kind: typ.Literal[
ct.FlowKind.Value, ct.FlowKind.Value,
ct.FlowKind.LazyArrayRange, ct.FlowKind.Range,
ct.FlowKind.Array, ct.FlowKind.Array,
ct.FlowKind.LazyValueFunc, ct.FlowKind.LazyValueFunc,
] = ct.FlowKind.Value ] = ct.FlowKind.Value
@ -947,7 +947,7 @@ class ExprSocketDef(base.SocketDef):
abs_min: spux.SympyExpr | None = None abs_min: spux.SympyExpr | None = None
abs_max: spux.SympyExpr | None = None abs_max: spux.SympyExpr | None = None
# FlowKind: LazyArrayRange # FlowKind: Range
default_min: spux.SympyExpr = 0 default_min: spux.SympyExpr = 0
default_max: spux.SympyExpr = 1 default_max: spux.SympyExpr = 1
default_steps: int = 2 default_steps: int = 2
@ -1107,7 +1107,7 @@ class ExprSocketDef(base.SocketDef):
return self return self
#################### ####################
# - Parse FlowKind.LazyArrayRange # - Parse FlowKind.Range
#################### ####################
@pyd.field_validator('default_steps') @pyd.field_validator('default_steps')
@classmethod @classmethod
@ -1120,8 +1120,8 @@ class ExprSocketDef(base.SocketDef):
return v return v
@pyd.model_validator(mode='after') @pyd.model_validator(mode='after')
def parse_default_lazy_array_range_numbers(self) -> typ.Self: def parse_default_lazy_range_numbers(self) -> typ.Self:
"""Guarantees that the default `ct.LazyArrayRange` bounds are sympy expressions. """Guarantees that the default `ct.Range` bounds are sympy expressions.
If `self.default_value` is a scalar Python type, it will be coerced into the corresponding Sympy type using `sp.S`. If `self.default_value` is a scalar Python type, it will be coerced into the corresponding Sympy type using `sp.S`.
@ -1150,7 +1150,7 @@ class ExprSocketDef(base.SocketDef):
if mathtype_guide == 'expr': if mathtype_guide == 'expr':
dv_mathtype = spux.MathType.from_expr(bound) dv_mathtype = spux.MathType.from_expr(bound)
if not self.mathtype.is_compatible(dv_mathtype): if not self.mathtype.is_compatible(dv_mathtype):
msg = f'ExprSocket: Mathtype {dv_mathtype} of a default LazyArrayRange min or max expression {bound} (type {type(self.default_value)}) is incompatible with socket MathType {self.mathtype}' msg = f'ExprSocket: Mathtype {dv_mathtype} of a default Range min or max expression {bound} (type {type(self.default_value)}) is incompatible with socket MathType {self.mathtype}'
raise ValueError(msg) raise ValueError(msg)
if new_bounds[0] is not None: if new_bounds[0] is not None:
@ -1161,8 +1161,8 @@ class ExprSocketDef(base.SocketDef):
return self return self
@pyd.model_validator(mode='after') @pyd.model_validator(mode='after')
def parse_default_lazy_array_range_size(self) -> typ.Self: def parse_default_lazy_range_size(self) -> typ.Self:
"""Guarantees that the default `ct.LazyArrayRange` bounds are unshaped. """Guarantees that the default `ct.Range` bounds are unshaped.
Raises: Raises:
ValueError: If `self.default_min` or `self.default_max` are shaped. ValueError: If `self.default_min` or `self.default_max` are shaped.
@ -1170,16 +1170,16 @@ class ExprSocketDef(base.SocketDef):
# Check ActiveKind and Size # Check ActiveKind and Size
## -> NOTE: This doesn't protect against dynamic changes to either. ## -> NOTE: This doesn't protect against dynamic changes to either.
if ( if (
self.active_kind == ct.FlowKind.LazyArrayRange self.active_kind == ct.FlowKind.Range
and self.size is not spux.NumberSize1D.Scalar and self.size is not spux.NumberSize1D.Scalar
): ):
msg = "Can't have a non-Scalar size when LazyArrayRange is set as the active kind." msg = "Can't have a non-Scalar size when Range is set as the active kind."
raise ValueError(msg) raise ValueError(msg)
# Check that Bounds are Shapeless # Check that Bounds are Shapeless
for bound in [self.default_min, self.default_max]: for bound in [self.default_min, self.default_max]:
if hasattr(bound, 'shape'): if hasattr(bound, 'shape'):
msg = f'ExprSocket: A default bound {bound} (type {type(bound)}) has a shape, but LazyArrayRange supports no shape in ExprSockets.' msg = f'ExprSocket: A default bound {bound} (type {type(bound)}) has a shape, but Range supports no shape in ExprSockets.'
raise ValueError(msg) raise ValueError(msg)
return self return self
@ -1235,9 +1235,9 @@ class ExprSocketDef(base.SocketDef):
bl_socket.prev_unit = bl_socket.active_unit bl_socket.prev_unit = bl_socket.active_unit
# FlowKind.LazyArrayRange # FlowKind.Range
## -> We can directly pass None to unit. ## -> We can directly pass None to unit.
bl_socket.lazy_array_range = ct.LazyArrayRangeFlow( bl_socket.lazy_range = ct.RangeFlow(
start=self.default_min, start=self.default_min,
stop=self.default_max, stop=self.default_max,
steps=self.default_steps, steps=self.default_steps,