pyfemtet 0.7.0__tar.gz → 0.7.1__tar.gz

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 pyfemtet might be problematic. Click here for more details.

Files changed (128) hide show
  1. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/PKG-INFO +2 -1
  2. pyfemtet-0.7.1/pyfemtet/__init__.py +1 -0
  3. pyfemtet-0.7.1/pyfemtet/_util/dask_util.py +10 -0
  4. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/_util/excel_macro_util.py +16 -4
  5. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/_femopt.py +27 -17
  6. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/_femopt_core.py +7 -2
  7. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/interface/_excel_interface.py +280 -91
  8. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/interface/_femtet.py +7 -20
  9. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/optimizer/_base.py +2 -1
  10. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyproject.toml +3 -1
  11. pyfemtet-0.7.0/pyfemtet/__init__.py +0 -1
  12. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/LICENSE +0 -0
  13. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/README.md +0 -0
  14. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/_femtet_config_util/__init__.py +0 -0
  15. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/_femtet_config_util/autosave.py +0 -0
  16. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/_femtet_config_util/exit.py +0 -0
  17. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/_message/1. make_pot.bat +0 -0
  18. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/_message/2. make_mo.bat +0 -0
  19. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/_message/__init__.py +0 -0
  20. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/_message/babel.cfg +0 -0
  21. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/_message/locales/ja/LC_MESSAGES/messages.po +0 -0
  22. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/_message/locales/messages.pot +0 -0
  23. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/_message/messages.py +0 -0
  24. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/_util/__init__.py +0 -0
  25. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/_warning.py +0 -0
  26. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/brep/__init__.py +0 -0
  27. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/brep/_impl.py +0 -0
  28. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/core.py +0 -0
  29. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/dispatch_extensions/__init__.py +0 -0
  30. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/dispatch_extensions/_impl.py +0 -0
  31. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/logger/__init__.py +0 -0
  32. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/logger/_impl.py +0 -0
  33. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/__init__.py +0 -0
  34. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/_test_utils/__init__.py +0 -0
  35. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/_test_utils/control_femtet.py +0 -0
  36. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/_test_utils/hyper_sphere.py +0 -0
  37. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/_test_utils/record_history.py +0 -0
  38. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/interface/__init__.py +0 -0
  39. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/interface/_base.py +0 -0
  40. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/interface/_femtet_parametric.py +0 -0
  41. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/interface/_femtet_with_nx/__init__.py +0 -0
  42. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/interface/_femtet_with_nx/_interface.py +0 -0
  43. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/interface/_femtet_with_nx/update_model.py +0 -0
  44. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/interface/_femtet_with_sldworks.py +0 -0
  45. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/optimizer/__init__.py +0 -0
  46. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/optimizer/_optuna/__init__.py +0 -0
  47. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/optimizer/_optuna/_botorch_patch/__init__.py +0 -0
  48. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/optimizer/_optuna/_botorch_patch/enable_nonlinear_constraint.py +0 -0
  49. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/optimizer/_optuna/_optuna.py +0 -0
  50. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/optimizer/_optuna/_pof_botorch.py +0 -0
  51. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/optimizer/_scipy.py +0 -0
  52. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/optimizer/_scipy_scalar.py +0 -0
  53. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/optimizer/parameter.py +0 -0
  54. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/prediction/__init__.py +0 -0
  55. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/prediction/_base.py +0 -0
  56. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/prediction/single_task_gp.py +0 -0
  57. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/ParametricIF.femprj +0 -0
  58. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/ParametricIF.py +0 -0
  59. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/ParametricIF_test_result.reccsv +0 -0
  60. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/cad_ex01_NX.femprj +0 -0
  61. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/cad_ex01_NX.prt +0 -0
  62. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/cad_ex01_NX.py +0 -0
  63. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/cad_ex01_NX_test_result.reccsv +0 -0
  64. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.SLDPRT +0 -0
  65. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.femprj +0 -0
  66. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.py +0 -0
  67. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/cad_ex01_SW_test_result.reccsv +0 -0
  68. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/constrained_pipe.femprj +0 -0
  69. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/constrained_pipe.py +0 -0
  70. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/constrained_pipe_test_result.reccsv +0 -0
  71. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric.femprj +0 -0
  72. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric.py +0 -0
  73. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric_test_result.reccsv +0 -0
  74. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/gau_ex08_parametric.femprj +0 -0
  75. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/gau_ex08_parametric.py +0 -0
  76. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/gau_ex08_parametric_test_result.reccsv +0 -0
  77. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/her_ex40_parametric.femprj +0 -0
  78. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/her_ex40_parametric.py +0 -0
  79. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/her_ex40_parametric_test_result.reccsv +0 -0
  80. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric.femprj +0 -0
  81. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric.py +0 -0
  82. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric_parallel.py +0 -0
  83. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric_test_result.reccsv +0 -0
  84. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric.femprj +0 -0
  85. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric.py +0 -0
  86. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric_parallel.py +0 -0
  87. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric_test_result.reccsv +0 -0
  88. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/ParametricIF_jp.femprj +0 -0
  89. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/ParametricIF_jp.py +0 -0
  90. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_NX_jp.femprj +0 -0
  91. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_NX_jp.py +0 -0
  92. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_SW_jp.femprj +0 -0
  93. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_SW_jp.py +0 -0
  94. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/constrained_pipe_jp.py +0 -0
  95. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/gal_ex58_parametric_jp.femprj +0 -0
  96. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/gal_ex58_parametric_jp.py +0 -0
  97. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/gau_ex08_parametric_jp.femprj +0 -0
  98. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/gau_ex08_parametric_jp.py +0 -0
  99. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/her_ex40_parametric_jp.femprj +0 -0
  100. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/her_ex40_parametric_jp.py +0 -0
  101. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/paswat_ex1_parametric_jp.femprj +0 -0
  102. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/paswat_ex1_parametric_jp.py +0 -0
  103. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/paswat_ex1_parametric_parallel_jp.py +0 -0
  104. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/wat_ex14_parametric_jp.femprj +0 -0
  105. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/wat_ex14_parametric_jp.py +0 -0
  106. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/samples/femprj_sample_jp/wat_ex14_parametric_parallel_jp.py +0 -0
  107. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/__init__.py +0 -0
  108. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/_base.py +0 -0
  109. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/_complex_components/__init__.py +0 -0
  110. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/_complex_components/alert_region.py +0 -0
  111. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/_complex_components/control_femtet.py +0 -0
  112. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/_complex_components/main_figure_creator.py +0 -0
  113. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/_complex_components/main_graph.py +0 -0
  114. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/_complex_components/pm_graph.py +0 -0
  115. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/_complex_components/pm_graph_creator.py +0 -0
  116. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/_create_wrapped_components.py +0 -0
  117. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/_process_monitor/__init__.py +0 -0
  118. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/_process_monitor/application.py +0 -0
  119. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/_process_monitor/pages.py +0 -0
  120. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/_wrapped_components/__init__.py +0 -0
  121. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/_wrapped_components/dbc.py +0 -0
  122. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/_wrapped_components/dcc.py +0 -0
  123. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/_wrapped_components/html.py +0 -0
  124. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/_wrapped_components/str_enum.py +0 -0
  125. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/result_viewer/.gitignore +0 -0
  126. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/result_viewer/__init__.py +0 -0
  127. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/result_viewer/application.py +0 -0
  128. {pyfemtet-0.7.0 → pyfemtet-0.7.1}/pyfemtet/opt/visualization/result_viewer/pages.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyfemtet
