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.
- pyfemtet/__init__.py +6 -1
- pyfemtet/_i18n/1. make_pot_and_update_po.bat +8 -0
- pyfemtet/_i18n/2. build_mo.bat +5 -0
- pyfemtet/_i18n/__init__.py +4 -0
- pyfemtet/_i18n/babel.cfg +2 -0
- pyfemtet/_i18n/i18n.py +37 -0
- pyfemtet/_i18n/locales/ja/LC_MESSAGES/messages.mo +0 -0
- pyfemtet/_i18n/locales/ja/LC_MESSAGES/messages.po +1020 -0
- pyfemtet/_i18n/locales/messages.pot +987 -0
- pyfemtet/{_message → _i18n}/messages.py +128 -41
- pyfemtet/_util/closing.py +19 -0
- pyfemtet/_util/dask_util.py +89 -7
- pyfemtet/_util/df_util.py +29 -0
- pyfemtet/_util/excel_macro_util.py +8 -3
- pyfemtet/_util/excel_parse_util.py +43 -23
- pyfemtet/_util/femtet_access_inspection.py +120 -0
- pyfemtet/{_femtet_config_util/autosave.py → _util/femtet_autosave.py} +7 -0
- pyfemtet/_util/femtet_exit.py +105 -0
- pyfemtet/_util/femtet_version.py +20 -0
- pyfemtet/_util/helper.py +94 -0
- pyfemtet/_util/process_util.py +107 -0
- pyfemtet/_util/str_enum.py +44 -0
- pyfemtet/core.py +15 -47
- pyfemtet/dispatch_extensions/__init__.py +8 -11
- pyfemtet/dispatch_extensions/_impl.py +42 -198
- pyfemtet/logger/__init__.py +8 -1
- pyfemtet/logger/_impl.py +5 -6
- pyfemtet/opt/__init__.py +3 -17
- pyfemtet/opt/exceptions.py +45 -0
- pyfemtet/opt/femopt.py +608 -0
- pyfemtet/opt/history/__init__.py +11 -0
- pyfemtet/opt/history/_history.py +1404 -0
- pyfemtet/opt/history/_hypervolume.py +169 -0
- pyfemtet/opt/history/_optimality.py +79 -0
- pyfemtet/opt/interface/__init__.py +17 -24
- pyfemtet/opt/interface/_base_interface.py +222 -0
- pyfemtet/opt/interface/_excel_interface/__init__.py +3 -0
- pyfemtet/opt/interface/_excel_interface/debug-excel-interface.xlsm +0 -0
- pyfemtet/opt/interface/_excel_interface/excel_interface.py +999 -0
- pyfemtet/opt/interface/_femtet_interface/__init__.py +3 -0
- pyfemtet/opt/interface/{_femtet_parametric.py → _femtet_interface/_femtet_parametric.py} +20 -12
- pyfemtet/opt/interface/{_femtet.py → _femtet_interface/femtet_interface.py} +505 -349
- pyfemtet/opt/interface/_femtet_with_nx_interface/__init__.py +5 -0
- pyfemtet/opt/interface/_femtet_with_nx_interface/femtet_with_nx_interface.py +230 -0
- pyfemtet/opt/interface/_femtet_with_nx_interface/model1.prt +0 -0
- pyfemtet/opt/interface/_femtet_with_nx_interface/model1.x_t +98 -0
- pyfemtet/opt/interface/{_femtet_with_nx → _femtet_with_nx_interface}/update_model.py +1 -3
- pyfemtet/opt/interface/_femtet_with_solidworks/__init__.py +5 -0
- pyfemtet/opt/interface/_femtet_with_solidworks/femtet_with_solidworks_interface.py +122 -0
- pyfemtet/opt/interface/_solidworks_interface/__init__.py +5 -0
- pyfemtet/opt/interface/_solidworks_interface/solidworks_interface.py +206 -0
- pyfemtet/opt/interface/_surrogate_model_interface/__init__.py +8 -0
- pyfemtet/opt/interface/_surrogate_model_interface/base_surrogate_interface.py +150 -0
- pyfemtet/opt/interface/_surrogate_model_interface/botorch_interface.py +298 -0
- pyfemtet/opt/interface/_surrogate_model_interface/debug-pof-botorch.reccsv +18 -0
- pyfemtet/opt/interface/_with_excel_settings/__init__.py +61 -0
- pyfemtet/opt/interface/_with_excel_settings/with_excel_settings.py +134 -0
- pyfemtet/opt/meta_script/YAML_Generator.xlsm +0 -0
- pyfemtet/opt/meta_script/__main__.py +58 -36
- pyfemtet/opt/optimizer/__init__.py +7 -9
- pyfemtet/opt/optimizer/_base_optimizer.py +885 -0
- pyfemtet/opt/optimizer/optuna_optimizer/__init__.py +9 -0
- pyfemtet/opt/optimizer/optuna_optimizer/_optuna_attribute.py +73 -0
- pyfemtet/opt/optimizer/optuna_optimizer/_optuna_optimizer.py +678 -0
- pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/__init__.py +7 -0
- pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/debug-pof-botorch.reccsv +18 -0
- pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/enable_nonlinear_constraint.py +244 -0
- pyfemtet/opt/optimizer/optuna_optimizer/_pof_botorch/pof_botorch_sampler.py +1249 -0
- pyfemtet/opt/optimizer/optuna_optimizer/wat_ex14_parametric_jp.femprj +0 -0
- pyfemtet/opt/optimizer/scipy_optimizer/__init__.py +1 -0
- pyfemtet/opt/optimizer/scipy_optimizer/_scipy_optimizer.py +364 -0
- pyfemtet/opt/prediction/__init__.py +7 -0
- pyfemtet/opt/prediction/_botorch_utils.py +133 -0
- pyfemtet/opt/prediction/_gpytorch_modules_extension.py +142 -0
- pyfemtet/opt/prediction/_helper.py +155 -0
- pyfemtet/opt/prediction/_model.py +118 -0
- pyfemtet/opt/problem/problem.py +304 -0
- pyfemtet/opt/problem/variable_manager/__init__.py +20 -0
- pyfemtet/opt/problem/variable_manager/_string_as_expression.py +115 -0
- pyfemtet/opt/problem/variable_manager/_variable_manager.py +295 -0
- pyfemtet/opt/visualization/history_viewer/__main__.py +5 -0
- pyfemtet/opt/visualization/{_base.py → history_viewer/_base_application.py} +18 -13
- pyfemtet/opt/visualization/history_viewer/_common_pages.py +150 -0
- pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/alert_region.py +10 -5
- pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/control_femtet.py +16 -13
- pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/main_graph.py +117 -47
- pyfemtet/opt/visualization/{_complex_components → history_viewer/_complex_components}/pm_graph.py +159 -138
- pyfemtet/opt/visualization/history_viewer/_process_monitor/_application.py +173 -0
- pyfemtet/opt/visualization/history_viewer/_process_monitor/_pages.py +291 -0
- pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/dbc.py +1 -1
- pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/dcc.py +1 -1
- pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/html.py +1 -1
- pyfemtet/opt/visualization/history_viewer/result_viewer/__main__.py +5 -0
- pyfemtet/opt/visualization/{result_viewer/application.py → history_viewer/result_viewer/_application.py} +6 -6
- pyfemtet/opt/visualization/{result_viewer/pages.py → history_viewer/result_viewer/_pages.py} +106 -82
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08.csv +18 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08.db +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8.log +45 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_1.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_1.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_10.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_10.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_11.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_11.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_12.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_12.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_13.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_13.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_14.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_14.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_15.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_15.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_16.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_16.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_17.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_17.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_18.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_18.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_19.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_19.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_2.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_2.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_20.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_20.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_3.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_3.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.bgr +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.bnd +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.btr +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.mtl +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_4.prm +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_5.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_5.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_6.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_6.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_7.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_7.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_8.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_8.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_9.jpg +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.Results/ex8_trial_9.pdt +0 -0
- pyfemtet/opt/visualization/history_viewer/result_viewer/tutorial_files/tutorial_gau_ex08_parametric.femprj +0 -0
- pyfemtet/opt/visualization/plotter/main_figure_creator.py +536 -0
- pyfemtet/opt/visualization/plotter/pm_graph_creator.py +359 -0
- pyfemtet/opt/worker_status.py +120 -0
- {pyfemtet-0.9.5.dist-info → pyfemtet-1.0.0b0.dist-info}/METADATA +23 -24
- pyfemtet-1.0.0b0.dist-info/RECORD +172 -0
- pyfemtet-1.0.0b0.dist-info/entry_points.txt +3 -0
- pyfemtet/_femtet_config_util/exit.py +0 -59
- pyfemtet/_message/1. make_pot.bat +0 -11
- pyfemtet/_message/2. make_mo.bat +0 -6
- pyfemtet/_message/__init__.py +0 -5
- pyfemtet/_message/babel.cfg +0 -2
- pyfemtet/_message/locales/ja/LC_MESSAGES/messages.mo +0 -0
- pyfemtet/_message/locales/ja/LC_MESSAGES/messages.po +0 -570
- pyfemtet/_message/locales/messages.pot +0 -551
- pyfemtet/_warning.py +0 -87
- pyfemtet/brep/_impl.py +0 -18
- pyfemtet/opt/_femopt.py +0 -1007
- pyfemtet/opt/_femopt_core.py +0 -1169
- pyfemtet/opt/_test_utils/control_femtet.py +0 -39
- pyfemtet/opt/_test_utils/hyper_sphere.py +0 -24
- pyfemtet/opt/_test_utils/record_history.py +0 -130
- pyfemtet/opt/advanced_samples/excel_ui/(ref) original_project.femprj +0 -0
- pyfemtet/opt/advanced_samples/excel_ui/femtet-macro.xlsm +0 -0
- pyfemtet/opt/advanced_samples/excel_ui/pyfemtet-core.py +0 -291
- pyfemtet/opt/advanced_samples/excel_ui/test-pyfemtet-core.cmd +0 -22
- pyfemtet/opt/advanced_samples/restart/gal_ex13_parametric.femprj +0 -0
- pyfemtet/opt/advanced_samples/restart/gal_ex13_parametric_restart.py +0 -99
- pyfemtet/opt/advanced_samples/restart/gal_ex13_parametric_restart_jp.py +0 -102
- pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_create_training_data.py +0 -60
- pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_create_training_data_jp.py +0 -57
- pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_optimize_with_surrogate.py +0 -100
- pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_optimize_with_surrogate_jp.py +0 -90
- pyfemtet/opt/advanced_samples/surrogate_model/gal_ex13_parametric.femprj +0 -0
- pyfemtet/opt/interface/_base.py +0 -101
- pyfemtet/opt/interface/_excel_interface.py +0 -984
- pyfemtet/opt/interface/_femtet_excel.py +0 -141
- pyfemtet/opt/interface/_femtet_with_nx/__init__.py +0 -3
- pyfemtet/opt/interface/_femtet_with_nx/_interface.py +0 -178
- pyfemtet/opt/interface/_femtet_with_sldworks.py +0 -298
- pyfemtet/opt/interface/_surrogate/__init__.py +0 -5
- pyfemtet/opt/interface/_surrogate/_base.py +0 -129
- pyfemtet/opt/interface/_surrogate/_chaospy.py +0 -71
- pyfemtet/opt/interface/_surrogate/_singletaskgp.py +0 -71
- pyfemtet/opt/interface/_surrogate_excel.py +0 -102
- pyfemtet/opt/optimizer/_base.py +0 -376
- pyfemtet/opt/optimizer/_optuna/_botorch_patch/enable_nonlinear_constraint.py +0 -220
- pyfemtet/opt/optimizer/_optuna/_optuna.py +0 -434
- pyfemtet/opt/optimizer/_optuna/_pof_botorch.py +0 -1914
- pyfemtet/opt/optimizer/_scipy.py +0 -159
- pyfemtet/opt/optimizer/_scipy_scalar.py +0 -127
- pyfemtet/opt/optimizer/parameter.py +0 -113
- pyfemtet/opt/prediction/_base.py +0 -61
- pyfemtet/opt/prediction/single_task_gp.py +0 -119
- pyfemtet/opt/samples/femprj_sample/ParametricIF.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/ParametricIF.py +0 -29
- pyfemtet/opt/samples/femprj_sample/ParametricIF_test_result.reccsv +0 -13
- pyfemtet/opt/samples/femprj_sample/cad_ex01_NX.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/cad_ex01_NX.prt +0 -0
- pyfemtet/opt/samples/femprj_sample/cad_ex01_NX.py +0 -135
- pyfemtet/opt/samples/femprj_sample/cad_ex01_NX_test_result.reccsv +0 -23
- pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.SLDPRT +0 -0
- pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/cad_ex01_SW.py +0 -131
- pyfemtet/opt/samples/femprj_sample/cad_ex01_SW_test_result.reccsv +0 -23
- pyfemtet/opt/samples/femprj_sample/constrained_pipe.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/constrained_pipe.py +0 -96
- pyfemtet/opt/samples/femprj_sample/constrained_pipe_test_result.reccsv +0 -13
- pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric.py +0 -74
- pyfemtet/opt/samples/femprj_sample/gal_ex58_parametric_test_result.reccsv +0 -13
- pyfemtet/opt/samples/femprj_sample/gau_ex08_parametric.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/gau_ex08_parametric.py +0 -58
- pyfemtet/opt/samples/femprj_sample/gau_ex08_parametric_test_result.reccsv +0 -23
- pyfemtet/opt/samples/femprj_sample/gau_ex12_parametric.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/gau_ex12_parametric.py +0 -52
- pyfemtet/opt/samples/femprj_sample/her_ex40_parametric.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/her_ex40_parametric.py +0 -138
- pyfemtet/opt/samples/femprj_sample/her_ex40_parametric_test_result.reccsv +0 -18
- pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric.py +0 -60
- pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric_parallel.py +0 -61
- pyfemtet/opt/samples/femprj_sample/paswat_ex1_parametric_test_result.reccsv +0 -18
- pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric.py +0 -58
- pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric_parallel.py +0 -58
- pyfemtet/opt/samples/femprj_sample/wat_ex14_parametric_test_result.reccsv +0 -18
- pyfemtet/opt/samples/femprj_sample_jp/ParametricIF_jp.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample_jp/ParametricIF_jp.py +0 -29
- pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_NX_jp.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_NX_jp.py +0 -129
- pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_SW_jp.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample_jp/cad_ex01_SW_jp.py +0 -125
- pyfemtet/opt/samples/femprj_sample_jp/constrained_pipe_jp.py +0 -93
- pyfemtet/opt/samples/femprj_sample_jp/gal_ex58_parametric_jp.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample_jp/gal_ex58_parametric_jp.py +0 -70
- pyfemtet/opt/samples/femprj_sample_jp/gau_ex08_parametric_jp.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample_jp/gau_ex08_parametric_jp.py +0 -57
- pyfemtet/opt/samples/femprj_sample_jp/gau_ex12_parametric_jp.py +0 -52
- pyfemtet/opt/samples/femprj_sample_jp/her_ex40_parametric_jp.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample_jp/her_ex40_parametric_jp.py +0 -138
- pyfemtet/opt/samples/femprj_sample_jp/paswat_ex1_parametric_jp.femprj +0 -0
- pyfemtet/opt/samples/femprj_sample_jp/paswat_ex1_parametric_jp.py +0 -58
- pyfemtet/opt/samples/femprj_sample_jp/paswat_ex1_parametric_parallel_jp.py +0 -59
- pyfemtet/opt/samples/femprj_sample_jp/wat_ex14_parametric_jp.py +0 -56
- pyfemtet/opt/samples/femprj_sample_jp/wat_ex14_parametric_parallel_jp.py +0 -56
- pyfemtet/opt/visualization/_complex_components/main_figure_creator.py +0 -332
- pyfemtet/opt/visualization/_complex_components/pm_graph_creator.py +0 -201
- pyfemtet/opt/visualization/_process_monitor/application.py +0 -226
- pyfemtet/opt/visualization/_process_monitor/pages.py +0 -406
- pyfemtet/opt/visualization/_wrapped_components/__init__.py +0 -0
- pyfemtet/opt/visualization/result_viewer/__init__.py +0 -0
- pyfemtet-0.9.5.dist-info/RECORD +0 -158
- pyfemtet-0.9.5.dist-info/entry_points.txt +0 -3
- /pyfemtet/{_femtet_config_util → opt/problem}/__init__.py +0 -0
- /pyfemtet/{brep → opt/visualization/history_viewer}/__init__.py +0 -0
- /pyfemtet/opt/{_test_utils → visualization/history_viewer/_complex_components}/__init__.py +0 -0
- /pyfemtet/opt/{optimizer/_optuna → visualization/history_viewer/_process_monitor}/__init__.py +0 -0
- /pyfemtet/opt/{optimizer/_optuna/_botorch_patch → visualization/history_viewer/_wrapped_components}/__init__.py +0 -0
- /pyfemtet/opt/visualization/{_wrapped_components → history_viewer/_wrapped_components}/str_enum.py +0 -0
- /pyfemtet/opt/visualization/{result_viewer → history_viewer/result_viewer}/.gitignore +0 -0
- /pyfemtet/opt/visualization/{_complex_components → history_viewer/result_viewer}/__init__.py +0 -0
- /pyfemtet/opt/visualization/{_process_monitor → plotter}/__init__.py +0 -0
- /pyfemtet/opt/{samples/femprj_sample_jp/wat_ex14_parametric_jp.femprj → wat_ex14_parametric_jp.femprj} +0 -0
- {pyfemtet-0.9.5.dist-info → pyfemtet-1.0.0b0.dist-info}/LICENSE +0 -0
- {pyfemtet-0.9.5.dist-info → pyfemtet-1.0.0b0.dist-info}/LICENSE_THIRD_PARTY.txt +0 -0
- {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,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
|