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,206 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from time import sleep
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import re
|
|
8
|
+
|
|
9
|
+
from win32com.client import DispatchEx, CDispatch
|
|
10
|
+
# noinspection PyUnresolvedReferences
|
|
11
|
+
from pythoncom import CoInitialize, CoUninitialize, com_error
|
|
12
|
+
|
|
13
|
+
from pyfemtet._util.dask_util import *
|
|
14
|
+
from pyfemtet.opt.exceptions import *
|
|
15
|
+
from pyfemtet.opt.interface._base_interface import COMInterface
|
|
16
|
+
from pyfemtet._i18n import _
|
|
17
|
+
from pyfemtet.opt.problem.variable_manager import SupportedVariableTypes
|
|
18
|
+
from pyfemtet.logger import get_module_logger
|
|
19
|
+
|
|
20
|
+
if TYPE_CHECKING:
|
|
21
|
+
from pyfemtet.opt.optimizer import AbstractOptimizer
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
logger = get_module_logger('opt.interface', False)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# 定数の宣言
|
|
28
|
+
swThisConfiguration = 1 # https://help.solidworks.com/2023/english/api/swconst/SOLIDWORKS.Interop.swconst~SOLIDWORKS.Interop.swconst.swInConfigurationOpts_e.html
|
|
29
|
+
swAllConfiguration = 2
|
|
30
|
+
swSpecifyConfiguration = 3 # use with ConfigName argument
|
|
31
|
+
swSaveAsCurrentVersion = 0
|
|
32
|
+
swSaveAsOptions_Copy = 2 #
|
|
33
|
+
swSaveAsOptions_Silent = 1 # https://help.solidworks.com/2021/english/api/swconst/solidworks.interop.swconst~solidworks.interop.swconst.swsaveasoptions_e.html
|
|
34
|
+
swSaveWithReferencesOptions_None = 0 # https://help-solidworks-com.translate.goog/2023/english/api/swconst/SolidWorks.Interop.swconst~SolidWorks.Interop.swconst.swSaveWithReferencesOptions_e.html?_x_tr_sl=auto&_x_tr_tl=ja&_x_tr_hl=ja&_x_tr_pto=wapp
|
|
35
|
+
swDocPART = 1 # https://help.solidworks.com/2023/english/api/swconst/SOLIDWORKS.Interop.swconst~SOLIDWORKS.Interop.swconst.swDocumentTypes_e.html
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class FileNotOpenedError(Exception):
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# noinspection PyPep8Naming
|
|
43
|
+
class SolidworksInterface(COMInterface):
|
|
44
|
+
|
|
45
|
+
swApp: CDispatch
|
|
46
|
+
com_members = {'swApp': 'SLDWORKS.Application'}
|
|
47
|
+
_access_sw_lock_name = 'access_sw'
|
|
48
|
+
|
|
49
|
+
def __init__(
|
|
50
|
+
self,
|
|
51
|
+
sldprt_path,
|
|
52
|
+
close_solidworks_on_terminate=False,
|
|
53
|
+
visible=True,
|
|
54
|
+
):
|
|
55
|
+
self.sldprt_path = os.path.abspath(sldprt_path)
|
|
56
|
+
self.quit_solidworks_on_terminate = close_solidworks_on_terminate
|
|
57
|
+
self.solidworks_visible = visible
|
|
58
|
+
|
|
59
|
+
assert os.path.isfile(self.sldprt_path)
|
|
60
|
+
self._original_sldprt_path = self.sldprt_path
|
|
61
|
+
|
|
62
|
+
def connect_sw(self):
|
|
63
|
+
logger.info(_(
|
|
64
|
+
en_message='Connecting to Solidworks...',
|
|
65
|
+
jp_message='Solidworks に接続しています...'
|
|
66
|
+
))
|
|
67
|
+
try:
|
|
68
|
+
self.swApp = DispatchEx('SLDWORKS.Application')
|
|
69
|
+
except com_error:
|
|
70
|
+
raise Exception(_(
|
|
71
|
+
en_message='Failed to instantiate Solidworks. '
|
|
72
|
+
'Please check installation and enabling macro.',
|
|
73
|
+
jp_message='Solidworks のインスタンス化に失敗しました。'
|
|
74
|
+
'Solidworks がインストールされており、'
|
|
75
|
+
'Solidworks マクロが有効であることを確認してください。'))
|
|
76
|
+
self.swApp.Visible = self.solidworks_visible
|
|
77
|
+
|
|
78
|
+
def _setup_before_parallel(self):
|
|
79
|
+
self._distribute_files([self.sldprt_path])
|
|
80
|
+
|
|
81
|
+
def _setup_after_parallel(self, opt: AbstractOptimizer = None):
|
|
82
|
+
|
|
83
|
+
# get suffix
|
|
84
|
+
suffix = self._get_worker_index_from_optimizer(opt)
|
|
85
|
+
|
|
86
|
+
# rename and get worker path
|
|
87
|
+
self.sldprt_path = self._rename_and_get_path_on_worker_space(
|
|
88
|
+
self._original_sldprt_path,
|
|
89
|
+
suffix,
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
# connect solidworks
|
|
93
|
+
CoInitialize()
|
|
94
|
+
with Lock(self._access_sw_lock_name):
|
|
95
|
+
self.connect_sw()
|
|
96
|
+
|
|
97
|
+
# open it
|
|
98
|
+
self.swApp.OpenDoc(self.sldprt_path, swDocPART)
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def swModel(self) -> CDispatch:
|
|
102
|
+
return _get_model_by_basename(self.swApp, os.path.basename(self.sldprt_path))
|
|
103
|
+
|
|
104
|
+
def update(self) -> None:
|
|
105
|
+
raise NotImplementedError
|
|
106
|
+
|
|
107
|
+
def update_parameter(self, x: dict[str, SupportedVariableTypes]) -> None:
|
|
108
|
+
|
|
109
|
+
COMInterface.update_parameter(self, x)
|
|
110
|
+
|
|
111
|
+
# sw はプロセスが一つなので Lock
|
|
112
|
+
with Lock(self._access_sw_lock_name):
|
|
113
|
+
|
|
114
|
+
sleep(0.2)
|
|
115
|
+
|
|
116
|
+
# ===== model を取得 =====
|
|
117
|
+
swModel = self.swModel
|
|
118
|
+
|
|
119
|
+
# ===== equation manager を取得 =====
|
|
120
|
+
swEqnMgr = swModel.GetEquationMgr
|
|
121
|
+
nEquation = swEqnMgr.GetCount
|
|
122
|
+
|
|
123
|
+
# プロパティを退避
|
|
124
|
+
buffer_aso = swEqnMgr.AutomaticSolveOrder
|
|
125
|
+
buffer_ar = swEqnMgr.AutomaticRebuild
|
|
126
|
+
swEqnMgr.AutomaticSolveOrder = False
|
|
127
|
+
swEqnMgr.AutomaticRebuild = False
|
|
128
|
+
|
|
129
|
+
# 値を更新
|
|
130
|
+
for i in range(nEquation):
|
|
131
|
+
# name, equation の取得
|
|
132
|
+
eq = swEqnMgr.Equation(i)
|
|
133
|
+
prm_name = _get_name_from_equation(eq)
|
|
134
|
+
# 対象なら処理
|
|
135
|
+
if prm_name in self.current_prm_values:
|
|
136
|
+
new_equation = f'"{prm_name}" = {self.current_prm_values[prm_name]}'
|
|
137
|
+
swEqnMgr.Equation(i, new_equation)
|
|
138
|
+
|
|
139
|
+
# 式の計算
|
|
140
|
+
# noinspection PyStatementEffect
|
|
141
|
+
swEqnMgr.EvaluateAll # always returns -1
|
|
142
|
+
|
|
143
|
+
# プロパティをもとに戻す
|
|
144
|
+
swEqnMgr.AutomaticSolveOrder = buffer_aso
|
|
145
|
+
swEqnMgr.AutomaticRebuild = buffer_ar
|
|
146
|
+
|
|
147
|
+
def update_model(self):
|
|
148
|
+
"""Update .sldprt"""
|
|
149
|
+
|
|
150
|
+
# sw はプロセスが一つなので Lock
|
|
151
|
+
with Lock(self._access_sw_lock_name):
|
|
152
|
+
|
|
153
|
+
sleep(0.2)
|
|
154
|
+
|
|
155
|
+
# ===== model を取得 =====
|
|
156
|
+
swModel = self.swModel
|
|
157
|
+
|
|
158
|
+
# モデル再構築
|
|
159
|
+
result = swModel.EditRebuild3 # モデル再構築
|
|
160
|
+
if not result:
|
|
161
|
+
raise ModelError(_(
|
|
162
|
+
en_message='Failed to update the model on Solidworks.',
|
|
163
|
+
jp_message='Solidworks モデルの更新に失敗しました。'
|
|
164
|
+
))
|
|
165
|
+
|
|
166
|
+
def close(self):
|
|
167
|
+
if not hasattr(self, 'swApp'):
|
|
168
|
+
return
|
|
169
|
+
|
|
170
|
+
if self.swApp is None:
|
|
171
|
+
return
|
|
172
|
+
|
|
173
|
+
with Lock(self._access_sw_lock_name):
|
|
174
|
+
model_name = os.path.basename(self.sldprt_path)
|
|
175
|
+
logger.info(_(
|
|
176
|
+
en_message='Closing {model_name} ...',
|
|
177
|
+
jp_message='モデル {model_name} を閉じています...',
|
|
178
|
+
model_name=model_name,
|
|
179
|
+
))
|
|
180
|
+
|
|
181
|
+
# 最後の Doc ならばプロセスを落とす仕様?
|
|
182
|
+
self.swApp.QuitDoc(os.path.basename(self.sldprt_path))
|
|
183
|
+
# logger.info(Msg.F_SW_MODEL_CLOSED(model_name))
|
|
184
|
+
logger.info(_(
|
|
185
|
+
en_message='Successfully closed {model_name}.',
|
|
186
|
+
jp_message='モデル {model_name} を閉じました。',
|
|
187
|
+
model_name=model_name,
|
|
188
|
+
))
|
|
189
|
+
sleep(3)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
# noinspection PyPep8Naming
|
|
193
|
+
def _get_model_by_basename(swApp, basename):
|
|
194
|
+
swModel = swApp.ActivateDoc(basename)
|
|
195
|
+
if swModel is None:
|
|
196
|
+
raise FileNotOpenedError(f'Model {basename} is not opened.')
|
|
197
|
+
return swModel
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def _get_name_from_equation(equation: str):
|
|
201
|
+
pattern = r'^\s*"(.+?)"\s*$'
|
|
202
|
+
matched = re.match(pattern, equation.split('=')[0])
|
|
203
|
+
if matched:
|
|
204
|
+
return matched.group(1)
|
|
205
|
+
else:
|
|
206
|
+
return None
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Sequence
|
|
4
|
+
|
|
5
|
+
from pyfemtet.opt.history import *
|
|
6
|
+
|
|
7
|
+
from pyfemtet.opt.interface import AbstractFEMInterface
|
|
8
|
+
from pyfemtet._i18n import _
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from pyfemtet.opt.optimizer import AbstractOptimizer
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
'AbstractSurrogateModelInterfaceBase',
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class AbstractSurrogateModelInterfaceBase(AbstractFEMInterface):
|
|
20
|
+
_load_problem_from_fem = True
|
|
21
|
+
current_obj_values: dict[str, float]
|
|
22
|
+
train_history: History
|
|
23
|
+
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
history_path: str = None,
|
|
27
|
+
train_history: History = None,
|
|
28
|
+
_output_directions: (
|
|
29
|
+
Sequence[str | float]
|
|
30
|
+
| dict[str, str | float]
|
|
31
|
+
| dict[int, str | float]
|
|
32
|
+
) = None
|
|
33
|
+
):
|
|
34
|
+
|
|
35
|
+
self._output_directions = _output_directions
|
|
36
|
+
|
|
37
|
+
# history_path が与えられた場合、train_history をコンストラクトする
|
|
38
|
+
if history_path is not None:
|
|
39
|
+
train_history = History()
|
|
40
|
+
train_history.load_csv(history_path, with_finalize=True)
|
|
41
|
+
|
|
42
|
+
assert train_history is not None
|
|
43
|
+
|
|
44
|
+
self.train_history = train_history
|
|
45
|
+
|
|
46
|
+
self.current_obj_values = {}
|
|
47
|
+
|
|
48
|
+
def load_objectives(self, opt: AbstractOptimizer):
|
|
49
|
+
|
|
50
|
+
# output directions が与えられない場合、
|
|
51
|
+
# opt.add_objective との整合をチェックする
|
|
52
|
+
if self._output_directions is None:
|
|
53
|
+
|
|
54
|
+
# add_objective された目的のうち、
|
|
55
|
+
# training data に含まれる名前ならば
|
|
56
|
+
# fun を「その時点の current_obj_values を返す関数」で
|
|
57
|
+
# 上書き
|
|
58
|
+
obj_name: str
|
|
59
|
+
for obj_name, obj in opt.objectives.items():
|
|
60
|
+
# あれば上書き、なければ surrogate 最適化の際に
|
|
61
|
+
# 新しく追加した model を使わない目的関数と見做して何もしない
|
|
62
|
+
if obj_name in self.train_history.obj_names:
|
|
63
|
+
obj.fun = lambda _, obj_name_=obj_name: self.current_obj_values[obj_name_]
|
|
64
|
+
|
|
65
|
+
# dict で与えられた場合
|
|
66
|
+
elif isinstance(self._output_directions, dict):
|
|
67
|
+
|
|
68
|
+
# index 入力か str 入力かで統一されているか確認
|
|
69
|
+
keys = tuple(self._output_directions.keys())
|
|
70
|
+
assert all([isinstance(key, type(keys[0])) for key in keys]), _(
|
|
71
|
+
en_message='The keys of _output_directions must be '
|
|
72
|
+
'all-int or all-str.',
|
|
73
|
+
jp_message='_output_directions のキーは int または str で'
|
|
74
|
+
'統一されていなければなりません。',
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# index がキーである場合
|
|
78
|
+
if isinstance(keys[0], int):
|
|
79
|
+
|
|
80
|
+
for index, direction in self._output_directions.items():
|
|
81
|
+
obj_name = self.train_history.obj_names[index]
|
|
82
|
+
|
|
83
|
+
opt.add_objective(
|
|
84
|
+
name=obj_name,
|
|
85
|
+
fun=lambda _, obj_name_=obj_name: self.current_obj_values[obj_name_],
|
|
86
|
+
direction=direction,
|
|
87
|
+
args=(),
|
|
88
|
+
kwargs={},
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# obj_name がキーである場合
|
|
92
|
+
if isinstance(keys[0], str):
|
|
93
|
+
|
|
94
|
+
for obj_name, direction in self._output_directions.items():
|
|
95
|
+
assert obj_name in self.train_history.obj_names, _(
|
|
96
|
+
en_message='The objective name passed as a key of '
|
|
97
|
+
'_output_direction must be one of the history\'s '
|
|
98
|
+
'objective names. Passed name: {obj_name} / '
|
|
99
|
+
'History\'s names: {obj_names}',
|
|
100
|
+
jp_message='_output_directions に目的関数名を与える場合は'
|
|
101
|
+
'history に含まれる名前を指定しなければなりません。'
|
|
102
|
+
'与えられた目的名: {obj_name} / history に含まれる'
|
|
103
|
+
'目的名: {obj_names}',
|
|
104
|
+
obj_name=obj_name,
|
|
105
|
+
obj_names=', '.join(self.train_history.obj_names)
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
opt.add_objective(
|
|
109
|
+
name=obj_name,
|
|
110
|
+
fun=lambda obj_name_=obj_name: self.current_obj_values[obj_name_],
|
|
111
|
+
direction=direction,
|
|
112
|
+
args=(),
|
|
113
|
+
kwargs={},
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
# tuple で与えられた場合
|
|
117
|
+
elif isinstance(self._output_directions, list) \
|
|
118
|
+
or isinstance(self._output_directions, tuple):
|
|
119
|
+
|
|
120
|
+
obj_names = self.train_history.obj_names
|
|
121
|
+
assert len(self._output_directions) == len(obj_names), _(
|
|
122
|
+
en_message='The length of _output_directions passed as a list '
|
|
123
|
+
'must be same with that of the history\'s objective '
|
|
124
|
+
'names.',
|
|
125
|
+
jp_message='_output_directions をリストで渡す場合は'
|
|
126
|
+
'その長さが history の目的関数数と一致して'
|
|
127
|
+
'いなければなりません。'
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
for obj_name, direction in zip(obj_names, self._output_directions):
|
|
131
|
+
opt.add_objective(
|
|
132
|
+
name=obj_name,
|
|
133
|
+
fun=lambda _, obj_name_=obj_name: self.current_obj_values[obj_name_],
|
|
134
|
+
direction=direction,
|
|
135
|
+
args=(),
|
|
136
|
+
kwargs={},
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
def load_variables(self, opt: AbstractOptimizer):
|
|
140
|
+
# opt の変数が充分であるかのチェックのみ
|
|
141
|
+
parameters = opt.variable_manager.get_variables()
|
|
142
|
+
assert len(set(self.train_history.prm_names) - set(parameters.keys())) == 0
|
|
143
|
+
|
|
144
|
+
def _check_using_fem(self, fun: callable) -> bool:
|
|
145
|
+
return False
|
|
146
|
+
|
|
147
|
+
def _check_param_and_raise(self, prm_name) -> None:
|
|
148
|
+
if prm_name not in self.train_history.prm_names:
|
|
149
|
+
raise KeyError(f'Parameter name {prm_name} is not in '
|
|
150
|
+
f'training input {self.train_history.prm_names}.')
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
from typing import Sequence
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from scipy.stats.distributions import norm
|
|
5
|
+
|
|
6
|
+
# from gpytorch.priors.torch_priors import GammaPrior
|
|
7
|
+
|
|
8
|
+
from pyfemtet._i18n import _
|
|
9
|
+
from pyfemtet.opt.history import *
|
|
10
|
+
from pyfemtet.opt.exceptions import *
|
|
11
|
+
|
|
12
|
+
from pyfemtet.opt.prediction._model import PyFemtetModel, SingleTaskGPModel
|
|
13
|
+
|
|
14
|
+
from pyfemtet.opt.interface._surrogate_model_interface.base_surrogate_interface import AbstractSurrogateModelInterfaceBase
|
|
15
|
+
|
|
16
|
+
from pyfemtet.logger import get_module_logger
|
|
17
|
+
|
|
18
|
+
logger = get_module_logger('opt.interface', False)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
'BoTorchInterface',
|
|
23
|
+
'PoFBoTorchInterface',
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class BoTorchInterface(AbstractSurrogateModelInterfaceBase):
|
|
28
|
+
|
|
29
|
+
def __init__(
|
|
30
|
+
self,
|
|
31
|
+
history_path: str = None,
|
|
32
|
+
train_history: History = None,
|
|
33
|
+
_output_directions: (
|
|
34
|
+
Sequence[str | float]
|
|
35
|
+
| dict[str, str | float]
|
|
36
|
+
| dict[int, str | float]
|
|
37
|
+
) = None
|
|
38
|
+
):
|
|
39
|
+
AbstractSurrogateModelInterfaceBase.__init__(
|
|
40
|
+
self,
|
|
41
|
+
history_path,
|
|
42
|
+
train_history,
|
|
43
|
+
_output_directions
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
self.model = SingleTaskGPModel()
|
|
47
|
+
self.pyfemtet_model = PyFemtetModel()
|
|
48
|
+
|
|
49
|
+
# get main only
|
|
50
|
+
df = self.train_history.get_df(MAIN_FILTER)
|
|
51
|
+
|
|
52
|
+
# filter succeeded only
|
|
53
|
+
df = df[df['state'] == TrialState.succeeded]
|
|
54
|
+
|
|
55
|
+
# training
|
|
56
|
+
self.pyfemtet_model.update_model(self.model)
|
|
57
|
+
self.pyfemtet_model.fit(
|
|
58
|
+
history=self.train_history,
|
|
59
|
+
df=df,
|
|
60
|
+
observation_noise='no',
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
def update(self) -> None:
|
|
64
|
+
# update current objective values
|
|
65
|
+
x = np.array([self.current_prm_values.values()])
|
|
66
|
+
|
|
67
|
+
y, _ = self.pyfemtet_model.predict(x)
|
|
68
|
+
y = y[0]
|
|
69
|
+
|
|
70
|
+
for obj_name, obj_value in zip(self.train_history.obj_names, y):
|
|
71
|
+
self.current_obj_values.update({obj_name: obj_value})
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class PoFBoTorchInterface(BoTorchInterface, AbstractSurrogateModelInterfaceBase):
|
|
75
|
+
|
|
76
|
+
_debug: bool = False
|
|
77
|
+
|
|
78
|
+
def __init__(
|
|
79
|
+
self,
|
|
80
|
+
history_path: str,
|
|
81
|
+
train_history: History = None,
|
|
82
|
+
observation_noise: float | str | None = None,
|
|
83
|
+
feasibility_noise: float | str | None = None,
|
|
84
|
+
feasibility_cdf_threshold: float | str = 0.5, # or 'sample_mean'
|
|
85
|
+
_output_directions: (
|
|
86
|
+
Sequence[str | float]
|
|
87
|
+
| dict[str, str | float]
|
|
88
|
+
| dict[int, str | float]
|
|
89
|
+
) = None
|
|
90
|
+
):
|
|
91
|
+
AbstractSurrogateModelInterfaceBase.__init__(
|
|
92
|
+
self,
|
|
93
|
+
history_path,
|
|
94
|
+
train_history,
|
|
95
|
+
_output_directions
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
self.model = SingleTaskGPModel()
|
|
99
|
+
self.pyfemtet_model = PyFemtetModel()
|
|
100
|
+
self.model_c = SingleTaskGPModel()
|
|
101
|
+
self.pyfemtet_model_c = PyFemtetModel()
|
|
102
|
+
self.train_history_c = History()
|
|
103
|
+
self.train_history_c.load_csv(history_path, with_finalize=True)
|
|
104
|
+
self.pof_threshold = 0.5
|
|
105
|
+
self.feasibility_cdf_threshold = feasibility_cdf_threshold
|
|
106
|
+
|
|
107
|
+
# use feasibility as a single objective
|
|
108
|
+
self.train_history_c.obj_names = ['feasibility']
|
|
109
|
+
|
|
110
|
+
# get main only
|
|
111
|
+
df = self.train_history.get_df(MAIN_FILTER)
|
|
112
|
+
df_c = self.train_history_c.get_df(MAIN_FILTER)
|
|
113
|
+
|
|
114
|
+
# filter succeeded only for main
|
|
115
|
+
df = df[df['state'] == TrialState.succeeded]
|
|
116
|
+
|
|
117
|
+
# convert type bool to float
|
|
118
|
+
df_c = df_c.astype({'feasibility': float})
|
|
119
|
+
|
|
120
|
+
# training main
|
|
121
|
+
self.pyfemtet_model.update_model(self.model)
|
|
122
|
+
self.pyfemtet_model.fit(
|
|
123
|
+
history=self.train_history,
|
|
124
|
+
df=df,
|
|
125
|
+
observation_noise=observation_noise,
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
# training model_c
|
|
129
|
+
self.pyfemtet_model_c.update_model(self.model_c)
|
|
130
|
+
self.pyfemtet_model_c.fit(
|
|
131
|
+
history=self.train_history_c,
|
|
132
|
+
df=df_c,
|
|
133
|
+
# observation_noise=None,
|
|
134
|
+
# observation_noise='no',
|
|
135
|
+
# observation_noise=0.001,
|
|
136
|
+
observation_noise=feasibility_noise,
|
|
137
|
+
# covar_module_settings=dict(
|
|
138
|
+
# name='matern_kernel_with_gamma_prior',
|
|
139
|
+
# nu=2.5,
|
|
140
|
+
# lengthscale_prior=GammaPrior(1.0, 9.0), # default: 3, 6
|
|
141
|
+
# outputscale_prior=GammaPrior(1.0, 0.15), # default: 2, 0.15
|
|
142
|
+
# )
|
|
143
|
+
covar_module_settings=dict(
|
|
144
|
+
name='get_covar_module_with_dim_scaled_prior_extension',
|
|
145
|
+
loc_coef=0.01,
|
|
146
|
+
scale_coef=0.01,
|
|
147
|
+
)
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
# set auto feasibility_cdf_threshold
|
|
151
|
+
if self.feasibility_cdf_threshold == 'sample_mean':
|
|
152
|
+
self.feasibility_cdf_threshold = df_c['feasibility'].mean()
|
|
153
|
+
|
|
154
|
+
if self._debug:
|
|
155
|
+
self._debug_df_c = df_c
|
|
156
|
+
|
|
157
|
+
def calc_pof(self):
|
|
158
|
+
|
|
159
|
+
if self._debug:
|
|
160
|
+
import plotly.graph_objects as go
|
|
161
|
+
|
|
162
|
+
df = self._debug_df_c
|
|
163
|
+
|
|
164
|
+
x_list = []
|
|
165
|
+
prm_names = self.train_history_c.prm_names
|
|
166
|
+
for prm_name in prm_names:
|
|
167
|
+
x_list.append(np.linspace(
|
|
168
|
+
df[prm_name + '_lower_bound'].values[0],
|
|
169
|
+
df[prm_name + '_upper_bound'].values[0],
|
|
170
|
+
20
|
|
171
|
+
))
|
|
172
|
+
|
|
173
|
+
for i in range(len(x_list)):
|
|
174
|
+
for j in range(i, len(x_list)):
|
|
175
|
+
if i == j:
|
|
176
|
+
continue
|
|
177
|
+
|
|
178
|
+
# i=0
|
|
179
|
+
# j=1
|
|
180
|
+
|
|
181
|
+
xx = np.meshgrid(x_list[i], x_list[j])
|
|
182
|
+
|
|
183
|
+
x_plot = np.array([[x[0]] * 400 for x in x_list]).T
|
|
184
|
+
x_plot[:, i] = xx[0].ravel()
|
|
185
|
+
x_plot[:, j] = xx[1].ravel()
|
|
186
|
+
|
|
187
|
+
y_mean, y_std = self.pyfemtet_model_c.predict(x_plot)
|
|
188
|
+
# feasibility_cdf_threshold = self.feasibility_cdf_threshold
|
|
189
|
+
# feasibility_cdf_threshold = 0.5
|
|
190
|
+
cdf_threshold = 0.25 # 不明なところは pof が 1 近くにすればあとは ACQF がうまいことやってくれる
|
|
191
|
+
# feasibility_cdf_threshold = self.feasibility_cdf_threshold * 0.5
|
|
192
|
+
pof = 1 - norm.cdf(cdf_threshold, y_mean, y_std)
|
|
193
|
+
|
|
194
|
+
x1 = x_list[i]
|
|
195
|
+
x2 = x_list[j]
|
|
196
|
+
xx1 = xx[0]
|
|
197
|
+
xx2 = xx[1]
|
|
198
|
+
|
|
199
|
+
fig = go.Figure()
|
|
200
|
+
fig.add_trace(
|
|
201
|
+
go.Contour(
|
|
202
|
+
x0=x1[0],
|
|
203
|
+
y0=x2[0],
|
|
204
|
+
dx=np.diff(x1)[0],
|
|
205
|
+
dy=np.diff(x2)[0],
|
|
206
|
+
z=pof.reshape(xx1.shape),
|
|
207
|
+
)
|
|
208
|
+
)
|
|
209
|
+
fig.add_trace(
|
|
210
|
+
go.Scatter(
|
|
211
|
+
x=self._debug_df_c[prm_names[i]],
|
|
212
|
+
y=self._debug_df_c[prm_names[j]],
|
|
213
|
+
mode='markers',
|
|
214
|
+
marker=dict(
|
|
215
|
+
color=self._debug_df_c['feasibility'],
|
|
216
|
+
colorscale='greens',
|
|
217
|
+
),
|
|
218
|
+
)
|
|
219
|
+
)
|
|
220
|
+
fig.show()
|
|
221
|
+
|
|
222
|
+
fig = go.Figure()
|
|
223
|
+
fig.add_trace(
|
|
224
|
+
go.Surface(
|
|
225
|
+
x=xx1,
|
|
226
|
+
y=xx2,
|
|
227
|
+
z=y_mean.reshape(xx1.shape),
|
|
228
|
+
)
|
|
229
|
+
)
|
|
230
|
+
fig.add_trace(
|
|
231
|
+
go.Surface(
|
|
232
|
+
x=xx1,
|
|
233
|
+
y=xx2,
|
|
234
|
+
z=(y_mean + y_std).reshape(xx1.shape),
|
|
235
|
+
opacity=0.3,
|
|
236
|
+
)
|
|
237
|
+
)
|
|
238
|
+
fig.add_trace(
|
|
239
|
+
go.Surface(
|
|
240
|
+
x=xx1,
|
|
241
|
+
y=xx2,
|
|
242
|
+
z=(y_mean - y_std).reshape(xx1.shape),
|
|
243
|
+
opacity=0.3,
|
|
244
|
+
)
|
|
245
|
+
)
|
|
246
|
+
fig.add_trace(
|
|
247
|
+
go.Scatter3d(
|
|
248
|
+
x=self._debug_df_c[prm_names[i]],
|
|
249
|
+
y=self._debug_df_c[prm_names[j]],
|
|
250
|
+
z=self._debug_df_c['feasibility'],
|
|
251
|
+
mode='markers',
|
|
252
|
+
)
|
|
253
|
+
)
|
|
254
|
+
fig.show()
|
|
255
|
+
|
|
256
|
+
return
|
|
257
|
+
|
|
258
|
+
x = np.array([self.current_prm_values.values()])
|
|
259
|
+
|
|
260
|
+
f_mean, f_std = self.pyfemtet_model_c.predict(x)
|
|
261
|
+
f_mean, f_std = f_mean[0][0], f_std[0][0]
|
|
262
|
+
|
|
263
|
+
if isinstance(self.feasibility_cdf_threshold, float):
|
|
264
|
+
cdf_threshold = self.feasibility_cdf_threshold
|
|
265
|
+
else:
|
|
266
|
+
raise NotImplementedError(
|
|
267
|
+
f'self.cdf_threshold must be float, '
|
|
268
|
+
f'passed {self.feasibility_cdf_threshold}'
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
pof = 1 - norm.cdf(cdf_threshold, f_mean, f_std)
|
|
272
|
+
|
|
273
|
+
return pof
|
|
274
|
+
|
|
275
|
+
def update(self) -> None:
|
|
276
|
+
|
|
277
|
+
# BoTorchInterface.update() の前に PoF を計算する
|
|
278
|
+
pof = self.calc_pof()
|
|
279
|
+
if pof < self.pof_threshold:
|
|
280
|
+
logger.info(
|
|
281
|
+
_(
|
|
282
|
+
en_message='The surrogate model estimated '
|
|
283
|
+
'that the probability of '
|
|
284
|
+
'feasibility (PoF) is {pof}. '
|
|
285
|
+
'This is under {thresh}. '
|
|
286
|
+
'So this trial is processed as '
|
|
287
|
+
'a constraint violation.',
|
|
288
|
+
jp_message='サロゲートモデルは解の実行可能確率(PoF)が'
|
|
289
|
+
'{pof} であると予測しました。'
|
|
290
|
+
'これは閾値 {thresh} を下回っているので、'
|
|
291
|
+
'最適化試行においては拘束違反であると扱います。',
|
|
292
|
+
pof=pof,
|
|
293
|
+
thresh=self.pof_threshold,
|
|
294
|
+
)
|
|
295
|
+
)
|
|
296
|
+
raise _HiddenConstraintViolation(f'PoF < {self.pof_threshold}')
|
|
297
|
+
|
|
298
|
+
BoTorchInterface.update(self)
|
|
@@ -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']",85.63019613,minimize,Success,48:10.2,48:10.2,,TRUE,FALSE
|
|
5
|
+
1,76.66824027,50,100,B,"['A', 'B', 'C']",76.66824027,minimize,Hidden constraint violation,48:11.7,48:11.7,,FALSE,FALSE
|
|
6
|
+
2,62.68444915,50,100,C,"['A', 'B', 'C']",62.68444915,minimize,Hidden constraint violation,48:16.6,48:16.6,,FALSE,FALSE
|
|
7
|
+
3,63.08476439,50,100,A,"['A', 'B', 'C']",63.08476439,minimize,Success,48:20.2,48:20.2,,TRUE,FALSE
|
|
8
|
+
4,78.95677052,50,100,B,"['A', 'B', 'C']",78.95677052,minimize,Hidden constraint violation,48:23.5,48:23.5,,FALSE,FALSE
|
|
9
|
+
5,79.90834979,50,100,C,"['A', 'B', 'C']",79.90834979,minimize,Hidden constraint violation,48:27.2,48:27.2,,FALSE,FALSE
|
|
10
|
+
6,97.4442698,50,100,A,"['A', 'B', 'C']",97.4442698,minimize,Success,48:29.8,48:29.8,,TRUE,FALSE
|
|
11
|
+
7,87.12500776,50,100,B,"['A', 'B', 'C']",87.12500776,minimize,Hidden constraint violation,03:52.7,03:52.7,,FALSE,FALSE
|
|
12
|
+
8,69.56378151,50,100,C,"['A', 'B', 'C']",69.56378151,minimize,Hidden constraint violation,04:00.1,04:00.1,,FALSE,FALSE
|
|
13
|
+
9,80.49012367,50,100,A,"['A', 'B', 'C']",80.49012367,minimize,Success,04:06.2,04:06.2,,TRUE,FALSE
|
|
14
|
+
10,87.55804836,50,100,B,"['A', 'B', 'C']",87.55804836,minimize,Hidden constraint violation,04:13.1,04:13.1,,FALSE,FALSE
|
|
15
|
+
11,59.55103039,50,100,C,"['A', 'B', 'C']",59.55103039,minimize,Hidden constraint violation,04:19.3,04:19.3,,FALSE,FALSE
|
|
16
|
+
12,97.91995423,50,100,A,"['A', 'B', 'C']",97.91995423,minimize,Success,04:24.6,04:24.6,,TRUE,FALSE
|
|
17
|
+
13,91.01111473,50,100,B,"['A', 'B', 'C']",91.01111473,minimize,Hidden constraint violation,04:31.3,04:31.3,,FALSE,FALSE
|
|
18
|
+
14,53.36556413,50,100,C,"['A', 'B', 'C']",53.36556413,minimize,Hidden constraint violation,04:36.6,04:36.6,,FALSE,FALSE
|