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.

Files changed (211) hide show
  1. ansys/systemcoupling/core/__init__.py +27 -17
  2. ansys/systemcoupling/core/adaptor/api_23_2/_add_participant.py +70 -0
  3. ansys/systemcoupling/core/adaptor/api_23_2/_solve.py +13 -0
  4. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_participant.py +38 -2
  5. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/analysis_control.py +8 -0
  6. ansys/systemcoupling/core/adaptor/api_23_2/automatic_alignment_options.py +46 -0
  7. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/avoid_data_reconstruction.py +10 -0
  8. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/coupling_participant_child.py +1 -1
  9. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/fmu_parameter_child.py +30 -0
  10. ansys/systemcoupling/core/adaptor/api_23_2/get_transformation.py +43 -0
  11. ansys/systemcoupling/core/adaptor/api_23_2/live_visualization.py +20 -0
  12. ansys/systemcoupling/core/adaptor/api_23_2/live_visualization_child.py +72 -0
  13. ansys/systemcoupling/core/adaptor/api_23_2/open_results_in_en_sight.py +56 -0
  14. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/output_control.py +6 -1
  15. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/setup_root.py +55 -49
  16. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/solution_root.py +48 -36
  17. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/solve.py +1 -1
  18. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/variable_child.py +31 -0
  19. ansys/systemcoupling/core/adaptor/api_24_1/_add_participant.py +70 -0
  20. ansys/systemcoupling/core/adaptor/api_24_1/_solve.py +13 -0
  21. ansys/systemcoupling/core/adaptor/api_24_1/abort.py +39 -0
  22. ansys/systemcoupling/core/adaptor/api_24_1/activate_hidden.py +46 -0
  23. ansys/systemcoupling/core/adaptor/api_24_1/add_data_transfer.py +190 -0
  24. ansys/systemcoupling/core/adaptor/api_24_1/add_data_transfer_by_display_names.py +191 -0
  25. ansys/systemcoupling/core/adaptor/api_24_1/add_expression_function.py +61 -0
  26. ansys/systemcoupling/core/adaptor/api_24_1/add_interface.py +77 -0
  27. ansys/systemcoupling/core/adaptor/api_24_1/add_interface_by_display_names.py +78 -0
  28. ansys/systemcoupling/core/adaptor/api_24_1/add_named_expression.py +42 -0
  29. ansys/systemcoupling/core/adaptor/api_24_1/add_participant.py +140 -0
  30. ansys/systemcoupling/core/adaptor/api_24_1/add_reference_frame.py +40 -0
  31. ansys/systemcoupling/core/adaptor/api_24_1/add_transformation.py +102 -0
  32. ansys/systemcoupling/core/adaptor/api_24_1/analysis_control.py +249 -0
  33. ansys/systemcoupling/core/adaptor/api_24_1/apip.py +33 -0
  34. ansys/systemcoupling/core/adaptor/api_24_1/ascii_output.py +44 -0
  35. ansys/systemcoupling/core/adaptor/api_24_1/attribute.py +20 -0
  36. ansys/systemcoupling/core/adaptor/api_24_1/attribute_child.py +54 -0
  37. ansys/systemcoupling/core/adaptor/api_24_1/automatic_alignment_options.py +46 -0
  38. ansys/systemcoupling/core/adaptor/api_24_1/available_ports.py +40 -0
  39. ansys/systemcoupling/core/adaptor/api_24_1/avoid_data_reconstruction.py +46 -0
  40. ansys/systemcoupling/core/adaptor/api_24_1/case_root.py +62 -0
  41. ansys/systemcoupling/core/adaptor/api_24_1/clear_state.py +16 -0
  42. ansys/systemcoupling/core/adaptor/api_24_1/coupling_interface.py +20 -0
  43. ansys/systemcoupling/core/adaptor/api_24_1/coupling_interface_child.py +42 -0
  44. ansys/systemcoupling/core/adaptor/api_24_1/coupling_participant.py +23 -0
  45. ansys/systemcoupling/core/adaptor/api_24_1/coupling_participant_child.py +230 -0
  46. ansys/systemcoupling/core/adaptor/api_24_1/create_restart_point.py +29 -0
  47. ansys/systemcoupling/core/adaptor/api_24_1/data_transfer.py +20 -0
  48. ansys/systemcoupling/core/adaptor/api_24_1/data_transfer_child.py +187 -0
  49. ansys/systemcoupling/core/adaptor/api_24_1/delete_snapshot.py +28 -0
  50. ansys/systemcoupling/core/adaptor/api_24_1/delete_transformation.py +42 -0
  51. ansys/systemcoupling/core/adaptor/api_24_1/dimensionality.py +96 -0
  52. ansys/systemcoupling/core/adaptor/api_24_1/execution_control.py +186 -0
  53. ansys/systemcoupling/core/adaptor/api_24_1/expression.py +20 -0
  54. ansys/systemcoupling/core/adaptor/api_24_1/expression_child.py +36 -0
  55. ansys/systemcoupling/core/adaptor/api_24_1/expression_function.py +20 -0
  56. ansys/systemcoupling/core/adaptor/api_24_1/expression_function_child.py +46 -0
  57. ansys/systemcoupling/core/adaptor/api_24_1/external_data_file.py +24 -0
  58. ansys/systemcoupling/core/adaptor/api_24_1/fluent_input.py +67 -0
  59. ansys/systemcoupling/core/adaptor/api_24_1/fmu_parameter.py +20 -0
  60. ansys/systemcoupling/core/adaptor/api_24_1/fmu_parameter_child.py +156 -0
  61. ansys/systemcoupling/core/adaptor/api_24_1/generate_input_file.py +41 -0
  62. ansys/systemcoupling/core/adaptor/api_24_1/get_execution_command.py +30 -0
  63. ansys/systemcoupling/core/adaptor/api_24_1/get_machines.py +13 -0
  64. ansys/systemcoupling/core/adaptor/api_24_1/get_region_names_for_participant.py +31 -0
  65. ansys/systemcoupling/core/adaptor/api_24_1/get_setup_summary.py +25 -0
  66. ansys/systemcoupling/core/adaptor/api_24_1/get_snapshots.py +14 -0
  67. ansys/systemcoupling/core/adaptor/api_24_1/get_status_messages.py +52 -0
  68. ansys/systemcoupling/core/adaptor/api_24_1/get_transformation.py +43 -0
  69. ansys/systemcoupling/core/adaptor/api_24_1/global_stabilization.py +143 -0
  70. ansys/systemcoupling/core/adaptor/api_24_1/has_input_file_changed.py +36 -0
  71. ansys/systemcoupling/core/adaptor/api_24_1/import_system_coupling_input_file.py +36 -0
  72. ansys/systemcoupling/core/adaptor/api_24_1/initialize.py +27 -0
  73. ansys/systemcoupling/core/adaptor/api_24_1/instancing.py +23 -0
  74. ansys/systemcoupling/core/adaptor/api_24_1/instancing_child.py +62 -0
  75. ansys/systemcoupling/core/adaptor/api_24_1/interrupt.py +39 -0
  76. ansys/systemcoupling/core/adaptor/api_24_1/library.py +37 -0
  77. ansys/systemcoupling/core/adaptor/api_24_1/live_visualization.py +20 -0
  78. ansys/systemcoupling/core/adaptor/api_24_1/live_visualization_child.py +72 -0
  79. ansys/systemcoupling/core/adaptor/api_24_1/mapping_control.py +229 -0
  80. ansys/systemcoupling/core/adaptor/api_24_1/open.py +102 -0
  81. ansys/systemcoupling/core/adaptor/api_24_1/open_results_in_en_sight.py +56 -0
  82. ansys/systemcoupling/core/adaptor/api_24_1/open_snapshot.py +37 -0
  83. ansys/systemcoupling/core/adaptor/api_24_1/output_control.py +134 -0
  84. ansys/systemcoupling/core/adaptor/api_24_1/parameter.py +20 -0
  85. ansys/systemcoupling/core/adaptor/api_24_1/parameter_child.py +64 -0
  86. ansys/systemcoupling/core/adaptor/api_24_1/partition_participants.py +138 -0
  87. ansys/systemcoupling/core/adaptor/api_24_1/reference_frame.py +20 -0
  88. ansys/systemcoupling/core/adaptor/api_24_1/reference_frame_child.py +71 -0
  89. ansys/systemcoupling/core/adaptor/api_24_1/region.py +20 -0
  90. ansys/systemcoupling/core/adaptor/api_24_1/region_child.py +72 -0
  91. ansys/systemcoupling/core/adaptor/api_24_1/reload_expression_function_modules.py +14 -0
  92. ansys/systemcoupling/core/adaptor/api_24_1/results.py +89 -0
  93. ansys/systemcoupling/core/adaptor/api_24_1/save.py +51 -0
  94. ansys/systemcoupling/core/adaptor/api_24_1/save_snapshot.py +54 -0
  95. ansys/systemcoupling/core/adaptor/api_24_1/setup_root.py +195 -0
  96. ansys/systemcoupling/core/adaptor/api_24_1/shutdown.py +25 -0
  97. ansys/systemcoupling/core/adaptor/api_24_1/side.py +20 -0
  98. ansys/systemcoupling/core/adaptor/api_24_1/side_child.py +56 -0
  99. ansys/systemcoupling/core/adaptor/api_24_1/solution_control.py +103 -0
  100. ansys/systemcoupling/core/adaptor/api_24_1/solution_root.py +110 -0
  101. ansys/systemcoupling/core/adaptor/api_24_1/solve.py +30 -0
  102. ansys/systemcoupling/core/adaptor/api_24_1/stabilization.py +157 -0
  103. ansys/systemcoupling/core/adaptor/api_24_1/start_participants.py +47 -0
  104. ansys/systemcoupling/core/adaptor/api_24_1/step.py +57 -0
  105. ansys/systemcoupling/core/adaptor/api_24_1/transformation.py +21 -0
  106. ansys/systemcoupling/core/adaptor/api_24_1/transformation_child.py +62 -0
  107. ansys/systemcoupling/core/adaptor/api_24_1/type.py +38 -0
  108. ansys/systemcoupling/core/adaptor/api_24_1/unmapped_value_options.py +158 -0
  109. ansys/systemcoupling/core/adaptor/api_24_1/update_control.py +44 -0
  110. ansys/systemcoupling/core/adaptor/api_24_1/update_participant.py +61 -0
  111. ansys/systemcoupling/core/adaptor/api_24_1/variable.py +20 -0
  112. ansys/systemcoupling/core/adaptor/api_24_1/variable_child.py +232 -0
  113. ansys/systemcoupling/core/adaptor/api_24_1/write_csv_chart_files.py +21 -0
  114. ansys/systemcoupling/core/adaptor/api_24_1/write_ensight.py +46 -0
  115. ansys/systemcoupling/core/adaptor/impl/get_syc_version.py +35 -0
  116. ansys/systemcoupling/core/adaptor/impl/injected_commands.py +97 -5
  117. ansys/systemcoupling/core/adaptor/impl/root_source.py +2 -0
  118. ansys/systemcoupling/core/adaptor/impl/static_info.py +69 -40
  119. ansys/systemcoupling/core/adaptor/impl/syc_proxy.py +1 -1
  120. ansys/systemcoupling/core/adaptor/impl/types.py +12 -0
  121. ansys/systemcoupling/core/client/grpc_client.py +14 -4
  122. ansys/systemcoupling/core/client/syc_container.py +18 -3
  123. ansys/systemcoupling/core/client/syc_process.py +33 -7
  124. ansys/systemcoupling/core/examples/downloads.py +2 -2
  125. ansys/systemcoupling/core/participant/manager.py +198 -0
  126. ansys/systemcoupling/core/participant/protocol.py +51 -0
  127. ansys/systemcoupling/core/session.py +8 -2
  128. ansys/systemcoupling/core/syc_version.py +82 -0
  129. {ansys_systemcoupling_core-0.1.3.dist-info → ansys_systemcoupling_core-0.3.0.dist-info}/METADATA +27 -25
  130. ansys_systemcoupling_core-0.3.0.dist-info/RECORD +230 -0
  131. {ansys_systemcoupling_core-0.1.3.dist-info → ansys_systemcoupling_core-0.3.0.dist-info}/WHEEL +1 -1
  132. ansys_systemcoupling_core-0.1.3.dist-info/RECORD +0 -123
  133. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/abort.py +0 -0
  134. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/activate_hidden.py +0 -0
  135. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_data_transfer.py +0 -0
  136. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_data_transfer_by_display_names.py +0 -0
  137. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_expression_function.py +0 -0
  138. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_interface.py +0 -0
  139. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_interface_by_display_names.py +0 -0
  140. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_named_expression.py +0 -0
  141. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_reference_frame.py +0 -0
  142. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/add_transformation.py +0 -0
  143. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/apip.py +0 -0
  144. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/ascii_output.py +0 -0
  145. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/attribute.py +0 -0
  146. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/attribute_child.py +0 -0
  147. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/available_ports.py +0 -0
  148. ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/case_root.py +13 -13
  149. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/clear_state.py +0 -0
  150. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/coupling_interface.py +0 -0
  151. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/coupling_interface_child.py +0 -0
  152. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/coupling_participant.py +0 -0
  153. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/create_restart_point.py +0 -0
  154. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/data_transfer.py +0 -0
  155. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/data_transfer_child.py +0 -0
  156. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/delete_snapshot.py +0 -0
  157. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/delete_transformation.py +0 -0
  158. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/dimensionality.py +0 -0
  159. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/execution_control.py +0 -0
  160. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/expression.py +0 -0
  161. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/expression_child.py +0 -0
  162. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/expression_function.py +0 -0
  163. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/expression_function_child.py +0 -0
  164. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/external_data_file.py +0 -0
  165. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/fluent_input.py +0 -0
  166. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/fmu_parameter.py +0 -0
  167. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/generate_input_file.py +0 -0
  168. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/get_execution_command.py +0 -0
  169. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/get_machines.py +0 -0
  170. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/get_region_names_for_participant.py +0 -0
  171. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/get_setup_summary.py +0 -0
  172. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/get_snapshots.py +0 -0
  173. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/get_status_messages.py +0 -0
  174. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/global_stabilization.py +0 -0
  175. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/has_input_file_changed.py +0 -0
  176. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/import_system_coupling_input_file.py +0 -0
  177. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/initialize.py +0 -0
  178. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/instancing.py +0 -0
  179. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/instancing_child.py +0 -0
  180. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/interrupt.py +0 -0
  181. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/library.py +0 -0
  182. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/mapping_control.py +0 -0
  183. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/open.py +0 -0
  184. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/open_snapshot.py +0 -0
  185. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/partition_participants.py +0 -0
  186. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/reference_frame.py +0 -0
  187. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/reference_frame_child.py +0 -0
  188. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/region.py +0 -0
  189. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/region_child.py +0 -0
  190. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/reload_expression_function_modules.py +0 -0
  191. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/results.py +0 -0
  192. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/save.py +0 -0
  193. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/save_snapshot.py +0 -0
  194. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/shutdown.py +0 -0
  195. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/side.py +0 -0
  196. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/side_child.py +0 -0
  197. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/solution_control.py +0 -0
  198. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/stabilization.py +0 -0
  199. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/start_participants.py +0 -0
  200. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/step.py +0 -0
  201. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/transformation.py +0 -0
  202. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/transformation_child.py +0 -0
  203. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/type.py +0 -0
  204. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/unmapped_value_options.py +0 -0
  205. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/update_control.py +0 -0
  206. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/update_participant.py +0 -0
  207. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/variable.py +0 -0
  208. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/write_csv_chart_files.py +0 -0
  209. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_23_2}/write_ensight.py +0 -0
  210. /ansys/systemcoupling/core/adaptor/{api_23_1 → api_24_1}/open_results_in_ensight.py +0 -0
  211. {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 = None
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(mounted_from, mounted_to, port=port)
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(_LOCALHOST_IP, port, working_dir, **kwargs)
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, mounted_from: str, mounted_to: str, network: str = None, port: int = None
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
- image_tag = os.getenv("SYC_IMAGE_TAG", "v23.1.0")
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/pyansys/pysystem-coupling:{image_tag}",
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 = "231"
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(host, port, working_dir, **kwargs)
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(host, port, working_dir, **kwargs): # pragma: no cover
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 = [_path_to_system_coupling(), "-m", "cosimgui", f"--grpcport={host}:{port}"]
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
- scroot = os.environ.get(_INSTALL_ROOT_VER_ENV, None)
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/pyansys/example-data/raw/master/"
41
- # root_url = "https://github.com/pyansys/pysystem-coupling/raw/feature/more_doc/"
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(get_injected_cmd_map(category, root, self.__rpc))
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