pyfemtet 0.9.4__py3-none-any.whl → 1.0.0a0__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 -19
  29. pyfemtet/opt/exceptions.py +45 -0
  30. pyfemtet/opt/femopt.py +602 -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} +490 -348
  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/_base.py +0 -129
  53. pyfemtet/opt/interface/_surrogate_model_interface/__init__.py +8 -0
  54. pyfemtet/opt/interface/_surrogate_model_interface/base_surrogate_interface.py +59 -0
  55. pyfemtet/opt/interface/_surrogate_model_interface/botorch_interface.py +271 -0
  56. pyfemtet/opt/interface/_surrogate_model_interface/debug-pof-botorch.reccsv +18 -0
  57. pyfemtet/opt/interface/_with_excel_settings/__init__.py +61 -0
  58. pyfemtet/opt/interface/_with_excel_settings/with_excel_settings.py +134 -0
  59. pyfemtet/opt/meta_script/YAML_Generator.xlsm +0 -0
  60. pyfemtet/opt/meta_script/__main__.py +58 -36
  61. pyfemtet/opt/optimizer/__init__.py +7 -9
  62. pyfemtet/opt/optimizer/_base_optimizer.py +876 -0
  63. pyfemtet/opt/optimizer/optuna_optimizer/__init__.py +9 -0
  64. pyfemtet/opt/optimizer/optuna_optimizer/_optuna_attribute.py +73 -0
  65. pyfemtet/opt/optimizer/optuna_optimizer/_optuna_optimizer.py +678 -0
  66. pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/__init__.py +7 -0
  67. pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/debug-pof-botorch.reccsv +18 -0
  68. pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/enable_nonlinear_constraint.py +244 -0
  69. pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/pof_botorch_sampler.py +1249 -0
  70. pyfemtet/opt/optimizer/optuna_optimizer/wat_ex14_parametric_jp.femprj +0 -0
  71. pyfemtet/opt/optimizer/scipy_optimizer/__init__.py +1 -0
  72. pyfemtet/opt/optimizer/scipy_optimizer/_scipy_optimizer.py +364 -0
  73. pyfemtet/opt/prediction/__init__.py +7 -0
  74. pyfemtet/opt/prediction/_botorch_utils.py +133 -0
  75. pyfemtet/opt/prediction/_gpytorch_modules_extension.py +142 -0
  76. pyfemtet/opt/prediction/_helper.py +155 -0
  77. pyfemtet/opt/prediction/_model.py +118 -0
  78. pyfemtet/opt/problem/problem.py +304 -0
  79. pyfemtet/opt/problem/variable_manager/__init__.py +20 -0
  80. pyfemtet/opt/problem/variable_manager/_string_as_expression.py +115 -0
  81. pyfemtet/opt/problem/variable_manager/_variable_manager.py +295 -0
  82. pyfemtet/opt/visualization/history_viewer/__main__.py +5 -0
  83. pyfemtet/opt/visualization/{_base.py → history_viewer/_base_application.py} +18 -13
  84. pyfemtet/opt/visualization/history_viewer/_common_pages.py +150 -0
  85. pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/alert_region.py +10 -5
  86. pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/control_femtet.py +16 -13
  87. pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/main_graph.py +117 -47
  88. pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/pm_graph.py +159 -138
  89. pyfemtet/opt/visualization/history_viewer/_process_monitor/_application.py +173 -0
  90. pyfemtet/opt/visualization/history_viewer/_process_monitor/_pages.py +291 -0
  91. pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/dbc.py +1 -1
  92. pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/dcc.py +1 -1
  93. pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/html.py +1 -1
  94. pyfemtet/opt/visualization/history_viewer/result_viewer/__main__.py +5 -0
  95. pyfemtet/opt/visualization/{result_viewer/application.py → history_viewer/result_viewer/_application.py} +6 -6
  96. pyfemtet/opt/visualization/{result_viewer/pages.py → history_viewer/result_viewer/_pages.py} +106 -82
  97. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08.csv +18 -0
  98. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08.db +0 -0
  99. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8.jpg +0 -0
  100. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8.log +45 -0
  101. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8.pdt +0 -0
  102. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_1.jpg +0 -0
  103. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_1.pdt +0 -0
  104. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_10.jpg +0 -0
  105. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_10.pdt +0 -0
  106. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_11.jpg +0 -0
  107. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_11.pdt +0 -0
  108. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_12.jpg +0 -0
  109. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_12.pdt +0 -0
  110. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_13.jpg +0 -0
  111. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_13.pdt +0 -0
  112. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_14.jpg +0 -0
  113. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_14.pdt +0 -0
  114. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_15.jpg +0 -0
  115. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_15.pdt +0 -0
  116. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_16.jpg +0 -0
  117. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_16.pdt +0 -0
  118. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_17.jpg +0 -0
  119. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_17.pdt +0 -0
  120. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_18.jpg +0 -0
  121. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_18.pdt +0 -0
  122. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_19.jpg +0 -0
  123. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_19.pdt +0 -0
  124. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_2.jpg +0 -0
  125. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_2.pdt +0 -0
  126. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_20.jpg +0 -0
  127. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_20.pdt +0 -0
  128. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_3.jpg +0 -0
  129. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_3.pdt +0 -0
  130. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.bgr +0 -0
  131. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.bnd +0 -0
  132. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.btr +0 -0
  133. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.jpg +0 -0
  134. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.mtl +0 -0
  135. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.pdt +0 -0
  136. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.prm +0 -0
  137. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_5.jpg +0 -0
  138. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_5.pdt +0 -0
  139. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_6.jpg +0 -0
  140. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_6.pdt +0 -0
  141. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_7.jpg +0 -0
  142. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_7.pdt +0 -0
  143. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_8.jpg +0 -0
  144. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_8.pdt +0 -0
  145. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_9.jpg +0 -0
  146. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_9.pdt +0 -0
  147. pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.femprj +0 -0
  148. pyfemtet/opt/visualization/plotter/main_figure_creator.py +536 -0
  149. pyfemtet/opt/visualization/plotter/pm_graph_creator.py +359 -0
  150. pyfemtet/opt/worker_status.py +120 -0
  151. {pyfemtet-0.9.4.dist-info → pyfemtet-1.0.0a0.dist-info}/METADATA +22 -24
  152. pyfemtet-1.0.0a0.dist-info/RECORD +173 -0
  153. pyfemtet-1.0.0a0.dist-info/entry_points.txt +3 -0
  154. pyfemtet/_femtet_config_util/exit.py +0 -59
  155. pyfemtet/_message/1. make_pot.bat +0 -11
  156. pyfemtet/_message/2. make_mo.bat +0 -6
  157. pyfemtet/_message/__init__.py +0 -5
  158. pyfemtet/_message/babel.cfg +0 -2
  159. pyfemtet/_message/locales/ja/LC_MESSAGES/messages.mo +0 -0
  160. pyfemtet/_message/locales/ja/LC_MESSAGES/messages.po +0 -570
  161. pyfemtet/_message/locales/messages.pot +0 -551
  162. pyfemtet/_warning.py +0 -87
  163. pyfemtet/brep/_impl.py +0 -18
  164. pyfemtet/opt/_femopt.py +0 -1007
  165. pyfemtet/opt/_femopt_core.py +0 -1169
  166. pyfemtet/opt/_test_utils/control_femtet.py +0 -39
  167. pyfemtet/opt/_test_utils/hyper_sphere.py +0 -24
  168. pyfemtet/opt/_test_utils/record_history.py +0 -130
  169. pyfemtet/opt/advanced_samples/excel_ui/(ref) original_project.femprj +0 -0
  170. pyfemtet/opt/advanced_samples/excel_ui/femtet-macro.xlsm +0 -0
  171. pyfemtet/opt/advanced_samples/excel_ui/pyfemtet-core.py +0 -291
  172. pyfemtet/opt/advanced_samples/excel_ui/test-pyfemtet-core.cmd +0 -22
  173. pyfemtet/opt/advanced_samples/restart/gal_ex13_parametric.femprj +0 -0
  174. pyfemtet/opt/advanced_samples/restart/gal_ex13_parametric_restart.py +0 -99
  175. pyfemtet/opt/advanced_samples/restart/gal_ex13_parametric_restart_jp.py +0 -102
  176. pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_create_training_data.py +0 -60
  177. pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_create_training_data_jp.py +0 -57
  178. pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_optimize_with_surrogate.py +0 -100
  179. pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_optimize_with_surrogate_jp.py +0 -90
  180. pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_parametric.femprj +0 -0
  181. pyfemtet/opt/interface/_base.py +0 -101
  182. pyfemtet/opt/interface/_excel_interface.py +0 -984
  183. pyfemtet/opt/interface/_femtet_excel.py +0 -141
  184. pyfemtet/opt/interface/_femtet_with_nx/__init__.py +0 -3
  185. pyfemtet/opt/interface/_femtet_with_nx/_interface.py +0 -178
  186. pyfemtet/opt/interface/_femtet_with_sldworks.py +0 -298
  187. pyfemtet/opt/interface/_surrogate/__init__.py +0 -5
  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.4.dist-info/RECORD +0 -158
  259. pyfemtet-0.9.4.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.4.dist-info → pyfemtet-1.0.0a0.dist-info}/LICENSE +0 -0
  271. {pyfemtet-0.9.4.dist-info → pyfemtet-1.0.0a0.dist-info}/LICENSE_THIRD_PARTY.txt +0 -0
  272. {pyfemtet-0.9.4.dist-info → pyfemtet-1.0.0a0.dist-info}/WHEEL +0 -0
