ansys-systemcoupling-core 0.4.1__py3-none-any.whl → 0.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ansys-systemcoupling-core might be problematic. Click here for more details.
- ansys/systemcoupling/core/__init__.py +11 -5
- ansys/systemcoupling/core/adaptor/api_23_1/_clear_state.py +13 -0
- ansys/systemcoupling/core/adaptor/api_23_1/case_root.py +7 -1
- ansys/systemcoupling/core/adaptor/api_23_1/clear_state.py +4 -2
- ansys/systemcoupling/core/adaptor/api_23_1/show_plot.py +75 -0
- ansys/systemcoupling/core/adaptor/api_23_1/solution_root.py +7 -1
- ansys/systemcoupling/core/adaptor/api_23_2/_clear_state.py +13 -0
- ansys/systemcoupling/core/adaptor/api_23_2/case_root.py +7 -1
- ansys/systemcoupling/core/adaptor/api_23_2/clear_state.py +4 -2
- ansys/systemcoupling/core/adaptor/api_23_2/show_plot.py +75 -0
- ansys/systemcoupling/core/adaptor/api_23_2/solution_root.py +7 -1
- ansys/systemcoupling/core/adaptor/api_24_1/_clear_state.py +13 -0
- ansys/systemcoupling/core/adaptor/api_24_1/case_root.py +7 -1
- ansys/systemcoupling/core/adaptor/api_24_1/clear_state.py +4 -2
- ansys/systemcoupling/core/adaptor/api_24_1/show_plot.py +75 -0
- ansys/systemcoupling/core/adaptor/api_24_1/solution_root.py +7 -1
- ansys/systemcoupling/core/adaptor/api_24_2/_add_participant.py +80 -0
- ansys/systemcoupling/core/adaptor/api_24_2/_clear_state.py +13 -0
- ansys/systemcoupling/core/adaptor/api_24_2/_solve.py +13 -0
- ansys/systemcoupling/core/adaptor/api_24_2/abort.py +39 -0
- ansys/systemcoupling/core/adaptor/api_24_2/activate_hidden.py +46 -0
- ansys/systemcoupling/core/adaptor/api_24_2/add_aerodamping_data_transfers.py +43 -0
- ansys/systemcoupling/core/adaptor/api_24_2/add_data_transfer.py +190 -0
- ansys/systemcoupling/core/adaptor/api_24_2/add_data_transfer_by_display_names.py +191 -0
- ansys/systemcoupling/core/adaptor/api_24_2/add_expression_function.py +61 -0
- ansys/systemcoupling/core/adaptor/api_24_2/add_fsi_data_transfers.py +43 -0
- ansys/systemcoupling/core/adaptor/api_24_2/add_interface.py +77 -0
- ansys/systemcoupling/core/adaptor/api_24_2/add_interface_by_display_names.py +78 -0
- ansys/systemcoupling/core/adaptor/api_24_2/add_named_expression.py +42 -0
- ansys/systemcoupling/core/adaptor/api_24_2/add_ordered_data_transfers.py +32 -0
- ansys/systemcoupling/core/adaptor/api_24_2/add_participant.py +162 -0
- ansys/systemcoupling/core/adaptor/api_24_2/add_reference_frame.py +40 -0
- ansys/systemcoupling/core/adaptor/api_24_2/add_thermal_data_transfers.py +43 -0
- ansys/systemcoupling/core/adaptor/api_24_2/add_transformation.py +102 -0
- ansys/systemcoupling/core/adaptor/api_24_2/analysis_control.py +283 -0
- ansys/systemcoupling/core/adaptor/api_24_2/apip.py +33 -0
- ansys/systemcoupling/core/adaptor/api_24_2/ascii_output.py +44 -0
- ansys/systemcoupling/core/adaptor/api_24_2/attribute.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_2/attribute_child.py +54 -0
- ansys/systemcoupling/core/adaptor/api_24_2/automatic_alignment_options.py +46 -0
- ansys/systemcoupling/core/adaptor/api_24_2/available_ports.py +40 -0
- ansys/systemcoupling/core/adaptor/api_24_2/avoid_data_reconstruction.py +46 -0
- ansys/systemcoupling/core/adaptor/api_24_2/case_root.py +62 -0
- ansys/systemcoupling/core/adaptor/api_24_2/clear_state.py +18 -0
- ansys/systemcoupling/core/adaptor/api_24_2/connect_ensight_dvs.py +41 -0
- ansys/systemcoupling/core/adaptor/api_24_2/coupling_interface.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_2/coupling_interface_child.py +42 -0
- ansys/systemcoupling/core/adaptor/api_24_2/coupling_participant.py +23 -0
- ansys/systemcoupling/core/adaptor/api_24_2/coupling_participant_child.py +265 -0
- ansys/systemcoupling/core/adaptor/api_24_2/create_restart_point.py +29 -0
- ansys/systemcoupling/core/adaptor/api_24_2/data_transfer.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_2/data_transfer_child.py +187 -0
- ansys/systemcoupling/core/adaptor/api_24_2/delete_snapshot.py +28 -0
- ansys/systemcoupling/core/adaptor/api_24_2/delete_transformation.py +42 -0
- ansys/systemcoupling/core/adaptor/api_24_2/dimensionality.py +96 -0
- ansys/systemcoupling/core/adaptor/api_24_2/execution_control.py +246 -0
- ansys/systemcoupling/core/adaptor/api_24_2/execution_control_1.py +24 -0
- ansys/systemcoupling/core/adaptor/api_24_2/expression.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_2/expression_child.py +36 -0
- ansys/systemcoupling/core/adaptor/api_24_2/expression_function.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_2/expression_function_child.py +46 -0
- ansys/systemcoupling/core/adaptor/api_24_2/external_data_file.py +24 -0
- ansys/systemcoupling/core/adaptor/api_24_2/fluent_input.py +77 -0
- ansys/systemcoupling/core/adaptor/api_24_2/fmu_parameter.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_2/fmu_parameter_child.py +156 -0
- ansys/systemcoupling/core/adaptor/api_24_2/generate_input_file.py +41 -0
- ansys/systemcoupling/core/adaptor/api_24_2/get_add_data_transfer_group_commands.py +29 -0
- ansys/systemcoupling/core/adaptor/api_24_2/get_execution_command.py +30 -0
- ansys/systemcoupling/core/adaptor/api_24_2/get_machines.py +13 -0
- ansys/systemcoupling/core/adaptor/api_24_2/get_mode_shape_variables.py +29 -0
- ansys/systemcoupling/core/adaptor/api_24_2/get_region_names_for_participant.py +31 -0
- ansys/systemcoupling/core/adaptor/api_24_2/get_setup_summary.py +25 -0
- ansys/systemcoupling/core/adaptor/api_24_2/get_status_messages.py +52 -0
- ansys/systemcoupling/core/adaptor/api_24_2/get_supported_participant_types.py +13 -0
- ansys/systemcoupling/core/adaptor/api_24_2/get_thermal_data_transfer_options.py +32 -0
- ansys/systemcoupling/core/adaptor/api_24_2/get_transformation.py +43 -0
- ansys/systemcoupling/core/adaptor/api_24_2/global_stabilization.py +143 -0
- ansys/systemcoupling/core/adaptor/api_24_2/has_input_file_changed.py +36 -0
- ansys/systemcoupling/core/adaptor/api_24_2/import_system_coupling_input_file.py +36 -0
- ansys/systemcoupling/core/adaptor/api_24_2/initialize.py +27 -0
- ansys/systemcoupling/core/adaptor/api_24_2/instancing.py +23 -0
- ansys/systemcoupling/core/adaptor/api_24_2/instancing_child.py +62 -0
- ansys/systemcoupling/core/adaptor/api_24_2/interrupt.py +39 -0
- ansys/systemcoupling/core/adaptor/api_24_2/library.py +37 -0
- ansys/systemcoupling/core/adaptor/api_24_2/live_visualization.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_2/live_visualization_child.py +100 -0
- ansys/systemcoupling/core/adaptor/api_24_2/mapping_control.py +239 -0
- ansys/systemcoupling/core/adaptor/api_24_2/open.py +102 -0
- ansys/systemcoupling/core/adaptor/api_24_2/open_results_in_ensight.py +56 -0
- ansys/systemcoupling/core/adaptor/api_24_2/open_snapshot.py +37 -0
- ansys/systemcoupling/core/adaptor/api_24_2/output_control.py +134 -0
- ansys/systemcoupling/core/adaptor/api_24_2/parameter.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_2/parameter_child.py +56 -0
- ansys/systemcoupling/core/adaptor/api_24_2/partition_participants.py +138 -0
- ansys/systemcoupling/core/adaptor/api_24_2/properties.py +36 -0
- ansys/systemcoupling/core/adaptor/api_24_2/record_interactions.py +46 -0
- ansys/systemcoupling/core/adaptor/api_24_2/reference_frame.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_2/reference_frame_child.py +71 -0
- ansys/systemcoupling/core/adaptor/api_24_2/region.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_2/region_child.py +71 -0
- ansys/systemcoupling/core/adaptor/api_24_2/reload_expression_function_modules.py +14 -0
- ansys/systemcoupling/core/adaptor/api_24_2/results.py +89 -0
- ansys/systemcoupling/core/adaptor/api_24_2/save.py +51 -0
- ansys/systemcoupling/core/adaptor/api_24_2/save_snapshot.py +54 -0
- ansys/systemcoupling/core/adaptor/api_24_2/setup_root.py +251 -0
- ansys/systemcoupling/core/adaptor/api_24_2/show_plot.py +75 -0
- ansys/systemcoupling/core/adaptor/api_24_2/shutdown.py +25 -0
- ansys/systemcoupling/core/adaptor/api_24_2/side.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_2/side_child.py +56 -0
- ansys/systemcoupling/core/adaptor/api_24_2/solution_control.py +115 -0
- ansys/systemcoupling/core/adaptor/api_24_2/solution_root.py +122 -0
- ansys/systemcoupling/core/adaptor/api_24_2/solve.py +30 -0
- ansys/systemcoupling/core/adaptor/api_24_2/stabilization.py +157 -0
- ansys/systemcoupling/core/adaptor/api_24_2/start_participants.py +47 -0
- ansys/systemcoupling/core/adaptor/api_24_2/step.py +57 -0
- ansys/systemcoupling/core/adaptor/api_24_2/transformation.py +21 -0
- ansys/systemcoupling/core/adaptor/api_24_2/transformation_child.py +62 -0
- ansys/systemcoupling/core/adaptor/api_24_2/type.py +38 -0
- ansys/systemcoupling/core/adaptor/api_24_2/unmapped_value_options.py +158 -0
- ansys/systemcoupling/core/adaptor/api_24_2/update_control.py +43 -0
- ansys/systemcoupling/core/adaptor/api_24_2/update_participant.py +61 -0
- ansys/systemcoupling/core/adaptor/api_24_2/variable.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_2/variable_child.py +231 -0
- ansys/systemcoupling/core/adaptor/api_24_2/write_csv_chart_files.py +21 -0
- ansys/systemcoupling/core/adaptor/api_24_2/write_ensight.py +46 -0
- ansys/systemcoupling/core/adaptor/impl/injected_commands.py +228 -27
- ansys/systemcoupling/core/adaptor/impl/static_info.py +17 -0
- ansys/systemcoupling/core/adaptor/impl/syc_proxy.py +3 -0
- ansys/systemcoupling/core/adaptor/impl/syc_proxy_interface.py +4 -0
- ansys/systemcoupling/core/adaptor/impl/types.py +1 -1
- ansys/systemcoupling/core/charts/chart_datatypes.py +169 -0
- ansys/systemcoupling/core/charts/csv_chartdata.py +299 -0
- ansys/systemcoupling/core/charts/live_csv_datasource.py +87 -0
- ansys/systemcoupling/core/charts/message_dispatcher.py +84 -0
- ansys/systemcoupling/core/charts/plot_functions.py +92 -0
- ansys/systemcoupling/core/charts/plotdefinition_manager.py +303 -0
- ansys/systemcoupling/core/charts/plotter.py +343 -0
- ansys/systemcoupling/core/client/grpc_client.py +6 -1
- ansys/systemcoupling/core/participant/manager.py +25 -9
- ansys/systemcoupling/core/participant/protocol.py +1 -0
- ansys/systemcoupling/core/session.py +4 -4
- ansys/systemcoupling/core/syc_version.py +1 -1
- ansys/systemcoupling/core/util/file_transfer.py +4 -0
- ansys/systemcoupling/core/util/logging.py +1 -1
- {ansys_systemcoupling_core-0.4.1.dist-info → ansys_systemcoupling_core-0.6.dist-info}/METADATA +17 -16
- {ansys_systemcoupling_core-0.4.1.dist-info → ansys_systemcoupling_core-0.6.dist-info}/RECORD +148 -26
- {ansys_systemcoupling_core-0.4.1.dist-info → ansys_systemcoupling_core-0.6.dist-info}/LICENSE +0 -0
- {ansys_systemcoupling_core-0.4.1.dist-info → ansys_systemcoupling_core-0.6.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
import threading
|
|
24
|
+
from typing import Callable
|
|
25
|
+
|
|
26
|
+
from ansys.systemcoupling.core.charts.csv_chartdata import CsvChartDataReader
|
|
27
|
+
from ansys.systemcoupling.core.charts.live_csv_datasource import LiveCsvDataSource
|
|
28
|
+
from ansys.systemcoupling.core.charts.message_dispatcher import MessageDispatcher
|
|
29
|
+
from ansys.systemcoupling.core.charts.plotdefinition_manager import (
|
|
30
|
+
PlotDefinitionManager,
|
|
31
|
+
PlotSpec,
|
|
32
|
+
)
|
|
33
|
+
from ansys.systemcoupling.core.charts.plotter import Plotter
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def create_and_show_plot(spec: PlotSpec, csv_list: list[str]) -> Plotter:
|
|
37
|
+
assert len(spec.interfaces) == 1, "Plots currently only support one interface"
|
|
38
|
+
assert len(spec.interfaces) == len(csv_list)
|
|
39
|
+
|
|
40
|
+
manager = PlotDefinitionManager(spec)
|
|
41
|
+
reader = CsvChartDataReader(spec.interfaces[0].name, csv_list[0])
|
|
42
|
+
plotter = Plotter(manager)
|
|
43
|
+
|
|
44
|
+
reader.read_metadata()
|
|
45
|
+
plotter.set_metadata(reader.metadata)
|
|
46
|
+
|
|
47
|
+
reader.read_new_data()
|
|
48
|
+
data = reader.data
|
|
49
|
+
if reader.metadata.is_transient:
|
|
50
|
+
plotter.set_timestep_data(reader.timestep_data)
|
|
51
|
+
|
|
52
|
+
for line_series in data.series:
|
|
53
|
+
plotter.update_line_series(line_series)
|
|
54
|
+
|
|
55
|
+
plotter.show_plot(noblock=True)
|
|
56
|
+
return plotter
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def solve_with_live_plot(
|
|
60
|
+
spec: PlotSpec,
|
|
61
|
+
csv_list: list[str],
|
|
62
|
+
solve_func: Callable[[], None],
|
|
63
|
+
):
|
|
64
|
+
assert len(spec.interfaces) == 1, "Plots currently only support one interface"
|
|
65
|
+
assert len(spec.interfaces) == len(csv_list)
|
|
66
|
+
|
|
67
|
+
manager = PlotDefinitionManager(spec)
|
|
68
|
+
dispatcher = MessageDispatcher()
|
|
69
|
+
plotter = Plotter(manager, dispatcher.dispatch_messages)
|
|
70
|
+
dispatcher.set_plotter(plotter)
|
|
71
|
+
|
|
72
|
+
data_source = LiveCsvDataSource(
|
|
73
|
+
spec.interfaces[0].name, csv_list[0], dispatcher.put_msg
|
|
74
|
+
)
|
|
75
|
+
data_thread = threading.Thread(target=data_source.read_data)
|
|
76
|
+
|
|
77
|
+
def solve():
|
|
78
|
+
solve_func()
|
|
79
|
+
data_source.cancel()
|
|
80
|
+
|
|
81
|
+
solve_thread = threading.Thread(target=solve)
|
|
82
|
+
|
|
83
|
+
data_thread.start()
|
|
84
|
+
solve_thread.start()
|
|
85
|
+
|
|
86
|
+
plotter.show_animated()
|
|
87
|
+
data_source.cancel()
|
|
88
|
+
data_thread.join()
|
|
89
|
+
solve_thread.join()
|
|
90
|
+
|
|
91
|
+
# Show a non-blocking static plot
|
|
92
|
+
return create_and_show_plot(spec, csv_list)
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# Copyright (C) 2023 - 2024 ANSYS, Inc. and/or its affiliates.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
#
|
|
4
|
+
#
|
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
# furnished to do so, subject to the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
# copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
# SOFTWARE.
|
|
22
|
+
|
|
23
|
+
from dataclasses import dataclass, field
|
|
24
|
+
from typing import Optional
|
|
25
|
+
|
|
26
|
+
from ansys.systemcoupling.core.charts.chart_datatypes import InterfaceInfo, SeriesType
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class DataTransferSpec:
|
|
31
|
+
# It's not ideal, but we have to work in terms of display names for transfers,
|
|
32
|
+
# as that is all we have in the data (the CSV data, at least).
|
|
33
|
+
display_name: str
|
|
34
|
+
show_convergence: bool = True
|
|
35
|
+
show_transfer_values: bool = True
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@dataclass
|
|
39
|
+
class InterfaceSpec:
|
|
40
|
+
name: str
|
|
41
|
+
display_name: str
|
|
42
|
+
transfers: list[DataTransferSpec] = field(default_factory=list)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass
|
|
46
|
+
class PlotSpec:
|
|
47
|
+
interfaces: list[InterfaceSpec] = field(default_factory=list)
|
|
48
|
+
plot_time: bool = False
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
"""
|
|
52
|
+
Convergence subplot:
|
|
53
|
+
title - Data Transfer Convergence for <interface disp name>
|
|
54
|
+
x-axis label - Iteration/Time
|
|
55
|
+
y-axis label - RMS Change in Target Value
|
|
56
|
+
|
|
57
|
+
# x-data: []
|
|
58
|
+
y-data: [([], <label=transfer disp name>)]
|
|
59
|
+
|
|
60
|
+
# y-data - we actually want an index
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
Transfer values subplot:
|
|
64
|
+
title - <interface display name> - <transfer display name> (<value type>)
|
|
65
|
+
x-axis label: Iteration/time
|
|
66
|
+
y-axis label: <NOT SET>
|
|
67
|
+
|
|
68
|
+
y-data: [([], <label=source|tgt disp name + suffix)]
|
|
69
|
+
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@dataclass
|
|
74
|
+
class SubplotDefinition:
|
|
75
|
+
"""Various data - mainly title and label strings - used in the rendering of
|
|
76
|
+
a subplot.
|
|
77
|
+
|
|
78
|
+
Attributes
|
|
79
|
+
----------
|
|
80
|
+
title: str
|
|
81
|
+
The title of the subplot.
|
|
82
|
+
is_log_y: bool
|
|
83
|
+
Whether the y-axis is logarithmic.
|
|
84
|
+
x_axis_label: str
|
|
85
|
+
The label shown on the x-axis.
|
|
86
|
+
y_axis_label: str
|
|
87
|
+
The label shown on the y-axis. This is an empty string for convergence plots.
|
|
88
|
+
index: int = -1
|
|
89
|
+
The index of this subplot within the list of subplots in the current figure.
|
|
90
|
+
(In `matplotlib` terms it also indexes the corresponding ``Axes`` item in
|
|
91
|
+
the figure.)
|
|
92
|
+
series_labels: list[str] = field(default_factory=list)
|
|
93
|
+
Labels for each series of the subplot.
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
title: str
|
|
97
|
+
is_log_y: bool
|
|
98
|
+
x_axis_label: str
|
|
99
|
+
y_axis_label: str
|
|
100
|
+
index: int = -1
|
|
101
|
+
series_labels: list[str] = field(default_factory=list)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class PlotDefinitionManager:
|
|
105
|
+
def __init__(self, spec: PlotSpec):
|
|
106
|
+
self._plot_spec = spec
|
|
107
|
+
self._data_index_map: dict[str, dict[int, tuple[SubplotDefinition, int]]] = {}
|
|
108
|
+
self._conv_subplots: dict[str, SubplotDefinition] = {}
|
|
109
|
+
self._transfer_subplots: dict[tuple[str, str, int], SubplotDefinition] = {}
|
|
110
|
+
self._subplots: list[SubplotDefinition] = []
|
|
111
|
+
self._allocate_subplots()
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def subplots(self) -> list[SubplotDefinition]:
|
|
115
|
+
return self._subplots
|
|
116
|
+
|
|
117
|
+
def subplot_for_data_index(
|
|
118
|
+
self, interface_name: str, data_index: int
|
|
119
|
+
) -> tuple[Optional[SubplotDefinition], int]:
|
|
120
|
+
"""Return the subplot definition, and the line index within the
|
|
121
|
+
subplot, corresponding to a given ``data_index``.
|
|
122
|
+
|
|
123
|
+
The ``data_index`` is a "global" line index for the interface.
|
|
124
|
+
|
|
125
|
+
If there is no subplot corresponding to the provided index,
|
|
126
|
+
return a tuple ``(None, -1)``
|
|
127
|
+
"""
|
|
128
|
+
try:
|
|
129
|
+
return self._data_index_map[interface_name][data_index]
|
|
130
|
+
except KeyError:
|
|
131
|
+
return (None, -1)
|
|
132
|
+
|
|
133
|
+
def get_layout(self) -> tuple[int, int]:
|
|
134
|
+
nsubplot = len(self._subplots)
|
|
135
|
+
|
|
136
|
+
if nsubplot == 1:
|
|
137
|
+
ncol = 1
|
|
138
|
+
elif nsubplot < 6:
|
|
139
|
+
ncol = 2
|
|
140
|
+
elif nsubplot < 12:
|
|
141
|
+
ncol = 3
|
|
142
|
+
elif nsubplot < 18:
|
|
143
|
+
ncol = 4
|
|
144
|
+
elif nsubplot < 26:
|
|
145
|
+
ncol = 5
|
|
146
|
+
else:
|
|
147
|
+
raise ValueError(f"Too many subplots requested: {nsubplot}")
|
|
148
|
+
nrow = nsubplot // ncol
|
|
149
|
+
if nsubplot % ncol != 0:
|
|
150
|
+
nrow += 1
|
|
151
|
+
|
|
152
|
+
return (nrow, ncol)
|
|
153
|
+
|
|
154
|
+
def _allocate_subplots(self):
|
|
155
|
+
is_time = self._plot_spec.plot_time
|
|
156
|
+
conv_subplots = {}
|
|
157
|
+
transfer_subplots = {}
|
|
158
|
+
subplots = []
|
|
159
|
+
for interface in self._plot_spec.interfaces:
|
|
160
|
+
conv = SubplotDefinition(
|
|
161
|
+
title=f"Data transfer convergence on {interface.display_name}",
|
|
162
|
+
is_log_y=True,
|
|
163
|
+
x_axis_label="Time" if is_time else "Iteration",
|
|
164
|
+
y_axis_label="RMS Change in target value",
|
|
165
|
+
)
|
|
166
|
+
# Add this now so that it is before transfer values plots but we may end
|
|
167
|
+
# up removing it if none of the transfers add a convergence line to it
|
|
168
|
+
conv_index = len(subplots)
|
|
169
|
+
subplots.append(conv)
|
|
170
|
+
keep_conv = False
|
|
171
|
+
transfer_disambig: dict[str, int] = {}
|
|
172
|
+
for transfer in interface.transfers:
|
|
173
|
+
if transfer.display_name in transfer_disambig:
|
|
174
|
+
transfer_disambig[transfer.display_name] += 1
|
|
175
|
+
else:
|
|
176
|
+
transfer_disambig[transfer.display_name] = 0
|
|
177
|
+
if transfer.show_convergence:
|
|
178
|
+
keep_conv = True
|
|
179
|
+
if transfer.show_transfer_values:
|
|
180
|
+
transfer_value = SubplotDefinition(
|
|
181
|
+
# NB: <VALUETYPE> is a placeholder - substitute later from metadata info
|
|
182
|
+
title=f"{interface.display_name} - {transfer.display_name} (<VALUETYPE>)",
|
|
183
|
+
is_log_y=False,
|
|
184
|
+
x_axis_label="Time" if is_time else "Iteration",
|
|
185
|
+
y_axis_label="",
|
|
186
|
+
)
|
|
187
|
+
transfer_subplots[
|
|
188
|
+
(
|
|
189
|
+
interface.name,
|
|
190
|
+
transfer.display_name,
|
|
191
|
+
transfer_disambig[transfer.display_name],
|
|
192
|
+
)
|
|
193
|
+
] = transfer_value
|
|
194
|
+
subplots.append(transfer_value)
|
|
195
|
+
if keep_conv:
|
|
196
|
+
conv_subplots[interface.name] = conv
|
|
197
|
+
else:
|
|
198
|
+
subplots[conv_index] = None
|
|
199
|
+
# Clean out inactive convergence plots
|
|
200
|
+
self._subplots = [subplot for subplot in subplots if subplot is not None]
|
|
201
|
+
for i, subplot in enumerate(self._subplots):
|
|
202
|
+
subplot.index = i
|
|
203
|
+
self._conv_subplots: dict[str, SubplotDefinition] = conv_subplots
|
|
204
|
+
self._transfer_subplots: dict[tuple[str, str, int], SubplotDefinition] = (
|
|
205
|
+
transfer_subplots
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
def set_metadata(self, metadata: InterfaceInfo):
|
|
209
|
+
"""Reconcile the metadata for a single interface with the pre-allocated
|
|
210
|
+
sub-plots and set up any necessary data routing.
|
|
211
|
+
|
|
212
|
+
Typically, this data only starts to be provided once the raw plot data starts
|
|
213
|
+
being generated.
|
|
214
|
+
"""
|
|
215
|
+
|
|
216
|
+
# If a subset of transfers was specified in the plot spec, this is already
|
|
217
|
+
# implicitly accounted for in self._tranfer_subplots, which will contain only
|
|
218
|
+
# the active ones. However, some additional work has to be done to filter the
|
|
219
|
+
# transfers shown on the convergence subplot and we have to go back to the plot
|
|
220
|
+
# spec to get a list of active transfers.
|
|
221
|
+
active_transfers = []
|
|
222
|
+
for intf in self._plot_spec.interfaces:
|
|
223
|
+
if intf.name == metadata.name:
|
|
224
|
+
active_transfers = [trans.display_name for trans in intf.transfers]
|
|
225
|
+
break
|
|
226
|
+
if not active_transfers:
|
|
227
|
+
# TODO: should this be an exception?
|
|
228
|
+
return
|
|
229
|
+
|
|
230
|
+
# map from source data index to corresponding (subplot, line index within subplot)
|
|
231
|
+
data_index_map: dict[int, tuple[SubplotDefinition, int]] = {}
|
|
232
|
+
interface_name = metadata.name
|
|
233
|
+
iconv = 0
|
|
234
|
+
|
|
235
|
+
# Keep a running count of the transfer value lines associated with a given
|
|
236
|
+
# transfer. There will be multiple if the transfer variable has vector
|
|
237
|
+
# and or real/imag components. Note that a transfer is uniquely identified by a
|
|
238
|
+
# pair (transfer_name, int) because transfer names are not guaranteed to be unique.
|
|
239
|
+
# The integer is the "disambiguation_index" the transfer's TransferSeriesInfo.
|
|
240
|
+
transfer_value_line_count: dict[tuple[str, int], int] = {}
|
|
241
|
+
|
|
242
|
+
for transfer in metadata.transfer_info:
|
|
243
|
+
transfer_key = (
|
|
244
|
+
transfer.transfer_display_name,
|
|
245
|
+
transfer.disambiguation_index,
|
|
246
|
+
)
|
|
247
|
+
if transfer.series_type == SeriesType.CONVERGENCE:
|
|
248
|
+
if transfer.transfer_display_name not in active_transfers:
|
|
249
|
+
# We don't want this transfer on the convergence plot
|
|
250
|
+
continue
|
|
251
|
+
# Clear the entry in case transfer names are not unique. (If another transfer
|
|
252
|
+
# with the same name needs plotting, then it should appear as a second entry
|
|
253
|
+
# in active_transfers.)
|
|
254
|
+
active_transfers[
|
|
255
|
+
active_transfers.index(transfer.transfer_display_name)
|
|
256
|
+
] = ""
|
|
257
|
+
|
|
258
|
+
if conv_subplot := self._conv_subplots.get(interface_name):
|
|
259
|
+
data_index_map[transfer.data_index] = (conv_subplot, iconv)
|
|
260
|
+
# Add a new series list to y_data, and label to series_labels
|
|
261
|
+
# Both will be at position iconv of respective lists
|
|
262
|
+
# conv_subplot.y_data.append([])
|
|
263
|
+
conv_subplot.series_labels.append(transfer.transfer_display_name)
|
|
264
|
+
iconv += 1
|
|
265
|
+
else:
|
|
266
|
+
transfer_value_subplot = self._transfer_subplots.get(
|
|
267
|
+
(interface_name, transfer_key[0], transfer_key[1])
|
|
268
|
+
)
|
|
269
|
+
if transfer_value_subplot:
|
|
270
|
+
value_type = (
|
|
271
|
+
"Sum"
|
|
272
|
+
if transfer.series_type == SeriesType.SUM
|
|
273
|
+
else "Weighted Average"
|
|
274
|
+
)
|
|
275
|
+
transfer_value_subplot.title = transfer_value_subplot.title.replace(
|
|
276
|
+
"<VALUETYPE>", value_type
|
|
277
|
+
)
|
|
278
|
+
itransval = transfer_value_line_count.get(transfer_key, 0)
|
|
279
|
+
if not transfer.line_suffixes:
|
|
280
|
+
data_index_map[transfer.data_index] = (
|
|
281
|
+
transfer_value_subplot,
|
|
282
|
+
itransval,
|
|
283
|
+
)
|
|
284
|
+
transfer_value_subplot.series_labels.append(
|
|
285
|
+
transfer.participant_display_name
|
|
286
|
+
)
|
|
287
|
+
itransval += 1
|
|
288
|
+
transfer_value_line_count[transfer_key] = itransval
|
|
289
|
+
else:
|
|
290
|
+
for i, suffix in enumerate(transfer.line_suffixes):
|
|
291
|
+
data_index_map[transfer.data_index + i] = (
|
|
292
|
+
transfer_value_subplot,
|
|
293
|
+
itransval + i,
|
|
294
|
+
)
|
|
295
|
+
transfer_value_subplot.series_labels.append(
|
|
296
|
+
transfer.participant_display_name + suffix
|
|
297
|
+
)
|
|
298
|
+
transfer_value_line_count[transfer_key] = itransval + len(
|
|
299
|
+
transfer.line_suffixes
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
# This will be what allows us to update subplot data as new data received
|
|
303
|
+
self._data_index_map[interface_name] = data_index_map
|