pyfemtet 0.4.12__py3-none-any.whl → 0.4.14__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 +1 -1
- pyfemtet/dispatch_extensions.py +4 -0
- pyfemtet/message/1. make_pot.bat +12 -0
- pyfemtet/message/2. make_mo.bat +6 -0
- pyfemtet/message/__init__.py +5 -0
- pyfemtet/message/babel.cfg +2 -0
- pyfemtet/message/locales/ja/LC_MESSAGES/messages.po +449 -0
- pyfemtet/message/locales/messages.pot +439 -0
- pyfemtet/message/messages.py +174 -0
- pyfemtet/opt/_femopt.py +9 -9
- pyfemtet/opt/_femopt_core.py +22 -17
- pyfemtet/opt/femprj_sample/ParametricIF - True.femprj +0 -0
- pyfemtet/opt/femprj_sample/ParametricIF.femprj +0 -0
- pyfemtet/opt/femprj_sample/ParametricIF.py +31 -0
- pyfemtet/opt/femprj_sample/ParametricIF_test_result.reccsv +13 -0
- pyfemtet/opt/femprj_sample/cad_ex01_NX_test_result.reccsv +13 -13
- pyfemtet/opt/femprj_sample/cad_ex01_SW_test_result.reccsv +13 -13
- pyfemtet/opt/femprj_sample/gal_ex58_parametric_test_result.reccsv +13 -13
- pyfemtet/opt/femprj_sample/gau_ex08_parametric_test_result.reccsv +23 -23
- pyfemtet/opt/femprj_sample/her_ex40_parametric_test_result.reccsv +18 -18
- pyfemtet/opt/femprj_sample/paswat_ex1_parametric_test_result.reccsv +18 -18
- pyfemtet/opt/femprj_sample/tutorial.femprj +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial1.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial1.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial10.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial10.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial11.jpg +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial11.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial12.jpg +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial12.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial13.jpg +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial13.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial14.jpg +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial14.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial15.jpg +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial15.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial2.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial2.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial3.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial3.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial4.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial4.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial5.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial5.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial6.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial6.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial7.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial7.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial8.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial8.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric.Results/Ex14_trial9.jpg +0 -0
- pyfemtet/opt/{visualization/result_viewer/tutorial → femprj_sample}/wat_ex14_parametric.Results/Ex14_trial9.pdt +0 -0
- pyfemtet/opt/femprj_sample/wat_ex14_parametric_test_result.reccsv +18 -18
- pyfemtet/opt/femprj_sample_jp/ParametricIF_jp.femprj +0 -0
- pyfemtet/opt/femprj_sample_jp/ParametricIF_jp.py +31 -0
- pyfemtet/opt/interface/_femtet.py +45 -47
- pyfemtet/opt/interface/_femtet_parametric.py +7 -2
- pyfemtet/opt/interface/_femtet_with_nx/_interface.py +4 -4
- pyfemtet/opt/interface/_femtet_with_nx/update_model.py +6 -6
- pyfemtet/opt/interface/_femtet_with_sldworks.py +5 -4
- pyfemtet/opt/opt/__init__.py +2 -0
- pyfemtet/opt/opt/_base.py +41 -20
- pyfemtet/opt/opt/_optuna.py +8 -13
- pyfemtet/opt/opt/_scipy.py +4 -8
- pyfemtet/opt/opt/_scipy_scalar.py +1 -5
- pyfemtet/opt/prediction/__init__.py +0 -0
- pyfemtet/opt/prediction/base.py +52 -0
- pyfemtet/opt/prediction/single_task_gp.py +82 -0
- pyfemtet/opt/visualization/complex_components/control_femtet.py +9 -11
- pyfemtet/opt/visualization/complex_components/main_figure_creator.py +24 -11
- pyfemtet/opt/visualization/complex_components/main_graph.py +3 -4
- pyfemtet/opt/visualization/complex_components/pm_graph.py +715 -0
- pyfemtet/opt/visualization/complex_components/pm_graph_creator.py +168 -0
- pyfemtet/opt/visualization/process_monitor/application.py +16 -12
- pyfemtet/opt/visualization/process_monitor/pages.py +22 -7
- pyfemtet/opt/visualization/result_viewer/application.py +8 -3
- pyfemtet/opt/visualization/result_viewer/pages.py +59 -47
- {pyfemtet-0.4.12.dist-info → pyfemtet-0.4.14.dist-info}/METADATA +2 -1
- pyfemtet-0.4.14.dist-info/RECORD +151 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/tutorial.csv +0 -18
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14.log +0 -81
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14.pdt +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_heatflow.csv +0 -28
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_heatflow_el.csv +0 -22
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial1.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial10.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial11.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial11.pdt +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial12.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial12.pdt +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial13.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial13.pdt +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial14.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial14.pdt +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial15.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial15.pdt +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial2.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial3.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial4.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial5.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial6.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial7.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial8.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.Results/Ex14_trial9.jpg +0 -0
- pyfemtet/opt/visualization/result_viewer/tutorial/wat_ex14_parametric.femprj +0 -0
- pyfemtet-0.4.12.dist-info/RECORD +0 -138
- {pyfemtet-0.4.12.dist-info → pyfemtet-0.4.14.dist-info}/LICENSE +0 -0
- {pyfemtet-0.4.12.dist-info → pyfemtet-0.4.14.dist-info}/WHEEL +0 -0
- {pyfemtet-0.4.12.dist-info → pyfemtet-0.4.14.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from pyfemtet.opt import FemtetInterface, FEMOpt, AbstractOptimizer
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def ex_in(_, opt: AbstractOptimizer):
|
|
5
|
+
ex_r, in_r = opt.get_parameter('values')
|
|
6
|
+
return ex_r - in_r
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
if __name__ == '__main__':
|
|
11
|
+
|
|
12
|
+
fem = FemtetInterface(
|
|
13
|
+
parametric_output_indexes_use_as_objective={
|
|
14
|
+
0: "minimize",
|
|
15
|
+
1: "minimize",
|
|
16
|
+
2: "minimize",
|
|
17
|
+
},
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
femopt = FEMOpt(fem=fem)
|
|
21
|
+
|
|
22
|
+
femopt.add_parameter("external_radius", 10, 1, 10)
|
|
23
|
+
femopt.add_parameter("internal_radius", 5, 1, 10)
|
|
24
|
+
femopt.add_constraint(ex_in, lower_bound=1, strict=True, args=(femopt.opt,))
|
|
25
|
+
femopt.set_random_seed(42)
|
|
26
|
+
femopt.optimize(
|
|
27
|
+
n_trials=10,
|
|
28
|
+
n_parallel=1,
|
|
29
|
+
)
|
|
30
|
+
input('enter to quit') # required to tests script
|
|
31
|
+
femopt.terminate_all()
|
|
@@ -33,6 +33,7 @@ from pyfemtet.dispatch_extensions import (
|
|
|
33
33
|
DispatchExtensionException,
|
|
34
34
|
)
|
|
35
35
|
from pyfemtet.opt.interface import FEMInterface, logger
|
|
36
|
+
from pyfemtet.message import Msg
|
|
36
37
|
|
|
37
38
|
|
|
38
39
|
def post_activate_message(hwnd):
|
|
@@ -204,17 +205,15 @@ class FemtetInterface(FEMInterface):
|
|
|
204
205
|
if not hasattr(constants, 'STATIC_C'):
|
|
205
206
|
cmd = f'{sys.executable} -m win32com.client.makepy FemtetMacro'
|
|
206
207
|
os.system(cmd)
|
|
207
|
-
message =
|
|
208
|
-
message += '設定は自動で行われました(python -m win32com.client.makepy FemtetMacro).'
|
|
209
|
-
message += 'プログラムを再起動してください.'
|
|
208
|
+
message = Msg.ERR_NO_MAKEPY
|
|
210
209
|
print('================')
|
|
211
210
|
print(message)
|
|
212
211
|
print('================')
|
|
213
|
-
input('
|
|
212
|
+
input('Press enter to finish...')
|
|
214
213
|
raise RuntimeError(message)
|
|
215
214
|
|
|
216
215
|
if self.Femtet is None:
|
|
217
|
-
raise RuntimeError(
|
|
216
|
+
raise RuntimeError(Msg.ERR_FEMTET_CONNECTION_FAILED)
|
|
218
217
|
|
|
219
218
|
def _call_femtet_api(
|
|
220
219
|
self,
|
|
@@ -291,10 +290,13 @@ class FemtetInterface(FEMInterface):
|
|
|
291
290
|
# API を実行
|
|
292
291
|
try:
|
|
293
292
|
# 解析結果を開いた状態で Gaudi.Activate して ReExecute する場合、ReExecute の前後にアクティブ化イベントが必要
|
|
293
|
+
# さらに、プロジェクトツリーが開いていないとアクティブ化イベントも意味がないらしい。
|
|
294
294
|
if fun.__name__ == 'ReExecute':
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
295
|
+
if self.open_result_with_gui or self.parametric_output_indexes_use_as_objective:
|
|
296
|
+
post_activate_message(self.Femtet.hWnd)
|
|
297
|
+
returns = fun(*args, **kwargs) # can raise pywintypes.error
|
|
298
|
+
if self.open_result_with_gui or self.parametric_output_indexes_use_as_objective:
|
|
299
|
+
post_activate_message(self.Femtet.hWnd)
|
|
298
300
|
else:
|
|
299
301
|
returns = fun(*args, **kwargs)
|
|
300
302
|
except (com_error, error):
|
|
@@ -331,20 +333,19 @@ class FemtetInterface(FEMInterface):
|
|
|
331
333
|
# 再起動試行回数の上限に達していたら諦める
|
|
332
334
|
logger.debug(' ' * print_indent + f'現在の Femtet 再起動回数: {recourse_depth}')
|
|
333
335
|
if recourse_depth >= self.max_api_retry:
|
|
334
|
-
raise Exception(
|
|
336
|
+
raise Exception(Msg.ERR_FEMTET_CRASHED_AND_RESTART_FAILED)
|
|
335
337
|
|
|
336
338
|
# 再起動
|
|
337
|
-
logger.warn('
|
|
339
|
+
logger.warn(' ' * print_indent + Msg.WARN_FEMTET_CRASHED_AND_TRY_RESTART)
|
|
338
340
|
CoInitialize()
|
|
339
341
|
self.connect_femtet(connect_method='new')
|
|
340
342
|
self.open(self.femprj_path, self.model_name)
|
|
341
343
|
|
|
342
344
|
# 状態を復元するために一度変数を渡して解析を行う(fun.__name__がSolveなら2度手間だが)
|
|
343
|
-
logger.info(' ' * print_indent +
|
|
345
|
+
logger.info(' ' * print_indent + Msg.INFO_FEMTET_CRASHED_AND_RESTARTED)
|
|
344
346
|
self.update(self.parameters)
|
|
345
347
|
|
|
346
348
|
# 与えられた API の再帰的再試行
|
|
347
|
-
logger.info(' ' * print_indent + f'Femtet が回復されました。コマンド {fun.__name__} を再試行します。')
|
|
348
349
|
return self._call_femtet_api(
|
|
349
350
|
fun,
|
|
350
351
|
return_value_if_failed,
|
|
@@ -423,16 +424,15 @@ class FemtetInterface(FEMInterface):
|
|
|
423
424
|
(self.connect_method == 'new')
|
|
424
425
|
and (not self.allow_without_project)
|
|
425
426
|
):
|
|
426
|
-
raise RuntimeError(
|
|
427
|
-
|
|
427
|
+
raise RuntimeError(Msg.ERR_NEW_FEMTET_BUT_NO_FEMPRJ)
|
|
428
|
+
|
|
428
429
|
# さらに auto の場合は Femtet が存在しなければ new と同じ挙動になるので同様の処理
|
|
429
430
|
if (
|
|
430
431
|
(self.connect_method == 'auto')
|
|
431
432
|
and (len(_get_pids(process_name='Femtet.exe')) == 0)
|
|
432
433
|
and (not self.allow_without_project)
|
|
433
434
|
):
|
|
434
|
-
raise RuntimeError(
|
|
435
|
-
'femprj_path を指定せず Femtet の connect_method を指定しない(又は "auto" に指定する)場合、Femtet を起動して処理したい .femprj ファイルを開いた状態にしてください。')
|
|
435
|
+
raise RuntimeError(Msg.ERR_NEW_FEMTET_BUT_NO_FEMPRJ)
|
|
436
436
|
self.connect_femtet(self.connect_method)
|
|
437
437
|
|
|
438
438
|
# 最終的に接続した Femtet の femprj_path と model を インスタンスに戻す
|
|
@@ -452,25 +452,22 @@ class FemtetInterface(FEMInterface):
|
|
|
452
452
|
try:
|
|
453
453
|
variable_names = self.Femtet.GetVariableNames_py()
|
|
454
454
|
except AttributeError as e:
|
|
455
|
-
message = 'GetVariableNames_py' + 'にアクセスできません。'
|
|
456
|
-
f'Femtet {major}.{minor}.{bugfix} 以降で「マクロの有効化」が行われていない可能性があります。'
|
|
457
|
-
'スタートメニューから、インストールされいてる Femtet と同一バージョンの「マクロ機能を有効化する」コマンドを管理者権限で実行してください。'
|
|
458
455
|
print('================')
|
|
459
|
-
logger.error(
|
|
456
|
+
logger.error(Msg.ERR_CANNOT_ACCESS_API + 'GetVariableNames_py')
|
|
457
|
+
logger.error(Msg.CERTIFY_MACRO_VERSION)
|
|
460
458
|
print('================')
|
|
461
|
-
input(
|
|
459
|
+
input(Msg.ENTER_TO_QUIT)
|
|
462
460
|
raise e
|
|
463
461
|
|
|
464
462
|
if variable_names is not None:
|
|
465
463
|
if param_name in variable_names:
|
|
466
464
|
return self.Femtet.GetVariableValue(param_name)
|
|
467
|
-
message =
|
|
468
|
-
message += f'現在のモデルに設定されている変数は {variable_names} です.'
|
|
469
|
-
message += '大文字・小文字の区別に注意してください.'
|
|
465
|
+
message = Msg.ERR_NO_SUCH_PARAMETER_IN_FEMTET
|
|
470
466
|
print('================')
|
|
471
467
|
logger.error(message)
|
|
468
|
+
logger.error(f'`{param_name}` not in {variable_names}')
|
|
472
469
|
print('================')
|
|
473
|
-
input(
|
|
470
|
+
input(Msg.ENTER_TO_QUIT)
|
|
474
471
|
raise RuntimeError(message)
|
|
475
472
|
else:
|
|
476
473
|
return None
|
|
@@ -485,7 +482,7 @@ class FemtetInterface(FEMInterface):
|
|
|
485
482
|
self.Femtet.Gaudi.Activate,
|
|
486
483
|
True, # 戻り値を持たないのでここは無意味で None 以外なら何でもいい
|
|
487
484
|
Exception, # 生きてるのに開けない場合
|
|
488
|
-
error_message=
|
|
485
|
+
error_message=Msg.NO_ANALYSIS_MODEL_IS_OPEN,
|
|
489
486
|
)
|
|
490
487
|
|
|
491
488
|
major, minor, bugfix = 2023, 1, 1
|
|
@@ -495,14 +492,14 @@ class FemtetInterface(FEMInterface):
|
|
|
495
492
|
fun=self.Femtet.GetVariableNames_py,
|
|
496
493
|
return_value_if_failed=False, # 意味がない
|
|
497
494
|
if_error=ModelError, # 生きてるのに失敗した場合
|
|
498
|
-
error_message=f'GetVariableNames_py
|
|
495
|
+
error_message=f'GetVariableNames_py failed.',
|
|
499
496
|
is_Gaudi_method=True,
|
|
500
497
|
)
|
|
501
498
|
|
|
502
499
|
# 変数を含まないプロジェクトである場合
|
|
503
500
|
if existing_variable_names is None:
|
|
504
501
|
if with_warning:
|
|
505
|
-
return [
|
|
502
|
+
return [Msg.FEMTET_ANALYSIS_MODEL_WITH_NO_PARAMETER]
|
|
506
503
|
else:
|
|
507
504
|
return None
|
|
508
505
|
|
|
@@ -516,12 +513,12 @@ class FemtetInterface(FEMInterface):
|
|
|
516
513
|
fun=self.Femtet.UpdateVariable,
|
|
517
514
|
return_value_if_failed=False,
|
|
518
515
|
if_error=ModelError, # 生きてるのに失敗した場合
|
|
519
|
-
error_message=f'
|
|
516
|
+
error_message=Msg.ERR_FAILED_TO_UPDATE_VARIABLE + f'{value} -> {name}',
|
|
520
517
|
is_Gaudi_method=True,
|
|
521
518
|
args=(name, value),
|
|
522
519
|
)
|
|
523
520
|
else:
|
|
524
|
-
msg = f'
|
|
521
|
+
msg = f'{name} not in {self.model_name}: ' + Msg.WARN_IGNORE_PARAMETER_NOT_CONTAINED
|
|
525
522
|
warnings.append(msg)
|
|
526
523
|
logger.warn(msg)
|
|
527
524
|
|
|
@@ -535,7 +532,7 @@ class FemtetInterface(FEMInterface):
|
|
|
535
532
|
fun=self.Femtet.UpdateVariable,
|
|
536
533
|
return_value_if_failed=False,
|
|
537
534
|
if_error=ModelError, # 生きてるのに失敗した場合
|
|
538
|
-
error_message=f'
|
|
535
|
+
error_message=Msg.ERR_FAILED_TO_UPDATE_VARIABLE + f'{value} -> {name}',
|
|
539
536
|
is_Gaudi_method=True,
|
|
540
537
|
args=(name, value),
|
|
541
538
|
)
|
|
@@ -559,7 +556,7 @@ class FemtetInterface(FEMInterface):
|
|
|
559
556
|
self.Femtet.Gaudi.ReExecute,
|
|
560
557
|
False,
|
|
561
558
|
ModelError, # 生きてるのに失敗した場合
|
|
562
|
-
error_message=
|
|
559
|
+
error_message=Msg.ERR_RE_EXECUTE_MODEL_FAILED,
|
|
563
560
|
is_Gaudi_method=True,
|
|
564
561
|
)
|
|
565
562
|
|
|
@@ -568,7 +565,7 @@ class FemtetInterface(FEMInterface):
|
|
|
568
565
|
self.Femtet.Redraw,
|
|
569
566
|
False, # 戻り値は常に None なのでこの変数に意味はなく None 以外なら何でもいい
|
|
570
567
|
ModelError, # 生きてるのに失敗した場合
|
|
571
|
-
error_message=
|
|
568
|
+
error_message=Msg.ERR_MODEL_REDRAW_FAILED,
|
|
572
569
|
is_Gaudi_method=True,
|
|
573
570
|
)
|
|
574
571
|
|
|
@@ -582,7 +579,7 @@ class FemtetInterface(FEMInterface):
|
|
|
582
579
|
self.Femtet.Gaudi.Mesh,
|
|
583
580
|
0,
|
|
584
581
|
MeshError,
|
|
585
|
-
|
|
582
|
+
Msg.ERR_MODEL_MESH_FAILED,
|
|
586
583
|
is_Gaudi_method=True,
|
|
587
584
|
)
|
|
588
585
|
|
|
@@ -592,7 +589,7 @@ class FemtetInterface(FEMInterface):
|
|
|
592
589
|
fun=solve_via_parametric_dll,
|
|
593
590
|
return_value_if_failed=False,
|
|
594
591
|
if_error=SolveError,
|
|
595
|
-
error_message=
|
|
592
|
+
error_message=Msg.ERR_PARAMETRIC_SOLVE_FAILED,
|
|
596
593
|
is_Gaudi_method=True,
|
|
597
594
|
args=(self.Femtet,),
|
|
598
595
|
)
|
|
@@ -602,7 +599,7 @@ class FemtetInterface(FEMInterface):
|
|
|
602
599
|
self.Femtet.Solve,
|
|
603
600
|
False,
|
|
604
601
|
SolveError,
|
|
605
|
-
|
|
602
|
+
Msg.ERR_SOLVE_FAILED,
|
|
606
603
|
is_Gaudi_method=True,
|
|
607
604
|
)
|
|
608
605
|
|
|
@@ -611,7 +608,7 @@ class FemtetInterface(FEMInterface):
|
|
|
611
608
|
self.Femtet.OpenCurrentResult,
|
|
612
609
|
False,
|
|
613
610
|
SolveError, # 生きてるのに開けない場合
|
|
614
|
-
error_message=
|
|
611
|
+
error_message=Msg.ERR_OPEN_RESULT_FAILED,
|
|
615
612
|
is_Gaudi_method=True,
|
|
616
613
|
args=(self.open_result_with_gui,),
|
|
617
614
|
)
|
|
@@ -620,9 +617,12 @@ class FemtetInterface(FEMInterface):
|
|
|
620
617
|
"""See :func:`FEMInterface.update`"""
|
|
621
618
|
self.parameters = parameters.copy()
|
|
622
619
|
self.update_model(parameters)
|
|
623
|
-
|
|
620
|
+
self.preprocess(self.Femtet)
|
|
624
621
|
self.solve()
|
|
625
622
|
|
|
623
|
+
def preprocess(self, Femtet):
|
|
624
|
+
pass
|
|
625
|
+
|
|
626
626
|
def quit(self, timeout=1, force=True):
|
|
627
627
|
"""Force to terminate connected Femtet."""
|
|
628
628
|
major, minor, bugfix = 2024, 0, 1
|
|
@@ -631,13 +631,11 @@ class FemtetInterface(FEMInterface):
|
|
|
631
631
|
try:
|
|
632
632
|
self.Femtet.Exit(True)
|
|
633
633
|
except AttributeError as e:
|
|
634
|
-
message = 'Femtet.Exit()' + 'にアクセスできません。'
|
|
635
|
-
f'Femtet {major}.{minor}.{bugfix} 以降で「マクロの有効化」が行われていない可能性があります。'
|
|
636
|
-
'スタートメニューから、インストールされいてる Femtet と同一バージョンの「マクロ機能を有効化する」コマンドを管理者権限で実行してください。'
|
|
637
634
|
print('================')
|
|
638
|
-
logger.error(
|
|
635
|
+
logger.error(Msg.ERR_CANNOT_ACCESS_API + 'Femtet.Exit()')
|
|
636
|
+
logger.error(Msg.CERTIFY_MACRO_VERSION)
|
|
639
637
|
print('================')
|
|
640
|
-
input(
|
|
638
|
+
input(Msg.ENTER_TO_QUIT)
|
|
641
639
|
raise e
|
|
642
640
|
|
|
643
641
|
else:
|
|
@@ -651,7 +649,7 @@ class FemtetInterface(FEMInterface):
|
|
|
651
649
|
start = time()
|
|
652
650
|
while psutil.pid_exists(pid):
|
|
653
651
|
if time() - start > 30: # 30 秒経っても存在するのは何かおかしい
|
|
654
|
-
logger.error(
|
|
652
|
+
logger.error(Msg.ERR_CLOSE_FEMTET_FAILED)
|
|
655
653
|
break
|
|
656
654
|
sleep(1)
|
|
657
655
|
sleep(1)
|
|
@@ -722,7 +720,7 @@ class FemtetInterface(FEMInterface):
|
|
|
722
720
|
return content
|
|
723
721
|
|
|
724
722
|
else:
|
|
725
|
-
raise Exception(
|
|
723
|
+
raise Exception(Msg.ERR_FAILED_TO_SAVE_PDT)
|
|
726
724
|
|
|
727
725
|
else:
|
|
728
726
|
return None
|
|
@@ -742,10 +740,10 @@ class FemtetInterface(FEMInterface):
|
|
|
742
740
|
self.Femtet.RedrawMode = True # 逐一の描画をオン
|
|
743
741
|
|
|
744
742
|
if not succeed:
|
|
745
|
-
raise Exception(
|
|
743
|
+
raise Exception(Msg.ERR_FAILED_TO_SAVE_JPG)
|
|
746
744
|
|
|
747
745
|
if not os.path.exists(jpg_path):
|
|
748
|
-
raise Exception(
|
|
746
|
+
raise Exception(Msg.ERR_JPG_NOT_FOUND)
|
|
749
747
|
|
|
750
748
|
with open(jpg_path, 'rb') as f:
|
|
751
749
|
content = f.read()
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from femtetutils import util, logger
|
|
2
4
|
from pyfemtet.dispatch_extensions import _get_pid
|
|
3
5
|
|
|
4
6
|
import ctypes
|
|
5
7
|
|
|
6
8
|
|
|
9
|
+
logger.setLevel(logging.ERROR)
|
|
10
|
+
|
|
11
|
+
|
|
7
12
|
def _get_dll():
|
|
8
13
|
femtet_exe_path = util.get_femtet_exe_path()
|
|
9
14
|
dll_path = femtet_exe_path.replace('Femtet.exe', 'ParametricIF.dll')
|
|
@@ -11,7 +16,7 @@ def _get_dll():
|
|
|
11
16
|
|
|
12
17
|
|
|
13
18
|
def _get_dll_with_set_femtet(Femtet):
|
|
14
|
-
dll = _get_dll(
|
|
19
|
+
dll = _get_dll()
|
|
15
20
|
pid = _get_pid(Femtet.hWnd)
|
|
16
21
|
dll.SetCurrentFemtet.restype = ctypes.c_bool
|
|
17
22
|
dll.SetCurrentFemtet(pid)
|
|
@@ -7,6 +7,7 @@ from dask.distributed import get_worker
|
|
|
7
7
|
|
|
8
8
|
from pyfemtet.core import ModelError
|
|
9
9
|
from pyfemtet.opt.interface import FemtetInterface, logger
|
|
10
|
+
from pyfemtet.message import Msg
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
here, me = os.path.split(__file__)
|
|
@@ -40,8 +41,7 @@ class FemtetWithNXInterface(FemtetInterface):
|
|
|
40
41
|
# check NX installation
|
|
41
42
|
self.run_journal_path = os.path.join(os.environ.get('UGII_BASE_DIR'), 'NXBIN', 'run_journal.exe')
|
|
42
43
|
if not os.path.isfile(self.run_journal_path):
|
|
43
|
-
raise FileNotFoundError(
|
|
44
|
-
r'"%UGII_BASE_DIR%\NXBIN\run_journal.exe" が見つかりませんでした。環境変数 UGII_BASE_DIR 又は NX のインストール状態を確認してください。')
|
|
44
|
+
raise FileNotFoundError(Msg.ERR_RUN_JOURNAL_NOT_FOUND)
|
|
45
45
|
|
|
46
46
|
# 引数の処理
|
|
47
47
|
# dask サブプロセスのときは prt_path を worker space から取るようにする
|
|
@@ -137,7 +137,7 @@ class FemtetWithNXInterface(FemtetInterface):
|
|
|
137
137
|
self.Femtet.Gaudi.ReExecute,
|
|
138
138
|
False,
|
|
139
139
|
ModelError, # 生きてるのに失敗した場合
|
|
140
|
-
error_message=
|
|
140
|
+
error_message=Msg.ERR_MODEL_RECONSTRUCTION_FAILED,
|
|
141
141
|
is_Gaudi_method=True,
|
|
142
142
|
)
|
|
143
143
|
|
|
@@ -146,7 +146,7 @@ class FemtetWithNXInterface(FemtetInterface):
|
|
|
146
146
|
self.Femtet.Redraw,
|
|
147
147
|
False, # 戻り値は常に None なのでこの変数に意味はなく None 以外なら何でもいい
|
|
148
148
|
ModelError, # 生きてるのに失敗した場合
|
|
149
|
-
error_message=
|
|
149
|
+
error_message=Msg.ERR_MODEL_UPDATE_FAILED,
|
|
150
150
|
is_Gaudi_method=True,
|
|
151
151
|
)
|
|
152
152
|
|
|
@@ -43,7 +43,7 @@ def main(
|
|
|
43
43
|
try:
|
|
44
44
|
exp = workPart.Expressions.FindObject(k)
|
|
45
45
|
except NXOpen.NXException:
|
|
46
|
-
print(f'├
|
|
46
|
+
print(f'├ .prt does not contain parameter{k}. {k} is ignored.')
|
|
47
47
|
continue
|
|
48
48
|
|
|
49
49
|
workPart.Expressions.Edit(exp, str(v))
|
|
@@ -54,10 +54,10 @@ def main(
|
|
|
54
54
|
# 更新に失敗
|
|
55
55
|
except NXOpen.NXException as e:
|
|
56
56
|
print(f'├ ERROR! {e}')
|
|
57
|
-
print(f'└
|
|
57
|
+
print(f'└ Failed to update model.')
|
|
58
58
|
return None
|
|
59
59
|
|
|
60
|
-
print('│
|
|
60
|
+
print('│ Model updated successfully.')
|
|
61
61
|
|
|
62
62
|
try:
|
|
63
63
|
# parasolid のエクスポート
|
|
@@ -84,17 +84,17 @@ def main(
|
|
|
84
84
|
|
|
85
85
|
except Exception as e:
|
|
86
86
|
print(f'├ ERROR! {e}')
|
|
87
|
-
print(f'└ parasolid
|
|
87
|
+
print(f'└ Failed to update parasolid file.')
|
|
88
88
|
return None
|
|
89
89
|
|
|
90
|
-
print('└
|
|
90
|
+
print('└ Parasolid file updates successfully.')
|
|
91
91
|
return None
|
|
92
92
|
|
|
93
93
|
|
|
94
94
|
|
|
95
95
|
if __name__ == "__main__":
|
|
96
96
|
print('---NX started---')
|
|
97
|
-
print('current directory: ', os.getcwd())
|
|
97
|
+
# print('current directory: ', os.getcwd())
|
|
98
98
|
print('arguments: ')
|
|
99
99
|
for arg in sys.argv[1:]:
|
|
100
100
|
print('│ ', arg)
|
|
@@ -10,6 +10,7 @@ from pythoncom import CoInitialize, CoUninitialize
|
|
|
10
10
|
|
|
11
11
|
from pyfemtet.core import ModelError
|
|
12
12
|
from pyfemtet.opt.interface import FemtetInterface, logger
|
|
13
|
+
from pyfemtet.message import Msg
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
class FemtetWithSolidworksInterface(FemtetInterface):
|
|
@@ -100,7 +101,7 @@ class FemtetWithSolidworksInterface(FemtetInterface):
|
|
|
100
101
|
if os.path.isfile(x_t_path):
|
|
101
102
|
break
|
|
102
103
|
if time() - start > timeout:
|
|
103
|
-
raise ModelError(
|
|
104
|
+
raise ModelError(Msg.ERR_MODEL_UPDATE_FAILED)
|
|
104
105
|
sleep(1)
|
|
105
106
|
|
|
106
107
|
# モデルの再インポート
|
|
@@ -108,7 +109,7 @@ class FemtetWithSolidworksInterface(FemtetInterface):
|
|
|
108
109
|
self.Femtet.Gaudi.ReExecute,
|
|
109
110
|
False,
|
|
110
111
|
ModelError, # 生きてるのに失敗した場合
|
|
111
|
-
error_message=
|
|
112
|
+
error_message=Msg.ERR_RE_EXECUTE_MODEL_FAILED,
|
|
112
113
|
is_Gaudi_method=True,
|
|
113
114
|
)
|
|
114
115
|
|
|
@@ -117,7 +118,7 @@ class FemtetWithSolidworksInterface(FemtetInterface):
|
|
|
117
118
|
self.Femtet.Redraw,
|
|
118
119
|
False, # 戻り値は常に None なのでこの変数に意味はなく None 以外なら何でもいい
|
|
119
120
|
ModelError, # 生きてるのに失敗した場合
|
|
120
|
-
error_message=
|
|
121
|
+
error_message=Msg.ERR_MODEL_REDRAW_FAILED,
|
|
121
122
|
is_Gaudi_method=True,
|
|
122
123
|
)
|
|
123
124
|
|
|
@@ -157,7 +158,7 @@ class FemtetWithSolidworksInterface(FemtetInterface):
|
|
|
157
158
|
# 更新する(ここで失敗はしうる)
|
|
158
159
|
result = self.swModel.EditRebuild3 # モデル再構築
|
|
159
160
|
if not result:
|
|
160
|
-
raise ModelError(
|
|
161
|
+
raise ModelError(Msg.ERR_UPDATE_SOLIDWORKS_MODEL_FAILED)
|
|
161
162
|
|
|
162
163
|
def _get_name_from_equation(self, equation: str):
|
|
163
164
|
pattern = r'^\s*"(.+?)"\s*$'
|
pyfemtet/opt/opt/__init__.py
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
from pyfemtet.opt.opt._base import AbstractOptimizer, logger, OptimizationMethodChecker
|
|
2
2
|
from pyfemtet.opt.opt._optuna import OptunaOptimizer
|
|
3
3
|
from pyfemtet.opt.opt._scipy import ScipyOptimizer
|
|
4
|
+
from pyfemtet.opt.opt._scipy_scalar import ScipyScalarOptimizer
|
|
4
5
|
|
|
5
6
|
__all__ = [
|
|
7
|
+
'ScipyScalarOptimizer',
|
|
6
8
|
'ScipyOptimizer',
|
|
7
9
|
'OptunaOptimizer',
|
|
8
10
|
'AbstractOptimizer',
|
pyfemtet/opt/opt/_base.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
from abc import ABC, abstractmethod
|
|
3
3
|
|
|
4
4
|
# built-in
|
|
5
|
-
import
|
|
5
|
+
import traceback
|
|
6
6
|
from time import sleep
|
|
7
7
|
|
|
8
8
|
# 3rd-party
|
|
@@ -12,6 +12,7 @@ import pandas as pd
|
|
|
12
12
|
# pyfemtet relative
|
|
13
13
|
from pyfemtet.opt.interface import FemtetInterface
|
|
14
14
|
from pyfemtet.opt._femopt_core import OptimizationStatus
|
|
15
|
+
from pyfemtet.message import Msg
|
|
15
16
|
|
|
16
17
|
# logger
|
|
17
18
|
import logging
|
|
@@ -27,8 +28,10 @@ class OptimizationMethodChecker:
|
|
|
27
28
|
self.opt = opt
|
|
28
29
|
|
|
29
30
|
def check_parallel(self, raise_error=True):
|
|
30
|
-
function = 'parallel
|
|
31
|
-
|
|
31
|
+
function = 'parallel-processing'
|
|
32
|
+
method = str(type(self.opt))
|
|
33
|
+
message = (Msg.ERR_NOT_IMPLEMENTED
|
|
34
|
+
+ f'method:{method}, function:{function}')
|
|
32
35
|
if raise_error:
|
|
33
36
|
raise NotImplementedError(message)
|
|
34
37
|
else:
|
|
@@ -36,7 +39,9 @@ class OptimizationMethodChecker:
|
|
|
36
39
|
|
|
37
40
|
def check_timeout(self, raise_error=True):
|
|
38
41
|
function = 'timeout'
|
|
39
|
-
|
|
42
|
+
method = str(type(self.opt))
|
|
43
|
+
message = (Msg.ERR_NOT_IMPLEMENTED
|
|
44
|
+
+ f'method:{method}, function:{function}')
|
|
40
45
|
if raise_error:
|
|
41
46
|
raise NotImplementedError(message)
|
|
42
47
|
else:
|
|
@@ -44,23 +49,29 @@ class OptimizationMethodChecker:
|
|
|
44
49
|
|
|
45
50
|
def check_multi_objective(self, raise_error=True):
|
|
46
51
|
function = 'multi-objective'
|
|
47
|
-
|
|
52
|
+
method = str(type(self.opt))
|
|
53
|
+
message = (Msg.ERR_NOT_IMPLEMENTED
|
|
54
|
+
+ f'method:{method}, function:{function}')
|
|
48
55
|
if raise_error:
|
|
49
56
|
raise NotImplementedError(message)
|
|
50
57
|
else:
|
|
51
58
|
logger.warning(message)
|
|
52
59
|
|
|
53
60
|
def check_strict_constraint(self, raise_error=True):
|
|
54
|
-
function = '
|
|
55
|
-
|
|
61
|
+
function = 'strict-constraint'
|
|
62
|
+
method = str(type(self.opt))
|
|
63
|
+
message = (Msg.ERR_NOT_IMPLEMENTED
|
|
64
|
+
+ f'method:{method}, function:{function}')
|
|
56
65
|
if raise_error:
|
|
57
66
|
raise NotImplementedError(message)
|
|
58
67
|
else:
|
|
59
68
|
logger.warning(message)
|
|
60
69
|
|
|
61
70
|
def check_constraint(self, raise_error=True):
|
|
62
|
-
function = '
|
|
63
|
-
|
|
71
|
+
function = 'constraint'
|
|
72
|
+
method = str(type(self.opt))
|
|
73
|
+
message = (Msg.ERR_NOT_IMPLEMENTED
|
|
74
|
+
+ f'method:{method}, function:{function}')
|
|
64
75
|
if raise_error:
|
|
65
76
|
raise NotImplementedError(message)
|
|
66
77
|
else:
|
|
@@ -68,7 +79,9 @@ class OptimizationMethodChecker:
|
|
|
68
79
|
|
|
69
80
|
def check_skip(self, raise_error=True):
|
|
70
81
|
function = 'skip'
|
|
71
|
-
|
|
82
|
+
method = str(type(self.opt))
|
|
83
|
+
message = (Msg.ERR_NOT_IMPLEMENTED
|
|
84
|
+
+ f'method:{method}, function:{function}')
|
|
72
85
|
if raise_error:
|
|
73
86
|
raise NotImplementedError(message)
|
|
74
87
|
else:
|
|
@@ -76,7 +89,9 @@ class OptimizationMethodChecker:
|
|
|
76
89
|
|
|
77
90
|
def check_seed(self, raise_error=True):
|
|
78
91
|
function = 'random seed setting'
|
|
79
|
-
|
|
92
|
+
method = str(type(self.opt))
|
|
93
|
+
message = (Msg.ERR_NOT_IMPLEMENTED
|
|
94
|
+
+ f'method:{method}, function:{function}')
|
|
80
95
|
if raise_error:
|
|
81
96
|
raise NotImplementedError(message)
|
|
82
97
|
else:
|
|
@@ -84,7 +99,9 @@ class OptimizationMethodChecker:
|
|
|
84
99
|
|
|
85
100
|
def check_incomplete_bounds(self, raise_error=True):
|
|
86
101
|
function = 'optimize with no or incomplete bounds'
|
|
87
|
-
|
|
102
|
+
method = str(type(self.opt))
|
|
103
|
+
message = (Msg.ERR_NOT_IMPLEMENTED
|
|
104
|
+
+ f'method:{method}, function:{function}')
|
|
88
105
|
if raise_error:
|
|
89
106
|
raise NotImplementedError(message)
|
|
90
107
|
else:
|
|
@@ -137,15 +154,18 @@ class AbstractOptimizer(ABC):
|
|
|
137
154
|
|
|
138
155
|
# x の更新
|
|
139
156
|
self.parameters['value'] = x
|
|
140
|
-
logger.info(
|
|
157
|
+
logger.info('---------------------')
|
|
158
|
+
logger.info(f'input: {x}')
|
|
141
159
|
|
|
142
160
|
# FEM の更新
|
|
143
161
|
logger.debug('fem.update() start')
|
|
144
162
|
try:
|
|
145
163
|
self.fem.update(self.parameters)
|
|
146
164
|
except Exception as e:
|
|
147
|
-
logger.
|
|
148
|
-
|
|
165
|
+
logger.info(f'{type(e).__name__} : {e}')
|
|
166
|
+
logger.info(Msg.INFO_EXCEPTION_DURING_FEM_ANALYSIS)
|
|
167
|
+
logger.info(x)
|
|
168
|
+
raise e # may be just a ModelError, etc.
|
|
149
169
|
|
|
150
170
|
# y, _y, c の更新
|
|
151
171
|
logger.debug('calculate y start')
|
|
@@ -171,7 +191,7 @@ class AbstractOptimizer(ABC):
|
|
|
171
191
|
|
|
172
192
|
logger.debug('history.record end')
|
|
173
193
|
|
|
174
|
-
logger.info(f'
|
|
194
|
+
logger.info(f'output: {_y}')
|
|
175
195
|
|
|
176
196
|
return np.array(y), np.array(_y), np.array(c)
|
|
177
197
|
|
|
@@ -191,7 +211,7 @@ class AbstractOptimizer(ABC):
|
|
|
191
211
|
"""Returns the parameters in the specified format.
|
|
192
212
|
|
|
193
213
|
Args:
|
|
194
|
-
format (str, optional): The desired format of the parameters. Can be 'df' (DataFrame), 'values', or 'dict'. Defaults to 'dict'.
|
|
214
|
+
format (str, optional): The desired format of the parameters. Can be 'df' (DataFrame), 'value' (alias of values), 'values' (np.ndarray), or 'dict'. Defaults to 'dict'.
|
|
195
215
|
|
|
196
216
|
Returns:
|
|
197
217
|
object: The parameters in the specified format.
|
|
@@ -210,7 +230,7 @@ class AbstractOptimizer(ABC):
|
|
|
210
230
|
ret[row['name']] = row.value
|
|
211
231
|
return ret
|
|
212
232
|
else:
|
|
213
|
-
raise ValueError('get_parameter() got invalid format: {format}')
|
|
233
|
+
raise ValueError(f'get_parameter() got invalid format: {format}')
|
|
214
234
|
|
|
215
235
|
def _check_interruption(self):
|
|
216
236
|
""""""
|
|
@@ -274,7 +294,8 @@ class AbstractOptimizer(ABC):
|
|
|
274
294
|
logger.error("=================================")
|
|
275
295
|
logger.error("An unexpected error has occurred!")
|
|
276
296
|
logger.error("=================================")
|
|
277
|
-
logger.error(f'{type(e)}: {e}')
|
|
297
|
+
logger.error(f'{type(e).__name__}: {e}')
|
|
298
|
+
traceback.print_exc()
|
|
278
299
|
self._is_error_exit = True
|
|
279
300
|
self.worker_status.set(OptimizationStatus.CRASHED)
|
|
280
301
|
finally:
|
|
@@ -284,7 +305,7 @@ class AbstractOptimizer(ABC):
|
|
|
284
305
|
|
|
285
306
|
@abstractmethod
|
|
286
307
|
def run(self) -> None:
|
|
287
|
-
"""Start
|
|
308
|
+
"""Start calculation using optimization library."""
|
|
288
309
|
pass
|
|
289
310
|
|
|
290
311
|
@abstractmethod
|