@@ -1,220 +0,0 @@
1
- from typing import Callable
2
- from functools import partial
3
-
4
- import numpy as np
5
-
6
- import torch
7
- from torch import Tensor
8
-
9
- from optuna.study import Study
10
- from optuna.trial import Trial
11
- from optuna._transform import _SearchSpaceTransform
12
-
13
- from botorch.acquisition import AcquisitionFunction
14
- from botorch.optim.initializers import gen_batch_initial_conditions
15
-
16
- from pyfemtet.opt._femopt_core import Constraint
17
- from pyfemtet.opt.optimizer import OptunaOptimizer
18
- from pyfemtet._message import Msg
19
-
20
- from pyfemtet.logger import get_module_logger
21
-
22
- logger = get_module_logger(__file__, __name__)
23
-
24
-
25
- BotorchConstraint = Callable[[Tensor], Tensor]
26
-
27
-
28
- # 拘束関数に pytorch の自動微分機能を適用するためのクラス
29
- class GeneralFunctionWithForwardDifference(torch.autograd.Function):
30
- """自作関数を pytorch で自動微分するためのクラスです。
31
-
32
- ユーザー定義関数を botorch 形式に変換する過程で微分の計算ができなくなるのでこれが必要です。
33
- """
34
-
35
- @staticmethod
36
- def forward(ctx, f, xs):
37
- ys = f(xs)
38
- ctx.save_for_backward(xs, ys)
39
- ctx.f = f
40
- return ys
41
-
42
- @staticmethod
43
- def backward(ctx, grad_output):
44
- xs, ys = ctx.saved_tensors
45
- f = ctx.f
46
- dx = 0.001 # 入力は normalized なので決め打ちでよい
47
- diff = []
48
- xs = xs.detach() # xs に余計な計算履歴を残さないために、detachする。
49
- for i in range(len(xs)):
50
- xs[i] += dx
51
- diff.append(torch.sum(grad_output * (f(xs) - ys)))
52
- xs[i] -= dx
53
- diff = torch.tensor(diff) / dx
54
- return None, diff
55
-
56
-
57
- # ユーザー定義関数 (pyfemtet.opt.Constraint) を受け取り、
58
- # botorch で処理できる callable オブジェクトを作成するクラス
59
- class ConvertedConstraint:
60
- """ユーザーが定義した Constraint を botorch で処理できる形式に変換します。
61
-
62
- `callable()` は形状 `d` の 1 次元テンソルを受け取り、スカラーを返します。
63
- """
64
-
65
- def __init__(self, constraint: Constraint, study: Study, bound: str, opt: OptunaOptimizer):
66
- self._constraint: Constraint = constraint
67
- self._study = study
68
- self._bound = bound
69
- self._opt = opt
70
-
71
- def __call__(self, x: Tensor) -> Tensor: # BotorchConstraint
72
- """optimize_acqf() に渡される非線形拘束関数の処理です。
73
-
74
- Args:
75
- x (Tensor): Normalized parameters. Its length is d (== len(prm)).
76
-
77
- Returns:
78
- float Tensor. >= 0 is feasible.
79
-
80
- """
81
-
82
- norm_x = x.detach().numpy()
83
- c = evaluate_pyfemtet_cns(self._study, self._constraint, norm_x, self._opt)
84
- if self._bound == 'lb':
85
- return Tensor([c - self._constraint.lb])
86
- elif self._bound == 'ub':
87
- return Tensor([self._constraint.ub - c])
88
-
89
-
90
- # list[pyfemtet.opt.Constraint] について、正規化された入力に対し、 feasible or not を返す関数
91
- def is_feasible(study: Study, constraints: list[Constraint], norm_x: np.ndarray, opt: OptunaOptimizer) -> bool:
92
- feasible = True
93
- cns: Constraint
94
- for cns in constraints:
95
- c = evaluate_pyfemtet_cns(study, cns, norm_x, opt)
96
- if cns.lb is not None:
97
- if cns.lb > c:
98
- feasible = False
99
- break
100
- if cns.ub is not None:
101
- if cns.ub < c:
102
- feasible = False
103
- break
104
- return feasible
105
-
106
-
107
- # 正規化された入力を受けて pyfemtet.opt.Constraint を評価する関数
108
- def evaluate_pyfemtet_cns(study: Study, cns: Constraint, norm_x: np.ndarray, opt: OptunaOptimizer) -> float:
109
- """Evaluate given constraint function by given NORMALIZED x.
110
-
111
- Args:
112
- study (Study): Optuna study. Use to detect search space from last trial's Distribution objects.
113
- cns (Constraint): PyFemtet's format constraint.
114
- norm_x (np.ndarray): NORMALIZED values of all parameters.
115
- opt (OptunaOptimizer): PyFemtet's optimizer. Used for update values of `opt` and `fem` who may be used in `cns`.
116
-
117
- Returns:
118
- bool: feasible or not.
119
- """
120
- # ===== unnormalize x =====
121
- search_space = study.sampler.infer_relative_search_space(study, None)
122
- trans = _SearchSpaceTransform(search_space, transform_0_1=True, transform_log=False, transform_step=False)
123
- params = trans.untransform(norm_x)
124
-
125
- # ===== update OptunaOptimizer and FEMInterface who is referenced by cns =====
126
-
127
- # opt
128
- opt.set_parameter(params)
129
-
130
- # fem
131
- if cns.using_fem:
132
- df_to_fem = opt.variables.get_variables(format='df', filter_pass_to_fem=True)
133
- opt.fem.update_parameter(df_to_fem)
134
-
135
- # ===== calc cns =====
136
- return cns.calc(opt.fem)
137
-
138
-
139
- # botorch の optimize_acqf で非線形拘束を使えるようにするクラス。以下を備える。
140
- # - 渡すパラメータ nonlinear_constraints を作成する
141
- # - gen_initial_conditions で feasible なものを返すラッパー関数
142
- class NonlinearInequalityConstraints:
143
- """botorch の optimize_acqf に parameter constraints を設定するための引数を作成します。"""
144
-
145
- def __init__(self, study: Study, constraints: list[Constraint], opt: OptunaOptimizer):
146
- self._study = study
147
- self._constraints = constraints
148
- self._opt = opt
149
-
150
- self._nonlinear_inequality_constraints = []
151
- cns: Constraint
152
- for cns in self._constraints:
153
- if cns.lb is not None:
154
- cns_botorch = ConvertedConstraint(cns, self._study, 'lb', self._opt)
155
- item = (lambda x: GeneralFunctionWithForwardDifference.apply(cns_botorch, x), True)
156
- self._nonlinear_inequality_constraints.append(item)
157
- if cns.ub is not None:
158
- cns_botorch = ConvertedConstraint(cns, self._study, 'ub', self._opt)
159
- item = (lambda x: GeneralFunctionWithForwardDifference.apply(cns_botorch, x), True)
160
- self._nonlinear_inequality_constraints.append(item)
161
-
162
- def _filter_feasible_conditions(self, ic_batch):
163
- # List to store feasible initial conditions
164
- feasible_ic_list = []
165
-
166
- for each_num_restarts in ic_batch:
167
- feasible_q_list = []
168
- for each_q in each_num_restarts:
169
- norm_x: np.ndarray = each_q.numpy() # normalized parameters
170
-
171
- if is_feasible(self._study, self._constraints, norm_x, self._opt):
172
- feasible_q_list.append(each_q) # Keep only feasible rows
173
-
174
- if feasible_q_list: # Only add if there are feasible rows
175
- feasible_ic_list.append(torch.stack(feasible_q_list))
176
-
177
- # Stack feasible conditions back into tensor format
178
- if feasible_ic_list:
179
- return torch.stack(feasible_ic_list)
180
- else:
181
- return None # Return None if none are feasible
182
-
183
- @staticmethod
184
- def _generate_random_initial_conditions(shape):
185
- # Generates random initial conditions with the same shape as ic_batch
186
- return torch.rand(shape)
187
-
188
- def _generate_feasible_initial_conditions(self, *args, **kwargs):
189
- # A `num_restarts x q x d` tensor of initial conditions.
190
- ic_batch = gen_batch_initial_conditions(*args, **kwargs)
191
- feasible_ic_batch = self._filter_feasible_conditions(ic_batch)
192
-
193
- while feasible_ic_batch is None:
194
- # Generate new random ic_batch with the same shape
195
- print('警告: gen_batch_initial_conditions() は feasible な初期値を提案しませんでした。'
196
- 'パラメータ提案を探索するための初期値をランダムに選定します。')
197
- random_ic_batch = self._generate_random_initial_conditions(ic_batch.shape)
198
- feasible_ic_batch = self._filter_feasible_conditions(random_ic_batch)
199
-
200
- return feasible_ic_batch
201
-
202
- def create_kwargs(self) -> dict:
203
- """
204
- nonlinear_inequality_constraints:
205
- 非線形不等式制約を表すタプルのリスト。
206
- タプルの最初の要素は、`callable(x) >= 0` という形式の制約を表す呼び出し可能オブジェクトです。
207
- 2 番目の要素はブール値で、点内制約の場合は `True`
208
- 制約は後で scipy ソルバーに渡されます。
209
- この場合、`batch_initial_conditions` を渡す必要があります。
210
- 非線形不等式制約を使用するには、`batch_limit` を 1 に設定する必要もあります。
211
- これは、`options` で指定されていない場合は自動的に行われます。
212
- """
213
- return dict(
214
- q=1,
215
- options=dict(
216
- batch_limit=1,
217
- ),
218
- nonlinear_inequality_constraints=self._nonlinear_inequality_constraints,
219
- ic_generator=self._generate_feasible_initial_conditions,
220
- )
@@ -1,434 +0,0 @@
1
- # typing
2
- from typing import Iterable
3
-
4
- # built-in
5
- import os
6
- import inspect
7
- import gc
8
-
9
- # 3rd-party
10
- import optuna
11
- from optuna.trial import TrialState, FrozenTrial
12
- from optuna.study import MaxTrialsCallback, Study
13
-
14
- # pyfemtet relative
15
- from pyfemtet.opt._femopt_core import OptimizationStatus, generate_lhs
16
- from pyfemtet.opt.optimizer import AbstractOptimizer, logger, OptimizationMethodChecker
17
- from pyfemtet.core import MeshError, ModelError, SolveError
18
- from pyfemtet._message import Msg
19
-
20
- # filter warnings
21
- import warnings
22
- from optuna.exceptions import ExperimentalWarning
23
-
24
-
25
- optuna.logging.set_verbosity(optuna.logging.ERROR)
26
-
27
- warnings.filterwarnings('ignore', category=ExperimentalWarning)
28
-
29
-
30
- class OptunaMethodChecker(OptimizationMethodChecker):
31
- def check_multi_objective(self, raise_error=True): return True
32
- def check_timeout(self, raise_error=True): return True
33
- def check_parallel(self, raise_error=True): return True
34
- def check_constraint(self, raise_error=True): return True
35
- def check_strict_constraint(self, raise_error=True): return True
36
- def check_skip(self, raise_error=True): return True
37
- def check_seed(self, raise_error=True): return True
38
-
39
-
40
- class OptunaOptimizer(AbstractOptimizer):
41
- """Optimizer using ```optuna```.
42
-
43
- This class provides an interface for the optimization
44
- engine using Optuna. For more details, please refer to
45
- the Optuna documentation.
46
-
47
- See Also:
48
- https://optuna.readthedocs.io/en/stable/reference/index.html
49
-
50
- Args:
51
- sampler_class (optuna.samplers.BaseSampler, optional):
52
- A sampler class from Optuna. If not specified,
53
- ```optuna.samplers.TPESampler``` is specified.
54
- This defines the sampling strategy used during
55
- optimization. Defaults to None.
56
- sampler_kwargs (dict, optional):
57
- A dictionary of keyword arguments to be passed to
58
- the sampler class. This allows for customization
59
- of the sampling process. Defaults to None.
60
- add_init_method (str or Iterable[str], optional):
61
- A method or a collection of methods to be added
62
- during initialization. This can be used to specify
63
- additional setup procedures.
64
- Currently, the only valid value is 'LHS'
65
- (using Latin Hypercube Sampling).
66
- Defaults to None.
67
-
68
- Warnings:
69
- Do not include ```constraints_func``` in ```sampler_kwargs```.
70
- It is generated and provided by :func:`FEMOpt.add_constraint`.
71
-
72
- """
73
-
74
- def __init__(
75
- self,
76
- sampler_class: optuna.samplers.BaseSampler or None = None,
77
- sampler_kwargs: dict or None = None,
78
- add_init_method: str or Iterable[str] or None = None
79
- ):
80
- super().__init__()
81
- self.study_name = None
82
- self.storage = None
83
- self.study = None
84
- self.optimize_callbacks = []
85
- self.sampler_class = optuna.samplers.TPESampler if sampler_class is None else sampler_class
86
- self.sampler_kwargs = dict() if sampler_kwargs is None else sampler_kwargs
87
- self.additional_initial_parameter = []
88
- self.additional_initial_methods = add_init_method if hasattr(add_init_method, '__iter__') else [add_init_method]
89
- self.method_checker = OptunaMethodChecker(self)
90
- self._temporary_storage = None
91
- self._temporary_storage_path = '_pyfemtet_temporary_file.db'
92
-
93
- def _objective(self, trial):
94
-
95
- logger.info('')
96
- logger.info(f'===== trial {1 + len(self.history.get_df())} ({len(self.history.get_df(valid_only=True))} succeeded trials) start =====')
97
-
98
- # 中断の確認 (FAIL loop に陥る対策)
99
- if self.entire_status.get() == OptimizationStatus.INTERRUPTING:
100
- self.worker_status.set(OptimizationStatus.INTERRUPTING)
101
- trial.study.stop() # 現在実行中の trial を最後にする
102
- self._retry_counter = 0
103
- return None # set TrialState FAIL
104
-
105
- # candidate x and update parameters
106
- logger.info('Searching new parameter set...')
107
- for prm in self.variables.get_variables(format='raw', filter_parameter=True):
108
- value = trial.suggest_float(
109
- name=prm.name,
110
- low=prm.lower_bound,
111
- high=prm.upper_bound,
112
- step=prm.step,
113
- )
114
- self.variables.variables[prm.name].value = value
115
-
116
- # update expressions
117
- self.variables.evaluate()
118
-
119
- # message の設定
120
- self.message = trial.user_attrs['message'] if 'message' in trial.user_attrs.keys() else ''
121
-
122
- # fem 経由で変数を取得して constraint を計算する時のためにアップデート
123
- df_fem = self.variables.get_variables(format='df', filter_pass_to_fem=True)
124
- self.fem.update_parameter(df_fem)
125
- x = self.variables.get_variables(format='values', filter_parameter=True)
126
-
127
- # strict 拘束
128
- strict_constraints = [cns for cns in self.constraints.values() if cns.strict]
129
- for cns in strict_constraints:
130
- feasible = True
131
- cns_value = cns.calc(self.fem)
132
- if cns.lb is not None:
133
- feasible = feasible and (cns_value >= cns.lb)
134
- if cns.ub is not None:
135
- feasible = feasible and (cns.ub >= cns_value)
136
- if not feasible:
137
- logger.info('----- Out of constraint! -----')
138
- logger.info(Msg.INFO_INFEASIBLE)
139
- logger.info(f'Constraint: {cns.name}')
140
- logger.info(self.variables.get_variables('dict', filter_parameter=True))
141
- self._retry_counter += 1
142
- self.message = f'Failed to calculate objectives because of the constraint violation: {cns.name}'
143
- self.f(x, _record_infeasible=True)
144
- raise optuna.TrialPruned() # set TrialState PRUNED because FAIL causes similar candidate loop.
145
-
146
- # 計算
147
- try:
148
- _, _y, c = self.f(x) # f の中で info は出している
149
- except (ModelError, MeshError, SolveError) as e:
150
- # 中断の確認 (解析中に interrupt されている場合対策)
151
- if self.entire_status.get() == OptimizationStatus.INTERRUPTING:
152
- self.worker_status.set(OptimizationStatus.INTERRUPTING)
153
- trial.study.stop() # 現在実行中の trial を最後にする
154
- return None # set TrialState FAIL
155
-
156
- logger.warning('----- Infeasible! -----')
157
- logger.warning(Msg.INFO_INFEASIBLE)
158
- logger.warning(f'Hidden Constraint ({type(e).__name__})')
159
- logger.warning(self.variables.get_variables('dict', filter_parameter=True))
160
- logger.warning('Please consider to determine the cause'
161
- 'of the above error and modify the model'
162
- 'or analysis.')
163
-
164
- self._retry_counter += 1
165
- self.message = f'Failed to calculate objectives because of the parameter broke the FEM model.'
166
- self.f(x, _record_infeasible=True)
167
- raise optuna.TrialPruned() # set TrialState PRUNED because FAIL causes similar candidate loop.
168
-
169
- # 拘束 attr の更新
170
- if len(self.constraints) > 0:
171
- _c = [] # <= 0 is feasible
172
- for (name, cns), c_value in zip(self.constraints.items(), c):
173
- lb, ub = cns.lb, cns.ub
174
- if lb is not None: # fun >= lb <=> lb - fun <= 0
175
- _c.append(lb - c_value)
176
- if ub is not None: # ub >= fun <=> fun - ub <= 0
177
- _c.append(c_value - ub)
178
- trial.set_user_attr('constraints', _c)
179
-
180
- # 中断の確認 (解析中に interrupt されている場合対策)
181
- if self.entire_status.get() == OptimizationStatus.INTERRUPTING:
182
- self.worker_status.set(OptimizationStatus.INTERRUPTING)
183
- trial.study.stop() # 現在実行中の trial を最後にする
184
- self._retry_counter = 0
185
- return None # set TrialState FAIL
186
-
187
- # 結果
188
- self._retry_counter = 0
189
- return tuple(_y)
190
-
191
- def _constraint(self, trial):
192
- # if break trial without weak constraint calculation, return 1 (as infeasible).
193
- if 'constraints' in trial.user_attrs.keys():
194
- return trial.user_attrs['constraints']
195
- else:
196
- _c = []
197
- for name, cns in self.constraints.items():
198
- lb, ub = cns.lb, cns.ub
199
- if lb is not None:
200
- _c.append(1.)
201
- if ub is not None:
202
- _c.append(1.)
203
- return _c
204
-
205
- def _setup_before_parallel(self):
206
- """Create storage, study and set initial parameter."""
207
-
208
- # create storage
209
- self.study_name = 'pyfemtet-study'
210
- storage_path = os.path.splitext(self.history.path)[0] + '.db' # history と同じところに保存
211
- if self.is_cluster: # remote cluster なら scheduler の working dir に保存
212
- storage_path = os.path.splitext(os.path.basename(self.history.path))[0] + '.db'
213
-
214
- # callback to terminate
215
- if self.n_trials is not None:
216
- n_trials = self.n_trials
217
-
218
- # restart である場合、追加 N 回と見做す
219
- if self.history.is_restart:
220
- n_existing_trials = len(self.history.get_df())
221
- n_trials += n_existing_trials
222
-
223
- self.optimize_callbacks.append(MaxTrialsCallback(n_trials, states=(TrialState.COMPLETE,)))
224
-
225
- # if not restart, create study if storage is not exists
226
- if not self.history.is_restart:
227
-
228
- self.storage = optuna.integration.dask.DaskStorage(
229
- f'sqlite:///{storage_path}',
230
- )
231
-
232
- self.study = optuna.create_study(
233
- study_name=self.study_name,
234
- storage=self.storage,
235
- load_if_exists=True,
236
- directions=['minimize'] * len(self.objectives),
237
- )
238
-
239
- # 初期値の設定
240
- if len(self.study.trials) == 0: # リスタートでなければ
241
- # ユーザーの指定した初期値
242
- params = self.variables.get_variables('dict', filter_parameter=True)
243
- self.study.enqueue_trial(params, user_attrs={"message": "initial"})
244
-
245
- # add_initial_parameter で追加された初期値
246
- for prm, prm_set_name in self.additional_initial_parameter:
247
- if type(prm) is dict:
248
- assert prm.keys() == params.keys(), Msg.ERR_INCONSISTENT_PARAMETER
249
- else:
250
- assert len(prm) == len(params.keys()), Msg.ERR_INCONSISTENT_PARAMETER
251
- prm = dict(zip(params.keys(), prm))
252
-
253
- self.study.enqueue_trial(
254
- prm,
255
- user_attrs={"message": prm_set_name}
256
- )
257
-
258
- # add_init で指定された方法による初期値
259
- if 'LHS' in self.additional_initial_methods:
260
- names = []
261
- bounds = []
262
- for i, row in self.get_parameter('df').iterrows():
263
- names.append(row['name'])
264
- lb = row['lower_bound']
265
- ub = row['upper_bound']
266
- bounds.append([lb, ub])
267
- data = generate_lhs(bounds, seed=self.seed)
268
- for datum in data:
269
- d = {}
270
- for name, v in zip(names, datum):
271
- d[name] = v
272
- self.study.enqueue_trial(
273
- d, user_attrs={"message": "additional initial (Latin Hypercube Sampling)"}
274
- )
275
-
276
- # if is_restart, load study
277
- else:
278
- if not os.path.exists(storage_path):
279
- raise FileNotFoundError(storage_path)
280
- self.storage = optuna.integration.dask.DaskStorage(
281
- f'sqlite:///{storage_path}',
282
- )
283
-
284
- # if TPESampler, create temporary study
285
- # due to instability in case of many pruned trials.
286
- from optuna.samplers import TPESampler
287
- if issubclass(self.sampler_class, TPESampler):
288
-
289
- import re
290
- pattern = r'_\d+$'
291
-
292
- while os.path.exists(self._temporary_storage_path):
293
- name, ext = os.path.splitext(self._temporary_storage_path)
294
-
295
- if bool(re.search(pattern, name)):
296
- base = '_'.join(name.split('_')[:-1])
297
- n = int(name.split('_')[-1])
298
- self._temporary_storage_path = name + '_' + str(n+1) + ext
299
-
300
- else:
301
- self._temporary_storage_path = name + '_2' + ext
302
-
303
- self._temporary_storage = optuna.integration.dask.DaskStorage(
304
- f'sqlite:///{self._temporary_storage_path}',
305
- )
306
-
307
- study = optuna.load_study(
308
- study_name=None,
309
- storage=self.storage,
310
- sampler=None,
311
- )
312
-
313
- _study = optuna.create_study(
314
- study_name='tmp',
315
- storage=self._temporary_storage,
316
- load_if_exists=True,
317
- directions=['minimize'] * len(self.objectives),
318
- )
319
-
320
- # Copy COMPLETE trials to temporary study.
321
- existing_trials = study.get_trials(states=(optuna.trial.TrialState.COMPLETE,))
322
- _study.add_trials(existing_trials)
323
-
324
- def add_init_parameter(
325
- self,
326
- parameter: dict or Iterable,
327
- name: str or None = None,
328
- ):
329
- """Add additional initial parameter for evaluate.
330
-
331
- The parameter set is ignored if the main() is continued.
332
-
333
- Args:
334
- parameter (dict or Iterable): Parameter to evaluate before run optimization algorithm.
335
- name (str or None): Optional. If specified, the name is saved in the history row. Default to None.
336
-
337
- """
338
- if name is None:
339
- name = 'additional initial'
340
- else:
341
- name = f'additional initial ({name})'
342
- self.additional_initial_parameter.append([parameter, name])
343
-
344
- def run(self):
345
- """Set random seed, sampler, study and run study.optimize()."""
346
-
347
- # (re)set random seed
348
- seed = self.seed
349
- if seed is not None:
350
- if self.subprocess_idx is not None:
351
- seed += self.subprocess_idx
352
-
353
- # restore sampler
354
- if len(self.constraints) > 0:
355
- self.sampler_kwargs.update(
356
- constraints_func=self._constraint
357
- )
358
- if seed is not None:
359
- self.sampler_kwargs.update(
360
- seed=seed
361
- )
362
- parameters = inspect.signature(self.sampler_class.__init__).parameters
363
- sampler_kwargs = dict()
364
- for k, v in self.sampler_kwargs.items():
365
- if k in parameters.keys():
366
- sampler_kwargs.update({k: v})
367
- sampler = self.sampler_class(
368
- **sampler_kwargs
369
- )
370
-
371
- from pyfemtet.opt.optimizer._optuna._pof_botorch import PoFBoTorchSampler
372
- if isinstance(sampler, PoFBoTorchSampler):
373
- sampler._pyfemtet_constraints = [cns for cns in self.constraints.values() if cns.strict]
374
- sampler._pyfemtet_optimizer = self
375
-
376
- # load study
377
- self.storage: optuna.storages.BaseStorage
378
- studies = self.storage.get_all_studies()
379
- if self.study_name in [s.study_name for s in studies]:
380
- pass
381
-
382
- elif len(studies) >= 1:
383
- self.study_name = studies[-1].study_name
384
-
385
- else:
386
- raise ValueError('An empty db is passed.')
387
-
388
- study = optuna.load_study(
389
- study_name=self.study_name,
390
- storage=self.storage,
391
- sampler=sampler,
392
- )
393
-
394
- # use temporary storage or not
395
- if self._temporary_storage is None:
396
- # run
397
- study.optimize(
398
- self._objective,
399
- timeout=self.timeout,
400
- callbacks=self.optimize_callbacks,
401
- )
402
-
403
- else:
404
- # load study
405
- _study = optuna.load_study(
406
- study_name="tmp",
407
- storage=self._temporary_storage,
408
- sampler=sampler,
409
- )
410
-
411
- # Add callback to coppy back each trial.
412
- class CopyBack:
413
- def __call__(self, _: Study, trial: FrozenTrial) -> None:
414
- # Write back added trials to the existing study.
415
- study.add_trial(trial)
416
- self.optimize_callbacks.append(CopyBack())
417
-
418
- # run
419
- _study.optimize(
420
- self._objective,
421
- timeout=self.timeout,
422
- callbacks=self.optimize_callbacks,
423
- )
424
-
425
- # clean up
426
- try:
427
- self._temporary_storage.remove_session()
428
- del self._temporary_storage
429
- del _study
430
- gc.collect()
431
- if os.path.exists(self._temporary_storage_path):
432
- os.remove(self._temporary_storage_path)
433
- except:
434
- pass