pyfemtet 0.9.5__py3-none-any.whl → 1.0.0b0__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 pyfemtet might be problematic. Click here for more details.

Files changed (272) hide show
  1. pyfemtet/__init__.py +6 -1
  2. pyfemtet/_i18n/1. make_pot_and_update_po.bat +8 -0
  3. pyfemtet/_i18n/2. build_mo.bat +5 -0
  4. pyfemtet/_i18n/__init__.py +4 -0
  5. pyfemtet/_i18n/babel.cfg +2 -0
  6. pyfemtet/_i18n/i18n.py +37 -0
  7. pyfemtet/_i18n/locales/ja/LC_MESSAGES/messages.mo +0 -0
  8. pyfemtet/_i18n/locales/ja/LC_MESSAGES/messages.po +1020 -0
  9. pyfemtet/_i18n/locales/messages.pot +987 -0
  10. pyfemtet/{_message → _i18n}/messages.py +128 -41
  11. pyfemtet/_util/closing.py +19 -0
  12. pyfemtet/_util/dask_util.py +89 -7
  13. pyfemtet/_util/df_util.py +29 -0
  14. pyfemtet/_util/excel_macro_util.py +8 -3
  15. pyfemtet/_util/excel_parse_util.py +43 -23
  16. pyfemtet/_util/femtet_access_inspection.py +120 -0
  17. pyfemtet/{_femtet_config_util/autosave.py → _util/femtet_autosave.py} +7 -0
  18. pyfemtet/_util/femtet_exit.py +105 -0
  19. pyfemtet/_util/femtet_version.py +20 -0
  20. pyfemtet/_util/helper.py +94 -0
  21. pyfemtet/_util/process_util.py +107 -0
  22. pyfemtet/_util/str_enum.py +44 -0
  23. pyfemtet/core.py +15 -47
  24. pyfemtet/dispatch_extensions/__init__.py +8 -11
  25. pyfemtet/dispatch_extensions/_impl.py +42 -198
  26. pyfemtet/logger/__init__.py +8 -1
  27. pyfemtet/logger/_impl.py +5 -6
  28. pyfemtet/opt/__init__.py +3 -17
  29. pyfemtet/opt/exceptions.py +45 -0
  30. pyfemtet/opt/femopt.py +608 -0
  31. pyfemtet/opt/history/__init__.py +11 -0
  32. pyfemtet/opt/history/_history.py +1404 -0
  33. pyfemtet/opt/history/_hypervolume.py +169 -0
  34. pyfemtet/opt/history/_optimality.py +79 -0
  35. pyfemtet/opt/interface/__init__.py +17 -24
  36. pyfemtet/opt/interface/_base_interface.py +222 -0
  37. pyfemtet/opt/interface/_excel_interface/__init__.py +3 -0
  38. pyfemtet/opt/interface/_excel_interface/debug-excel-interface.xlsm +0 -0
  39. pyfemtet/opt/interface/_excel_interface/excel_interface.py +999 -0
  40. pyfemtet/opt/interface/_femtet_interface/__init__.py +3 -0
  41. pyfemtet/opt/interface/{_femtet_parametric.py → _femtet_interface/_femtet_parametric.py} +20 -12
  42. pyfemtet/opt/interface/{_femtet.py → _femtet_interface/femtet_interface.py} +505 -349
  43. pyfemtet/opt/interface/_femtet_with_nx_interface/__init__.py +5 -0
  44. pyfemtet/opt/interface/_femtet_with_nx_interface/femtet_with_nx_interface.py +230 -0
  45. pyfemtet/opt/interface/_femtet_with_nx_interface/model1.prt +0 -0
  46. pyfemtet/opt/interface/_femtet_with_nx_interface/model1.x_t +98 -0
  47. pyfemtet/opt/interface/{_femtet_with_nx → _femtet_with_nx_interface}/update_model.py +1 -3
  48. pyfemtet/opt/interface/_femtet_with_solidworks/__init__.py +5 -0
  49. pyfemtet/opt/interface/_femtet_with_solidworks/femtet_with_solidworks_interface.py +122 -0
  50. pyfemtet/opt/interface/_solidworks_interface/__init__.py +5 -0
  51. pyfemtet/opt/interface/_solidworks_interface/solidworks_interface.py +206 -0
  52. pyfemtet/opt/interface/_surrogate_model_interface/__init__.py +8 -0
  53. pyfemtet/opt/interface/_surrogate_model_interface/base_surrogate_interface.py +150 -0
  54. pyfemtet/opt/interface/_surrogate_model_interface/botorch_interface.py +298 -0
  55. pyfemtet/opt/interface/_surrogate_model_interface/debug-pof-botorch.reccsv +18 -0
  56. pyfemtet/opt/interface/_with_excel_settings/__init__.py +61 -0
  57. pyfemtet/opt/interface/_with_excel_settings/with_excel_settings.py +134 -0
  58. pyfemtet/opt/meta_script/YAML_Generator.xlsm +0 -0
  59. pyfemtet/opt/meta_script/__main__.py +58 -36
  60. pyfemtet/opt/optimizer/__init__.py +7 -9
  61. pyfemtet/opt/optimizer/_base_optimizer.py +885 -0
  62. pyfemtet/opt/optimizer/optuna_optimizer/__init__.py +9 -0
  63. pyfemtet/opt/optimizer/optuna_optimizer/_optuna_attribute.py +73 -0
  64. pyfemtet/opt/optimizer/optuna_optimizer/_optuna_optimizer.py +678 -0
  65. pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/__init__.py +7 -0
  66. pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/debug-pof-botorch.reccsv +18 -0
  67. pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/enable_nonlinear_constraint.py +244 -0
  68. pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/pof_botorch_sampler.py +1249 -0
  69. pyfemtet/opt/optimizer/optuna_optimizer/wat_ex14_parametric_jp.femprj +0 -0
  70. pyfemtet/opt/optimizer/scipy_optimizer/__init__.py +1 -0
  71. pyfemtet/opt/optimizer/scipy_optimizer/_scipy_optimizer.py +364 -0
  72. pyfemtet/opt/prediction/__init__.py +7 -0
  73. pyfemtet/opt/prediction/_botorch_utils.py +133 -0
  74. pyfemtet/opt/prediction/_gpytorch_modules_extension.py +142 -0
  75. pyfemtet/opt/prediction/_helper.py +155 -0
  76. pyfemtet/opt/prediction/_model.py +118 -0
  77. pyfemtet/opt/problem/problem.py +304 -0
  78. pyfemtet/opt/problem/variable_manager/__init__.py +20 -0
  79. pyfemtet/opt/problem/variable_manager/_string_as_expression.py +115 -0
  80. pyfemtet/opt/problem/variable_manager/_variable_manager.py +295 -0
  81. pyfemtet/opt/visualization/history_viewer/__main__.py +5 -0
  82. pyfemtet/opt/visualization/{_base.py → history_viewer/_base_application.py} +18 -13
  83. pyfemtet/opt/visualization/history_viewer/_common_pages.py +150 -0
  84. pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/alert_region.py +10 -5
  85. pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/control_femtet.py +16 -13
  86. pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/main_graph.py +117 -47
  87. pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/pm_graph.py +159 -138
  88. pyfemtet/opt/visualization/history_viewer/_process_monitor/_application.py +173 -0
  89. pyfemtet/opt/visualization/history_viewer/_process_monitor/_pages.py +291 -0
  90. pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/dbc.py +1 -1
  91. pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/dcc.py +1 -1
  92. pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/html.py +1 -1
  93. pyfemtet/opt/visualization/history_viewer/result_viewer/__main__.py +5 -0
  94. pyfemtet/opt/visualization/{result_viewer/application.py → history_viewer/result_viewer/_application.py} +6 -6
  95. pyfemtet/opt/visualization/{result_viewer/pages.py → history_viewer/result_viewer/_pages.py} +106 -82
  96. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08.csv +18 -0
  97. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08.db +0 -0
  98. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8.jpg +0 -0
  99. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8.log +45 -0
  100. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8.pdt +0 -0
  101. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_1.jpg +0 -0
  102. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_1.pdt +0 -0
  103. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_10.jpg +0 -0
  104. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_10.pdt +0 -0
  105. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_11.jpg +0 -0
  106. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_11.pdt +0 -0
  107. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_12.jpg +0 -0
  108. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_12.pdt +0 -0
  109. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_13.jpg +0 -0
  110. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_13.pdt +0 -0
  111. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_14.jpg +0 -0
  112. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_14.pdt +0 -0
  113. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_15.jpg +0 -0
  114. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_15.pdt +0 -0
  115. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_16.jpg +0 -0
  116. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_16.pdt +0 -0
  117. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_17.jpg +0 -0
  118. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_17.pdt +0 -0
  119. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_18.jpg +0 -0
  120. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_18.pdt +0 -0
  121. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_19.jpg +0 -0
  122. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_19.pdt +0 -0
  123. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_2.jpg +0 -0
  124. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_2.pdt +0 -0
  125. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_20.jpg +0 -0
  126. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_20.pdt +0 -0
  127. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_3.jpg +0 -0
  128. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_3.pdt +0 -0
  129. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.bgr +0 -0
  130. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.bnd +0 -0
  131. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.btr +0 -0
  132. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.jpg +0 -0
  133. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.mtl +0 -0
  134. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.pdt +0 -0
  135. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.prm +0 -0
  136. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_5.jpg +0 -0
  137. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_5.pdt +0 -0
  138. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_6.jpg +0 -0
  139. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_6.pdt +0 -0
  140. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_7.jpg +0 -0
  141. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_7.pdt +0 -0
  142. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_8.jpg +0 -0
  143. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_8.pdt +0 -0
  144. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_9.jpg +0 -0
  145. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_9.pdt +0 -0
  146. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.femprj +0 -0
  147. pyfemtet/opt/visualization/plotter/main_figure_creator.py +536 -0
  148. pyfemtet/opt/visualization/plotter/pm_graph_creator.py +359 -0
  149. pyfemtet/opt/worker_status.py +120 -0
  150. {pyfemtet-0.9.5.dist-info → pyfemtet-1.0.0b0.dist-info}/METADATA +23 -24
  151. pyfemtet-1.0.0b0.dist-info/RECORD +172 -0
  152. pyfemtet-1.0.0b0.dist-info/entry_points.txt +3 -0
  153. pyfemtet/_femtet_config_util/exit.py +0 -59
  154. pyfemtet/_message/1. make_pot.bat +0 -11
  155. pyfemtet/_message/2. make_mo.bat +0 -6
  156. pyfemtet/_message/__init__.py +0 -5
  157. pyfemtet/_message/babel.cfg +0 -2
  158. pyfemtet/_message/locales/ja/LC_MESSAGES/messages.mo +0 -0
  159. pyfemtet/_message/locales/ja/LC_MESSAGES/messages.po +0 -570
  160. pyfemtet/_message/locales/messages.pot +0 -551
  161. pyfemtet/_warning.py +0 -87
  162. pyfemtet/brep/_impl.py +0 -18
  163. pyfemtet/opt/_femopt.py +0 -1007
  164. pyfemtet/opt/_femopt_core.py +0 -1169
  165. pyfemtet/opt/_test_utils/control_femtet.py +0 -39
  166. pyfemtet/opt/_test_utils/hyper_sphere.py +0 -24
  167. pyfemtet/opt/_test_utils/record_history.py +0 -130
  168. pyfemtet/opt/advanced_samples/excel_ui/(ref) original_project.femprj +0 -0
  169. pyfemtet/opt/advanced_samples/excel_ui/femtet-macro.xlsm +0 -0
  170. pyfemtet/opt/advanced_samples/excel_ui/pyfemtet-core.py +0 -291
  171. pyfemtet/opt/advanced_samples/excel_ui/test-pyfemtet-core.cmd +0 -22
  172. pyfemtet/opt/advanced_samples/restart/gal_ex13_parametric.femprj +0 -0
  173. pyfemtet/opt/advanced_samples/restart/gal_ex13_parametric_restart.py +0 -99
  174. pyfemtet/opt/advanced_samples/restart/gal_ex13_parametric_restart_jp.py +0 -102
  175. pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_create_training_data.py +0 -60
  176. pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_create_training_data_jp.py +0 -57
  177. pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_optimize_with_surrogate.py +0 -100
  178. pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_optimize_with_surrogate_jp.py +0 -90
  179. pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_parametric.femprj +0 -0
  180. pyfemtet/opt/interface/_base.py +0 -101
  181. pyfemtet/opt/interface/_excel_interface.py +0 -984
  182. pyfemtet/opt/interface/_femtet_excel.py +0 -141
  183. pyfemtet/opt/interface/_femtet_with_nx/__init__.py +0 -3
  184. pyfemtet/opt/interface/_femtet_with_nx/_interface.py +0 -178
  185. pyfemtet/opt/interface/_femtet_with_sldworks.py +0 -298
  186. pyfemtet/opt/interface/_surrogate/__init__.py +0 -5
  187. pyfemtet/opt/interface/_surrogate/_base.py +0 -129
  188. pyfemtet/opt/interface/_surrogate/_chaospy.py +0 -71
  189. pyfemtet/opt/interface/_surrogate/_singletaskgp.py +0 -71
  190. pyfemtet/opt/interface/_surrogate_excel.py +0 -102
  191. pyfemtet/opt/optimizer/_base.py +0 -376
  192. pyfemtet/opt/optimizer/_optuna/_botorch_patch/enable_nonlinear_constraint.py +0 -220
  193. pyfemtet/opt/optimizer/_optuna/_optuna.py +0 -434
  194. pyfemtet/opt/optimizer/_optuna/_pof_botorch.py +0 -1914
  195. pyfemtet/opt/optimizer/_scipy.py +0 -159
  196. pyfemtet/opt/optimizer/_scipy_scalar.py +0 -127
  197. pyfemtet/opt/optimizer/parameter.py +0 -113
  198. pyfemtet/opt/prediction/_base.py +0 -61
  199. pyfemtet/opt/prediction/single_task_gp.py +0 -119
  200. pyfemtet/opt/samples/femprj_sample/ParametricIF.femprj +0 -0
  201. pyfemtet/opt/samples/femprj_sample/ParametricIF.py +0 -29
  202. pyfemtet/opt/samples/femprj_sample/ParametricIF_test_result.reccsv +0 -13
  203. pyfemtet/opt/samples/femprj_sample/cad_ex01_NX.femprj +0 -0
  204. pyfemtet/opt/samples/femprj_sample/cad_ex01_NX.prt +0 -0
  205. pyfemtet/opt/samples/femprj_sample/cad_ex01_NX.py +0 -135
  206. pyfemtet/opt/samples/femprj_sample/cad_ex01_NX_test_result.reccsv +0 -23
  207. pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.SLDPRT +0 -0
  208. pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.femprj +0 -0
  209. pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.py +0 -131
  210. pyfemtet/opt/samples/femprj_sample/cad_ex01_SW_test_result.reccsv +0 -23
  211. pyfemtet/opt/samples/femprj_sample/constrained_pipe.femprj +0 -0
  212. pyfemtet/opt/samples/femprj_sample/constrained_pipe.py +0 -96
  213. pyfemtet/opt/samples/femprj_sample/constrained_pipe_test_result.reccsv +0 -13
  214. pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric.femprj +0 -0
  215. pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric.py +0 -74
  216. pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric_test_result.reccsv +0 -13
  217. pyfemtet/opt/samples/femprj_sample/gau_ex08_parametric.femprj +0 -0
  218. pyfemtet/opt/samples/femprj_sample/gau_ex08_parametric.py +0 -58
  219. pyfemtet/opt/samples/femprj_sample/gau_ex08_parametric_test_result.reccsv +0 -23
  220. pyfemtet/opt/samples/femprj_sample/gau_ex12_parametric.femprj +0 -0
  221. pyfemtet/opt/samples/femprj_sample/gau_ex12_parametric.py +0 -52
  222. pyfemtet/opt/samples/femprj_sample/her_ex40_parametric.femprj +0 -0
  223. pyfemtet/opt/samples/femprj_sample/her_ex40_parametric.py +0 -138
  224. pyfemtet/opt/samples/femprj_sample/her_ex40_parametric_test_result.reccsv +0 -18
  225. pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric.femprj +0 -0
  226. pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric.py +0 -60
  227. pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric_parallel.py +0 -61
  228. pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric_test_result.reccsv +0 -18
  229. pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric.femprj +0 -0
  230. pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric.py +0 -58
  231. pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric_parallel.py +0 -58
  232. pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric_test_result.reccsv +0 -18
  233. pyfemtet/opt/samples/femprj_sample_jp/ParametricIF_jp.femprj +0 -0
  234. pyfemtet/opt/samples/femprj_sample_jp/ParametricIF_jp.py +0 -29
  235. pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_NX_jp.femprj +0 -0
  236. pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_NX_jp.py +0 -129
  237. pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_SW_jp.femprj +0 -0
  238. pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_SW_jp.py +0 -125
  239. pyfemtet/opt/samples/femprj_sample_jp/constrained_pipe_jp.py +0 -93
  240. pyfemtet/opt/samples/femprj_sample_jp/gal_ex58_parametric_jp.femprj +0 -0
  241. pyfemtet/opt/samples/femprj_sample_jp/gal_ex58_parametric_jp.py +0 -70
  242. pyfemtet/opt/samples/femprj_sample_jp/gau_ex08_parametric_jp.femprj +0 -0
  243. pyfemtet/opt/samples/femprj_sample_jp/gau_ex08_parametric_jp.py +0 -57
  244. pyfemtet/opt/samples/femprj_sample_jp/gau_ex12_parametric_jp.py +0 -52
  245. pyfemtet/opt/samples/femprj_sample_jp/her_ex40_parametric_jp.femprj +0 -0
  246. pyfemtet/opt/samples/femprj_sample_jp/her_ex40_parametric_jp.py +0 -138
  247. pyfemtet/opt/samples/femprj_sample_jp/paswat_ex1_parametric_jp.femprj +0 -0
  248. pyfemtet/opt/samples/femprj_sample_jp/paswat_ex1_parametric_jp.py +0 -58
  249. pyfemtet/opt/samples/femprj_sample_jp/paswat_ex1_parametric_parallel_jp.py +0 -59
  250. pyfemtet/opt/samples/femprj_sample_jp/wat_ex14_parametric_jp.py +0 -56
  251. pyfemtet/opt/samples/femprj_sample_jp/wat_ex14_parametric_parallel_jp.py +0 -56
  252. pyfemtet/opt/visualization/_complex_components/main_figure_creator.py +0 -332
  253. pyfemtet/opt/visualization/_complex_components/pm_graph_creator.py +0 -201
  254. pyfemtet/opt/visualization/_process_monitor/application.py +0 -226
  255. pyfemtet/opt/visualization/_process_monitor/pages.py +0 -406
  256. pyfemtet/opt/visualization/_wrapped_components/__init__.py +0 -0
  257. pyfemtet/opt/visualization/result_viewer/__init__.py +0 -0
  258. pyfemtet-0.9.5.dist-info/RECORD +0 -158
  259. pyfemtet-0.9.5.dist-info/entry_points.txt +0 -3
  260. /pyfemtet/{_femtet_config_util → opt/problem}/__init__.py +0 -0
  261. /pyfemtet/{brep → opt/visualization/history_viewer}/__init__.py +0 -0
  262. /pyfemtet/opt/{_test_utils → visualization/history_viewer/_complex_components}/__init__.py +0 -0
  263. /pyfemtet/opt/{optimizer/_optuna → visualization/history_viewer/_process_monitor}/__init__.py +0 -0
  264. /pyfemtet/opt/{optimizer/_optuna/_botorch_patch → visualization/history_viewer/_wrapped_components}/__init__.py +0 -0
  265. /pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/str_enum.py +0 -0
  266. /pyfemtet/opt/visualization/{result_viewer → history_viewer/result_viewer}/.gitignore +0 -0
  267. /pyfemtet/opt/visualization/{_complex_components → history_viewer/result_viewer}/__init__.py +0 -0
  268. /pyfemtet/opt/visualization/{_process_monitor → plotter}/__init__.py +0 -0
  269. /pyfemtet/opt/{samples/femprj_sample_jp/wat_ex14_parametric_jp.femprj → wat_ex14_parametric_jp.femprj} +0 -0
  270. {pyfemtet-0.9.5.dist-info → pyfemtet-1.0.0b0.dist-info}/LICENSE +0 -0
  271. {pyfemtet-0.9.5.dist-info → pyfemtet-1.0.0b0.dist-info}/LICENSE_THIRD_PARTY.txt +0 -0
  272. {pyfemtet-0.9.5.dist-info → pyfemtet-1.0.0b0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,678 @@
1
+ from __future__ import annotations
2
+
3
+ import gc
4
+ import os
5
+ import inspect
6
+ import tempfile
7
+ import warnings
8
+ from time import sleep
9
+ from contextlib import suppress, nullcontext
10
+
11
+ import numpy as np
12
+
13
+ import optuna
14
+ from optuna.samplers import TPESampler
15
+ from optuna.study import MaxTrialsCallback
16
+ from optuna_integration.dask import DaskStorage
17
+
18
+ from pyfemtet._i18n import _
19
+ from pyfemtet.opt.history import *
20
+ from pyfemtet.opt.interface import *
21
+ from pyfemtet.opt.exceptions import *
22
+ from pyfemtet.opt.problem.variable_manager import *
23
+ from pyfemtet._util.dask_util import *
24
+ from pyfemtet._util.closing import closing
25
+ from pyfemtet.logger import get_optuna_logger, remove_all_output, get_module_logger
26
+
27
+ from pyfemtet.opt.optimizer._base_optimizer import *
28
+ from pyfemtet.opt.optimizer.optuna_optimizer._optuna_attribute import OptunaAttribute
29
+ from pyfemtet.opt.optimizer.optuna_optimizer._pof_botorch.pof_botorch_sampler import PoFBoTorchSampler
30
+ from pyfemtet.opt.worker_status import WorkerStatus
31
+
32
+ logger = get_module_logger('opt.optimizer', False)
33
+
34
+ remove_all_output(get_optuna_logger())
35
+
36
+ warnings.filterwarnings('ignore', 'set_metric_names', optuna.exceptions.ExperimentalWarning)
37
+ warnings.filterwarnings('ignore', 'Argument ``constraints_func`` is an experimental feature.',
38
+ optuna.exceptions.ExperimentalWarning)
39
+
40
+
41
+ class OptunaOptimizer(AbstractOptimizer):
42
+ # system
43
+ study_name = 'pyfemtet-study'
44
+ storage: str | optuna.storages.BaseStorage
45
+ storage_path: str
46
+ current_trial: optuna.trial.Trial | None
47
+
48
+ # settings
49
+ # sampler: optuna.samplers.BaseSampler | None = None # reseed_rng が seed 指定できないため
50
+ sampler_class: type[optuna.samplers.BaseSampler]
51
+ sampler_kwargs: dict
52
+ n_trials: int | None
53
+ timeout: float | None
54
+ callbacks: list
55
+
56
+ def __init__(
57
+ self,
58
+ sampler_class: type[optuna.samplers.BaseSampler] = None,
59
+ sampler_kwargs: dict[str, ...] = None,
60
+ ):
61
+ super().__init__()
62
+ self.sampler_kwargs = sampler_kwargs or {}
63
+ self.sampler_class = sampler_class or TPESampler
64
+ self.n_trials: int | None = None
65
+ self.timeout: float | None = None
66
+ self.callbacks = []
67
+
68
+ # ===== method checker =====
69
+ # noinspection PyMethodOverriding
70
+ def add_parameter(
71
+ self,
72
+ name: str,
73
+ initial_value: float,
74
+ lower_bound: float,
75
+ upper_bound: float,
76
+ step: float | None = None,
77
+ properties: dict[str, ...] | None = None,
78
+ *,
79
+ pass_to_fem: bool = True,
80
+ fix: bool = False,
81
+ ) -> None:
82
+ AbstractOptimizer.add_parameter(self, name, initial_value, lower_bound, upper_bound, step, properties,
83
+ pass_to_fem=pass_to_fem, fix=fix)
84
+
85
+ # noinspection PyMethodOverriding
86
+ def add_categorical_parameter(
87
+ self,
88
+ name: str,
89
+ initial_value: str,
90
+ choices: list[str],
91
+ properties: dict[str, ...] | None = None,
92
+ *,
93
+ pass_to_fem: bool = True,
94
+ fix: bool = False,
95
+ ) -> None:
96
+ AbstractOptimizer.add_categorical_parameter(self, name, initial_value, choices, properties,
97
+ pass_to_fem=pass_to_fem, fix=fix)
98
+
99
+ class _SolveSet(AbstractOptimizer._SolveSet):
100
+ opt: OptunaOptimizer
101
+ optuna_attr: OptunaAttribute
102
+
103
+ def _preprocess(self):
104
+ # prepare attribute
105
+ self.optuna_attr = OptunaAttribute(self.opt_)
106
+
107
+ def _common(self, e):
108
+ # if (hidden) constraint violation, set trial attribute
109
+ self.optuna_attr.pf_state = TrialState.get_corresponding_state_from_exception(e)
110
+ self.optuna_attr.v_values = self.opt._create_infeasible_constraints(self.opt_)
111
+
112
+ def _hard_constraint_handling(self, e: HardConstraintViolation):
113
+ self._common(e)
114
+
115
+ def _hidden_constraint_handling(self, e: _HiddenConstraintViolation):
116
+ self._common(e)
117
+
118
+ def _skip_handling(self, e: SkipSolve):
119
+ self.optuna_attr.pf_state = TrialState.skipped
120
+
121
+ def _if_succeeded(self, f_return: _FReturnValue):
122
+
123
+ y, dict_y_internal, c, record = f_return
124
+
125
+ # convert constraint to **sorted** violation
126
+ assert len(c) == len(self.opt_.constraints)
127
+ v = {}
128
+ for cns_name, cns in self.opt_.constraints.items():
129
+ # This is {lower or upper: violation_value} dict
130
+ violation: dict[str, float] = c[cns_name].calc_violation()
131
+ for l_or_u, violation_value in violation.items():
132
+ key_ = cns_name + '_' + l_or_u
133
+ v.update({key_: violation_value})
134
+
135
+ # register results
136
+ self.optuna_attr.v_values = tuple(v.values())
137
+ self.optuna_attr.y_values = tuple(dict_y_internal.values())
138
+ self.optuna_attr.pf_state = record.state
139
+
140
+ def _postprocess(self):
141
+ # update trial attribute
142
+ self.opt.current_trial.set_user_attr(
143
+ self.optuna_attr.key,
144
+ self.optuna_attr.value,
145
+ )
146
+
147
+ def _create_infeasible_constraints(self, opt_: AbstractOptimizer = None) -> tuple:
148
+ opt_ = opt_ if opt_ is not None else self
149
+ count = 0
150
+ for name, cns in opt_.constraints.items():
151
+ if cns.lower_bound is not None:
152
+ count += 1
153
+ if cns.upper_bound is not None:
154
+ count += 1
155
+ return tuple(1e9 * np.ones(count, dtype=np.float64))
156
+
157
+ def _constraint(self, trial: optuna.trial.FrozenTrial):
158
+ key = OptunaAttribute(self).key
159
+ value = trial.user_attrs[key]
160
+ return OptunaAttribute.get_violation_from_trial_attr(value)
161
+
162
+ def _objective(self, trial: optuna.trial.Trial):
163
+
164
+ self.current_trial = trial
165
+
166
+ with self._logging():
167
+
168
+ vm = self.variable_manager
169
+
170
+ # check interruption
171
+ self._check_and_raise_interruption()
172
+
173
+ # parameter suggestion
174
+ params = vm.get_variables(filter='parameter')
175
+ for name, prm in params.items():
176
+
177
+ if prm.properties.get('fix', False): # default is False
178
+ continue
179
+
180
+ if isinstance(prm, NumericParameter):
181
+ prm.value = trial.suggest_float(
182
+ name,
183
+ prm.lower_bound,
184
+ prm.upper_bound,
185
+ step=prm.step,
186
+ log=prm.properties.get('log', __default := False),
187
+ )
188
+ elif isinstance(prm, CategoricalParameter):
189
+ prm.value = trial.suggest_categorical(
190
+ name, prm.choices
191
+ )
192
+ else:
193
+ raise NotImplementedError
194
+
195
+ # evaluate expressions
196
+ vm.eval_expressions()
197
+
198
+ # check interruption
199
+ self._check_and_raise_interruption()
200
+
201
+ # construct TrialInput
202
+ x = vm.get_variables(filter='parameter')
203
+ x_pass_to_fem: dict[str, SupportedVariableTypes] = vm.get_variables(filter='pass_to_fem', format='dict')
204
+
205
+ # prepare solve
206
+ solve_set = self._get_solve_set()
207
+
208
+ # process main fidelity model
209
+ f_return = solve_set.solve(x, x_pass_to_fem)
210
+ if f_return is None:
211
+ y_internal: None = None
212
+ else:
213
+ y_internal: tuple[float] = tuple(f_return[1].values()) # type: ignore
214
+
215
+ # process sub_fidelity_models
216
+ for sub_fidelity_name, sub_opt in self.sub_fidelity_models.items():
217
+ # _SolveSet に特殊な初期化を入れていないので
218
+ # sub fidelity でも初期化せず使用可能
219
+ solve_set.solve(x, x_pass_to_fem, sub_opt)
220
+
221
+ # check interruption
222
+ self._check_and_raise_interruption()
223
+
224
+ # clear trial
225
+ self.current_trial = None
226
+
227
+ # To avoid trial FAILED with hard constraint
228
+ # violation, check pf_state and raise TrialPruned.
229
+ key = OptunaAttribute(self).key
230
+ value = trial.user_attrs[key]
231
+ state = OptunaAttribute.get_pf_state_from_trial_attr(value)
232
+ if state in [
233
+ TrialState.hard_constraint_violation,
234
+ TrialState.model_error,
235
+ TrialState.mesh_error,
236
+ TrialState.solve_error,
237
+ TrialState.post_error,
238
+ ]:
239
+ raise optuna.TrialPruned
240
+
241
+ # if main solve skipped, y_internal is empty.
242
+ # this should be processed as FAIL.
243
+ elif state == TrialState.skipped:
244
+ return None
245
+
246
+ return y_internal
247
+
248
+ if get_client() is None:
249
+ self.history.save()
250
+
251
+ def _get_callback(self, n_trials: int):
252
+
253
+ # restart である場合、追加 N 回と見做す
254
+ if self.history.is_restart:
255
+ df = self.history.get_df(equality_filters=MAIN_FILTER)
256
+ n_existing_succeeded_trials = len(df[df['state'] == TrialState.succeeded])
257
+ n_trials = n_trials + n_existing_succeeded_trials
258
+
259
+ return MaxTrialsCallback(n_trials, states=(optuna.trial.TrialState.COMPLETE,))
260
+
261
+ def _setup_before_parallel(self):
262
+
263
+ if self._done_setup_before_parallel:
264
+ return
265
+
266
+ AbstractOptimizer._setup_before_parallel(self) # set flag inside this
267
+
268
+ # set default values
269
+ self.sampler_class = self.sampler_class or optuna.samplers.TPESampler
270
+ self.sampler_kwargs = self.sampler_kwargs or {}
271
+
272
+ # remove automatically-given arguments
273
+ if 'seed' in self.sampler_kwargs:
274
+ warnings.warn('sampler_kwargs `seed` は'
275
+ 'Optimizer.set_random_seed() で'
276
+ '与えてください。引数は無視されます。')
277
+ self.sampler_kwargs.pop('seed')
278
+ if 'constraints_func' in self.sampler_kwargs:
279
+ warnings.warn('sampler_kwargs `constraints_func` は'
280
+ 'pyfemtet.opt の内部で自動的に与えられます。'
281
+ '引数は無視されます。')
282
+ self.sampler_kwargs.pop('constraints_func')
283
+
284
+ # create storage path
285
+ self.storage_path = self.history.path.removesuffix('.csv') + '.db'
286
+
287
+ # file check
288
+ if self.history.is_restart:
289
+ # check db file existing
290
+ if not os.path.exists(self.storage_path):
291
+ raise FileNotFoundError(self.storage_path)
292
+ else:
293
+ # certify no db file
294
+ if os.path.isfile(self.storage_path):
295
+ os.remove(self.storage_path)
296
+
297
+ # if TPESampler and re-starting,
298
+ # create temporary study to avoid error
299
+ # with many pruned trials.
300
+ if issubclass(self.sampler_class, optuna.samplers.TPESampler) \
301
+ and self.history.is_restart:
302
+ # get unique tmp file
303
+ tmp_storage_path = tempfile.mktemp(suffix='.db')
304
+ self._existing_storage_path = self.storage_path
305
+ self.storage_path = tmp_storage_path
306
+
307
+ # load existing study
308
+ existing_study = optuna.load_study(
309
+ study_name=self.study_name,
310
+ storage=f'sqlite:///{self._existing_storage_path}',
311
+ )
312
+
313
+ # create new study
314
+ tmp_study = optuna.create_study(
315
+ study_name=self.study_name,
316
+ storage=f'sqlite:///{self.storage_path}',
317
+ load_if_exists=True,
318
+ directions=['minimize'] * len(self.objectives),
319
+ )
320
+
321
+ # Copy COMPLETE trials to temporary study.
322
+ existing_trials = existing_study.get_trials(states=(optuna.trial.TrialState.COMPLETE,))
323
+ tmp_study.add_trials(existing_trials)
324
+
325
+ # setup storage
326
+ client = get_client()
327
+ if client is None:
328
+ self.storage = optuna.storages.get_storage(f'sqlite:///{self.storage_path}')
329
+ else:
330
+ self.storage = DaskStorage(
331
+ f'sqlite:///{self.storage_path}'
332
+ )
333
+
334
+ # if new study, create it.
335
+ if not self.history.is_restart:
336
+ # create study
337
+ study = optuna.create_study(
338
+ study_name=self.study_name,
339
+ storage=self.storage,
340
+ load_if_exists=True,
341
+ directions=['minimize'] * len(self.objectives),
342
+ )
343
+
344
+ # set objective names
345
+ study.set_metric_names(list(self.objectives.keys()))
346
+
347
+ # initial trial
348
+ params = self.variable_manager.get_variables(format='dict', filter='parameter')
349
+ study.enqueue_trial(params, user_attrs={"message": "Initial values"})
350
+
351
+ def _setup_after_parallel(self):
352
+ # reseed
353
+ worker = get_worker()
354
+ if worker is not None:
355
+ # self.sampler.reseed_rng() # サブプロセスのランダム化が固定されない
356
+ idx = self._worker_index
357
+ assert isinstance(idx, int)
358
+ if self.seed is not None:
359
+ self.seed += idx
360
+
361
+ def _is_tpe_addressing(self):
362
+ out = False
363
+ if hasattr(self, '_existing_storage_path'):
364
+ if self._existing_storage_path is not None:
365
+ assert os.path.isfile(self._existing_storage_path)
366
+ out = True
367
+ return out
368
+
369
+ def _removing_tmp_db_if_needed(self):
370
+
371
+ if not self._is_tpe_addressing():
372
+ return nullcontext()
373
+
374
+ # noinspection PyMethodParameters
375
+ class RemovingTempDB:
376
+ def __enter__(self_):
377
+ pass
378
+
379
+ def __exit__(self_, exc_type, exc_val, exc_tb):
380
+
381
+ # clean up temporary file
382
+ if isinstance(self.storage, optuna.storages._CachedStorage):
383
+ rdb_storage = self.storage._backend
384
+ elif isinstance(self.storage, optuna.storages.RDBStorage):
385
+ rdb_storage = self.storage
386
+ elif isinstance(self.storage, DaskStorage):
387
+ base_storage = self.storage.get_base_storage()
388
+ assert isinstance(base_storage, optuna.storages._CachedStorage)
389
+ rdb_storage = base_storage._backend
390
+ else:
391
+ raise NotImplementedError(f'{type(self.storage)=}')
392
+
393
+ assert isinstance(rdb_storage, optuna.storages.RDBStorage)
394
+
395
+ client = get_client()
396
+
397
+ # 最後のプロセスにしか消せないので、
398
+ # 各 worker は dispose だけは行い、
399
+ # 削除は失敗しても気にしないことにする
400
+
401
+ if client is None:
402
+ # 通常 dispose
403
+ rdb_storage.engine.dispose()
404
+
405
+ # run_on_scheduler での dispose
406
+ else:
407
+
408
+ # 他の worker を待つ
409
+ while True:
410
+ if all([ws.value >= WorkerStatus.finishing for ws in self.worker_status_list]):
411
+ break
412
+ sleep(1)
413
+
414
+ # 通常 dispose
415
+ rdb_storage.engine.dispose()
416
+
417
+ def dispose_(dask_scheduler):
418
+ assert isinstance(self.storage, DaskStorage)
419
+ name_ = self.storage.name
420
+ ext = dask_scheduler.extensions["optuna"]
421
+ base_storage_ = ext.storages[name_]
422
+ rdb_storage_ = base_storage_._backend
423
+ rdb_storage_.engine.dispose()
424
+
425
+ client.run_on_scheduler(dispose_)
426
+ gc.collect()
427
+
428
+ # try remove
429
+ if os.path.exists(self.storage_path):
430
+ try:
431
+ os.remove(self.storage_path)
432
+ except PermissionError:
433
+ logger.debug(f'パーミッションエラー。{self.storage_path} の削除処理をスキップします。')
434
+ else:
435
+ logger.debug(f'{self.storage_path} の削除に成功しました。')
436
+
437
+ self.storage_path = self._existing_storage_path
438
+
439
+ return RemovingTempDB()
440
+
441
+ def run(self):
442
+
443
+ # ===== finalize =====
444
+ self._finalize()
445
+
446
+ # ===== construct sampler =====
447
+
448
+ # automatically-given arguments
449
+ if len(self.constraints) > 0:
450
+ self.sampler_kwargs.update(
451
+ constraints_func=self._constraint
452
+ )
453
+ if self.seed is not None:
454
+ self.sampler_kwargs.update(
455
+ seed=self.seed
456
+ )
457
+
458
+ actual_sampler_kwargs = dict()
459
+ arguments = inspect.signature(self.sampler_class.__init__).parameters
460
+ for k, v in self.sampler_kwargs.items():
461
+
462
+ # the key is valid, pass to sampler
463
+ if k in arguments.keys():
464
+ actual_sampler_kwargs.update({k: v})
465
+
466
+ # if not automatically-given arguments,
467
+ # show warning
468
+ elif k not in ('seed', 'constraints_func'):
469
+ logger.warning(_(
470
+ en_message='The given argument {key} is not '
471
+ 'included in ones of {sampler_name}. '
472
+ '{key} is ignored.',
473
+ jp_message='{key} は {sampler_name} の'
474
+ '有効な引数ではないので'
475
+ '無視されます。',
476
+ key=k,
477
+ sampler_name=self.sampler_class.__name__,
478
+ ))
479
+
480
+ # else, ignore it
481
+ else:
482
+ pass
483
+
484
+ # noinspection PyArgumentList
485
+ sampler = self.sampler_class(**actual_sampler_kwargs)
486
+
487
+ # if PoFBoTorchSampler, set opt
488
+ if isinstance(sampler, PoFBoTorchSampler):
489
+ sampler.pyfemtet_optimizer = self # FIXME: multi-fidelity に対応できない?
490
+
491
+ # ===== load study and run =====
492
+
493
+ # after quit FEM, try to remove tmp db
494
+ with self._removing_tmp_db_if_needed():
495
+
496
+ # quit FEM even if abnormal termination
497
+ with closing(self.fem):
498
+
499
+ # load study creating in setup_before_parallel()
500
+ # located on dask scheduler
501
+ study = optuna.load_study(
502
+ study_name=self.study_name,
503
+ storage=self.storage,
504
+ sampler=sampler,
505
+ )
506
+
507
+ # if tpe_addressing, load main study
508
+ if self._is_tpe_addressing():
509
+ # load it
510
+ existing_study = optuna.load_study(
511
+ study_name=self.study_name,
512
+ storage=f'sqlite:///{self._existing_storage_path}',
513
+ )
514
+
515
+ # and add callback to copy-back
516
+ # from processing study to existing one.
517
+ def copy_back(_, trial):
518
+ existing_study.add_trial(trial)
519
+
520
+ self.callbacks.append(copy_back)
521
+
522
+ # callback
523
+ if self.n_trials is not None:
524
+ self.callbacks.append(self._get_callback(self.n_trials))
525
+
526
+ # run
527
+ with self._setting_status(), suppress(InterruptOptimization):
528
+ study.optimize(
529
+ self._objective,
530
+ timeout=self.timeout,
531
+ callbacks=self.callbacks,
532
+ )
533
+
534
+
535
+ def debug_1():
536
+ # from pyfemtet.opt.optimizer.optuna_optimizer.pof_botorch.pof_botorch_sampler import
537
+ # sampler = PoFBoTorchSampler(
538
+ # n_startup_trials=5,
539
+ # seed=42,
540
+ # constraints_func=self._constraint,
541
+ # pof_config=PoFConfig(
542
+ # # consider_pof=False,
543
+ # # feasibility_cdf_threshold='mean',
544
+ # ),
545
+ # partial_optimize_acqf_kwargs=PartialOptimizeACQFConfig(
546
+ # # gen_candidates='scipy',
547
+ # timeout_sec=5.,
548
+ # # method='SLSQP' # 'COBYLA, COBYQA, SLSQP or trust-constr
549
+ # tol=0.1,
550
+ # # scipy_minimize_kwargs=dict(),
551
+ # ),
552
+ # )
553
+ # from optuna_integration import BoTorchSampler
554
+ # sampler = BoTorchSampler(n_startup_trials=5)
555
+
556
+ os.chdir(os.path.dirname(__file__))
557
+
558
+ def _parabola(_fem: AbstractFEMInterface, _opt: AbstractOptimizer) -> float:
559
+ d = _opt.get_variables()
560
+ x1 = d['x1']
561
+ x2 = d['x2']
562
+ # if _cns(_fem, _opt) < 0:
563
+ # raise PostProcessError
564
+ return x1 ** 2 + x2 ** 2
565
+
566
+ def _parabola2(_fem: AbstractFEMInterface, _opt: AbstractOptimizer) -> float:
567
+ x = _opt.get_variables('values')
568
+ return ((x - 0.1) ** 2).sum()
569
+
570
+ def _cns(_fem: AbstractFEMInterface, _opt: AbstractOptimizer) -> float:
571
+ x = _opt.get_variables('values')
572
+ return x[0]
573
+
574
+ _fem = NoFEM()
575
+ _opt = OptunaOptimizer()
576
+ _opt.fem = _fem
577
+
578
+ # _opt.sampler = optuna.samplers.RandomSampler(seed=42)
579
+ _opt.seed = 42
580
+ _opt.sampler_class = optuna.samplers.TPESampler
581
+ # _opt.sampler_class = optuna.samplers.RandomSampler
582
+ _opt.sampler_kwargs = dict(
583
+ n_startup_trials=5,
584
+ )
585
+ _opt.n_trials = 10
586
+
587
+ _opt.add_parameter('x1', 1, -1, 1, step=0.1)
588
+ _opt.add_parameter('x2', 1, -1, 1, step=0.1)
589
+ _opt.add_categorical_parameter('x3', 'a', choices=['a', 'b', 'c'])
590
+ _opt.add_constraint('cns', _cns, lower_bound=-0.9, args=(_fem, _opt))
591
+ _opt.add_objective('obj1', _parabola, args=(_fem, _opt))
592
+ # _opt.add_objective('obj2', _parabola2, args=(_fem, _opt))
593
+
594
+ # # ===== sub-fidelity =====
595
+ # __fem = NoFEM()
596
+ # __opt = SubFidelityModel()
597
+ # __opt.fem = __fem
598
+ # __opt.add_objective('obj1', _parabola, args=(__fem, __opt))
599
+ # __opt.add_objective('obj2', _parabola2, args=(__fem, __opt))
600
+ #
601
+ # _opt.add_sub_fidelity_model(name='low-fidelity', sub_fidelity_model=__opt, fidelity=0.5)
602
+ #
603
+ # def _solve_condition(_history: History):
604
+ #
605
+ # sub_fidelity_df = _history.get_df(
606
+ # {'sub_fidelity_name': 'low-fidelity'}
607
+ # )
608
+ # idx = sub_fidelity_df['state'] == TrialState.succeeded
609
+ # pdf = sub_fidelity_df[idx]
610
+ #
611
+ # return len(pdf) % 5 == 0
612
+ #
613
+ # _opt.set_solve_condition(_solve_condition)
614
+
615
+ # _opt.history.path = 'restart-test.csv'
616
+ _opt.run()
617
+
618
+ # import plotly.express as px
619
+ # _df = _opt.history.get_df()
620
+ # px.scatter_3d(_df, x='x1', y='x2', z='obj', color='fidelity', opacity=0.5).show()
621
+
622
+ _opt.history.save()
623
+
624
+
625
+ def substrate_size(Femtet):
626
+ """基板のXY平面上での専有面積を計算します。"""
627
+ substrate_w = Femtet.GetVariableValue('substrate_w')
628
+ substrate_d = Femtet.GetVariableValue('substrate_d')
629
+ return substrate_w * substrate_d # 単位: mm2
630
+
631
+
632
+ def debug_2():
633
+ from pyfemtet.opt.interface._femtet_interface.femtet_interface import FemtetInterface
634
+
635
+ fem = FemtetInterface(
636
+ femprj_path=os.path.join(os.path.dirname(__file__), 'wat_ex14_parametric_jp.femprj'),
637
+ )
638
+
639
+ opt = OptunaOptimizer()
640
+
641
+ opt.fem = fem
642
+
643
+ opt.add_parameter(name="substrate_w", initial_value=40, lower_bound=22, upper_bound=60)
644
+ opt.add_parameter(name="substrate_d", initial_value=60, lower_bound=34, upper_bound=60)
645
+ opt.add_objective(name='基板サイズ(mm2)', fun=substrate_size)
646
+
647
+ opt.n_trials = 5
648
+ opt.history.path = os.path.join(os.path.dirname(__file__), 'femtet-test.csv')
649
+
650
+ opt.run()
651
+
652
+
653
+ def debug_3():
654
+ from pyfemtet.opt.interface._femtet_interface.femtet_interface import FemtetInterface
655
+
656
+ fem = FemtetInterface(
657
+ femprj_path=os.path.join(os.path.dirname(__file__), 'wat_ex14_parametric_jp.femprj'),
658
+ )
659
+
660
+ fem.use_parametric_output_as_objective(
661
+ number=1, direction='minimize',
662
+ )
663
+
664
+ opt = OptunaOptimizer()
665
+
666
+ opt.fem = fem
667
+
668
+ opt.add_parameter(name="substrate_w", initial_value=40, lower_bound=22, upper_bound=60)
669
+ opt.add_parameter(name="substrate_d", initial_value=60, lower_bound=34, upper_bound=60)
670
+
671
+ opt.n_trials = 5
672
+ opt.history.path = os.path.join(os.path.dirname(__file__), 'femtet-test.csv')
673
+
674
+ opt.run()
675
+
676
+
677
+ if __name__ == '__main__':
678
+ debug_3()
@@ -0,0 +1,7 @@
1
+ from .pof_botorch_sampler import PoFBoTorchSampler, PoFConfig, PartialOptimizeACQFConfig
2
+
3
+ __all__ = [
4
+ 'PoFBoTorchSampler',
5
+ 'PoFConfig',
6
+ 'PartialOptimizeACQFConfig',
7
+ ]
@@ -0,0 +1,18 @@
1
+ ,prm,prm_lower_bound,prm_upper_bound,prm,prm_choices,obj,obj_direction,,,,,,
2
+ ,,,,,,,,,,,,,
3
+ trial,x1,x1_lower_bound,x1_upper_bound,x2,x2_choices,obj,obj_direction,state,datetime_start,datetime_end,message,feasibility,optimality
4
+ 0,85.63019613,50,100,A,"['A', 'B', 'C']",,minimize,Success,48:10.2,48:10.2,,TRUE,FALSE
5
+ 1,76.66824027,50,100,B,"['A', 'B', 'C']",,minimize,Hidden constraint violation,48:11.7,48:11.7,,FALSE,FALSE
6
+ 2,62.68444915,50,100,C,"['A', 'B', 'C']",,minimize,Hidden constraint violation,48:16.6,48:16.6,,FALSE,FALSE
7
+ 3,63.08476439,50,100,A,"['A', 'B', 'C']",,minimize,Success,48:20.2,48:20.2,,TRUE,FALSE
8
+ 4,78.95677052,50,100,B,"['A', 'B', 'C']",,minimize,Hidden constraint violation,48:23.5,48:23.5,,FALSE,FALSE
9
+ 5,79.90834979,50,100,C,"['A', 'B', 'C']",,minimize,Hidden constraint violation,48:27.2,48:27.2,,FALSE,FALSE
10
+ 6,97.4442698,50,100,A,"['A', 'B', 'C']",,minimize,Success,48:29.8,48:29.8,,TRUE,FALSE
11
+ 7,87.12500776,50,100,B,"['A', 'B', 'C']",,minimize,Hidden constraint violation,03:52.7,03:52.7,,FALSE,FALSE
12
+ 8,69.56378151,50,100,C,"['A', 'B', 'C']",,minimize,Hidden constraint violation,04:00.1,04:00.1,,FALSE,FALSE
13
+ 9,80.49012367,50,100,A,"['A', 'B', 'C']",,minimize,Success,04:06.2,04:06.2,,TRUE,FALSE
14
+ 10,87.55804836,50,100,B,"['A', 'B', 'C']",,minimize,Hidden constraint violation,04:13.1,04:13.1,,FALSE,FALSE
15
+ 11,59.55103039,50,100,C,"['A', 'B', 'C']",,minimize,Hidden constraint violation,04:19.3,04:19.3,,FALSE,FALSE
16
+ 12,97.91995423,50,100,A,"['A', 'B', 'C']",,minimize,Success,04:24.6,04:24.6,,TRUE,FALSE
17
+ 13,91.01111473,50,100,B,"['A', 'B', 'C']",,minimize,Hidden constraint violation,04:31.3,04:31.3,,FALSE,FALSE
18
+ 14,53.36556413,50,100,C,"['A', 'B', 'C']",,minimize,Hidden constraint violation,04:36.6,04:36.6,,FALSE,FALSE