3
- Version: 0.7.0
3
+ Version: 0.7.1
4
4
  Summary: Design parameter optimization using Femtet.
5
5
  Home-page: https://github.com/pyfemtet/pyfemtet
6
6
  License: BSD-3-Clause
@@ -22,6 +22,7 @@ Requires-Dist: dash-bootstrap-components (>=1.5.0,<2.0.0)
22
22
  Requires-Dist: dask (>=2023.12.1,<2024.0.0)
23
23
  Requires-Dist: distributed (>=2023.12.1,<2024.0.0)
24
24
  Requires-Dist: femtetutils (>=1.0.0,<2.0.0)
25
+ Requires-Dist: fire (>=0.6.0,<0.7.0)
25
26
  Requires-Dist: numpy (>=1.26.2,<2.0.0)
26
27
  Requires-Dist: openpyxl (>=3.1.2,<4.0.0)
27
28
  Requires-Dist: optuna (>=3.4.0,<5.0.0)
@@ -0,0 +1 @@
1
+ __version__ = "0.7.1"
@@ -0,0 +1,10 @@
1
+ from contextlib import nullcontext
2
+ from dask.distributed import Lock
3
+
4
+
5
+ def lock_or_no_lock(name: str, client=None):
6
+ lock = Lock(name, client)
7
+ if lock.client is None:
8
+ return nullcontext()
9
+ else:
10
+ return lock
@@ -5,16 +5,27 @@ import asyncio # for timeout
5
5
  import win32gui
6
6
  import win32con
7
7
  import win32api
8
+ import win32process
8
9
 
9
10
  from pyfemtet.logger import get_module_logger
10
11
 
