ansys-systemcoupling-core 0.1.3__py3-none-any.whl → 0.3.0__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 +27 -17
- ansys/systemcoupling/core/adaptor/api_23_2/_add_participant.py +70 -0
- ansys/systemcoupling/core/adaptor/api_23_2/_solve.py +13 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_participant.py +38 -2
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/analysis_control.py +8 -0
- ansys/systemcoupling/core/adaptor/api_23_2/automatic_alignment_options.py +46 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/avoid_data_reconstruction.py +10 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/coupling_participant_child.py +1 -1
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/fmu_parameter_child.py +30 -0
- ansys/systemcoupling/core/adaptor/api_23_2/get_transformation.py +43 -0
- ansys/systemcoupling/core/adaptor/api_23_2/live_visualization.py +20 -0
- ansys/systemcoupling/core/adaptor/api_23_2/live_visualization_child.py +72 -0
- ansys/systemcoupling/core/adaptor/api_23_2/open_results_in_en_sight.py +56 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/output_control.py +6 -1
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/setup_root.py +55 -49
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/solution_root.py +48 -36
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/solve.py +1 -1
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/variable_child.py +31 -0
- ansys/systemcoupling/core/adaptor/api_24_1/_add_participant.py +70 -0
- ansys/systemcoupling/core/adaptor/api_24_1/_solve.py +13 -0
- ansys/systemcoupling/core/adaptor/api_24_1/abort.py +39 -0
- ansys/systemcoupling/core/adaptor/api_24_1/activate_hidden.py +46 -0
- ansys/systemcoupling/core/adaptor/api_24_1/add_data_transfer.py +190 -0
- ansys/systemcoupling/core/adaptor/api_24_1/add_data_transfer_by_display_names.py +191 -0
- ansys/systemcoupling/core/adaptor/api_24_1/add_expression_function.py +61 -0
- ansys/systemcoupling/core/adaptor/api_24_1/add_interface.py +77 -0
- ansys/systemcoupling/core/adaptor/api_24_1/add_interface_by_display_names.py +78 -0
- ansys/systemcoupling/core/adaptor/api_24_1/add_named_expression.py +42 -0
- ansys/systemcoupling/core/adaptor/api_24_1/add_participant.py +140 -0
- ansys/systemcoupling/core/adaptor/api_24_1/add_reference_frame.py +40 -0
- ansys/systemcoupling/core/adaptor/api_24_1/add_transformation.py +102 -0
- ansys/systemcoupling/core/adaptor/api_24_1/analysis_control.py +249 -0
- ansys/systemcoupling/core/adaptor/api_24_1/apip.py +33 -0
- ansys/systemcoupling/core/adaptor/api_24_1/ascii_output.py +44 -0
- ansys/systemcoupling/core/adaptor/api_24_1/attribute.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_1/attribute_child.py +54 -0
- ansys/systemcoupling/core/adaptor/api_24_1/automatic_alignment_options.py +46 -0
- ansys/systemcoupling/core/adaptor/api_24_1/available_ports.py +40 -0
- ansys/systemcoupling/core/adaptor/api_24_1/avoid_data_reconstruction.py +46 -0
- ansys/systemcoupling/core/adaptor/api_24_1/case_root.py +62 -0
- ansys/systemcoupling/core/adaptor/api_24_1/clear_state.py +16 -0
- ansys/systemcoupling/core/adaptor/api_24_1/coupling_interface.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_1/coupling_interface_child.py +42 -0
- ansys/systemcoupling/core/adaptor/api_24_1/coupling_participant.py +23 -0
- ansys/systemcoupling/core/adaptor/api_24_1/coupling_participant_child.py +230 -0
- ansys/systemcoupling/core/adaptor/api_24_1/create_restart_point.py +29 -0
- ansys/systemcoupling/core/adaptor/api_24_1/data_transfer.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_1/data_transfer_child.py +187 -0
- ansys/systemcoupling/core/adaptor/api_24_1/delete_snapshot.py +28 -0
- ansys/systemcoupling/core/adaptor/api_24_1/delete_transformation.py +42 -0
- ansys/systemcoupling/core/adaptor/api_24_1/dimensionality.py +96 -0
- ansys/systemcoupling/core/adaptor/api_24_1/execution_control.py +186 -0
- ansys/systemcoupling/core/adaptor/api_24_1/expression.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_1/expression_child.py +36 -0
- ansys/systemcoupling/core/adaptor/api_24_1/expression_function.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_1/expression_function_child.py +46 -0
- ansys/systemcoupling/core/adaptor/api_24_1/external_data_file.py +24 -0
- ansys/systemcoupling/core/adaptor/api_24_1/fluent_input.py +67 -0
- ansys/systemcoupling/core/adaptor/api_24_1/fmu_parameter.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_1/fmu_parameter_child.py +156 -0
- ansys/systemcoupling/core/adaptor/api_24_1/generate_input_file.py +41 -0
- ansys/systemcoupling/core/adaptor/api_24_1/get_execution_command.py +30 -0
- ansys/systemcoupling/core/adaptor/api_24_1/get_machines.py +13 -0
- ansys/systemcoupling/core/adaptor/api_24_1/get_region_names_for_participant.py +31 -0
- ansys/systemcoupling/core/adaptor/api_24_1/get_setup_summary.py +25 -0
- ansys/systemcoupling/core/adaptor/api_24_1/get_snapshots.py +14 -0
- ansys/systemcoupling/core/adaptor/api_24_1/get_status_messages.py +52 -0
- ansys/systemcoupling/core/adaptor/api_24_1/get_transformation.py +43 -0
- ansys/systemcoupling/core/adaptor/api_24_1/global_stabilization.py +143 -0
- ansys/systemcoupling/core/adaptor/api_24_1/has_input_file_changed.py +36 -0
- ansys/systemcoupling/core/adaptor/api_24_1/import_system_coupling_input_file.py +36 -0
- ansys/systemcoupling/core/adaptor/api_24_1/initialize.py +27 -0
- ansys/systemcoupling/core/adaptor/api_24_1/instancing.py +23 -0
- ansys/systemcoupling/core/adaptor/api_24_1/instancing_child.py +62 -0
- ansys/systemcoupling/core/adaptor/api_24_1/interrupt.py +39 -0
- ansys/systemcoupling/core/adaptor/api_24_1/library.py +37 -0
- ansys/systemcoupling/core/adaptor/api_24_1/live_visualization.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_1/live_visualization_child.py +72 -0
- ansys/systemcoupling/core/adaptor/api_24_1/mapping_control.py +229 -0
- ansys/systemcoupling/core/adaptor/api_24_1/open.py +102 -0
- ansys/systemcoupling/core/adaptor/api_24_1/open_results_in_en_sight.py +56 -0
- ansys/systemcoupling/core/adaptor/api_24_1/open_snapshot.py +37 -0
- ansys/systemcoupling/core/adaptor/api_24_1/output_control.py +134 -0
- ansys/systemcoupling/core/adaptor/api_24_1/parameter.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_1/parameter_child.py +64 -0
- ansys/systemcoupling/core/adaptor/api_24_1/partition_participants.py +138 -0
- ansys/systemcoupling/core/adaptor/api_24_1/reference_frame.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_1/reference_frame_child.py +71 -0
- ansys/systemcoupling/core/adaptor/api_24_1/region.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_1/region_child.py +72 -0
- ansys/systemcoupling/core/adaptor/api_24_1/reload_expression_function_modules.py +14 -0
- ansys/systemcoupling/core/adaptor/api_24_1/results.py +89 -0
- ansys/systemcoupling/core/adaptor/api_24_1/save.py +51 -0
- ansys/systemcoupling/core/adaptor/api_24_1/save_snapshot.py +54 -0
- ansys/systemcoupling/core/adaptor/api_24_1/setup_root.py +195 -0
- ansys/systemcoupling/core/adaptor/api_24_1/shutdown.py +25 -0
- ansys/systemcoupling/core/adaptor/api_24_1/side.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_1/side_child.py +56 -0
- ansys/systemcoupling/core/adaptor/api_24_1/solution_control.py +103 -0
- ansys/systemcoupling/core/adaptor/api_24_1/solution_root.py +110 -0
- ansys/systemcoupling/core/adaptor/api_24_1/solve.py +30 -0
- ansys/systemcoupling/core/adaptor/api_24_1/stabilization.py +157 -0
- ansys/systemcoupling/core/adaptor/api_24_1/start_participants.py +47 -0
- ansys/systemcoupling/core/adaptor/api_24_1/step.py +57 -0
- ansys/systemcoupling/core/adaptor/api_24_1/transformation.py +21 -0
- ansys/systemcoupling/core/adaptor/api_24_1/transformation_child.py +62 -0
- ansys/systemcoupling/core/adaptor/api_24_1/type.py +38 -0
- ansys/systemcoupling/core/adaptor/api_24_1/unmapped_value_options.py +158 -0
- ansys/systemcoupling/core/adaptor/api_24_1/update_control.py +44 -0
- ansys/systemcoupling/core/adaptor/api_24_1/update_participant.py +61 -0
- ansys/systemcoupling/core/adaptor/api_24_1/variable.py +20 -0
- ansys/systemcoupling/core/adaptor/api_24_1/variable_child.py +232 -0
- ansys/systemcoupling/core/adaptor/api_24_1/write_csv_chart_files.py +21 -0
- ansys/systemcoupling/core/adaptor/api_24_1/write_ensight.py +46 -0
- ansys/systemcoupling/core/adaptor/impl/get_syc_version.py +35 -0
- ansys/systemcoupling/core/adaptor/impl/injected_commands.py +97 -5
- ansys/systemcoupling/core/adaptor/impl/root_source.py +2 -0
- ansys/systemcoupling/core/adaptor/impl/static_info.py +69 -40
- ansys/systemcoupling/core/adaptor/impl/syc_proxy.py +1 -1
- ansys/systemcoupling/core/adaptor/impl/types.py +12 -0
- ansys/systemcoupling/core/client/grpc_client.py +14 -4
- ansys/systemcoupling/core/client/syc_container.py +18 -3
- ansys/systemcoupling/core/client/syc_process.py +33 -7
- ansys/systemcoupling/core/examples/downloads.py +2 -2
- ansys/systemcoupling/core/participant/manager.py +198 -0
- ansys/systemcoupling/core/participant/protocol.py +51 -0
- ansys/systemcoupling/core/session.py +8 -2
- ansys/systemcoupling/core/syc_version.py +82 -0
- {ansys_systemcoupling_core-0.1.3.dist-info → ansys_systemcoupling_core-0.3.0.dist-info}/METADATA +27 -25
- ansys_systemcoupling_core-0.3.0.dist-info/RECORD +230 -0
- {ansys_systemcoupling_core-0.1.3.dist-info → ansys_systemcoupling_core-0.3.0.dist-info}/WHEEL +1 -1
- ansys_systemcoupling_core-0.1.3.dist-info/RECORD +0 -123
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/abort.py +0 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/activate_hidden.py +0 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_data_transfer.py +0 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_data_transfer_by_display_names.py +0 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_expression_function.py +0 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_interface.py +0 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_interface_by_display_names.py +0 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_named_expression.py +0 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_reference_frame.py +0 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_transformation.py +0 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/apip.py +0 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/ascii_output.py +0 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/attribute.py +0 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/attribute_child.py +0 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/available_ports.py +0 -0
- ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/case_root.py +13 -13
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/clear_state.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/coupling_interface.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/coupling_interface_child.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/coupling_participant.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/create_restart_point.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/data_transfer.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/data_transfer_child.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/delete_snapshot.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/delete_transformation.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/dimensionality.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/execution_control.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/expression.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/expression_child.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/expression_function.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/expression_function_child.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/external_data_file.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/fluent_input.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/fmu_parameter.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/generate_input_file.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/get_execution_command.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/get_machines.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/get_region_names_for_participant.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/get_setup_summary.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/get_snapshots.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/get_status_messages.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/global_stabilization.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/has_input_file_changed.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/import_system_coupling_input_file.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/initialize.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/instancing.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/instancing_child.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/interrupt.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/library.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/mapping_control.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/open.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/open_snapshot.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/partition_participants.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/reference_frame.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/reference_frame_child.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/region.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/region_child.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/reload_expression_function_modules.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/results.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/save.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/save_snapshot.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/shutdown.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/side.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/side_child.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/solution_control.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/stabilization.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/start_participants.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/step.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/transformation.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/transformation_child.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/type.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/unmapped_value_options.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/update_control.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/update_participant.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/variable.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/write_csv_chart_files.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/write_ensight.py +0 -0
- /ansys/systemcoupling/core/adaptor/{api_23_1 → api_24_1}/open_results_in_ensight.py +0 -0
- {ansys_systemcoupling_core-0.1.3.dist-info → ansys_systemcoupling_core-0.3.0.dist-info}/LICENSE +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from copy import deepcopy
|
|
2
|
-
from typing import Tuple
|
|
2
|
+
from typing import Dict, List, Tuple
|
|
3
3
|
|
|
4
4
|
from ansys.systemcoupling.core.adaptor.impl.injected_commands import (
|
|
5
5
|
get_injected_cmd_data,
|
|
@@ -288,22 +288,85 @@ def get_extended_cmd_metadata(api) -> list:
|
|
|
288
288
|
Object providing access to the System Coupling *native API*.
|
|
289
289
|
"""
|
|
290
290
|
|
|
291
|
+
def find_item_by_name(items: List[Dict], name: str) -> dict:
|
|
292
|
+
for item in items:
|
|
293
|
+
if item["name"] == name:
|
|
294
|
+
return item
|
|
295
|
+
raise RuntimeError(f"Did not find dict element of list with 'name' == {name}")
|
|
296
|
+
|
|
291
297
|
def merge_data(target: list, source: list) -> None:
|
|
292
298
|
target_names = set(d["name"] for d in target)
|
|
293
299
|
source_names = set(d["name"] for d in source)
|
|
294
300
|
new_names = source_names - target_names
|
|
295
301
|
common_names = source_names & target_names
|
|
296
302
|
|
|
303
|
+
# Injected commands can either be completely new commands injected into
|
|
304
|
+
# the set of available commands, or can be "overrides" that replace the
|
|
305
|
+
# SyC command that would have been generated. Occasionally, we still
|
|
306
|
+
# want to generate the command that is being replaced so that we can
|
|
307
|
+
# call it internally. This is identified by a "pysyc_internal_name"
|
|
308
|
+
# field. In this case we split the command data into an injected command
|
|
309
|
+
# and a "normal" command but with the internal name as the pysyc name
|
|
310
|
+
# for the latter.
|
|
311
|
+
|
|
312
|
+
special_injected_commands = [
|
|
313
|
+
name
|
|
314
|
+
for name in common_names
|
|
315
|
+
if "pysyc_internal_name" in find_item_by_name(source, name)
|
|
316
|
+
]
|
|
317
|
+
|
|
318
|
+
for name in special_injected_commands:
|
|
319
|
+
src_item = find_item_by_name(source, name)
|
|
320
|
+
tgt_item = find_item_by_name(target, name)
|
|
321
|
+
|
|
322
|
+
# Target item becomes a "normally" exposed SyC command except that
|
|
323
|
+
# it is "internal" on the PySyC side - only intended for internal
|
|
324
|
+
# PySyC use. It will be given a special internal name rather than
|
|
325
|
+
# the one derived from its SyC name. It will also have its doc
|
|
326
|
+
# info removed.
|
|
327
|
+
|
|
328
|
+
# - Take a copy of tgt before we remove doc.
|
|
329
|
+
tgt_copy = deepcopy(tgt_item)
|
|
330
|
+
if "doc" in tgt_item:
|
|
331
|
+
tgt_item["doc"] = "For internal use only."
|
|
332
|
+
|
|
333
|
+
for arg in tgt_item.get("args", []):
|
|
334
|
+
_, arg_info = arg
|
|
335
|
+
if "doc" in arg_info:
|
|
336
|
+
arg_info["doc"] = "..."
|
|
337
|
+
|
|
338
|
+
# - Name for PySyC exposure is the "pysyc_internal_name" from the source item
|
|
339
|
+
tgt_item["pyname"] = src_item["pysyc_internal_name"]
|
|
340
|
+
|
|
341
|
+
# Source item becomes a normal injected command. It is processed like the
|
|
342
|
+
# items in the common_names later but has special treatment for its
|
|
343
|
+
# doc and arguments. That is done here, so it will be removed from
|
|
344
|
+
# common_names and added to new_names.
|
|
345
|
+
for k, v in tgt_copy.items():
|
|
346
|
+
if k in ("essentialArgNames", "optionalArgNames", "args"):
|
|
347
|
+
src_item[k] = src_item.get(f"{k}_extra", []) + v
|
|
348
|
+
elif k == "doc":
|
|
349
|
+
prefix = src_item.get(f"{k}_prefix", "")
|
|
350
|
+
if prefix:
|
|
351
|
+
prefix += "\n\n"
|
|
352
|
+
suffix = src_item.get(f"{k}_suffix", "")
|
|
353
|
+
if suffix:
|
|
354
|
+
suffix = "\n" + suffix
|
|
355
|
+
src_item[k] = prefix + v + suffix
|
|
356
|
+
else:
|
|
357
|
+
src_item[k] = v
|
|
358
|
+
|
|
359
|
+
src_item["name"] = src_item["pyname"]
|
|
360
|
+
|
|
361
|
+
common_names.remove(name)
|
|
362
|
+
new_names.add(src_item["name"])
|
|
363
|
+
|
|
297
364
|
for src_item in source:
|
|
298
365
|
name = src_item["name"]
|
|
299
366
|
if name in new_names:
|
|
300
367
|
target.append(src_item)
|
|
301
368
|
elif name in common_names:
|
|
302
|
-
tgt_item =
|
|
303
|
-
for titem in target:
|
|
304
|
-
if titem["name"] == name:
|
|
305
|
-
tgt_item = titem
|
|
306
|
-
break
|
|
369
|
+
tgt_item = find_item_by_name(target, name)
|
|
307
370
|
|
|
308
371
|
# Single-level merge of source item dictionary into
|
|
309
372
|
# target item dictionary. If any aspect of the arguments
|
|
@@ -316,37 +379,3 @@ def get_extended_cmd_metadata(api) -> list:
|
|
|
316
379
|
injected_data = get_injected_cmd_data()
|
|
317
380
|
merge_data(cmd_metadata, injected_data)
|
|
318
381
|
return cmd_metadata
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
def get_syc_version(api) -> str:
|
|
322
|
-
"""Get the System Coupling version.
|
|
323
|
-
|
|
324
|
-
The version is returned in a string like ``"23.2"``.
|
|
325
|
-
|
|
326
|
-
System Coupling versions earlier than 23.2 (2023 R2) do not expose
|
|
327
|
-
the ``GetVersion`` command. Because the server that PySystemCoupling
|
|
328
|
-
connects to did not exist prior to 23.1 (2023 R1), if no version query
|
|
329
|
-
exists, the version is assumed to be 23.1.
|
|
330
|
-
|
|
331
|
-
Parameters
|
|
332
|
-
----------
|
|
333
|
-
api : NativeApi
|
|
334
|
-
Object providing access to the System Coupling *native API* .
|
|
335
|
-
"""
|
|
336
|
-
|
|
337
|
-
def clean_version_string(version_in: str) -> str:
|
|
338
|
-
year, _, release = version_in.partition(" ")
|
|
339
|
-
if len(year) == 4 and year.startswith("20") and release.startswith("R"):
|
|
340
|
-
try:
|
|
341
|
-
year = int(year[2:])
|
|
342
|
-
release = int(release[1:])
|
|
343
|
-
return f"{year}.{release}"
|
|
344
|
-
except:
|
|
345
|
-
pass
|
|
346
|
-
raise RuntimeError(
|
|
347
|
-
f"Version string {version_in} has invalid format (expect '20yy Rn')."
|
|
348
|
-
)
|
|
349
|
-
|
|
350
|
-
cmds = api.GetCommandAndQueryMetadata()
|
|
351
|
-
exists = any(cmd["name"] == "GetVersion" for cmd in cmds)
|
|
352
|
-
return clean_version_string(api.GetVersion()) if exists else "23.1"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
from ansys.systemcoupling.core.adaptor.impl.get_syc_version import get_syc_version
|
|
1
2
|
from ansys.systemcoupling.core.adaptor.impl.static_info import (
|
|
2
3
|
get_dm_metadata,
|
|
3
4
|
get_extended_cmd_metadata,
|
|
4
|
-
get_syc_version,
|
|
5
5
|
make_cmdonly_metadata,
|
|
6
6
|
make_combined_metadata,
|
|
7
7
|
)
|
|
@@ -29,6 +29,7 @@ import sys
|
|
|
29
29
|
from typing import Dict, Generic, List, NewType, Tuple, TypeVar, Union
|
|
30
30
|
import weakref
|
|
31
31
|
|
|
32
|
+
from ansys.systemcoupling.core.participant.protocol import ParticipantProtocol
|
|
32
33
|
from ansys.systemcoupling.core.util import name_util
|
|
33
34
|
|
|
34
35
|
# Type hints
|
|
@@ -246,6 +247,17 @@ class SettingsBase(Base, Generic[StateT]):
|
|
|
246
247
|
out.flush()
|
|
247
248
|
|
|
248
249
|
|
|
250
|
+
# TODO: this doesn't make much sense as a "setting" but is needed to
|
|
251
|
+
# make the special form of add_participant work. Ideally we want to move
|
|
252
|
+
# away from treating command arguments as "settings" but that needs to be
|
|
253
|
+
# handled as a separate task.
|
|
254
|
+
class ParticipantSession(SettingsBase[ParticipantProtocol]):
|
|
255
|
+
"""Object conforming to the ``ParticipantProtocol`` runtime protocol
|
|
256
|
+
for participant session objects."""
|
|
257
|
+
|
|
258
|
+
_state_type = ParticipantProtocol
|
|
259
|
+
|
|
260
|
+
|
|
249
261
|
class Integer(SettingsBase[int]):
|
|
250
262
|
"""Provides an ``Integer`` object that represents an integer value setting."""
|
|
251
263
|
|
|
@@ -90,28 +90,38 @@ class SycGrpc(object):
|
|
|
90
90
|
|
|
91
91
|
working_dir = kwargs.pop("working_dir", None)
|
|
92
92
|
port = kwargs.pop("port", None)
|
|
93
|
+
version = kwargs.pop("version", None)
|
|
93
94
|
|
|
94
95
|
if os.environ.get("SYC_LAUNCH_CONTAINER") == "1":
|
|
95
96
|
mounted_from = working_dir if working_dir else "./"
|
|
96
97
|
mounted_to = "/working"
|
|
97
|
-
self.start_container_and_connect(
|
|
98
|
+
self.start_container_and_connect(
|
|
99
|
+
mounted_from, mounted_to, port=port, version=version
|
|
100
|
+
)
|
|
98
101
|
else: # pragma: no cover
|
|
99
102
|
if port is None:
|
|
100
103
|
port = _find_port()
|
|
101
104
|
if working_dir is None:
|
|
102
105
|
working_dir = "."
|
|
103
106
|
LOG.debug("Starting process...")
|
|
104
|
-
self.__process = SycProcess(
|
|
107
|
+
self.__process = SycProcess(
|
|
108
|
+
_LOCALHOST_IP, port, working_dir, version, **kwargs
|
|
109
|
+
)
|
|
105
110
|
LOG.debug("...started")
|
|
106
111
|
self._connect(_LOCALHOST_IP, port)
|
|
107
112
|
|
|
108
113
|
def start_container_and_connect(
|
|
109
|
-
self,
|
|
114
|
+
self,
|
|
115
|
+
mounted_from: str,
|
|
116
|
+
mounted_to: str,
|
|
117
|
+
network: str = None,
|
|
118
|
+
port: int = None,
|
|
119
|
+
version: str = None,
|
|
110
120
|
):
|
|
111
121
|
"""Start the System Coupling container and establish a connection."""
|
|
112
122
|
LOG.debug("Starting container...")
|
|
113
123
|
port = port if port is not None else _find_port()
|
|
114
|
-
start_container(mounted_from, mounted_to, network, port)
|
|
124
|
+
start_container(mounted_from, mounted_to, network, port, version)
|
|
115
125
|
LOG.debug("...started")
|
|
116
126
|
self._connect(_LOCALHOST_IP, port)
|
|
117
127
|
|
|
@@ -2,12 +2,23 @@ import os
|
|
|
2
2
|
from pathlib import Path
|
|
3
3
|
import subprocess
|
|
4
4
|
|
|
5
|
+
from ansys.systemcoupling.core.syc_version import SYC_VERSION_DOT, normalize_version
|
|
6
|
+
|
|
5
7
|
_MPI_VERSION_VAR = "FLUENT_INTEL_MPI_VERSION"
|
|
6
8
|
_MPI_VERSION = "2021"
|
|
7
9
|
|
|
10
|
+
_DEFAULT_IMAGE_TAG = f"v{SYC_VERSION_DOT}.0"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _image_tag(version: str) -> str:
|
|
14
|
+
if version == "latest":
|
|
15
|
+
return version
|
|
16
|
+
major, minor = normalize_version(version)
|
|
17
|
+
return f"v{major}.{minor}.0"
|
|
18
|
+
|
|
8
19
|
|
|
9
20
|
def start_container(
|
|
10
|
-
mounted_from: str, mounted_to: str, network: str, port: int
|
|
21
|
+
mounted_from: str, mounted_to: str, network: str, port: int, version: str
|
|
11
22
|
) -> None:
|
|
12
23
|
"""Start a System Coupling container.
|
|
13
24
|
|
|
@@ -17,7 +28,11 @@ def start_container(
|
|
|
17
28
|
gPRC server local port, mapped to the same port in container.
|
|
18
29
|
"""
|
|
19
30
|
args = ["-m", "cosimgui", f"--grpcport=0.0.0.0:{port}"]
|
|
20
|
-
|
|
31
|
+
|
|
32
|
+
if version:
|
|
33
|
+
image_tag = _image_tag(version)
|
|
34
|
+
else:
|
|
35
|
+
image_tag = os.getenv("SYC_IMAGE_TAG", _DEFAULT_IMAGE_TAG)
|
|
21
36
|
|
|
22
37
|
mounted_from = str(Path(mounted_from).absolute())
|
|
23
38
|
|
|
@@ -36,7 +51,7 @@ def start_container(
|
|
|
36
51
|
f"{_MPI_VERSION_VAR}={_MPI_VERSION}",
|
|
37
52
|
"-e",
|
|
38
53
|
f"AWP_ROOT=/ansys_inc",
|
|
39
|
-
f"ghcr.io/
|
|
54
|
+
f"ghcr.io/ansys/pysystem-coupling:{image_tag}",
|
|
40
55
|
] + args
|
|
41
56
|
|
|
42
57
|
if network:
|
|
@@ -5,11 +5,12 @@ import subprocess
|
|
|
5
5
|
|
|
6
6
|
import psutil
|
|
7
7
|
|
|
8
|
+
from ansys.systemcoupling.core.syc_version import SYC_VERSION_CONCAT, normalize_version
|
|
8
9
|
from ansys.systemcoupling.core.util.logging import LOG
|
|
9
10
|
|
|
10
11
|
_isWindows = any(platform.win32_ver())
|
|
11
12
|
|
|
12
|
-
_CURR_VER =
|
|
13
|
+
_CURR_VER = SYC_VERSION_CONCAT
|
|
13
14
|
_INSTALL_ROOT_ENV = "AWP_ROOT"
|
|
14
15
|
_INSTALL_ROOT_VER_ENV = _INSTALL_ROOT_ENV + _CURR_VER
|
|
15
16
|
_SC_ROOT_ENV = "SYSC_ROOT"
|
|
@@ -22,8 +23,10 @@ _SCRIPT_NAME = "systemcoupling" + _SCRIPT_EXT
|
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
class SycProcess: # pragma: no cover
|
|
25
|
-
def __init__(self, host, port, working_dir, **kwargs):
|
|
26
|
-
self.__process = _start_system_coupling(
|
|
26
|
+
def __init__(self, host, port, working_dir, version=None, **kwargs):
|
|
27
|
+
self.__process = _start_system_coupling(
|
|
28
|
+
host, port, working_dir, version, **kwargs
|
|
29
|
+
)
|
|
27
30
|
|
|
28
31
|
def end(self):
|
|
29
32
|
if self.__process and self.__process.poll() is None:
|
|
@@ -41,11 +44,18 @@ class SycProcess: # pragma: no cover
|
|
|
41
44
|
self.__process = None
|
|
42
45
|
|
|
43
46
|
|
|
44
|
-
def _start_system_coupling(
|
|
47
|
+
def _start_system_coupling(
|
|
48
|
+
host, port, working_dir, version, **kwargs
|
|
49
|
+
): # pragma: no cover
|
|
45
50
|
env = deepcopy(os.environ)
|
|
46
51
|
env["PYTHONUNBUFFERED"] = "1"
|
|
47
52
|
env["SYC_GUI_SILENT_SERVER"] = "1"
|
|
48
|
-
args = [
|
|
53
|
+
args = [
|
|
54
|
+
_path_to_system_coupling(version),
|
|
55
|
+
"-m",
|
|
56
|
+
"cosimgui",
|
|
57
|
+
f"--grpcport={host}:{port}",
|
|
58
|
+
]
|
|
49
59
|
|
|
50
60
|
# Extract arguments that we currently recognize - scope to extend in future
|
|
51
61
|
nprocs = kwargs.pop("nprocs", None)
|
|
@@ -72,13 +82,29 @@ def _start_system_coupling(host, port, working_dir, **kwargs): # pragma: no cov
|
|
|
72
82
|
)
|
|
73
83
|
|
|
74
84
|
|
|
75
|
-
def _path_to_system_coupling(): # pragma: no cover
|
|
85
|
+
def _path_to_system_coupling(version): # pragma: no cover
|
|
86
|
+
if version is not None:
|
|
87
|
+
if os.environ.get(_SC_ROOT_ENV, None) or os.environ.get(
|
|
88
|
+
_INSTALL_ROOT_ENV, None
|
|
89
|
+
):
|
|
90
|
+
raise ValueError(
|
|
91
|
+
f"An explicit version, {version}, has been specified for "
|
|
92
|
+
"launching System Coupling, while at least one of the "
|
|
93
|
+
f"environment variables {_SC_ROOT_ENV} and {_INSTALL_ROOT_ENV} "
|
|
94
|
+
"is set. To remove the ambiguity, either unset the environment "
|
|
95
|
+
"variable(s) or do not provide the version argument."
|
|
96
|
+
)
|
|
97
|
+
|
|
76
98
|
scroot = os.environ.get(_SC_ROOT_ENV, None)
|
|
77
99
|
|
|
78
100
|
if not scroot:
|
|
79
101
|
scroot = os.environ.get(_INSTALL_ROOT_ENV, None)
|
|
80
102
|
if scroot is None:
|
|
81
|
-
|
|
103
|
+
if version is None:
|
|
104
|
+
scroot = os.environ.get(_INSTALL_ROOT_VER_ENV, None)
|
|
105
|
+
else:
|
|
106
|
+
ver_maj, ver_min = normalize_version(version)
|
|
107
|
+
scroot = os.environ.get(f"{_INSTALL_ROOT_ENV}{ver_maj}{ver_min}", None)
|
|
82
108
|
if scroot:
|
|
83
109
|
scroot = os.path.join(scroot, "SystemCoupling")
|
|
84
110
|
|
|
@@ -37,8 +37,8 @@ def _decompress(filename: str) -> None:
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
def _get_file_url(filename: str, directory: Optional[str] = None) -> str:
|
|
40
|
-
root_url = "https://github.com/
|
|
41
|
-
# root_url = "https://github.com/
|
|
40
|
+
root_url = "https://github.com/ansys/example-data/raw/master/"
|
|
41
|
+
# root_url = "https://github.com/ansys/pysystem-coupling/raw/feature/more_doc/"
|
|
42
42
|
if directory:
|
|
43
43
|
return f"{root_url}" f"{directory}/{filename}"
|
|
44
44
|
return f"{root_url}/{filename}"
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import threading
|
|
2
|
+
from typing import Dict, List, Tuple
|
|
3
|
+
|
|
4
|
+
from ansys.systemcoupling.core.participant.protocol import ParticipantProtocol
|
|
5
|
+
from ansys.systemcoupling.core.util.logging import LOG
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ParticipantManager:
|
|
9
|
+
"""Manages a System Coupling solution in which the participant solvers are
|
|
10
|
+
provided as "session" objects from other PyAnsys APIs.
|
|
11
|
+
|
|
12
|
+
These objects must conform (in a Python "duck typing" sense) to the
|
|
13
|
+
``ParticipantProtocol`` protocol.
|
|
14
|
+
|
|
15
|
+
The ParticipantManager will play a role whenever participants are added to the
|
|
16
|
+
analysis using the ``add_participant`` command with ``participant_session`` being the one
|
|
17
|
+
and only argument.
|
|
18
|
+
|
|
19
|
+
In this case, the manager creates ``coupling_participant`` data model objects
|
|
20
|
+
based on queries to the session object. It will also store the session object
|
|
21
|
+
for later use if a solve is initiated.
|
|
22
|
+
|
|
23
|
+
If ``solve`` is called on the manager, it will coordinate both the connection of the
|
|
24
|
+
participants to System Coupling and, subsequently, the invocation of their solve
|
|
25
|
+
operations. In standard System Coupling terms, the solves that are initiated from
|
|
26
|
+
the "PyAnsys" environment will be regarded by the System Coupling solver as
|
|
27
|
+
"externally managed".
|
|
28
|
+
|
|
29
|
+
.. warning:
|
|
30
|
+
This facility should be regarded as sub-Beta level.
|
|
31
|
+
It is likely to be subject to further development, and has fairly limited utility
|
|
32
|
+
until more participant types support the protocol.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def __init__(self, syc_session):
|
|
36
|
+
self.__participants: Dict[str, ParticipantProtocol] = {}
|
|
37
|
+
self.__syc_session = syc_session
|
|
38
|
+
self.__connection_lock = threading.Lock()
|
|
39
|
+
self.clear()
|
|
40
|
+
|
|
41
|
+
def clear(self):
|
|
42
|
+
self.__participants: Dict[str, ParticipantProtocol] = {}
|
|
43
|
+
self.__n_connected = 0
|
|
44
|
+
self.__solve_exception = None
|
|
45
|
+
|
|
46
|
+
def add_participant(self, participant_session: ParticipantProtocol) -> str:
|
|
47
|
+
participant_name = (
|
|
48
|
+
f"{participant_session.participant_type}-{len(self.__participants) + 1}"
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
setup = self.__syc_session.setup
|
|
52
|
+
|
|
53
|
+
part_state = setup.coupling_participant.create(participant_name)
|
|
54
|
+
part_state.participant_type = participant_session.participant_type
|
|
55
|
+
part_state.participant_analysis_type = participant_session.get_analysis_type()
|
|
56
|
+
part_state.execution_control.option = "ExternallyManaged"
|
|
57
|
+
|
|
58
|
+
setup.analysis_control.analysis_type = (
|
|
59
|
+
participant_session.get_analysis_type()
|
|
60
|
+
) # TODO: this logic isn't quite right, maybe delegate to controller
|
|
61
|
+
|
|
62
|
+
for variable in participant_session.get_variables():
|
|
63
|
+
part_state.variable.create(variable.name).set_state(
|
|
64
|
+
{
|
|
65
|
+
"tensor_type": variable.tensor_type,
|
|
66
|
+
"is_extensive": variable.is_extensive,
|
|
67
|
+
"location": variable.location,
|
|
68
|
+
"quantity_type": variable.quantity_type,
|
|
69
|
+
"participant_display_name": variable.display_name,
|
|
70
|
+
"display_name": variable.display_name.replace(
|
|
71
|
+
" ", "_"
|
|
72
|
+
), # TODO: delegate this to controller
|
|
73
|
+
}
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
for region in participant_session.get_regions():
|
|
77
|
+
part_state.region.create(region.name).set_state(
|
|
78
|
+
{
|
|
79
|
+
"topology": region.topology,
|
|
80
|
+
"input_variables": region.input_variables,
|
|
81
|
+
"output_variables": region.output_variables,
|
|
82
|
+
"display_name": region.display_name,
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
self.__participants[participant_name] = participant_session
|
|
87
|
+
return participant_name
|
|
88
|
+
|
|
89
|
+
def solve(self):
|
|
90
|
+
self.__solve_exception = None
|
|
91
|
+
self._clear_n_connected()
|
|
92
|
+
|
|
93
|
+
if len(self.__participants) == 0:
|
|
94
|
+
# Fall back to normal solve
|
|
95
|
+
self.__syc_session.solution._solve()
|
|
96
|
+
return
|
|
97
|
+
|
|
98
|
+
# TODO : if we *don't* check for validation error before solve, and
|
|
99
|
+
# leave it for the SyC Solve() to find them, we see participants hang
|
|
100
|
+
# during connection. (This is independent of PySyC.)
|
|
101
|
+
|
|
102
|
+
if any(
|
|
103
|
+
msg
|
|
104
|
+
for msg in self.__syc_session.setup.get_status_messages()
|
|
105
|
+
if msg["level"] == "Error"
|
|
106
|
+
):
|
|
107
|
+
raise RuntimeError(
|
|
108
|
+
"The setup data contains errors. solve() cannot proceed until these are fixed."
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
syc_solve_thread = threading.Thread(target=self._syc_solve)
|
|
112
|
+
try:
|
|
113
|
+
self._do_solve(syc_solve_thread)
|
|
114
|
+
finally:
|
|
115
|
+
syc_solve_thread.join()
|
|
116
|
+
LOG.info("SyC solve joined.")
|
|
117
|
+
|
|
118
|
+
if self.__solve_exception:
|
|
119
|
+
raise self.__solve_exception
|
|
120
|
+
|
|
121
|
+
def _do_solve(self, syc_solve_thread):
|
|
122
|
+
connection_threads = [
|
|
123
|
+
threading.Thread(
|
|
124
|
+
target=lambda host_port, name=name, part=participant: self._participant_connect(
|
|
125
|
+
name, host_port, part
|
|
126
|
+
),
|
|
127
|
+
args=(self._get_host_and_port(name), name, participant),
|
|
128
|
+
)
|
|
129
|
+
for name, participant in self.__participants.items()
|
|
130
|
+
]
|
|
131
|
+
|
|
132
|
+
LOG.info("Starting SyC solve thread...")
|
|
133
|
+
syc_solve_thread.start()
|
|
134
|
+
LOG.info("Waiting for participants to connect.")
|
|
135
|
+
_start_threads(connection_threads)
|
|
136
|
+
_join_threads(connection_threads)
|
|
137
|
+
connection_threads.clear()
|
|
138
|
+
if self._get_n_connected() < len(self.__participants):
|
|
139
|
+
LOG.error("Some participants were unable to connect to System Coupling.")
|
|
140
|
+
self.__syc_session.solution.abort()
|
|
141
|
+
else:
|
|
142
|
+
LOG.info("Participants connected.")
|
|
143
|
+
|
|
144
|
+
LOG.info("Starting participant solve threads.")
|
|
145
|
+
partsolve_threads = [
|
|
146
|
+
threading.Thread(target=participant.solve)
|
|
147
|
+
for participant in self.__participants.values()
|
|
148
|
+
]
|
|
149
|
+
_start_threads(partsolve_threads)
|
|
150
|
+
|
|
151
|
+
LOG.info("Waiting for all solve threads to join.")
|
|
152
|
+
_join_threads(partsolve_threads)
|
|
153
|
+
LOG.info("All participant solve threads joined.")
|
|
154
|
+
|
|
155
|
+
def _clear_n_connected(self) -> None:
|
|
156
|
+
with self.__connection_lock:
|
|
157
|
+
self.__n_connected = 0
|
|
158
|
+
|
|
159
|
+
def _get_n_connected(self) -> int:
|
|
160
|
+
with self.__connection_lock:
|
|
161
|
+
return self.__n_connected
|
|
162
|
+
|
|
163
|
+
def _increment_n_connected(self) -> None:
|
|
164
|
+
with self.__connection_lock:
|
|
165
|
+
self.__n_connected += 1
|
|
166
|
+
|
|
167
|
+
def _get_host_and_port(self, participant_name: str) -> Tuple[str, int]:
|
|
168
|
+
port, host = self.__syc_session._native_api.GetServerInfo()
|
|
169
|
+
return host, port
|
|
170
|
+
|
|
171
|
+
def _participant_connect(
|
|
172
|
+
self, name: str, host_port: Tuple[str, int], participant: ParticipantProtocol
|
|
173
|
+
) -> None:
|
|
174
|
+
try:
|
|
175
|
+
participant.connect(*host_port, name)
|
|
176
|
+
self._increment_n_connected()
|
|
177
|
+
except Exception as e:
|
|
178
|
+
LOG.error(f"Participant {name} failed to connect. Exception: {e}")
|
|
179
|
+
|
|
180
|
+
def _syc_solve(self):
|
|
181
|
+
try:
|
|
182
|
+
# We use `syc_session.solution._solve` here as it is
|
|
183
|
+
# the lower level solve command. `sys_session.solution.solve`
|
|
184
|
+
# would bring us recursively back into *this* function
|
|
185
|
+
self.__syc_session.solution._solve()
|
|
186
|
+
except Exception as e:
|
|
187
|
+
self.__solve_exception = e
|
|
188
|
+
LOG.error(f"Solve terminated with exception: {e}.")
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def _start_threads(threads: List[threading.Thread]) -> None:
|
|
192
|
+
for thread in threads:
|
|
193
|
+
thread.start()
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def _join_threads(threads: List[threading.Thread]) -> None:
|
|
197
|
+
for thread in threads:
|
|
198
|
+
thread.join()
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import List, Protocol
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@dataclass
|
|
6
|
+
class Variable(Protocol):
|
|
7
|
+
name: str
|
|
8
|
+
display_name: str
|
|
9
|
+
tensor_type: str
|
|
10
|
+
is_extensive: bool
|
|
11
|
+
location: str
|
|
12
|
+
quantity_type: str
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class Region(Protocol):
|
|
17
|
+
name: str
|
|
18
|
+
display_name: str
|
|
19
|
+
topology: str
|
|
20
|
+
input_variables: List[str]
|
|
21
|
+
output_variables: List[str]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ParticipantProtocol(Protocol):
|
|
25
|
+
"""Protocol class to which PyAnsys sessions that are added to a PySystemCoupling
|
|
26
|
+
session must conform."""
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def participant_type(self) -> str:
|
|
30
|
+
"""Type of participant."""
|
|
31
|
+
...
|
|
32
|
+
|
|
33
|
+
def get_variables(self) -> List[Variable]:
|
|
34
|
+
"""List of variables that can be transferred from the participant."""
|
|
35
|
+
...
|
|
36
|
+
|
|
37
|
+
def get_regions(self) -> List[Region]:
|
|
38
|
+
"""List of regions on which data transfers can occur."""
|
|
39
|
+
...
|
|
40
|
+
|
|
41
|
+
def get_analysis_type(self) -> str:
|
|
42
|
+
"""The type of the analysis - "Steady" or "Transient"."""
|
|
43
|
+
...
|
|
44
|
+
|
|
45
|
+
def connect(self, host: str, port: int, name: str) -> None:
|
|
46
|
+
"""Establish connection between the participant solver and System Coupling."""
|
|
47
|
+
...
|
|
48
|
+
|
|
49
|
+
def solve(self) -> None:
|
|
50
|
+
"""Run the participant's solve operation."""
|
|
51
|
+
...
|
|
@@ -8,6 +8,7 @@ from ansys.systemcoupling.core.adaptor.impl.injected_commands import (
|
|
|
8
8
|
from ansys.systemcoupling.core.adaptor.impl.root_source import get_root
|
|
9
9
|
from ansys.systemcoupling.core.adaptor.impl.syc_proxy import SycProxy
|
|
10
10
|
from ansys.systemcoupling.core.native_api import NativeApi
|
|
11
|
+
from ansys.systemcoupling.core.participant.manager import ParticipantManager
|
|
11
12
|
|
|
12
13
|
if os.environ.get("PYSYC_DOC_BUILD_VERSION"):
|
|
13
14
|
# It is useful to import explicit types while building doc as it
|
|
@@ -60,6 +61,7 @@ class Session:
|
|
|
60
61
|
self.__rpc = rpc
|
|
61
62
|
self.__native_api = None
|
|
62
63
|
self.__syc_version = None
|
|
64
|
+
self.__part_mgr = ParticipantManager(self)
|
|
63
65
|
|
|
64
66
|
def exit(self) -> None:
|
|
65
67
|
"""Close the System Coupling server instance.
|
|
@@ -152,7 +154,11 @@ class Session:
|
|
|
152
154
|
version = sycproxy.get_version()
|
|
153
155
|
self.__syc_version = version.replace(".", "_")
|
|
154
156
|
root = get_root(sycproxy, category=category, version=self.__syc_version)
|
|
155
|
-
sycproxy.set_injected_commands(
|
|
157
|
+
sycproxy.set_injected_commands(
|
|
158
|
+
get_injected_cmd_map(
|
|
159
|
+
self.__syc_version, category, root, self.__part_mgr, self.__rpc
|
|
160
|
+
)
|
|
161
|
+
)
|
|
156
162
|
return (root, sycproxy)
|
|
157
163
|
|
|
158
164
|
@property
|
|
@@ -161,7 +167,7 @@ class Session:
|
|
|
161
167
|
|
|
162
168
|
Use of this API is not particularly encouraged, but there may be
|
|
163
169
|
situations where it is useful to access functionality that, for
|
|
164
|
-
some reason, not been fully exposed in PySystemCoupling.
|
|
170
|
+
some reason, has not been fully exposed in PySystemCoupling.
|
|
165
171
|
|
|
166
172
|
Furthermore, existing users of the System Coupling CLI may initially
|
|
167
173
|
find it comfortable to work with the familiar API while transitioning
|