bluemira.radiation_transport.neutronics.slicing =============================================== .. py:module:: bluemira.radiation_transport.neutronics.slicing .. autoapi-nested-parse:: Oversees the conversion from bluemira wires into pre-cells, then into csg. Classes ------- .. autoapisummary:: bluemira.radiation_transport.neutronics.slicing.PanelsAndExteriorCurve bluemira.radiation_transport.neutronics.slicing.DivertorWireAndExteriorCurve Functions --------- .. autoapisummary:: bluemira.radiation_transport.neutronics.slicing.cut_curve bluemira.radiation_transport.neutronics.slicing.check_and_breakdown_wire bluemira.radiation_transport.neutronics.slicing.turned_morethan_180 bluemira.radiation_transport.neutronics.slicing.deviate_less_than bluemira.radiation_transport.neutronics.slicing.straight_lines_deviate_less_than bluemira.radiation_transport.neutronics.slicing.break_wire_into_convex_chunks Module Contents --------------- .. py:function:: cut_curve(cut_points: list[numpy.typing.NDArray], wire: bluemira.geometry.wire.BluemiraWire, discretisation_level: int, *, reverse: bool = False) -> collections.abc.Iterator[numpy.typing.NDArray[numpy.float64]] Generator to cut a closed BluemiraWire to size. Current implementation is to yield a parameter range for every sequential cut-point pair. Subject to change of implementation in the future when issue 3038 is fixed. :param cut_points: A list of at least 3 points, presumed to be lying on the wire, that we want to cut the wire at. :param wire: The wire that we want to cut up. :param discretisation_level: We yield a list of points of len==discretisation_level, such that we can build a wire made of (discretisation_level-1) straight lines to approximate each segment. :param reverse: Whether we want the neutron spectrum to go in the increasing or the decreasing direction. :Yields: *params_range* -- For each segment, yield the values of the parametric variable t such that `[wire.value_at(t) for t in params_range]` is a list of points (sufficient to built up a series of (discretisation_level-1) straight lines that approximate that segment) :raises GeometryError: Point inconsitencies .. py:function:: check_and_breakdown_wire(wire: bluemira.geometry.wire.BluemiraWire) -> bluemira.radiation_transport.neutronics.wires.WireInfoList Raise GeometryError if the BluemiraWire has an unexpected data storage structure. Then, get only the key information (start/end points and tangent) of each segment of the wire. :returns: List of WireInfo, each one representing a segment of the wire. :raises GeometryError: Wire has too many edges .. py:function:: turned_morethan_180(xyz_vector1: collections.abc.Sequence[float], xyz_vector2: collections.abc.Sequence[float], direction_sign: int) -> bool Checked if one needs to rotate vector 1 by more than 180° in the specified direction by more than 180° to align with vector 2. :param xyz_vector1: xyz array of where the vector points. :type xyz_vector1: Sequence[float] :param xyz_vector2: xyz array of where the vector points. :type xyz_vector2: Sequence[float] :param direction_sign: +1: evaluate rotation required in the counter-clockwise direction. -1: evaluate rotation required in the clockwise direction. :type direction_sign: signed integer :returns: boolean :raises GeometryError: Tangent not connected to plane .. py:function:: deviate_less_than(xyz_vector1: collections.abc.Sequence[float], xyz_vector2: collections.abc.Sequence[float], threshold_degrees: float) -> bool Check if two vector's angles less than a certain threshold angle (in degrees). :returns: boolean .. py:function:: straight_lines_deviate_less_than(info1: bluemira.radiation_transport.neutronics.wires.WireInfo, info2: bluemira.radiation_transport.neutronics.wires.WireInfo, threshold_degrees: float) -> bool Check that both lines are straight lines, then check if deviation is less than threshold_degrees or not. :returns: boolean .. py:function:: break_wire_into_convex_chunks(wire: bluemira.geometry.wire.BluemiraWire, curvature_sign: int = -1) -> list[bluemira.radiation_transport.neutronics.wires.WireInfoList] Break a wire up into several convex wires. Merge if they are almost collinear. :param wire: :param curvature_sign: if it's -1: we allow each convex chunk's wire to turn right only. if it's 1: we allow each convex chunk's wire to turn left only. :returns: a list of WireInfos :rtype: convex_chunks .. py:class:: PanelsAndExteriorCurve(panel_break_points: numpy.typing.NDArray[numpy.float64], vv_interior: bluemira.geometry.wire.BluemiraWire, vv_exterior: bluemira.geometry.wire.BluemiraWire) A collection of three objects, the first wall panels, the vacuum vessel interior curve, and the exterior curve. :param panel_break_points: numpy array of shape==(N, 2), showing the RZ coordinates of joining points between adjacent first wall panels, running in the clockwise direction, from the inboard divertor to the top, then down to the outboard divertor. :param vv_interior: The BluemiraWire representing the inside surface of the vacuum vessel. :param vv_exterior: The BluemiraWire representing the outside surface of the vacuum vessel. .. py:attribute:: vv_interior .. py:attribute:: vv_exterior .. py:attribute:: interior_panels .. py:method:: get_bisection_line(index: int) -> tuple[numpy.typing.NDArray[numpy.float64], numpy.typing.NDArray[numpy.float64]] Calculate the bisection line that separates two panels at breakpoint[i]. :param index: the n-th breakpoint that we want the bisection line to project from. (N.B. There are N+1 breakpoints for N panels.) Thus this is the last point of the n-th panel. :returns: * *line_origin* -- A point on the line bisecting the two panels at breakpoint[i]. * *line_direction* -- A vector tangent to the line bisecting the two panels at breakpoint[i]. Together, line_origin+p*line_direction = a parametric representation of the bisection line. .. py:method:: calculate_cut_points(starting_cut: numpy.typing.NDArray[numpy.float64] | None, ending_cut: numpy.typing.NDArray[numpy.float64] | None, snap_to_horizontal_angle: float) -> tuple[list[numpy.typing.NDArray[numpy.float64]], Ellipsis] Cut the curves according to some specified criteria: In general, a line would be drawn from each panel break point outwards towards the curves. This would form the cut line. The space between two neighbouring cut line makes a PreCell. Usually these cut's angle is the bisection of the normal angles of its neighbouring panels, but in special rules applies when snap_to_horizontal_angle is set to a value >0. Since there is only one neighbouring panel at the start break point and end break point, starting_cut and end_cut must be specified. If not, they are chosen to be horizontal cuts. :param snap_to_horizontal_angle: If the cutting plane is less than x degrees (°) away from horizontal, then snap it to horizontal. allowed range: [0, 90] :param starting_cut: Each is an ndarray with shape (2,), denoting the destination of the cut lines. The program cannot deduce what angle to cut the curves at these locations without extra user input. Therefore the user is able to use these options to specify the cut line's destination point for the first and final points respectively. For the first cut line, the cut line would start from interior_panels[0] and reach starting_cut. For the final cut line, the cut line would start from interior_panels[-1] and reach ending_cut. Both arguments have shape (2,) if given, representing the RZ coordinates. :param ending_cut: Each is an ndarray with shape (2,), denoting the destination of the cut lines. The program cannot deduce what angle to cut the curves at these locations without extra user input. Therefore the user is able to use these options to specify the cut line's destination point for the first and final points respectively. For the first cut line, the cut line would start from interior_panels[0] and reach starting_cut. For the final cut line, the cut line would start from interior_panels[-1] and reach ending_cut. Both arguments have shape (2,) if given, representing the RZ coordinates. :returns: * *vv_cut_points* -- cut points where the vacuum vessel interior wire is split * *exterior_cut_points* -- cut points where the vacuum vessel exterior wire is split .. py:method:: execute_curve_cut(discretisation_level: int, starting_cut: numpy.typing.NDArray[numpy.float64] | None = None, ending_cut: numpy.typing.NDArray[numpy.float64] | None = None, snap_to_horizontal_angle: float = 30.0) -> tuple[list[bluemira.geometry.wire.BluemiraWire], Ellipsis] Cut the exterior curve into a series and return them. This is the slowest part of the entire csg-creation process, because of the discretisation. :param snap_to_horizontal_angle: See :meth:`~bluemira.radiation_transport.neutronics.slicing.PanelsAndExteriorCurve.calculate_cut_points` :param starting_cut: See :meth:`~bluemira.radiation_transport.neutronics.slicing.PanelsAndExteriorCurve.calculate_cut_points` :param ending_cut: See :meth:`~bluemira.radiation_transport.neutronics.slicing.PanelsAndExteriorCurve.calculate_cut_points` :param discretisation_level: how many points to use to approximate the curve. :returns: * *vv_curve_segments* -- len=(discretisation_level-1) segments of the vacuum vessel interior curve forming each pre-cell's interior curve. * *exterior_curve_segments* -- len=(discretisation_level-1) segments of the vacuum vessel exterior curve forming each pre-cell's exterior curve. .. py:method:: approximate_curve(curve: bluemira.geometry.wire.BluemiraWire, param_range: numpy.typing.NDArray[numpy.float64], label='') -> bluemira.geometry.wire.BluemiraWire :staticmethod: Given params_range (an iterable of floats of len n between 0 to 1), create n-1 straight lines such that the n-th point corresponds to `curve.value_at(params_range[n])`. This implementation shall be replaced when issue #3038 gets resolved. :returns: A BluemiraWire made entirely out of segments of straight lines. .. py:method:: make_quadrilateral_pre_cell_array(discretisation_level: int = DISCRETISATION_LEVEL, starting_cut: numpy.typing.NDArray[numpy.float64] | None = None, ending_cut: numpy.typing.NDArray[numpy.float64] | None = None, snap_to_horizontal_angle: float = 30.0) -> bluemira.radiation_transport.neutronics.make_pre_cell.PreCellArray Cut the exterior curve up, so that it would act as the exterior side of the quadrilateral pre-cell. Then, the panel would act as the interior side of the pre-cell. The two remaining sides are the counter-clockwise and clockwise walls. The vacuum vessel interior surface is sandwiched between them. :returns: A pre-cell array where each pre-cell has exactly four sides. .. py:class:: DivertorWireAndExteriorCurve(divertor_wire: bluemira.geometry.wire.BluemiraWire, vv_interior: bluemira.geometry.wire.BluemiraWire, vv_exterior: bluemira.geometry.wire.BluemiraWire) A class to store a wire with a vacuum vessel interior curve and an exterior curve. .. py:attribute:: convex_segments :value: [] .. py:attribute:: key_points .. py:attribute:: tangents .. py:attribute:: center_point .. py:attribute:: vv_interior .. py:attribute:: vv_exterior .. py:method:: get_projection_line(prev_idx: int) -> tuple[numpy.typing.NDArray[numpy.float64], numpy.typing.NDArray[numpy.float64]] Get the the line bisecting the x and the y, represented as origin and direction. :param prev_idx: two convex chunks are involved when making a bisection line. This index refers to the smaller of these two chunks' indices. :returns: * *line_origin* -- a point on this line * *line_direction* -- a normal vector pointing in the direction of this line. .. py:method:: calculate_cut_points(starting_cut: numpy.typing.NDArray[numpy.float64] | None, ending_cut: numpy.typing.NDArray[numpy.float64] | None) -> tuple[list[numpy.typing.NDArray[numpy.float64]], Ellipsis] Cut the curves up into N segments to match the N convex chunks of the divertor. The space between two neighbouring cut line makes a DivertorPreCell. :param starting_cut: Each is an ndarray with shape (2,), denoting the destination of the cut lines. The program cannot deduce what angle to cut the curves at these locations without extra user input. Therefore the user is able to use these options to specify the cut line's destination point for the first and final points respectively. For the first cut line, the cut line would start from interior_panels[0] and reach starting_cut. For the final cut line, the cut line would start from interior_panels[-1] and reach ending_cut. Both arguments have shape (2,) if given, representing the RZ coordinates. :param ending_cut: Each is an ndarray with shape (2,), denoting the destination of the cut lines. The program cannot deduce what angle to cut the curves at these locations without extra user input. Therefore the user is able to use these options to specify the cut line's destination point for the first and final points respectively. For the first cut line, the cut line would start from interior_panels[0] and reach starting_cut. For the final cut line, the cut line would start from interior_panels[-1] and reach ending_cut. Both arguments have shape (2,) if given, representing the RZ coordinates. :returns: * *self.vv_cut_points* -- cut points where the vacuum vessel interior wire is split * *self.exterior_cut_points* -- cut points where the vacuum vessel exterior wire is split .. py:method:: execute_curve_cut(discretisation_level: int, starting_cut: numpy.typing.NDArray[numpy.float64] | None, ending_cut: numpy.typing.NDArray[numpy.float64] | None) -> tuple[list[bluemira.radiation_transport.neutronics.wires.WireInfoList], Ellipsis] Cut the vacuum vessel curves into a series return these segments. (Obsolete) ---------- Use the following table to decide whether the segments run clockwise or counter-clockwise. | | INCREASING = True | INCREASING = False | ------------------------------------------------------------ | reverse = False | clockwise | counter-clockwise | | reverse = False | counter-clockwise | clockwise | This is the slowest part of the entire csg-creation process, because of the discretisation. :param starting_cut: See :meth:`~bluemira.radiation_transport.neutronics.slicing.DivertorWireAndExteriorCurve.calculate_cut_points` :param ending_cut: See :meth:`~bluemira.radiation_transport.neutronics.slicing.DivertorWireAndExteriorCurve.calculate_cut_points` :param discretisation_level: how many points to use to approximate the curve. :returns: * *vv_curve_segments* -- list of WireInfoList describing the each pre-cell's vacuum vessel interior curve, with len=(discretisation_level-1) * *exterior_curve_segments* -- list of WireInfoList describing the each pre-cell's vacuum vessel exterior curve, with len=(discretisation_level-1) .. py:method:: approximate_curve(curve: bluemira.geometry.wire.BluemiraWire, param_range: numpy.typing.NDArray[numpy.float64]) -> bluemira.radiation_transport.neutronics.wires.WireInfoList :staticmethod: Given params_range (len(params_range)==n, 0<=params_range[i]<=1), create n-1 straight lines such that the n-th point corresponds to `curve.value_at(params_range[n])`. This implementation shall be updated/replaced when issue #3038 gets resolved. :returns: WireInfoList made of n different WireInfo's. .. py:method:: make_divertor_pre_cell_array(starting_cut: numpy.typing.NDArray[numpy.float64] | None = None, ending_cut: numpy.typing.NDArray[numpy.float64] | None = None, discretisation_level: int = DISCRETISATION_LEVEL) -> bluemira.radiation_transport.neutronics.make_pre_cell.DivertorPreCellArray Cut the exterior curve up, so that would act as the exterior side of the quadrilateral pre-cell. Then, the panel would act as the interior side of the pre-cell. The two remaining sides are the counter-clockwise and clockwise walls. The vv_interior curve would be sandwiched between these two. Ordering: The cells should run from inoboard to outboard. :param starting_cut: shape = (2,) :param ending_cut: shape = (2,) :param discretisation_level: integer: how many points to use to approximate each curve segment. :returns: An array of len=(discretisation_level+1) divertor pre-cells created by cutting the exterior curve.