11
12
  logger = get_module_logger('util.excel', __name__)
12
13
 
13
14
 
15
+ def _get_pid(hwnd):
16
+ """Window handle から process ID を取得します."""
17
+ if hwnd > 0:
18
+ _, pid = win32process.GetWindowThreadProcessId(hwnd)
19
+ else:
20
+ pid = 0
21
+ return pid
22
+
23
+
14
24
  class _ExcelDialogProcessor:
15
25
 
16
26
  def __init__(self, excel_, timeout, restore_book=True):
17
27
  self.excel = excel_
28
+ self.excel_pid = _get_pid(excel_.hWnd)
18
29
  self.__excel_window_title = f' - Excel' # {basename} - Excel
19
30
  self.__error_dialog_title = 'Microsoft Visual Basic'
20
31
  self.__vbe_window_title = f'Microsoft Visual Basic for Applications - ' # Microsoft Visual Basic for Applications - {basename}
@@ -42,6 +53,7 @@ class _ExcelDialogProcessor:
42
53
  win32gui.EnumWindows(self.enum_callback_to_close_dialog, found)
43
54
  await asyncio.sleep(0.5)
44
55
  if any(found):
56
+ await asyncio.sleep(1.)
45
57
  break
46
58
 
47
59
  logger.debug('ブックを閉じます。')
@@ -56,7 +68,7 @@ class _ExcelDialogProcessor:
56
68
  def enum_callback_to_activate(self, hwnd, _):
57
69
  title = win32gui.GetWindowText(hwnd)
58
70
  # Excel 本体
59
- if self.__excel_window_title in title:
71
+ if (self.excel_pid == _get_pid(hwnd)) and (self.__excel_window_title in title):
60
72
  # Visible == True の際、エラーが発生した際、
61
73
  # 一度 Excel ウィンドウをアクティブ化しないと dialog が出てこない
62
74
  # が、これだけではダメかも。
@@ -65,7 +77,7 @@ class _ExcelDialogProcessor:
65
77
  def enum_callback_to_close_dialog(self, hwnd, found):
66
78
  title = win32gui.GetWindowText(hwnd)
67
79
  # エラーダイアログ
68
- if self.__error_dialog_title == title:
80
+ if (self.excel_pid == _get_pid(hwnd)) and (self.__error_dialog_title == title):
69
81
  # 何故かこのコマンド以外受け付けず、
70
82
  # このコマンドで問答無用でデバッグモードに入る
71
83
  logger.debug('エラーダイアログを見つけました。')
@@ -77,14 +89,14 @@ class _ExcelDialogProcessor:
77
89
  def enum_callback_to_close_confirm_dialog(self, hwnd, _):
78
90
  title = win32gui.GetWindowText(hwnd)
79
91
  # 確認ダイアログ
80
- if "Microsoft Excel" in title:
92
+ if (self.excel_pid == _get_pid(hwnd)) and ("Microsoft Excel" in title):
81
93
  # DisplayAlerts が False の場合は不要
82
94
  win32gui.SendMessage(hwnd, win32con.WM_SYSCOMMAND, win32con.SC_CLOSE, 0)
83
95
 
84
96
  def enum_callback_to_close_book(self, hwnd, _):
85
97
  title = win32gui.GetWindowText(hwnd)
86
98
  # VBE
87
- if self.__vbe_window_title in title:
99
+ if (self.excel_pid == _get_pid(hwnd)) and (self.__vbe_window_title in title):
88
100
  # 何故かこれで book 本体が閉じる
89
101
  win32gui.SendMessage(hwnd, win32con.WM_CLOSE, 0, 0)
90
102
 
@@ -12,7 +12,7 @@ from traceback import print_exception
12
12
  # 3rd-party
13
13
  import numpy as np
14
14
  import pandas as pd
15
- from dask.distributed import LocalCluster, Client
15
+ from dask.distributed import LocalCluster, Client, get_worker, Nanny
16
16
 
17
17
  # pyfemtet relative
18
18
  from pyfemtet.opt.interface import FEMInterface, FemtetInterface
@@ -136,6 +136,7 @@ class FEMOpt:
136
136
  self.monitor_server_kwargs = dict()
137
137
  self.monitor_process_worker_name = None
138
138
  self._hv_reference = None
139
+ self._extra_space_dir = None
139
140
 
140
141
  # multiprocess 時に pickle できないオブジェクト参照の削除
141
142
  def __getstate__(self):
@@ -675,10 +676,6 @@ class FEMOpt:
675
676
  directions,
676
677
  )
677
678
 
678
- # Femtet の confirm_before_exit のセット
679
- self.fem.confirm_before_exit = confirm_before_exit
680
- self.fem.kwargs['confirm_before_exit'] = confirm_before_exit
681
-
682
679
  logger.info('Femtet loaded successfully.')
683
680
 
684
681
  # クラスターの設定
@@ -718,30 +715,43 @@ class FEMOpt:
718
715
  # これは CLI の --no-nanny オプションも同様らしい。
719
716
 
720
717
  # クラスターの構築
718
+ # noinspection PyTypeChecker
721
719
  cluster = LocalCluster(
722
720
  processes=True,
723
721
  n_workers=n_parallel,
724
722
  threads_per_worker=1,
723
+ worker_class=Nanny,
725
724
  )
726
725
  logger.info('LocalCluster launched successfully.')
727
726
 
728
- self.client = Client(cluster, direct_to_workers=False)
729
- self.scheduler_address = self.client.scheduler.address
727
+ self.client = Client(
728
+ cluster,
729
+ direct_to_workers=False,
730
+ )
730
731
  logger.info('Client launched successfully.')
731
732
 
732
- # 最適化タスクを振り分ける worker を指定
733
- subprocess_indices = list(range(n_parallel))[1:]
734
- worker_addresses = list(self.client.nthreads().keys())
733
+ self.scheduler_address = self.client.scheduler.address
735
734
 
736
- # monitor worker の設定
737
- self.monitor_process_worker_name = worker_addresses[0]
738
- worker_addresses[0] = 'Main'
735
+ # worker address を取得
736
+ nannies_dict: dict[Any, Nanny] = self.client.cluster.workers
737
+ nannies = tuple(nannies_dict.values())
738
+
739
+ # ひとつの Nanny を選んで monitor 用にしつつ
740
+ # その space は main process に使わせるために記憶する
741
+ self.monitor_process_worker_name = nannies[0].worker_address
742
+ self._extra_space_dir = nannies[0].worker_dir
743
+
744
+ # 名前と address がごちゃごちゃになっていて可読性が悪いが
745
+ # 選んだ以外の Nanny は計算を割り当てる用にする
746
+ worker_addresses = ['Main']
747
+ worker_addresses.extend([n.worker_address for n in nannies[1:]])
748
+ subprocess_indices = list(range(n_parallel))[1:]
739
749
 
740
750
  with self.client.cluster as _cluster, self.client as _client:
741
751
 
742
752
  # actor の設定
743
- self.status = OptimizationStatus(_client)
744
- self.worker_status_list = [OptimizationStatus(_client, name) for name in worker_addresses] # tqdm 検討
753
+ self.status = OptimizationStatus(_client, worker_address=self.monitor_process_worker_name)
754
+ self.worker_status_list = [OptimizationStatus(_client, worker_address=self.monitor_process_worker_name, name=name) for name in worker_addresses] # tqdm 検討
745
755
  self.status.set(OptimizationStatus.SETTING_UP)
746
756
  self.history = History(
747
757
  self.history_path,
@@ -773,7 +783,6 @@ class FEMOpt:
773
783
  logger.info('Process monitor initialized successfully.')
774
784
 
775
785
  # fem
776
- # TODO: n_parallel=1 のときもアップロードしている。これを使うべきか、アップロードしないべき。
777
786
  self.fem._setup_before_parallel(_client)
778
787
 
779
788
  # opt
@@ -794,7 +803,7 @@ class FEMOpt:
794
803
  subprocess_indices,
795
804
  [self.worker_status_list] * len(subprocess_indices),
796
805
  [wait_setup] * len(subprocess_indices),
797
- workers=worker_addresses,
806
+ workers=worker_addresses if self.opt.is_cluster else worker_addresses[1:],
798
807
  allow_other_workers=False,
799
808
  )
800
809
 
@@ -818,6 +827,7 @@ class FEMOpt:
818
827
  ),
819
828
  kwargs=dict(
820
829
  skip_reconstruct=True,
830
+ space_dir=self._extra_space_dir,
821
831
  )
822
832
  )
823
833
  t_main.start()
@@ -980,8 +980,13 @@ class OptimizationStatus:
980
980
  TERMINATE_ALL = 60
981
981
  CRASHED = 70
982
982
 
983
- def __init__(self, client, name='entire'):
984
- self._future = client.submit(_OptimizationStatusActor, actor=True)
983
+ def __init__(self, client, worker_address, name='entire'):
984
+ self._future = client.submit(
985
+ _OptimizationStatusActor,
986
+ actor=True,
987
+ workers=[worker_address],
988
+ allow_other_workers=False,
989
+ )
985
990
  self._actor = self._future.result()
986
991
  self.name = name
987
992
  self.set(self.INITIALIZING)